// Stock trading lot(qty) for orders //private int mStockTradingLot; //protected int StockTradingLot //{ // get { lock (lockObjectProperties) { return mStockTradingLot; } } // set { lock (lockObjectProperties) { mStockTradingLot = value; } } //} public BrokerErrorCode RunCoreAlgo() { #region SimpleBuySellPairSquareAlgo bool bCancelPairOrder = false; string stockCode = stockInfo.StockCode; int stockExchange = stockInfo.MainExchange == Exchange.NSE ? 0 : 1; BrokerErrorCode errorCode = BrokerErrorCode.Unknown; int tryCnt = 0; while (errorCode != BrokerErrorCode.Success && tryCnt <= 5) { // refresh stock state (doesnt have price info) errorCode = EquityStockState.EquityRefreshStockStateToday(mBroker, stockInfo); if (errorCode == BrokerErrorCode.NotLoggedIn) { mBroker.LogOut(); errorCode = mBroker.CheckAndLogInIfNeeded(true); tryCnt++; } } string traceString = "RefreshEquityStockStateToday: " + errorCode.ToString(); FileTracing.TraceOut(traceString); if (errorCode.Equals(BrokerErrorCode.Success)) { // If no buy or sell order pending, i.e. the square-off pair orders have executed // then place a pair of fresh buy-sell orders if (!(stockInfo.IsAnyOutstandingBuyOrder() || stockInfo.IsAnyOutstandingSellOrder() )) { // Place buy-sell order pair // Get latest quote EquitySymbolQuote[] stockPrice; errorCode = mBroker.GetEquityQuote(stockCode, out stockPrice); if (!errorCode.Equals(BrokerErrorCode.Success)) { return(errorCode); } // Generate orders List <EquityOrderRecord> generatedOrders = new List <EquityOrderRecord>(); string BidPrice; string OfferPrice; // price decision // First orders, only if market not open and it is first order pair if ((stockInfo.NumTrades == 0) && !MarketUtils.IsMarketOpen()) { double closePrice = stockPrice[stockExchange].PreviousClosePriceDouble; if (algoParams.initBidPrice > 0) { BidPrice = algoParams.initBidPrice.ToString(); } else { decimal buy = (decimal)(closePrice - (2.0 / 100 * closePrice));//prevclose - 3% buy = decimal.Subtract(buy, 0.05M); buy = decimal.Round(buy, 1); BidPrice = buy.ToString(); } if (algoParams.initOfferPrice > 0) { OfferPrice = algoParams.initOfferPrice.ToString(); } else { decimal sell = (decimal)(closePrice + (2.0 / 100 * closePrice));//prevclose + 3% sell = decimal.Add(sell, 0.05M); sell = decimal.Round(sell, 1, MidpointRounding.AwayFromZero); OfferPrice = sell.ToString(); } } // Subsequent orders // TODO: May put time conditions or market volatility conditions here in else if else { double ltp = stockPrice[stockExchange].LastTradePriceDouble; decimal buy = (decimal)(ltp - ((double)(0.85 / 100) * ltp));//prevclose - 0.85% buy = decimal.Subtract(buy, 0.05M); buy = decimal.Round(buy, 1); BidPrice = buy.ToString(); decimal sell = (decimal)(ltp + ((double)(0.85 / 100) * ltp));//prevclose + 0.85% sell = decimal.Add(sell, 0.05M); sell = decimal.Round(sell, 1, MidpointRounding.AwayFromZero); OfferPrice = sell.ToString(); } // Buy generatedOrders.Add(new EquityOrderRecord(stockCode, algoParams.StockTradingLot, BidPrice, OrderPriceType.LIMIT, OrderDirection.BUY, stockInfo.MainExchange, EquityOrderType.DELIVERY, "0", "0")); if (!bGenerateASingleBuyOrderAtStart) { // Sell generatedOrders.Add(new EquityOrderRecord(stockCode, algoParams.StockTradingLot, OfferPrice, OrderPriceType.LIMIT, OrderDirection.SELL, stockInfo.MainExchange, EquityOrderType.DELIVERY, "0", "0")); } List <BrokerErrorCode> errorCodes = null; // Validate orders List <EquityOrderRecord> ordersToPlace = stockInfo.ReturnFilteredValidOrders(generatedOrders); // Place validated orders errorCodes = mBroker.PlaceMultipleEquityOrders(ordersToPlace, 5); traceString = "Stock: " + stockInfo.StockCode + " :PlaceMultipleEquityOrders: 2\n"; int o = 0; foreach (BrokerErrorCode errCodeEach in errorCodes) { EquityOrderRecord order = ordersToPlace[o++]; traceString = traceString + order.OrderDirection.ToString() + "-" + order.Quantity.ToString() + " at " + order.Price + ": " + errCodeEach.ToString() + "\n"; // Place Order failed if (!errCodeEach.Equals(BrokerErrorCode.Success)) { // Cancel both the orders bCancelPairOrder = true; } } FileTracing.TraceOut(traceString); // Even if any one of the orders failed to place, cancel the pair if (bCancelPairOrder) { errorCode = BrokerUtils.CancelStockOutstandingOrdersAndTrace(mBroker, stockCode); } } } return(errorCode); #endregion }
// Stock algo worker thread public static void Background_StockWorkerThread(object obj) { BrokerErrorCode errorCode = BrokerErrorCode.Success; BrokerSymbolAlgosObject stockTraderObj = (BrokerSymbolAlgosObject)obj; IBroker broker = stockTraderObj.Broker; //EquityStockTradeStats stockInfo = stockTraderObj.stockInfo; ITradingAlgo algo = stockTraderObj.Algos[0]; // Thread local params int threadRunCount = 0; int threadFailCount = 0; //string stockCode = stockInfo.StockCode; string traceString; bool bChecked = false; // On program re-run, cancel any previous outstanding orders // BUGBUGCD: is this infinite loop necessary or try only once // and come out on failure do { errorCode = algo.Prolog(); if (!errorCode.Equals(BrokerErrorCode.Success)) { Thread.Sleep(1000 * 30); } } while (!stockTraderObj.DoStopThread && !errorCode.Equals(BrokerErrorCode.Success)); while (!stockTraderObj.DoStopThread) { // Main Algo errorCode = algo.RunCoreAlgo(); // thread stats if (!errorCode.Equals(BrokerErrorCode.Success)) { threadFailCount++; } threadRunCount++; // Check remote control //ProgramRemoteControl remoteControlValue = CheckRemoteControlInAlgo(ref bChecked); //if (remoteControlValue.Equals(ProgramRemoteControl.STOP) || // remoteControlValue.Equals(ProgramRemoteControl.HIBERNATE)) // break; // Check if login problem if (errorCode == BrokerErrorCode.NotLoggedIn) { FileTracing.TraceOut("AlgoRunner: " + errorCode.ToString() + " Trying to login again\n"); // MGOYAL: TEMP SLEEP this is for external login to do some work . // External logger will have 2 minute (CheckAndLoginIfNeeded) window to complete a work before he is logged out. // Sleep for a minute // It means someone has stolen session, so let it be. if they need for more time then will set remote to PAUSE Thread.Sleep(120000); broker.LogOut(); errorCode = broker.CheckAndLogInIfNeeded(true); continue; } if (errorCode == BrokerErrorCode.InvalidLoginPassword || errorCode == BrokerErrorCode.ChangePassword) { FileTracing.TraceOut("AlgoRunner: InvalidLoginPassword, Exiting"); break; } Thread.Sleep(algo.GetSleepTimeInMilliSecs()); } errorCode = algo.Epilog(); // Trace out Thread run stats // TODO: more such fancy stuff later traceString = string.Format("AlgoRunner: Thread Run Stats: \nTotalRuns: {0}\nFailures: {1}\nFailurePercentagH: {2}", threadRunCount, threadFailCount, (double)(threadFailCount / (threadRunCount > 0 ? threadRunCount : 1)) * 100); FileTracing.TraceOut(traceString); }