コード例 #1
0
        private async Task <IReadOnlyCollection <HedgeLimitOrder> > CreateLimitOrdersAsync(
            IEnumerable <AssetInvestment> assetInvestments)
        {
            HedgeSettings hedgeSettings = await _hedgeSettingsService.GetAsync();

            var hedgeLimitOrders = new List <HedgeLimitOrder>();

            foreach (AssetInvestment assetInvestment in assetInvestments)
            {
                AssetHedgeSettings assetHedgeSettings =
                    await _assetHedgeSettingsService.EnsureAsync(assetInvestment.AssetId);

                LimitOrderType limitOrderType = assetInvestment.RemainingAmount > 0
                    ? LimitOrderType.Sell
                    : LimitOrderType.Buy;

                if (!CanCreateHedgeLimitOrder(assetInvestment, assetHedgeSettings, hedgeSettings, limitOrderType))
                {
                    continue;
                }

                decimal commonThresholdUp = limitOrderType == LimitOrderType.Buy
                    ? hedgeSettings.ThresholdUpBuy
                    : hedgeSettings.ThresholdUpSell;

                LimitOrderPrice limitOrderPrice = LimitOrderPriceCalculator.Calculate(assetInvestment.Quote,
                                                                                      Math.Abs(assetInvestment.RemainingAmount), limitOrderType,
                                                                                      assetHedgeSettings.ThresholdUp ?? commonThresholdUp, hedgeSettings.MarketOrderMarkup);

                decimal price = limitOrderPrice.Price;

                decimal volume = Math.Abs(assetInvestment.RemainingAmount / assetInvestment.Quote.Mid);

                HedgeLimitOrder hedgeLimitOrder = HedgeLimitOrder.Create(assetHedgeSettings.Exchange,
                                                                         assetHedgeSettings.AssetId, assetHedgeSettings.AssetPairId, limitOrderType, limitOrderPrice.Type,
                                                                         price, volume);

                hedgeLimitOrder.Context = assetInvestment.ToJson();

                hedgeLimitOrders.Add(hedgeLimitOrder);
            }

            return(hedgeLimitOrders);
        }
コード例 #2
0
        public async Task HandleIndexAsync(Index index)
        {
            MarketMakerState marketMakerState = await _marketMakerStateService.GetAsync();

            IndexSettings indexSettings = await _indexSettingsService.GetByIndexAsync(index.Name);

            if (marketMakerState.Status != MarketMakerStatus.Active)
            {
                if (indexSettings != null)
                {
                    foreach (AssetWeight assetWeight in index.Weights)
                    {
                        await _assetHedgeSettingsService.EnsureAsync(assetWeight.AssetId);
                    }
                }

                return;
            }

            foreach (var assetWeight in index.Weights)
            {
                Quote quote = new Quote($"{assetWeight.AssetId}USD", index.Timestamp, assetWeight.Price,
                                        assetWeight.Price, ExchangeNames.Virtual);

                await _quoteService.UpdateAsync(quote);
            }

            if (indexSettings == null)
            {
                return;
            }

            await _semaphore.WaitAsync();

            try
            {
                await _indexPriceService.UpdateAsync(index);

                await _hedgeService.UpdateLimitOrdersAsync();

                await _marketMakerService.UpdateLimitOrdersAsync(index.Name);
            }
            catch (InvalidOperationException exception)
            {
                _log.WarningWithDetails("An error occurred while processing index", exception, index);
            }
            catch (Exception exception)
            {
                _log.ErrorWithDetails(exception, "An error occurred while processing index", index);
                throw;
            }
            finally
            {
                _semaphore.Release();
            }
        }
コード例 #3
0
 private async Task UpdateAssets(IndexSettings indexSettings, Index index)
 {
     if (indexSettings != null)
     {
         foreach (AssetWeight assetWeight in index.Weights)
         {
             await _assetHedgeSettingsService.EnsureAsync(assetWeight.AssetId);
         }
     }
 }
コード例 #4
0
        private async Task CalculateAssetSettlementsAsync(Settlement settlement, IEnumerable <AssetWeight> assetWeights)
        {
            decimal amountInUsd = settlement.Amount * settlement.Price;

            var assetSettlements = new List <AssetSettlement>();

            foreach (AssetWeight assetWeight in assetWeights)
            {
                AssetHedgeSettings assetHedgeSettings =
                    await _assetHedgeSettingsService.EnsureAsync(assetWeight.AssetId);

                Quote quote = _quoteService.GetByAssetPairId(assetHedgeSettings.Exchange,
                                                             assetHedgeSettings.AssetPairId);

                decimal amount = 0;
                decimal price  = 0;

                if (quote != null)
                {
                    amount = amountInUsd * assetWeight.Weight / quote.Mid;
                    price  = quote.Mid;
                }

                assetSettlements.Add(new AssetSettlement
                {
                    AssetId      = assetWeight.AssetId,
                    SettlementId = settlement.Id,
                    Amount       = amount,
                    Price        = price,
                    Fee          = decimal.Zero,
                    Weight       = assetWeight.Weight,
                    IsDirect     = settlement.IsDirect && assetWeight.Weight > AssetMinWeightToDirectTransfer,
                    IsExternal   = assetHedgeSettings.Exchange != ExchangeNames.Lykke,
                    Status       = AssetSettlementStatus.New,
                    ActualAmount = amount,
                    ActualPrice  = price,
                    Error        = quote == null ? SettlementError.NoQuote : SettlementError.None
                });
            }

            settlement.Assets = assetSettlements;
        }
        private async Task <IReadOnlyCollection <PositionReport> > CreateReports()
        {
            IReadOnlyCollection <Position> positions = await _positionService.GetAllAsync();

            IReadOnlyCollection <AssetInvestment> assetInvestments = _investmentService.GetAll();

            IReadOnlyCollection <HedgeLimitOrder> hedgeLimitOrders = _hedgeLimitOrderService.GetAll();

            HedgeSettings hedgeSettings = await _hedgeSettingsService.GetAsync();

            IReadOnlyCollection <AssetHedgeSettings>
            assetsHedgeSettings = await _assetHedgeSettingsService.GetAllAsync();

            string[] assets = positions.Select(o => o.AssetId)
                              .Union(assetInvestments.Select(o => o.AssetId))
                              .Union(assetsHedgeSettings.Select(o => o.AssetId))
                              .ToArray();

            var positionReports = new List <PositionReport>();

            foreach (string assetId in assets)
            {
                AssetHedgeSettings assetHedgeSettings = await _assetHedgeSettingsService.EnsureAsync(assetId);

                Position currentPosition = positions
                                           .SingleOrDefault(o => o.AssetId == assetId && o.Exchange == assetHedgeSettings.Exchange);

                HedgeLimitOrder hedgeLimitOrder = hedgeLimitOrders.SingleOrDefault(o => o.AssetId == assetId);

                AssetInvestment assetInvestment = assetInvestments.SingleOrDefault(o => o.AssetId == assetId);

                decimal?volumeInUsd = null;

                if (currentPosition != null)
                {
                    volumeInUsd = GetVolumeInUsd(currentPosition.AssetId, currentPosition.Exchange,
                                                 currentPosition.Volume);
                }

                Quote assetQuote;

                if (assetInvestment == null)
                {
                    assetQuote = _rateService.GetQuoteUsd(assetHedgeSettings.AssetId, assetHedgeSettings.Exchange);
                }
                else
                {
                    assetQuote = assetInvestment.Quote;
                }

                positionReports.Add(new PositionReport
                {
                    AssetId         = assetId,
                    Exchange        = assetHedgeSettings.Exchange,
                    Quote           = assetQuote,
                    Volume          = currentPosition?.Volume,
                    VolumeInUsd     = volumeInUsd,
                    OppositeVolume  = currentPosition?.OppositeVolume,
                    PnL             = volumeInUsd.HasValue ? currentPosition.OppositeVolume + volumeInUsd : null,
                    HedgeLimitOrder = hedgeLimitOrder,
                    AssetInvestment = assetInvestment,
                    Error           = ValidateAssetHedgeSettings(assetHedgeSettings)
                                      ?? ValidateInvestments(assetInvestment)
                                      ?? ValidateThresholdCritical(assetInvestment, hedgeSettings, assetHedgeSettings)
                                      ?? ValidateQuote(assetQuote)
                });

                IEnumerable <Position> otherPositions = positions
                                                        .Where(o => o.AssetId == assetId && o.Exchange != assetHedgeSettings.Exchange);

                foreach (Position position in otherPositions)
                {
                    Quote otherPositionQuote = _rateService.GetQuoteUsd(position.AssetId, position.Exchange);

                    volumeInUsd = GetVolumeInUsd(position.AssetId, position.Exchange, position.Volume);

                    positionReports.Add(new PositionReport
                    {
                        AssetId         = assetId,
                        Exchange        = position.Exchange,
                        Quote           = otherPositionQuote,
                        Volume          = position.Volume,
                        VolumeInUsd     = volumeInUsd,
                        OppositeVolume  = position.OppositeVolume,
                        PnL             = volumeInUsd.HasValue ? position.OppositeVolume + volumeInUsd : null,
                        HedgeLimitOrder = null,
                        AssetInvestment = null,
                        Error           = ValidateAssetHedgeSettings(assetHedgeSettings)
                                          ?? ValidateQuote(otherPositionQuote)
                    });
                }
            }

            foreach (PositionReport positionReport in positionReports)
            {
                if (positionReport.Exchange == ExchangeNames.Virtual)
                {
                    positionReport.ActualPnL = -1 * positionReport.PnL;
                }
                else
                {
                    positionReport.ActualPnL = positionReport.PnL;
                }
            }

            return(positionReports
                   .OrderBy(o => o.AssetId)
                   .ToArray());
        }