public Order BestBidOrOffer(string sym, bool side, Account Account) { Order best = new OrderImpl(); if (!MasterOrders.ContainsKey(Account)) { return(best); } List <Order> orders = MasterOrders[Account]; for (int i = 0; i < orders.Count; i++) { Order o = orders[i]; if (o.symbol != sym) { continue; } if (o.side != side) { continue; } if (!best.isValid) { best = new OrderImpl(o); continue; } Order test = BestBidOrOffer(best, o); if (test.isValid) { best = new OrderImpl(test); } } return(best); }
public Order BestBidOrOffer(string sym, bool side, Account Account) { Order best = new OrderImpl(); if (!MasterOrders.ContainsKey(Account)) { return(best); } foreach (OrderImpl o in MasterOrders[Account]) { if (o.symbol != sym) { continue; } if (o.Side != side) { continue; } if (!best.isValid) { best = new OrderImpl(o); continue; } Order test = BestBidOrOffer(best, o); if (test.isValid) { best = new OrderImpl(test); } } return(best); }
public Order BestBidOrOffer(string symbol, bool side) { Order best = new OrderImpl(); Order next = new OrderImpl(); Account[] accts = new Account[MasterOrders.Count]; MasterOrders.Keys.CopyTo(accts, 0); for (int i = 0; i < accts.Length; i++) { Account a = accts[i]; // get our first order if (!best.isValid) { // if we don't have a valid one yet, check this account best = new OrderImpl(BestBidOrOffer(symbol, side, a)); continue; // keep checking the accounts till we find a valid one } // now we have our first order, which will be best if we can't find a second one next = new OrderImpl(BestBidOrOffer(symbol, side, a)); if (!next.isValid) { continue; // keep going till we have a second order } best = BestBidOrOffer(best, next); // when we have two, compare and get best // then keep fetching next valid order to see if it's better } return(best); // if there's no more orders left, this is best }
/// <summary> /// Deserialize string to Order /// </summary> /// <returns></returns> public new static Order Deserialize(string message) { Order o = null; string[] rec = message.Split(','); // get the record if (rec.Length < 17) { throw new InvalidOrder(); } bool side = Convert.ToBoolean(rec[(int)OrderField.Side]); int size = Convert.ToInt32(rec[(int)OrderField.Size]); decimal oprice = Convert.ToDecimal(rec[(int)OrderField.Price]); decimal ostop = Convert.ToDecimal(rec[(int)OrderField.Stop]); string sym = rec[(int)OrderField.Symbol]; o = new OrderImpl(sym, side, size); o.price = oprice; o.stopp = ostop; o.comment = rec[(int)OrderField.Comment]; o.Account = rec[(int)OrderField.Account]; o.ex = rec[(int)OrderField.Exchange]; o.LocalSymbol = rec[(int)OrderField.LocalSymbol]; o.Currency = (CurrencyType)Enum.Parse(typeof(CurrencyType), rec[(int)OrderField.Currency]); o.Security = (SecurityType)Enum.Parse(typeof(SecurityType), rec[(int)OrderField.Security]); o.id = Convert.ToUInt32(rec[(int)OrderField.OrderID]); o.TIF = rec[(int)OrderField.OrderTIF]; o.trail = Convert.ToDecimal(rec[(int)OrderField.Trail]); o.date = Convert.ToInt32(rec[(int)OrderField.oDate]); o.time = Convert.ToInt32(rec[(int)OrderField.oTime]); return(o); }
public void Defaults() { // assert that a default order is: // not valid, not filled OrderImpl o = new OrderImpl(); Assert.That(!o.isValid); Assert.That(!o.isFilled); }
/// <summary> /// track and correct oversells (either by splitting into two orders, or dropping oversell) /// </summary> /// <param name="o"></param> public void sendorder(Order o) { // get original size int osize = o.size; int uosize = o.UnsignedSize; // get existing size int size = _pt[o.symbol].Size; int upsize = _pt[o.symbol].UnsignedSize; // check for overfill/overbuy bool over = (o.size * size < -1) && (o.UnsignedSize > Math.Abs(size)) && (upsize >= MinLotSize); // detect if (over) { // determine correct size int oksize = _pt[o.symbol].FlatSize; // adjust o.size = Calc.Norm2Min(oksize, MinLotSize); // send sonow(o); // count osa++; // notify debug(o.symbol + " oversell detected on pos: " + size + " order adjustment: " + osize + "->" + size + " " + o.ToString()); // see if we're splitting if (Split) { // calculate new size int nsize = Calc.Norm2Min(Math.Abs(uosize - Math.Abs(oksize)), MinLotSize); // adjust side nsize *= (o.side ? 1 : -1); // create order Order newo = new OrderImpl(o); newo.size = nsize; newo.id = _idt.AssignId; if (_orgid2splitid.ContainsKey(o.id)) { _orgid2splitid[o.id] = newo.id; } else { _orgid2splitid.Add(o.id, newo.id); } // send if (nsize != 0) { sonow(newo); } // notify debug(o.symbol + " splitting oversell/overcover: " + o.ToString() + " to 2nd order: " + newo); } } else { sonow(o); } }
private void SrvDoExecute(string msg) // handle an order (= execute request) { Order o = OrderImpl.Deserialize(msg); if (newSendOrderRequest != null) { newSendOrderRequest(o); //request fill } }
void reset() { tks = new TIFTracker_Ticks(); tks.SendCancelEvent += new LongDelegate(tks_SendCancelEvent); tks.SendDebugEvent += new DebugDelegate(tks_SendDebugEvent); tks.SendOrderEvent += new OrderDelegate(tks_SendOrderEvent); lasto = new OrderImpl(); lastcancel = 0; }
public void newOrder(Order o, bool allclients) { for (int i = 0; i < client.Count; i++) // send tick to each client that has subscribed to tick's stock { if ((client[i] != null) && (allclients || (stocks[i].Contains(o.symbol)))) { TLSend(OrderImpl.Serialize(o), MessageTypes.ORDERNOTIFY, i); } } }
public void SplitCancelCopy() { lasto = new OrderImpl(); oc = 0; cancels.Clear(); ost = new OversellTracker(); ost.SendOrderEvent += new OrderDelegate(ost_SendOrderEvent); ost.SendDebugEvent += new DebugDelegate(rt.d); ost.SendCancelEvent += new LongDelegate(ost_SendCancelEvent); ost.Split = true; // take a position ost.GotPosition(new PositionImpl("TST", 100, 300)); // over sell Order o = new SellMarket("TST", 500); o.id = 5; ost.sendorder(o); // verify that only flat was sent Assert.AreEqual(2, oc); Assert.AreEqual(-200, lasto.size); // make sure we've not canceled Assert.AreEqual(0, cancels.Count); // cancel original order ost.sendcancel(5); // ensure two cancels sent Assert.AreEqual(2, cancels.Count); // ensure different cancels Assert.AreEqual(5, cancels[0]); Assert.AreNotEqual(5, cancels[1]); // do it again // take a position ost.GotPosition(new PositionImpl("TST", 100, 300)); // over sell o = new SellMarket("TST", 500); o.id = 10; ost.sendorder(o); // verify that only flat was sent Assert.AreEqual(4, oc); Assert.AreEqual(-200, lasto.size); // make sure we've not canceled Assert.AreEqual(2, cancels.Count); // cancel original order ost.sendcancel(10); // ensure two cancels sent Assert.AreEqual(4, cancels.Count); // ensure different cancels Assert.AreEqual(10, cancels[2]); Assert.AreNotEqual(10, cancels[3]); }
public void MarketOrder() { const string s = "SYM"; OrderImpl o = new OrderImpl(s,100); Assert.That(o.isValid); Assert.That(o.isMarket); Assert.That(!o.isLimit); Assert.That(!o.isStop); Assert.That(!o.isFilled); Assert.That(o.symbol == s); }
/// <summary> /// Generate a stop order for a position, at a specified per-share/contract price /// </summary> /// <param name="p">your position</param> /// <param name="offset">how far away stop is</param> /// <param name="percent">what percent of position to close</param> /// <param name="normalizesize">whether to normalize size to even-lots</param> /// <param name="MINSIZE">size of an even lot</param> /// <returns></returns> public static Order PositionStop(Position p, decimal offset, decimal percent, bool normalizesize, int MINSIZE) { Order o = new OrderImpl(); if (!p.isValid || p.isFlat) { return(o); } decimal price = OffsetPrice(p, Math.Abs(offset) * -1); int size = !normalizesize ? (int)(p.FlatSize * percent) : Norm2Min(p.FlatSize * percent, MINSIZE); o = new StopOrder(p.Symbol, !p.isLong, size, price); return(o); }
/// <summary> /// Sends the order. /// </summary> /// <param name="o">The oorder</param> /// <returns>Zero if succeeded, Broker error code otherwise.</returns> public int SendOrder(Order o) { if (o == null) { return((int)MessageTypes.EMPTY_ORDER); } if (!o.isValid) { return((int)MessageTypes.EMPTY_ORDER); } string m = OrderImpl.Serialize(o); return((int)TLSend(MessageTypes.SENDORDER, m)); }
public void Basics() { Broker broker = new Broker(); broker.GotFill += new FillDelegate(broker_GotFill); broker.GotOrder += new OrderDelegate(broker_GotOrder); OrderImpl o = new OrderImpl(); int error = broker.SendOrderStatus(o); Assert.AreNotEqual((int)MessageTypes.OK,error); Assert.That(orders == 0); Assert.That(fills == 0); o = new BuyMarket(s, 100); broker.SendOrderStatus(o); Assert.That(orders == 1); Assert.That(fills == 0); Assert.That(broker.Execute(TickImpl.NewTrade(s,10,200)) == 1); Assert.That(fills == 1); // test that a limit order is not filled outside the market o = new BuyLimit(s, 100, 9); broker.SendOrderStatus(o); Assert.AreEqual(0, broker.Execute(TickImpl.NewTrade(s, 10, 100))); Assert.That(fills == 1); // redudant but for counting // test that limit order is filled inside the market Assert.AreEqual(1, broker.Execute(TickImpl.NewTrade(s, 8, 100))); Assert.That(fills == 2); OrderImpl x = new OrderImpl(); // test that a market order is filled when opposite book exists o = new SellLimit(s, 100, 11); x = new BuyMarket(s, 100); const string t2 = "trader2"; x.Account = t2; broker.SendOrderStatus(o); broker.SendOrderStatus(x); Assert.AreEqual(3, fills); // test that a market order is not filled when no book exists // on opposite side // clear existing orders broker.CancelOrders(); o = new SellMarket(s, 100); o.Account = t2; broker.SendOrderStatus(o); Assert.AreEqual(3, fills); }
private void SrvDoExecute(string msg) // handle an order (= execute request) { if (this.InvokeRequired) { this.Invoke(new DebugDelegate(SrvDoExecute), new object[] { msg }); } else { Order o = OrderImpl.Deserialize(msg); if (newSendOrderRequest != null) { newSendOrderRequest(o); //request fill } } }
public void newOrder(Order o, bool allclients) { if (this.InvokeRequired) { this.Invoke(new tlneworderdelegate(newOrder), new object[] { o, allclients }); } else { for (int i = 0; i < client.Count; i++) { if ((client[i] != null) && (client[i] != "") && (stocks[i].Contains(o.symbol) || allclients)) { WMUtil.SendMsg(OrderImpl.Serialize(o), MessageTypes.ORDERNOTIFY, Handle, client[i]); } } } }
public void TestNormalExit() { lasto = new OrderImpl(); oc = 0; ost = new OversellTracker(); ost.SendOrderEvent += new OrderDelegate(ost_SendOrderEvent); ost.SendDebugEvent += new DebugDelegate(rt.d); // take a position ost.GotPosition(new PositionImpl("TST",100,500)); // sell ost.sendorder(new SellMarket("TST", 500)); // verify that was sent Assert.AreEqual(1, oc); Assert.AreEqual(-500, lasto.size); }
/////////////////////////////////////////////////////////////////////// // TradeLink Hooks /////////////////////////////////////////////////////////////////////// public override void GotTick(Tick tick) { if (RequestedForSymbol.getindex(tick.symbol) == GenericTracker.UNKNOWN || RequestedForSymbol[tick.symbol] == false) { RequestedForSymbol.addindex(tick.symbol, true); // send opening order Order Opener = new OrderImpl(tick.symbol, true, 100); sendorder(Opener); // send closing order Order Closer = new MOCOrder(tick.symbol, false, 100); sendorder(Closer); senddebug("Sent Order: " + Closer); } }
public void DoubleBasicWithFlat() { long id = 1; sho = new REGSHO_ShortTracker(); sho.SendDebugEvent += new DebugDelegate(sho_SendDebugEvent); sho.VerboseDebugging = true; Order o = new OrderImpl(); // take a position sho.GotPosition(new PositionImpl(sym, 89.7m, 100)); // accept two exits o = new SellStop(sym, 100, 89.65m, id++); long stop1 = o.id; Assert.IsFalse(sho.isOrderShort(o), "entry1: first sell was incorrectly short"); sho.GotOrder(o); o = new SellLimit(sym, 100, 89.75m, id++); long profit1 = o.id; Assert.IsTrue(sho.isOrderShort(o), "entry1: second sell was incorrectly sell"); sho.GotOrder(o); // flat o = new SellStop(sym, 100, 89.65m, stop1); o.Fill(TickImpl.NewTrade(sym,89.62m,100)); sho.GotFill((Trade)o); sho.GotCancel(profit1); // do again // take a position o = new BuyMarket(sym,100); o.id = id++; o.Fill(TickImpl.NewTrade(sym, 89.64m, 100)); sho.GotFill((Trade)o); // accept two exits o = new SellStop(sym, 100, 89.65m, id++); Assert.IsFalse(sho.isOrderShort(o), "entry2: first sell was incorrectly short"); sho.GotOrder(o); o = new SellLimit(sym, 100, 89.75m, id++); Assert.IsTrue(sho.isOrderShort(o), "entry2: second sell was incorrectly NOT short"); sho.GotOrder(o); }
public Order BestBidOrOffer(string sym, bool side,Account Account) { Order best = new OrderImpl(); if (!MasterOrders.ContainsKey(Account)) return best; foreach (OrderImpl o in MasterOrders[Account]) { if (o.symbol != sym) continue; if (o.Side != side) continue; if (!best.isValid) { best = new OrderImpl(o); continue; } Order test = BestBidOrOffer(best, o); if (test.isValid) best = new OrderImpl(test); } return best; }
public void sendorder(Order o) { // get original size int osize = o.size; int uosize = o.UnsignedSize; // get existing size int size = _pt[o.symbol].Size; // check for overfill/overbuy bool over = o.size * size < -1; // detect if (over) { // determine correct size int oksize = _pt[o.symbol].FlatSize; // adjust o.size = oksize; // send sonow(o); // count osa++; // notify debug(o.symbol + " oversell detected: " + osize + ">" + size + " adjusted to: " + o.ToString()); // see if we're splitting if (Split) { // calculate new size int nsize = Math.Abs(uosize - Math.Abs(oksize)); // adjust side nsize *= (o.side ? 1 : -1); // create order Order newo = new OrderImpl(o); newo.size = nsize; // send sonow(newo); // notify debug(o.symbol + " splitting oversell/overcover to 2nd order: " + newo); } } else { sonow(o); } }
public void SplitWithPartialFillRoundMinsize100() { lasto = new OrderImpl(); oc = 0; ost = new OversellTracker(); ost.SendOrderEvent += new OrderDelegate(ost_SendOrderEvent); ost.SendDebugEvent += new DebugDelegate(rt.d); ost.MinLotSize = 100; ost.Split = true; // take a position ost.GotPosition(new PositionImpl("TST", 100, 58)); // over sell Order o = new SellMarket("TST", 100); o.id = 1; ost.sendorder(o); // verify that flat and adjustment were sent Assert.AreEqual(1, oc); Assert.AreEqual(-100, lasto.size); }
/// <summary> /// Deserialize string to Order /// </summary> /// <returns></returns> public new static Order Deserialize(string message) { Order o = null; string[] rec = message.Split(','); // get the record if (rec.Length < 17) { throw new InvalidOrder(); } bool side = Convert.ToBoolean(rec[(int)OrderField.Side]); int size = Math.Abs(Convert.ToInt32(rec[(int)OrderField.Size])) * (side ? 1 : -1); decimal oprice = Convert.ToDecimal(rec[(int)OrderField.Price], System.Globalization.CultureInfo.InvariantCulture); decimal ostop = Convert.ToDecimal(rec[(int)OrderField.Stop], System.Globalization.CultureInfo.InvariantCulture); string sym = rec[(int)OrderField.Symbol]; o = new OrderImpl(sym, side, size); o.price = oprice; o.stopp = ostop; o.comment = rec[(int)OrderField.Comment]; o.Account = rec[(int)OrderField.Account]; o.ex = rec[(int)OrderField.Exchange]; o.LocalSymbol = rec[(int)OrderField.LocalSymbol]; o.Currency = (CurrencyType)Enum.Parse(typeof(CurrencyType), rec[(int)OrderField.Currency]); o.Security = (SecurityType)Enum.Parse(typeof(SecurityType), rec[(int)OrderField.Security]); o.id = Convert.ToInt64(rec[(int)OrderField.OrderID]); OrderInstructionType oit = OrderInstructionType.DAY; if (Enum.TryParse <OrderInstructionType>(rec[(int)OrderField.OrderTIF], out oit)) { o.ValidInstruct = oit; } decimal trail = 0; if (decimal.TryParse(rec[(int)OrderField.Trail], System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.InvariantCulture, out trail)) { o.trail = trail; } o.date = Convert.ToInt32(rec[(int)OrderField.oDate]); o.time = Convert.ToInt32(rec[(int)OrderField.oTime]); return(o); }
public Order BestBidOrOffer(string symbol,bool side) { Order best = new OrderImpl(); Order next = new OrderImpl(); foreach (Account a in MasterOrders.Keys) { // get our first order if (!best.isValid) { // if we don't have a valid one yet, check this account best = new OrderImpl(BestBidOrOffer(symbol,side,a)); continue; // keep checking the accounts till we find a valid one } // now we have our first order, which will be best if we can't find a second one next = new OrderImpl(BestBidOrOffer(symbol,side,a)); if (!next.isValid) continue; // keep going till we have a second order best = BestBidOrOffer(best, next); // when we have two, compare and get best // then keep fetching next valid order to see if it's better } return best; // if there's no more orders left, this is best }
private void SrvDoExecute(string msg) // handle an order (= execute request) { if (this.InvokeRequired) { this.Invoke(new DebugDelegate(SrvDoExecute), new object[] { msg }); } else { try { Order o = OrderImpl.Deserialize(msg); if (newSendOrderRequest != null) { newSendOrderRequest(o); //request fill } } catch (Exception ex) { debug("Error unpacking order: " + msg + " " + ex.Message + ex.StackTrace); } } }
// takes two orders and returns the better one // if orders aren't for same side or symbol or not limit, returns invalid order // if orders are equally good, adds them together public Order BestBidOrOffer(Order first, Order second) { if ((first.symbol != second.symbol) || (first.side != second.side) || !first.isLimit || !second.isLimit) { return(new OrderImpl()); // if not comparable return an invalid order } if ((first.side && (first.price > second.price)) || // if first is better, use it (!first.side && (first.price < second.price))) { return(new OrderImpl(first)); } else if ((first.side && (first.price < second.price)) || // if second is better, use it (!first.side && (first.price > second.price))) { return(new OrderImpl(second)); } // if order is matching then add the sizes OrderImpl add = new OrderImpl(first); add.size = add.UnsignedSize + second.UnsignedSize * (add.side? 1 : -1); return(add); }
/// <summary> /// Sends the order. /// </summary> /// <param name="o">The oorder</param> /// <returns>Zero if succeeded</returns> public int SendOrder(Order o) { if (o == null) { return((int)MessageTypes.EMPTY_ORDER); } if (!o.isValid) { return((int)MessageTypes.EMPTY_ORDER); } string m = OrderImpl.Serialize(o); try { TLSend(MessageTypes.SENDORDER, m); return(0); } catch (SocketException ex) { debug("Exception sending order: " + o.ToString() + " " + ex.SocketErrorCode + ex.Message + ex.StackTrace); return((int)MessageTypes.UNKNOWN_ERROR); } }
public void Basic() { long id = 1; sho = new REGSHO_ShortTracker(); sho.SendDebugEvent+=new DebugDelegate(rt.d); Order o = new OrderImpl(); // take a position sho.GotPosition(new PositionImpl(sym,100,300)); // accept two exits o = new SellLimit(sym, 100, 200, id++); Assert.IsFalse(sho.isOrderShort(o)); sho.GotOrder(o); o = new SellLimit(sym, 200, 105, id++); Assert.IsFalse(sho.isOrderShort(o)); sho.GotOrder(o); // send another short o = new SellStop(sym, 300, 99); Assert.IsTrue(sho.isOrderShort(o)); }
public void BasicStopAndLimit() { long id = 1; sho = new REGSHO_ShortTracker(); sho.SendDebugEvent += new DebugDelegate(rt.d); sho.VerboseDebugging = true; Order o = new OrderImpl(); // take a position o = new BuyLimit(sym, 100, 21.18m, id++); o.Account = ACCT; Assert.IsFalse(sho.isOrderShort(o), "entry buy never a short."); sho.GotOrder(o); Assert.IsTrue(o.Fill(TickImpl.NewTrade(sym,21.14m,100)),"unable to fill order"); Trade t = (Trade)o; Assert.IsTrue(t.isValid && t.isFilled, "not a valid trade"); sho.GotFill(t); // accept two exits o = new SellStop(sym, 100, 21.09m, id++); o.Account = ACCT; Assert.IsFalse(sho.isOrderShort(o),"first exit was wrongly a short"); sho.GotOrder(o); o = new SellLimit(sym, 100, 21.19m, id++); o.Account = ACCT; Assert.IsTrue(sho.isOrderShort(o), "second exit was wrongly a sell"); sho.GotOrder(o); }
/// <summary> /// Generate a stop order for a position, at a specified per-share/contract price /// </summary> /// <param name="p">your position</param> /// <param name="offset">how far away stop is</param> /// <param name="percent">what percent of position to close</param> /// <param name="normalizesize">whether to normalize size to even-lots</param> /// <param name="MINSIZE">size of an even lot</param> /// <returns></returns> public static Order PositionStop(Position p, decimal offset, decimal percent, bool normalizesize, int MINSIZE) { Order o = new OrderImpl(); if (!p.isValid || p.isFlat) return o; decimal price = OffsetPrice(p, Math.Abs(offset)*-1); int size = !normalizesize ? (int)(p.FlatSize * percent) : Norm2Min(p.FlatSize * percent, MINSIZE); o = new StopOrder(p.Symbol, !p.isLong, size, price); return o; }
protected override void WndProc(ref System.Windows.Forms.Message m) { long result = 0; TradeLinkMessage tlm = WMUtil.ToTradeLinkMessage(ref m); if (tlm == null) // if it's not a WM_COPYDATA message { base.WndProc(ref m); // let form process it return; // we're done } string msg = tlm.body; string[] r = msg.Split(','); switch (tlm.type) { case MessageTypes.ORDERCANCELRESPONSE: if (gotOrderCancel != null) { gotOrderCancel(Convert.ToUInt32(msg)); } break; case MessageTypes.TICKNOTIFY: Tick t = TickImpl.Deserialize(msg); if (t.isTrade) { try { if (t.trade > chighs[t.symbol]) { chighs[t.symbol] = t.trade; } if (t.trade < clows[t.symbol]) { clows[t.symbol] = t.trade; } } catch (KeyNotFoundException) { chighs.Add(t.symbol, 0); clows.Add(t.symbol, decimal.MaxValue); } } if (gotTick != null) { gotTick(t); } break; case MessageTypes.EXECUTENOTIFY: // date,time,symbol,side,size,price,comment Trade tr = TradeImpl.Deserialize(msg); if (gotFill != null) { gotFill(tr); } break; case MessageTypes.ORDERNOTIFY: Order o = OrderImpl.Deserialize(msg); if (gotOrder != null) { gotOrder(o); } break; case MessageTypes.POSITIONRESPONSE: Position pos = PositionImpl.Deserialize(msg); if (gotPosition != null) { gotPosition(pos); } break; case MessageTypes.ACCOUNTRESPONSE: if (gotAccounts != null) { gotAccounts(msg); } break; case MessageTypes.FEATURERESPONSE: string[] p = msg.Split(','); List <MessageTypes> f = new List <MessageTypes>(); foreach (string s in p) { try { f.Add((MessageTypes)Convert.ToInt32(s)); } catch (Exception) { } } if (gotSupportedFeatures != null) { gotSupportedFeatures(f.ToArray()); } break; case MessageTypes.IMBALANCERESPONSE: Imbalance i = ImbalanceImpl.Deserialize(msg); if (gotImbalance != null) { gotImbalance(i); } break; } result = 0; m.Result = (IntPtr)result; }
/// <summary> /// Deserialize string to Order /// </summary> /// <returns></returns> public new static Order Deserialize(string message) { Order o = null; string[] rec = message.Split(','); // get the record if (rec.Length < 17) throw new InvalidOrder(); bool side = Convert.ToBoolean(rec[(int)OrderField.Side]); int size = Convert.ToInt32(rec[(int)OrderField.Size]); decimal oprice = Convert.ToDecimal(rec[(int)OrderField.Price]); decimal ostop = Convert.ToDecimal(rec[(int)OrderField.Stop]); string sym = rec[(int)OrderField.Symbol]; o = new OrderImpl(sym, side, size); o.price = oprice; o.stopp = ostop; o.comment = rec[(int)OrderField.Comment]; o.Account = rec[(int)OrderField.Account]; o.ex = rec[(int)OrderField.Exchange]; o.LocalSymbol = rec[(int)OrderField.LocalSymbol]; o.Currency = (CurrencyType)Enum.Parse(typeof(CurrencyType), rec[(int)OrderField.Currency]); o.Security = (SecurityType)Enum.Parse(typeof(SecurityType), rec[(int)OrderField.Security]); o.id = Convert.ToUInt32(rec[(int)OrderField.OrderID]); o.TIF = rec[(int)OrderField.OrderTIF]; o.trail = Convert.ToDecimal(rec[(int)OrderField.Trail]); o.date = Convert.ToInt32(rec[(int)OrderField.oDate]); o.time = Convert.ToInt32(rec[(int)OrderField.oTime]); return o; }
void m_OrderClient_OnSubmit(MbtOpenOrder pOrd) { OrderImpl o = new OrderImpl(pOrd.Symbol,pOrd.Quantity); o.side = pOrd.BuySell == MBConst.VALUE_BUY; o.price = (decimal)pOrd.Price; o.stopp = (decimal)pOrd.StopLimit; o.TIF = pOrd.TimeInForce == MBConst.VALUE_DAY ? "DAY" : "GTC"; o.time = Util.ToTLTime(pOrd.UTCDateTime); o.date = Util.ToTLDate(pOrd.UTCDateTime); o.sec = pOrd.UTCDateTime.Second; o.trail = (decimal)pOrd.TrailingOffset; //o.ex = pOrd.Route; o.id = Convert.ToUInt32(pOrd.OrderNumber); tl.newOrder(o); }
public void SerializationAndDeserialization() { // create an order const string s = "TST"; const string x = "NYSE"; const string a = "ACCOUNT"; const string u = "COMMENT"; const string ot = "GTC"; const decimal p = 10; const int z = 100; const CurrencyType c = CurrencyType.USD; const SecurityType t = SecurityType.STK; Order o = new OrderImpl(s, z); o.date = 20080718; o.time = 94800; o.price = p; o.Account = a; o.ex = x; o.Currency = c; o.Security = t; o.comment = u; o.TIF = ot; // convert it to a message string msg = OrderImpl.Serialize(o); // convert it back to an object and validate nothing was lost string exception=null; Order n = new OrderImpl(); try { n = OrderImpl.Deserialize(msg); } catch (Exception ex) { exception = ex.ToString(); } Assert.That(exception==null, msg+" "+exception); Assert.That(n.Account == a,n.Account); Assert.That(n.symbol == s,n.symbol); Assert.That(n.size == z,n.size.ToString()); Assert.That(n.price == p,n.price.ToString()); Assert.That(n.Exchange == x,n.Exchange); Assert.That(n.Security == t,n.Security.ToString()); Assert.That(n.Currency == c,n.Currency.ToString()); Assert.That(n.TIF == ot, n.TIF); Assert.That(n.date == o.date, n.date.ToString()); Assert.That(n.time == o.time, n.time.ToString()); }
public void sendorder(Order o) { // get original size int osize = o.size; int uosize = o.UnsignedSize; // get existing size int size = _pt[o.symbol].Size; // check for overfill/overbuy bool over = o.size * size < -1; // detect if (over) { // determine correct size int oksize = _pt[o.symbol].FlatSize; // adjust o.size = oksize; // send sonow(o); // count osa++; // notify debug(o.symbol + " oversell detected: " + osize + ">" + size + " adjusted to: " + o.ToString()); // see if we're splitting if (Split) { // calculate new size int nsize = Math.Abs(uosize - Math.Abs(oksize)); // adjust side nsize *= (o.side ? 1 : -1); // create order Order newo = new OrderImpl(o); newo.size = nsize; // send sonow(newo); // notify debug(o.symbol + " splitting oversell/overcover to 2nd order: " + newo); } } else sonow(o); }
public Order BestBidOrOffer(string sym, bool side,Account Account) { Order best = new OrderImpl(); if (!MasterOrders.ContainsKey(Account)) return best; List<Order> orders = MasterOrders[Account]; for (int i = 0; i<orders.Count; i++) { Order o = orders[i]; if (o.symbol != sym) continue; if (o.side != side) continue; if (!best.isValid) { best = new OrderImpl(o); continue; } Order test = BestBidOrOffer(best, o); if (test.isValid) best = new OrderImpl(test); } return best; }
private void OrderNotifyHandler(object sender, OrderArgs e) { itemOrder iorder = e.ItemOrder; // if (!ls.Contains(iorder.morigtkn)) return; DateTime mdate = ComFucs.GetDate(iorder.mm_date); Order o = new OrderImpl(iorder.msecsym, iorder.IsBuyOrder(), iorder.mqty, Convert.ToDecimal(iorder.mprice), Convert.ToDecimal(iorder.mstopprice), "", mdate.Second + mdate.Minute * 100 + mdate.Hour * 10000, mdate.Second + mdate.Minute * 100 + mdate.Hour * 10000, iorder.morderid); tl.newOrder(o); v(o.symbol + " received order ack for: " + o.ToString()); }
void doorderupdate(ref structSTIOrderUpdate structOrderUpdate) { Order o = new OrderImpl(); o.symbol = structOrderUpdate.bstrSymbol; long id = 0; // see if the order id is unknown if (!long.TryParse(structOrderUpdate.bstrClOrderId, out id)) { // use the norderrecordid as our order id id = (long)structOrderUpdate.nOrderRecordId; // ensure this is not a secondary notification of same order string tmp; if (!idacct.TryGetValue(id, out tmp)) { // save the id debug("manual order: " + id + " " + structOrderUpdate.bstrAccount); idacct.Add(id, structOrderUpdate.bstrAccount); ismanorder.Add(id, true); } } // if this is a cancel notification, pass along if (structOrderUpdate.nOrderStatus == (int)STIOrderStatus.osSTICanceled) { // if it's a cancel, we'll have cancel id rather than order id // get new id long orderid = 0; if (_cancel2order.TryGetValue(id, out orderid)) { tl.newCancel(orderid); if (VerboseDebugging) debug("cancel received for: " + orderid); } else debug("manual cancel sent with id: " + id); return; } // don't notify for same order more than once if (_onotified.Contains(id)) return; if (structOrderUpdate.bstrLogMessage.Contains("REJ")) debug(id+" "+structOrderUpdate.bstrLogMessage); o.id = id; o.size = structOrderUpdate.nQuantity; o.side = structOrderUpdate.bstrSide == "B"; o.price = (decimal)structOrderUpdate.fLmtPrice; o.stopp = (decimal)structOrderUpdate.fStpPrice; o.TIF = structOrderUpdate.bstrTif; o.Account = structOrderUpdate.bstrAccount; o.ex = structOrderUpdate.bstrDestination; long now = Convert.ToInt64(structOrderUpdate.bstrUpdateTime); int xsec = (int)(now % 100); long rem = (now - xsec) / 100; o.time = ((int)(rem % 10000)) * 100 + xsec; o.date = (int)((rem - o.time) / 10000); _onotified.Add(o.id); if (VerboseDebugging) debug("order acknowledgement: " + o.ToString()); tl.newOrder(o); }
// takes two orders and returns the better one // if orders aren't for same side or symbol or not limit, returns invalid order // if orders are equally good, adds them together public Order BestBidOrOffer(Order first,Order second) { if ((first.symbol!= second.symbol) || (first.side!=second.side) || !first.isLimit || !second.isLimit) return new OrderImpl(); // if not comparable return an invalid order if ((first.side && (first.price > second.price)) || // if first is better, use it (!first.side && (first.price < second.price))) return new OrderImpl(first); else if ((first.side && (first.price < second.price)) || // if second is better, use it (!first.side && (first.price > second.price))) return new OrderImpl(second); // if order is matching then add the sizes OrderImpl add = new OrderImpl(first); add.size = add.UnsignedSize + second.UnsignedSize * (add.side? 1 : -1); return add; }
void rightticket(object sender, EventArgs e) { Security s = GetVisibleSecurity(CurrentRow); if (s.Type == SecurityType.IDX) return; string sym = s.Symbol; if ((s.FullName == string.Empty) || (sym == string.Empty)) { return; } Order o = new OrderImpl(s.FullName,0); o.ex = s.DestEx; o.Security = s.Type; o.LocalSymbol = sym; Ticket t = new Ticket(o); t.SendOrder += new OrderDelegate(t_neworder); spillTick +=new TickDelegate(t.newTick); orderStatus+=new OrderStatusDel(t.orderStatus); System.Drawing.Point p = new System.Drawing.Point(MousePosition.X, MousePosition.Y); p.Offset(-315, 20); t.SetDesktopLocation(p.X, p.Y); t.Show(); }
public void Fill() { const string s = "TST"; // market should fill on trade but not on quote OrderImpl o = new BuyMarket(s, 100); Assert.That(o.Fill(TickImpl.NewTrade(s, 9, 100))); Assert.That(!o.Fill(TickImpl.NewBid(s, 8, 100))); // buy limit // limit should fill if order price is inside market o = new BuyLimit(s, 100, 10m); Assert.That(o.Fill(TickImpl.NewTrade(s, 9, 100))); // shouldn't fill outside market o = new BuyLimit(s, 100, 10m); Assert.That(!o.Fill(TickImpl.NewTrade(s, 11, 100))); // sell limit // limit should fill if order price is inside market o = new SellLimit(s, 100, 10m); Assert.That(o.Fill(TickImpl.NewTrade(s, 11, 100))); // shouldn't fill outside market o = new SellLimit(s, 100, 10m); Assert.That(!o.Fill(TickImpl.NewTrade(s, 9, 100))); // buy stop o = new BuyStop(s, 100, 10m); Assert.That(o.Fill(TickImpl.NewTrade(s, 11, 100))); // shouldn't fill outside market o = new BuyStop(s, 100, 10m); Assert.That(!o.Fill(TickImpl.NewTrade(s, 9, 100))); // sell stop o = new SellStop(s, 100, 10m); Assert.That(o.Fill(TickImpl.NewTrade(s, 9, 100))); // shouldn't fill outside market o = new SellStop(s, 100, 10m); Assert.That(!o.Fill(TickImpl.NewTrade(s, 11, 100))); // always fail filling an invalid tick o = new BuyMarket(s, 100); Assert.IsFalse(o.Fill(TickImpl.NewTrade(s, 0, 0))); // always fail filling invalid order o = new BuyLimit(s, 100, 10); OrderImpl x = new OrderImpl(); Assert.IsFalse(o.Fill(x)); // always fail filling an order that doesn't cross market x = new BuyMarket(s, 100); Assert.IsFalse(o.Fill(x)); const string t2 = "trader2"; // suceed on crossing market x = new SellMarket(s,100); x.Account = t2; Assert.IsTrue(o.Fill(x)); // fail when accounts are the same x = new SellMarket(s, 100); x.Account = o.Account; Assert.IsFalse(o.Fill(x)); // fail on match outside of market x = new SellLimit(s, 100, 11); x.Account = t2; Assert.IsFalse(o.Fill(x)); // succeed on limit cross o = new BuyLimit(s, 100, 10); x = new SellLimit(s, 100, 10); x.Account = t2; Assert.IsTrue(o.Fill(x)); // make sure we can stop cross o = new SellStop(s, 100, 10); x = new BuyMarket(s, 100); x.Account = t2; Assert.IsTrue(o.Fill(x)); }
void bwOrder_BWOrderUpdateEvent(object sender, BWOrderStatus BWOrderStatus) { BWOrder bwo = (BWOrder)sender; long id = (long)bwo.CustomID; Order o = new OrderImpl(bwo.Symbol, (int)bwo.Size); o.id = (long)bwo.CustomID; o.side = (bwo.OrderSide == ORDER_SIDE.SIDE_BUY) || (bwo.OrderSide == ORDER_SIDE.SIDE_COVER); o.price = (decimal)bwo.LimitPrice; o.stopp = (decimal)bwo.StopPrice; o.Account = bwo.UserID.ToString(); o.ex = bwo.Venue.ToString(); switch (BWOrderStatus) { case BWOrderStatus.ACCEPTED: { tl.newOrder(o); v(o.symbol + " sent order acknowledgement for: " + o.ToString()); if (_bwOrdIds.ContainsKey(o.id)) { _bwOrdIds[o.id] = bwo.OrderID; } } break; case BWOrderStatus.CANCELED: { tl.newCancel(id); v("sent cancel notification for order: " + id); } break; case BWOrderStatus.REJECTED: { tl.newCancel(id); debug("Rejected: " + bwo.CustomID.ToString() + bwo.RejectReason); } break; } }
void handle(MessageTypes type, string msg) { long result = 0; switch (type) { case MessageTypes.TICKNOTIFY: Tick t; try { _lastheartbeat = DateTime.Now.Ticks; t = TickImpl.Deserialize(msg); } catch (Exception ex) { _tickerrors++; debug("Error processing tick: " + msg); debug("TickErrors: " + _tickerrors); debug("Error: " + ex.Message + ex.StackTrace); break; } if (gotTick != null) { gotTick(t); } break; case MessageTypes.IMBALANCERESPONSE: Imbalance i = ImbalanceImpl.Deserialize(msg); _lastheartbeat = DateTime.Now.Ticks; if (gotImbalance != null) { gotImbalance(i); } break; case MessageTypes.ORDERCANCELRESPONSE: { long id = 0; _lastheartbeat = DateTime.Now.Ticks; if (gotOrderCancel != null) { if (long.TryParse(msg, out id)) { gotOrderCancel(id); } else if (SendDebugEvent != null) { SendDebugEvent("Count not parse order cancel: " + msg); } } } break; case MessageTypes.EXECUTENOTIFY: _lastheartbeat = DateTime.Now.Ticks; // date,time,symbol,side,size,price,comment Trade tr = TradeImpl.Deserialize(msg); if (gotFill != null) { gotFill(tr); } break; case MessageTypes.ORDERNOTIFY: _lastheartbeat = DateTime.Now.Ticks; Order o = OrderImpl.Deserialize(msg); if (gotOrder != null) { gotOrder(o); } break; case MessageTypes.HEARTBEATRESPONSE: { _lastheartbeat = DateTime.Now.Ticks; v("got heartbeat response at: " + _lastheartbeat); _recvheartbeat = !_recvheartbeat; } break; case MessageTypes.POSITIONRESPONSE: try { _lastheartbeat = DateTime.Now.Ticks; Position pos = PositionImpl.Deserialize(msg); if (gotPosition != null) { gotPosition(pos); } } catch (Exception ex) { if (SendDebugEvent != null) { SendDebugEvent(msg + " " + ex.Message + ex.StackTrace); } } break; case MessageTypes.ACCOUNTRESPONSE: _lastheartbeat = DateTime.Now.Ticks; if (gotAccounts != null) { gotAccounts(msg); } break; case MessageTypes.FEATURERESPONSE: _lastheartbeat = DateTime.Now.Ticks; string[] p = msg.Split(','); List <MessageTypes> f = new List <MessageTypes>(); _rfl.Clear(); foreach (string s in p) { try { MessageTypes mt = (MessageTypes)Convert.ToInt32(s); f.Add(mt); _rfl.Add(mt); } catch (Exception) { } } if (gotFeatures != null) { gotFeatures(f.ToArray()); } break; case MessageTypes.SERVERDOWN: if (gotServerDown != null) { gotServerDown(msg); } break; case MessageTypes.SERVERUP: if (gotServerUp != null) { gotServerUp(msg); } break; default: _lastheartbeat = DateTime.Now.Ticks; if (gotUnknownMessage != null) { gotUnknownMessage(type, 0, 0, 0, string.Empty, ref msg); } break; } result = 0; }
void BlackBox_GrayBoxOrderConfirmEventMy(object ob, GrayBoxAPI.BBEventArgs e) { UpdateOrderStatus(e); Order o = new OrderImpl(); OrderList.TryGetValue(e.BBXid, out o); tl.newOrder(o); string orderside = o.side ? "BUY" : "SELL"; debug("Order confirmed " + o.id + " " + o.symbol + " " + orderside + " " + o.size); }
/// <summary> /// Executes any open orders allowed by the specified tick. /// </summary> /// <param name="tick">The tick.</param> /// <returns>the number of orders executed using the tick.</returns> public int Execute(Tick tick) { if (_pendorders == 0) { return(0); } if (!tick.isTrade && !_usebidaskfill) { return(0); } int filledorders = 0; Account[] accts = new Account[MasterOrders.Count]; MasterOrders.Keys.CopyTo(accts, 0); for (int idx = 0; idx < accts.Length; idx++) { // go through each account Account a = accts[idx]; // if account has requested no executions, skip it if (!a.Execute) { continue; } // make sure we have a record for this account if (!MasterTrades.ContainsKey(a.ID)) { MasterTrades.Add(a.ID, new List <Trade>()); } // track orders being removed and trades that need notification List <int> notifytrade = new List <int>(); List <int> remove = new List <int>(); // go through each order in the account for (int i = 0; i < MasterOrders[a].Count; i++) { Order o = MasterOrders[a][i]; //make sure tick is for the right stock if (tick.symbol != o.symbol) { continue; } bool filled = false; if (UseHighLiquidityFillsEOD) { OrderImpl oi = (OrderImpl)o; filled = oi.Fill(tick, _usebidaskfill, false, true); } else if (o.ValidInstruct <= OrderInstructionType.GTC) { filled = o.Fill(tick, _usebidaskfill, false); // fill our trade } else if (o.ValidInstruct == OrderInstructionType.OPG) { // if it's already opened, we missed our shot if (hasopened.Contains(o.symbol)) { continue; } // otherwise make sure it's really the opening if (tick.ex == OPGEX) { // it's the opening tick, so fill it as an opg filled = o.Fill(tick, _usebidaskfill, true); // mark this symbol as already being open hasopened.Add(tick.symbol); } } // other orders fill normally, except MOC orders which are at 4:00PM else if (o.ValidInstruct == OrderInstructionType.MOC) { if (tick.time >= 160000) { filled = o.Fill(tick, _usebidaskfill, false); // fill our trade } } else { filled = o.Fill(tick, _usebidaskfill, false); // fill our trade } if (filled) { // remove filled size from size available in trade tick.size -= o.UnsignedSize; // get copy of trade for recording Trade trade = new TradeImpl((Trade)o); // if trade represents entire requested order, mark order for removal if (trade.UnsignedSize == o.UnsignedSize) { remove.Add(i); } else // otherwise reflect order's remaining size { o.size = (o.UnsignedSize - trade.UnsignedSize) * (o.side ? 1 : -1); } // record trade MasterTrades[a.ID].Add(trade); // mark it for notification notifytrade.Add(MasterTrades[a.ID].Count - 1); // count the trade filledorders++; } } int rmcount = remove.Count; // remove the filled orders for (int i = remove.Count - 1; i >= 0; i--) { MasterOrders[a].RemoveAt(remove[i]); } // unmark filled orders as pending _pendorders -= rmcount; if (_pendorders < 0) { _pendorders = 0; } // notify subscribers of trade if ((GotFill != null) && a.Notify) { for (int tradeidx = 0; tradeidx < notifytrade.Count; tradeidx++) { GotFill(MasterTrades[a.ID][notifytrade[tradeidx]]); } } } return(filledorders); }
void BlackBox_GrayBoxOrderExecuteEventMy(object ob, GrayBoxAPI.BBEventArgs e) { UpdateOrderStatus(e); Order o = new OrderImpl(); OrderList.TryGetValue(e.BBXid, out o); Position p = new PositionImpl( o.symbol, (decimal) e.Price, e.Quantity, (decimal) e.Price, o.Account); string orderside = o.side ? "BUY" : "SELL"; debug("Order executed " + o.id + " " + o.symbol + " " + orderside + " " + o.size); pt.NewPosition(p); }
protected override void WndProc(ref System.Windows.Forms.Message m) { long result = 0; TradeLinkMessage tlm = WMUtil.ToTradeLinkMessage(ref m); if (tlm == null) // if it's not a WM_COPYDATA message { base.WndProc(ref m); // let form process it return; // we're done } string msg = tlm.body; switch (tlm.type) { case MessageTypes.TICKNOTIFY: Tick t; try { t = TickImpl.Deserialize(msg); } catch (Exception ex) { _tickerrors++; debug("Error processing tick: " + msg); debug("TickErrors: " + _tickerrors); debug("Error: " + ex.Message + ex.StackTrace); break; } if (gotTick != null) { gotTick(t); } break; case MessageTypes.IMBALANCERESPONSE: Imbalance i = ImbalanceImpl.Deserialize(msg); if (gotImbalance != null) { gotImbalance(i); } break; case MessageTypes.ORDERCANCELRESPONSE: { long id = 0; if (gotOrderCancel != null) { if (long.TryParse(msg, out id)) { gotOrderCancel(id); } else if (SendDebugEvent != null) { SendDebugEvent("Count not parse order cancel: " + msg); } } } break; case MessageTypes.EXECUTENOTIFY: // date,time,symbol,side,size,price,comment try { Trade tr = TradeImpl.Deserialize(msg); if (gotFill != null) { gotFill(tr); } } catch (Exception ex) { debug("error deserializing fill: " + msg); debug("error: " + ex.Message + ex.StackTrace); debug("broker: " + BrokerName); } break; case MessageTypes.ORDERNOTIFY: try { Order o = OrderImpl.Deserialize(msg); if (gotOrder != null) { gotOrder(o); } } catch (Exception ex) { debug("error deserializing order: " + msg); debug("error: " + ex.Message + ex.StackTrace); debug("broker: " + BrokerName); } break; case MessageTypes.POSITIONRESPONSE: try { Position pos = PositionImpl.Deserialize(msg); if (gotPosition != null) { gotPosition(pos); } } catch (Exception ex) { if (SendDebugEvent != null) { SendDebugEvent(msg + " " + ex.Message + ex.StackTrace); } } break; case MessageTypes.ACCOUNTRESPONSE: if (gotAccounts != null) { gotAccounts(msg); } break; case MessageTypes.FEATURERESPONSE: string[] p = msg.Split(','); List <MessageTypes> f = new List <MessageTypes>(); foreach (string s in p) { try { f.Add((MessageTypes)Convert.ToInt32(s)); } catch (Exception) { } } if (gotFeatures != null) { gotFeatures(f.ToArray()); } if (gotUnknownMessage != null) { gotUnknownMessage(tlm.type, 0, 0, 0, string.Empty, ref tlm.body); } break; case MessageTypes.SERVERDOWN: if (gotServerDown != null) { gotServerDown(msg); } break; case MessageTypes.SERVERUP: if (gotServerUp != null) { gotServerUp(msg); } break; default: if (gotUnknownMessage != null) { gotUnknownMessage(tlm.type, 0, 0, 0, string.Empty, ref tlm.body); } break; } result = 0; m.Result = (IntPtr)result; }
void MessageCache_CacheEvent(int action, int row) { switch (action) { case 1: //CN_Submit break; case 4: //CN_Insert { try { int i = row; int err = 0; object cv = null; string orderReferenceNumber = String.Empty; Order o = new OrderImpl(); _messageCache.VBGetCell(row, "SYMBOL", ref cv, ref err); if (!(cv == null)) { o.symbol = cv.ToString(); } _messageCache.VBGetCell(row, "SIDE", ref cv, ref err); if (!(cv == null)) { v("order side: "+cv.ToString()); if (cv.ToString() == "BUY") { o.side = true; } else if (cv.ToString() == "SELL") { o.side = false; } else if (cv.ToString().Contains("SHORT")) { o.side = false; } } _messageCache.VBGetCell(row, "QUANTITY", ref cv, ref err); if (!(cv == null)) { o.size = int.Parse(cv.ToString()); } _messageCache.VBGetCell(row, "PRICE", ref cv, ref err); if (!(cv == null)) { o.price = decimal.Parse(cv.ToString()); } _messageCache.VBGetCell(row, "STOPPRICE", ref cv, ref err); if (!(cv == null)) { o.stopp = decimal.Parse(cv.ToString()); } _messageCache.VBGetCell(row, "ACCOUNT", ref cv, ref err); if (!(cv == null)) { o.Account = cv.ToString(); } _messageCache.VBGetCell(row, "BRSEQ", ref cv, ref err); if (!(cv == null)) { orderReferenceNumber = cv.ToString(); } _messageCache.VBGetCell(row, "Status", ref cv, ref err); if (!(cv == null)) { if (cv.ToString() == "Open") { o.id = row; long now = Util.ToTLDate(DateTime.Now); int xsec = (int)(now % 100); long rem = (now - xsec) / 100; o.time = ((int)(rem % 10000)) * 100 + xsec; o.date = (int)((rem - o.time) / 10000); o.size = o.side ? o.UnsignedSize : o.UnsignedSize * -1; OrderIdDict.Add(orderReferenceNumber, (long)row); if (_onotified.Contains((int)row)) return; _onotified.Add(o.id); tl.newOrder(o); v("order ack received and sent: " + o.ToString()); } else if (cv.ToString() == "Canceled") { long id = OrderIdDict[orderReferenceNumber]; tl.newCancel(id); v("order cancel ack received and sent: " + id); } else if (cv.ToString() == "Complete") { Trade f = new TradeImpl(); _messageCache.VBGetCell(row, "SYMBOL", ref cv, ref err); if (!(cv == null)) { f.symbol = cv.ToString(); } _messageCache.VBGetCell(row, "ACCOUNT", ref cv, ref err); if (!(cv == null)) { f.Account = cv.ToString(); } _messageCache.VBGetCell(row, "BRSEQ", ref cv, ref err); if (!(cv == null)) { long id = 0; if (OrderIdDict.TryGetValue(cv.ToString(), out id)) f.id = id; else f.id = _idt.AssignId; f.id = id; } _messageCache.VBGetCell(row, "EXECPRICE", ref cv, ref err); if (!(cv == null)) { f.xprice = decimal.Parse(cv.ToString()); } _messageCache.VBGetCell(row, "EXECQUANTITY", ref cv, ref err); if (!(cv == null)) { f.xsize = int.Parse(cv.ToString()); } _messageCache.VBGetCell(row, "EXCHANGE", ref cv, ref err); if (!(cv == null)) { f.ex = cv.ToString(); } _messageCache.VBGetCell(row, "SIDE", ref cv, ref err); if (!(cv == null)) { if (cv.ToString() == "BUY") { f.side = true; } else if (cv.ToString() == "SELL") { f.side = false; } else if (cv.ToString().Contains("SHORT")) { f.side = false; } else v("invalid fill side: " + cv.ToString()); } long now = Util.ToTLDate(DateTime.Now); int xsec = (int)(now % 100); long rem = (now - xsec) / 100; f.xtime = ((int)(rem % 10000)) * 100 + xsec; f.xdate = (int)((now - f.xtime) / 1000000); Object objErr = null; _positionCache.VBRediCache.AddWatch(2, string.Empty, f.Account, ref objErr); if (f.isValid) { pt.Adjust(f); tl.newFill(f); v("fill ack received and sent: " + f.ToString()); } else debug("ignoring invalid fill: " + f.ToString()); } } } catch (Exception ex) { debug(ex.Message+ex.StackTrace); } } break; case 5: //CN_Update { try { int i = row; int err = 0; object cv = null; string orderStatus = null; _messageCache.VBGetCell(row, "Status", ref cv, ref err); if (!(cv == null)) { orderStatus = cv.ToString(); } if (orderStatus == "Complete") { Trade f = new TradeImpl(); _messageCache.VBGetCell(row, "SYMBOL", ref cv, ref err); if (!(cv == null)) { f.symbol = cv.ToString(); } _messageCache.VBGetCell(row, "ACCOUNT", ref cv, ref err); if (!(cv == null)) { f.Account = cv.ToString(); } _messageCache.VBGetCell(row, "BRSEQ", ref cv, ref err); if (!(cv == null)) { long id = 0; if (OrderIdDict.TryGetValue(cv.ToString(), out id)) f.id = id; else f.id = _idt.AssignId; f.id = id; } _messageCache.VBGetCell(row, "EXECPRICE", ref cv, ref err); if (!(cv == null)) { f.xprice = decimal.Parse(cv.ToString()); } _messageCache.VBGetCell(row, "EXECQUANTITY", ref cv, ref err); if (!(cv == null)) { f.xsize = int.Parse(cv.ToString()); } _messageCache.VBGetCell(row, "EXCHANGE", ref cv, ref err); if (!(cv == null)) { f.ex = cv.ToString(); } _messageCache.VBGetCell(row, "SIDE", ref cv, ref err); if (!(cv == null)) { if (cv.ToString() == "BUY") { f.side = true; } else if (cv.ToString() == "SELL") { f.side = false; } } long now = Util.ToTLDate(DateTime.Now); int xsec = (int)(now % 100); long rem = (now - xsec) / 100; f.xtime = ((int)(rem % 10000)) * 100 + xsec; f.xdate = (int)((now - f.xtime) / 1000000); Object objErr = null; _positionCache.VBRediCache.AddWatch(2, string.Empty, f.Account, ref objErr); if (f.isValid) { pt.Adjust(f); tl.newFill(f); v("fill ack received and sent: " + f.ToString()); } else debug("ignoring invalid fill: " + f.ToString()); } if (orderStatus == "Partial") { } } catch (Exception exc) { debug(exc.Message); } } break; case 8: //CN_Remove break; } }
public void OrderTests() { // no orders yet Assert.That(orders == 0, orders.ToString()); // no fill requests yet Assert.That(fillrequest == 0, fillrequest.ToString()); // client wants to buy 100 TST at market OrderImpl o = new OrderImpl(SYM, 100); // if it works it'll return zero int error = c.SendOrderStatus(o); Assert.That(error==0,error.ToString()); // client should have received notification that an order entered his account Assert.That(orders == 1, orders.ToString()); // server should have gotten a request to fill an order Assert.That(fillrequest == 1, fillrequest.ToString()); // make sure order was copied to other clients Assert.AreEqual(copyorders, orders); }
/// <summary> /// Convert an MbtOpenOrder to a TradeLink OrderImpl and check if the order token /// is mapped to an existing TradeLink order. If so, replace the token with the OrderNumber and /// update the mapping for tl2broker with the order number as well. If not generate a new order number /// </summary> /// <param name="pOrd"></param> /// <returns></returns> OrderImpl ToTradeLinkOrder(MbtOpenOrder pOrd) { //get the token string token = pOrd.Token; //get the actual broker ID number now string bid = pOrd.OrderNumber, s = ""; //check for a matching tradelink order long tlid = 0, v = 0; //first try to get the tlid by token if (!broker2tl.TryGetValue(token, out tlid)) { //ok now try to get it by broker OrderNumber if it has been processed once before. if (!broker2tl.TryGetValue(bid, out tlid)) { //this order must be initiated by MB Trading so assign a new one tlid = _idt.AssignId; debug(String.Format("No matching TradeLink ID found for token {0}, generated {1}", token, tlid)); } //save the mappings if (!broker2tl.ContainsKey(bid)) { broker2tl.Add(bid, tlid); } else { broker2tl.TryGetValue(bid, out v); debug(String.Format("WARNING! OrderNumber {0} is already mapped to {1}. Overwriting it with {2}", bid, v, tlid)); broker2tl[bid] = tlid; } if (!tl2broker.ContainsKey(tlid)) { tl2broker.Add(tlid, bid); } else { tl2broker.TryGetValue(tlid, out s); debug(String.Format("WARNING! TradeLinkID {0} is already mapped to {1}. Overwriting it with {2}", tlid, s, bid)); tl2broker[tlid] = bid; } } else { //we have a match so this order was generated by TradeLink //overwrite the Token with the OrderNumber debug(String.Format("Overwriting token {0} with OrderNumber {1} for TradeLink order ID {2}", token, bid, tlid)); tl2broker[tlid] = bid; //remove the Token mapping broker2tl.Remove(token); //and map the OrderNumber to the TradeLink ID if (!broker2tl.ContainsKey(bid)) broker2tl.Add(bid, tlid); } OrderImpl o = new OrderImpl(pOrd.Symbol, pOrd.Quantity); o.id = tlid; o.Account = pOrd.Account.Account; o.side = (pOrd.BuySell == MBConst.VALUE_BUY); o.price = (decimal)pOrd.Price; o.stopp = (decimal)pOrd.StopPrice; o.ValidInstruct = pOrd.TimeInForce == MBConst.VALUE_DAY ? OrderInstructionType.DAY : OrderInstructionType.GTC; o.time = Util.DT2FT(pOrd.UTCDateTime); o.date = Util.ToTLDate(pOrd.UTCDateTime); o.trail = (decimal)pOrd.TrailingOffset; return o; }