示例#1
0
        private async void OnCandlesUpdated(object sender, CandlesUpdatedEventArgs e)
        {
            await _positionUpdatingSemaphore.WaitAsync();

            try
            {
                if (e.Period != _workingCandlePeriod || Position.CurrencyPairId != e.CurrencyPairId)
                {
                    return;
                }

                if (Position.IsAwaitingOrderUpdating)
                {
                    return;
                }

                if (Position.IsCompletedPosition)
                {
                    return;
                }

                var nextPosition = Position.Clone();
                if (Position.IsOpenPosition)
                {
                    var marketInfo = _marketOpenPositionAnalysisService.ProcessMarketPosition(Position);
                    if (marketInfo.PositionType == OpenMarketPositionType.UpdateOrder)
                    {
                        nextPosition.ChangePosition((UpdateClosePositionInfo)marketInfo);
                    }
                    else if (marketInfo.PositionType == OpenMarketPositionType.FixStopLoss)
                    {
                        nextPosition.ChangePosition((FixStopLossInfo)marketInfo);
                    }
                    else if (marketInfo.PositionType == OpenMarketPositionType.Suspend)
                    {
                        nextPosition.ChangePosition((SuspendPositionInfo)marketInfo);
                    }

                    if (marketInfo.PositionType != OpenMarketPositionType.Hold)
                    {
                        var updatedPosition = await _tradingPositionService.UpdatePosition(Position, nextPosition, true, OnPositionChanged);

                        if (updatedPosition != null)
                        {
                            Position.SyncWithAnotherPosition(updatedPosition, true);
                        }
                    }
                }
                else if (Position.IsPendingPosition)
                {
                    var marketInfo = _marketPendingPositionAnalysisService.ProcessMarketPosition(Position);
                    if (marketInfo.PositionType == PendingMarketPositionType.UpdateOrder)
                    {
                        nextPosition.ChangePosition((UpdateOrderInfo)marketInfo);
                    }
                    else if (marketInfo.PositionType == PendingMarketPositionType.CancelOrder)
                    {
                        nextPosition.ChangePosition((CancelOrderInfo)marketInfo);
                    }

                    if (marketInfo.PositionType != PendingMarketPositionType.Hold)
                    {
                        var updatedPosition = await _tradingPositionService.UpdatePosition(Position, nextPosition, true, OnPositionChanged);

                        if (updatedPosition != null)
                        {
                            Position.SyncWithAnotherPosition(updatedPosition, true);
                        }
                    }
                }
                else
                {
                    throw new BusinessException("Unexpected position state")
                          {
                              Details = $"Order pair: {JsonConvert.SerializeObject(Position)}"
                          }
                };
            }
            finally
            {
                _positionUpdatingSemaphore.Release();
            }
        }
        private async Task RunTradingIteration()
        {
            try
            {
                var onPositionChangedCallback = new Action <PositionChangedEventArgs>(positionChangedEventArgs => _tradingEventsObserver.RaisePositionChanged(positionChangedEventArgs));

                await _tradingPositionService.SyncExistingPositionsWithStock(onPositionChangedCallback);

                var tradingPositions = await _tradingPositionService.GetOpenPositions();

                if (tradingPositions.Any())
                {
                    foreach (var tradingPosition in tradingPositions)
                    {
                        var nextPosition = tradingPosition.Clone();
                        if (tradingPosition.IsOpenPosition)
                        {
                            var marketInfo = _marketOpenPositionAnalysisService.ProcessMarketPosition(tradingPosition);
                            if (marketInfo.PositionType == OpenMarketPositionType.UpdateOrder)
                            {
                                nextPosition.ChangePosition((UpdateClosePositionInfo)marketInfo);
                            }
                            else if (marketInfo.PositionType == OpenMarketPositionType.FixStopLoss)
                            {
                                nextPosition.ChangePosition((FixStopLossInfo)marketInfo);
                            }
                            else if (marketInfo.PositionType == OpenMarketPositionType.Suspend)
                            {
                                nextPosition.ChangePosition((SuspendPositionInfo)marketInfo);
                            }

                            if (marketInfo.PositionType != OpenMarketPositionType.Hold)
                            {
                                var updatedPosition = await _tradingPositionService.UpdatePosition(tradingPosition, nextPosition, true, onPositionChangedCallback);

                                if (updatedPosition != null)
                                {
                                    tradingPosition.SyncWithAnotherPosition(updatedPosition, true);
                                }
                            }
                        }
                        else if (tradingPosition.IsPendingPosition)
                        {
                            var marketInfo = _marketPendingPositionAnalysisService.ProcessMarketPosition(tradingPosition);
                            if (marketInfo.PositionType == PendingMarketPositionType.UpdateOrder)
                            {
                                nextPosition.ChangePosition((UpdateOrderInfo)marketInfo);
                            }
                            else if (marketInfo.PositionType == PendingMarketPositionType.CancelOrder)
                            {
                                nextPosition.ChangePosition((CancelOrderInfo)marketInfo);
                            }

                            if (marketInfo.PositionType != PendingMarketPositionType.Hold)
                            {
                                var updatedPosition = await _tradingPositionService.UpdatePosition(tradingPosition, nextPosition, true, onPositionChangedCallback);

                                if (updatedPosition != null)
                                {
                                    tradingPosition.SyncWithAnotherPosition(updatedPosition, true);
                                }
                            }
                        }
                        else
                        {
                            throw new BusinessException("Unexpected position state")
                                  {
                                      Details = $"Order pair: {JsonConvert.SerializeObject(tradingPosition)}"
                                  }
                        };
                    }
                }

                {
                    var tradingSettings = _configurationService.GetTradingSettings();

                    var allCurrencyPairs = await _stockRestConnector.GetCurrencyPairs();

                    var baseCurrencyPairs = allCurrencyPairs
                                            .Where(item => tradingSettings.QuoteCurrencies.Any(currencyId =>
                                                                                               String.Equals(item.QuoteCurrencyId, currencyId, StringComparison.OrdinalIgnoreCase)) &&
                                                   !tradingPositions.Any(orderPair => String.Equals(orderPair.OpenPositionOrder.CurrencyPair.BaseCurrencyId, item.BaseCurrencyId))
                                                   );

                    var allTickers = await _stockRestConnector.GetTickers();

                    var tradingTickers = allTickers
                                         .Where(tickerItem =>
                                                baseCurrencyPairs.Any(currencyPairItem => String.Equals(tickerItem.CurrencyPairId, currencyPairItem.Id)))
                                         .Where(tickerItem =>
                    {
                        var tickerCurrencyPair = baseCurrencyPairs.First(currencyPairItem =>
                                                                         String.Equals(tickerItem.CurrencyPairId, currencyPairItem.Id));
                        decimal volumeToCompare;
                        if (String.Equals(tickerCurrencyPair.QuoteCurrencyId, Constants.BTC, StringComparison.OrdinalIgnoreCase))
                        {
                            volumeToCompare = tickerItem.VolumeInQuoteCurrency;
                        }
                        else
                        {
                            var btcConvertFactor    = 0m;
                            var requestCurrencyPair = allCurrencyPairs.FirstOrDefault(item =>
                                                                                      String.Equals(tickerCurrencyPair.QuoteCurrencyId, item.QuoteCurrencyId, StringComparison.OrdinalIgnoreCase) &&
                                                                                      String.Equals(item.BaseCurrencyId, Constants.BTC, StringComparison.OrdinalIgnoreCase));
                            if (requestCurrencyPair != null)
                            {
                                btcConvertFactor = allTickers.First(item =>
                                                                    String.Equals(item.CurrencyPairId, requestCurrencyPair.Id, StringComparison.OrdinalIgnoreCase)).LastPrice;
                            }
                            else
                            {
                                requestCurrencyPair = allCurrencyPairs.FirstOrDefault(item =>
                                                                                      String.Equals(tickerCurrencyPair.QuoteCurrencyId, item.BaseCurrencyId, StringComparison.OrdinalIgnoreCase) &&
                                                                                      String.Equals(item.QuoteCurrencyId, Constants.BTC, StringComparison.OrdinalIgnoreCase));
                                if (requestCurrencyPair != null)
                                {
                                    btcConvertFactor = 1 / allTickers.First(item =>
                                                                            String.Equals(item.CurrencyPairId, requestCurrencyPair.Id,
                                                                                          StringComparison.OrdinalIgnoreCase)).LastPrice;
                                }
                            }

                            volumeToCompare = btcConvertFactor > 0 ? tickerItem.VolumeInQuoteCurrency / btcConvertFactor : 0;
                        }
                        return(volumeToCompare > tradingSettings.MinCurrencyPairTradingVolumeInBTC);
                    })
                                         .ToList();

                    foreach (var currencyPair in baseCurrencyPairs.Where(currencyPairItem => tradingTickers.Any(tickerItem =>
                                                                                                                String.Equals(tickerItem.CurrencyPairId, currencyPairItem.Id, StringComparison.OrdinalIgnoreCase))).ToList())
                    {
                        var tradingBalance = await _stockRestConnector.GetTradingBalance(currencyPair.QuoteCurrencyId);

                        if (tradingBalance?.Available <= 0)
                        {
                            continue;
                        }

                        var marketInfo = _marketNewPositionAnalysisService.ProcessMarketPosition(currencyPair);
                        if (marketInfo.PositionType != NewMarketPositionType.Wait)
                        {
                            var newPosition = await _tradingPositionService.OpenPosition((NewOrderPositionInfo)marketInfo);

                            newPosition = await _tradingPositionService.UpdatePosition(null, newPosition, true, onPositionChangedCallback);

                            _tradingEventsObserver.RaisePositionChanged(TradingEventType.NewPosition, newPosition);
                            break;
                        }
                    }
                }
            }
            catch (BusinessWarning e)
            {
                _loggingService.LogAction(new ErrorAction
                {
                    ExceptionType = e.GetType().ToString(),
                    Message       = e.Message,
                    Details       = e.Details,
                    StackTrace    = e.StackTrace
                });
            }
            catch (BusinessException e)
            {
                _loggingService.LogAction(new ErrorAction
                {
                    ExceptionType = e.GetType().ToString(),
                    Message       = e.Message,
                    Details       = e.Details,
                    StackTrace    = e.StackTrace
                });
                OnException(new UnhandledExceptionEventArgs(e, false));
            }
            catch (ParseResponseException e)
            {
                _loggingService.LogAction(new ErrorAction
                {
                    ExceptionType = e.GetType().ToString(),
                    Message       = e.Message,
                    Details       = e.SourceData,
                    StackTrace    = e.StackTrace
                });
                OnException(new UnhandledExceptionEventArgs(e, false));
            }
            catch (Exception e)
            {
                _loggingService.LogAction(new ErrorAction
                {
                    ExceptionType = e.GetType().ToString(),
                    Message       = e.Message,
                    StackTrace    = e.StackTrace
                });
                OnException(new UnhandledExceptionEventArgs(e, false));
            }
        }