コード例 #1
0
 public HyperlinkCrawlerStrategy(
     HyperlinkCrawlerSettings settings,
     HttpClient httpClient,
     ILogger logger,
     HyperlinkCrawlRequest request)
     : base(httpClient, logger, request, settings.MaxUriProcessingDegreeOfParallelism)
 {
     _settings               = settings;
     _httpClient             = httpClient;
     _logger                 = logger;
     _crawlCompleteTokenLock = new SemaphoreSlim(1, 1);
     _events                 = new StrategyEvents(
         accepted => {
         _state.AddAccepted(accepted);
         _logger.LogDebug($"Accepted URI: {accepted.Uri}");
     },
         processed => {
         _state.AddProcessed(processed);
         _logger.LogDebug($"Processed URI: {processed.Uri}");
     },
         failure => {
         _state.AddFailure(failure);
         _logger.LogDebug($"Failed URI: {failure.Uri}");
     },
         discovered => {
         _state.AddDiscovered(discovered);
         _logger.LogDebug($"Discovered URIs: {discovered.Uris.Count}" + string.Join(Environment.NewLine, discovered.Uris));
     });
 }
コード例 #2
0
        protected override void CalcBar()
        {
            CurSpecOrdersMode = ESpecOrdersMode.PerPosition;

            if (!Environment.IsRealTimeCalc) // There is no need to calculate on historical data, that is why backtesting is ignored
            {
                // As soon as backtesting is finished, the signal gets immediately calculated by the timer.
                // It is necessary to calculate the CRTDR and other values which can be requested by MM-signal at any moment.
                ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(recalcFrequency));
                return;
            }

            // This method will be called over and over again because of the RecalcLastBarAfter setting
            // Since we do not want to get the same logs all the time we have a throttling in place
            // which will allow only certain calls to really log their output.
            // Depending on the time of the day we log more of less often.
            UpdateLogThrottling();

            var high  = Bars.HighValue;
            var low   = Bars.LowValue;
            var close = Bars.CloseValue;

            var crtdr = CRTDRIndicatorMath.CalcNextValue(high, low, close);

            var xAverageLongValue  = xAverageLong.Value;
            var xAverageShortValue = xAverageShort.Value;

            var trend = GetTrend(close, xAverageLongValue, xAverageShortValue);

            var rsiDown = cutlersRSIIndicatorMathDown.Value;
            var rsiFlat = cutlersRSIIndicatorMathFlat.Value;
            var rsiUp   = cutlersRSIIndicatorMathUp.Value;

            var rsi = trend == Trend.Down ? rsiDown : (trend == Trend.Up ? rsiUp : rsiFlat);

            MyPortfolioData[PortfolioDataKeys.IWantToBuy]  = false;
            MyPortfolioData[PortfolioDataKeys.IWantToSell] = false;
            MyPortfolioData[PortfolioDataKeys.CRTDR]       = crtdr;

            LogThrottled("Reason: {0}, Status: {1}, Open: {2}, High: {3}, Low: {4}, Close: {5}, RSI: {6}, CRTDR: {7}, xAvgLong: {8}, xAvgShort: {9}", Environment.CalcReason, Bars.Status, Bars.OpenValue, Bars.HighValue, Bars.LowValue, Bars.CloseValue, rsi, crtdr, xAverageLongValue, xAverageShortValue);

            if (StrategyInfo.MarketPosition == 0)
            {
                if (GetSignalUp(crtdr, rsi, trend))
                {
                    //var numLots = Convert.ToInt32((InitialCapital + (doReinvestment ? Portfolio.NetProfit : 0.0)) / Bars.CloseValue);
                    MyPortfolioData[PortfolioDataKeys.IWantToBuy] = true;
                    LogThrottled("Signal says: We would like to buy @ {0}$", Bars.CloseValue);
                }
                //                else if (GetSignalDown(crtdr, rsi, trend))
                //                {
                //                       Output.WriteLine("SHORT on {0}, high {1} low {2} close {3} rsi {4} crtdr {5} xAverageLong {6} xAverageShort {7}", Bars.TimeValue, high, low, close, rsi, crtdr, xAverageLongValue, xAverageShortValue);
                //                    MyPortfolioData[PortfolioHelpFunctions.PotentialEntryPrice] = -Bars.CloseValue;
                //                    sellShortOrder.Send(Convert.ToInt32((InitialCapital + (doReinvestment ? Portfolio.NetProfit : 0.0)) / 10.0 / Bars.CloseValue));
                //                }
                //                else
                //                {
                //                       Log("---  FLAT - NOP ---");
                //                }
            }
            else if (StrategyInfo.MarketPosition > 0)
            {
                // WE ARE LONG
                //var barsSinceEntry = Bars.CurrentBar - CurrentPosition.OpenTrades[0].EntryOrder.BarNumber;
                // BarsSinceEntry() doesn't work upon the restart of a trading session in which case BarsSinceEntry() will be zero no matter when the deals were actually opened
                var barsSinceEntry = Math.Min(1, this.BarsSinceEntry());
                var openProfit     = CurrentPosition.OpenProfit;
                var signalUp       = GetSignalUp(crtdr, rsi, trend);
                var rsiSellLevel   = GetRsiSellLevel(trend);
                LogThrottled("Should we sell? Bars since entry: {0}, open profit: {1}, signal up: {2}, rsi: {3}, rsiSellLevel: {4}", barsSinceEntry, openProfit, signalUp, rsi, rsiSellLevel);

                // close non-profitable positions straight away because we have picked a loser and need to free up money for new deals
                if (openProfit < 0)
                {
                    LogThrottled("Loser cut! Assumed loss: {0}$", CurrentPosition.OpenProfit);
                    MyPortfolioData[PortfolioDataKeys.IWantToSell] = true;
                }
                else if (barsSinceEntry > 2 && !signalUp)
                {
                    LogThrottled("SELL! Bars since entry > 2 and no up signal. Assuming to cash in ~{0}$", CurrentPosition.OpenProfit);
                    MyPortfolioData[PortfolioDataKeys.IWantToSell] = true;
                }
                else if (rsi > rsiSellLevel)
                {
                    LogThrottled("SELL! RSI condition satisfied, we take the profit (~{0}$) and run!", CurrentPosition.OpenProfit);
                    MyPortfolioData[PortfolioDataKeys.IWantToSell] = true;
                }
                else
                {
                    //Log("---  LONG - NOP ---");
                }
            }
            //            else if(marketPosition < 0)
            //            {
            //                // WE ARE SHORT
            //                GenerateStopLoss(StrategyInfo.AvgEntryPrice * Math.Abs(marketPosition) * StopLossLevel);
            //
            //                if(this.BarsSinceEntry() > 2 && !GetSignalDown(crtdr, rsi, trend))
            //                {
            //                       //Output.WriteLine("{8}: COVER1 on {0}, high {1} low {2} close {3} rsi {4} crtdr {5} xAverageLong {6} xAverageShort {7}", Bars.TimeValue, high, low, close, rsi, crtdr, xAverageLongValue, xAverageShortValue, Bars.Info.Name);
            //                    buyToCoverOrder.Send();
            //                }
            //                else if(rsi < (trend == Trend.Down ? RsiCoverLevelDown : (trend == Trend.Up ? RsiCoverLevelUp : RsiCoverLevelFlat)))
            //                {
            //                       //Output.WriteLine("{8}: COVER2 on {0}, high {1} low {2} close {3} rsi {4} crtdr {5} xAverageLong {6} xAverageShort {7}", Bars.TimeValue, high, low, close, rsi, crtdr, xAverageLongValue, xAverageShortValue, Bars.Info.Name);
            //                    buyToCoverOrder.Send();
            //                }
            //                else
            //                {
            //                       Log("--- SHORT - NOP ---");
            //                }
            //            }

            StrategyEvents cmd = StrategyEvents.None;
            object         obj = MyPortfolioData[PortfolioDataKeys.MoneyManagementCommand]; // Check, if there are any MM-signal events available

            if (obj != null)
            {
                cmd = (StrategyEvents)obj;
            }

            //Log("Got command {0}", cmd);

            switch (cmd) // Execute specific commands, depending on the event
            {
            case StrategyEvents.GenerateOrders_Long:
                int numberOfShares = Convert.ToInt32(MyPortfolioData[PortfolioDataKeys.NumberOfShares]);
                buyOrder.Send(numberOfShares);
                LogThrottled("Generated Buy: {0}#", numberOfShares);
                GenerateOrAdjustStopLosses();
                break;

            case StrategyEvents.GenerateOrders_Short:
                sellOrder.Send();
                LogThrottled("Generated Sell.");
                break;

            case StrategyEvents.None:
                ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(recalcFrequency));
                break;
            }

            // During calculation at the bar close, global variables, used to exchange messages between the current signal and MM-signal should be reset
            if (Bars.Status == EBarState.Close)
            {
                Log("Close event received."); // only send email output if trade has been sent on this day
                DumpFileLog();

                MyPortfolioData[PortfolioDataKeys.CRTDR] = 1.0;
                MyPortfolioData[PortfolioDataKeys.MoneyManagementCommand] = StrategyEvents.None;
                MyPortfolioData[PortfolioDataKeys.IWantToBuy]             = false;
                MyPortfolioData[PortfolioDataKeys.IWantToSell]            = false;
                MyPortfolioData[PortfolioDataKeys.NumberOfShares]         = 0;
                ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(recalcFrequency)); // And start the timer to wait for the new commands from MM-signal
            }
        }