private BrokerErrorCode RefreshEquityOrderBookToday()
        {
            DateTime EarliestValidMarketOpenDate = MarketUtils.GetMarketCurrentDate();
            Dictionary <string, EquityOrderBookRecord> orders;

            return(GetEquityOrderBookToday(false, false, null, out orders));
        }
Ejemplo n.º 2
0
        public DerivativeSymbolTick GetTick(bool getSpread, out BrokerErrorCode code)
        {
            DerivativeSymbolQuote  Q  = null;
            DerivativeSymbolSpread S  = null;
            DerivativeSymbolTick   T  = new DerivativeSymbolTick();
            StringBuilder          sb = new StringBuilder();

            code = _broker.GetDerivativeQuote(Instrument.Symbol, Instrument.InstrumentType, Instrument.ExpiryDate, Instrument.StrikePrice, out Q);
            // Check for exchange closed or contract disabled code
            if (code == BrokerErrorCode.Success)
            {
                T.Q = Q;
                sb.Append(Q.ToTickString());
            }
            if (getSpread)
            {
                code = _broker.GetDerivativeSpread(Instrument.Symbol, Instrument.InstrumentType, Instrument.ExpiryDate, Instrument.StrikePrice, out S);
                if (code == BrokerErrorCode.Success)
                {
                    T.S = S;
                    sb.Append(";" + S.ToString());
                }
            }
            if (code.Equals(BrokerErrorCode.Success) && (_writeTicks || MarketUtils.IsTimeTodayAfter915(Q.QuoteTime)))
            {
                _writeTicks = true;
                _ticksw.WriteLine(sb.ToString());
            }
            return(T);
        }
Ejemplo n.º 3
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);
            }
        }
Ejemplo n.º 4
0
        public void ConvertToDeliveryPreviousDaysExpiringOpenPositions()
        {
            if (!MarketUtils.IsTimeAfter2XMin(50))
            {
                return;
            }

            BrokerErrorCode errCode = BrokerErrorCode.Unknown;

            // Get holding order matching this. check expiry date. if today then cancel holding order and convert it
            List <EquityPendingPositionForDelivery> pendingPositions;

            errCode = broker.GetOpenPositionsPendingForDelivery(stockCode, out pendingPositions);

            var positionsExpiringToday = pendingPositions.Where(p => p.ExpiryDate <= DateTime.Today.Date);

            var holdingsOrdersToRemove = new List <HoldingOrder>();

            foreach (var position in positionsExpiringToday)
            {
                var holdingOrder = holdingsOrders.Where(h => h.Type == OrderPositionTypeEnum.OpenPendingDelivery && h.SettlementNumber == position.SettlementNumber && !string.IsNullOrEmpty(h.OrderRef) && h.Qty == position.BlockedQuantity && h.Qty > 0).FirstOrDefault();
                var qtyToConvert = holdingOrder.Qty;

                // free up the blocked qty to go ahead with conversion
                errCode = CancelEquityOrder(string.Format("[Holding Conversion EOD] {0} {1}", holdingOrder.Type, holdingOrder.SettlementNumber), ref holdingOrder.OrderRef, EquityOrderType.DELIVERY, OrderDirection.SELL);
                if (errCode == BrokerErrorCode.Success)
                {
                    // instead of removing the order mark the status as Cancelled and set Qty to 0
                    holdingOrder.Qty    = 0;
                    holdingOrder.Status = OrderStatus.CANCELLED;
                    //holdingsOrdersToRemove.Add(holdingOrder);
                }

                int retryCount = 0;
                errCode = BrokerErrorCode.Unknown;
                while (errCode != BrokerErrorCode.Success && retryCount++ < 3)
                {
                    // Just to ensure the qty is freed up and some time before retry
                    Thread.Sleep(5000);
                    // convert to delivery
                    errCode = ConvertToDeliveryFromPendingForDelivery(stockCode, qtyToConvert, qtyToConvert, position.SettlementNumber, position.Exchange);
                    if (errCode != BrokerErrorCode.Success)
                    {
                        // Conversion fails.. log the parameters
                        Trace(string.Format("Previous ConversionToDelivery Failed: {5} {0} {1} qty expiring on {2} {3} {4}", stockCode, qtyToConvert, position.ExpiryDate.Date, position.SettlementNumber, position.Exchange, errCode));
                    }
                }
            }

            if (holdingsOrdersToRemove.Any())
            {
                holdingsOrders.RemoveAll(h => holdingsOrdersToRemove.Contains(h));
                UpdatePositionFile();
            }
        }
        public static BrokerErrorCode RefreshEquityStockStateToday(IBroker broker, EquityStockTradeStats stockInfo)
        {
            DateTime EarliestValidMarketOpenDate = MarketUtils.GetMarketCurrentDate();

            if (stockInfo == null)
            {
                return(BrokerErrorCode.InValidArg);
            }

            return(stockInfo.EquityRefreshStockState(broker, EarliestValidMarketOpenDate, EarliestValidMarketOpenDate));
        }
Ejemplo n.º 6
0
 public static void hasExpired(Marketplace.Schemas.Services.SessionInfoResponse session, UIViewController controller)
 {
     accountViewController = controller;
     if (session.MultiSessionDetect)
     {
         AppSecurity.IsLogged = false;
         accountViewController.NavigationController.PopToRootViewController(true);
         MarketUtils.AlertView(controller, "Seguridad", "Se ha detectado otro inicio de sesión con el mismo usuario, se ha cerrado esta sesión.");
         return;
     }
 }
Ejemplo n.º 7
0
        public DTick GetTickXMinutesOld(int minutes)
        {
            var time = GeneralUtils.RoundUp(DateTime.Now.AddMinutes(-minutes), TimeSpan.FromMinutes(1));

            while (MarketUtils.IsTimeAfter915(time) && !AllTicks.ContainsKey(time) || AllTicks[time].Count == 0)
            {
                time = time.AddMinutes(-1);
            }

            if (AllTicks.ContainsKey(time))
            {
                return(AllTicks[time][0]);
            }
            else
            {
                return(null);
            }
        }
Ejemplo n.º 8
0
        public List <PriceHistoryDay> PriceHistory(int appId, string hashName)
        {
            var url = Urls.Market + $"/pricehistory/?appid={appId}&market_hash_name={Uri.EscapeDataString(hashName)}";

            var resp = this.steam.Request(url, Method.GET, Urls.Market, null, true, proxy: this.Proxy);

            var respDes = JsonConvert.DeserializeObject <JPriceHistory>(resp.Data.Content);

            if (!respDes.Success)
            {
                throw new SteamException($"Cannot get price history for [{hashName}]");
            }

            IEnumerable <dynamic> prices = Enumerable.ToList(respDes.Prices);

            var list = prices.Select(
                (g, index) =>
            {
                var count = 0;
                if (g[2] != null && !int.TryParse(g[2].ToString(), out count))
                {
                    throw new SteamException($"Cannot parse items count in price history. Index: {index}");
                }

                double price = 0;
                if (g[1] != null && !double.TryParse(g[1].ToString(), out price))
                {
                    throw new SteamException($"Cannot parse item price in price history. Index: {index}");
                }

                return(new PriceHistoryItem
                {
                    DateTime = MarketUtils.SteamTimeConvertor(g[0].ToString()),
                    Count = count,
                    Price = Math.Round(price, 2)
                });
            }).GroupBy(x => x.DateTime.Date).Select(
                g => new PriceHistoryDay {
                Date = g.Key, History = g.Select(p => p).ToList()
            }).ToList();

            return(list);
        }
        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.º 10
0
        static void Main(string[] args)
        {
            BrokerErrorCode errCode = BrokerErrorCode.Unknown;

            // Check for Holiday today
            if (IsHolidayToday())
            {
                Trace("Exchange Holiday today.. exiting.");
                return;
            }

            // Wait 2 seconds if contended – in case another instance
            // of the program is in the process of shutting down.
            if (!mutex.WaitOne(TimeSpan.FromSeconds(2), false))
            {
                var message = "Another instance of the app is running. Only one instance for a userId is allowed! UserId: " + userId + ". Exiting..";
                Trace(message);
                //Console.WriteLine("Press any key to exit..");
                //Console.ReadKey();
                return;
            }

            Trace(userId);
            MarketUtils.WaitUntilMarketOpen();

            // Broker
            var broker = new IciciDirectBroker(userId, "AMIT1978", "08071986");

            //var broker = new IciciDirectBroker(userId, "amit1978", "07111982");
            broker.LogIn();

            //// Separate Login thread in background
            //BrokingAccountThread loginThread = new BrokingAccountThread();
            //Thread thread = new Thread(new ParameterizedThreadStart(LoginUtils.Background_LoginCheckerThread));
            //BrokingAccountObject iciciAccObj = new BrokingAccountObject(broker);
            //loginThread.brokerAccountObj = iciciAccObj;
            //loginThread.thread = thread;
            //loginThread.thread.Name = "Main Login Thread of MUNISGcS";
            //loginThread.thread.IsBackground = true;
            //loginThread.thread.Start(iciciAccObj);

            // ************ TESTING Code starts ****************** //
            //Trace("Testing starts");
            //string ordertestref = "";
            //double funds;
            //errCode = broker.GetFundsAvailable(out funds);
            //errCode = broker.AllocateFunds(FundAllocationCategory.IpoMf, funds);
            //errCode = broker.AllocateFunds(FundAllocationCategory.IpoMf, -4.67);
            //var str = string.Format("[Holding EOD] {0} {1}", OrderPositionTypeEnum.Btst, "");
            //errCode = CancelEquityOrder(string.Format("[Holding EOD] {0} {1}", HoldingTypeEnum.Btst, ""), ref ordertestref, OrderDirection.SELL);
            //var newTrades = new Dictionary<string, EquityTradeBookRecord>();
            //List<EquityDematHoldingRecord> holdings;
            //List<EquityBTSTTradeBookRecord> btstHoldings;
            //errCode = broker.GetBTSTListings("CAPFIR", out btstHoldings);
            //List<EquityPendingPositionForDelivery> pendingPositions;
            //errCode = broker.GetOpenPositionsPendingForDelivery("BAJFI", out pendingPositions);
            //errCode = broker.GetOpenPositionsPendingForDelivery("MOTSUM", out pendingPositions);
            //Dictionary<string, EquityOrderBookRecord> orders;
            //errCode = broker.GetEquityOrderBookToday(false, false, "MOTSUM", out orders);
            //errCode = broker.PlaceEquityMarginSquareOffOrder("BAJFI", 34, 34, "1733", OrderPriceType.LIMIT, OrderDirection.SELL, EquityOrderType.DELIVERY, "2017232", Exchange.NSE, out ordertestref);
            //errCode = broker.PlaceEquityMarginDeliveryFBSOrder("BAJFI", 5, "1733", OrderPriceType.LIMIT, OrderDirection.SELL, EquityOrderType.DELIVERY, Exchange.NSE, out ordertestref);

            //errCode = broker.GetDematAllocation("BAJFI", out holdings);
            //errCode = broker.GetDematAllocation("CAPFIR", out holdings);
            //errCode = broker.GetDematAllocation("CAPPOI", out holdings);
            //errCode = broker.ConvertToDeliveryFromMarginOpenPositions("BAJFI", 3, 1, "2017223", OrderDirection.BUY, Exchange.NSE);
            //errCode = broker.GetEquityTradeBookToday(true, "BAJFI", out newTrades);
            //errCode = broker.ConvertToDeliveryFromPendingForDelivery("CAPFIR", 4, 1, "2017217", Exchange.NSE);
            //errCode = broker.CancelEquityOrder("20171120N900017136", EquityOrderType.DELIVERY);
            //while (errCode != BrokerErrorCode.Success)
            //{
            //    errCode = broker.CancelAllOutstandingEquityOrders("BAJFI", out Dictionary<string, BrokerErrorCode> cancelledOrders);
            //    errCode = broker.PlaceEquityDeliveryBTSTOrder("BAJFI", 1, "1831", OrderPriceType.LIMIT, OrderDirection.SELL, EquityOrderType.DELIVERY, Exchange.NSE, "2017221", out ordertestref);
            //}
            ////errCode = broker.PlaceEquityMarginDeliveryFBSOrder("BAJFI", 1, "1831", OrderPriceType.LIMIT, OrderDirection.SELL, EquityOrderType.DELIVERY, Exchange.NSE, out ordertestref);
            //Trace("Testing ends");
            // ************ TESTING Code ends ****************** //

            // Ensure all funds are allocated
            double funds;

            errCode = BrokerErrorCode.Unknown;
            errCode = broker.GetFundsAvailable(out funds);
            funds  -= 1000;
            funds   = funds < 0 ? 0 : funds;
            if (funds > 0)
            {
                errCode = broker.AllocateFunds(FundAllocationCategory.Equity, funds);
                Trace(string.Format("Ensure free funds [{0}] are allocated to Equity: {1}", funds, errCode));
            }

            // Read the config file
            List <TradeParams> stocksConfig = ReadTradingConfigFile();

            var threads = new List <Thread>(stocksConfig.Count);

            foreach (var stockConfig in stocksConfig)
            {
                stockConfig.broker = broker;
                var t = new Thread(new AverageTheBuyThenSell(stockConfig).StockBuySell);
                threads.Add(t);
            }

            threads.ForEach(t => { t.Start(); Thread.Sleep(1000); });
            threads.ForEach(t => t.Join());

            // Send out the log in email and chat
            Trace("All stock threads completed. Emailing today's log file");
            MessagingUtils.Init();
            var log = GetLogContent();

            MessagingUtils.SendAlertMessage("SimpleTrader log", log);
            Trace("Exiting..");
        }
Ejemplo n.º 11
0
        public MarketSearch Search(
            string query = "",
            int start    = 0,
            int count    = 10,
            bool searchInDescriptions = false,
            int appId = 0,
            EMarketSearchSortColumns sortColumn = EMarketSearchSortColumns.Name,
            ESort sort = ESort.Desc,
            IDictionary <string, string> custom = null)
        {
            var urlQuery = new Dictionary <string, string>
            {
                { "query", query },
                { "start", start.ToString() },
                { "count", count.ToString() },
                { "search_descriptions", (searchInDescriptions ? 1 : 0).ToString() },
                { "appid", appId.ToString() },
                { "sort_column", MarketUtils.FirstCharacterToLower(sortColumn.ToString()) },
                { "sort_dir", MarketUtils.FirstCharacterToLower(sort.ToString()) }
            };

            if (custom != null && custom.Count > 0)
            {
                urlQuery = urlQuery.Concat(custom).ToDictionary(x => x.Key, x => x.Value);
            }

            var resp = this.steam.Request(
                Urls.Market + "/search/render/",
                Method.GET,
                Urls.Market,
                urlQuery,
                true,
                proxy: this.Proxy);
            var respDes = JsonConvert.DeserializeObject <JMarketSearch>(resp.Data.Content);

            if (!respDes.Success)
            {
                throw new SteamException("Failed Search");
            }

            var marketSearch = new MarketSearch();

            if (respDes.TotalCount <= 0)
            {
                return(marketSearch);
            }

            marketSearch.TotalCount = respDes.TotalCount;

            var html = respDes.ResultsHtml;
            var doc  = new HtmlDocument();

            doc.LoadHtml(html);

            var itemNodes = doc.DocumentNode.SelectNodes("//a[@class='market_listing_row_link']");

            if (itemNodes == null || itemNodes.Count <= 0)
            {
                return(marketSearch);
            }

            var tempIndex = 0;

            foreach (var item in itemNodes)
            {
                tempIndex++;

                var nameNode = item.SelectSingleNode(".//span[@class='market_listing_item_name']");
                if (nameNode == null)
                {
                    throw new SteamException($"Cannot parse item name. Index [{tempIndex}]");
                }

                var name = nameNode.InnerText;

                var gameNode = item.SelectSingleNode(".//span[@class='market_listing_game_name']");
                if (gameNode == null)
                {
                    throw new SteamException($"Cannot parse game name. Index [{tempIndex}]");
                }

                var game = gameNode.InnerText;

                var imageUrlNode = item.SelectSingleNode(".//img[@class='market_listing_item_img']");

                var imageUrl = imageUrlNode?.Attributes["srcset"]?.Value;

                var urlAttr = item.Attributes["href"];
                if (urlAttr == null)
                {
                    throw new SteamException($"Cannot find item url. Item [{name}], Index [{tempIndex}]");
                }

                var url = urlAttr.Value;

                var quantityNode = item.SelectSingleNode(".//span[@class='market_listing_num_listings_qty']");
                if (quantityNode == null)
                {
                    throw new SteamException($"Cannot find quantity. Item [{name}], Index [{tempIndex}]");
                }

                var quantityParse = int.TryParse(
                    quantityNode.InnerText,
                    NumberStyles.AllowThousands,
                    CultureInfo.InvariantCulture,
                    out var quantity);

                if (!quantityParse)
                {
                    throw new SteamException($"Cannot parse quantity. Item [{name}], Index [{tempIndex}]");
                }

                var minPriceNode = item.SelectSingleNode(".//span[@class='normal_price']");
                if (minPriceNode == null)
                {
                    throw new SteamException($"Cannot find item price. Item [{name}], Index [{tempIndex}]");
                }

                var minPriceClean = minPriceNode.InnerText.Split(' ')[0];

                var minPriceParse = double.TryParse(
                    minPriceClean,
                    NumberStyles.Currency,
                    CultureInfo.GetCultureInfo("en-US"),
                    out var minPrice);
                if (!minPriceParse)
                {
                    throw new SteamException($"Cannot parse min. price. Item [{name}], Index [{tempIndex}]");
                }

                marketSearch.Items.Add(
                    new MarketSearchItem
                {
                    ImageUrl = imageUrl,
                    Name     = name,
                    Quantity = quantity,
                    Game     = game,
                    Url      = url,
                    MinPrice = minPrice,
                    HashName = MarketUtils.HashNameFromUrl(url),
                    AppId    = MarketUtils.AppIdFromUrl(url)
                });
            }

            return(marketSearch);
        }
Ejemplo n.º 12
0
        private MyListingsSalesItem ProcessSellListings(HtmlNode item, string currency)
        {
            var node        = item.SelectSingleNode(".//span[@class='market_listing_price']");
            var date        = Regex.Match(item.InnerText, @"Listed: (.+)?\s").Groups[1].Value.Trim();
            var priceString = node.InnerText.Replace("\r", string.Empty).Replace("\n", string.Empty)
                              .Replace("\t", string.Empty).Replace(" ", string.Empty);

            if (priceString.Contains("Sold!"))
            {
                return(null);
            }

            var    game = item.SelectSingleNode("//span[@class='market_listing_game_name']").InnerText;
            double price;

            try
            {
                var priceParse     = priceString.Split('(')[0];
                var currencySymbol = SteamCurrencies.Currencies[currency];
                priceParse = priceParse.Replace(currencySymbol, string.Empty);
                var parseDouble = NumberUtils.TryParseDouble(priceParse, out price);
                if (parseDouble == false)
                {
                    throw new SteamException($"Cannot parse order listing price - {priceString}");
                }
            }
            catch (SteamException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new SteamException($"Cannot parse order listing price - {priceString} - {e.Message}");
            }

            var saleIdMatch = Regex.Match(item.InnerHtml, "(?<=mylisting_)([0-9]*)(?=_name)");

            if (!saleIdMatch.Success)
            {
                throw new SteamException("Cannot find sale listing ID");
            }

            var saleIdParse = long.TryParse(saleIdMatch.Value, out var saleId);

            if (!saleIdParse)
            {
                throw new SteamException($"Cannot parse sale listing ID - {saleIdMatch.Value}");
            }

            var imageUrl = item.SelectSingleNode($"//img[contains(@id, 'mylisting_{saleId}_image')]").Attributes["src"]
                           .Value;

            imageUrl = Regex.Match(imageUrl, "image/(.*)/").Groups[1].Value;

            var urlNode = item.SelectSingleNode(".//a[@class='market_listing_item_name_link']");

            if (urlNode == null)
            {
                throw new SteamException("Cannot find sale listing url");
            }

            var url = urlNode.Attributes["href"].Value;

            var hashName = MarketUtils.HashNameFromUrl(url);
            var appId    = MarketUtils.AppIdFromUrl(url);

            var nameNode = urlNode.InnerText;

            var result = new MyListingsSalesItem
            {
                AppId    = appId,
                HashName = hashName,
                Name     = nameNode,
                Date     = date,
                SaleId   = saleId,
                Price    = price,
                Url      = url,
                ImageUrl = imageUrl,
                Game     = game
            };

            return(result);
        }
Ejemplo n.º 13
0
        private void GetPendingTransactionData(
            HtmlNode item,
            int tempIndex,
            MyListings myListings,
            ETransactionType type,
            string currency)
        {
            if (item == null)
            {
                return;
            }

            var node = item.SelectSingleNode(".//span[@class='market_listing_price']");

            if (node == null)
            {
                throw new SteamException(
                          $"Cannot parse order listing price and quantity node. Item index [{tempIndex}]");
            }

            var date = Regex.Match(item.InnerText, @"Listed: (.+)?\s").Groups[1].Value.Trim();
            var game = item.SelectSingleNode("//span[@class='market_listing_game_name']")?.InnerText;

            if (type == ETransactionType.Order)
            {
                var priceAndQuantityString = node.InnerText.Replace("\r", string.Empty).Replace("\n", string.Empty)
                                             .Replace("\t", string.Empty).Replace(" ", string.Empty);
                var priceAndQuantitySplit = priceAndQuantityString.Split('@');

                double price;
                try
                {
                    var priceParse     = priceAndQuantitySplit[1].Replace(".", string.Empty);
                    var currencySymbol = SteamCurrencies.Currencies[currency];
                    double.TryParse(priceParse.Replace(currencySymbol, string.Empty), out price);
                }
                catch (Exception)
                {
                    throw new SteamException($"Cannot parse order listing price. Item index [{tempIndex}]");
                }

                var quantityParse = int.TryParse(priceAndQuantitySplit[0], out var quantity);

                if (!quantityParse)
                {
                    throw new SteamException($"Cannot parse order listing quantity. Item index [{tempIndex}]");
                }

                var orderIdMatch = Regex.Match(item.InnerHtml, "(?<=mbuyorder_)([0-9]*)(?=_name)");

                if (!orderIdMatch.Success)
                {
                    throw new SteamException($"Cannot find order listing ID. Item index [{tempIndex}]");
                }

                var orderIdParse = long.TryParse(orderIdMatch.Value, out var orderId);

                if (!orderIdParse)
                {
                    throw new SteamException($"Cannot parse order listing ID. Item index [{tempIndex}]");
                }

                var imageUrl = item.SelectSingleNode($"//img[contains(@id, 'mylisting_{orderId}_image')]")
                               .Attributes["src"].Value;

                imageUrl = Regex.Match(imageUrl, "image/(.*)/").Groups[1].Value;

                var urlNode = item.SelectSingleNode(".//a[@class='market_listing_item_name_link']");
                if (urlNode == null)
                {
                    throw new SteamException($"Cannot find order listing url. Item index [{tempIndex}]");
                }

                var url = urlNode.Attributes["href"].Value;

                var hashName = MarketUtils.HashNameFromUrl(url);
                var appId    = MarketUtils.AppIdFromUrl(url);

                var nameNode = urlNode.InnerText;

                myListings.Orders.Add(
                    new MyListingsOrdersItem
                {
                    AppId    = appId,
                    HashName = hashName,
                    Name     = nameNode,
                    Date     = date,
                    OrderId  = orderId,
                    Price    = price,
                    Quantity = quantity,
                    Url      = url,
                    ImageUrl = imageUrl,
                    Game     = game
                });
            }
            else
            {
                var priceString = node.InnerText.Replace("\r", string.Empty).Replace("\n", string.Empty)
                                  .Replace("\t", string.Empty).Replace(" ", string.Empty);
                double price;
                try
                {
                    var priceParse     = priceString.Split('(')[0];
                    var currencySymbol = SteamCurrencies.Currencies[currency];
                    double.TryParse(priceParse.Replace(currencySymbol, string.Empty), out price);
                }
                catch (Exception)
                {
                    throw new SteamException($"Cannot parse order listing price. Item index [{tempIndex}]");
                }

                var saleIdMatch = Regex.Match(item.InnerHtml, "(?<=mylisting_)([0-9]*)(?=_name)");
                if (!saleIdMatch.Success)
                {
                    throw new SteamException($"Cannot find sale listing ID. Item index [{tempIndex}]");
                }

                var saleIdParse = long.TryParse(saleIdMatch.Value, out var saleId);

                if (!saleIdParse)
                {
                    throw new SteamException($"Cannot parse sale listing ID. Item index [{tempIndex}]");
                }

                var imageUrl = item.SelectSingleNode($"//img[contains(@id, 'mylisting_{saleId}_image')]")
                               .Attributes["src"].Value.Replace("38fx38f", string.Empty).Replace(
                    "https://steamcommunity-a.akamaihd.net/economy/image/",
                    string.Empty);

                var urlNode = item.SelectSingleNode(".//a[@class='market_listing_item_name_link']");
                if (urlNode == null)
                {
                    throw new SteamException($"Cannot find sale listing url. Item index [{tempIndex}]");
                }

                var url = urlNode.Attributes["href"].Value;

                var hashName = MarketUtils.HashNameFromUrl(url);
                var appId    = MarketUtils.AppIdFromUrl(url);

                var nameNode = urlNode.InnerText;

                var result = new MyListingsSalesItem
                {
                    AppId    = appId,
                    HashName = hashName,
                    Name     = nameNode,
                    Date     = date,
                    SaleId   = saleId,
                    Price    = price,
                    Url      = url,
                    ImageUrl = imageUrl,
                    Game     = game
                };

                var isConfirmation = item.InnerHtml.Contains("CancelMarketListingConfirmation");

                if (isConfirmation == false)
                {
                    myListings.Sales.Add(result);
                }
                else
                {
                    myListings.ConfirmationSales.Add(result);
                }
            }
        }
Ejemplo n.º 14
0
        // 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);
                            }
                        }
                    }
                }
            }
        }
        public BrokerErrorCode GetEquitySpread(string stockCode, out EquitySymbolSpread[] info)
        {
            BrokerErrorCode errorCode = BrokerErrorCode.Success;

            info = new EquitySymbolSpread[2];

            string quoteData  = null;
            int    retryCount = 0;

            do
            {
                quoteData = HttpHelper.GetWebPageResponse(
                    URL_ICICI_EQT_SPREAD + stockCode.ToUpper(),
                    null,
                    null,
                    mCookieContainer);
                retryCount++;
            } while (quoteData == null && retryCount < 5);

            // web problems, slow connection, server down etc.
            if (string.IsNullOrEmpty(quoteData) || quoteData.IndexOf("entered is not valid") > -1)
            {
                return(BrokerErrorCode.NullResponse);
            }

            ParsedTable table = (ParsedTable)HtmlTableParser.ParseHtmlIntoTables(quoteData, true);

            // NSE price info
            info[0]          = new EquitySymbolSpread();
            info[0].Symbol   = stockCode;
            info[0].Exchange = Exchange.NSE;
            string   tempStr       = ParsedTable.GetValue(table, new int[] { 0, 3, 0, 1 });
            DateTime lastTradeTime = DateTime.Parse(tempStr);

            tempStr           = ParsedTable.GetValue(table, new int[] { 0, 3, 1, 1 });
            lastTradeTime    += TimeSpan.Parse(tempStr);
            info[0].QuoteTime = lastTradeTime;

            info[0].TotalBidQty   = MarketUtils.GetVolume(ParsedTable.GetValue(table, new int[] { 0, 5, 7, 1 }));
            info[0].TotalOfferQty = MarketUtils.GetVolume(ParsedTable.GetValue(table, new int[] { 0, 5, 8, 1 }));

            for (int i = 0; i < 5; i++)
            {
                info[0].BestBidQty[i]   = MarketUtils.GetVolume(ParsedTable.GetValue(table, new int[] { 0, 5, i + 2, 0 }));
                info[0].BestBidPrice[i] = MarketUtils.GetPrice(ParsedTable.GetValue(table, new int[] { 0, 5, i + 2, 1 }));

                info[0].BestOfferQty[i]   = MarketUtils.GetVolume(ParsedTable.GetValue(table, new int[] { 0, 5, i + 2, 2 }));
                info[0].BestOfferPrice[i] = MarketUtils.GetPrice(ParsedTable.GetValue(table, new int[] { 0, 5, i + 2, 3 }));
            }

            // BSE price info
            info[1]           = new EquitySymbolSpread();
            info[1].Symbol    = stockCode;
            info[1].Exchange  = Exchange.BSE;
            tempStr           = ParsedTable.GetValue(table, new int[] { 0, 3, 0, 3 });
            lastTradeTime     = DateTime.Parse(tempStr);
            tempStr           = ParsedTable.GetValue(table, new int[] { 0, 3, 1, 3 });
            lastTradeTime    += TimeSpan.Parse(tempStr);
            info[1].QuoteTime = lastTradeTime;

            info[1].TotalBidQty   = MarketUtils.GetVolume(ParsedTable.GetValue(table, new int[] { 0, 5, 7, 3 }));
            info[1].TotalOfferQty = MarketUtils.GetVolume(ParsedTable.GetValue(table, new int[] { 0, 5, 8, 3 }));

            for (int i = 0; i < 5; i++)
            {
                info[1].BestBidQty[i]   = MarketUtils.GetVolume(ParsedTable.GetValue(table, new int[] { 0, 5, i + 2, 4 }));
                info[1].BestBidPrice[i] = MarketUtils.GetPrice(ParsedTable.GetValue(table, new int[] { 0, 5, i + 2, 5 }));

                info[1].BestOfferQty[i]   = MarketUtils.GetVolume(ParsedTable.GetValue(table, new int[] { 0, 5, i + 2, 6 }));
                info[1].BestOfferPrice[i] = MarketUtils.GetPrice(ParsedTable.GetValue(table, new int[] { 0, 5, i + 2, 7 }));
            }
            return(errorCode);
        }
        private BrokerErrorCode CancelEquityOrder(string orderRef, bool refreshOrderBook)
        {
            // Login If needed
            BrokerErrorCode errorCode = CheckAndLogInIfNeeded(false);

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

            if (refreshOrderBook)
            {
                // Make sure we have the latest order book data
                errorCode = RefreshEquityOrderBookToday();
                if (errorCode != BrokerErrorCode.Success)
                {
                    return(errorCode);
                }
            }

            EquityOrderBookRecord orderInfo;

            // Search for order in the Orders dictionary
            lock (lockObjectEquity)
            {
                if (mEquityOrderBook.ContainsKey(orderRef))
                {
                    orderInfo = mEquityOrderBook[orderRef];
                }
                else
                {
                    return(BrokerErrorCode.OrderDoesNotExist);
                }
            }

            if (orderInfo.Status != OrderStatus.ORDERED &&
                orderInfo.Status != OrderStatus.PARTEXEC &&
                orderInfo.Status != OrderStatus.REQUESTED)
            {
                if (orderInfo.Status == OrderStatus.QUEUED)
                {
                    errorCode = BrokerErrorCode.OrderQueuedCannotCancel;
                }
                else if (orderInfo.Status == OrderStatus.EXECUTED)
                {
                    errorCode = BrokerErrorCode.OrderExecutedCannotCancel;
                }
                else
                {
                    errorCode = BrokerErrorCode.InValidOrderToCancel;
                }
                return(errorCode);
            }

            // Instead of getting it actually from order book
            // We simply assume current day only
            DateTime currentDate = MarketUtils.GetMarketCurrentDate();
            string   orderStatus = IciciConstants.OrderStatusString[(int)orderInfo.Status];
            string   zipCode     = orderRef.Substring(8, 2);

            string postData = "Submit1=Yes&FML_PASS=1&NicValue=&m_pipeId=N9" +
                              "&pgname=CanOrd&ismethodcall=0&mthname=" +
                              "&m_status=" + orderStatus +
                              "&m_nsestatus=C" +
                              "&m_bsestatus=C" +
                              "&FML_ORDR_REF=" + orderRef +
                                                                                                              // TODO: C for CASH , currently hardcoded. needs to be handled.
                                                                                                              // Get it in order book stock info somehow
                              "&m_ProductType=C" +
                              "&m_ordFlow=" + IciciConstants.OrderDirectionString[(int)orderInfo.Direction] + // order direction S/B
                              "&m_exchCd=" + IciciConstants.ExchangeString[(int)orderInfo.Exchange] +         // get exchange
                              "";

            string orderBookData = IciciGetWebPageResponse(URL_ICICI_EQT_CANCEL_ORDER,
                                                           postData,
                                                           URL_ICICI_REFERRER,
                                                           mCookieContainer,
                                                           out errorCode);

            if (errorCode.Equals(BrokerErrorCode.Success))
            {
                string cancelConfirm = "Your order has been cancelled";
                string cancelRequestSentToExchange = "Your request for order cancellation has been sent to the exchange";

                // Either cancel confirm or cancellation request sent to exchange both are succes cases
                // Success
                if (orderBookData.Contains(cancelConfirm) || orderBookData.Contains(cancelRequestSentToExchange))
                {
                    // TODO: revist if any prob
                    // Delete the orderRef from mEquityOrderBook
                    // We ideally want it to remain in equity order book in cancelled state
                    // but right now remove it rather than update
                    // because let the GetEquityOrddrBook update it as per its protocol
                    lock (lockObjectEquity)
                    {
                        mEquityOrderBook.Remove(orderRef);
                    }
                    return(BrokerErrorCode.Success);
                }
            }

            return(BrokerErrorCode.OrderCancelFailed);
        }
Ejemplo n.º 17
0
        static void Main(string[] args)
        {
            BrokerErrorCode errCode = BrokerErrorCode.Unknown;

            var upstoxBroker = new MyUpstoxWrapper(apiKey, apiSecret, redirectUrl);

#if DEBUG
            Trace("DEBUG MODE");
            List <UpstoxTradeParams> stocksConfig1 = ReadTradingConfigFile();

            errCode = upstoxBroker.Login1();
#else
            Trace("RELEASE MODE"); errCode = upstoxBroker.Login();
#endif
            // Check for Holiday today
            if (IsHolidayToday())
            {
                Trace("Exchange Holiday today.. exiting.");
                return;
            }

            // Wait 2 seconds if contended – in case another instance
            // of the program is in the process of shutting down.
            if (!mutex.WaitOne(TimeSpan.FromSeconds(2), false))
            {
                var message = "Another instance of the app is running. Only one instance for a userId is allowed! UserId: " + userId + ". Exiting..";
                Trace(message);
                return;
            }

            Trace(userId);

#if !DEBUG
            MarketUtils.WaitUntilMarketOpen();
#endif

            //Thread.Sleep(5000);// Let the rates etc update on server

            // Read the config file
            List <UpstoxTradeParams> stocksConfig = ReadTradingConfigFile();

            var threads = new List <Thread>(stocksConfig.Count);

            var mktTrendConfig = new UpstoxMarketTrendParams();


            var monthNow = DateTime.Now.Month + (DateTime.Now.Day > 20 ? 1 : 0);
            var yearNow  = DateTime.Now.Year + (monthNow > 12 ? 1 : 0);
            if (monthNow > 12)
            {
                monthNow = 1;
            }

            var months = new[] { "DUMMY", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };

            var niftyFutCode = string.Format("NIFTY{0}{1}FUT", (yearNow - 2000), months[monthNow]);

            mktTrendConfig.stockCode   = niftyFutCode;
            mktTrendConfig.exchangeStr = "NSE_FO";
            mktTrendConfig.upstox      = upstoxBroker;
            var mktTrend  = new MarketTrend(mktTrendConfig);
            var mktThread = new Thread(mktTrend.StartCapturingMarketTrend);
            threads.Add(mktThread);

            foreach (var stockConfig in stocksConfig)
            {
                stockConfig.upstox   = upstoxBroker;
                stockConfig.mktTrend = mktTrend;
                upstoxBroker.AddStock(stockConfig.stockCode);
                var t = new Thread(new UpstoxAverageTheBuyThenSell(stockConfig).StockBuySell);
                threads.Add(t);
            }

            threads.ForEach(t => { t.Start(); /*Thread.Sleep(200);*/ });
            threads.ForEach(t => t.Join());

            Trace("Update PnL files");
            WritePnL(upstoxBroker, stocksConfig);

            // Send out the log in email and chat
            Trace("All stock threads completed. Emailing today's log file");
            MessagingUtils.Init();
            var log = GetLogContent();
            MessagingUtils.SendAlertMessage("SimpleTrader log", log);
            Trace("Exiting..");
        }
Ejemplo n.º 18
0
        ////////////////////////////////////
        //////      EQUITY STOCK STATE      //////
        //////////////////////////////////


        public static BrokerErrorCode EquityRefreshStockStateToday(IBroker broker, EquityStockTradeStats stockInfo)
        {
            DateTime EarliestValidMarketOpenDate = MarketUtils.GetMarketCurrentDate();

            return(EquityRefreshStockState(broker, EarliestValidMarketOpenDate, EarliestValidMarketOpenDate, stockInfo));
        }
Ejemplo n.º 19
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
        }
        public void TradeUpdated(object sender, TradeUpdateEventArgs args)
        {
            lock (lockRunEitherPlaceBuyOrTradeUpdated)
            {
                try
                {
                    var trade = ConvertTradeUpdateArgsToTradeRecord(args);

                    if (stockCode != trade.StockCode)
                    {
                        return;
                    }

                    var isSellExecutedFully = false;

                    Trace(string.Format(tradeTraceFormat, stockCode, trade.Direction == OrderDirection.BUY ? "bought" : "sold", args.TradedQty, args.TradedPrice,
                                        holdingSellOrder.OrderId == trade.OrderId ? "DELIVERY" : "MARGIN", trade.OrderId, trade.TradeId, trade.DateTime, args.ExchTime, args.TimeStamp));

                    // if any holding sell executed
                    if (trade.OrderId == holdingSellOrder.OrderId)
                    {
                        ProcessHoldingSellOrderExecution(trade.NewQuantity);
                    }

                    // if SELL executed, then update today outstanding with executed qty (handle part executions using NewQuantity)
                    // If it is after 3.15 and broker did auto sq off, then broker's order ref is not with us and wont match with our sq off order. Our sqoff order will be cancelled by the broker
                    if (trade.OrderId == outstandingSellOrder.OrderId || ((MarketUtils.IsTimeAfter315() && trade.EquityOrderType == EquityOrderType.MARGIN && trade.Direction == OrderDirection.SELL)))
                    {
                        if (!string.IsNullOrEmpty(outstandingSellOrder.OrderId) && trade.OrderId != outstandingSellOrder.OrderId)
                        {
                            // If broker initiated market squareoff then Cancel the known sell order to avoid extra execution
                            errCode = CancelEquityOrder("[Broker SquareOff Executed]", ref outstandingSellOrder.OrderId, orderType, OrderDirection.SELL);
                        }

                        todayOutstandingQty -= trade.NewQuantity;

                        if (todayOutstandingQty == 0)
                        {
                            todayOutstandingPrice        = 0;
                            outstandingSellOrder.OrderId = "";
                            todayOutstandingTradeCount   = 0;
                            isSellExecutedFully          = true;
                        }
                    }

                    // if BUY executed, then place a corresponding updated sell order.
                    if (trade.OrderId == outstandingBuyOrder.OrderId)
                    {
                        currentBuyOrdExecutedQty += trade.NewQuantity;

                        if (currentBuyOrdExecutedQty == currentBuyOrdQty)
                        {
                            Trace(string.Format("[Trade Execution] Fully executed NewQty={0} TotalQty={1}", trade.NewQuantity, currentBuyOrdQty));
                            outstandingBuyOrder.OrderId = "";
                            todayOutstandingTradeCount++;
                        }
                        else
                        {
                            Trace(string.Format("[Trade Execution] Partially executed NewQty={0} TotalQty={1}", trade.NewQuantity, currentBuyOrdQty));
                        }

                        // update outstanding qty and outstanding price to place updated sell order
                        todayOutstandingPrice = (todayOutstandingPrice * todayOutstandingQty) + (trade.NewQuantity * trade.Price);
                        todayOutstandingQty  += trade.NewQuantity;
                        todayOutstandingPrice = todayOutstandingQty == 0 ? 0 : todayOutstandingPrice / todayOutstandingQty;

                        UpdatePnLStats();

                        if (todayOutstandingQty >= maxTodayOutstandingQtyAllowed)
                        {
                            Trace(string.Format("[Trading Limits Hit] TodayOutstandingQty reached the max. todayOutstandingQty: {0} maxTodayPositionValueMultiple: {1}", todayOutstandingQty, maxTodayOutstandingQtyAllowed));
                        }

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

                        lastBuyPrice = trade.Price;

                        var sellPrice = GetSellPrice(todayOutstandingPrice, false, false);

                        if (!string.IsNullOrEmpty(outstandingSellOrder.OrderId))
                        {
                            // modify existing sell order if it exists
                            errCode = ModifyEquityOrder("NewBuy modify squareoff", stockCode, outstandingSellOrder.OrderId, OrderPriceType.LIMIT, todayOutstandingQty, sellPrice, out upstoxOrderStatus);

                            // cancel existing sell order if it exists
                            //errCode = CancelEquityOrder("[Buy Executed]", ref outstandingSellOrder.OrderId, orderType, OrderDirection.SELL);
                        }
                        if (string.IsNullOrEmpty(outstandingSellOrder.OrderId))
                        {
                            // place new sell order if previous cancelled or it was first one, update sell order ref
                            errCode = PlaceEquityOrder(exchStr, stockCode, OrderDirection.SELL, OrderPriceType.LIMIT, todayOutstandingQty, orderType, sellPrice, out outstandingSellOrder.OrderId, out upstoxOrderStatus);
                        }
                    }

                    if (isSellExecutedFully)
                    {
                        // Cancel existing Buy order which might be an average seeking order, as the pricecalc might have changed
                        if (!string.IsNullOrEmpty(outstandingBuyOrder.OrderId))
                        {
                            // cancel existing buy order
                            errCode = CancelEquityOrder("[Sell Executed Fully]", ref outstandingBuyOrder.OrderId, orderType, OrderDirection.BUY);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Trace("Error:" + ex.Message + "\nStacktrace:" + ex.StackTrace);
                }
            }
        }
        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.º 22
0
 public Instrument(string symbol, InstrumentType type, DateTime expiry, int qty)
     : this(symbol, type, qty)
 {
     ExpiryDate = MarketUtils.GetExpiryExactDate(expiry);
 }
Ejemplo n.º 23
0
        // 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. cancel the outstanding buys anyway
            if (MarketUtils.IsTimeAfter310())
            {
                var ordPriceType   = OrderPriceType.LIMIT;
                var doUpdateOrders = false;

                // 3.20 - 3.25 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.IsTimeAfter320() && !MarketUtils.IsTimeAfter325() && squareOffAllPositionsAtEOD && !isEODMinLossSquareOffMarketOrderUpdated)
                {
                    double ltp;
                    var    errCode = GetLTP(out ltp);

                    if (errCode != BrokerErrorCode.Success)
                    {
                        return;
                    }

                    ordPriceType = OrderPriceType.MARKET;

                    var diff = (ltp - todayOutstandingPrice) / ltp;

                    Trace(string.Format("[Margin EOD]: diff {0} ltp {1} outstandingprice {2} pctMaxLossSquareOffPositions {3} goodPrice {4} ", diff, ltp, todayOutstandingPrice, pctMaxLossSquareOffPositions, goodPrice));

                    if ((Math.Abs(diff) < pctMaxLossSquareOffPositions || diff > 0) && todayOutstandingPrice > goodPrice)
                    {
                        Trace(string.Format("[Margin EOD]: max loss {0}% is less than {1}% and avg outstanding price {2} is greater than good price of {3}. LTP is {4}. Place squareoff @ MARKET.", diff, pctMaxLossSquareOffPositions, todayOutstandingPrice, goodPrice, ltp));
                        doUpdateOrders = true;
                        isEODMinLossSquareOffMarketOrderUpdated = true;
                    }
                }

                // 3.10 - 3.20 pm time. try simple limit order with min profit price. watch until 3.10 pm
                else if (!isEODMinProfitSquareOffLimitOrderUpdated)
                {
                    Trace(string.Format("[Margin EOD]: MinProfit Squareoff and cancel outstanding buy 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("[Margin EOD]", ref todayOutstandingBuyOrderRef, EquityOrderType.MARGIN, 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("[Margin EOD]", ref todayOutstandingSellOrderRef, EquityOrderType.MARGIN, OrderDirection.SELL);

                            if (errCode == BrokerErrorCode.Success)
                            {
                                // place new sell order, update sell order ref
                                var sellPrice = GetSellPrice(todayOutstandingPrice, false, true);
                                errCode = PlaceEquityOrder(stockCode, OrderPositionTypeEnum.Margin, todayOutstandingQty, todayOutstandingQty, sellPrice.ToString(), ordPriceType, OrderDirection.SELL, EquityOrderType.MARGIN, exchange, "", out todayOutstandingSellOrderRef);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 24
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.º 25
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();
        }
Ejemplo n.º 26
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);
        }