Exemple #1
0
        public Tuple <Trade, bool> ProcessTradeMessage(Security security, ExecutionMessage message)
        {
            if (security == null)
            {
                throw new ArgumentNullException("security");
            }

            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            var trade = GetTrade(security, message.TradeId, message.TradeStringId, (id, stringId) =>
            {
                var t       = message.ToTrade(EntityFactory.CreateTrade(security, id, stringId));
                t.LocalTime = message.LocalTime;
                t.Time      = message.ServerTime;
                message.CopyExtensionInfo(t);
                return(t);
            });

            return(trade);
        }
Exemple #2
0
        public Tuple <OrderFail, bool> ProcessOrderFailMessage(Security security, ExecutionMessage message)
        {
            if (security == null)
            {
                throw new ArgumentNullException("security");
            }

            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            var data = _cache.GetData(security);

            Order order = null;

            if (!message.OrderStringId.IsEmpty())
            {
                order = data.OrdersByStringId.TryGetValue(message.OrderStringId);
            }

            bool isCancelled;

            if (order == null)
            {
                if (message.OriginalTransactionId == 0)
                {
                    throw new ArgumentOutOfRangeException("message", message.OriginalTransactionId, LocalizedStrings.Str715);
                }

                var orders = data.Orders;

                order = (Order)orders.TryGetValue(CreateOrderKey(message.OrderType, message.OriginalTransactionId, true));

                if (order != null && order.Id == message.OrderId)
                {
                    isCancelled = true;
                }
                else
                {
                    order       = (Order)orders.TryGetValue(CreateOrderKey(message.OrderType, message.OriginalTransactionId, false));
                    isCancelled = false;
                }

                if (order == null)
                {
                    return(null);
                }
            }
            else
            {
                var pair = data.Orders.LastOrDefault(p => p.Value.Order == order);
                isCancelled = pair.Key.Item3;
            }

            // ServerTime для заявки - это время регистрации
            order.LastChangeTime = message.LocalTime;
            order.LocalTime      = message.LocalTime;

            if (message.OrderStatus != null)
            {
                order.Status = message.OrderStatus;
            }

            //для ошибок снятия не надо менять состояние заявки
            if (!isCancelled)
            {
                order.State = OrderStates.Failed;
            }

            if (message.Commission != null)
            {
                order.Commission = message.Commission;
            }

            message.CopyExtensionInfo(order);

            var error = message.Error ?? new InvalidOperationException(
                isCancelled ? LocalizedStrings.Str716 : LocalizedStrings.Str717);

            var fail = EntityFactory.CreateOrderFail(order, error);

            fail.ServerTime = message.ServerTime;
            fail.LocalTime  = message.LocalTime;
            return(Tuple.Create(fail, isCancelled));
        }
Exemple #3
0
        public Tuple <MyTrade, bool> ProcessMyTradeMessage(Security security, ExecutionMessage message)
        {
            if (security == null)
            {
                throw new ArgumentNullException("security");
            }

            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            var originalTransactionId = _orderStatusTransactions.Contains(message.OriginalTransactionId)
                                ? 0 : message.OriginalTransactionId;

            if (originalTransactionId == 0 && message.OrderId == null && message.OrderStringId.IsEmpty())
            {
                throw new ArgumentOutOfRangeException("message", originalTransactionId, LocalizedStrings.Str715);
            }

            var securityData = _cache.GetData(security);

            var myTrade = securityData.MyTrades.TryGetValue(Tuple.Create(originalTransactionId, message.TradeId ?? 0));

            if (myTrade != null)
            {
                return(Tuple.Create(myTrade, false));
            }

            var order = GetOrder(security, originalTransactionId, message.OrderId, message.OrderStringId);

            if (order == null)
            {
                return(null);
            }

            var trade = message.ToTrade(EntityFactory.CreateTrade(security, message.TradeId, message.TradeStringId));

            var isNew = false;

            myTrade = securityData.MyTrades.SafeAdd(Tuple.Create(order.TransactionId, trade.Id), key =>
            {
                isNew = true;

                var t = EntityFactory.CreateMyTrade(order, trade);

                if (t.ExtensionInfo == null)
                {
                    t.ExtensionInfo = new Dictionary <object, object>();
                }

                if (message.Commission != null)
                {
                    t.Commission = message.Commission;
                }

                if (message.Slippage != null)
                {
                    t.Slippage = message.Slippage;
                }

                message.CopyExtensionInfo(t);

                //trades.Add(t);
                _cache.MyTrades.Add(t);

                return(t);
            });

            return(Tuple.Create(myTrade, isNew));

            // mika
            // http://stocksharp.com/forum/yaf_postst1072_Probliemy-so-sdielkami--pozitsiiami.aspx
            // из-за того, что сделки по заявке иногда приходит быстрее события NewOrders, неправильно расчитывается поза по стратегиям

            //var raiseOrderChanged = false;

            //trades.SyncDo(d =>
            //{
            //    var newBalance = order.Volume - d.Sum(t => t.Trade.Volume);

            //    if (order.Balance > newBalance)
            //    {
            //        raiseOrderChanged = true;

            //        order.Balance = newBalance;

            //        if (order.Balance == 0)
            //            order.State = OrderStates.Done;
            //    }
            //});

            //if (raiseOrderChanged)
            //    RaiseOrderChanged(order);
        }
Exemple #4
0
            public OrderChangeInfo ApplyChanges(ExecutionMessage message, bool isCancel)
            {
                var order = Order;

                OrderChangeInfo retVal;

                if (order.State == OrderStates.Done)
                {
                    // данные о заявке могут приходить из маркет-дата и транзакционного адаптеров
                    retVal         = OrderChangeInfo.Create(order, _raiseNewOrder, false);
                    _raiseNewOrder = false;
                    return(retVal);
                    //throw new InvalidOperationException("Изменение заявки в состоянии Done невозможно.");
                }
                else if (order.State == OrderStates.Failed)
                {
                    // some adapters can resend order's info

                    //throw new InvalidOperationException();
                    return(null);
                }

                var isPending = order.State == OrderStates.Pending;

                if (message.OrderId != null)
                {
                    order.Id = message.OrderId.Value;
                }

                if (!message.OrderStringId.IsEmpty())
                {
                    order.StringId = message.OrderStringId;
                }

                if (!message.OrderBoardId.IsEmpty())
                {
                    order.BoardId = message.OrderBoardId;
                }

                //// некоторые коннекторы не транслируют при отмене отмененный объем
                //// esper. при перерегистрации заявок необходимо обновлять баланс
                //if (message.Balance > 0 || !isCancelled || isReRegisterCancelled)
                //{
                //	// BTCE коннектор не транслирует баланс заявки
                //	if (!(message.OrderState == OrderStates.Active && message.Balance == 0))
                //		order.Balance = message.Balance;
                //}

                if (message.Balance != null)
                {
                    order.Balance = message.Balance.Value;
                }

                // IB коннектор не транслирует состояние заявки в одном из своих сообщений
                if (message.OrderState != null)
                {
                    order.State = order.State.CheckModification(message.OrderState.Value);
                }

                if (order.Time == DateTimeOffset.MinValue)
                {
                    order.Time = message.ServerTime;
                }

                // для новых заявок используем серверное время,
                // т.к. заявка получена первый раз и не менялась
                // ServerTime для заявки - это время регистрации
                order.LastChangeTime = _raiseNewOrder ? message.ServerTime : message.LocalTime;
                order.LocalTime      = message.LocalTime;

                //нулевой объем может быть при перерегистрации
                if (order.Volume == 0 && message.OrderVolume != null)
                {
                    order.Volume = message.OrderVolume.Value;
                }

                if (message.Commission != null)
                {
                    order.Commission = message.Commission;
                }

                if (!message.CommissionCurrency.IsEmpty())
                {
                    order.CommissionCurrency = message.CommissionCurrency;
                }

                if (message.TimeInForce != null)
                {
                    order.TimeInForce = message.TimeInForce.Value;
                }

                if (message.Latency != null)
                {
                    if (isCancel)
                    {
                        order.LatencyCancellation = message.Latency.Value;
                    }
                    else if (isPending)
                    {
                        if (order.State != OrderStates.Pending)
                        {
                            order.LatencyRegistration = message.Latency.Value;
                        }
                    }
                }

                if (message.AveragePrice != null)
                {
                    order.AveragePrice = message.AveragePrice;
                }

                if (message.Yield != null)
                {
                    order.Yield = message.Yield;
                }

                message.CopyExtensionInfo(order);

                retVal         = OrderChangeInfo.Create(order, _raiseNewOrder, true);
                _raiseNewOrder = false;
                return(retVal);
            }
Exemple #5
0
        public Tuple <Order, bool, bool> ProcessOrderMessage(Security security, ExecutionMessage message)
        {
            if (security == null)
            {
                throw new ArgumentNullException("security");
            }

            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            if (message.Error != null)
            {
                throw new ArgumentException(LocalizedStrings.Str714Params.PutEx(message));
            }

            bool isNew;

            var transactionId = message.TransactionId;

            if (transactionId == 0)
            {
                // ExecMsg.OriginalTransactionId == OrderStatMsg.TransactionId when orders info requested by OrderStatMsg
                transactionId = _orderStatusTransactions.Contains(message.OriginalTransactionId) ? 0 : message.OriginalTransactionId;
            }

            var securityData = _cache.GetData(security);

            var orderInfo = GetOrderInfo(securityData, message.OrderType, transactionId, message.OrderId, message.OrderStringId, trId =>
            {
                var o = EntityFactory.CreateOrder(security, message.OrderType, trId);

                o.Time        = message.ServerTime;
                o.Price       = message.Price;
                o.Volume      = message.Volume ?? 0;
                o.Direction   = message.Side;
                o.Comment     = message.Comment;
                o.ExpiryDate  = message.ExpiryDate;
                o.Condition   = message.Condition;
                o.UserOrderId = message.UserOrderId;
                o.Portfolio   = message.PortfolioName.IsEmpty()
                                        ? _portfolios.FirstOrDefault().Value
                                        : ProcessPortfolio(message.PortfolioName).Item1;

                return(o);
            }, out isNew, true);

            var order       = orderInfo.Item1;
            var isCancelled = orderInfo.Item2;
            //var isReReregisterCancelled = orderInfo.Item3;
            var raiseNewOrder = orderInfo.Item3;

            var isPending = order.State == OrderStates.Pending;
            //var isPrevIdSet = (order.Id != null || !order.StringId.IsEmpty());

            bool isChanged;

            if (order.State == OrderStates.Done)
            {
                // данные о заявке могут приходить из маркет-дата и транзакционного адаптеров
                isChanged = false;
                //throw new InvalidOperationException("Изменение заявки в состоянии Done невозможно.");
            }
            else
            {
                if (message.OrderId != null)
                {
                    order.Id = message.OrderId.Value;
                }

                if (!message.OrderStringId.IsEmpty())
                {
                    order.StringId = message.OrderStringId;
                }

                if (!message.OrderBoardId.IsEmpty())
                {
                    order.BoardId = message.OrderBoardId;
                }

                //// некоторые коннекторы не транслируют при отмене отмененный объем
                //// esper. при перерегистрации заявок необходимо обновлять баланс
                //if (message.Balance > 0 || !isCancelled || isReReregisterCancelled)
                //{
                //	// BTCE коннектор не транслирует баланс заявки
                //	if (!(message.OrderState == OrderStates.Active && message.Balance == 0))
                //		order.Balance = message.Balance;
                //}

                if (message.Balance != null)
                {
                    order.Balance = message.Balance.Value;
                }

                // IB коннектор не транслирует состояние заявки в одном из своих сообщений
                if (message.OrderState != null)
                {
                    order.State = message.OrderState.Value;
                }

                if (order.Time == DateTimeOffset.MinValue)
                {
                    order.Time = message.ServerTime;
                }

                // для новых заявок используем серверное время,
                // т.к. заявка получена первый раз и не менялась
                // ServerTime для заявки - это время регистрации
                order.LastChangeTime = isNew ? message.ServerTime : message.LocalTime;
                order.LocalTime      = message.LocalTime;

                //нулевой объем может быть при перерегистрации
                if (order.Volume == 0 && message.Volume != null)
                {
                    order.Volume = message.Volume.Value;
                }

                if (message.Commission != null)
                {
                    order.Commission = message.Commission;
                }

                if (message.TimeInForce != null)
                {
                    order.TimeInForce = message.TimeInForce.Value;
                }

                if (isPending)
                {
                    if (order.State != OrderStates.Pending && message.Latency != null)
                    {
                        order.LatencyRegistration = message.Latency.Value;
                    }
                }
                else if (isCancelled && order.State == OrderStates.Done)
                {
                    if (message.Latency != null)
                    {
                        order.LatencyCancellation = message.Latency.Value;
                    }
                }

                isChanged = true;
            }

            //if (isNew || (!isPrevIdSet && (order.Id != null || !order.StringId.IsEmpty())))
            //{

            // так как биржевые идентифиаторы могут повторяться, то переписываем старые заявки новыми как наиболее актуальными

            if (order.Id != null)
            {
                securityData.OrdersById[order.Id.Value] = order;
                _cache.AllOrdersById[order.Id.Value]    = order;
            }

            if (!order.StringId.IsEmpty())
            {
                securityData.OrdersByStringId[order.StringId] = order;
                _cache.AllOrdersByStringId[order.StringId]    = order;
            }

            //}

            //if (message.OrderType == OrderTypes.Conditional && (message.DerivedOrderId != null || !message.DerivedOrderStringId.IsEmpty()))
            //{
            //	var derivedOrder = GetOrder(security, 0L, message.DerivedOrderId ?? 0, message.DerivedOrderStringId);

            //	if (order == null)
            //		_orderStopOrderAssociations.Add(Tuple.Create(message.DerivedOrderId ?? 0, message.DerivedOrderStringId), new RefPair<Order, Action<Order, Order>>(order, (s, o) => s.DerivedOrder = o));
            //	else
            //		order.DerivedOrder = derivedOrder;
            //}

            message.CopyExtensionInfo(order);

            return(Tuple.Create(order, raiseNewOrder, isChanged));
        }
Exemple #6
0
        public Tuple <MyTrade, bool> ProcessMyTradeMessage(Order order, Security security, ExecutionMessage message, long transactionId)
        {
            if (security == null)
            {
                throw new ArgumentNullException(nameof(security));
            }

            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            var securityData = GetData(security);

            if (transactionId == 0 && message.OrderId == null && message.OrderStringId.IsEmpty())
            {
                throw new ArgumentOutOfRangeException(nameof(message), transactionId, LocalizedStrings.Str715);
            }

            var myTrade = securityData.MyTrades.TryGetValue(Tuple.Create(transactionId, message.TradeId ?? 0));

            if (myTrade != null)
            {
                return(Tuple.Create(myTrade, false));
            }

            if (order == null)
            {
                order = GetOrder(security, transactionId, message.OrderId, message.OrderStringId);

                if (order == null)
                {
                    return(null);
                }
            }

            var trade = message.ToTrade(EntityFactory.CreateTrade(security, message.TradeId, message.TradeStringId));

            var isNew = false;

            myTrade = securityData.MyTrades.SafeAdd(Tuple.Create(order.TransactionId, trade.Id), key =>
            {
                isNew = true;

                var t = EntityFactory.CreateMyTrade(order, trade);

                if (t.ExtensionInfo == null)
                {
                    t.ExtensionInfo = new Dictionary <object, object>();
                }

                if (message.Commission != null)
                {
                    t.Commission = message.Commission;
                }

                if (message.Slippage != null)
                {
                    t.Slippage = message.Slippage;
                }

                if (message.PnL != null)
                {
                    t.PnL = message.PnL;
                }

                if (message.Position != null)
                {
                    t.Position = message.Position;
                }

                message.CopyExtensionInfo(t);

                _myTrades.Add(t);

                return(t);
            });

            return(Tuple.Create(myTrade, isNew));
        }
Exemple #7
0
        public IEnumerable <Tuple <OrderFail, bool> > ProcessOrderFailMessage(Order order, Security security, ExecutionMessage message)
        {
            if (security == null)
            {
                throw new ArgumentNullException(nameof(security));
            }

            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            var data = GetData(security);

            var orders = new List <Tuple <Order, bool> >();

            if (message.OriginalTransactionId == 0)
            {
                throw new ArgumentOutOfRangeException(nameof(message), message.OriginalTransactionId, LocalizedStrings.Str715);
            }

            var orderType = message.OrderType;

            if (order == null)
            {
                var cancelledOrder = data.Orders.TryGetValue(CreateOrderKey(orderType, message.OriginalTransactionId, true))?.Order;

                if (cancelledOrder == null && orderType == null)
                {
                    cancelledOrder = data.Orders.TryGetValue(CreateOrderKey(OrderTypes.Conditional, message.OriginalTransactionId, true))?.Order;

                    if (cancelledOrder != null)
                    {
                        orderType = OrderTypes.Conditional;
                    }
                }

                if (cancelledOrder != null /*&& order.Id == message.OrderId*/)
                {
                    orders.Add(Tuple.Create(cancelledOrder, true));
                }

                var registeredOrder = data.Orders.TryGetValue(CreateOrderKey(orderType, message.OriginalTransactionId, false))?.Order;

                if (registeredOrder == null && orderType == null)
                {
                    registeredOrder = data.Orders.TryGetValue(CreateOrderKey(OrderTypes.Conditional, message.OriginalTransactionId, false))?.Order;
                }

                if (registeredOrder != null)
                {
                    orders.Add(Tuple.Create(registeredOrder, false));
                }

                if (cancelledOrder == null && registeredOrder == null)
                {
                    if (!message.OrderStringId.IsEmpty())
                    {
                        order = data.OrdersByStringId.TryGetValue(message.OrderStringId);

                        if (order != null)
                        {
                            var pair = data.Orders.LastOrDefault(p => p.Value.Order == order);

                            if (pair.Key != null)
                            {
                                orders.Add(Tuple.Create(pair.Value.Order, pair.Key.Item3));
                            }
                        }
                    }
                }
            }
            else
            {
                if (data.Orders.ContainsKey(CreateOrderKey(order.Type, message.OriginalTransactionId, true)))
                {
                    orders.Add(Tuple.Create(order, true));
                }

                var registeredOrder = data.Orders.TryGetValue(CreateOrderKey(order.Type, message.OriginalTransactionId, false))?.Order;
                if (registeredOrder != null)
                {
                    orders.Add(Tuple.Create(registeredOrder, false));
                }
            }

            if (orders.Count == 0)
            {
                return(Enumerable.Empty <Tuple <OrderFail, bool> >());
            }

            return(orders.Select(t =>
            {
                var o = t.Item1;
                var isCancelTransaction = t.Item2;

                o.LastChangeTime = message.ServerTime;
                o.LocalTime = message.LocalTime;

                if (message.OrderStatus != null)
                {
                    o.Status = message.OrderStatus;
                }

                //для ошибок снятия не надо менять состояние заявки
                if (!isCancelTransaction)
                {
                    o.State = o.State.CheckModification(OrderStates.Failed);
                }

                if (message.Commission != null)
                {
                    o.Commission = message.Commission;
                }

                message.CopyExtensionInfo(o);

                var error = message.Error ?? new InvalidOperationException(isCancelTransaction ? LocalizedStrings.Str716 : LocalizedStrings.Str717);

                var fail = EntityFactory.CreateOrderFail(o, error);
                fail.ServerTime = message.ServerTime;
                fail.LocalTime = message.LocalTime;
                return Tuple.Create(fail, isCancelTransaction);
            }));
        }
Exemple #8
0
            public IEnumerable <OrderChangeInfo> ApplyChanges(ExecutionMessage message, bool isCancel, Action <Order> process)
            {
                if (process is null)
                {
                    throw new ArgumentNullException(nameof(process));
                }

                var order = Order;

                OrderChangeInfo retVal;

                if (order.State == OrderStates.Done)
                {
                    // данные о заявке могут приходить из маркет-дата и транзакционного адаптеров
                    retVal         = new OrderChangeInfo(order, _raiseNewOrder, false);
                    _raiseNewOrder = false;
                    process(order);
                    yield return(retVal);
                    //throw new InvalidOperationException("Изменение заявки в состоянии Done невозможно.");
                }
                else if (order.State == OrderStates.Failed)
                {
                    // some adapters can resend order's info

                    //throw new InvalidOperationException();
                    yield break;
                }

                var isPending = order.State == OrderStates.Pending;

                // is we have Pending order and received Done event
                // add intermediate Active event
                if (isPending && message.OrderState == OrderStates.Done)
                {
                    var clone = message.TypedClone();
                    clone.OrderState = OrderStates.Active;
                    clone.Balance    = null;

                    foreach (var i in ApplyChanges(clone, false, process))
                    {
                        yield return(i);
                    }
                }

                if (message.OrderId != null)
                {
                    order.Id = message.OrderId.Value;
                }

                if (!message.OrderStringId.IsEmpty())
                {
                    order.StringId = message.OrderStringId;
                }

                if (!message.OrderBoardId.IsEmpty())
                {
                    order.BoardId = message.OrderBoardId;
                }

                if (message.Balance != null)
                {
                    order.Balance = ((decimal?)order.Balance).ApplyNewBalance(message.Balance.Value, order.TransactionId, _parent._logReceiver);
                }

                if (message.OrderState != null)
                {
                    order.ApplyNewState(message.OrderState.Value, _parent._logReceiver);
                }

                if (order.Time == DateTimeOffset.MinValue)
                {
                    order.Time = message.ServerTime;
                }

                // для новых заявок используем серверное время,
                // т.к. заявка получена первый раз и не менялась
                // ServerTime для заявки - это время регистрации
                order.LastChangeTime = _raiseNewOrder ? message.ServerTime : message.LocalTime;
                order.LocalTime      = message.LocalTime;

                //нулевой объем может быть при перерегистрации
                if (order.Volume == 0 && message.OrderVolume != null)
                {
                    order.Volume = message.OrderVolume.Value;
                }

                if (message.Commission != null)
                {
                    order.Commission = message.Commission;
                }

                if (!message.CommissionCurrency.IsEmpty())
                {
                    order.CommissionCurrency = message.CommissionCurrency;
                }

                if (message.TimeInForce != null)
                {
                    order.TimeInForce = message.TimeInForce.Value;
                }

                if (message.Latency != null)
                {
                    if (isCancel)
                    {
                        order.LatencyCancellation = message.Latency.Value;
                    }
                    else if (isPending)
                    {
                        if (order.State != OrderStates.Pending)
                        {
                            order.LatencyRegistration = message.Latency.Value;
                        }
                    }
                }

                if (message.AveragePrice != null)
                {
                    order.AveragePrice = message.AveragePrice;
                }

                if (message.Yield != null)
                {
                    order.Yield = message.Yield;
                }

                message.CopyExtensionInfo(order);

                retVal         = new OrderChangeInfo(order, _raiseNewOrder, true);
                _raiseNewOrder = false;
                process(order);
                yield return(retVal);
            }
Exemple #9
0
            public OrderChangeInfo ApplyChanges(ExecutionMessage message, bool isCancel)
            {
                var order = Order;

                OrderChangeInfo retVal;

                if (order.State == OrderStates.Done)
                {
                    // данные о заявке могут приходить из маркет-дата и транзакционного адаптеров
                    retVal         = OrderChangeInfo.Create(order, _raiseNewOrder, false);
                    _raiseNewOrder = false;
                    return(retVal);
                    //throw new InvalidOperationException("Изменение заявки в состоянии Done невозможно.");
                }
                else if (order.State == OrderStates.Failed)
                {
                    // some adapters can resend order's info

                    //throw new InvalidOperationException();
                    return(null);
                }

                var isPending = order.State == OrderStates.Pending;

                if (message.OrderId != null)
                {
                    order.Id = message.OrderId.Value;
                }

                if (!message.OrderStringId.IsEmpty())
                {
                    order.StringId = message.OrderStringId;
                }

                if (!message.OrderBoardId.IsEmpty())
                {
                    order.BoardId = message.OrderBoardId;
                }

                if (message.Balance != null)
                {
                    if (order.Balance < message.Balance.Value)
                    {
                        _parent._logReceiver.AddErrorLog($"Order {order.TransactionId}: bal_old {order.Balance} -> bal_new {message.Balance.Value}");
                    }

                    order.Balance = message.Balance.Value;
                }

                if (message.OrderState != null)
                {
                    order.State = order.State.CheckModification(message.OrderState.Value);
                }

                if (order.Time == DateTimeOffset.MinValue)
                {
                    order.Time = message.ServerTime;
                }

                // для новых заявок используем серверное время,
                // т.к. заявка получена первый раз и не менялась
                // ServerTime для заявки - это время регистрации
                order.LastChangeTime = _raiseNewOrder ? message.ServerTime : message.LocalTime;
                order.LocalTime      = message.LocalTime;

                //нулевой объем может быть при перерегистрации
                if (order.Volume == 0 && message.OrderVolume != null)
                {
                    order.Volume = message.OrderVolume.Value;
                }

                if (message.Commission != null)
                {
                    order.Commission = message.Commission;
                }

                if (!message.CommissionCurrency.IsEmpty())
                {
                    order.CommissionCurrency = message.CommissionCurrency;
                }

                if (message.TimeInForce != null)
                {
                    order.TimeInForce = message.TimeInForce.Value;
                }

                if (message.Latency != null)
                {
                    if (isCancel)
                    {
                        order.LatencyCancellation = message.Latency.Value;
                    }
                    else if (isPending)
                    {
                        if (order.State != OrderStates.Pending)
                        {
                            order.LatencyRegistration = message.Latency.Value;
                        }
                    }
                }

                if (message.AveragePrice != null)
                {
                    order.AveragePrice = message.AveragePrice;
                }

                if (message.Yield != null)
                {
                    order.Yield = message.Yield;
                }

                message.CopyExtensionInfo(order);

                retVal         = OrderChangeInfo.Create(order, _raiseNewOrder, true);
                _raiseNewOrder = false;
                return(retVal);
            }
Exemple #10
0
        private Tuple <MyTrade, bool> AddMyTrade(Order order, Trade trade, ExecutionMessage message)
        {
            if (order == null)
            {
                throw new ArgumentNullException("order");
            }

            if (trade == null)
            {
                throw new ArgumentNullException("trade");
            }

            var isNew = false;

            var myTrade = _cache.GetData(order.Security).MyTrades.SafeAdd(Tuple.Create(order.TransactionId, trade.Id), key =>
            {
                isNew = true;

                var t = EntityFactory.CreateMyTrade(order, trade);

                if (t.ExtensionInfo == null)
                {
                    t.ExtensionInfo = new Dictionary <object, object>();
                }

                if (message.Commission != null)
                {
                    t.Commission = message.Commission;
                }

                if (message.Slippage != null)
                {
                    t.Slippage = message.Slippage;
                }

                message.CopyExtensionInfo(t);

                //trades.Add(t);
                _cache.MyTrades.Add(t);

                return(t);
            });

            return(Tuple.Create(myTrade, isNew));

            // mika
            // http://stocksharp.com/forum/yaf_postst1072_Probliemy-so-sdielkami--pozitsiiami.aspx
            // из-за того, что сделки по заявке иногда приходит быстрее события NewOrders, неправильно расчитывается поза по стратегиям

            //var raiseOrderChanged = false;

            //trades.SyncDo(d =>
            //{
            //    var newBalance = order.Volume - d.Sum(t => t.Trade.Volume);

            //    if (order.Balance > newBalance)
            //    {
            //        raiseOrderChanged = true;

            //        order.Balance = newBalance;

            //        if (order.Balance == 0)
            //            order.State = OrderStates.Done;
            //    }
            //});

            //if (raiseOrderChanged)
            //    RaiseOrderChanged(order);
        }