Пример #1
0
        private static bool AreEqual(IReadOnlyCollection <AssetInvestment> left,
                                     IReadOnlyCollection <AssetInvestment> right)
        {
            if (left.Count != right.Count)
            {
                return(false);
            }

            foreach (AssetInvestment leftAssetInvestment in left)
            {
                AssetInvestment rightAssetInvestment =
                    right.SingleOrDefault(o => o.AssetId == leftAssetInvestment.AssetId);

                if (rightAssetInvestment == null)
                {
                    return(false);
                }

                if (!AreEqual(leftAssetInvestment, rightAssetInvestment))
                {
                    return(false);
                }
            }

            return(true);
        }
        private static string ValidateInvestments(AssetInvestment assetInvestment)
        {
            if (assetInvestment?.IsDisabled == true)
            {
                return("Asset disabled");
            }

            return(null);
        }
Пример #3
0
 private static bool AreEqual(AssetInvestment left, AssetInvestment right)
 {
     return(left.AssetId == right.AssetId &&
            left.Volume == right.Volume &&
            left.TotalAmount == right.TotalAmount &&
            left.RemainingAmount == right.RemainingAmount &&
            left.IsDisabled == right.IsDisabled &&
            AreEqual(left.Quote, right.Quote) &&
            AreEqual(left.Indices, right.Indices));
 }
        private static string ValidateThresholdCritical(AssetInvestment assetInvestment, HedgeSettings hedgeSettings,
                                                        AssetHedgeSettings assetHedgeSettings)
        {
            decimal thresholdCritical = assetHedgeSettings.ThresholdCritical ?? hedgeSettings.ThresholdCritical;

            if (assetInvestment != null && thresholdCritical <= Math.Abs(assetInvestment.RemainingAmount))
            {
                return("Critical delta threshold exceeded");
            }

            return(null);
        }
        private static bool CanCreateHedgeLimitOrder(AssetInvestment assetInvestment,
                                                     AssetHedgeSettings assetHedgeSettings, HedgeSettings hedgeSettings, LimitOrderType limitOrderType)
        {
            if (assetInvestment.IsDisabled)
            {
                return(false);
            }

            decimal absoluteRemainingAmount = Math.Abs(assetInvestment.RemainingAmount);

            if (absoluteRemainingAmount <= 0)
            {
                return(false);
            }

            decimal thresholdCritical = assetHedgeSettings.ThresholdCritical ?? hedgeSettings.ThresholdCritical;

            if (0 < thresholdCritical && thresholdCritical <= absoluteRemainingAmount)
            {
                return(false);
            }

            decimal commonThresholdDown = limitOrderType == LimitOrderType.Buy ? hedgeSettings.ThresholdDownBuy : hedgeSettings.ThresholdDownSell;

            decimal thresholdDown = assetHedgeSettings.ThresholdDown ?? commonThresholdDown;

            if (assetHedgeSettings.Exchange != ExchangeNames.Virtual && absoluteRemainingAmount < thresholdDown)
            {
                return(false);
            }

            if (assetHedgeSettings.Mode != AssetHedgeMode.Auto && assetHedgeSettings.Mode != AssetHedgeMode.Idle)
            {
                return(false);
            }

            if (assetInvestment.Quote == null)
            {
                return(false);
            }

            return(true);
        }
        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());
        }