void esig_OnQuoteChanged(string sSymbol) { try { // get tick info BasicQuote q = esig.get_GetBasicQuote(sSymbol); // get our struct Tick k = new TickImpl(sSymbol); // convert it k.ask = (decimal)q.dAsk; k.bid = (decimal)q.dBid; k.trade = (decimal)q.dLast; k.bs = q.lBidSize; k.os = q.lAskSize; k.size = q.lLastSize; DateTime now = esig.GetAppTime; k.time = Util.ToTLTime(now); k.date = Util.ToTLDate(now); if (isPaperTradeEnabled) { ptt.newTick(k); } // send it tl.newTick(k); } catch (Exception ex) { if (GotDebug != null) { GotDebug(DebugImpl.Create(ex.Message + ex.StackTrace, DebugLevel.Debug)); } } }
public void FillBidAskPartial() { PapertradeTracker ptt = new PapertradeTracker(); PositionTracker pt = new PositionTracker(); ptt.UseBidAskFills = true; ptt.GotFillEvent += new FillDelegate(pt.GotFill); foreach (bool side in new bool[] { true, false }) { pt.Clear(); Order o = new MarketOrder("IBM", side, 1000); int size = o.size; o.id = 1; ptt.sendorder(o); Tick k = TickImpl.NewQuote("IBM", 100, 101, 400, 400, "", ""); ptt.newTick(k); // partial fill ptt.newTick(k); // partial fill ptt.newTick(k); // partial fill, completed Expect(pt["IBM"].Size, Is.EqualTo(size)); } }
public void TestTradeFill() { ptt = new PapertradeTracker(); ptt.SendDebugEvent += new DebugDelegate(debug); ptt.UseBidAskFills = false; fills = 0; pt = new PositionTracker(); const string SYM = "TST"; ptt.GotFillEvent += new FillDelegate(ptt_GotFillEvent); ptt.GotOrderEvent += new OrderDelegate(ptt_GotOrderEvent); // send an order ptt.sendorder(new BuyMarket(SYM, 1000)); // verify it did not fill Assert.AreEqual(0, pt[SYM].Size); // send a tick ptt.newTick(TickImpl.NewTrade(SYM, 10, 100)); // verify it fills Assert.AreEqual(100, pt[SYM].Size); }
// respond to redi events void VBRediCache_CacheEvent(int action, int row) { int err = 0; object cv = new object(); decimal dv = 0; int iv = 0; switch (action) { case 1: //CN_SUBMIT { try { v("for submit row: " + row.ToString() + " action: " + action.ToString()); int i = row != 0 ? row - 1 : row; Tick k = new TickImpl(); _cc.VBGetCell(i, "SYMBOL", ref cv, ref err); v("getcellerr: " + err.ToString()); if (!(cv == null)) { k.symbol = cv.ToString(); } _cc.VBGetCell(i, "LastPrice", ref cv, ref err); if (!(cv == null)) { if (decimal.TryParse(cv.ToString(), out dv)) { k.trade = dv; } } _cc.VBGetCell(i, "BidPrice", ref cv, ref err); if (!(cv == null)) { if (decimal.TryParse(cv.ToString(), out dv)) { k.bid = dv; } } _cc.VBGetCell(i, "AskPrice", ref cv, ref err); if (!(cv == null)) { if (decimal.TryParse(cv.ToString(), out dv)) { k.ask = dv; } } _cc.VBGetCell(i, "LastSize", ref cv, ref err); if (!(cv == null)) { if (int.TryParse(cv.ToString(), out iv)) { k.size = iv; } } _cc.VBGetCell(i, "BidSize", ref cv, ref err); if (!(cv == null)) { if (int.TryParse(cv.ToString(), out iv)) { k.bs = iv; } } _cc.VBGetCell(i, "AskSize", ref cv, ref err); if (!(cv == null)) { if (int.TryParse(cv.ToString(), out iv)) { k.os = iv; } } k.date = Util.ToTLDate(DateTime.Now); k.time = Util.DT2FT(DateTime.Now); // fill papertrade orders first if (isPaperTradeEnabled) { ptt.newTick(k); } tl.newTick(k); } catch (Exception exc) { debug(exc.Message); } } break; /* * case 4 : //CN_INSERT * break; * */ case 5: // CN_UPDATE { try { if (TickDebugVerbose) { v("for update row: " + row.ToString() + " action: " + action.ToString()); } int i = row; Tick k = new TickImpl(); _cc.VBGetCell(i, "SYMBOL", ref cv, ref err); if (TickDebugVerbose) { v("getcellerr: " + err.ToString()); } if (!(cv == null)) { k.symbol = cv.ToString(); } _cc.VBGetCell(i, "LastPrice", ref cv, ref err); if (!(cv == null)) { if (decimal.TryParse(cv.ToString(), out dv)) { k.trade = dv; k.size = 1; // this code is just to make everything else working, i.e. Last, High and Low. } } _cc.VBGetCell(i, "BidPrice", ref cv, ref err); if (!(cv == null)) { if (decimal.TryParse(cv.ToString(), out dv)) { k.bid = dv; } } _cc.VBGetCell(i, "AskPrice", ref cv, ref err); if (!(cv == null)) { if (decimal.TryParse(cv.ToString(), out dv)) { k.ask = dv; } } //_cc.VBGetCell(i, "LastSize", ref cv, ref err); //if (!(cv == null)) //{ // if (int.TryParse(cv.ToString(), out iv)) // k.size = iv; //} _cc.VBGetCell(i, "BidSize", ref cv, ref err); if (!(cv == null)) { if (int.TryParse(cv.ToString(), out iv)) { k.bs = iv; } } _cc.VBGetCell(i, "AskSize", ref cv, ref err); if (!(cv == null)) { if (int.TryParse(cv.ToString(), out iv)) { k.os = iv; } } k.date = Util.ToTLDate(DateTime.Now); k.time = Util.DT2FT(DateTime.Now); tl.newTick(k); } catch (Exception exc) { debug(exc.Message); } } break; /* * case 7: // CN_REMOVING * break; * case 8 : // CN_REMOVED * break; */ } }
public void FireTick(string[] actualData) { if (actualData.Length < 66) { return; } try { if (actualData[0] == "F") { return; } Tick tick = new TickImpl(); tick.date = Util.ToTLDate(); DateTime now; int local = Util.ToTLTime(); if (DateTime.TryParse(actualData[65], out now)) { tick.time = Util.DT2FT(now); if (ReportLatency) { Int64 latency = 0; if (lastticktime != 0) { latency = DateTime.Now.Ticks - lastticktime; } lastticktime = now.Ticks; latencyavg = (latency + latencyavg) / 2; tickssincelastlatencyreport++; // test for peak if (latency > peaklatency) { peaklatency = latency; } // test for report if (tickssincelastlatencyreport > 500000) { // convert to ms double latencyms = latencyavg / 10000; double peakms = peaklatency / 10000; debug(string.Format("latency (ms) avg {0:N1} peak: {0:N1}", latencyms, peaklatency)); tickssincelastlatencyreport = 0; latencyavg = 0; } } } else { tick.time = local; } // see if user has tick ignoring enabled //(this is because in early AM iqfeed will frequently send ticks with yesterday time stamps if (usebeforeafterignoretime) { // ensure that ordering works across multiple days if (lasttickdate != tick.date) { lasttickordertime = 0; lasttickdate = tick.date; } // see if tick should be ignored if ((local < IfBeforeTimeUseIgnoreAfter) && (tick.time > IgnoreAfterTimeWithBefore)) { return; } // allow ignoring for ignoring other ticks that are out of order else if (ignoreoutoforder && (tick.time < lasttickordertime)) { return; } lasttickordertime = tick.time; } int v = 0; if (int.TryParse(actualData[64], out v)) { tick.oe = getmarket(v); } if (int.TryParse(actualData[63], out v)) { tick.be = getmarket(v); } if (int.TryParse(actualData[62], out v)) { tick.ex = getmarket(v); } tick.symbol = actualData[1]; tick.bid = Convert.ToDecimal(actualData[10]); tick.ask = Convert.ToDecimal(actualData[11]); tick.trade = Convert.ToDecimal(actualData[3]); tick.size = Convert.ToInt32(actualData[7]); tick.BidSize = Convert.ToInt32(actualData[12]); tick.AskSize = Convert.ToInt32(actualData[13]); // get symbol index for custom data requests int idx = _highs.getindex(tick.symbol); // update custom data (tryparse is faster than convert) decimal d = 0; if (decimal.TryParse(actualData[8], out d)) { _highs[idx] = d; } if (decimal.TryParse(actualData[9], out d)) { _lows[idx] = d; } if (isPaperTradeEnabled) { ptt.newTick(tick); } tl.newTick(tick); } catch (Exception ex) { debug("Tick error: " + string.Join(",", actualData)); debug(ex.Message + ex.StackTrace); } }
void doquote(ref structSTIQuoteUpdate q) { Tick k = new TickImpl(q.bstrSymbol); k.bid = (decimal)q.fBidPrice; k.ask = (decimal)q.fAskPrice; k.bs = q.nBidSize / 100; k.os = q.nAskSize / 100; k.ex = GetExPretty(q.bstrExch); k.be = GetExPretty(q.bstrBidExch); k.oe = GetExPretty(q.bstrAskExch); int now = Convert.ToInt32(q.bstrUpdateTime); k.date = Util.ToTLDate(DateTime.Now); //int sec = now % 100; k.time = now; // we don't want to simply return on out-of-order ticks because it'll prevent processing // of the mdx messages further in this function. if (!IgnoreOutOfOrderTicks || (k.time > _lasttime)) { _lasttime = k.time; k.trade = (decimal)q.fLastPrice; k.size = q.nLastSize; // execute orders if papertrade is enabled if (isPaperTradeEnabled) { ptt.newTick(k); } // notify clients of tick if (!_imbalance || (_imbalance && k.isValid)) { tl.newTick(k); } } ///////////////////////// // MDX Processing ///////////////////////// if (q.nMdxMsgType == 1) { if (VerboseDebugging) { debug(q.bstrUpdateTime + " Received Regulatory Imbalance for: " + q.bstrSymbol + " ValidIntradayMarketImb: " + q.bValidIntradayMktImb + " ValidMktImb: " + q.bValidMktImb + " Imbalance: " + q.nImbalance + " iMktImbalance: " + q.nIntradayMktImbalance + " MktImbalance: " + q.nMktImbalance); } int time; if (int.TryParse(q.bstrUpdateTime, out time)) { Imbalance imb = new ImbalanceImpl(q.bstrSymbol, GetExPretty(q.bstrExch), q.nIntradayMktImbalance, time, 0, 0, 0); tl.newImbalance(imb); } } else if (q.nMdxMsgType == 2) { if (VerboseDebugging) { debug(q.bstrUpdateTime + " Received Informational Imbalance for: " + q.bstrSymbol + " ValidIntradayMarketImb: " + q.bValidIntradayMktImb + " ValidMktImb: " + q.bValidMktImb + " Imbalance: " + q.nImbalance + " iMktImbalance: " + q.nIntradayMktImbalance + " MktImbalance: " + q.nMktImbalance); } int time; if (int.TryParse(q.bstrUpdateTime, out time)) { Imbalance imb = new ImbalanceImpl(q.bstrSymbol, GetExPretty(q.bstrExch), 0, time, 0, 0, q.nIntradayMktImbalance); tl.newImbalance(imb); } } else if (q.nMdxMsgType == 3) { if (VerboseDebugging) { debug(q.bstrUpdateTime + " Received Halt/Delay for: " + q.bstrSymbol + " Status: " + q.bstrHaltResumeStatus + " Reason: " + q.bstrHaltResumeReason); } int time; if (int.TryParse(q.bstrUpdateTime, out time)) { HaltResume h = new HaltResumeImpl(q.bstrSymbol, GetExPretty(q.bstrExch), time, q.bstrHaltResumeStatus, q.bstrHaltResumeReason); for (int clientNumber = 0; clientNumber < tl.NumClients; clientNumber++) { tl.TLSend(HaltResumeImpl.Serialize(h), MessageTypes.HALTRESUME, clientNumber); } } } else if (q.nMdxMsgType == 4) { if (VerboseDebugging) { debug(q.bstrUpdateTime + " Received Indication for: " + q.bstrSymbol + " ValidIndicators: " + q.bValidIndicators + " IndicatorHigh: " + q.fIndicatorHigh + " IndicatorLow: " + q.fIndicatorLow); } int time; if (int.TryParse(q.bstrUpdateTime, out time)) { Indication ind = new IndicationImpl(q.bstrSymbol, GetExPretty(q.bstrExch), time, q.bValidIndicators, (decimal)q.fIndicatorHigh, (decimal)q.fIndicatorLow); for (int clientNumber = 0; clientNumber < tl.NumClients; clientNumber++) { tl.TLSend(IndicationImpl.Serialize(ind), MessageTypes.INDICATION, clientNumber); } } } }
public void TestBidAsk() { ptt = new PapertradeTracker(); pt = new PositionTracker(); fills = 0; const string SYM = "TST"; ptt.SendDebugEvent += new DebugDelegate(debug); ptt.GotFillEvent += new FillDelegate(ptt_GotFillEvent); ptt.GotOrderEvent += new OrderDelegate(ptt_GotOrderEvent); // enable bid ask fills ptt.UseBidAskFills = true; // send an order ptt.sendorder(new BuyMarket(SYM, 1000)); // verify it did not fill Assert.AreEqual(0, pt[SYM].Size); // send a tick ptt.newTick(TickImpl.NewTrade(SYM, 10, 100)); // verify it did not fill Assert.AreEqual(0, pt[SYM].Size); // send bid ptt.newTick(TickImpl.NewBid(SYM, 10, 100)); // verify it did not fill Assert.AreEqual(0, pt[SYM].Size); // send ask ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); // verify it fills Assert.AreEqual(100, pt[SYM].Size); Assert.AreEqual(1, fills); // fill rest of the order ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); Assert.AreEqual(10, fills); Assert.AreEqual(1000, pt[SYM].Size); // send a bunch more ticks and ensure nothing else is filled ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); ptt.newTick(TickImpl.NewAsk(SYM, 12, 100)); Assert.AreEqual(0, ptt.QueuedOrders.Length); Assert.AreEqual(10, fills); Assert.AreEqual(1000, pt[SYM].Size); }