Ejemplo n.º 1
0
        public void StartCapturingMarketTrend()
        {
            try
            {
                EquitySymbolQuote quote;
                errCode = myUpstoxWrapper.GetSnapQuote(exchStr, stockCode, out quote);

                myUpstoxWrapper.Upstox.QuotesReceivedEvent += new Upstox.QuotesReceivedEventEventHandler(QuoteReceived);
                var substatus = myUpstoxWrapper.Upstox.SubscribeQuotes(exchStr, stockCode);
                Trace(string.Format("SubscribeQuotes status={0}", substatus));
            }
            catch (Exception ex)
            {
                Trace(string.Format("{0} Error: {1} \nStacktrace:{2}", stockCode, ex.Message, ex.StackTrace));
                throw;
            }

            while (MarketUtils.IsMarketOpen())
            {
                try
                {
                    if (quote != null)
                    {
                        var changePct = (quote.LTP - quote.Close) / quote.Close;

                        var prevmktTrendFactorForBuyMarkdown = mktTrendFactorForBuyMarkdown;

                        if (changePct < -0.005)
                        {
                            mktTrendFactorForBuyMarkdown = 1.2;
                        }
                        else if (changePct < -0.01)
                        {
                            mktTrendFactorForBuyMarkdown = 1.5;
                        }
                        else if (changePct < -0.015)
                        {
                            mktTrendFactorForBuyMarkdown = 2;
                        }
                        else
                        {
                            mktTrendFactorForBuyMarkdown = 1;
                        }

                        if (prevmktTrendFactorForBuyMarkdown != mktTrendFactorForBuyMarkdown)
                        {
                            Trace(string.Format("MarketTrendForBuyMarkdown changed from {0} to {1}. Nifty changePct={2}", prevmktTrendFactorForBuyMarkdown, mktTrendFactorForBuyMarkdown, Math.Round(changePct, 5)));
                        }
                    }
                }
                catch (Exception ex)
                {
                    Trace("Error:" + ex.Message + "\nStacktrace:" + ex.StackTrace);
                }

                Thread.Sleep(1000 * 15);
            }
        }
        public override void StockBuySell()
        {
            try
            {
                myUpstoxWrapper.Upstox.TradeUpdateEvent    += new Upstox.TradeUpdateEventEventHandler(TradeUpdated);
                myUpstoxWrapper.Upstox.OrderUpdateEvent    += new Upstox.OrderUpdateEventEventHandler(OrderUpdated);
                myUpstoxWrapper.Upstox.PositionUpdateEvent += new Upstox.PositionUpdateEventEventHandler(PositionUpdated);
                Init(AlgoType.AverageTheBuyThenSell);
            }
            catch (Exception ex)
            {
                Trace(string.Format("{0} Error: {1} \nStacktrace:{2}", stockCode, ex.Message, ex.StackTrace));
                throw;
            }

            while (MarketUtils.IsMarketOpen())
            {
                try
                {
                    PlaceBuyOrderIfEligible();
                    HandleConversionAnytimeNew();

                    if (MarketUtils.IsTimeAfter3XMin(0))
                    {
                        NearEODSquareOffAndCancelBuyOrder();
                    }

                    if (MarketUtils.IsTimeAfter3XMin(29))
                    {
                        CancelOpenOrders();
                    }
                }
                catch (Exception ex)
                {
                    Trace("Error:" + ex.Message + "\nStacktrace:" + ex.StackTrace);
                }

                MainLoopPause();
            }

            EODProcess(true); // EOD final update
        }
