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

📄 mktmaker.m

📁 仿真人工金融市场Jackson代码
💻 M
📖 第 1 页 / 共 3 页
字号:
  else if Mkt bid orders < Mkt Sell order, then price must fall      * may have limit sell  orders below prior mkt price    1.  Determine # shares demanded at each price point below and        including last periods clearing price.  Price points are        determined by examining the limit bid 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.  else Mkt bids = Mkt ssell orders    1.  Clear mkt at old clearing price filling the entire orders        of both sides of the market.*******************************************************************/#endif     riskyClearPrice = [mktStats getRiskyLagPrice:0];  // Search limit offer list for price points. Build clearing info list  //   be sure to include prior clearing price as a price point.  aClearInfo = [ClearingInfo create: [self getZone]];  [aClearInfo setPricePoint: riskyClearPrice];  pricePoint = riskyClearPrice;  addAscending ((id) priceList, (id) aClearInfo);//    [ascendList addAscend: (id) aClearInfo];  index = [(id) limitOfferList begin: scratchZone];  while ((aRequest = [index next])) {    // don't want any duplicates    if ([aRequest getUnitPrice] != pricePoint) {      aClearInfo = [ClearingInfo create: [self getZone]];      [aClearInfo setPricePoint: [aRequest getUnitPrice]];      pricePoint = [aRequest getUnitPrice];      addAscending ((id) priceList, (id) aClearInfo);    }   } // end search of limitOfferList  [index drop];  index = [(id) limitBidList begin: scratchZone];  while ((aRequest = [index next])) {    // don't want any duplicates    if ([aRequest getUnitPrice] != pricePoint) {      aClearInfo = [ClearingInfo create: [self getZone]];      [aClearInfo setPricePoint: [aRequest getUnitPrice]];      pricePoint = [aRequest getUnitPrice];      addAscending ((id) priceList, (id) aClearInfo);    }   } // end search of limitOfferList  [index drop];  shrsBid = shrsOffer = 0;  // find turnover at each price point.  index = [(id) priceList begin: scratchZone];  while ((aClearInfo = [index next])) {    shrsBid = mktOrderBidAmt;    shrsOffer = mktOrderOfferAmt;    // Determine shrs demanded at each price point. Limit bid list is    //   in descending order so if I find one that doesn't satisfy, don't    //   need to search further.    indexBid = [(id) limitBidList begin: scratchZone];    while ((aRequest = [indexBid next])) {      if ([aRequest getUnitPrice] >= [aClearInfo getPricePoint])         shrsBid = shrsBid + [aRequest getNetUnits];      else        break;    }    [indexBid drop];    // Determine shrs supplied at each price point. At the highest price    //   point all mkt offers and limit offers are active.  At the lowest    //   price point only mkt orders and possibly limit orders are active.    indexOffer = [(id) limitOfferList begin: scratchZone];    while ((aRequest = [indexOffer next])) {      if (([aRequest getUnitPrice] <= [aClearInfo getPricePoint]))        shrsOffer = shrsOffer + [aRequest getNetUnits];      else        break;    }    [indexOffer drop];    [aClearInfo setDemand: shrsBid];    [aClearInfo setSupply: shrsOffer];  }     [index drop];  // Traverse clearingInfoList to determine price point with greatest  //   turnover.  index = [(id) priceList begin: scratchZone];  pricePoint = [mktStats getRiskyLagPrice:0];     // default is last period's price  maxTurnover = 0;  demand = supply = 0;  while ((aClearInfo = [index next])) {    turnover = fmin ([aClearInfo getDemand], 	           [aClearInfo getSupply]);          // since clearInfo list is in ascending order, this is    //   strictly greater than. If two pricePoints have samne    //   turnover, we choose the lowest clearing price.    if (turnover > maxTurnover) {      maxTurnover = turnover;    }  }  [index drop];  // don't bother if no trades  if (maxTurnover > 0) {    // If multiple price points have equiv turnover, choose    //   the one nearest to prior clearing price.    minPriceDiff = 1000;    index = [(id) priceList begin: scratchZone];    while ((aClearInfo = [index next])) {      turnover = fmin ([aClearInfo getDemand], 	           [aClearInfo getSupply]);      // Find pricePoint nearest prior clearing price such that      //   turnover is maximized!      if (turnover == maxTurnover) {        priceDiff = fabs ([aClearInfo getPricePoint] - 		          [mktStats getRiskyPrice]);         if (priceDiff < minPriceDiff) {          minPriceDiff = priceDiff;          pricePoint = [aClearInfo getPricePoint];          demand = [aClearInfo getDemand];          supply = [aClearInfo getSupply];        }      }    }    [index drop];  }  // if no turnover occurs this period, then leave volume at zero and leave  //     riskyClearPrice at last periods clearing price (the default)  if ( ! ((demand == 0) && (supply == 0))) {    // clearing price is minimum price point with maximum turnover    riskyClearPrice = pricePoint;    // Inform traders willing to transact at price point of their    //   given transaction amounts and the clearing price    if (demand > supply) {      amtRationedDmd = supply/demand;      amtRationedSup = 1;    } else {      amtRationedDmd = 1;      amtRationedSup = demand/supply;    }        index = [(id) mktBidList begin: scratchZone];    while ((aRequest = [index next])) {      [(Trader *) [aRequest getTrader] 	addRiskyUnits: amtRationedDmd*[aRequest getNetUnits]];      [(Trader *) [aRequest getTrader] subtractCash:          [aRequest getNetUnits]*amtRationedDmd*riskyClearPrice];    }    [index drop];    index = [(id) mktOfferList begin: scratchZone];    while ((aRequest = [index next])) {      [(Trader *) [aRequest getTrader] 	subtractRiskyUnits: amtRationedSup*[aRequest getNetUnits]];      [(Trader *) [aRequest getTrader] addCash:          [aRequest getNetUnits]*amtRationedSup*riskyClearPrice];    }    [index drop];    indexBid = [(id) limitBidList begin: scratchZone];    while ((aRequest = [indexBid next])) {      if ([aRequest getUnitPrice] >= pricePoint) {        [(Trader *) [aRequest getTrader] 	   addRiskyUnits: amtRationedDmd*[aRequest getNetUnits]];        [(Trader *) [aRequest getTrader] subtractCash:   	   [aRequest getNetUnits]*amtRationedDmd*riskyClearPrice];      } else           break;    }    [indexBid drop];    indexOffer = [(id) limitOfferList begin: scratchZone];    while ((aRequest = [indexOffer next])) {      if ([aRequest getUnitPrice] <= pricePoint) {        [(Trader *) [aRequest getTrader] 	   subtractRiskyUnits: amtRationedSup*[aRequest getNetUnits]];        [(Trader *) [aRequest getTrader] addCash:    	   [aRequest getNetUnits]*amtRationedSup*riskyClearPrice];      }  else          break;    }    [indexOffer drop];    } else {  //  There is NO turnover this period            //  In this case, we want to report zero turnover, but            //  we report a market price which is the average of the             //  highest bid and lowest offer available.            //  These will be the first on their respective lists.        if ([limitBidList getCount] != 0) {      aRequest = [limitBidList removeFirst];      highBid = [aRequest getUnitPrice];      // replace so all memory is freed in one place      [limitBidList addLast: aRequest];    } else {      highBid = 0;    }    if ([limitOfferList getCount] != 0) {      aRequest = [limitOfferList removeFirst];      lowOffer = [aRequest getUnitPrice];      [limitOfferList addLast: aRequest];    } else {      lowOffer = 0;    }    // if have bids & offers, take average.    // if missing one or the other, take what I have    // if no limit orders avail, report price unchanged    if (highBid == 0)      riskyClearPrice = lowOffer;    else if (lowOffer == 0)      riskyClearPrice = highBid;    else if ((highBid != 0) && (lowOffer != 0) )       riskyClearPrice = (lowOffer + highBid)/2;    else      riskyClearPrice = [mktStats getRiskyPrice];  }  // end if-else there IS a positive turnover this period  // Let everyone with cash invest at riskless rate.  // Traders get cash during clearing by selling risky or  // riskless assets and through dividends and riskless coupon pmnts  // NOTE:  We're simply turning all (+ and -) cash positions into  //   riskless positions since we've been working with their cash  //   positions while clearing the riskless market.  index = [(id) traderList begin: scratchZone];  while ((aTrader = [index next])) {    cash = [aTrader checkCash];    // cash amt is number of riskless units since its price is unity,    //   nevertheless, we'll be overly explicit about the process for    //   now to maintain some  generality    aTrader->riskLessBidAmt = cash;    [aTrader addRiskLessUnits: aTrader->riskLessBidAmt];    [aTrader subtractCash: (aTrader->riskLessBidAmt)*riskLessClearPrice];  }  [index  drop];  // DON'T FORGET TO DROP ALL CLEARINGINFO OBJECTS AND PURGE ALL  //    LISTS!!!!  [priceList deleteAll];  // purge lists and delete all shr request objects   [mktBidList deleteAll];  [mktOfferList deleteAll];  [limitBidList deleteAll];  [limitOfferList deleteAll];  // Let statistician update history  [mktStats addPrices: riskyClearPrice : riskLessClearPrice ];  [mktStats addVol: maxTurnover];  // Reset supply/demand totals  mktOrderBidAmt = mktOrderOfferAmt = 0;  // Reset CF amounts  riskyCF = 0;  riskLessCF = 0;//  riskLessSupply = riskLessDemand = 0;    return self;}// The Bids should be ordered from the highest to the//   lowest so that I can sequentially search them//   for the most "favorable".void addLimitBid ( id list, ShareRequest * newRequest) {  id index;  ShareRequest *aRequest;  if ([list getCount] != 0) {    index = [(id) list begin: scratchZone];    while ((aRequest = [index next])) {      // if >= then add in front      if ([newRequest getUnitPrice] >= [aRequest getUnitPrice]) {        [index addBefore: newRequest];        break;      }    }    [index drop];    // If we got to the end of the list, index will be    //    nil, but the trader won't be on the list    if (aRequest == nil)      [list addLast: newRequest];          } else  // this is the first    [list addLast: newRequest];}// The Offers should be ordered from the lowest to the//   highest so that I can sequentially search them//   for the most "favorable".void addLimitOffer ( id list, ShareRequest * newRequest) {  id index;  ShareRequest *aRequest;  if ([list getCount] != 0) {    index = [(id) list begin: scratchZone];    while ((aRequest = [index next])) {      // if <= then add in front      if ([newRequest getUnitPrice] <= [aRequest getUnitPrice]) {        [index addBefore: newRequest];        break;      }    }    [index drop];    // If we got to the end of the list, index will be    //    nil, but the trader won't be on the list    if (aRequest == nil)      [list addLast: newRequest];  } else  // this is the first    [list addLast: newRequest];}void addAscending ( id list, ClearingInfo *c) {  ClearingInfo *aClearInfo;  id index;  if ([list getCount] != 0 ) {    index = [(id) list begin: scratchZone];    while ((aClearInfo = [index next])) {      // if <= then add in front      if ([c getPricePoint] <= [aClearInfo getPricePoint]) {        [index addBefore: c];        break;      }    }    [index drop];    // if we got to the end of the list, index will be    //   nil, but the trader won't be on teh list    if (aClearInfo == nil)      [list addLast: c];   } else  // this is the first      [list addLast: c];}@end

⌨️ 快捷键说明

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