public override void StockBuySell() { Init(AlgoType.SimultaneousBuySell); while (MarketUtils.IsMarketOpen()) { try { var newTrades = new Dictionary <string, EquityTradeBookRecord>(); // refresh trade book errCode = broker.GetEquityTradeBookToday(true, stockCode, out newTrades); if (newTrades.Count > 0) { var trade = newTrades.First().Value; Trace(string.Format(tradeTraceFormat, stockCode, trade.Direction == OrderDirection.BUY ? "bought" : "sold", trade.Quantity, trade.Price, newTrades.ContainsKey(holdingSellOrderRef) ? "CASH" : "MARGIN")); if (newTrades.ContainsKey(todayOutstandingBuyOrderRef)) { todayOutstandingQty += trade.Quantity; todayOutstandingPrice = trade.Price; todayOutstandingBuyOrderRef = ""; } else if (newTrades.ContainsKey(todayOutstandingSellOrderRef)) { todayOutstandingQty -= trade.Quantity; todayOutstandingPrice = trade.Price; todayOutstandingSellOrderRef = ""; } else if (newTrades.ContainsKey(holdingSellOrderRef)) { holdingOutstandingQty = 0; holdingOutstandingPrice = 0; holdingSellOrderRef = ""; UpdatePositionFile(holdingOutstandingQty, holdingOutstandingPrice, holdingSellOrderRef); } else { // upstox squared off the sell. verify it and cancel the buy order if (trade.Direction == OrderDirection.BUY) { CancelEquityOrder("Broker squared off the sell", todayOutstandingBuyOrderRef, trade.Direction); todayOutstandingQty += trade.Quantity; todayOutstandingPrice = trade.Price; todayOutstandingBuyOrderRef = ""; } } } // if order time is within range and today's buy order count is below max then only place pair if (IsOrderTimeWithinRange() && string.IsNullOrEmpty(todayOutstandingBuyOrderRef) && string.IsNullOrEmpty(todayOutstandingSellOrderRef) && buyOrderCount < maxBuyOrders && (todayOutstandingQty + holdingOutstandingQty) < maxAllowedOutstandingQty) { // no pair existing, place a pair order // place buy order, update buy order ref var buyPrice = GetBuyPrice(); errCode = PlaceEquityOrder(stockCode, ordQty, buyPrice.ToString(), OrderPriceType.LIMIT, OrderDirection.BUY, EquityOrderType.MARGIN, Exchange.NSE, out todayOutstandingBuyOrderRef); // place new sell order, update sell order ref var sellPrice = GetSellPrice(buyPrice, false); errCode = PlaceEquityOrder(stockCode, ordQty, sellPrice.ToString(), OrderPriceType.LIMIT, OrderDirection.SELL, EquityOrderType.MARGIN, Exchange.NSE, out todayOutstandingSellOrderRef); } else if (MarketUtils.IsTimeAfter3() && (!string.IsNullOrEmpty(todayOutstandingBuyOrderRef) && !string.IsNullOrEmpty(todayOutstandingSellOrderRef))) { // if existing pair is unexecuted, then cancel the pair Trace("Cancelling the pair orders as no side is executed and its past 3 pm"); errCode = CancelEquityOrder("Unexecuted Pair cancellation", todayOutstandingBuyOrderRef, OrderDirection.BUY); if (errCode == BrokerErrorCode.Success) { todayOutstandingBuyOrderRef = ""; } errCode = CancelEquityOrder("Unexecuted Pair cancellation", todayOutstandingSellOrderRef, OrderDirection.SELL); if (errCode == BrokerErrorCode.Success) { todayOutstandingSellOrderRef = ""; } } TrySquareOffNearEOD(AlgoType.SimultaneousBuySell); } catch (Exception ex) { Trace("Error:" + ex.Message + "\nStacktrace:" + ex.StackTrace); } if (MarketUtils.IsTimeAfter325()) { ConvertToDeliveryAndUpdatePositionFile(); } PauseBetweenTradeBookCheck(); } ConvertToDeliveryAndUpdatePositionFile(); }
// Try min profit squareoff first between 3 - 3.10 time. // From 3.10 to 3.15 time if squareoff of all positions is set to true and the ltp diff meets threshold for max loss pct, then do a market order squareoff public void TrySquareOffNearEOD(AlgoType algoType) { // if after 3 pm, then try to square off in at least no profit no loss if possible. either buy or sell is outstanding if (MarketUtils.IsTimeAfter3()) { var ordPriceType = OrderPriceType.LIMIT; var doUpdateOrders = false; // 3.10 - 3.15 pm time. market order type for forced square off given pct loss is within acceptable range // do it before 3.15, otherwise broker will try to squareoff on its own anytime between 3.15 - 3.30 if (MarketUtils.IsTimeAfter310() && !MarketUtils.IsTimeAfter315() && squareOffAllPositionsAtEOD && !isEODMinLossSquareOffMarketOrderUpdated) { var ltp = GetLTP(); ordPriceType = OrderPriceType.MARKET; var diff = Math.Abs((ltp - todayOutstandingPrice) / ltp); if (diff < pctMaxLossSquareOffPositions && todayOutstandingPrice > goodPrice) { Trace(string.Format("TrySquareOffNearEOD: max loss % {0} is within acceptable range of {1} and avg outstanding price {2} is greater than good price of {3}. Update squareoff at MARKET price type.", diff, pctMaxLossSquareOffPositions, todayOutstandingPrice, goodPrice)); doUpdateOrders = true; isEODMinLossSquareOffMarketOrderUpdated = true; } } // 3 - 3.10 pm time. try simple limit order with min profit price else if (!isEODMinProfitSquareOffLimitOrderUpdated) { Trace(string.Format("TrySquareOffNearEOD: Update squareoff LIMIT order with min profit % price or cancel outstanding orders")); ordPriceType = OrderPriceType.LIMIT; isEODMinProfitSquareOffLimitOrderUpdated = true; doUpdateOrders = true; } if (doUpdateOrders) { if (algoType == AlgoType.AverageTheBuyThenSell) { // just cancel the outstanding buy order if (!string.IsNullOrEmpty(todayOutstandingBuyOrderRef)) { // cancel existing buy order errCode = CancelEquityOrder("(EOD squareoff) @ " + ordPriceType, ref todayOutstandingBuyOrderRef, OrderDirection.BUY); } // bought qty needs square off. there is outstanding sell order, revise the price to try square off if (!string.IsNullOrEmpty(todayOutstandingSellOrderRef)) { // cancel existing sell order errCode = CancelEquityOrder("(EOD squareoff) @ " + ordPriceType, ref todayOutstandingSellOrderRef, OrderDirection.SELL); if (errCode == BrokerErrorCode.Success) { todayOutstandingSellOrderRef = ""; // place new sell order, update sell order ref Trace("Placing EOD squareoff updated order"); var sellPrice = GetSellPrice(todayOutstandingPrice, false, true); errCode = PlaceEquityOrder(stockCode, todayOutstandingQty, sellPrice.ToString(), ordPriceType, OrderDirection.SELL, EquityOrderType.MARGIN, exchange, out todayOutstandingSellOrderRef); } } } else if (algoType == AlgoType.SimultaneousBuySell) { // if there is an outstanding order pair, just cancel both if (!string.IsNullOrEmpty(todayOutstandingBuyOrderRef) && !string.IsNullOrEmpty(todayOutstandingSellOrderRef)) { // cancel existing sell order errCode = CancelEquityOrder("(EOD squareoff) @ " + ordPriceType, ref todayOutstandingSellOrderRef, OrderDirection.SELL); // cancel existing buy order errCode = CancelEquityOrder("(EOD squareoff) @ " + ordPriceType, ref todayOutstandingBuyOrderRef, OrderDirection.BUY); } // bought qty needs square off. there is outstanding sell order, revise the price to try square off else if (string.IsNullOrEmpty(todayOutstandingBuyOrderRef) && !string.IsNullOrEmpty(todayOutstandingSellOrderRef)) { // cancel existing sell order errCode = CancelEquityOrder("(EOD squareoff) @ " + ordPriceType, ref todayOutstandingSellOrderRef, OrderDirection.SELL); if (errCode == BrokerErrorCode.Success) { todayOutstandingSellOrderRef = ""; // place new sell order, update sell order ref Trace("Placing EOD squareoff updated order"); var sellPrice = GetSellPrice(todayOutstandingPrice, false, true); errCode = PlaceEquityOrder(stockCode, ordQty, sellPrice.ToString(), ordPriceType, OrderDirection.SELL, EquityOrderType.MARGIN, exchange, out todayOutstandingSellOrderRef); } } // sold qty needs square off. there is outstanding buy order, revise the price to try square off else if (string.IsNullOrEmpty(todayOutstandingSellOrderRef) && !string.IsNullOrEmpty(todayOutstandingBuyOrderRef)) { // cancel existing buy order errCode = CancelEquityOrder("(EOD squareoff) @ " + ordPriceType, ref todayOutstandingBuyOrderRef, OrderDirection.BUY); if (errCode == BrokerErrorCode.Success) { todayOutstandingBuyOrderRef = ""; // place new buy order, update buy order ref Trace("Placing EOD squareoff updated order"); var buyPrice = GetBuySquareOffPrice(todayOutstandingPrice); errCode = PlaceEquityOrder(stockCode, ordQty, buyPrice.ToString(), ordPriceType, OrderDirection.BUY, EquityOrderType.MARGIN, exchange, out todayOutstandingBuyOrderRef); } } } } } }