📄 world.java
字号:
if(dividend > olddividend){ dupdown[updown_top] = 1; }else{ dupdown[updown_top] = 0; }/* Update the price and dividend moving averages *///历史长度下标更新 history_top = history_top + 1 + MAXHISTORY; //update moving averages of price and dividend //更新价格和股息的移动平均数组 for (i = 0; i < NMAS; i++) { int rago = (history_top-malength[i])%MAXHISTORY; priceMA[i].addValue(price); divMA[i].addValue(dividend); oldpriceMA[i].addValue(pricehistory[rago]); olddivMA[i].addValue(divhistory[rago]); }/* Update the price and dividend histories *///记录价格和股息的历史信息 history_top %= MAXHISTORY; pricehistory[history_top] = price; divhistory[history_top] = dividend;/* Construct the bit vector for the current state of the world *///建立世界的编码 makebitvector();}void makebitvector()/*" Set all the world bits, based on the current dividend, price,and their moving averages and histories. This moves through therealworld array, bit by bit, setting the values to 0, 1 or 2,according to the data that has been observed. Note the pointer math, such as realworld[i++], that steps the integer i through the array. Note that "i" increases monotonically throughout this routine, alwaysbeing the next bit to assign. It is crucial that the order here is thesame as in bitnamelist[]. "*/{ int i, j, k, temp; double multiple; i = 0; //设定前三位"on", "dummy bit -- always on"}{"off", "dummy bit -- always off"},{"random", "random on or off"}, realworld[i++] = 1; realworld[i++] = 0; realworld[i++] = (int)(Math.random()*2); /* Dividend went up or down, now and for last few periods */ //{"dup", "dividend went up this period"}, // 3 //{"dup1", "dividend went up one period ago"}, //{"dup2", "dividend went up two periods ago"}, //{"dup3", "dividend went up three periods ago"}, //{"dup4", "dividend went up four periods ago"}, temp = updown_top + UPDOWNLOOKBACK; for (j = 0; j < UPDOWNLOOKBACK; j++, temp--) realworld[i++] = dupdown[temp%UPDOWNLOOKBACK]; /* Dividend moving averages went up or down {"d5up", "5-period MA of dividend went up"}, // 8 {"d20up", "20-period MA of dividend went up"}, {"d100up", "100-period MA of dividend went up"}, {"d500up", "500-period MA of dividend went up"},*/ for (j = 0; j < NMAS; j++){ double temp1,temp2; if(exponentialMAs){ temp1=divMA[j].getEWMA(); temp2=olddivMA[j].getEWMA(); }else{ temp1=divMA[j].getMA(); temp2=olddivMA[j].getMA(); } if(temp1>temp2)realworld[i++] =1; else realworld[i++]=0; } /* Dividend > MA[j] *///{"d>d5", "dividend > 5-period MA"}, // 12//{"d>d20", "dividend > 20-period MA"},//{"d>d100", "dividend > 100-period MA"},//{"d>d500", "dividend > 500-period MA"}, for (j = 0; j < NMAS; j++){ double temp1,temp2; if(exponentialMAs){ temp1=dividend; temp2=divMA[j].getEWMA(); }else{ temp1=dividend; temp2=divMA[j].getMA(); } if(temp1>temp2)realworld[i++] =1; else realworld[i++]=0; } //realworld[i++] = dividend > ( GETMA(divMA,j)); /* Dividend MA[j] > dividend MA[k] {"d5>d20", "dividend: 5-period MA > 20-period MA"}, // 16 {"d5>d100", "dividend: 5-period MA > 100-period MA"}, {"d5>d500", "dividend: 5-period MA > 500-period MA"}, {"d20>d100", "dividend: 20-period MA > 100-period MA"}, {"d20>d500", "dividend: 20-period MA > 500-period MA"}, {"d100>d500", "dividend: 100-period MA > 500-period MA"},*/ for (j = 0; j < NMAS-1; j++){ for (k = j+1; k < NMAS; k++){ //realworld[i++] = (GETMA(divMA,j)) > (GETMA(divMA,k)); double temp1,temp2; if(exponentialMAs){ temp1=divMA[j].getEWMA(); temp2=divMA[k].getEWMA(); }else{ temp1=divMA[j].getMA(); temp2=divMA[k].getMA(); } if(temp1>temp2)realworld[i++] =1; else realworld[i++]=0; } } /* Dividend as multiple of meandividend {"d/md>1/4", "dividend/mean dividend > 1/4"}, // 22 {"d/md>1/2", "dividend/mean dividend > 1/2"}, {"d/md>3/4", "dividend/mean dividend > 3/4"}, {"d/md>7/8", "dividend/mean dividend > 7/8"}, {"d/md>1", "dividend/mean dividend > 1 "}, {"d/md>9/8", "dividend/mean dividend > 9/8"}, {"d/md>5/4", "dividend/mean dividend > 5/4"}, {"d/md>3/2", "dividend/mean dividend > 3/2"}, {"d/md>2", "dividend/mean dividend > 2"}, {"d/md>4", "dividend/mean dividend > 4"},*/ multiple = dividend/dividendscale; for (j = 0; j < NRATIOS; j++){ if(multiple>ratios[j])realworld[i++]=1; else realworld[i++]=0; } /* Price as multiple of dividend/intrate. Here we use olddividend to * make a more reasonable comparison with the [old] price. {"pr/d>1/4", "price*interest/dividend > 1/4"}, // 32 {"pr/d>1/2", "price*interest/dividend > 1/2"}, {"pr/d>3/4", "price*interest/dividend > 3/4"}, {"pr/d>7/8", "price*interest/dividend > 7/8"}, {"pr/d>1", "price*interest/dividend > 1"}, {"pr/d>9/8", "price*interest/dividend > 9/8"}, {"pr/d>5/4", "price*interest/dividend > 5/4"}, {"pr/d>3/2", "price*interest/dividend > 3/2"}, {"pr/d>2", "price*interest/dividend > 2"}, {"pr/d>4", "price*interest/dividend > 4"},*/ multiple = price*intrate/olddividend; for (j = 0; j < NRATIOS; j++){ if(multiple>ratios[j])realworld[i++]=1; else realworld[i++]=0; } /* Price went up or down, now and for last few periods {"pup", "price went up this period"}, // 42 {"pup1", "price went up one period ago"}, {"pup2", "price went up two periods ago"}, {"pup3", "price went up three periods ago"}, {"pup4", "price went up four periods ago"},*/ temp = updown_top + UPDOWNLOOKBACK; for (j = 0; j < UPDOWNLOOKBACK; j++, temp--) realworld[i++] = pupdown[temp%UPDOWNLOOKBACK]; /* Price moving averages went up or down {"p5up", "5-period MA of price went up"}, // 47 {"p20up", "20-period MA of price went up"}, {"p100up", "100-period MA of price went up"}, {"p500up", "500-period MA of price went up"},*/ for (j = 0; j < NMAS; j++){ double temp1,temp2; if(exponentialMAs){ temp1=priceMA[j].getEWMA(); temp2=oldpriceMA[j].getEWMA(); }else{ temp1=priceMA[j].getMA(); temp2=oldpriceMA[j].getMA(); } if(temp1>temp2)realworld[i++] = 1; else realworld[i++]=0; } /* Price > MA[j] {"p>p5", "price > 5-period MA"}, // 51 {"p>p20", "price > 20-period MA"}, {"p>p100", "price > 100-period MA"}, {"p>p500", "price > 500-period MA"},*/ for (j = 0; j < NMAS; j++){ double temp1; if(exponentialMAs){ temp1=priceMA[j].getEWMA(); }else{ temp1=priceMA[j].getMA(); } if(price>temp1)realworld[i++] =1; else realworld[i++] =0; } /* Price MA[j] > price MA[k] {"p5>p20", "price: 5-period MA > 20-period MA"}, // 55 {"p5>p100", "price: 5-period MA > 100-period MA"}, {"p5>p500", "price: 5-period MA > 500-period MA"}, {"p20>p100", "price: 20-period MA > 100-period MA"}, {"p20>p500", "price: 20-period MA > 500-period MA"}, {"p100>p500", "price: 100-period MA > 500-period MA"} */ for (j = 0; j < NMAS-1; j++){ for (k = j+1; k < NMAS; k++){ double temp1,temp2; if(exponentialMAs){ temp1=priceMA[j].getEWMA(); temp2=priceMA[k].getEWMA(); }else{ temp1=priceMA[j].getMA(); temp2=priceMA[k].getMA(); } if(temp1>temp2)realworld[i++] =1; else realworld[i++]=0; } }}/*" Returns the real world array of bits. Used by BFagent to compare their worlds to the real world."*/String getRealWorld(){ //将realworld数组转换成字符串 String result=""; for(int i=0;i<realworld.length;i++){ result+=String.valueOf(realworld[i]); } return result;}//将世界的历史信息记录到向量中,以便之后绘图使用public void RecordHistory(int currentTime){ WorldVariants now_world=new WorldVariants(); now_world.price=price; now_world.dividend=dividend; now_world.currentTime=currentTime; now_world.rate=intrate; now_world.risk_neutral=riskNeutral; Histories.addElement(now_world); if(Histories.size()>WorldVariants.cycleMax){ Histories.setElementAt(now_world,Histories.size()%WorldVariants.cycleMax); }}}//MovingAverage类负责一个时间序列求平均值的纪录//这个时间序列的记录有一个宽度width,然后对所有时间序列求平均值class MovingAverage{ public int width; /*时间序列数据的宽度"number of observations used for a fixed interval moving average"*/ public int numInputs; /*已经纪录的个数"number of observations that have already been inserted"*/ public double maInputs[]; /*保存下的历史数聚"historical inputs are kept in this array."*/ public int arrayPosition; /*当前纪录的下标"element of maInputs that has been most recently inserted"*/ public double sumOfInputs;/*全长的数据和"sum of the last 'width' inputs"*/ public double uncorrectedSum; /*当对象被建立以后所有输入的和"sum of all inputs since object was created"*/ public double expWMA; //指数加权的移动平均值exponentially weighted moving average public double aweight, bweight; /*计算指数加权平均值的权值"Weights used to calculate exponentially weighted moving averages. These depend on the specified 'width' according to: bweight = -expm1(-1.0/w);aweight = 1.0 - bweight; ewma=aweight*ma(x)+bweight*x"*//*"This is a general purpose class for creating Moving Averages, either flat "equally weighted" moving averages or exponentially weighted moving averages"*/void initWidth(int w){ //初始化移动平均中的各个变量 int i; width=w; maInputs=new double[w]; for(i=0; i < w; i++){ maInputs[i] = 0; } numInputs=0; sumOfInputs=0; arrayPosition=0; uncorrectedSum=0; bweight = -Math.exp(-1.0/w); aweight = 1.0 - bweight; //weight for expWMA; ma=a*ma(x)+b*x}void initWidth(int w,double val){ int i; width=w; maInputs=new double[w]; for(i=0; i < w; i++) { maInputs[i] = val; } numInputs=w; sumOfInputs=w*val; arrayPosition=0; uncorrectedSum=w*val; bweight = -Math.exp(-1.0/w); aweight = 1.0 - bweight; //weight for expWMA; ma=a*ma(x)+b*x expWMA = val;}int getNumInputs(){ return numInputs;}double getMA(){ //得到序列的平均值 double movingAverage; if (numInputs == 0) return 0; //当纪录的个数小于width的时候则指标数是numInputs,否则是width else if (numInputs < width){ movingAverage= (double)sumOfInputs / (double) numInputs; } else{ movingAverage = (double)sumOfInputs / (double) width; } return movingAverage;}double getAverage(){ //返回所有记录过的纪录的全体平均值 if (numInputs ==0) return 0; else return (double)uncorrectedSum/numInputs;}double getEWMA(){ return expWMA;}void addValue(double x){ //当加入一个时间序列的纪录的时候 //记录下标对宽度进行循环 arrayPosition = (width + numInputs) % width; //如果纪录的总数小于宽度就直接纪录,并求总和,如果不是,那么需要把对应记录位置的值减去再加上新的值 if(numInputs < width){ sumOfInputs+=x; maInputs[arrayPosition]=x; } else{ sumOfInputs=sumOfInputs - maInputs[arrayPosition] + x ; maInputs[arrayPosition]=x; } numInputs++; //所有记录过的纪录的全体和 uncorrectedSum+=x; expWMA = aweight*expWMA + bweight*x;}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -