/** * Method invoked when we stop processing the last level in a message. We * invoke this method after the last entry for the level gets processed. * The subscription may be destroyed from this callback. */ void onBookAtomicEndBook ( MamdaSubscription* subscription, MamdaBookAtomicListener& listener) { /** * When level recap/delta is received, it is stored in a MamdaOrderBookPriceLevel. * If no entry deltas/recaps are received, then the price level should be applied * to the book. * The entry delta/recap callback will mark the price level with an UNKNOWN side to * show that it does not need to be applied to the book */ if(mReusablePriceLevel.getSide() != MamdaOrderBookPriceLevel::MAMDA_BOOK_SIDE_UNKNOWN) { if (gExampleLogLevel == EXAMPLE_LOG_LEVEL_NORMAL && mOrderBook.getQuality() == MAMA_QUALITY_OK) { prettyPrint(subscription, mReusablePriceLevel); } applyLevel(mReusablePriceLevel); mReusablePriceLevel.setSide(MamdaOrderBookPriceLevel::MAMDA_BOOK_SIDE_UNKNOWN); } if(mOrderBook.getQuality() == MAMA_QUALITY_OK && gExampleLogLevel == EXAMPLE_LOG_LEVEL_NORMAL) { prettyPrint(mOrderBook); } cout<< "BOOK END\n"; }
/** * Method invoked when a full refresh of the order book for the * security is available. The reason for the invocation may be * any of the following: * - Initial image. * - Recap update (e.g., after server fault tolerant event or data * quality event.) * - After stale status removed. */ void onBookAtomicLevelEntryRecap ( MamdaSubscription* subscription, MamdaBookAtomicListener& listener, const MamaMsg& msg, const MamdaBookAtomicLevelEntry& levelEntry) { applyEntry(levelEntry); /** * An entry has been processed on the level so mark the level with * an unknown side so that it will not be applied to book */ mReusablePriceLevel.setSide (MamdaOrderBookPriceLevel::MAMDA_BOOK_SIDE_UNKNOWN); }
/** * Helper function to store a MamdaBookAtomicLevel in * the resuabale MamdaOrderBookPriceLevel */ void storeLevel(const MamdaBookAtomicLevel& level) { mReusablePriceLevel.clear(); mReusablePriceLevel.setPrice (level.getPriceLevelPrice()); mReusablePriceLevel.setSide ((MamdaOrderBookPriceLevel::Side)level.getPriceLevelSide()); mReusablePriceLevel.setTime (level.getPriceLevelTime()); /** * As per the MAMDA Developers Guide, the following three accessors on a MamdaBookAtomicLevel * object should not be used for V5 entry updates. Here, these calls are used and * the resulting MamdaOrderBookPriceLevel is only used when the callbacks received * indicate that the update was not a V5 entry update. */ mReusablePriceLevel.setSize (level.getPriceLevelSize()); mReusablePriceLevel.setAction ((MamdaOrderBookPriceLevel::Action) level.getPriceLevelAction()); mReusablePriceLevel.setNumEntries ((mama_u32_t)level.getPriceLevelNumEntries()); }
/** * Method invoked when an order book delta is reported. */ void onBookAtomicLevelEntryDelta ( MamdaSubscription* subscription, MamdaBookAtomicListener& listener, const MamaMsg& msg, const MamdaBookAtomicLevelEntry& levelEntry) { if (gExampleLogLevel == EXAMPLE_LOG_LEVEL_NORMAL && mOrderBook.getQuality() == MAMA_QUALITY_OK) { prettyPrint (subscription, levelEntry); } applyEntry (levelEntry); /** * An entry has been processed on the level so mark the level with * an unknown side so that it will not be applied to book */ mReusablePriceLevel.setSide (MamdaOrderBookPriceLevel::MAMDA_BOOK_SIDE_UNKNOWN); }
void BookPublisher::processOrder () { MamdaOrderBookPriceLevel* level = NULL; MamdaOrderBookEntry* entry = NULL; order thisOrder = orderArray[mOrderCount]; mBookTime.setToNow(); if (mProcessEntries) { switch (thisOrder.entAction) { case ENTDELETE: { level = mBook->getLevelAtPrice (thisOrder.price, thisOrder.side); if (level) entry = level->findEntry (thisOrder.entId); if (entry) mBook->deleteEntry (entry, mBookTime, NULL); break; } case ENTADD: { mBook->addEntry (thisOrder.entId, thisOrder.entSize, thisOrder.price, thisOrder.side, mBookTime, NULL, NULL); break; } case ENTUPDATE: { entry = level->findEntry (thisOrder.entId); mBook->updateEntry (entry, thisOrder.entSize, mBookTime, NULL); break; } } } else { level = mBook->getLevelAtPrice(thisOrder.price, thisOrder.side); if (level) { level->setSizeChange (thisOrder.sizeChange); level->setPrice (thisOrder.price); level->setSize (thisOrder.volume); level->setNumEntries (thisOrder.numEntries); level->setTime (mBookTime); level->setAction (thisOrder.plAction); } else { level = new MamdaOrderBookPriceLevel(); level->setSide (thisOrder.side); level->setSizeChange (thisOrder.sizeChange); level->setPrice (thisOrder.price); level->setSize (thisOrder.volume); level->setNumEntries (thisOrder.numEntries); level->setTime (mBookTime); level->setAction (thisOrder.plAction); } switch (thisOrder.plAction) { case PLDELETE: mBook->deleteLevel(*level); break; case PLADD: mBook->addLevel(*level); break; case PLUPDATE: mBook->updateLevel(*level); break; } } mOrderCount++; }