예제 #1
0
        private void OpenNewPosition(Order order, decimal volume)
        {
            if (order.ExecutionPrice == null)
            {
                _log.WriteWarning(nameof(OpenNewPosition), order.ToJson(),
                                  "Execution price is null. Position was not opened");
                return;
            }

            var position = new Position(order.Id, order.Code, order.AssetPairId, volume, order.AccountId,
                                        order.TradingConditionId, order.AccountAssetId, order.Price, order.MatchingEngineId,
                                        order.Executed.Value, order.Id, order.OrderType, order.Volume, order.ExecutionPrice.Value, order.FxRate,
                                        order.EquivalentAsset, order.EquivalentRate, order.RelatedOrders, order.LegalEntity, order.Originator,
                                        order.ExternalProviderId, order.FxAssetPairId, order.FxToAssetPairDirection, order.AdditionalInfo, order.ForceOpen);

            var defaultMatchingEngine = _meRouter.GetMatchingEngineForClose(position.OpenMatchingEngineId);

            var closePrice = defaultMatchingEngine.GetPriceForClose(position.AssetPairId, position.Volume,
                                                                    position.ExternalProviderId);

            position.UpdateClosePrice(closePrice ?? order.ExecutionPrice.Value);

            var isPositionAlreadyExist = _ordersCache.Positions.GetPositionsByInstrumentAndAccount(
                position.AssetPairId,
                position.AccountId).Any(p => p.Direction == position.Direction);

            _ordersCache.Positions.Add(position);

            var metadata = new PositionOpenMetadata {
                ExistingPositionIncreased = isPositionAlreadyExist
            };

            SendPositionHistoryEvent(position, PositionHistoryTypeContract.Open, 0,
                                     order.AdditionalInfo, metadata: metadata);

            ActivateRelatedOrders(position);
        }
예제 #2
0
        private void SendPositionHistoryEvent(Position position, PositionHistoryTypeContract historyType,
                                              decimal chargedPnl, string orderAdditionalInfo, Order dealOrder = null, decimal?dealVolume = null,
                                              PositionOpenMetadata metadata = null)
        {
            DealContract deal = null;

            if (dealOrder != null && dealVolume != null)
            {
                var sign = position.Volume > 0 ? 1 : -1;

                var accountBaseAssetAccuracy = AssetsConstants.DefaultAssetAccuracy;

                var fpl = Math.Round((dealOrder.ExecutionPrice.Value - position.OpenPrice) *
                                     dealOrder.FxRate * dealVolume.Value * sign, accountBaseAssetAccuracy);
                var balanceDelta = fpl - Math.Round(chargedPnl, accountBaseAssetAccuracy);

                var dealId = historyType == PositionHistoryTypeContract.Close
                    ? position.Id
                    : _identityGenerator.GenerateAlphanumericId();

                deal = new DealContract
                {
                    DealId                  = dealId,
                    PositionId              = position.Id,
                    Volume                  = dealVolume.Value,
                    Created                 = dealOrder.Executed.Value,
                    OpenTradeId             = position.OpenTradeId,
                    OpenOrderType           = position.OpenOrderType.ToType <OrderTypeContract>(),
                    OpenOrderVolume         = position.OpenOrderVolume,
                    OpenOrderExpectedPrice  = position.ExpectedOpenPrice,
                    CloseTradeId            = dealOrder.Id,
                    CloseOrderType          = dealOrder.OrderType.ToType <OrderTypeContract>(),
                    CloseOrderVolume        = dealOrder.Volume,
                    CloseOrderExpectedPrice = dealOrder.Price,
                    OpenPrice               = position.OpenPrice,
                    OpenFxPrice             = position.OpenFxPrice,
                    ClosePrice              = dealOrder.ExecutionPrice.Value,
                    CloseFxPrice            = dealOrder.FxRate,
                    Fpl             = fpl,
                    PnlOfTheLastDay = balanceDelta,
                    AdditionalInfo  = dealOrder.AdditionalInfo,
                    Originator      = dealOrder.Originator.ToType <OriginatorTypeContract>()
                };

                var account = _accountsCacheService.Get(position.AccountId);

                _cqrsSender.PublishEvent(new PositionClosedEvent(account.Id, account.ClientId,
                                                                 deal.DealId, position.AssetPairId, balanceDelta));

                _accountUpdateService.FreezeUnconfirmedMargin(position.AccountId, deal.DealId, balanceDelta)
                .GetAwaiter().GetResult();    //todo consider making this async or pass to broker
            }

            var positionContract = _convertService.Convert <Position, PositionContract>(position,
                                                                                        o => o.ConfigureMap(MemberList.Destination).ForMember(x => x.TotalPnL, c => c.Ignore()));

            positionContract.TotalPnL = position.GetFpl();

            var historyEvent = new PositionHistoryEvent
            {
                PositionSnapshot    = positionContract,
                Deal                = deal,
                EventType           = historyType,
                Timestamp           = _dateService.Now(),
                ActivitiesMetadata  = metadata?.ToJson(),
                OrderAdditionalInfo = orderAdditionalInfo,
            };

            _rabbitMqNotifyService.PositionHistory(historyEvent);
        }