public void stopAndCross() { foreach (SterlingLib.ISTIOrder order in ordersAbove) { orderMaint.CancelOrder(Globals.account, 0, order.ClOrderID, Guid.NewGuid().ToString()); } foreach (SterlingLib.ISTIOrder order in ordersBelow) { orderMaint.CancelOrder(Globals.account, 0, order.ClOrderID, Guid.NewGuid().ToString()); } status = "Stopped"; //Cross out. int orderQuantity = 0; string orderSide = "B"; if (currentPosition > 0) { orderQuantity = currentPosition; orderSide = "S"; } else if (currentPosition < 0) { orderQuantity = -(currentPosition); orderSide = "B"; } else { return; } SterlingLib.STIOrder stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; if (orderSide != null) { stiOrder.Side = orderSide; } stiOrder.Quantity = orderQuantity; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTIMkt; stiOrder.Destination = "BATS"; stiOrder.ClOrderID = Guid.NewGuid().ToString(); int orderStatus = stiOrder.SubmitOrder(); if (orderStatus != 0) { Debug.WriteLine("Order Error on Stop and Close Order: " + orderStatus.ToString()); } else { //Success } }
private void stiEvents_OnSTIOrderUpdateXML(ref string orderUpdateInfo) { XmlSerializer xs = new XmlSerializer(typeof(SterlingLib.structSTIOrderUpdate)); SterlingLib.structSTIOrderUpdate structTrade = (SterlingLib.structSTIOrderUpdate)xs.Deserialize(new StringReader(orderUpdateInfo)); //MessageBox.Show(structTrade.nOrderStatus.ToString()); //Find associated order level, trigger new order SterlingAlgos.OrderLevel orderLevel = orderLevels.Where(i => i.sittingOrder.ClOrderID == structTrade.bstrClOrderId).FirstOrDefault(); //MessageBox.Show(orderLevel.lastFilledOrder.fAvgExecPrice.ToString()); Console.WriteLine("TU" + " : " + orderLevel.startPrice + " : " + orderLevel.sittingOrder.ClOrderID); if (orderLevel != null) { //Check if orderLevel actually found if (orderLevel.isStop) { if (structTrade.nOrderStatus == 5) { stop(); } } else if (structTrade.nOrderStatus == 5) //Check for complete fill { bool isRestore = (direction == orderLevel.sittingOrder.Side) || (direction == "S" && orderLevel.sittingOrder.Side == "T"); //If true, size has been restored, so do TP order. If false, TP order is hit, calculate profit and do restore size order if (direction == "B" && isRestore) // Restore Size has just occurred { orderLevel.totalFills += 1; orderLevel.completedOrders.Add(orderLevel.sittingOrder); orderLevel.lastFilledOrder = structTrade; //Create take profit order SterlingLib.STIOrder stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = "S"; stiOrder.Quantity = incrementSize; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(orderLevel.startPrice + profitOffset); stiOrder.Destination = Globals.desination; stiOrder.ClOrderID = Guid.NewGuid().ToString(); if (!isStopped) { //Submit order int ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString()); } else //No error, new sitting order is the new "buy" order (restore size order) { orderLevel.sittingOrder = stiOrder; orderLevel.isRestore = false; } } else { orderLevel.sittingOrder = stiOrder; orderLevel.isRestore = false; } } if (direction == "B" && !isRestore) //Take Profit has just occurred { //orderLevel.PL += Convert.ToDecimal(structTrade.fExecPrice - orderLevel.lastFilledOrder.fExecPrice); orderLevel.totalFills += 1; orderLevel.completedOrders.Add(orderLevel.sittingOrder); orderLevel.lastFilledOrder = structTrade; //Create restore size order SterlingLib.STIOrder stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = "B"; stiOrder.Quantity = incrementSize; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(orderLevel.startPrice); stiOrder.Destination = Globals.desination; stiOrder.ClOrderID = Guid.NewGuid().ToString(); if (!isStopped) { //Submit order if (restoreSize) { int ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString()); } else //No error, new sitting order is the new "buy" order (restore size order) { orderLevel.sittingOrder = stiOrder; } } else { orderLevel.sittingOrder = stiOrder; //Order will sit there but not execute is no restore size option orderLevel.isRestore = true; } } else { orderLevel.sittingOrder = stiOrder; } } if (direction == "S" && isRestore) // Restore Size has just occurred { orderLevel.totalFills += 1; orderLevel.completedOrders.Add(orderLevel.sittingOrder); orderLevel.lastFilledOrder = structTrade; //Create take profit order SterlingLib.STIOrder stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = "B"; stiOrder.Quantity = incrementSize; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(orderLevel.startPrice - profitOffset); stiOrder.Destination = Globals.desination; stiOrder.ClOrderID = Guid.NewGuid().ToString(); if (!isStopped) { //Submit order int ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString()); } else //No error, new sitting order is the new "buy" order (restore size order) { orderLevel.sittingOrder = stiOrder; orderLevel.isRestore = false; } } else { orderLevel.sittingOrder = stiOrder; orderLevel.isRestore = false; } } if (direction == "S" && !isRestore) //Take Profit has just occurred { //orderLevel.PL += Convert.ToDecimal(orderLevel.lastFilledOrder.fExecPrice - structTrade.fExecPrice); orderLevel.totalFills += 1; orderLevel.completedOrders.Add(orderLevel.sittingOrder); orderLevel.lastFilledOrder = structTrade; //Create restore size order SterlingLib.STIOrder stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = "S"; stiOrder.Quantity = incrementSize; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(orderLevel.startPrice); stiOrder.Destination = Globals.desination; stiOrder.ClOrderID = Guid.NewGuid().ToString(); if (!isStopped) { if (restoreSize) { //Submit order int ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString()); } else //No error, new sitting order is the new "buy" order (restore size order) { orderLevel.sittingOrder = stiOrder; } } else { orderLevel.sittingOrder = stiOrder; //Order will sit there but not execute is no restore size option orderLevel.isRestore = true; } } else { orderLevel.sittingOrder = stiOrder; } } } } }
public bool initiateTrade() { int restartLevels = 0; //Remaining restart levels if (isRestart) { if (isRunning) { stop(); } orderLevels.Clear(); restartLevels = restartInitialLevels; isStopped = false; } priceLevels.Clear(); if (direction == "B") { SterlingLib.STIOrder stiOrder = new SterlingLib.STIOrder(); //Stop Order First if (hasHardStop) { stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = "S"; stiOrder.Quantity = maxSize; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmtStp; stiOrder.StpPrice = Convert.ToDouble(hardStop); stiOrder.Destination = "EDGX"; stiOrder.ClOrderID = Guid.NewGuid().ToString(); int ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString() + " - 1"); } else { OrderLevel orderLevel = new OrderLevel(); orderLevel.isStop = true; orderLevel.startPrice = hardStop; orderLevel.sittingOrder = stiOrder; //Setting start size order as trigger order for each level orderLevels.Add(orderLevel); } } //Initial position //Create Order Levels for Starting Size and all levels above it (for buy side) //for (decimal price = startingPrice; price < rangeTop; price += incrementPrice) for (decimal price = rangeTop - incrementPrice; price >= startingPrice; price -= incrementPrice) { stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = direction; stiOrder.Quantity = incrementSize; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(startingPrice); stiOrder.Destination = Globals.desination; stiOrder.ClOrderID = Guid.NewGuid().ToString(); if (restartLevels > 0) //If this is a restart scale trade and one of the initial position levels, make it a take profit instead of a restore size { stiOrder.Side = "S"; stiOrder.LmtPrice = Convert.ToDouble(price + profitOffset); restartLevels -= 1; } //Submit order int ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString() + " - 2"); } else { OrderLevel orderLevel = new OrderLevel(); orderLevel.startPrice = price; orderLevel.sittingOrder = stiOrder; //Setting start size order as trigger order for each level if (stiOrder.Side == "B") { orderLevel.isRestore = true; } orderLevels.Add(orderLevel); } } //Price Levels for (decimal price = rangeBottom; price < rangeTop; price += incrementPrice) { priceLevels.Add(price); } priceLevels.Reverse(); //allOrders.Add(stiOrder); //Stopwatch sw = new Stopwatch(); //sw.Start(); //All prices below (for buy side) starting price foreach (decimal price in priceLevels) { SterlingLib.STIOrder order = new SterlingLib.STIOrder(); if (price < startingPrice) { order.Symbol = symbol; order.Account = Globals.account; order.Side = direction; order.Quantity = incrementSize; order.Tif = "D"; //day order order.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; order.LmtPrice = Convert.ToDouble(price); order.Destination = Globals.desination; order.ClOrderID = Guid.NewGuid().ToString(); if (restartLevels > 0) //If this is a restart scale trade and one of the initial position levels, make it a take profit instead of a restore size { order.Side = "S"; order.LmtPrice = Convert.ToDouble(price + profitOffset); restartLevels--; } int orderSuccess = order.SubmitOrder(); if (orderSuccess != 0) { Console.WriteLine("Order Error :" + order.ToString() + " - 3"); } else //Create order level then append to orderLevels list { OrderLevel orderLevel = new OrderLevel(); orderLevel.startPrice = Convert.ToDecimal(price); orderLevel.sittingOrder = order; orderLevels.Add(orderLevel); } } } orderLevels.Sort((x, y) => x.startPrice.CompareTo(y.startPrice)); orderLevels.Reverse(); //sw.Stop(); //Console.WriteLine(sw.Elapsed); foreach (OrderLevel level in orderLevels) { Console.WriteLine(level.startPrice); } } else if (direction == "S") { //Stop order first SterlingLib.STIOrder stiOrder = new SterlingLib.STIOrder(); if (hasHardStop) { stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = "B"; stiOrder.Quantity = maxSize; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmtStp; stiOrder.StpPrice = Convert.ToDouble(hardStop); stiOrder.Destination = "EDGX"; stiOrder.ClOrderID = Guid.NewGuid().ToString(); int ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString() + " - 4"); } else { OrderLevel orderLevel = new OrderLevel(); orderLevel.isStop = true; orderLevel.startPrice = hardStop; orderLevel.sittingOrder = stiOrder; //Setting start size order as trigger order for each level orderLevels.Add(orderLevel); } } //Create Order Levels for Starting Size and all levels above it (for sell side) //Initial Position for (decimal price = rangeBottom + incrementPrice; price <= startingPrice; price += incrementPrice) { stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = "T"; stiOrder.Quantity = incrementSize; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(startingPrice); stiOrder.Destination = Globals.desination; stiOrder.ClOrderID = Guid.NewGuid().ToString(); if (restartLevels > 0) //If this is a restart scale trade and one of the initial position levels, make it a take profit instead of a restore size { stiOrder.Side = "B"; stiOrder.LmtPrice = Convert.ToDouble(price - profitOffset); restartLevels--; } //Submit order int ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString() + " - 5"); } else { OrderLevel orderLevel = new OrderLevel(); orderLevel.startPrice = price; orderLevel.sittingOrder = stiOrder; //Setting start size order as trigger order for each level if (stiOrder.Side == "S") { orderLevel.isRestore = true; } orderLevels.Add(orderLevel); } } //Price Levels for (decimal price = rangeBottom + incrementPrice; price <= rangeTop; price += incrementPrice) { priceLevels.Add(price); } //allOrders.Add(stiOrder); //Stopwatch sw = new Stopwatch(); //sw.Start(); //All prices below (for buy side) starting price foreach (decimal price in priceLevels) { SterlingLib.STIOrder order = new SterlingLib.STIOrder(); if (price > startingPrice) { order.Symbol = symbol; order.Account = Globals.account; order.Side = "T"; order.Quantity = incrementSize; order.Tif = "D"; //day order order.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; order.LmtPrice = Convert.ToDouble(price); order.Destination = Globals.desination; order.ClOrderID = Guid.NewGuid().ToString(); if (restartLevels > 0) //If this is a restart scale trade and one of the initial position levels, make it a take profit instead of a restore size { order.Side = "B"; order.LmtPrice = Convert.ToDouble(price - profitOffset); restartLevels--; } int orderSuccess = order.SubmitOrder(); if (orderSuccess != 0) { Console.WriteLine("Order Error :" + order.ToString() + " - 6"); } else //Create order level then append to orderLevels list { OrderLevel orderLevel = new OrderLevel(); orderLevel.startPrice = Convert.ToDecimal(price); orderLevel.sittingOrder = order; orderLevels.Add(orderLevel); } } } orderLevels.Sort((x, y) => x.startPrice.CompareTo(y.startPrice)); //sw.Stop(); //Console.WriteLine(sw.Elapsed); foreach (OrderLevel level in orderLevels) { Console.WriteLine(level.startPrice); } } foreach (OrderLevel level in orderLevels) { Console.WriteLine("IO" + " : " + level.startPrice + " : " + level.sittingOrder.ClOrderID + " : " + level.sittingOrder.LmtPrice); } isRunning = true; return(true); }
public void Start(decimal _midPrice) { midPrice = _midPrice; ordersBelow.Clear(); ordersAbove.Clear(); //Create orders around midprice... //Closest first... List <decimal> orderPrices = new List <decimal>(); orderPrices.Add(midPrice + incrementPrice); orderPrices.Add(midPrice - incrementPrice); orderPrices.Add(midPrice + (incrementPrice * 2)); orderPrices.Add(midPrice - (incrementPrice * 2)); orderPrices.Add(midPrice + (incrementPrice * 3)); orderPrices.Add(midPrice - (incrementPrice * 3)); orderPrices.Add(midPrice + (incrementPrice * 4)); orderPrices.Add(midPrice - (incrementPrice * 4)); orderPrices.Add(midPrice + (incrementPrice * 5)); orderPrices.Add(midPrice - (incrementPrice * 5)); foreach (decimal price in orderPrices) { //Create order, execute, add to list string side = null; if (price < midPrice) { side = "B"; } if (price > midPrice) { side = "S"; } SterlingLib.STIOrder stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; if (side != null) { stiOrder.Side = side; } stiOrder.Quantity = 100; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(price); stiOrder.Destination = "BATS"; stiOrder.ClOrderID = Guid.NewGuid().ToString(); if (side == "B") { ordersBelow.Add(stiOrder); } else if (side == "S") { ordersAbove.Add(stiOrder); } } if (ordersBelow.Count == 5 && ordersAbove.Count == 5) { for (int i = 0; i <= 4; i++) { int orderStatus = ordersAbove[i].SubmitOrder(); if (orderStatus != 0) { MessageBox.Show("Order Error: " + orderStatus.ToString()); } orderStatus = ordersBelow[i].SubmitOrder(); if (orderStatus != 0) { MessageBox.Show("Order Error: " + orderStatus.ToString()); } } } }
private void OnSTIOrderUpdateXML(ref string strOrder) { if (testAlgo.status == "Stopped") { return; } XmlSerializer xs = new XmlSerializer(typeof(SterlingLib.structSTIOrderUpdate)); SterlingLib.structSTIOrderUpdate structOrder = (SterlingLib.structSTIOrderUpdate)xs.Deserialize(new StringReader(strOrder)); if (structOrder.bstrSymbol.ToUpper() == testAlgo.symbol.ToUpper() && structOrder.nOrderStatus == 5) { //Limit Order has been filled if (Convert.ToDecimal(structOrder.fLmtPrice) < testAlgo.midPrice) //Buy order has been filled { testAlgo.buyFills++; //Calculate priceMovePL if (testAlgo.currentPosition > 0) { testAlgo.priceMovePL -= testAlgo.currentPosition * testAlgo.incrementPrice; } else if (testAlgo.currentPosition < 0) { testAlgo.priceMovePL -= (testAlgo.currentPosition + testAlgo.incrementSize) * testAlgo.incrementPrice; } //Shift orders //Normal behaviour, if lists are full if (testAlgo.ordersAbove.Count == 5 && testAlgo.ordersBelow.Count == 5) { testAlgo.midPrice = Convert.ToDecimal(structOrder.fLmtPrice); //UPDATE METRICS if (testAlgo.currentPosition < 0) // If short, Add to incrementPL { testAlgo.incrementPL += testAlgo.incrementPrice * testAlgo.incrementSize; } //Update TotalPL testAlgo.totalPL = testAlgo.incrementPL + testAlgo.priceMovePL; //Update position testAlgo.currentPosition += structOrder.nQuantity; //Hard Stop Check if (-(testAlgo.totalPL) >= testAlgo.hardStop) { testAlgo.stopAndCross(); updateAlgoStatusDB("Stopped"); return; } //Move filled order to completed list, remove from active list SterlingLib.ISTIOrder filledOrder = testAlgo.ordersAbove.Find(i => i.ClOrderID == structOrder.bstrClOrderId); testAlgo.ordersBelow.RemoveAt(0); testAlgo.filledOrders.Add(filledOrder); //Insert new order below 5 orders away SterlingLib.STIOrder stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = testAlgo.symbol; stiOrder.Account = Globals.account; stiOrder.Side = "B"; stiOrder.Quantity = testAlgo.incrementSize; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(testAlgo.midPrice - (testAlgo.incrementPrice * 5)); stiOrder.Destination = "BATS"; stiOrder.ClOrderID = Guid.NewGuid().ToString(); int orderStatus = stiOrder.SubmitOrder(); if (orderStatus != 0) { MessageBox.Show("Order Error: " + orderStatus.ToString()); } else { //Add to appropriate list testAlgo.ordersBelow.Add(stiOrder); } //Cancel the "6th" order from opposite side order list SterlingLib.ISTIOrder cancelOrder = testAlgo.ordersAbove[testAlgo.ordersAbove.Count - 1]; orderMaint.CancelOrder(Globals.account, 0, cancelOrder.ClOrderID, Guid.NewGuid().ToString()); testAlgo.ordersAbove.RemoveAt(testAlgo.ordersAbove.Count - 1); //Place new order in opposite side order list int orderQuantity = testAlgo.incrementSize; //Autobalance check //If over long if (testAlgo.currentPosition >= testAlgo.autoBalance) { orderQuantity = testAlgo.incrementSize * 2; } stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = testAlgo.symbol; stiOrder.Account = Globals.account; stiOrder.Side = "S"; stiOrder.Quantity = orderQuantity; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(testAlgo.midPrice + (testAlgo.incrementPrice)); stiOrder.Destination = "BATS"; stiOrder.ClOrderID = Guid.NewGuid().ToString(); orderStatus = stiOrder.SubmitOrder(); if (orderStatus != 0) { MessageBox.Show("Order Error: " + orderStatus.ToString()); } else { //Add to appropriate list testAlgo.ordersAbove.Insert(0, stiOrder); } //If over autobalance, check orders above and adjust sizes if (testAlgo.currentPosition >= testAlgo.autoBalance) { int ifFilledPosition = testAlgo.currentPosition - testAlgo.ordersAbove[0].Quantity; for (int i = 1; i < testAlgo.bracketedOrders; i++) { //Calculation if (ifFilledPosition < testAlgo.autoBalance) { if (testAlgo.ordersAbove[i].Quantity == testAlgo.incrementSize * 2) // Order should be reverted to regular increment size { //First cancel order orderMaint.CancelOrder(Globals.account, 0, testAlgo.ordersAbove[i].ClOrderID, Guid.NewGuid().ToString()); //Then resubmit with base increment size stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = testAlgo.symbol; stiOrder.Account = Globals.account; stiOrder.Side = "S"; stiOrder.Quantity = testAlgo.incrementSize; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = testAlgo.ordersAbove[i].LmtPrice; stiOrder.Destination = "BATS"; stiOrder.ClOrderID = Guid.NewGuid().ToString(); //Remove cancelled order testAlgo.ordersAbove.RemoveAt(i); //Submit new order and add to list orderStatus = stiOrder.SubmitOrder(); if (orderStatus != 0) { MessageBox.Show("Order Error: " + orderStatus.ToString()); } else { //Add to appropriate list testAlgo.ordersAbove.Insert(i, stiOrder); } break; //Should only be one order to adjust } } ifFilledPosition -= testAlgo.ordersAbove[i].Quantity; } } } foreach (SterlingLib.ISTIOrder order in testAlgo.ordersAbove) { Debug.WriteLine(order.LmtPrice); } foreach (SterlingLib.ISTIOrder order in testAlgo.ordersBelow) { Debug.WriteLine(order.LmtPrice); } Debug.WriteLine("Buy Fills: " + testAlgo.buyFills); Debug.WriteLine("Sell Fills: " + testAlgo.sellFills); Debug.WriteLine("Current Position: " + testAlgo.currentPosition); Debug.WriteLine("Increment PL: " + testAlgo.incrementPL); Debug.WriteLine("Price Move PL: " + testAlgo.priceMovePL); Debug.WriteLine("Total PL: " + testAlgo.totalPL); Debug.WriteLine("--------------"); Debug.WriteLine("--------------"); } else if (Convert.ToDecimal(structOrder.fLmtPrice) > testAlgo.midPrice) { testAlgo.sellFills++; //Calculate priceMovePL if (testAlgo.currentPosition < 0) { testAlgo.priceMovePL += testAlgo.currentPosition * testAlgo.incrementPrice; } else if (testAlgo.currentPosition > 0) { testAlgo.priceMovePL += (testAlgo.currentPosition - testAlgo.incrementSize) * testAlgo.incrementPrice; } //Shift orders //Normal behaviour, if lists are full if (testAlgo.ordersAbove.Count == 5 && testAlgo.ordersBelow.Count == 5) { testAlgo.midPrice = Convert.ToDecimal(structOrder.fLmtPrice); //UPDATE METRICS if (testAlgo.currentPosition > 0) // If long, Add to incrementPL { testAlgo.incrementPL += testAlgo.incrementPrice * testAlgo.incrementSize; } testAlgo.currentPosition -= structOrder.nQuantity; //Update position //Update TotalPL testAlgo.totalPL = testAlgo.incrementPL + testAlgo.priceMovePL; //Hard Stop Check if (-(testAlgo.totalPL) >= testAlgo.hardStop) { testAlgo.stopAndCross(); updateAlgoStatusDB("Stopped"); return; } //Move filled order to completed list, remove from active list SterlingLib.ISTIOrder filledOrder = testAlgo.ordersAbove.Find(i => i.ClOrderID == structOrder.bstrClOrderId); testAlgo.ordersAbove.RemoveAt(0); testAlgo.filledOrders.Add(filledOrder); //Insert new order above 5 orders away SterlingLib.STIOrder stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = testAlgo.symbol; stiOrder.Account = Globals.account; stiOrder.Side = "S"; stiOrder.Quantity = testAlgo.incrementSize; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(testAlgo.midPrice + (testAlgo.incrementPrice * 5)); stiOrder.Destination = "BATS"; stiOrder.ClOrderID = Guid.NewGuid().ToString(); int orderStatus = stiOrder.SubmitOrder(); if (orderStatus != 0) { MessageBox.Show("Order Error: " + orderStatus.ToString()); } else { //Add to appropriate list testAlgo.ordersAbove.Add(stiOrder); } //Cancel the "6th" order from opposite side order list SterlingLib.ISTIOrder cancelOrder = testAlgo.ordersBelow[testAlgo.ordersBelow.Count - 1]; orderMaint.CancelOrder(Globals.account, 0, cancelOrder.ClOrderID, Guid.NewGuid().ToString()); testAlgo.ordersBelow.RemoveAt(testAlgo.ordersBelow.Count - 1); //Place new order in opposite side order list //Autobalance check int orderQuantity = testAlgo.incrementSize; //If over short if (testAlgo.currentPosition <= -(testAlgo.autoBalance)) { orderQuantity = testAlgo.incrementSize * 2; } stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = testAlgo.symbol; stiOrder.Account = Globals.account; stiOrder.Side = "B"; stiOrder.Quantity = orderQuantity; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(testAlgo.midPrice - (testAlgo.incrementPrice)); stiOrder.Destination = "BATS"; stiOrder.ClOrderID = Guid.NewGuid().ToString(); orderStatus = stiOrder.SubmitOrder(); if (orderStatus != 0) { MessageBox.Show("Order Error: " + orderStatus.ToString()); } else { //Add to appropriate list testAlgo.ordersBelow.Insert(0, stiOrder); } //If over autobalance, check orders above and adjust sizes if (testAlgo.currentPosition <= -(testAlgo.autoBalance)) { int ifFilledPosition = testAlgo.currentPosition + testAlgo.ordersBelow[0].Quantity; for (int i = 1; i < testAlgo.bracketedOrders; i++) { //Calculation if (ifFilledPosition > -(testAlgo.autoBalance)) { if (testAlgo.ordersBelow[i].Quantity == testAlgo.incrementSize * 2) // Order should be reverted to regular increment size { //First cancel order orderMaint.CancelOrder(Globals.account, 0, testAlgo.ordersBelow[i].ClOrderID, Guid.NewGuid().ToString()); //Then resubmit with base increment size stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = testAlgo.symbol; stiOrder.Account = Globals.account; stiOrder.Side = "B"; stiOrder.Quantity = testAlgo.incrementSize; stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = testAlgo.ordersBelow[i].LmtPrice; stiOrder.Destination = "BATS"; stiOrder.ClOrderID = Guid.NewGuid().ToString(); //Remove cancelled order testAlgo.ordersBelow.RemoveAt(i); //Submit new order and add to list orderStatus = stiOrder.SubmitOrder(); if (orderStatus != 0) { MessageBox.Show("Order Error: " + orderStatus.ToString()); } else { //Add to appropriate list testAlgo.ordersBelow.Insert(i, stiOrder); } break; //Should only be one order to adjust } } ifFilledPosition += testAlgo.ordersBelow[i].Quantity; } } } Debug.WriteLine("Mid Price: " + testAlgo.midPrice); Debug.WriteLine("--------------"); foreach (SterlingLib.ISTIOrder order in testAlgo.ordersAbove) { Debug.WriteLine(order.LmtPrice); } foreach (SterlingLib.ISTIOrder order in testAlgo.ordersBelow) { Debug.WriteLine(order.LmtPrice); } Debug.WriteLine("Buy Fills: " + testAlgo.buyFills); Debug.WriteLine("Sell Fills: " + testAlgo.sellFills); Debug.WriteLine("Current Position: " + testAlgo.currentPosition); Debug.WriteLine("Increment PL: " + testAlgo.incrementPL); Debug.WriteLine("Price Move PL: " + testAlgo.priceMovePL); Debug.WriteLine("Total PL: " + testAlgo.totalPL); Debug.WriteLine("--------------"); Debug.WriteLine("--------------"); } } }
private void button2_Click(object sender, EventArgs e) //Initiate Scale Trade { //if (!errorChecker()) return; //Error checker if (direction == "B") { //fill 1 //Create take profit order SterlingLib.STIOrder stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = "S"; stiOrder.Quantity = Convert.ToInt32(fill1[0]); stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(fill1[1]); stiOrder.Destination = Globals.desination; stiOrder.ClOrderID = Guid.NewGuid().ToString(); //Submit order int ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString()); } else //No error, add to current order list { currentOrders.Add(stiOrder); } //fill 2 stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = "S"; stiOrder.Quantity = Convert.ToInt32(fill2[0]); stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(fill2[1]); stiOrder.Destination = Globals.desination; stiOrder.ClOrderID = Guid.NewGuid().ToString(); //Submit order ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString()); } else //No error, new sitting order is the new "buy" order (restore size order) { currentOrders.Add(stiOrder); } //fill 3 stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = "S"; stiOrder.Quantity = Convert.ToInt32(fill3[0]); stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(fill3[1]); stiOrder.Destination = Globals.desination; stiOrder.ClOrderID = Guid.NewGuid().ToString(); //Submit order ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString()); } else //No error, new sitting order is the new "buy" order (restore size order) { currentOrders.Add(stiOrder); } } else if (direction == "S") { //fill 1 //Create take profit order SterlingLib.STIOrder stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = "B"; stiOrder.Quantity = Convert.ToInt32(fill1[0]); stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(fill1[1]); stiOrder.Destination = Globals.desination; stiOrder.ClOrderID = Guid.NewGuid().ToString(); //Submit order int ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString()); } else //No error, new sitting order is the new "buy" order (restore size order) { currentOrders.Add(stiOrder); } //fill 2 stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = "B"; stiOrder.Quantity = Convert.ToInt32(fill2[0]); stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(fill2[1]); stiOrder.Destination = Globals.desination; stiOrder.ClOrderID = Guid.NewGuid().ToString(); //Submit order ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString()); } else //No error, new sitting order is the new "buy" order (restore size order) { currentOrders.Add(stiOrder); } //fill 3 stiOrder = new SterlingLib.STIOrder(); stiOrder.Symbol = symbol; stiOrder.Account = Globals.account; stiOrder.Side = "B"; stiOrder.Quantity = Convert.ToInt32(fill3[0]); stiOrder.Tif = "D"; //day order stiOrder.PriceType = SterlingLib.STIPriceTypes.ptSTILmt; stiOrder.LmtPrice = Convert.ToDouble(fill3[1]); stiOrder.Destination = Globals.desination; stiOrder.ClOrderID = Guid.NewGuid().ToString(); //Submit order ord = stiOrder.SubmitOrder(); if (ord != 0) { MessageBox.Show("Order Error: " + ord.ToString()); } else //No error, new sitting order is the new "buy" order (restore size order) { currentOrders.Add(stiOrder); } } isRunning = true; button1.Enabled = true; }