コード例 #1
0
        public NewPositionInfo ProcessMarketPosition(CurrencyPair currencyPair)
        {
            NewPositionInfo newPositionInfo;
            var             conditionCheckingResult = CheckConditions(currencyPair);

            switch (conditionCheckingResult.ResultType)
            {
            case ConditionCheckingResultType.Passed:
                var buyPositionInfo = new NewOrderPositionInfo(NewMarketPositionType.Buy);
                buyPositionInfo.CurrencyPairId = currencyPair.Id;

                buyPositionInfo.OpenPrice = OrderBookLoadingService.GetTopMeaningfulBidPrice(currencyPair);

                buyPositionInfo.OpenStopPrice = OrderBookLoadingService.GetBottomAskPrice(currencyPair, 1);

                buyPositionInfo.ClosePrice         =
                    buyPositionInfo.CloseStopPrice =
                        buyPositionInfo.OpenStopPrice;

                buyPositionInfo.StopLossPrice = buyPositionInfo.OpenPrice - currencyPair.TickSize * 2000;

                newPositionInfo = buyPositionInfo;
                break;

            default:
                newPositionInfo = new WaitPositionInfo();
                break;
            }

            return(newPositionInfo);
        }
コード例 #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);
        }
コード例 #3
0
        private async void OnOrderBookUpdated(object sender, OrderBookUpdatedEventArgs e)
        {
            if (Position.CurrencyPairId != e.CurrencyPairId)
            {
                return;
            }

            if (Position.IsAwaitingOrderUpdating)
            {
                return;
            }

            if (Interlocked.Read(ref _positionUpdatingTasksCount) > 0)
            {
                return;
            }

            Interlocked.Increment(ref _positionUpdatingTasksCount);

            await _positionUpdatingSemaphore.WaitAsync();

            try
            {
                if (!Position.IsCompletedPosition)
                {
                    if (Position.OpenPositionOrder.OrderStateType == OrderStateType.New)
                    {
                        var newPrice = _orderBookLoadingService.GetTopBidPrice(Position.OpenPositionOrder.CurrencyPair, 3);
                        if (newPrice > Position.OpenPositionOrder.Price)
                        {
                            var nextPosition = Position.Clone();
                            nextPosition.OpenPositionOrder.Price = newPrice;
                            nextPosition = await _tradingPositionService.UpdatePosition(Position, nextPosition, true, OnPositionChanged);

                            if (nextPosition != null)
                            {
                                Position.SyncWithAnotherPosition(nextPosition, true);
                            }
                        }
                    }
                    else if (Position.ClosePositionOrder.OrderStateType == OrderStateType.New)
                    {
                        var newPrice = _orderBookLoadingService.GetBottomAskPrice(Position.OpenPositionOrder.CurrencyPair, 3);
                        if (newPrice > 0 && newPrice < Position.ClosePositionOrder.Price)
                        {
                            var nextPosition = Position.Clone();
                            nextPosition.ClosePositionOrder.Price = newPrice;
                            nextPosition = await _tradingPositionService.UpdatePosition(Position, nextPosition, true, OnPositionChanged);

                            if (nextPosition != null)
                            {
                                Position.SyncWithAnotherPosition(nextPosition, true);
                            }
                        }
                    }
                }
            }
            finally
            {
                _positionUpdatingSemaphore.Release();
            }

            Interlocked.Decrement(ref _positionUpdatingTasksCount);
        }