⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mktmaker.m

📁 仿真人工金融市场Jackson代码
💻 M
📖 第 1 页 / 共 3 页
字号:
    // reduce netUnits by the number that grossUnits exceeds what this    //   trader has available.    netUnits = [aRequest getNetUnits] - 		(grossUnits - maxUnits);    netUnits = fmax (0, netUnits);    [aRequest setNetUnits: netUnits];  }// ***************************************************************************//  ADD ORDER TO PROCESSING LISTS       if ([aRequest getUnitPrice] == -1) {      mktOrderOfferAmt = mktOrderOfferAmt + [aRequest getNetUnits];      [mktOfferList addLast: (ShareRequest *) aRequest];   } else if ([aRequest getUnitPrice] < 0) {      // if negative offer, simply ignore it   } else {      addLimitOffer ((id) limitOfferList, (ShareRequest *) aRequest);   } // ***************************************************************************   return self;}/*-addRiskLessDemand: (Trader *) aTrader {   if (aTrader->riskLessBidAmt > 0)  {     [riskLessDemandList addLast: aTrader];     riskLessDemand = riskLessDemand + aTrader->riskLessBidAmt;   }   return self;}*//*-addRiskLessSupply: (Trader *) aTrader {   if (aTrader->riskLessOfferAmt > 0) {     [riskLessSupplyList addLast: aTrader];     riskLessSupply = riskLessSupply + aTrader->riskLessOfferAmt;   }   return self;}*/-print {  printf("MKTMAKER TESTS \n");  return self;}  //  NOTE:  payInterest must be scheduled after pay earnings so that  //    the riskyCF is correct for those days that earnings are paid.  This  //    is done so that all   other days have a riskyCF of zero.-payInterest {  Trader * aTrader;  id	 index;   if ((diagLevel & METHOD_ENTRY) ||       (diagLevel & METHOD_SCHED))      printf("*** payInterest (MktMaker) entry, (%d)\n",		 (int) getCurrentTime());  // Cleanup from last period -- if necessary  // Prepare info for traders to determine their demand -- if neccesary  // Determine riskLess mkt clearing price -- set at $1 for now  riskLessCF = 1 * riskLessRate;  riskLessClearPrice = 1;  //  // Distribute interest to ALL shareholders  //    NOTE:  this applies to everyone, whether they're  //		trading or not.    //  index = [(id) traderList begin: scratchZone];  while ((aTrader = [index next])) {    // coupon pmt    [aTrader addCash: aTrader->riskLessUnits*riskLessRate];    if (diagLevel & MKTMAKER_TRDR_WEALTH) {      printf ("Wealth of <%s> is %f\n",                [aTrader getName],               [aTrader getWealth]);    }  }  [index  drop];  // Tell statistician  [mktStats addRiskLessCF: riskLessCF : riskyCF];   return self;}-payEarnings {  Trader * aTrader;  id	 index;   if ((diagLevel & METHOD_ENTRY) ||       (diagLevel & METHOD_SCHED))      printf("*** payEarnings (MktMaker) entry, (%d)\n",		 (int) getCurrentTime());  // Cleanup from last period -- if necessary  // Prepare info for traders to determine their demand -- if neccesary  // DETERMINE DIVIDEND PER SHARE  riskyCFNoise = [riskyCFDist getDoubleSample];    // for now, steady growth rate to determine CF (div)...  // It is possible to have a negative CF, but we don't  //   want it to persist.  If last period was negative, just  //   use noise to set this period's CF.  This prevents an  //   explosive downturn in CFs.  // Use ARMA(1,1) process as described in Kmenta p. 529  //   with lambda = 0.75    riskyCF = (1+riskyGrowthRate)		* ([mktStats getEarningsLag:0])		 + riskyCFNoise		 - (0.75) * riskyCFNoiseLag;  //  Save for next period  riskyCFNoiseLag = riskyCFNoise;   if (diagLevel & MKTMAKER_TSERIES) {    printf ("Earnings[0] <%f> and Earnings[-1] <%f> Noise <%f>\n",	riskyCF, [mktStats getEarningsLag:0],        riskyCFNoise);  }  //  // Distribute dividends to ALL shareholders  //    NOTE:  this applies to everyone, whether they're  //		trading or not.  Some may be restricted  //		from trading for a period of time due  //		to margin, short-selling, or wealth   //		limitations.  //  index = [(id) traderList begin: scratchZone];  while ((aTrader = [index next])) {    // earnings    [aTrader addCash: aTrader->riskyUnits*riskyCF];    if (diagLevel & MKTMAKER_TRDR_WEALTH) {      printf ("Wealth of <%s> is %f\n",                [aTrader getName],               [aTrader getWealth]);    }  }  [index  drop];  // Tell statistician  [mktStats addEarnings: riskyCF];   return self;}-printDemandSched {  id index;   ShareRequest * aReq;  if (diagLevel & MKTMAKER_CLEARING) {  printf ("\n------------------DEMAND SCHEDULE------------------\n");  printf (" MktBidList\n");  index = [(id) mktBidList begin: scratchZone];  while ((aReq = [index next])) {    printf ("  [%s] Bid (%f) Amt (%f) \n",	[(Trader *) [aReq getTrader] getName],         [aReq getUnitPrice],        [aReq getNetUnits]);  }  [index drop];  printf (" MktOfferList\n");  index = [(id) mktOfferList begin: scratchZone];  while ((aReq = [index next])) {    printf ("  [%s] Offer (%f) Amt (%f) \n",	[(Trader *) [aReq getTrader] getName],         [aReq getUnitPrice],        [aReq getNetUnits]);  }  [index drop];  printf (" LimitBidList\n");  index = [(id) limitBidList begin: scratchZone];  while ((aReq = [index next])) {    printf ("  [%s] Bid (%f) Amt (%f) \n",	[(Trader *) [aReq getTrader] getName],         [aReq getUnitPrice],        [aReq getNetUnits]);  }  [index drop];  printf (" LimitOfferList\n");  index = [(id) limitOfferList begin: scratchZone];  while ((aReq = [index next])) {    printf ("  [%s] Offer (%f) Amt (%f) \n",	[(Trader *) [aReq getTrader] getName],         [aReq getUnitPrice],        [aReq getNetUnits]);  }  [index drop];  printf ("\n------------------END DEMAND SCHEDULE------------------\n");    }  // end if  CLEARING LOGGING IS ON  return self;}-checkBankruptcies {  void addLimitBid(), addLimitOffer();  ShareRequest * aRequest;  Trader * aTrader;  id index;  index = [(id) traderList begin: scratchZone];  while ((aTrader = [index next])) {     // BANKRUPTCY CODE:  IF WEALTH IS NEGATIVE, THE TRADER MUST     //   CLEAR ALL POSITIONS IN THE RISKY ASSET (LONG OR SHORT)    aRequest = [ShareRequest create: [self getZone]];    [aRequest setUnitPrice: -1];    [aRequest setTrader: (id *) aTrader];    // force bankrupt traders to liquidate all RISKY positions    if ([aTrader getWealth] <= 0) {      if (aTrader->riskyUnits > 0) { // have some and MUST sell ALL        [aRequest setGrossUnits: aTrader->riskyUnits];        [aRequest setNetUnits: aTrader->riskyUnits];        mktOrderOfferAmt = mktOrderOfferAmt + [aRequest getNetUnits];        [mktOfferList addLast: aRequest];      } else if (aTrader->riskyUnits < 0) {  // MUST close out SHORT positions        [aRequest setGrossUnits: -(aTrader->riskyUnits)];        [aRequest setNetUnits: -(aTrader->riskyUnits)];        mktOrderBidAmt = mktOrderBidAmt + [aRequest getNetUnits];        [mktBidList addLast: aRequest];      }      // Be sure to note when this trader's wealth became non-positive      [aTrader setBRPeriod: [mktStats getPeriod]];    }  }  [index  drop];  return self;}-countShares {  Trader * aTrader;  id index;  double totalShrs;  totalShrs = 0;  index = [(id) traderList begin: scratchZone];  while ((aTrader = [index next])) {    totalShrs = totalShrs + aTrader->riskyUnits;  }  [index  drop];  if (diagLevel & MKTMAKER_CLEARING)    printf ("TOTAL RISKY SHARES(%d) = %f", 	[mktStats getPeriod], totalShrs); return self;}//// LET WEALTH GO NEGATIVE FOR NOW....//// Mkt maker must clear both the riskless and risky mkts simultaneously// in case people want to fund risky purchases with riskless sales. Or// in the future if risky sales fund other risky purchases....// 1) Handle riskless sales, since they are certain to clear and//     money can go into their cash account.// 2) -step {  ClearingInfo *aClearInfo;  Trader * aTrader;  ShareRequest * aRequest;  //  id	 index, bidIndex, offerIndex;  id	 index, indexBid, indexOffer;  double amtRationedDmd, amtRationedSup;  double cash;  double shrsBid, shrsOffer;  double pricePoint;  double priceDiff, minPriceDiff;  double turnover, maxTurnover;  double demand, supply;  double highBid, lowOffer;  void addAscending();  int period;  period = [mktStats getPeriod];   if ((diagLevel & METHOD_ENTRY) ||       (diagLevel & METHOD_SCHED))      printf("*** step (MktMaker) entry\n");  // PRINT EVERYTIME FOR NOW  [self printDemandSched];   //  INITIALIZE risky volume for this period//  riskyVol = 0;  // Determine riskLess mkt clearing price -- set at $1 for now  riskLessClearPrice = 1;  // Convert ALL riskless holdings to cash in case it's  // need to buy risky asset.  ALL will be reinvested at  // riskless rate when risky mkt clears  // NOTE:  Since riskless units can be negative (borrowing),  //  this sequence can work to decrease cash (possibly negative).  //  This causes no problems unless total wealth is non-  //  postitive. Any cash positions (+ or -) will be closed  //  out after the risky market is cleared.  index = [(id) traderList begin: scratchZone];  while ((aTrader = [index next])) {    [aTrader addCash: (aTrader->riskLessUnits)*riskLessClearPrice];    [aTrader subtractRiskLessUnits: aTrader->riskLessUnits];    if (diagLevel & MKTMAKER_TRDR_WEALTH) {      printf ("<%s> has (%f) risky (%f) riskless (%f) cash (%f)\n", 	[aTrader getName], 	[aTrader getWealth],	aTrader->riskyUnits,        aTrader->riskLessUnits,        aTrader->cash);    }  }  [index  drop];#if 0/******************************************************************   Mkt Clearing Algorithm  If Mkt bid order > Mkt Sell orders, then price must rise to clear      * may have limit bid orders above prior mkt price    1.  Determine # shares demanded at each price point above and        including last periods clearing price.  Price points are        determined by examining the limit offer list and last         period's clearing price.    2.  Determine # of shares supply at each price point.    3.  Choose clearing price as LOWEST price at which the greatest        amount of turnover will occur.  We will "ration" whichever        side has the most available shares.  The side with the        fewest available shares will receive their full order.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -