コード例 #1
0
 public static void ChangePosition(this TradingPosition tradingPosition, SuspendPositionInfo marketInfo)
 {
     tradingPosition.ClosePositionOrder.OrderStateType = OrderStateType.Pending;
 }
コード例 #2
0
        public OpenPositionInfo ProcessMarketPosition(TradingPosition activeTradingPosition)
        {
            var settings = _configurationService.GetTradingSettings();
            var moment   = settings.Moment ?? DateTime.UtcNow;

            var initialPositionInfo = new UpdateClosePositionInfo
            {
                ClosePrice     = activeTradingPosition.ClosePositionOrder.Price,
                CloseStopPrice = activeTradingPosition.ClosePositionOrder.StopPrice ?? 0,
                StopLossPrice  = activeTradingPosition.StopLossOrder.StopPrice ?? 0
            };

            OpenPositionInfo newPositionInfo = null;

            var rsiSettings = new CommonIndicatorSettings
            {
                Period = 10
            };

            var higherPeriodMACDSettings = new MACDSettings
            {
                EMAPeriod1   = 12,
                EMAPeriod2   = 26,
                SignalPeriod = 9
            };

            var candleRangeSize = new[]
            {
                rsiSettings.Period + 2,
                2
            }.Max();

            var targetPeriodLastCandles = _candleLoadingService.LoadCandles(
                activeTradingPosition.OpenPositionOrder.CurrencyPair.Id,
                settings.Period,
                candleRangeSize,
                moment)
                                          .ToList();

            if (!targetPeriodLastCandles.Any())
            {
                throw new NoNullAllowedException("No candles loaded");
            }
            var currentTargetPeriodCandle = targetPeriodLastCandles.Last();

            var higherPeriodLastCandles = _candleLoadingService.LoadCandles(
                activeTradingPosition.OpenPositionOrder.CurrencyPair.Id,
                settings.Period.GetHigherFramePeriod(),
                rsiSettings.Period,
                moment)
                                          .ToList();

            if (!higherPeriodLastCandles.Any())
            {
                throw new NoNullAllowedException("No candles loaded");
            }

            var lowerPeriodCandles = _candleLoadingService.LoadCandles(
                activeTradingPosition.OpenPositionOrder.CurrencyPair.Id,
                settings.Period.GetLowerFramePeriod(),
                rsiSettings.Period + 1,
                moment)
                                     .ToList();

            if (!lowerPeriodCandles.Any())
            {
                throw new NoNullAllowedException("No candles loaded");
            }
            var currentLowPeriodCandle = lowerPeriodCandles.Last();

            if (currentTargetPeriodCandle.Moment < currentLowPeriodCandle.Moment)
            {
                var lastLowPeriodCandles = lowerPeriodCandles
                                           .Where(item => item.Moment > currentTargetPeriodCandle.Moment)
                                           .OrderBy(item => item.Moment)
                                           .ToList();

                if (lastLowPeriodCandles.Any())
                {
                    targetPeriodLastCandles.Add(new Candle
                    {
                        Moment                = lastLowPeriodCandles.Last().Moment,
                        MaxPrice              = lastLowPeriodCandles.Max(item => item.MaxPrice),
                        MinPrice              = lastLowPeriodCandles.Min(item => item.MinPrice),
                        OpenPrice             = lastLowPeriodCandles.First().OpenPrice,
                        ClosePrice            = lastLowPeriodCandles.Last().ClosePrice,
                        VolumeInBaseCurrency  = lastLowPeriodCandles.Sum(item => item.VolumeInBaseCurrency),
                        VolumeInQuoteCurrency = lastLowPeriodCandles.Sum(item => item.VolumeInQuoteCurrency)
                    });
                }
            }

            var candlesCount = targetPeriodLastCandles.Count;
            var period       = (candlesCount - 2) > rsiSettings.Period ? rsiSettings.Period : candlesCount - 2;
            var rsiValues    = _indicatorComputingService.ComputeRelativeStrengthIndex(
                targetPeriodLastCandles,
                period)
                               .OfType <SimpleIndicatorValue>()
                               .ToList();

            var currentRSIValue  = rsiValues.ElementAtOrDefault(rsiValues.Count - 1);
            var previousRSIValue = rsiValues.ElementAtOrDefault(rsiValues.Count - 2);

            var higherPeriodMACDValues = _indicatorComputingService.ComputeMACD(
                higherPeriodLastCandles,
                higherPeriodMACDSettings.EMAPeriod1,
                higherPeriodMACDSettings.EMAPeriod2,
                higherPeriodMACDSettings.SignalPeriod)
                                         .OfType <MACDValue>()
                                         .ToList();

            var higherPeriodCurrentMACDValue = higherPeriodMACDValues.ElementAtOrDefault(higherPeriodMACDValues.Count - 1);

            var rsiBottomBorder = 70;

            if (higherPeriodCurrentMACDValue?.MACD < 0 && higherPeriodCurrentMACDValue.Histogram < 0)
            {
                rsiBottomBorder = 50;
            }
            if (higherPeriodCurrentMACDValue?.MACD < 0 || higherPeriodCurrentMACDValue?.Histogram < 0)
            {
                rsiBottomBorder = 60;
            }

            if ((currentRSIValue?.Value >= rsiBottomBorder &&
                 currentRSIValue.Value < 80 &&
                 currentRSIValue.Value < previousRSIValue?.Value) ||
                (activeTradingPosition.ClosePositionOrder.OrderStateType != OrderStateType.Pending &&
                 currentRSIValue?.Value < 40 &&
                 currentRSIValue.Value < previousRSIValue?.Value))
            {
                var updatePositionInfo = new UpdateClosePositionInfo
                {
                    StopLossPrice = initialPositionInfo.StopLossPrice
                };

                if (activeTradingPosition.ClosePositionOrder.OrderStateType == OrderStateType.Pending ||
                    activeTradingPosition.ClosePositionOrder.OrderStateType == OrderStateType.Suspended)
                {
                    var bottomMeaningfulAskPrice = _orderBookLoadingService.GetBottomMeaningfulAskPrice(activeTradingPosition.ClosePositionOrder.CurrencyPair);

                    updatePositionInfo.ClosePrice = bottomMeaningfulAskPrice - activeTradingPosition.ClosePositionOrder.CurrencyPair.TickSize;

                    var topBidPrice = _orderBookLoadingService.GetTopBidPrice(activeTradingPosition.ClosePositionOrder.CurrencyPair, 3);

                    updatePositionInfo.CloseStopPrice = !activeTradingPosition.ClosePositionOrder.StopPrice.HasValue || topBidPrice >= activeTradingPosition.ClosePositionOrder.StopPrice ?
                                                        topBidPrice :
                                                        activeTradingPosition.ClosePositionOrder.StopPrice.Value;
                }
                else
                {
                    var bottomAskPrice = _orderBookLoadingService.GetBottomAskPrice(activeTradingPosition.ClosePositionOrder.CurrencyPair, 3);

                    updatePositionInfo.ClosePrice = activeTradingPosition.ClosePositionOrder.Price <= bottomAskPrice ?
                                                    activeTradingPosition.ClosePositionOrder.Price :
                                                    bottomAskPrice;

                    updatePositionInfo.CloseStopPrice = 0;
                }

                if (updatePositionInfo.ClosePrice != initialPositionInfo.ClosePrice ||
                    updatePositionInfo.CloseStopPrice != initialPositionInfo.CloseStopPrice)
                {
                    newPositionInfo = updatePositionInfo;
                }
            }
            else if (activeTradingPosition.ClosePositionOrder.OrderStateType != OrderStateType.Pending &&
                     currentRSIValue?.Value < rsiBottomBorder &&
                     currentRSIValue.Value > previousRSIValue?.Value)
            {
                newPositionInfo = new SuspendPositionInfo();
            }
            else if (activeTradingPosition.ClosePositionOrder.OrderStateType != OrderStateType.Pending &&
                     currentRSIValue?.Value >= 80)
            {
                newPositionInfo = new SuspendPositionInfo();
            }

            if (newPositionInfo == null &&
                currentTargetPeriodCandle.Moment >= currentLowPeriodCandle.Moment &&
                currentRSIValue?.Value > previousRSIValue?.Value)
            {
                var fixStopLossInfo = new FixStopLossInfo {
                    StopLossPrice = initialPositionInfo.StopLossPrice
                };
                ComputeStopLossUsingParabolicSAR(
                    fixStopLossInfo,
                    activeTradingPosition.StopLossOrder,
                    currentTargetPeriodCandle);

                if (fixStopLossInfo.StopLossPrice != initialPositionInfo.StopLossPrice)
                {
                    newPositionInfo = fixStopLossInfo;
                }
            }

            if (newPositionInfo == null)
            {
                return(new HoldPositionInfo());
            }

            return(newPositionInfo);
        }