Ejemplo n.º 3
0
        public override void StockBuySell()
        {
            Init();

            // place buy order if eligible: if there is no pending buy order and if totaloutstanding qt is less than maxoutstanding
            if (string.IsNullOrEmpty(buyOrderRef) && todayOutstandingQty == 0 && (todayOutstandingQty + holdingOutstandingQty) < maxOutstandingQty)
            {
                // place buy order, update buy order ref
                var buyPrice = GetBuyPrice();
                errCode = PlaceMarginOrder(stockCode, ordQty, buyPrice.ToString(), OrderPriceType.LIMIT, OrderDirection.BUY, EquityOrderType.MARGIN, exchange, out buyOrderRef);
            }

            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 buy executed, then place a corresponding margin sell order
                        if (newTrades.ContainsKey(buyOrderRef))
                        {
                            // update outstanding qty and outstanding price to place updated sell order
                            todayOutstandingQty   = trade.Quantity;
                            todayOutstandingPrice = trade.Price;

                            settlementNumber = trade.SettlementNumber;

                            // place new sell order, update sell order ref
                            var sellPrice = GetSellPrice(todayOutstandingPrice, false);
                            errCode = PlaceMarginOrder(stockCode, ordQty, sellPrice.ToString(), OrderPriceType.LIMIT, OrderDirection.SELL, EquityOrderType.MARGIN, exchange, out sellOrderRef);
                        }

                        // if sell executed, then place a fresh buy order
                        if (newTrades.ContainsKey(sellOrderRef))
                        {
                            todayOutstandingQty   = 0;
                            todayOutstandingPrice = 0;

                            if (string.IsNullOrEmpty(buyOrderRef))
                            {
                                if (buyOrderCount >= maxBuyOrders)
                                {
                                    break;
                                }

                                // place buy order, update buy order ref
                                var buyPrice = GetBuyPrice();
                                errCode = PlaceMarginOrder(stockCode, ordQty, buyPrice.ToString(), OrderPriceType.LIMIT, OrderDirection.BUY, EquityOrderType.MARGIN, exchange, out buyOrderRef);
                            }
                        }

                        // if holding sell executed
                        if (newTrades.ContainsKey(holdingSellOrderRef))
                        {
                            holdingOutstandingQty   = 0;
                            holdingOutstandingPrice = 0;
                            holdingSellOrderRef     = "";

                            var positionStr = string.Format("{0} {1} {2}", todayOutstandingQty, todayOutstandingPrice, holdingSellOrderRef);
                            File.WriteAllText(positionFile, positionStr);

                            if (string.IsNullOrEmpty(buyOrderRef) && todayOutstandingQty == 0)
                            {
                                if (buyOrderCount >= maxBuyOrders)
                                {
                                    break;
                                }

                                // place buy order if eligible: if there is no pending buy order and if totaloutstanding qt is less than maxoutstanding
                                if ((todayOutstandingQty + holdingOutstandingQty) < maxOutstandingQty)
                                {
                                    // place buy order, update buy order ref
                                    var buyPrice = GetBuyPrice();
                                    errCode = PlaceMarginOrder(stockCode, ordQty, buyPrice.ToString(), OrderPriceType.LIMIT, OrderDirection.BUY, EquityOrderType.MARGIN, exchange, out buyOrderRef);
                                }
                            }
                        }
                    }

                    TrySquareOffNearEOD();
                }
                catch (Exception ex)
                {
                    Trace("Error:" + ex.Message + "\nStacktrace:" + ex.StackTrace);
                }

                Thread.Sleep(1000 * 90);
            }

            // convert to delivery any open buy position
            ConvertToDeliveryAndUpdatePositionFile();
        }
        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();
        }
Ejemplo n.º 5
0
        public BrokerErrorCode Prolog()
        {
            BrokerErrorCode errorCode   = BrokerErrorCode.Success;
            string          traceString = "Algo1_SimplePairedBuySellDelivery.Prolog :: ENTER";

            FileTracing.TraceOut(traceString);

            if (algoParams.bCancelOutstandingOrdersAtStart)
            {
                errorCode = BrokerUtils.CancelStockOutstandingOrdersAndTrace(mBroker, stockCode);
            }
            if (!algoParams.bStartAFresh)
            {
                // Start from last run state and try to be in pair-execute state
                // There may be less than or equal to 1 lot of stock as long or short
                // Pick up the last trade from xml
                // TODO:
            }
            // Get latest quote
            EquitySymbolQuote[] stockPrice;

            errorCode = mBroker.GetEquityQuote(stockCode, out stockPrice);

            if (!errorCode.Equals(BrokerErrorCode.Success))
            {
                return(errorCode);
            }

            int stockExchange = stockInfo.MainExchange == Exchange.NSE ? 0 : 1;

            double buyOrderValue = (stockPrice[stockExchange].LastTradePriceDouble * algoParams.StockTradingLot);

            buyOrderValue += stockInfo.EstimatedBrokerage(buyOrderValue);


            // Erroneous conditions get out, do later
            // TODO: right now assume stock abvailable is at least = stock trading lot
            // and assume limit is available
            //if(stockInfo.StockAvailableAtStart <


            // TODO: find better alternative to fit this variable
            if ((stockInfo.StockAvailableAtStart < algoParams.StockTradingLot) && (stockInfo.FundLimitAtStart >= 2 * buyOrderValue))
            {
                // This means first buy the stock, then start trading it
                bGenerateASingleBuyOrderAtStart = true;
            }
            else if (stockInfo.StockAvailableAtStart < algoParams.StockTradingLot)
            {
                errorCode = BrokerErrorCode.InValidArg;
            }

            if (!bGenerateASingleBuyOrderAtStart && errorCode.Equals(BrokerErrorCode.Success))
            {
                // There should be suficient stock to place a sell order to generate limit first
                // and then for the pair-orders
                // stockavailable should be at least twice the trading lot
                if ((stockInfo.FundLimitAtStart < buyOrderValue) && (stockInfo.StockAvailableAtStart >= 2 * algoParams.StockTradingLot))
                {
                    // Generate a sell order
                    bGenerateASingleSellOrderAtStart = true;
                }
                else if (stockInfo.FundLimitAtStart < buyOrderValue)
                {
                    errorCode = BrokerErrorCode.InValidArg;
                }
            }

            string         price          = "1";
            bool           bGenerateOrder = false;
            OrderDirection orderDirection = OrderDirection.BUY;

            // BUY order
            if (bGenerateASingleBuyOrderAtStart)
            {
                // price decision
                if (algoParams.initBidPrice > 0)
                {
                    price = algoParams.initBidPrice.ToString();
                }
                // First orders, only if market not open and it is first order pair
                else if (!MarketUtils.IsMarketOpen())
                {
                    double closePrice = stockPrice[stockExchange].PreviousClosePriceDouble;

                    decimal buy = (decimal)(closePrice - ((double)(3.0 / 100) * closePrice));//prevclose - 3%
                    buy   = decimal.Subtract(buy, 0.05M);
                    buy   = decimal.Round(buy, 1);
                    price = buy.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.65 / 100) * ltp));//prevclose - 0.65%
                    buy   = decimal.Subtract(buy, 0.05M);
                    buy   = decimal.Round(buy, 1);
                    price = buy.ToString();
                }
                orderDirection = OrderDirection.BUY;
                bGenerateASingleBuyOrderAtStart = false;
                bGenerateOrder = true;
            }


            // SELL order
            if (bGenerateASingleSellOrderAtStart)
            {
                // price decision
                if (algoParams.initOfferPrice > 0)
                {
                    price = algoParams.initOfferPrice.ToString();
                }
                // First orders, only if market not open and it is first order pair
                if (!MarketUtils.IsMarketOpen())
                {
                    double closePrice = stockPrice[stockExchange].PreviousClosePriceDouble;

                    decimal sell = (decimal)(closePrice + (3.0 / 100 * closePrice));//prevclose + 3%
                    sell  = decimal.Add(sell, 0.05M);
                    sell  = decimal.Round(sell, 1, MidpointRounding.AwayFromZero);
                    price = sell.ToString();
                }
                // Subsequent orders
                // TODO: May put time conditions or market volatility conditions here in else if
                else
                {
                    double ltp = stockPrice[stockExchange].LastTradePriceDouble;

                    decimal sell = (decimal)(ltp + (0.65 / 100 * ltp));//prevclose + 0.65%
                    sell  = decimal.Add(sell, 0.05M);
                    sell  = decimal.Round(sell, 1, MidpointRounding.AwayFromZero);
                    price = sell.ToString();
                }

                orderDirection = OrderDirection.SELL;
                bGenerateASingleSellOrderAtStart = false;
                bGenerateOrder = true;
            }

            if (bGenerateOrder)
            {
                // Generate orders
                List <EquityOrderRecord> generatedOrders = new List <EquityOrderRecord>
                {
                    new EquityOrderRecord(stockCode,
                                          algoParams.StockTradingLot,
                                          price, OrderPriceType.LIMIT,
                                          orderDirection,
                                          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 = "Algo1_SimplePairedBuySellDelivery.Prolog\n" + "Stock: " + stockInfo.StockCode + " :PlaceMultipleEquityOrders: 1\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";

                    errorCode = errCodeEach;
                }
                FileTracing.TraceOut(traceString);
            }
            traceString = "Algo1_SimplePairedBuySellDelivery.Prolog :: EXIT";
            FileTracing.TraceOut(traceString);

            return(errorCode);
        }
Ejemplo n.º 6
0
        // 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
        }
Ejemplo n.º 7
0
        public override void StockBuySell()
        {
            try
            {
                Init(AlgoType.AverageTheBuyThenSell);
            }
            catch (Exception ex)
            {
                Trace("Error:" + ex.Message + "\nStacktrace:" + ex.StackTrace);
                throw;
            }

            while (MarketUtils.IsMarketOpen())
            {
                try
                {
                    // Try to convert to delivery pending open positions (nearing expiry) from previous days
                    ConvertToDeliveryPreviousDaysExpiringOpenPositions();

                    var holdingTradesRef = holdingsOrders.Select(h => h.OrderRef);

                    {
                        var newTrades = new Dictionary <string, EquityTradeBookRecord>();
                        // refresh trade book
                        errCode = broker.GetEquityTradeBookToday(true, stockCode, out newTrades);

                        foreach (var tradeKv in newTrades.OrderBy(t => t.Value.Direction).Reverse())
                        {
                            var tradeRef = tradeKv.Key;
                            var trade    = tradeKv.Value;

                            Trace(string.Format(tradeTraceFormat, stockCode, trade.Direction == OrderDirection.BUY ? "bought" : "sold", trade.NewQuantity, trade.Price,
                                                holdingTradesRef.Contains(tradeRef) ? "CASH" : "MARGIN"));

                            // if any holding sell executed
                            ProcessHoldingSellOrderExecution(newTrades);

                            // if sell executed, then update today outstanding to 0 , because sell order always contains the total outstanding qty and now all of it got sold with this trade
                            // but handle part executions using NewQuantity
                            if (tradeRef == todayOutstandingSellOrderRef)
                            {
                                todayOutstandingQty -= trade.NewQuantity;

                                if (todayOutstandingQty == 0)
                                {
                                    todayOutstandingPrice        = 0;
                                    todayOutstandingSellOrderRef = "";
                                }
                            }

                            // if buy executed, then place a corresponding updated sell order. assumption is that qty is completely executed.
                            // part executed qty will get considered only for first part, for later ones there is no update because we wont get it in newTrades again
                            if (tradeRef == todayOutstandingBuyOrderRef)
                            {
                                Dictionary <string, EquityOrderBookRecord> orders;
                                errCode = broker.GetEquityOrderBookToday(false, false, stockCode, out orders);

                                if (orders[todayOutstandingBuyOrderRef].Status == OrderStatus.EXECUTED)
                                {
                                    Trace(string.Format("Fully executed newqty {0} todayoutstandingqty {1} todayoutstandingprice {2} sellorderref {3} buyorderef {4} buyorderstatus {5}", trade.NewQuantity, todayOutstandingQty, todayOutstandingPrice, todayOutstandingSellOrderRef, todayOutstandingBuyOrderRef, orders[todayOutstandingBuyOrderRef].Status));
                                    todayOutstandingBuyOrderRef = "";
                                }
                                else
                                {
                                    Trace(string.Format("Partially executed newqty {0} todayoutstandingqty {1} todayoutstandingprice {2} sellorderref {3} buyorderef {4} buyorderstatus {5}", trade.NewQuantity, todayOutstandingQty, todayOutstandingPrice, todayOutstandingSellOrderRef, todayOutstandingBuyOrderRef, orders[todayOutstandingBuyOrderRef].Status));
                                }

                                // update outstanding qty and outstanding price to place updated sell order
                                todayOutstandingPrice = (todayOutstandingPrice * todayOutstandingQty) + (trade.NewQuantity * trade.Price);
                                todayOutstandingQty  += trade.NewQuantity;
                                if (todayOutstandingQty == 0)
                                {
                                    todayOutstandingPrice = 0;
                                }
                                else
                                {
                                    todayOutstandingPrice /= todayOutstandingQty;
                                }
                                todayOutstandingPrice = Math.Round(todayOutstandingPrice, 2);

                                if (todayOutstandingQty >= maxTodayOutstandingQtyAllowed)
                                {
                                    Trace(string.Format("TodayOutstandingQty reached the max. todayOutstandingQty: {0} maxTodayOutstandingQtyAllowed: {1}", todayOutstandingQty, maxTodayOutstandingQtyAllowed));
                                }

                                if ((todayOutstandingQty + holdingOutstandingQty) >= maxTotalOutstandingQtyAllowed)
                                {
                                    Trace(string.Format("TotalOutstandingQty reached the max. todayOutstandingQty: {0} holdingOutstandingQty: {1} maxTotalOutstandingQtyAllowed: {2}", todayOutstandingQty, holdingOutstandingQty, maxTotalOutstandingQtyAllowed));
                                }

                                settlementNumber = trade.SettlementNumber;

                                lastBuyPrice = useAvgBuyPriceInsteadOfLastBuyPriceToCalculateBuyPriceForNewOrder ? todayOutstandingPrice : trade.Price;

                                if (!string.IsNullOrEmpty(todayOutstandingSellOrderRef))
                                {
                                    // cancel existing sell order if it exists
                                    errCode = CancelEquityOrder("[Buy Executed]", ref todayOutstandingSellOrderRef, EquityOrderType.MARGIN, OrderDirection.SELL);
                                }
                                if (errCode == BrokerErrorCode.Success || string.IsNullOrEmpty(todayOutstandingSellOrderRef))
                                {
                                    // place new sell order if previous cancelled or it was first one, update sell order ref
                                    var sellPrice = GetSellPrice(todayOutstandingPrice, false, false);
                                    errCode = PlaceEquityOrder(stockCode, OrderPositionTypeEnum.Margin, todayOutstandingQty, todayOutstandingQty, sellPrice.ToString(), OrderPriceType.LIMIT, OrderDirection.SELL, EquityOrderType.MARGIN, exchange, "", out todayOutstandingSellOrderRef);
                                }
                            }
                        }

                        PlaceBuyOrderIfEligible();
                    }

                    // Only relevant near EOD
                    TrySquareOffNearEOD(AlgoType.AverageTheBuyThenSell);
                }
                catch (Exception ex)
                {
                    Trace("Error:" + ex.Message + "\nStacktrace:" + ex.StackTrace);
                }

                if (MarketUtils.IsTimeAfter3XMin(28))
                {
                    CancelHoldingSellOrders();
                    ConvertToDeliveryAndUpdatePositionFile();
                }

                PauseBetweenTradeBookCheck();
            }

            // for safety call conversion once more if the conversion call in the above loop was missed due to Pause and loop's time check
            //CancelHoldingSellOrders();
            ConvertToDeliveryAndUpdatePositionFile(true); // EOD final update
        }