📄 world.java
字号:
package asm;import java.util.Vector;/** * Title: Artificial Stock Market * Description: 人工模拟股市(来源:SFI的Swarm版本)的Java版本 * Copyright: Copyright (c) 2003 * Company: http://agents.yeah.net * @author jake * @version 1.0 *///该类负责对世界的状态进行纪录并编码public class World { public double intrate; /*利率" interest rate"*/ public double dividendscale; /*股息的基本值" The baseline dividend that is set by initWithBaseline: "*/ public int pupdown[]; /*一个数组记录价格的升降情况" array, dimension UPDOWNLOOKBACK "*/ public int dupdown[]; /*一个数组记录股息的升降情况" array, dimension UPDOWNLOOKBACK "*/ public int history_top; /*价格、股息数组的历史纪录指标" index value of current input into history arrays "*/ public int updown_top; /*pupdown和dupdown两个数组的指标"number of time steps to look back to form pupdown and dupdown bits"*/ public double price; /*股票的市场价格"market clearning price"*/ public double oldprice; /*上一期的市场价格" previous price "*/ public double dividend; /*当前的股息" dividend "*/ public double olddividend; /*上一期的股息"previous dividend"*/ public double saveddividend; /* copy of olddividend, used for some double-checking on object integrity"*/ public double savedprice; /* copy of oldprice, used for some double-checking on object integrity"*/ public double riskNeutral; /*"dividend/intrate"*/; public double profitperunit; /*没支股票的静收益=price - oldprice + dividend"*/ public double returnratio; /*回报率=profitperunit/oldprice"*/ public int malength[]; /*" For each MA, we must specify the length over which the average is calculated. This array has one integer for each of the moving averages we plan to keep, and it is used to set the widths covered by the moving averages."*/ public int nworldbits; /*世界信息编码的长度"The number of aspects of the world that are recorded as bits"*/ public int realworld[]; /*真实世界的编码,每个索引对应的值为0~2"An array (dynamically allocated, sorry) of ints, one for each bit being monitored. This is kept up-to-date. There's a lot of pointer math going on with this and I don't feel so glad about it (PJ: 2001-11-01)"*/ public boolean exponentialMAs; /*是否用指数加权的方法计算移动平均数值"Indicator variable, YES if the World is supposed to report back exponentially weighted moving averages"*/ public MovingAverage priceMA[]; /*价格的移动平均" MovingAverage objects which hold price information. There are NMAS of these, and have various widths for the moving averages "*/ public MovingAverage divMA[]; /*股息的移动平均" MovingAverage objects which hold dividend moving averages. "*/ public MovingAverage oldpriceMA[]; /*上期价格的移动平均" MovingAverage objects which hold lagged price moving averages "*/ public MovingAverage olddivMA[];/*上期股息的移动平均" MovingAverage objects which hold lagged dividend moving averages "*/ public Vector Histories; //记录世界的历史信息 double divhistory[]; /*股息历史数组" dividend history array, goes back MAXHISTORY points"*/ double pricehistory[]; /*价格历史数组" price history array "*/ static int NULLBIT=-1; static int PUPDOWNBITNUM=42; static int NWORLDBITS=61; static int NRATIOS=10; static int EQ=0; static int UPDOWNLOOKBACK=5; static int NMAS=4; static int MAXHISTORY=500; //定义世界编码对应位的名称 String bitnamelist[][]={{"on", "dummy bit -- always on"}, // 0{"off", "dummy bit -- always off"},{"random", "random on or off"},{"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"},{"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"},{"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"},{"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"},{"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"},{"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"},{"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"},{"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"},{"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"},{"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"}};double ratios[] ={0.25, 0.5, 0.75, 0.875, 1.0, 1.125, 1.25, 1.5, 2.0, 4.0};//比例数值数组public World() { //构建函数,初始化各个变量 pupdown=new int[UPDOWNLOOKBACK]; /*" array, dimension UPDOWNLOOKBACK "*/ dupdown=new int[UPDOWNLOOKBACK]; malength=new int[NMAS]; priceMA=new MovingAverage[NMAS]; /*" MovingAverage objects which hold price information. There are NMAS of these, and have various widths for the moving averages "*/ divMA=new MovingAverage[NMAS]; /*" MovingAverage objects which hold dividend moving averages. "*/ oldpriceMA=new MovingAverage[NMAS]; /*" MovingAverage objects which hold lagged price moving averages "*/ olddivMA=new MovingAverage[NMAS]; Histories=new Vector();}String descriptionOfBit(int n){ //获得指定位的描述 if (n == NULLBIT) return "(Unused bit for spacing)"; else if (n < 0 || n >= NWORLDBITS) return "(Invalid world bit)"; return bitnamelist[n][1];}String nameOfBit(int n){ //获得指定位的名称 if (n == NULLBIT) return "null"; else if (n < 0 || n >= NWORLDBITS) return ""; return bitnamelist[n][0];}int bitNumberOf(String name)/*" Converts a bit name to a bit number. Supplies the number of a bit * given its name. Unknown names return NULLBIT. Relatively slow * (linear search). Could be made faster with a hash table etc, but * that's not worth it for the intended usage. "*/{ //根据位的名称获得位的值 int n; for (n = 0; n < NWORLDBITS; n++) if (bitnamelist[n][0].equals(name)) break; if (n >= NWORLDBITS) n = NULLBIT; return n;}void setintrate(double rate) /*" Interest rate set in ASMModelSwarm."*/{ intrate = rate;}void setExponentialMAs(boolean aBool) /*" Turns on the use of exponential MAs in calculations. Can be turned on in GUI or ASMModelSwarm.m. If not, simple averages of the last N periods."*/{ exponentialMAs = aBool;}int getNumWorldBits() /*" Returns numworldbits; used by the BFagent."*/{ return nworldbits;}void initWithBaseline(double baseline)/*"Initializes moving averages, using initial values based ona price scale of "baseline" for the dividend. The baseline isset in ASMModelSwarm. " */{ int i; double initprice, initdividend;// Check pup index //if (!nameOfBit(PUPDOWNBITNUM).equals("pup")) //system.out("PUPDOWNBITNUM is incorrect");// Set price and dividend etc from baseline dividendscale = baseline; initprice = baseline/intrate;//初始化价格 initdividend = baseline;//初始化股息 saveddividend = dividend = initdividend; setDividend(initdividend); savedprice = price = initprice; setPrice(initprice);// Initialize profit measures returnratio = intrate;//初始化回报率 profitperunit = 0.0;// Initialize miscellaneous variables nworldbits = NWORLDBITS; //各个移动平均数组的记录长度 malength[0] = 5; malength[1] = 20; malength[2] = 100; malength[3] = MAXHISTORY; history_top = 0; updown_top = 0; divhistory=new double[MAXHISTORY]; /*" dividend history array, goes back MAXHISTORY points"*/ pricehistory=new double[MAXHISTORY]; realworld = new int[NWORLDBITS]; // Initialize arrays for (i = 0; i < UPDOWNLOOKBACK; i++) { pupdown[i] = 0; dupdown[i] = 0; } for (i = 0; i < MAXHISTORY; i++) { pricehistory[i] = initprice; divhistory[i] = initdividend; } //初始化各种移动平均数组 for (i = 0; i < NMAS; i++) { priceMA[i] = new MovingAverage(); priceMA[i].initWidth(malength[i],initprice); divMA[i] =new MovingAverage(); divMA[i].initWidth(malength[i],initdividend); oldpriceMA[i] = new MovingAverage(); oldpriceMA[i].initWidth(malength[i],initprice); olddivMA[i] =new MovingAverage(); olddivMA[i].initWidth(malength[i],initdividend); }// Initialize bits//初始化世界的信息编码 makebitvector();}/*设置价格p,并计算回报率" Sets the market price to "p". All price changes (besides trialprices) should use this method. Also computes profitperunit andreturnratio. Checks internally for illegal changes of "price", giving us theeffective benefit of encapsulation with the simplicity of use ofa global variable. "*/void setPrice(double p){ //if (price != savedprice) //system.Out("Price was changed illegally"); oldprice = price; price = p; //计算每股的收益 profitperunit = price - oldprice + dividend; //计算回报率 if (oldprice <= 0.0) returnratio = profitperunit*1000.0; /* Arbitrarily large */ else returnratio = profitperunit/oldprice; savedprice = price;}/*"Returns the price, used by many classes."*/double getPrice(){ return price;}/*"Returns profitperunit, used by Specialist."*/double getProfitPerUnit(){ return profitperunit;}/*"Sets the global value of "dividend". All dividend changes should use this method. It checks for illegal changes, as does -setPrice:."*/void setDividend(double d){ //if (dividend != saveddividend) //system.Out("Dividend was changed illegally."); //设置股息,并计算风险中性价格 olddividend = dividend; dividend = d; saveddividend = dividend; riskNeutral = dividend/intrate;}/*"Returns the most recent dividend, used by many."*/double getDividend(){ return dividend;}/*"Returns the risk neutral price. It is just dividend/intrate."*/double getRiskNeutral(){ return riskNeutral;}/*" Updates the history records, moving averages, and world bits to * reflect the current price and dividend. Note that this is called * in each period after a new dividend has been declared but before * the bidding and price adjustment. The bits seen by the agents thus * do NOT reflect the trial price. The "price" here becomes the * "oldprice" by the end of the period. It is called once per period. * (This could be done automatically as part of -setDividend:). * * The dividend used here is at present the latest value, though it * could be argued that it should be the one before, to match price. * For the p*r/d bits we do use the old one. "*///对世界当前的状况进行编码,每个运行周期内,先进行该动作然后才让每个agent进行报价、交易void updateWorld(){ int i;/* Update the binary up/down indicators for price and dividend *///纪录当前的价格和股息是升还是降 updown_top = (updown_top + 1) % UPDOWNLOOKBACK; if(price>oldprice){ pupdown[updown_top] = 1; }else{ pupdown[updown_top] = 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -