//returns string[] of orderIds public string[] SendSpreadOrder(string buySell) { string action = buySell == "Buy" ? "Sell" : "Buy"; double[] prices = findPrices(buySell); double aPrice = prices[0]; double bPrice = prices[1]; string a = procSpread.SendOrder(buySell, aPrice, procSpread.productOne); string b = procSpread.SendOrder(action, bPrice, procSpread.productTwo); Order one = new Order(buySell, procSpread.instruments[0].Size, aPrice, a, procSpread.productOne); Order two = new Order(action, procSpread.instruments[1].Size, bPrice, b, procSpread.productTwo); SpreadOrder so = new SpreadOrder(new Order[] { one, two }, Interlocked.Add(ref spreadIDcount, 1)); orders.Add(so); //log the cost of the spread if (log.IsInfoEnabled) { log.Info( new System.Text.StringBuilder("spreadID:").AppendFormat("{0} orders: {1} {2} {3} @ {4}" , spreadIDcount, a, b, buySell, prices[2]) ); } return(new string[] { a, b }); }
private string[] SendSpreadOrder(string buySell, double[] prices) { string action = buySell == "Buy" ? "Sell" : "Buy"; double aPrice = prices[0]; double bPrice = prices[1]; string a = procSpread.SendOrder(buySell, aPrice, procSpread.productOne); string b = procSpread.SendOrder(action, bPrice, procSpread.productTwo); Order one = new Order(buySell, procSpread.instruments[0].Size, aPrice, a, procSpread.productOne); Order two = new Order(action, procSpread.instruments[1].Size, bPrice, b, procSpread.productTwo); SpreadOrder so = new SpreadOrder(new Order[] { one, two } , Interlocked.Add(ref spreadIDcount, 1) ); orders.Add(so); //log the cost of the spread if (log.IsInfoEnabled) log.Info( new System.Text.StringBuilder("spreadID:").AppendFormat("{0} orders: {1} {2} {3} @ {4}" ,spreadIDcount,a,b,buySell,prices[2] ) ); return new string[] { a, b }; }
private void checkSpreadLevel( SpreadOrder so ) { double[] mktprices = findPrices(so.buySell); double mktlevel = mktprices[2]; Order[] o = so.getLegs(); double[] wkprices = so.workPrices(); //the sell leg is off mkt if (so.buySell == "Buy" && o[1].Price > market.ask(o[1].IPROC.Product) ) { if (log.IsDebugEnabled) log.Debug("BUY: sell leg is off mkt shift spread lower"); //lower sell leg CancelReplace( o[1].buySell ,o[1].SOK ,o[1].IPROC ,o[1].WkQty ,1 ); //lower the buy leg CancelReplace( o[0].buySell ,o[0].SOK ,o[0].IPROC ,o[0].WkQty ,-1 ); o[1].Price = market.ask(o[1].IPROC.Product) - o[1].IPROC.TickPrice; o[0].Price = market.bid(o[0].IPROC.Product) - o[0].IPROC.TickPrice; } //the buy leg is off mkt else if (so.buySell == "Buy" && o[0].Price < market.bid(o[0].IPROC.Product)) { if (log.IsDebugEnabled) log.Debug("BUY: buy leg is off mkt shift spread higher"); //higher sell leg CancelReplace(o[1].buySell , o[1].SOK , o[1].IPROC , o[1].WkQty , -1); //higher the buy leg CancelReplace(o[0].buySell , o[0].SOK , o[0].IPROC , o[0].WkQty , 1); o[1].Price = market.ask(o[1].IPROC.Product) + o[1].IPROC.TickPrice; o[0].Price = market.bid(o[0].IPROC.Product) + o[0].IPROC.TickPrice; } //the sell leg is off mkt else if (so.buySell == "Sell" && o[0].Price > market.ask(o[0].IPROC.Product)) { if (log.IsDebugEnabled) log.Debug("SELL: sell leg is off mkt shift spread lower"); //lower sell leg CancelReplace( o[0].buySell , o[0].SOK , o[0].IPROC , o[0].WkQty , 1); //lower the buy leg CancelReplace( o[1].buySell , o[1].SOK , o[1].IPROC , o[1].WkQty , -1); o[0].Price = market.ask(o[0].IPROC.Product) - o[0].IPROC.TickPrice; o[1].Price = market.bid(o[1].IPROC.Product) - o[1].IPROC.TickPrice; } //the buy leg is off mkt else if (so.buySell == "Sell" && o[1].Price < market.bid(o[1].IPROC.Product)) { if (log.IsDebugEnabled) log.Debug("SELL: buy leg is off mkt shift spread higher"); //higher sell leg CancelReplace( o[0].buySell ,o[0].SOK ,o[0].IPROC ,o[0].WkQty ,-1); //higher the buy leg CancelReplace(o[1].buySell , o[1].SOK , o[1].IPROC , o[1].WkQty , 1); o[0].Price = market.ask(o[0].IPROC.Product) + o[0].IPROC.TickPrice; o[1].Price = market.bid(o[1].IPROC.Product) + o[1].IPROC.TickPrice; } }
private void OnFill(object sender, FillEventArgs e) { try { Fill fill = e.fill; string action = fill.Buy ? "Sell" : "Buy"; //keep track of current positions if (fill.Product == procSpread.productOne.Product) { currentPosOne += fill.Buy ? fill.Qty : -fill.Qty; } else if (fill.Product == procSpread.productTwo.Product) { currentPosTwo += fill.Buy ? fill.Qty : -fill.Qty; } if (log.IsDebugEnabled) { log.Debug("closeouts size= " + closeouts.Count); log.Debug("fillbugs size= " + fillbugs.Count); log.Debug("orders count " + orders.Count + "\n" + fill.ToString()); log.Debug("offorders size= " + offOrders.Count); } if (fillbugs.ContainsKey(fill.Key) && fill.Full) { orders.Remove(fillbugs[fill.Key]); fillbugs.Remove(fill.Key); return; } SpreadOrder spo = findSpread(fill.Key); if (spo == null) { if (offOrders.ContainsKey(fill.Key)) { if (log.IsDebugEnabled) { log.Debug("late fill in OffOrders " + fill.ToString()); } Order o = offOrders[fill.Key]; procSpread.SendOrder(o.buySell == "Buy" ? "Sell" : "Buy" , o.buySell == "Buy" ? market.bid(o.IPROC.Product) - o.IPROC.TickPrice * 5 : market.ask(o.IPROC.Product) + o.IPROC.TickPrice * 5 , fill.Qty , o.IPROC); offOrders.Remove(fill.Key); } return; } spo.AddFill(fill); /* * if we got back a full fill check to see if the whole spread is full * if its not then work the open leg in a seperate thread incrementing the price by * payUp params. add the thread to closeouts so we can stop it when it is full filled */ if (fill.Full) { if (spo.IsFull()) { lastfill.Clear(); if (log.IsDebugEnabled) { log.Debug("removing spread from orders"); } orders.Remove(spo); lastfill[spo.buySell] = spo.fillPrice(); if (log.IsInfoEnabled) { log.Info( new System.Text.StringBuilder("SpreadID:").AppendFormat("{0} spreadType: {1} filled spreadcost: {2}" , spo.spreadID, spo.buySell, spo.fillPrice()) ); } if (closeouts.ContainsKey(fill.Key)) { try { closeouts[fill.Key].Abort(); } catch (Exception exc) { if (log.IsErrorEnabled) { log.Error(exc.StackTrace); } } closeouts.Remove(fill.Key); } } else { Order wkLeg = spo.getWorkingLeg(); Order filledLeg = spo.getFilledLeg(); //we got a Full fill but the spread itself is not full. however we are already running the cleanup //thread which means TT sent back full fill error if (closeouts.ContainsKey(wkLeg.SOK)) { if (log.IsDebugEnabled) { log.Debug("XXX fix for full fill bug: " + wkLeg.SOK); } try{ closeouts[wkLeg.SOK].Abort(); } catch (Exception exc) { if (log.IsErrorEnabled) { log.Error(exc.StackTrace); } } closeouts.Remove(wkLeg.SOK); string k = procSpread.SendOrder(wkLeg.buySell , wkLeg.buySell == "Buy" ? market.ask(wkLeg.IPROC.Product) + wkLeg.IPROC.TickPrice * 5 : market.bid(wkLeg.IPROC.Product) - wkLeg.IPROC.TickPrice * 6 , wkLeg.WkQty , wkLeg.IPROC); fillbugs.Add(k, spo); } else { if (log.IsDebugEnabled) { log.Debug("closeout out remaing leg: " + wkLeg.SOK); } Thread thrdCloseout = new Thread(delegate() { int PayUpTicks = spread.PayUpTicks; for (int i = 0; i < spread.PayUpCount; i++) { double price = action == "Buy" ? wkLeg.Price + wkLeg.IPROC.TickPrice * PayUpTicks : wkLeg.Price - wkLeg.IPROC.TickPrice * PayUpTicks; int wkqty = wkLeg.WkQty; if (wkqty > 0) { CancelReplace(action, wkLeg.SOK, wkLeg.IPROC, wkqty, price); } else { break; } Thread.Sleep(spread.PayUpPeriod); PayUpTicks++; } //if we exhausted payUpCount and still not filled then closeout full leg. if (wkLeg.WkQty == wkLeg.IPROC.Size) { scratchLegs.Enqueue(filledLeg); closeouts.Remove(wkLeg.SOK); procSpread.Delete(wkLeg.SOK, wkLeg.IPROC.ttOrderSet); } }); thrdCloseout.Start(); closeouts.Add(wkLeg.SOK, thrdCloseout); } } } } catch (Exception ex) { if (log.IsErrorEnabled) { log.Error(ex.StackTrace + "\n\n" + ex.Message); } } }
private void checkSpreadLevel(SpreadOrder so) { double[] mktprices = findPrices(so.buySell); double mktlevel = mktprices[2]; Order[] o = so.getLegs(); double[] wkprices = so.workPrices(); //the sell leg is off mkt if (so.buySell == "Buy" && o[1].Price > market.ask(o[1].IPROC.Product)) { if (log.IsDebugEnabled) { log.Debug("BUY: sell leg is off mkt shift spread lower"); } //lower sell leg CancelReplace(o[1].buySell , o[1].SOK , o[1].IPROC , o[1].WkQty , 1); //lower the buy leg CancelReplace(o[0].buySell , o[0].SOK , o[0].IPROC , o[0].WkQty , -1); o[1].Price = market.ask(o[1].IPROC.Product) - o[1].IPROC.TickPrice; o[0].Price = market.bid(o[0].IPROC.Product) - o[0].IPROC.TickPrice; } //the buy leg is off mkt else if (so.buySell == "Buy" && o[0].Price < market.bid(o[0].IPROC.Product)) { if (log.IsDebugEnabled) { log.Debug("BUY: buy leg is off mkt shift spread higher"); } //higher sell leg CancelReplace(o[1].buySell , o[1].SOK , o[1].IPROC , o[1].WkQty , -1); //higher the buy leg CancelReplace(o[0].buySell , o[0].SOK , o[0].IPROC , o[0].WkQty , 1); o[1].Price = market.ask(o[1].IPROC.Product) + o[1].IPROC.TickPrice; o[0].Price = market.bid(o[0].IPROC.Product) + o[0].IPROC.TickPrice; } //the sell leg is off mkt else if (so.buySell == "Sell" && o[0].Price > market.ask(o[0].IPROC.Product)) { if (log.IsDebugEnabled) { log.Debug("SELL: sell leg is off mkt shift spread lower"); } //lower sell leg CancelReplace(o[0].buySell , o[0].SOK , o[0].IPROC , o[0].WkQty , 1); //lower the buy leg CancelReplace(o[1].buySell , o[1].SOK , o[1].IPROC , o[1].WkQty , -1); o[0].Price = market.ask(o[0].IPROC.Product) - o[0].IPROC.TickPrice; o[1].Price = market.bid(o[1].IPROC.Product) - o[1].IPROC.TickPrice; } //the buy leg is off mkt else if (so.buySell == "Sell" && o[1].Price < market.bid(o[1].IPROC.Product)) { if (log.IsDebugEnabled) { log.Debug("SELL: buy leg is off mkt shift spread higher"); } //higher sell leg CancelReplace(o[0].buySell , o[0].SOK , o[0].IPROC , o[0].WkQty , -1); //higher the buy leg CancelReplace(o[1].buySell , o[1].SOK , o[1].IPROC , o[1].WkQty , 1); o[0].Price = market.ask(o[0].IPROC.Product) + o[0].IPROC.TickPrice; o[1].Price = market.bid(o[1].IPROC.Product) + o[1].IPROC.TickPrice; } }