//Sends in the initial orders so that we can begin waiting for the signal private void setup() { if(myOrders != null && myOrders.Count() > 0) unwindTrades(); this.state = StrategyState.INITIALIZING; //enter initial trades, two for each product BrokerManager brk = getFirstBroker(); //We don't want anyone else submitting orders at this time, so that we limit the time //in between the submission of these four orders. lock(brk) { //enter A side based on B price LimitOrder sellAOrd = new LimitOrder(productA, bidQtyA, Order.Side.SELL, askB + sellSpread); LimitOrder buyAOrd = new LimitOrder(productA, bidQtyA, Order.Side.BUY, bidB + buySpread); //submit A side orders brk.submitOrder(sellAOrd); brk.submitOrder(buyAOrd); //Keep track of the A side orders myOrders.Add(StrategyOrderType.SELL_A, sellAOrd); myOrders.Add(StrategyOrderType.BUY_A, buyAOrd); myFills.Add(sellAOrd.internalId, 0); myFills.Add(buyAOrd.internalId, 0); //enter B side based on A price LimitOrder sellBOrd = new LimitOrder(productB, bidQtyB, Order.Side.SELL, askA + sellSpread); LimitOrder buyBOrd = new LimitOrder(productB, bidQtyB, Order.Side.BUY, bidA + buySpread); //submit B side orders brk.submitOrder(sellAOrd); brk.submitOrder(buyAOrd); //Keep track of the B side orders myOrders.Add(StrategyOrderType.SELL_B, sellBOrd); myOrders.Add(StrategyOrderType.BUY_B, buyBOrd); myFills.Add(sellBOrd.internalId, 0); myFills.Add(buyBOrd.internalId, 0); this.state = StrategyState.READY; } }
//When we detect the signal, we perform these actions private void tradeOnSignal(Fill fill) { LimitOrder hedgeOrder; List<Order> ordersToCancel = new List<Order>(); //determine which of the orders where filled, and add the orders //that werent filled to a list. Also, based on the type of fill, //determine which order needs to be submitted if (fill.originalOrder.product.Equals(productA)) { //This was a fill for product A, so cancel the orders for B ordersToCancel.Add(myOrders[StrategyOrderType.BUY_B]); ordersToCancel.Add(myOrders[StrategyOrderType.SELL_B]); if (fill.originalOrder.side.Equals(Order.Side.BUY)) { //This was a buy of A, so cancel the sell of A and submit a hedge to buy B hedgeOrder = new LimitOrder(productB, fill.qty, Order.Side.SELL, fill.price - sellSpread); ordersToCancel.Add(myOrders[StrategyOrderType.SELL_A]); } else { //This was a sell of A, so cancel the buy of A and submit a hedge to sell B hedgeOrder = new LimitOrder(productB, fill.qty, Order.Side. BUY, fill.price - buySpread); ordersToCancel.Add(myOrders[StrategyOrderType.BUY_A]); } } else { //This was a fill for product B, so cancel the orders for A ordersToCancel.Add(myOrders[StrategyOrderType.BUY_A]); ordersToCancel.Add(myOrders[StrategyOrderType.SELL_A]); if (fill.originalOrder.side.Equals(Order.Side.BUY)) { //This was a buy of B, so cancel the sell of B and submit a hedge to buy A hedgeOrder = new LimitOrder(productA, fill.qty, Order.Side.SELL, fill.price - sellSpread); ordersToCancel.Add(myOrders[StrategyOrderType.SELL_B]); } else { //This was a sell of B, so cancel the buy of B and submit a hedge to sell A hedgeOrder = new LimitOrder(productA, fill.qty, Order.Side.BUY, fill.price - buySpread); ordersToCancel.Add(myOrders[StrategyOrderType.BUY_B]); } } //cancel the orders that aren't a part of this trade cancelOrders(ordersToCancel); //TODO: What happens if this was a partial fill? //submit hedge orders getFirstBroker().submitOrder(hedgeOrder); }