📄 asmmodel.java
字号:
//限制股息的数值不能超界 if (dvdnd < mindividend) dvdnd = mindividend; if (dvdnd > maxdividend) dvdnd = maxdividend; //dvdnd=baseline; return dvdnd;}double normal(int n){ //产生一个正态分布的随机数 double s=0; for(int i=0;i<n;i++){ s+=Math.random(); } return Math.sqrt((double)(12)/(double)(n))*(s-n/2);}}class Specialist{ public double maxprice; /*"最大价格"*/ public double minprice; /*"最小价格"*/ public double eta; /*"用来调节价格供求比例"*/ public double minexcess; /*"过量需求必须小于这个数值excess demand must be smaller than this if the price adjustment process is to stop"*/ public double rea; /*"理性预期的标准rational expectations benchmark"*/ public double reb; /*"初始的价格 trialprice = rea*dividend + reb "*/ public double bidfrac; /*"用来交易的数值=volume/bidtotal"*/ public double offerfrac; /*"=volume/offertotal"*/ public int maxiterations; /*"最大调节市场价格的周期"*/ public double volume; /*交易量" volume of trades conducted"*/ public double taupdecay; /*agent的利润系数"The agent's profit is calculated as an exponentially weighted moving average. This coefficient weights old inputs in the EWMA"*/ public double taupnew; /*taupnew = -expm1(-1.0/aTaup); taupdecay = 1.0 - taupnew;"Used in calculating exponentially weighted moving average; taupnew = -expm1(-1.0/aTaup); taupdecay = 1.0 - taupnew; "*/ int sptype; /*不同的数值决定了市场出清的方法" an enumerated type indicating the sort of Specialist is being used, valued 0, 1, or 2"*/ /*"这个类的一个实例保证了交易的正确执行,并存储了关于市场的一些参数"*/void setTaup(double aTaup){ taupnew=-Math.exp(-1.0/aTaup); //taupnew = -expm1(-1.0/aTaup); //pj: moved here from init method taupdecay = 1.0 - taupnew; // moved to simplify!}/*考察类型参数的范围是否超界*/void setSPtype(int i){ if(i != 0 && i != 1 && i != 2 &&i!=3) { //system.Out("The specialist type chosen is invalid. Only 0, 1, or 2 are acceptable. The Specialist will be set to Slope (i.e., 1)."); i = 1; } sptype = i;}double performTrading(Vector agentList,World worldForSpec)/*" 这个方法是核心方法,完成市场出清 对于sptype=2的时候完成下面几个步骤: * asks the agents for their bids or offer at each, generally * adjusting the price towards reducing |bids - offers|. * It gets * bids and offers from the agents and * adjuss the price. Returns * the final trading price, which becomes * the next market price. * Various methods are implemented, but all * have the structure: * 1. Set a trial price 2. Send each agent a -getDemandAndSlope:forPrice: message and accumulate the total * number of bids and offers at that price. 3. [In some cases] go to 1. 4. Return the last trial price. "*/{ int mcount; boolean done; //需求量,不平衡量,当前股息 double demand, imbalance, dividend; //获得的边际需求量 double slope[]=new double[1]; //边际需求量的总和 double slopetotal = 0.0; //尝试价格 double trialprice = 0.0; //总的供给量 double offertotal = 0.0; //was IVAR //总的需求量 double bidtotal = 0.0; //was IVAR //交易量 volume = 0.0; dividend = worldForSpec.getDividend();//总的循环: for (mcount = 0, done = false; mcount < maxiterations && !done; mcount++) { // Set trial price -- various methods switch (sptype) { case 0: //理性预期学派的调整过程,系数rea,reb必须手工计算 Rational expectations benchmark: The rea and reb parameters must // be calculated by hand (highly dependent on agent and dividend). trialprice = rea*dividend + reb; done = true; // One pass break; case 1: //根据供求动态调整价格 if (mcount == 0) trialprice = worldForSpec.getPrice(); else{ // Use demand and slope information from the agent to set a new // price where the market should clear if the slopes are all // present and correct. Iterate until it's close or until // maxiterations is reached. imbalance = bidtotal - offertotal; if (imbalance <= minexcess && imbalance >= -minexcess) { done = true; continue; } // Update price using demand curve slope information if (slopetotal != 0) trialprice += imbalance/(10+slopetotal); else trialprice *= 1 + eta*imbalance; } break; case 2: //人工神经网络agent if (mcount == 0){ trialprice = worldForSpec.getPrice(); } else{ trialprice = (worldForSpec.getPrice())*(1.0 + eta*(bidtotal-offertotal)); done = true; // Two passes } break; case 3: //直接根据预期计算出股票的需求量 //因为市场出清要求:sigma(x)=N(初始时刻全部的股票量) //而x=(E(p+d)-(trialprice+dividend))/lamda*dev^2 //所以可以直接计算出trialprice的价格 int size=agentList.size(); double sigmac,sigmab,sigmaa; sigmac=sigmab=sigmaa=0; for(int i=0;i<size;i++){ Agent agent=(Agent)agentList.elementAt(i); sigmac+=ASMParam.initholding;// agent.position; sigmab+=(agent.pdcoeff*dividend+agent.offset)/agent.divisor; sigmaa+=(agent.pdcoeff-agent.intratep1)/agent.divisor; } if(sigmaa!=0){ trialprice=(sigmac-sigmab)/(sigmaa+1); } done=true; break; } //限制价格的范围 if (trialprice < minprice) trialprice = minprice; if (trialprice > maxprice) trialprice = maxprice; //得到每个agent的需求和边际需求 bidtotal = 0.0; offertotal = 0.0; slopetotal = 0.0; int size=agentList.size();//index = [agentList begin: [self getZone]]; for(int i=0;i<size;i++){ Agent agent=(Agent)agentList.elementAt(i); slope[0] = 0.0; demand = agent.getDemandAndSlope(slope,trialprice); slopetotal += slope[0]; if (demand > 0.0) bidtotal += demand; else if (demand < 0.0) offertotal -= demand; } // 计算交易量 if(bidtotal>offertotal)volume = offertotal; else volume=bidtotal; if(bidtotal>0.0)bidfrac = volume / bidtotal; else volume=0.0; if(offertotal>0.0)offerfrac = volume / offertotal; else offerfrac=0.0; } return trialprice;}void completeTrades(Vector agentList,World worldForSpec)/*完成交易,更新每个agent的现金量、持股量、总体财富"Updates the agents cash and position to consummate the trades previously negotiated in -performTrading, with rationing if necessary. * Makes the actual trades at the last trial price (which is now the * market price), by adjusting the agents' holdings and cash. The * actual purchase/sale my be less than that requested if rationing * is imposed by the specialist -- usually one of "bidfrac" and * "offerfrac" will be less than 1.0. * * This could easiliy be done by the agents themselves, but we let * the specialist do it for efficiency. "*/{ Agent agent; double bfp, ofp, tp, profitperunit; double price = 0.0; //pj: was IVAR price = worldForSpec.getPrice(); //获得每支股票的利润 profitperunit = worldForSpec.getProfitPerUnit();// Intermediates, for speed // bfp = bidfrac*price; ofp = offerfrac*price; tp = taupnew*profitperunit; int size=agentList.size(); for(int i=0;i<size;i++){// ((agent = [index next])) Agent agent1=(Agent)agentList.elementAt(i); // 更新利润,根据两个参数的加权和 agent1.profit = taupdecay*agent1.profit + tp*agent1.position; //完成实际的交易,更新股票持有量 if (agent1.demand > 0.0) { agent1.position += agent1.demand*bidfrac; agent1.cash-=agent1.demand*bfp; } else if (agent1.demand < 0.0) { agent1.position += agent1.demand*offerfrac; agent1.cash-= agent1.demand*ofp; } }}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -