private void Symbol_Tick(SymbolTick obj) // MOVE unsubscribe logic  to Base
        {
            if (End == default(DateTime))        // REFACTOR to base
            {
                End = DateTime.Now + TimeSpan.FromSeconds(150);
            }
            //Console.WriteLine($"[liontrender] [tick] {z} {obj}    (Test time remaining: {(End-DateTime.Now).TotalSeconds.ToString("N")} seconds)");

#if !cAlgo
            if (End <= DateTime.Now)
            {
                Console.WriteLine("[test] Test complete.  Unsubscribing from tick events.");
                this.Symbol.Ticked -= Symbol_Tick;
            }
#endif
        }
        public override void AddTick(SymbolTick si)
        {
            bool marketClosing = false;

            if (!AlgoUpdateTick(si, out marketClosing))
            {
                PostProcAddTick();
                return;
            }

            UpdateMinMax();

            // Try Profitable SquareOff
            int numOpenPositions = Math.Abs(S.TotalBuyTrades - S.TotalSellTrades);

            if (numOpenPositions != 0)
            {
                bool   isBuy      = S.TotalBuyTrades < S.TotalSellTrades;
                double profitPerc = GetSquareOffProfitPerc();

                if (profitPerc > AlgoParams.PercMinProfit)
                {
                    AlgoTryPlaceOrder(isBuy, S.CurrTick, marketClosing);
                }
                else
                {
                    S.PercChangeThreshold = AlgoParams.PercSquareOffThreshold;
                }
            }
            else
            {
                S.PercChangeThreshold = AlgoParams.PercMarketDirectionChange;
            }

            // detect peaks and square off trigger points
            bool isOrderPlaceSuccess = FindPeaksAndOrder(marketClosing);

            PostProcAddTick();
        }
Beispiel #3
0
        void ProcessIncomingDataStream(OpenApiMessagesFactory msgFactory, byte[] rawData)
        {
            var _msg = msgFactory.GetMessage(rawData);

#if TRACE_DATA_INCOMING
            if (isDebugIsOn)
            {
                //if (_msg.PayloadType == (int)OpenApiLib.ProtoOAPayloadType.OA_SPOT_EVENT)
                //{
                //    Console.Write(".");
                //}
                //else
                {
                    Console.WriteLine("ProcessIncomingDataStream() received: " + OpenApiMessagesPresentation.ToString(_msg));
                }
            }
#endif

            if (!_msg.HasPayload)
            {
                return;
            }

            var lastLastHeartBeatReceived = lastHeartBeatReceived;
            lastHeartBeatReceived = DateTime.UtcNow;

            switch (_msg.PayloadType)
            {
            case (int)OpenApiLib.ProtoPayloadType.PING_RES:
            {
                var payload = msgFactory.GetPingResponse(rawData);
                if (payload.HasTimestamp)
                {
                    ServerTime = new DateTime((long)payload.Timestamp);
                    Console.WriteLine("[time] " + Server.Time.ToShortTimeString());
                    //Server.Time = DateTime.FromFileTimeUtc();
                }
                break;
            }

            case (int)OpenApiLib.ProtoPayloadType.HEARTBEAT_EVENT:
                //var _payload_msg = msgFactory.GetHeartbeatEvent(rawData);
                var timeBetween = (lastHeartBeatReceived - lastLastHeartBeatReceived).TotalSeconds;
                Console.WriteLine($"<3 ({timeBetween.ToString("N1")}s)");
                break;

            case (int)OpenApiLib.ProtoOAPayloadType.OA_EXECUTION_EVENT:
            {
                var msg          = "";
                var _payload_msg = msgFactory.GetExecutionEvent(rawData);

                if (_payload_msg.HasReasonCode)
                {
                    var executionType = _payload_msg.ExecutionType.ToString().Replace("OA_ORDER_", "");
                    var reason        = _payload_msg.HasReasonCode ? $"({_payload_msg.ReasonCode})" : "";
                    msg += $"*** [EXECUTION: {executionType} {reason}] *** ";
                }

                if (_payload_msg.HasOrder)
                {
                    orderId = _payload_msg.Order.OrderId;
                    var slPrice    = _payload_msg.Order.HasStopLossPrice ? " sl:" + _payload_msg.Order.StopLossPrice : "";
                    var tpPrice    = _payload_msg.Order.HasTakeProfitPrice ? " tp:" + _payload_msg.Order.TakeProfitPrice : "";
                    var limitPrice = _payload_msg.Order.HasLimitPrice ? " limit:" + _payload_msg.Order.LimitPrice : "";
                    var stopPrice  = _payload_msg.Order.HasStopPrice ? " stop:" + _payload_msg.Order.StopPrice : "";
                    msg += $"[ORDER {orderId}] {_payload_msg.Order.TradeSide} {_payload_msg.Order.RequestedVolume} {_payload_msg.Order.SymbolName} {limitPrice}{stopPrice} {slPrice}{tpPrice}";
                }
                else if (_payload_msg.HasPosition)
                {
                    positionId = _payload_msg.Position.PositionId;
                    var p = _payload_msg.Position;
                    msg += $"[POSITION {positionId}] {p.TradeSide} {p.Volume} {p.SymbolName} @ {p.EntryPrice}";
                }
                else
                {
                }
                Console.WriteLine(msg);
            }
            break;

            case (int)OpenApiLib.ProtoOAPayloadType.OA_AUTH_RES:
                //var payload = msgFactory.GetAuthorizationResponse(rawData);
                IsAuthorized = true;
                Console.WriteLine("[authorized]");
                break;

            case (int)OpenApiLib.ProtoOAPayloadType.OA_SPOT_EVENT:
            {
                if (rawData.Length > 40)
                {
                    Console.WriteLine("================= GOT LONG SPOT EVENT: " + rawData.Length + " ===================");
                }
                var payload = msgFactory.GetSpotEvent(rawData);

                WriteUnknownFields(_msg.PayloadType, payload);

                //var timestamp = timestampField.VarintList[0];
                //var time = new DateTime(1970, 1, 1) + TimeSpan.FromMilliseconds(timestamp);
                var time = new DateTime(1970, 1, 1) + TimeSpan.FromMilliseconds(payload.Timestamp);

                if (payload.TrendbarCount > 0 || payload.TrendbarList.Count > 0)
                {
                    foreach (var bar in payload.TrendbarList)
                    {
                        Console.WriteLine($"*********************** TRENDBAR: {bar.Period} o:{bar.Open} h:{bar.High} l:{bar.Low} c:{bar.Close} [v:{bar.Volume}]");
                        if (bar.Period == ProtoOATrendbarPeriod.H1)
                        {
                            AccountStats.Increment(StatEventType.H1Bar);
                        }
                        else if (bar.Period == ProtoOATrendbarPeriod.H1)
                        {
                            AccountStats.Increment(StatEventType.H1Bar);
                        }
                        else
                        {
                            AccountStats.Increment(StatEventType.Other);
                        }
                        throw new Exception("***** got a trendbar!  Celebrate!");
                    }
                }
                var tick = new SymbolTick
                {
                    Symbol = payload.SymbolName,
                    Ask    = payload.HasAskPrice ? payload.AskPrice : double.NaN,
                    Bid    = payload.HasBidPrice ? payload.BidPrice : double.NaN,
                    Time   = time
                };
                if (payload.HasAskPrice || payload.HasBidPrice)
                {
                    AccountStats.Increment(StatEventType.Tick);
#if DEBUG
                    //if (AccountStats.Totals.Ticks % 100 == 0)
                    //{
                    //    Debug.WriteLine($"[stats] {AccountStats.Totals.Ticks} ticks received");
                    //}
#endif
                }

                var symbol = (ISymbolInternal)GetSymbol(payload.SymbolName);

                symbol.OnTick(tick);
                break;
            }

            case (int)OpenApiLib.ProtoOAPayloadType.OA_SUBSCRIBE_FOR_SPOTS_RES:
            {
                var payload = msgFactory.GetSubscribeForSpotsResponse(rawData);

                uint?subId = payload.HasSubscriptionId ? (uint?)payload.SubscriptionId : null;
#if TRACE_SUBSCRIPTIONS
                Console.WriteLine($"[SUBSCRIBED] {subId}");
#endif

#if GET_SUBS_AFTER_SUB
                SendGetSpotSubscriptionReq(subId);
                SendGetAllSpotSubscriptionsReq();
#endif

                WriteUnknownFields(_msg.PayloadType, payload);
                break;
            }

            case (int)OpenApiLib.ProtoOAPayloadType.OA_UNSUBSCRIBE_FROM_SPOTS_RES:
            {
                var payload = msgFactory.GetUnsubscribeFromSpotsResponse(rawData);

                //uint? subId = payload. ? (uint?)payload.SubscriptionId : null;
                Debug.WriteLine($"[UNSUBSCRIBED]");

#if GET_SUBS_AFTER_SUB
                SendGetAllSpotSubscriptionsReq();
#endif

                WriteUnknownFields(_msg.PayloadType, payload);

                break;
            }

            case (int)OpenApiLib.ProtoOAPayloadType.OA_GET_ALL_SPOT_SUBSCRIPTIONS_RES:
            {
#if TRACE_SUBSCRIPTIONS
                Debug.WriteLine($"--- GET_ALL_SPOT_SUBSCRIPTIONS_RES: ---");
                var payload = msgFactory.GetGetAllSpotSubscriptionsResponse(rawData);
                foreach (var x in payload.SpotSubscriptionsList)
                {
                    foreach (var y in x.SubscribedSymbolsList)
                    {
                        Debug.Write($" - subscription {x.SubscriptionId}: {y.SymbolName} periods: ");
                        foreach (var z in y.PeriodList)
                        {
                            Debug.Write($" {z.ToString()}");
                        }
                        Debug.WriteLine();
                    }
                }
                Debug.WriteLine($"--------------------------------------- ");
#endif
            }
            break;

            case (int)OpenApiLib.ProtoOAPayloadType.OA_GET_SPOT_SUBSCRIPTION_RES:
            {
#if TRACE_SUBSCRIPTIONS
                var payload = msgFactory.GetGetSpotSubscriptionResponse(rawData);
                Debug.WriteLine($"--- GET_SPOT_SUBSCRIPTION_RES for subscription {payload.SpotSubscription.SubscriptionId}: --- ");
                foreach (var y in payload.SpotSubscription.SubscribedSymbolsList)
                {
                    Debug.Write($" - {y.SymbolName} periods: ");
                    foreach (var z in y.PeriodList)
                    {
                        Debug.Write($"{z.ToString()} ");
                    }
                    Debug.WriteLine();
                }
                Debug.WriteLine($"------------------------------------------------------ ");
#endif
            }
            break;

            case (int)OpenApiLib.ProtoOAPayloadType.OA_SUBSCRIBE_FOR_TRADING_EVENTS_RES:
            {
                var payload = msgFactory.GetSubscribeForTradingEventsResponse(rawData);
                Console.WriteLine("[TRADE EVENTS] SUBSCRIBED");
            }
            break;

            default:
                Console.WriteLine("UNHANDLED MESSAGE: " + _msg.PayloadType);
                break;
            }
            ;
        }
Beispiel #4
0
        public static DTick GetNearestOptionTick(DTick futTick, Dictionary <int, Dictionary <int, SymbolTick> > tickStore, ref int strkPrc, DTick optTick, bool determineOwnStrkPrc = false, bool isBuy = false)
        {
            if (tickStore.Keys.Count == 0)
            {
                return(null);
            }

            if (determineOwnStrkPrc)
            {
                bool isCall = IsCallOption(tickStore.First().Value.First().Value.I.InstrumentType);
                strkPrc = StockUtils.GetNearestOptionStrikePrice(futTick.Di, isCall, isBuy);

                var tries = 0;
                while (!tickStore.ContainsKey(strkPrc) && tries++ < 4)
                {
                    if (tickStore.Last().Key < strkPrc)
                    {
                        strkPrc -= 100;
                    }
                    else if (tickStore.First().Key > strkPrc)
                    {
                        strkPrc += 100;
                    }
                }
                if (!tickStore.ContainsKey(strkPrc))
                {
                    strkPrc = tickStore.First().Key;
                }
            }

            DateTime datetime = futTick.Di.QuoteTime;

            if (!tickStore.ContainsKey(strkPrc))
            {
                return(null);
            }

            int time = datetime.Hour * 100 + datetime.Minute;

            var        prcStore      = tickStore[strkPrc];
            SymbolTick si            = null;
            int        maxTimeWindow = 15;

            do
            {
                if (!prcStore.ContainsKey(time))
                {
                    if (time % 100 >= 60)
                    {
                        time = time - 60 + 100;
                    }
                    time++;
                }
                else
                {
                    si = prcStore[time];
                }

                maxTimeWindow--;
            } while (si == null && maxTimeWindow > 0);

            if (si == null && optTick.Di == null)
            {
                if (prcStore.Count > 0)
                {
                    si = prcStore.First().Value;
                }
                else
                {
                    optTick.Di = new DerivativeSymbolQuote(1, 1, 1);
                }
            }

            return(si == null ? optTick : new DTick(si.D.Q, 0));
        }
Beispiel #5
0
        public override void AddTick(SymbolTick si)
        {
            if (!AlgoUpdateTick(si))
            {
                PostProcAddTick();
                return;
            }

            // Remotely called squareoff
            if (S.IsSquareoffAtProfit)
            {
                if (S.TotalBuyTrades != S.TotalSellTrades)
                {
                    var profitPerc = GetSquareOffProfitPerc();
                    if (profitPerc > 0.05)
                    {
                        var orderPlaceCode = TryImmediateSquareOff(false, false, true);
                        if (orderPlaceCode == OrderPlaceAlgoCode.SUCCESS || orderPlaceCode != OrderPlaceAlgoCode.RETRY)
                        {
                            S.IsSquareoffAtProfit = false;
                            if (S.IsPauseAfterSquareOffAtProfit)
                            {
                                Pause(false);
                                S.IsPauseAfterSquareOffAtProfit = false;
                            }
                        }
                    }
                }
            }

            if (AlgoParams.AlgoId >= 150)
            {
                Scalper20(1, 0.5);
            }

            else if (AlgoParams.AlgoId < 20)
            {
                Scalper10();
            }
            else if (AlgoParams.AlgoId < 30)
            {
                Scalper10(true, true);
            }
            else if (AlgoParams.AlgoId < 40)
            {
                Scalper20(1, 0.5);
            }
            else if (AlgoParams.AlgoId < 50)
            {
                Scalper20(0.5, 0.5);
            }
            else if (AlgoParams.AlgoId < 100)
            {
                Scalper20(0.5, 0.5, false, true);
            }
            else if (AlgoParams.AlgoId > 115 && AlgoParams.AlgoId < 120)
            {
                Scalper116();
            }
            else
            {
                Scalper20(0.5, 0.4, true);
            }

            PostProcAddTick();
        }
        public override void AddTick(SymbolTick si)
        {
            bool marketClosing = false;

            if (!AlgoUpdateTick(si, out marketClosing))
            {
                PostProcAddTick();
                return;
            }

            UpdateMinMax();

            // Try Profitable SquareOff
            int numOpenPositions = Math.Abs(S.TotalBuyTrades - S.TotalSellTrades);

            if (numOpenPositions != 0)
            {
                bool   isBuy      = S.TotalBuyTrades < S.TotalSellTrades;
                double profitPerc = GetSquareOffProfitPerc();

                if (profitPerc > AlgoParams.PercMinProfit)
                {
                    S.IsOnceCrossedMinProfit = true;
                    if (!isBuy && S.PercChangeFromMax > 0)
                    {
                        S.IsMinProfitDirectionPercRaised = true;
                        S.PercChangeThreshold            = (profitPerc - AlgoParams.PercMinProfit) / 2;
                    }
                    else if (isBuy && S.PercChangeFromMin < 0)
                    {
                        S.IsMinProfitDirectionPercRaised = true;
                        S.PercChangeThreshold            = (profitPerc - AlgoParams.PercMinProfit) / 2;
                    }
                }
                else if (S.IsOnceCrossedMinProfit && profitPerc > 0)
                {
                    if (!S.IsMinProfitDirectionPercRaised)
                    {
                        S.PercChangeThreshold = profitPerc / 2;
                    }
                }
                else
                {
                    S.PercChangeThreshold = AlgoParams.PercSquareOffThreshold;
                }
            }
            else
            {
                S.PercChangeThreshold = AlgoParams.PercMarketDirectionChange;
            }

            // detect peaks for fresh order and squareoff trigger points
            bool isOrderPlaceSuccess = FindPeaksAndOrder();

            // reset values on order placement
            if (isOrderPlaceSuccess)
            {
                S.IsOnceCrossedMinProfit         = false;
                S.IsMinProfitDirectionPercRaised = false;
                numOpenPositions = Math.Abs(S.TotalBuyTrades - S.TotalSellTrades);
                if (numOpenPositions == 0) // this was square off trade, then reset the peak
                {
                    S.LastPeakType = PeakType.NONE;
                }
            }

            PostProcAddTick();
        }
        public override void AddTick(SymbolTick si)
        {
            if (!AlgoUpdateTick(si))
            {
                PostProcAddTick();
                return;
            }

            // Get call-put tick for mock, for live implement later
            if (AlgoParams.IsReplayMode)
            {
                bool isBuy = S.TotalBuyTrades < S.TotalSellTrades;
                if (S.TotalBuyTrades != S.TotalSellTrades)
                {
                    var ordCall = GetPairedSquareOffOrder(isBuy ? Position.BUY : Position.SELL, DerivativePositionType.Call, false);
                    if (ordCall != null)
                    {
                        var strkPrc = (int)ordCall.OrderTick.Di.StrikePriceDouble;
                        // get tick from tick store
                        S.TickCall = StockUtils.GetNearestOptionTick(S.Ticks.CurrTick, S.TicksCall, ref strkPrc, S.TickCall);
                    }
                    else
                    {
                        S.TickCall = null;
                    }

                    var ordPut = GetPairedSquareOffOrder(isBuy ? Position.BUY : Position.SELL, DerivativePositionType.Put, false);
                    if (ordPut != null)
                    {
                        var strkPrc = (int)ordPut.OrderTick.Di.StrikePriceDouble;
                        // get tick from tick store
                        S.TickPut = StockUtils.GetNearestOptionTick(S.Ticks.CurrTick, S.TicksPut, ref strkPrc, S.TickPut);
                    }
                    else
                    {
                        S.TickPut = null;
                    }
                }
            }

            // Remotely called squareoff
            if (S.IsSquareoffAtProfit)
            {
                if (S.TotalBuyTrades != S.TotalSellTrades)
                {
                    var profitPerc = GetSquareOffProfitPerc();
                    if (profitPerc > 0.05)
                    {
                        var orderPlaceCode = TryImmediateSquareOff(false, false, true);
                        if (orderPlaceCode == OrderPlaceAlgoCode.SUCCESS || orderPlaceCode != OrderPlaceAlgoCode.RETRY)
                        {
                            S.IsSquareoffAtProfit = false;
                            if (S.IsPauseAfterSquareOffAtProfit)
                            {
                                Pause(false);
                                S.IsPauseAfterSquareOffAtProfit = false;
                            }
                        }
                    }
                }
            }

            if (AlgoParams.AlgoId >= 150)
            {
                Scalper20(1, 0.5);
            }

            else if (AlgoParams.AlgoId < 20)
            {
                Scalper10();
            }
            else if (AlgoParams.AlgoId < 30)
            {
                Scalper10(true, true);
            }
            else if (AlgoParams.AlgoId < 40)
            {
                Scalper20(1, 0.5);
            }
            else if (AlgoParams.AlgoId < 50)
            {
                Scalper20(0.5, 0.5);
            }
            else if (AlgoParams.AlgoId < 100)
            {
                Scalper20(0.5, 0.5, false, true);
            }
            else if (AlgoParams.AlgoId > 115 && AlgoParams.AlgoId < 120)
            {
                Scalper116();
            }
            else
            {
                Scalper20(0.5, 0.4, true);
            }

            PostProcAddTick();
        }
Beispiel #8
0
        // Hardcoded to Bid prices
        // Move elsewhere, potentially reuse?
        private void TickToMinuteHandler(SymbolTick tick)
        {
            if (!tick.Time.IsSameMinute(ServerTimeFromTick) && tick.Time < serverTickToMinuteTime)
            {
                logger.LogWarning($"[TICK] Got old {tick.Symbol} tick for time {tick.Time} when server tick to minute time is {serverTickToMinuteTime} and server time from tick is {ServerTimeFromTick}");
            }

            if (tick.Time > ServerTimeFromTick)
            {
                ServerTimeFromTick = tick.Time; // May trigger a bar from previous minute, for all symbols, after a delay (to wait for remaining ticks to come in)
            }

            TimedBar bar = tickToMinuteBars.TryGetValue(tick.Symbol, TimedBar.Invalid);

            if (bar.IsValid && !bar.OpenTime.IsSameMinute(tick.Time))
            {
                // Immediately Trigger a finished bar even after starting the timer above.
                TickToMinuteBar(tick.Symbol, bar);
                bar = TimedBar.Invalid;
            }

            if (!bar.IsValid)
            {
                var minuteBarOpen = new DateTime(tick.Time.Year, tick.Time.Month, tick.Time.Day, tick.Time.Hour, tick.Time.Minute, 0);

                bar = new TimedBar(minuteBarOpen);
            }

            if (!double.IsNaN(tick.Bid))
            {
                if (double.IsNaN(bar.Open))
                {
                    bar.Open = tick.Bid;
                }
                bar.Close = tick.Bid;
                if (double.IsNaN(bar.High) || bar.High < tick.Bid)
                {
                    bar.High = tick.Bid;
                }
                if (double.IsNaN(bar.Low) || bar.Low > tick.Bid)
                {
                    bar.Low = tick.Bid;
                }
            }

            if (double.IsNaN(bar.Volume)) // REVIEW - is this correct for volume?
            {
                bar.Volume = 1;
            }
            else
            {
                bar.Volume++;
            }

            if (tickToMinuteBars.ContainsKey(tick.Symbol))
            {
                tickToMinuteBars[tick.Symbol] = bar;
            }
            else
            {
                tickToMinuteBars.Add(tick.Symbol, bar);
            }
        }
Beispiel #9
0
 public BrokerErrorCode RunCoreAlgoLive(SymbolTick si)
 {
     return(RunCoreAlgo());
 }
Beispiel #10
0
        // Stock algo worker thread
        public static void BG_StockWorkerThread_SingleSymbol(object obj)
        {
            BrokerSymbolAlgosObject stockTraderObj      = (BrokerSymbolAlgosObject)obj;
            IBroker                           broker    = stockTraderObj.Broker;
            List <ITradingAlgo>               algos     = stockTraderObj.Algos;
            BrokerErrorCode                   errorCode = BrokerErrorCode.Success;
            EquitySymbolLiveTickGenerator     ETicks    = stockTraderObj.ETicks;
            DerivativeSymbolLiveTickGenerator DTicks    = stockTraderObj.DTicks;
            bool     isDayNewTicksStarted           = false;
            bool     isAnyAlgoSquareOffRetryPending = false;
            DateTime quoteTime;

            foreach (ITradingAlgo algo in algos)
            {
                algo.ErrorCode = algo.Prolog();
                if (algo.ErrorCode != BrokerErrorCode.Success)
                {
                    errorCode = algo.ErrorCode;
                }
            }

            do
            {
                errorCode = BrokerErrorCode.Success;

                foreach (ITradingAlgo algo in algos)
                {
                    if (algo.ErrorCode != BrokerErrorCode.Success)
                    {
                        algo.ErrorCode = algo.Prolog();
                        if (algo.ErrorCode != BrokerErrorCode.Success)
                        {
                            errorCode = algo.ErrorCode;
                        }
                    }
                }

                if (!errorCode.Equals(BrokerErrorCode.Success))
                {
                    Thread.Sleep(1000 * 30);
                }
            } while (!stockTraderObj.DoStopThread && !errorCode.Equals(BrokerErrorCode.Success));

            SymbolTick tick = new SymbolTick();

            tick.I = stockTraderObj.Instrument;

            while (!stockTraderObj.DoStopThread)
            {
                if (stockTraderObj.Instrument.InstrumentType == InstrumentType.Share)
                {
                    tick.E = ETicks.GetTick(false, out errorCode);
                }
                else
                {
                    tick.D = DTicks.GetTick(false, out errorCode);
                }

                if (!errorCode.Equals(BrokerErrorCode.Success))
                {
                    Thread.Sleep(1000);
                    continue;
                }

                if (stockTraderObj.Instrument.InstrumentType == InstrumentType.Share)
                {
                    quoteTime = tick.E.Q[0].QuoteTime;
                }
                else
                {
                    quoteTime = tick.D.Q.QuoteTime;
                }


                // to guard against previous day's ticks
                if (!isDayNewTicksStarted)
                {
                    isDayNewTicksStarted = quoteTime.Date == DateTime.Now.Date;

                    if (!isDayNewTicksStarted)
                    {
                        Thread.Sleep(10 * 1000);
                        continue;
                    }
                }

                // Main Algo
                foreach (ITradingAlgo algo in algos)
                {
                    if (!algo.DoStopAlgo)
                    {
                        algo.IsExternallySuspended = false;
                        algo.ErrorCode             = errorCode = algo.RunCoreAlgoLive(tick);
                        if (algo.IsOrderExecutionPending)
                        {
                            isAnyAlgoSquareOffRetryPending = true;
                        }
                    }
                    else
                    {
                        algo.IsExternallySuspended = true;
                    }
                }

                if (!isAnyAlgoSquareOffRetryPending)
                {
                    Thread.Sleep(stockTraderObj.TickIntervalInMiliSeconds);//algo.GetSleepTimeInMilliSecs());
                }
                isAnyAlgoSquareOffRetryPending = false;
            }

            foreach (ITradingAlgo algo in algos)
            {
                algo.ErrorCode = algo.Epilog();
            }

            if (stockTraderObj.Instrument.InstrumentType == InstrumentType.Share)
            {
                ETicks.Close();
            }
            else
            {
                DTicks.Close();
            }
        }
        public override void AddTick(SymbolTick si)
        {
            bool marketClosing = false;

            if (!AlgoUpdateTick(si))
            {
                PostProcAddTick();
                return;
            }

            UpdateMinMax();

            OrderPlaceAlgoCode isOrderPlaceSuccess = OrderPlaceAlgoCode.ALGORISKREJECT;

            // ************** 1. CHECK TOP ********************** //
            // detect peaks and square off trigger points
            if (S.LastPeakType == PeakType.BOTTOM)
            {
                bool canOrderThisAnalysis = true; // whether can palce new order on same tick where squareoff is tried

                // Sell Squareoff check
                if (AlgoParams.IsSquareOffTrigger && S.PercChangeFromMax < 0 &&
                    Math.Abs(S.PercChangeFromMax) >= AlgoParams.PercSquareOffThreshold)
                {
                    int numOpenPositions = Math.Abs(S.TotalBuyTrades - S.TotalSellTrades);

                    if (numOpenPositions != 0)
                    {
                        // May be add quantity also to all these calculations
                        double profitPerc = GetSquareOffProfitPerc();

                        if (!AlgoParams.IsMinProfitMust || profitPerc > AlgoParams.PercMinProfit)
                        {
                            // SquareOff point reached
                            canOrderThisAnalysis = AlgoTryPlaceOrder(false, S.Ticks.CurrTick) != OrderPlaceAlgoCode.SUCCESS;
                        }
                    }
                }

                // New sell order
                if (S.PercChangeFromMax < 0 && Math.Abs(S.PercChangeFromMax) >= S.PercChangeThreshold)
                {
                    // Record tick abberations
                    if (Math.Abs(S.PercChangeFromMax) - S.PercChangeThreshold > 1)
                    {
                        Logger.LogWarningMessage(
                            string.Format("{3}: {0} : PriceTick non-continuous {1}: PercThreshold = {4} S.PercChangeFromMax = {2} times.",
                                          S.Ticks.CurrTick.Di.QuoteTime, _discontinuousMaxTickNum++,
                                          S.PercChangeFromMax / S.PercChangeThreshold, AlgoParams.I.Symbol, S.PercChangeThreshold));
                    }
                    // New top found
                    S.LastPeakType  = PeakType.TOP;
                    _lastPeak       = S.Ticks.MaxTick;
                    S.Ticks.MinTick = S.Ticks.CurrTick;
                    _allPeaks.Add(S.TotalTickCount, _lastPeak);

                    if (canOrderThisAnalysis)
                    {
                        isOrderPlaceSuccess = AlgoTryPlaceOrder(false, S.Ticks.CurrTick);
                    }
                }
            }
            // 2. CHECK BOTTOM
            else if (S.LastPeakType == PeakType.TOP)
            {
                bool canOrderThisAnalysis = true; // whether can palce new order on same tick where squareoff is tried

                // Look for squareoff
                if (AlgoParams.IsSquareOffTrigger && S.PercChangeFromMin > 0 &&
                    Math.Abs(S.PercChangeFromMin) >= AlgoParams.PercSquareOffThreshold)
                {
                    int numOpenPositions = Math.Abs(S.TotalBuyTrades - S.TotalSellTrades);

                    if (numOpenPositions != 0)
                    {
                        double profitPerc = GetSquareOffProfitPerc();

                        if (!AlgoParams.IsMinProfitMust || profitPerc > AlgoParams.PercMinProfit)
                        {
                            // SquareOff point reached
                            canOrderThisAnalysis = AlgoTryPlaceOrder(true, S.Ticks.CurrTick) != OrderPlaceAlgoCode.SUCCESS;
                        }
                    }
                }

                // New buy trade
                if (S.PercChangeFromMin > 0 && Math.Abs(S.PercChangeFromMin) >= S.PercChangeThreshold)
                {
                    // Record tick abberations
                    if (Math.Abs(S.PercChangeFromMin) - S.PercChangeThreshold > 1)
                    {
                        Logger.LogWarningMessage(
                            string.Format("{3}: {0} : PriceTick non-continuous {1}: PercThreshold = {4} S.PercChangeFromMin = {2} times.",
                                          S.Ticks.CurrTick.Di.QuoteTime, _discontinuousMaxTickNum++,
                                          S.PercChangeFromMax / S.PercChangeThreshold, AlgoParams.I.Symbol, S.PercChangeThreshold));
                    }

                    // New bottom found
                    S.LastPeakType  = PeakType.BOTTOM;
                    _lastPeak       = S.Ticks.MinTick;
                    S.Ticks.MaxTick = S.Ticks.CurrTick; // range of maxtick set at this point
                    _allPeaks.Add(S.TotalTickCount, _lastPeak);

                    if (canOrderThisAnalysis)
                    {
                        isOrderPlaceSuccess = AlgoTryPlaceOrder(true, S.Ticks.CurrTick);
                    }
                }
            }
            // 3. 1st PEAK (TOP/BOTTOM)
            else if (S.LastPeakType == PeakType.NONE)
            {
                // 1st peak
                double percDiffMinMax = 100 *
                                        ((GetPriceForAnalysis(S.Ticks.MaxTick.Di) - GetPriceForAnalysis(S.Ticks.MinTick.Di)) /
                                         GetPriceForAnalysis(S.Ticks.MinTick.Di)); // should be > than mPercChangeThreshold

                bool isBuy  = S.PercChangeFromMin > 0 && Math.Abs(S.PercChangeFromMin) >= S.PercChangeThreshold;
                bool isSell = S.PercChangeFromMax < 0 && Math.Abs(S.PercChangeFromMax) >= S.PercChangeThreshold;

                if (isBuy && isSell)
                {
                    FileTracing.TraceOut("Error , 1st peak says both buy and sell. Bug in order placing, order not getting executed. Still recover from it..");
                    isBuy  = Math.Abs(S.PercChangeFromMin) > Math.Abs(S.PercChangeFromMax);
                    isSell = !isBuy;
                }
                //if (Math.Abs(percDiffMinMax) >= mPercChangeThreshold)
                if (isBuy || isSell)
                {
                    isOrderPlaceSuccess = AlgoTryPlaceOrder(isBuy, S.Ticks.CurrTick);

                    if (isOrderPlaceSuccess == OrderPlaceAlgoCode.SUCCESS)
                    {
                        // Set last peak as reverse of current tick direction
                        S.LastPeakType = isBuy ? PeakType.BOTTOM : PeakType.TOP;

                        if (S.LastPeakType == PeakType.BOTTOM)
                        {
                            // 1st peak is BOTTOM
                            _lastPeak = S.Ticks.MinTick;
                        }
                        else
                        {
                            // 1st peak is TOP
                            _lastPeak = S.Ticks.MaxTick;
                        }
                        _allPeaks.Add(S.TotalTickCount, _lastPeak);
                    }
                }
            }

            PostProcAddTick();
        }
Beispiel #12
0
        // IEOD - with Only LTP files (and no re-run) algo
        public void RunAlgos(object obj)
        {
            int symbolCounter = 0;
            var sts           = new List <SymbolTick>(10000);

            // Get algo data
            var     brokerAccountObj = (BrokingAccountObject)obj;
            IBroker broker = brokerAccountObj.Broker;
            var     algoMetadata = (AlgoMetadata)brokerAccountObj.CustomData;
            AddTickChartDelegate dataDelegate = algoMetadata.DataDelegate;
            var    chartDelegate = algoMetadata.ChartDelegate;
            var    logDelegate = algoMetadata.LogDelegate;
            var    tickMetaData = algoMetadata.TickMetadata;
            string r1, r2;
            var    isForceUpdate = algoMetadata.IsForceUpdate;
            var    algoParams    = algoMetadata.AlgoParams;

            var AlgoIdSet = AlgoIds;

            if (DoAllAlgos)
            {
                short minAlgo = 10;
                short maxAlgo = 160;
                AlgoIdSet = new short[maxAlgo - minAlgo + 1];
                for (short i = minAlgo; i <= maxAlgo; i++)
                {
                    AlgoIdSet[i - minAlgo] = i;
                }

                //AlgoIdSet[maxAlgo - minAlgo + 1] = 1;
            }

            // Go for each symbol
            foreach (var tmd in tickMetaData)
            {
                r1 = tmd.R1;
                r2 = tmd.R2;
                var symbol       = tmd.Symbol;
                var tickFileName = tmd.Path;


                logDelegate(string.Format("Thread {0}: Time: {4} Starting Stock: {1} r1: {2} r2: {3}\n",
                                          Thread.CurrentThread.ManagedThreadId, symbol, r1, r2, DateTime.Now));

                // CHECK TICKFILE EXISTS
                if (!File.Exists(tickFileName))
                {
                    Logger.LogWarningMessage(string.Format("TickFile {0} not found.", tickFileName));
                    continue;
                }

                // Check if ALGO results already exist (or need to be overwritten) PERIODWISE (r1, r2 combo).Checking last mktDir
                // If this goes past then it means need to run at least 1 mktDirPerc
                if (!isForceUpdate)
                {
                    bool doesEOPExist = true;
                    foreach (var algoId in AlgoIdSet)
                    {
                        if (GetAlgo(algoId, algoParams.Clone(), true) == null)
                        {
                            continue;
                        }
                        // if trader run is already present for this symbol, then just move to next symbol
                        doesEOPExist = doesEOPExist && EOPTradeStats.DoesExistEOPStatsForMinMaxAlgos(symbol, algoId,
                                                                                                     MktDirectionParams[MktDirectionParams.Length - 1], r1, r2);
                        if (!doesEOPExist)
                        {
                            break;
                        }
                    }
                    if (doesEOPExist)
                    {
                        continue;
                    }
                }

                ++symbolCounter;

                sts.Clear();
                GC.Collect();

                // Go through Each day's data for given symbol
                logDelegate(string.Format("Thread {0}: Stock: {1} " +
                                          "Time: {2} , Reading tickfile\n", Thread.CurrentThread.ManagedThreadId, symbol,
                                          DateTime.Now));

                Dictionary <int, Dictionary <int, SymbolTick> > TicksCall = new Dictionary <int, Dictionary <int, SymbolTick> >(10);
                Dictionary <int, Dictionary <int, SymbolTick> > TicksPut  = new Dictionary <int, Dictionary <int, SymbolTick> >(10);

                DateTime       expiryDate = DateTime.Now;
                int            lotSize    = 50;
                InstrumentType instrType  = InstrumentType.OptionCallIndex;
                Instrument     instr      = null;

                if (algoParams.IsHedgeAlgo)
                {
                    Dictionary <int, Dictionary <int, SymbolTick> > dict;
                    //OPT-CNXBAN-26-Jul-2012-10500-CE-Q25-0915
                    var dir               = Path.GetDirectoryName(tickFileName);
                    var allTickFiles      = Directory.EnumerateFiles(dir, "*", SearchOption.AllDirectories);
                    var allSymbolOptFiles = Directory.EnumerateFiles(dir, "OPT-" + symbol + "*", SearchOption.AllDirectories);

                    if (allSymbolOptFiles.Count() == 0)
                    {
                        continue;
                    }

                    foreach (string filePath in allTickFiles)
                    {
                        var fileName = Path.GetFileNameWithoutExtension(filePath);
                        if (!fileName.StartsWith("OPT-" + symbol))
                        {
                            continue;
                        }

                        var fileParts = fileName.Split('-');

                        expiryDate = DateTime.Parse(fileParts[2] + "-" + fileParts[3] + "-" + fileParts[4]);
                        lotSize    = int.Parse(fileParts[7].Replace("Q", ""));
                        var strkPrc = int.Parse(fileParts[5]);

                        if (fileParts[6] == "CE")
                        {
                            instrType = InstrumentType.OptionCallIndex;
                            dict      = TicksCall;
                        }
                        else
                        {
                            instrType = InstrumentType.OptionPutIndex;
                            dict      = TicksPut;
                        }
                        instr = new Instrument(symbol, instrType, strkPrc, expiryDate, lotSize);

                        if (!dict.ContainsKey(strkPrc))
                        {
                            dict.Add(strkPrc, new Dictionary <int, SymbolTick>(400));
                        }

                        var prcStore = dict[strkPrc];

                        var arrOpt = File.ReadAllLines(filePath);

                        int tickCnt = 0;
                        foreach (var s in arrOpt)
                        {
                            var dqi = ParseTickString(s, tmd.TickFormatType);

                            // Add to list of DQI
                            if (dqi == null)
                            {
                                continue;
                            }

                            dqi.InstrumentType    = instrType;
                            dqi.UnderlyingSymbol  = symbol;
                            dqi.ExpiryDateTime    = expiryDate;
                            dqi.StrikePriceDouble = strkPrc;
                            var si = new SymbolTick(true);
                            si.D.Q = dqi;
                            si.I   = instr;
                            tickCnt++;
                            var datetime = si.D.Q.QuoteTime;
                            int time     = datetime.Hour * 100 + datetime.Minute;

                            if (!prcStore.ContainsKey(time))
                            {
                                prcStore.Add(time, si);
                            }
                        }
                    }
                }


                // READ TICKFILE
                var    arr       = File.ReadAllLines(tickFileName);
                double ltp       = 0;
                int    tickCount = 0;
                instrType = InstrumentType.FutureIndex;
                instr     = new Instrument(symbol, instrType, 0, expiryDate, lotSize);
                foreach (var s in arr)
                {
                    var dqi = ParseTickString(s, tmd.TickFormatType);

                    // Add to list of DQI
                    if (dqi == null)
                    {
                        continue;
                    }

                    dqi.InstrumentType   = instrType;
                    dqi.UnderlyingSymbol = symbol;
                    dqi.ExpiryDateTime   = expiryDate;
                    // Add only stablemarket ticks, i.e. after inital 5 minutes. Start from 10 AM for stable data
                    //if (MarketUtils.IsTimeAfter10AM(dqi.UpdateTime))
                    {
                        var si = new SymbolTick(true);
                        si.D.Q = dqi;
                        si.I   = instr;
                        sts.Add(si);
                        ltp += dqi.LastTradedPriceDouble;
                        tickCount++;
                    }
                }

                // Derive the quantity for FNO
                int    qty         = 1;
                double avgLotValue = 300000;
                if (tickCount != 0 && ltp != 0)
                {
                    ltp = ltp / tickCount;
                    qty = (int)Math.Round(avgLotValue / ltp);
                }

                foreach (var algoId in AlgoIdSet)
                {
                    if (GetAlgo(algoId, algoParams.Clone(), true) == null)
                    {
                        continue;
                    }

                    // This is ALGO wise check. (for a given symbol, r1, r2) Check by last mktDirPerc
                    if (!isForceUpdate)
                    {
                        // if trader run is already present for this symbol, then just move to next symbol
                        var doesEOPExist = EOPTradeStats.DoesExistEOPStatsForMinMaxAlgos(symbol, algoId,
                                                                                         MktDirectionParams[MktDirectionParams.Length - 1], r1, r2);
                        if (doesEOPExist)
                        {
                            //Logger.LogWarningMessage(
                            //    string.Format(
                            //        "EOP TradeRun Stats for symbol={0}, algo={1} already exist. Skipping FULL symbol.",
                            //        symbol, algoId));
                            continue;
                        }
                    }

                    foreach (var mktDirecparam in MktDirectionParams)
                    {
                        var percMarketDirectionChange = Math.Round(mktDirecparam, 2);

                        // Special for 1 sec data
                        //if (percMarketDirectionChange == 0.1)// || percMarketDirectionChange == 0.5)
                        //    if (!(symbol == "NIFTY" || symbol == "DEFTY" || symbol == "SENSEX"))
                        //        continue;


                        // MktDirPerc wise check for a given symbol, algo, r1 and r2
                        if (!isForceUpdate)
                        {
                            // if trader run is already present for this symbol, then just move to next symbol
                            bool doesEOPExist = EOPTradeStats.DoesExistEOPStatsForMinMaxAlgos(symbol, algoId,
                                                                                              percMarketDirectionChange,
                                                                                              r1, r2);
                            if (doesEOPExist)
                            {
                                //Logger.LogWarningMessage(
                                //    string.Format(
                                //        "EOP TradeRun Stats for symbol={0}, algo={1}, marketDirection={2} already exist. Skipping for this combination.",
                                //        symbol, algoId, percMarketDirectionChange));
                                continue;
                            }
                        }

                        logDelegate(string.Format("Thread {0} Time {1} ~ Stock: {2}, R1: {3}, Running {4} @ {5}%\n",
                                                  Thread.CurrentThread.ManagedThreadId,
                                                  DateTime.Now,
                                                  symbol,
                                                  r1,
                                                  algoId,
                                                  percMarketDirectionChange));

                        // RUN ALGO
                        var algoParamsClone = algoParams.Clone();
                        algoParamsClone.PercMarketDirectionChange = percMarketDirectionChange;
                        algoParamsClone.AlgoId = algoId;
                        algoParamsClone.R1     = r1;
                        algoParamsClone.R2     = r2;
                        if (symbol.Contains("OPT-"))
                        {
                            algoParamsClone.I = new Instrument(symbol, InstrumentType.OptionCallIndex, ltp, new DateTime(2013, 03, 28), 50);
                        }
                        else
                        {
                            algoParamsClone.I = new Instrument(symbol, InstrumentType.FutureStock, 100, new DateTime(2013, 03, 28), qty);
                        }

                        algoParamsClone.PositionsFile = SystemUtils.GetStockRunTempFileName("Positions-" + algoParamsClone.Description());
                        algoParamsClone.StateFile     = SystemUtils.GetStockRunTempFileName("AlgoState-" + algoParamsClone.Description());

                        TradingAlgo algo = GetAlgo(algoId, algoParamsClone, false);

                        algo.Prolog();

                        if (algoParams.IsHedgeAlgo)
                        {
                            algo.S.TicksCall = TicksCall;
                            algo.S.TicksPut  = TicksPut;
                        }

                        //int tickCntr1Min = 0;
                        // Run for each quote tick now out of all collected from the replay file
                        foreach (var st in sts)
                        {
                            //if (!MarketUtils.IsTimeAfter10AM(dqi.UpdateTime))
                            //{
                            //    continue;
                            //}


                            //tickCntr1Min++;
                            try
                            {
                                if (algo.DoStopAlgo)
                                {
                                    logDelegate(string.Format("Thread {0}: Stock: {1} " +
                                                              "Time: {2} , Coming out due to Stop loss/NumTrades for the day\n", Thread.CurrentThread.ManagedThreadId, symbol,
                                                              DateTime.Now));
                                    break;
                                }
                                //if (algo.AlgoParams.AlgoId >= 120 && algo.AlgoParams.AlgoId < 150)
                                //{
                                //    if (tickCntr1Min % 5 == 0)
                                //    {
                                //        algo.S.TotalTickCount++;
                                //        algo.AddTick(st);
                                //    }
                                //    continue;
                                //}

                                algo.S.TotalTickCount++;
                                algo.AddTick(st);
                            }
                            catch (Exception ex)
                            {
                                FileTracing.TraceOut("Exception in algo.AddTick(): " + ex.Message + "\n" + ex.StackTrace);
                            }

                            algo.LTP = st.GetLTP();
                        }

                        algo.Epilog();

                        //EventResetChart(null, null);

                        // RESET Time in Ticks
                        //foreach (var st in sts)
                        //    st.D.Q.UpdateTime = st.D.Q.QuoteTime;
                    } // foreach algo param
                }     // foreach algo
            }         //foreach symbol

            logDelegate(string.Format("Thread {0} completed !! at Time: {1} \n", Thread.CurrentThread.ManagedThreadId,
                                      DateTime.Now));
        }