private void dump(TextWriter writer, MamdaOrderBookPriceLevel level, int index) { string title = level.getSide() == MamdaOrderBookPriceLevel.Sides.Ask ? "Ask" : "Bid"; writer.WriteLine("{0} {1} | price={2} size={3} action={4} entries={5} time={6}", title, index, level.getPrice(), level.getSize(), level.getAction(), level.getNumEntries(), level.hasTime() ? level.getTime().ToString() : "null"); foreach (MamdaOrderBookEntry entry in level) { writer.WriteLine(" | id={0} size={1} action={2} time={3}", entry.getId(), entry.getSize(), entry.getAction(), entry.hasTime() ? entry.getTime().ToString() : "null"); } }
private TreeMap determineDiffs( TreeMap resultSide, TreeMap lhs, TreeMap rhs, bool ascending) { IEnumerator lhsEnum = lhs.Values.GetEnumerator(); IEnumerator rhsEnum = rhs.Values.GetEnumerator(); bool lhsHasNext = lhsEnum.MoveNext(); bool rhsHasNext = rhsEnum.MoveNext(); while (lhsHasNext || rhsHasNext) { MamdaOrderBookPriceLevel lhsLevel = null; MamdaOrderBookPriceLevel rhsLevel = null; double lhsPrice = double.MinValue; double rhsPrice = double.MinValue; long lhsSize = 0; long rhsSize = 0; if (lhsHasNext) { lhsLevel = (MamdaOrderBookPriceLevel)lhsEnum.Current; lhsPrice = lhsLevel.getPrice().getValue(); lhsSize = lhsLevel.getSize(); } if (rhsHasNext) { rhsLevel = (MamdaOrderBookPriceLevel)rhsEnum.Current; rhsPrice = rhsLevel.getPrice().getValue(); rhsSize = rhsLevel.getSize(); } // Compare two doubles using an epsilon if ((doubleEquals(lhsPrice, rhsPrice)) && (lhsSize == rhsSize)) { // Usual scenario: both levels are the same lhsHasNext = lhsEnum.MoveNext(); rhsHasNext = rhsEnum.MoveNext(); continue; } if (doubleEquals(lhsPrice, rhsPrice)) { // Same price, different size. Need to determine the // different entries. MamdaOrderBookPriceLevel diffLevel = new MamdaOrderBookPriceLevel(); diffLevel.setAsDifference(lhsLevel, rhsLevel); resultSide.Add(lhsLevel.getPrice(), diffLevel); lhsHasNext = lhsEnum.MoveNext(); rhsHasNext = rhsEnum.MoveNext(); continue; } if (ascending) { if (((lhsPrice > rhsPrice) && (rhsPrice != double.MinValue)) || (lhsPrice == double.MinValue)) { // RHS has an additional price level MamdaOrderBookPriceLevel diffLevel = new MamdaOrderBookPriceLevel(rhsLevel); resultSide.Add(rhsLevel.getPrice(), diffLevel); rhsHasNext = rhsEnum.MoveNext(); continue; } else { // RHS does not have a price level that is on the LHS. // Copy the LHS level and mark all as deleted. MamdaOrderBookPriceLevel diffLevel = new MamdaOrderBookPriceLevel(lhsLevel); resultSide.Add(lhsLevel.getPrice(), diffLevel); lhsHasNext = lhsEnum.MoveNext(); continue; } } else { if (((lhsPrice > rhsPrice) && (lhsPrice != double.MinValue)) || (rhsPrice == double.MinValue)) { // LHS has an additional price level MamdaOrderBookPriceLevel diffLevel = new MamdaOrderBookPriceLevel(lhsLevel); resultSide.Add(lhsLevel.getPrice(), diffLevel); // CHECK: use indexer? lhsHasNext = lhsEnum.MoveNext(); continue; } else { // LHS does not have a price level that is on the RHS. // Copy the RHS level and mark all as deleted. MamdaOrderBookPriceLevel diffLevel = new MamdaOrderBookPriceLevel(rhsLevel); resultSide.Add(rhsLevel.getPrice(), diffLevel); // CHECK: use indexer? rhsHasNext = rhsEnum.MoveNext(); continue; } } } return(resultSide); }
/// <summary> /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> public void setAsDifference( MamdaOrderBookPriceLevel lhs, MamdaOrderBookPriceLevel rhs) { int lhsBookSize = lhs.mEntries.Count; int rhsBookSize = rhs.mEntries.Count; int lhsIndex = 0; int rhsIndex = 0; while ((lhsIndex < lhsBookSize) && (rhsIndex < rhsBookSize)) { string lhsId = null; string rhsId = null; long lhsSize = 0; long rhsSize = 0; MamdaOrderBookEntry lhsEntry = null; MamdaOrderBookEntry rhsEntry = null; if (lhsIndex < lhsBookSize) { lhsEntry = (MamdaOrderBookEntry)lhs.mEntries[lhsIndex]; lhsId = lhsEntry.getId(); lhsSize = lhsEntry.getSize(); } if (rhsIndex < rhsBookSize) { rhsEntry = (MamdaOrderBookEntry)rhs.mEntries[rhsIndex]; rhsId = rhsEntry.getId(); rhsSize = rhsEntry.getSize(); } if ((lhsId != null) && (rhsId != null)) { if (lhsId == rhsId) { // Same ID, maybe different size. if (lhsSize != rhsSize) { MamdaOrderBookEntry updateEntry = new MamdaOrderBookEntry(rhsEntry); updateEntry.setAction(MamdaOrderBookEntry.Actions.Update); addEntry(updateEntry); } lhsIndex++; rhsIndex++; continue; } else { // Different ID (either something exists on the LHS // and not on RHS or vice versa). int rhsFound = findEntryAfter(rhs.mEntries, rhsIndex, lhsId); if (rhsFound != rhsSize) { // The ID from the LHS was found on the RHS, so // there must have been additional entries on the // RHS, which we now need to add. do { addEntry((MamdaOrderBookEntry)rhs.mEntries[rhsIndex]); rhsIndex++; } while (rhsIndex < rhsFound); } else { // The ID from the LHS was not present on the RHS, // so add the LHS entry. Note: it would probably // be faster to iterate over the LHS side rather // than begin the loop again. addEntry((MamdaOrderBookEntry)lhs.mEntries[lhsIndex]); lhsIndex++; } } } } if (mPrice != null && rhs.getPrice() != null) { mPrice.destroy(); } mPrice = rhs.getPrice(); setSizeChange(rhs.getSize() - lhs.getSize()); setSize(rhs.getSize()); setNumEntries(rhs.getNumEntries()); setAction(Actions.Update); mTime = rhs.getTime(); setSide(rhs.getSide()); }
/// <summary> /// </summary> /// <param name="lhs"></param> /// <param name="rhs"></param> public void setAsDifference( MamdaOrderBookPriceLevel lhs, MamdaOrderBookPriceLevel rhs) { int lhsBookSize = lhs.mEntries.Count; int rhsBookSize = rhs.mEntries.Count; int lhsIndex = 0; int rhsIndex = 0; while ((lhsIndex < lhsBookSize) && (rhsIndex < rhsBookSize)) { string lhsId = null; string rhsId = null; long lhsSize = 0; long rhsSize = 0; MamdaOrderBookEntry lhsEntry = null; MamdaOrderBookEntry rhsEntry = null; if (lhsIndex < lhsBookSize) { lhsEntry = (MamdaOrderBookEntry)lhs.mEntries[lhsIndex]; lhsId = lhsEntry.getId(); lhsSize = lhsEntry.getSize(); } if (rhsIndex < rhsBookSize) { rhsEntry = (MamdaOrderBookEntry)rhs.mEntries[rhsIndex]; rhsId = rhsEntry.getId(); rhsSize = rhsEntry.getSize(); } if ((lhsId != null) && (rhsId != null)) { if (lhsId == rhsId) { // Same ID, maybe different size. if (lhsSize != rhsSize) { MamdaOrderBookEntry updateEntry = new MamdaOrderBookEntry(rhsEntry); updateEntry.setAction(MamdaOrderBookEntry.Actions.Update); addEntry(updateEntry); } lhsIndex++; rhsIndex++; continue; } else { // Different ID (either something exists on the LHS // and not on RHS or vice versa). int rhsFound = findEntryAfter(rhs.mEntries, rhsIndex, lhsId); if (rhsFound != rhsSize) { // The ID from the LHS was found on the RHS, so // there must have been additional entries on the // RHS, which we now need to add. do { addEntry((MamdaOrderBookEntry)rhs.mEntries[rhsIndex]); rhsIndex++; }while (rhsIndex < rhsFound); } else { // The ID from the LHS was not present on the RHS, // so add the LHS entry. Note: it would probably // be faster to iterate over the LHS side rather // than begin the loop again. addEntry((MamdaOrderBookEntry)lhs.mEntries[lhsIndex]); lhsIndex++; } } } } if (mPrice != null && rhs.getPrice() != null) { mPrice.destroy(); } mPrice = rhs.getPrice(); setSizeChange(rhs.getSize() - lhs.getSize()); setSize(rhs.getSize()); setNumEntries(rhs.getNumEntries()); setAction(Actions.Update); mTime = rhs.getTime(); setSide(rhs.getSide()); }