Exemplo n.º 1
0
 public void LoadMarketData(string currencyPairId, int candleLimit)
 {
     foreach (var candlePeriod in Enum.GetValues(typeof(CandlePeriod)).Cast <CandlePeriod>())
     {
         _candleLoadingService.LoadCandles(currencyPairId,
                                           candlePeriod,
                                           candleLimit,
                                           DateTime.UtcNow);
     }
 }
Exemplo n.º 2
0
        public ChartDataset GetChartData(ChartSettings settings)
        {
            var chartDataset = new ChartDataset();

            chartDataset.Candles = _candleLoadingService.LoadCandles(
                settings.CurrencyPairId,
                settings.Period,
                settings.CandleRangeSize,
                settings.CurrentMoment).ToList();

            foreach (var indicatorSettings in settings.Indicators)
            {
                var indicatorDataset = new IndicatorDataset();
                indicatorDataset.Settings = indicatorSettings;

                var candles = indicatorSettings.CandlePeriod != settings.Period ?
                              _candleLoadingService.LoadCandles(
                    settings.CurrencyPairId,
                    indicatorSettings.CandlePeriod,
                    settings.CandleRangeSize,
                    settings.CurrentMoment).ToList() :
                              chartDataset.Candles;

                switch (indicatorSettings.Type)
                {
                case IndicatorType.HighestMaxPrice:
                    indicatorDataset.Values = _indicatorComputingService.ComputeHighestMaxPrices(
                        candles,
                        ((CommonIndicatorSettings)indicatorSettings).Period);
                    break;

                case IndicatorType.EMA:
                    indicatorDataset.Values = _indicatorComputingService.ComputeEMA(
                        candles,
                        ((CommonIndicatorSettings)indicatorSettings).Period);
                    break;

                case IndicatorType.MACD:
                    indicatorDataset.Values = _indicatorComputingService.ComputeMACD(
                        candles,
                        ((MACDSettings)indicatorSettings).EMAPeriod1,
                        ((MACDSettings)indicatorSettings).EMAPeriod2,
                        ((MACDSettings)indicatorSettings).SignalPeriod);
                    break;

                case IndicatorType.Stochastic:
                    indicatorDataset.Values = _indicatorComputingService.ComputeStochastic(
                        candles,
                        ((StochasticSettings)indicatorSettings).Period,
                        ((StochasticSettings)indicatorSettings).SMAPeriodK,
                        ((StochasticSettings)indicatorSettings).SMAPeriodD);
                    break;

                case IndicatorType.RelativeStrengthIndex:
                    indicatorDataset.Values = _indicatorComputingService.ComputeRelativeStrengthIndex(
                        candles,
                        ((CommonIndicatorSettings)indicatorSettings).Period);
                    break;

                case IndicatorType.AccumulationDistribution:
                    indicatorDataset.Values = _indicatorComputingService.ComputeAccumulationDistribution(
                        candles);
                    break;

                case IndicatorType.WilliamsR:
                    indicatorDataset.Values = _indicatorComputingService.ComputeWilliamsR(
                        candles,
                        ((CommonIndicatorSettings)indicatorSettings).Period);
                    break;

                case IndicatorType.ParabolicSAR:
                    indicatorDataset.Values = _indicatorComputingService.ComputeParabolicSAR(candles);
                    break;

                default:
                    throw new AnalysisException("Undefined indicator type");
                }
                chartDataset.IndicatorData.Add(indicatorDataset);
            }

            var defaultTradingSettings = _configurationService.GetTradingSettings();

            var tradingSettings = _configurationService.GetTradingSettings();

            tradingSettings.Period = settings.Period;
            tradingSettings.Moment = settings.CurrentMoment;
            _configurationService.UpdateTradingSettings(tradingSettings);

            foreach (var candle in chartDataset.Candles)
            {
                tradingSettings.Moment = candle.Moment;

                _configurationService.UpdateTradingSettings(tradingSettings);

                //var newPositionInfo = await _marketNewPositionAnalysisService.ProcessMarketPosition(settings.CurrencyPairId);

                var tradingData = new TradingData
                {
                    Moment = candle.Moment
                };

                //switch (newPositionInfo.PositionType)
                //{
                //	case NewMarketPositionType.Buy:
                //		tradingData.BuyPrice = candle.ClosePrice;
                //		break;
                //}
                chartDataset.TradingData.Add(tradingData);
            }

            _configurationService.UpdateTradingSettings(defaultTradingSettings);

            return(chartDataset);
        }
        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);
        }
        protected override ConditionCheckingResult CheckConditions(CurrencyPair currencyPair)
        {
            var settings = ConfigurationService.GetTradingSettings();
            var moment   = settings.Moment ?? DateTime.UtcNow;

            var conditionCheckingResult = new ConditionCheckingResult()
            {
                ResultType = ConditionCheckingResultType.Failed
            };

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

            var firstFrameCandles = CandleLoadingService.LoadCandles(
                currencyPair.Id,
                settings.Period.GetHigherFramePeriod(),
                firstFrameMACDSettings.RequiredCandleRangeSize,
                moment)
                                    .OrderBy(candle => candle.Moment)
                                    .ToList();

            var firstFrameMACDValues = IndicatorComputingService.ComputeMACD(
                firstFrameCandles,
                firstFrameMACDSettings.EMAPeriod1,
                firstFrameMACDSettings.EMAPeriod2,
                firstFrameMACDSettings.SignalPeriod)
                                       .OfType <MACDValue>()
                                       .ToList();

            var firstFrameCurrentMACDValue     = firstFrameMACDValues.ElementAtOrDefault(firstFrameMACDValues.Count - 1);
            var firstFrameOnePreviousMACDValue = firstFrameMACDValues.ElementAtOrDefault(firstFrameMACDValues.Count - 2);

            //If all valuable parameters are not null
            if (firstFrameCurrentMACDValue?.Histogram == null ||
                firstFrameOnePreviousMACDValue?.Histogram == null)
            {
                return(conditionCheckingResult);
            }

            //if MACD higher then Signal then it is Bullish trend
            //if Histogram is rising
            if (!(firstFrameCurrentMACDValue.MACD > 0 ||
                  firstFrameCurrentMACDValue.Histogram.Value >= 0 ||
                  firstFrameCurrentMACDValue.Histogram.Value > firstFrameOnePreviousMACDValue.Histogram))
            {
                return(conditionCheckingResult);
            }

            var rsiSettings = new RSISettings
            {
                Period = 14
            };

            var secondFrameTargetPeriodCandles = CandleLoadingService.LoadCandles(
                currencyPair.Id,
                settings.Period,
                rsiSettings.Period + 2,
                moment)
                                                 .OrderBy(candle => candle.Moment)
                                                 .ToList();

            var candlesCount = secondFrameTargetPeriodCandles.Count;

            if (candlesCount < rsiSettings.Period)
            {
                return(conditionCheckingResult);
            }

            var secondFrameCurrentCandle = secondFrameTargetPeriodCandles.ElementAtOrDefault(secondFrameTargetPeriodCandles.Count - 1);

            if (secondFrameCurrentCandle?.VolumeInBaseCurrency == null)
            {
                return(conditionCheckingResult);
            }

            var lowerPeriodCandles = CandleLoadingService.LoadCandles(
                currencyPair.Id,
                settings.Period.GetLowerFramePeriod(),
                rsiSettings.Period,
                moment)
                                     .OrderBy(candle => candle.Moment)
                                     .ToList();

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

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

                if (lastLowPeriodCandles.Any())
                {
                    secondFrameTargetPeriodCandles.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 period = (candlesCount - 2) > rsiSettings.Period ? rsiSettings.Period : candlesCount - 2;
            var secondFrameRSIValues = IndicatorComputingService.ComputeRelativeStrengthIndex(
                secondFrameTargetPeriodCandles,
                period)
                                       .OfType <SimpleIndicatorValue>()
                                       .ToList();

            var secondFrameCurrentRSIValue     = secondFrameRSIValues.ElementAtOrDefault(secondFrameRSIValues.Count - 1);
            var secondFrameOnePreviousRSIValue = secondFrameRSIValues.ElementAtOrDefault(secondFrameRSIValues.Count - 2);

            if (secondFrameCurrentRSIValue?.Value == null || secondFrameOnePreviousRSIValue?.Value == null)
            {
                return(conditionCheckingResult);
            }

            var rsiTopBorder = 45;

            if (firstFrameCurrentMACDValue.MACD > 0 && firstFrameCurrentMACDValue.Histogram.Value >= 0)
            {
                rsiTopBorder = 65;
            }
            if (firstFrameCurrentMACDValue.MACD > 0 || firstFrameCurrentMACDValue.Histogram.Value >= 0)
            {
                rsiTopBorder = 60;
            }
            if (secondFrameCurrentRSIValue.Value > rsiTopBorder || secondFrameCurrentRSIValue.Value < 25)
            {
                return(conditionCheckingResult);
            }

            if (secondFrameCurrentRSIValue.Value < secondFrameOnePreviousRSIValue.Value)
            {
                return(conditionCheckingResult);
            }

            conditionCheckingResult.ResultType = ConditionCheckingResultType.Passed;
            return(conditionCheckingResult);
        }
Exemplo n.º 5
0
        public async Task <IList <Order> > GetActiveOrders(CurrencyPair currencyPair)
        {
            var storedOrders = _orderRepository.GetAll()
                               .Where(orderEntity => String.Equals(orderEntity.CurrencyPair, currencyPair.Id, StringComparison.OrdinalIgnoreCase))
                               .ToList();

            if (storedOrders.Any())
            {
                var settings = _configurationService.GetTradingSettings();

                var candle = (await _candleLoadingService.LoadCandles(
                                  currencyPair.Id,
                                  settings.Period.GetLowerFramePeriod(),
                                  1,
                                  settings.Moment))
                             .Single();

                var tradingBallanceQuoteCurrencyEntity = GetTradingBallnceInner(currencyPair.QuoteCurrencyId);
                if (tradingBallanceQuoteCurrencyEntity == null)
                {
                    throw new ConnectorException(String.Format("Ballance for currency {0} not found", currencyPair.QuoteCurrencyId));
                }

                var tradingBallanceBaseCurrencyEntity = GetTradingBallnceInner(currencyPair.BaseCurrencyId);
                if (tradingBallanceBaseCurrencyEntity == null)
                {
                    throw new ConnectorException(String.Format("Ballance for currency {0} not found", currencyPair.BaseCurrencyId));
                }

                var openPositionOrderEntity = storedOrders.Single(orderEntity => orderEntity.Role == OrderRoleType.OpenPosition);
                switch (openPositionOrderEntity.OrderStateType)
                {
                case OrderStateType.Suspended:
                    if (openPositionOrderEntity.StopPrice <= candle.MaxPrice)
                    {
                        openPositionOrderEntity.OrderStateType = OrderStateType.New;
                        openPositionOrderEntity.OrderType      = OrderType.Limit;

                        tradingBallanceQuoteCurrencyEntity.Reserved   = openPositionOrderEntity.Price * openPositionOrderEntity.Quantity;
                        tradingBallanceQuoteCurrencyEntity.Available -= openPositionOrderEntity.Price * openPositionOrderEntity.Quantity;

                        if (tradingBallanceQuoteCurrencyEntity.Available < 0)
                        {
                            throw new ConnectorException("Ballance unavailable");
                        }

                        _orderRepository.Update(openPositionOrderEntity);

                        _tradingBallanceRepository.Update(tradingBallanceQuoteCurrencyEntity);
                    }
                    break;

                case OrderStateType.New:
                    if (openPositionOrderEntity.Price >= candle.MinPrice)
                    {
                        openPositionOrderEntity.OrderStateType = OrderStateType.Filled;

                        tradingBallanceQuoteCurrencyEntity.Available += openPositionOrderEntity.Price * openPositionOrderEntity.Quantity * 0.0001m;
                        tradingBallanceBaseCurrencyEntity.Available  += openPositionOrderEntity.Quantity;
                        tradingBallanceQuoteCurrencyEntity.Reserved   = 0m;

                        _orderRepository.Update(openPositionOrderEntity);

                        _tradingBallanceRepository.Update(tradingBallanceQuoteCurrencyEntity);
                        _tradingBallanceRepository.Update(tradingBallanceBaseCurrencyEntity);
                    }
                    break;

                case OrderStateType.Filled:
                    var closePositionOrderEntity =
                        storedOrders.Single(orderEntity => orderEntity.Role == OrderRoleType.ClosePosition && orderEntity.ParentClientId == openPositionOrderEntity.ClientId);

                    var processStopOrders = true;

                    switch (closePositionOrderEntity.OrderStateType)
                    {
                    case OrderStateType.Suspended:
                        if (closePositionOrderEntity.StopPrice >= candle.MinPrice)
                        {
                            closePositionOrderEntity.OrderStateType = OrderStateType.New;
                            openPositionOrderEntity.OrderType       = OrderType.Limit;

                            tradingBallanceBaseCurrencyEntity.Reserved   = closePositionOrderEntity.Quantity;
                            tradingBallanceBaseCurrencyEntity.Available -= closePositionOrderEntity.Quantity;

                            if (tradingBallanceBaseCurrencyEntity.Available < 0)
                            {
                                throw new ConnectorException("Ballance unavailable");
                            }

                            _orderRepository.Update(closePositionOrderEntity);

                            _tradingBallanceRepository.Update(tradingBallanceBaseCurrencyEntity);

                            processStopOrders = false;
                        }
                        break;

                    case OrderStateType.New:
                        if (closePositionOrderEntity.Price <= candle.MaxPrice)
                        {
                            closePositionOrderEntity.OrderStateType = OrderStateType.Filled;

                            tradingBallanceQuoteCurrencyEntity.Available +=
                                closePositionOrderEntity.Quantity * closePositionOrderEntity.Price * 1.0001m;

                            tradingBallanceBaseCurrencyEntity.Reserved = 0m;

                            _orderRepository.Update(closePositionOrderEntity);

                            _tradingBallanceRepository.Update(tradingBallanceQuoteCurrencyEntity);
                            _tradingBallanceRepository.Update(tradingBallanceBaseCurrencyEntity);

                            processStopOrders = false;
                        }
                        break;
                    }

                    if (processStopOrders)
                    {
                        var stopLossOrderEntity =
                            storedOrders.Single(orderEntity => orderEntity.Role == OrderRoleType.StopLoss && orderEntity.ParentClientId == openPositionOrderEntity.ClientId);
                        switch (stopLossOrderEntity.OrderStateType)
                        {
                        case OrderStateType.Suspended:
                            if (stopLossOrderEntity.StopPrice >= candle.MinPrice || stopLossOrderEntity.Price >= candle.MinPrice)
                            {
                                stopLossOrderEntity.OrderStateType = OrderStateType.Filled;

                                tradingBallanceQuoteCurrencyEntity.Available +=
                                    (stopLossOrderEntity.Quantity * stopLossOrderEntity.StopPrice ?? 0m) * 0.999m;

                                if (tradingBallanceBaseCurrencyEntity.Reserved == 0)
                                {
                                    tradingBallanceBaseCurrencyEntity.Available -= stopLossOrderEntity.Quantity;
                                }
                                tradingBallanceBaseCurrencyEntity.Reserved = 0m;

                                _orderRepository.Update(stopLossOrderEntity);

                                _tradingBallanceRepository.Update(tradingBallanceQuoteCurrencyEntity);
                                _tradingBallanceRepository.Update(tradingBallanceBaseCurrencyEntity);
                            }
                            break;
                        }
                    }
                    break;
                }
            }

            return(_orderRepository.GetAll()
                   .Where(orderEntity => String.Equals(orderEntity.CurrencyPair, currencyPair.Id, StringComparison.OrdinalIgnoreCase))
                   .Select(orderEntity => orderEntity.ToModel(currencyPair)).ToList());
        }
        public PendingPositionInfo ProcessMarketPosition(TradingPosition activeTradingPosition)
        {
            var settings = _configurationService.GetTradingSettings();
            var moment   = settings.Moment ?? DateTime.UtcNow;

            var rsiSettings = new CommonIndicatorSettings
            {
                Period = 14
            };

            var targetPeriodLastCandles = _candleLoadingService.LoadCandles(
                activeTradingPosition.OpenPositionOrder.CurrencyPair.Id,
                settings.Period,
                rsiSettings.Period * 2,
                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,
                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)
                    });

                    currentTargetPeriodCandle = targetPeriodLastCandles.Last();
                }
            }

            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 minWilliamsRValue = rsiValues.Where(item => item.Value.HasValue).Select(item => item.Value.Value).Min();

            if (currentRSIValue?.Value == null)
            {
                throw new NoNullAllowedException("No WilliamR values calculated");
            }

            //var higherPeriodMACDSettings = new MACDSettings
            //{
            //	EMAPeriod1 = 12,
            //	EMAPeriod2 = 26,
            //	SignalPeriod = 9
            //};
            //var higherPeriodMACDValues = _indicatorComputingService.ComputeMACD(
            //		higherPeriodLastCandles,
            //		higherPeriodMACDSettings.EMAPeriod1,
            //		higherPeriodMACDSettings.EMAPeriod2,
            //		higherPeriodMACDSettings.SignalPeriod)
            //	.OfType<MACDValue>()
            //	.ToList();
            //var higherPeriodCurrentMACDValue = higherPeriodMACDValues.ElementAtOrDefault(higherPeriodMACDValues.Count - 1);

            var rsiTopBorder = 45;

            //if (higherPeriodCurrentMACDValue?.MACD > 0 && higherPeriodCurrentMACDValue.Histogram >= 0)
            //	rsiTopBorder = 65;
            //if (higherPeriodCurrentMACDValue?.MACD > 0 || higherPeriodCurrentMACDValue?.Histogram >= 0)
            //	rsiTopBorder = 60;

            if (currentRSIValue.Value <= rsiTopBorder &&
                currentRSIValue.Value > 25 &&
                ((activeTradingPosition.OpenPositionOrder.OrderStateType == OrderStateType.Suspended && currentRSIValue.Value > previousRSIValue?.Value) ||
                 (activeTradingPosition.OpenPositionOrder.OrderStateType != OrderStateType.Suspended)) &&
                Math.Abs(minWilliamsRValue - currentRSIValue.Value ?? 0) < 20)
            {
                var topBidPrice = _orderBookLoadingService.GetTopBidPrice(activeTradingPosition.OpenPositionOrder.CurrencyPair, 3);

                var openPrice = activeTradingPosition.OpenPositionOrder.Price >= topBidPrice ?
                                activeTradingPosition.OpenPositionOrder.Price :
                                topBidPrice;

                if (activeTradingPosition.OpenPositionOrder.OrderStateType == OrderStateType.New &&
                    activeTradingPosition.OpenPositionOrder.Price != openPrice)
                {
                    return new UpdateOrderInfo
                           {
                               OpenPrice = openPrice,

                               ClosePrice = new[] { currentTargetPeriodCandle.MaxPrice, activeTradingPosition.ClosePositionOrder.Price }.Max(),
                               CloseStopPrice = new[] { currentTargetPeriodCandle.MinPrice, activeTradingPosition.ClosePositionOrder.StopPrice ?? 0 }.Min(),

                               StopLossPrice = new[]
                               {
                                   currentTargetPeriodCandle.MinPrice - targetPeriodLastCandles.Select(candle => (candle.MaxPrice - candle.MinPrice) * 5).Average(),
                                   activeTradingPosition.StopLossOrder.StopPrice ?? 0
                               }.Min()
                           }
                }
                ;

                return(new PendingOrderInfo());
            }
            return(new CancelOrderInfo());
        }
    }