예제 #1
0
 private static string MyTradeToString(ExecutionMessage trade)
 {
     return string.Format("{0};{1};{2};{3};{4};{5};{6}",
         trade.SecurityId.SecurityCode,
         trade.TradeId,
         trade.ServerTime,
         trade.TradePrice,
         trade.Volume,
         trade.Side,
         trade.OrderId);
 }
예제 #2
0
 private static string TradeToString(ExecutionMessage tick)
 {
     //securityId;tradeId;time;price;volume;orderdirection 
     return string.Format("{0};{1};{2};{3};{4};{5}",
         tick.SecurityId.SecurityCode,
         tick.TradeId,
         tick.ServerTime,
         tick.TradePrice,
         tick.Volume,
         tick.Side);
 }
예제 #3
0
        public Tuple <Trade, bool> ProcessTradeMessage(Security security, ExecutionMessage message)
        {
            if (security == null)
            {
                throw new ArgumentNullException(nameof(security));
            }

            if (message == null)
            {
                throw new ArgumentNullException(nameof(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);
        }
예제 #4
0
        /// <summary>
        /// To calculate trade profitability. If the trade was already processed earlier, previous information returns.
        /// </summary>
        /// <param name="trade">Trade.</param>
        /// <param name="info">Information on new trade.</param>
        /// <returns><see langword="true" />, if new trade received, otherwise, <see langword="false" />.</returns>
        public bool ProcessMyTrade(ExecutionMessage trade, out PnLInfo info)
        {
            if (trade == null)
            {
                throw new ArgumentNullException(nameof(trade));
            }

            var tradeId = trade.GetTradeId();

            if (_tradeInfos.TryGetValue(tradeId, out info))
            {
                return(false);
            }

            var queue = _securityPnLs.SafeAdd(trade.SecurityId, security => new PnLQueue(security));

            info = queue.Process(trade);

            _tradeInfos.Add(tradeId, info);
            _realizedPnL += info.PnL;

            return(true);
        }
예제 #5
0
        public void StartExport()
        {
            MarketDataAdapter.SendInMessage(new PortfolioLookupMessage {
                TransactionId = TransactionIdGenerator.GetNextId()
            });

            var exm = new ExecutionMessage {
                ExtensionInfo = new Dictionary <object, object>()
            };

            exm.ExtensionInfo.Add(new KeyValuePair <object, object>("GetMyTrades", null));
            exm.ExtensionInfo.Add(new KeyValuePair <object, object>("GetOrders", null));

            MarketDataAdapter.SendInMessage(exm);

            var posm = new PositionMessage {
                ExtensionInfo = new Dictionary <object, object>()
            };

            posm.ExtensionInfo.Add(new KeyValuePair <object, object>("GetPositions", null));

            MarketDataAdapter.SendInMessage(posm);
        }
예제 #6
0
		private static void SaveTransaction(ISnapshotStorage snapshotStorage, ExecutionMessage message)
		{
			ExecutionMessage sepTrade = null;

			if (message.HasOrderInfo && message.HasTradeInfo)
			{
				sepTrade = new ExecutionMessage
				{
					HasTradeInfo = true,
					SecurityId = message.SecurityId,
					ServerTime = message.ServerTime,
					TransactionId = message.TransactionId,
					ExecutionType = message.ExecutionType,
					TradeId = message.TradeId,
					TradeVolume = message.TradeVolume,
					TradePrice = message.TradePrice,
					TradeStatus = message.TradeStatus,
					TradeStringId = message.TradeStringId,
					OriginSide = message.OriginSide,
					Commission = message.Commission,
					IsSystem = message.IsSystem,
				};

				message.HasTradeInfo = false;
				message.TradeId = null;
				message.TradeVolume = null;
				message.TradePrice = null;
				message.TradeStatus = null;
				message.TradeStringId = null;
				message.OriginSide = null;
			}

			snapshotStorage.Update(message);

			if (sepTrade != null)
				snapshotStorage.Update(sepTrade);
		}
예제 #7
0
        private void ProcessLevel1Trade(Level1ChangeMessage message, decimal lastTradePrice, decimal lastTradeVolume, List <ExecutionMessage> retVal)
        {
            if (message.LocalTime.Date == _lastTradeDate)
            {
                return;
            }

            if (lastTradePrice == 0 || lastTradeVolume == 0)
            {
                return;
            }

            var exec = new ExecutionMessage
            {
                LocalTime     = message.LocalTime,
                ServerTime    = message.ServerTime,
                SecurityId    = message.SecurityId,
                ExecutionType = ExecutionTypes.Tick,
                TradePrice    = lastTradePrice,
                Volume        = lastTradeVolume,
            };

            retVal.AddRange(ProcessExecution(exec));
        }
예제 #8
0
 private static string TradeToString(ExecutionMessage tick)
 {
     //securityId;tradeId;time;price;volume;orderdirection 
     return $"{tick.SecurityId.SecurityCode};{tick.TradeId};{tick.ServerTime};{tick.TradePrice};{tick.TradeVolume};{tick.Side}";
 }
예제 #9
0
 private void OnMessageReported(FileBasedProject project, ExecutionMessage executionMessage)
 {
     MessageReported?.Invoke(this, new ProjectMessageEventArgs {
         Project = project, Message = executionMessage.Level + ": " + executionMessage.Message
     });
 }
		private void ProcessOrderMessage(Order o, Security security, ExecutionMessage message, long transactionId)
		{
			if (message.OrderState != OrderStates.Failed)
			{
				Tuple<Portfolio, bool, bool> pfInfo;
				var tuples = _entityCache.ProcessOrderMessage(o, security, message, transactionId, out pfInfo);

				if (tuples == null)
				{
					this.AddWarningLog(LocalizedStrings.Str1156Params, message.OrderId.To<string>() ?? message.OrderStringId);
					return;
				}

				if (pfInfo != null)
					ProcessPortfolio(pfInfo);

				foreach (var tuple in tuples)
				{
					var order = tuple.Item1;
					var isNew = tuple.Item2;
					var isChanged = tuple.Item3;

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

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

					if (message.OrderState == OrderStates.Active || message.OrderState == OrderStates.Done)
					{
						var info = _filteredMarketDepths.TryGetValue(order.Security);
						info?.Process(message);
					}

					if (isNew)
					{
						this.AddOrderInfoLog(order, "New order");

						if (order.Type == OrderTypes.Conditional)
							RaiseNewStopOrders(new[] { order });
						else
							RaiseNewOrder(order);
					}
					else if (isChanged)
					{
						this.AddOrderInfoLog(order, "Order changed");

						if (order.Type == OrderTypes.Conditional)
							RaiseStopOrdersChanged(new[] { order });
						else
							RaiseOrderChanged(order);
					}

					if (order.Id != null)
						ProcessMyTrades(order, order.Id.Value, _nonAssociatedByIdMyTrades);

					ProcessMyTrades(order, order.TransactionId, _nonAssociatedByTransactionIdMyTrades);

					if (!order.StringId.IsEmpty())
						ProcessMyTrades(order, order.StringId, _nonAssociatedByStringIdMyTrades);

					ProcessConditionOrders(order);
				}
			}
			else
			{
				foreach (var tuple in _entityCache.ProcessOrderFailMessage(o, security, message))
				{
					var fail = tuple.Item1;

					//TryProcessFilteredMarketDepth(fail.Order.Security, message);

					//var isRegisterFail = (fail.Order.Id == null && fail.Order.StringId.IsEmpty()) || fail.Order.Status == OrderStatus.RejectedBySystem;
					var isCancelTransaction = tuple.Item2;

					this.AddErrorLog(() => (isCancelTransaction ? "OrderCancelFailed" : "OrderRegisterFailed")
						+ Environment.NewLine + fail.Order + Environment.NewLine + fail.Error);

					var isStop = fail.Order.Type == OrderTypes.Conditional;

					if (!isCancelTransaction)
					{
						_entityCache.AddRegisterFail(fail);

						if (isStop)
							RaiseStopOrdersRegisterFailed(new[] { fail });
						else
							RaiseOrderRegisterFailed(fail);
					}
					else
					{
						_entityCache.AddCancelFail(fail);

						if (isStop)
							RaiseStopOrdersCancelFailed(new[] { fail });
						else
							RaiseOrderCancelFailed(fail);
					}
				}
			}
		}
예제 #11
0
 protected override void WriterFixOrderCondition(IFixWriter writer, ExecutionMessage message)
 {
     writer.WriteOrderCondition((QuikOrderCondition)message.Condition, TransactionSession.DateTimeFormat);
 }
        private void OnSessionOrderChanged(LmaxOrder lmaxOrder)
        {
            var transactionId = TryParseTransactionId(lmaxOrder.InstructionId);

            if (transactionId == null)
            {
                return;
            }

            LmaxOrderCondition condition = null;
            decimal            price     = 0;
            OrderTypes         orderType;

            switch (lmaxOrder.OrderType)
            {
            case OrderType.MARKET:
                orderType = OrderTypes.Market;
                break;

            case OrderType.LIMIT:
                orderType = OrderTypes.Limit;

                if (lmaxOrder.LimitPrice == null)
                {
                    throw new ArgumentException(LocalizedStrings.Str3394Params.Put(transactionId), nameof(lmaxOrder));
                }

                price = (decimal)lmaxOrder.LimitPrice;
                break;

            case OrderType.STOP_ORDER:
            case OrderType.STOP_LOSS_MARKET_ORDER:
            case OrderType.STOP_PROFIT_LIMIT_ORDER:
                orderType = OrderTypes.Conditional;

                if (lmaxOrder.StopPrice == null)
                {
                    throw new ArgumentException(LocalizedStrings.Str3395Params.Put(transactionId), nameof(lmaxOrder));
                }

                price = (decimal)lmaxOrder.StopPrice;

                condition = new LmaxOrderCondition
                {
                    StopLossOffset   = lmaxOrder.StopLossOffset,
                    TakeProfitOffset = lmaxOrder.StopProfitOffset,
                };
                break;

            case OrderType.CLOSE_OUT_ORDER_POSITION:
            case OrderType.CLOSE_OUT_POSITION:
            case OrderType.SETTLEMENT_ORDER:
            case OrderType.OFF_ORDERBOOK:
            case OrderType.REVERSAL:
            case OrderType.UNKNOWN:
                orderType = OrderTypes.Execute;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            DateTimeOffset?expiryDate = null;
            var            tif        = StockSharpTimeInForce.PutInQueue;

            switch (lmaxOrder.TimeInForce)
            {
            case LmaxTimeInForce.FillOrKill:
                tif = StockSharpTimeInForce.MatchOrCancel;
                break;

            case LmaxTimeInForce.ImmediateOrCancel:
                tif = StockSharpTimeInForce.CancelBalance;
                break;

            case LmaxTimeInForce.GoodForDay:
                expiryDate = DateTime.Today.ApplyTimeZone(TimeZoneInfo.Utc);
                break;

            case LmaxTimeInForce.GoodTilCancelled:
                break;

            case LmaxTimeInForce.Unknown:
                throw new NotSupportedException(LocalizedStrings.Str3396Params.Put(lmaxOrder.TimeInForce, transactionId.Value, lmaxOrder.OrderId));

            default:
                throw new InvalidOperationException(LocalizedStrings.Str3397Params.Put(lmaxOrder.TimeInForce, transactionId.Value, lmaxOrder.OrderId));
            }

            var msg = new ExecutionMessage
            {
                SecurityId = new SecurityId {
                    Native = lmaxOrder.InstrumentId
                },
                OriginalTransactionId = transactionId.Value,
                OrderType             = orderType,
                OrderPrice            = price,
                Condition             = condition,
                OrderVolume           = lmaxOrder.Quantity.Abs(),
                Side          = lmaxOrder.Quantity > 0 ? Sides.Buy : Sides.Sell,
                Balance       = lmaxOrder.Quantity - lmaxOrder.FilledQuantity,
                PortfolioName = lmaxOrder.AccountId.To <string>(),
                TimeInForce   = tif,
                ExpiryDate    = expiryDate,
                OrderStringId = lmaxOrder.OrderId,
                ExecutionType = ExecutionTypes.Transaction,
                Commission    = lmaxOrder.Commission,
                ServerTime    = CurrentTime.Convert(TimeZoneInfo.Utc),
                HasOrderInfo  = true,
            };

            msg.OrderState = lmaxOrder.CancelledQuantity > 0
                                                                ? OrderStates.Done
                                                                : (msg.Balance == 0 ? OrderStates.Done : OrderStates.Active);

            //msg.Action = lmaxOrder.CancelledQuantity > 0
            //				 ? ExecutionActions.Canceled
            //				 : (lmaxOrder.FilledQuantity == 0 ? ExecutionActions.Registered : ExecutionActions.Matched);

            SendOutMessage(msg);
        }
예제 #13
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));
        }
예제 #14
0
        public static string PrintExecutionMsg(ExecutionMessage msg)
        {
            Execution exe = msg.Execution;

            return(string.Format("executioID {0}, orderID {1}, side {2}, price {3}, qty {4}, reqeustID {5}.", exe.ExecId, exe.OrderId, exe.Side, exe.Price, exe.Shares, msg.ReqId));
        }
예제 #15
0
        /// <summary>
        /// Обработать сообщение.
        /// </summary>
        /// <param name="message">Сообщение.</param>
        /// <returns>Результат обработки. Если будет возрвщено <see langword="null"/>,
        /// то генератору пока недостаточно данных для генерации нового сообщения.</returns>
        protected override Message OnProcess(Message message)
        {
            DateTimeOffset time;

            switch (message.Type)
            {
            case MessageTypes.Level1Change:
            {
                var l1Msg = (Level1ChangeMessage)message;

                var value = l1Msg.Changes.TryGetValue(Level1Fields.LastTradePrice);

                if (value != null)
                {
                    _lastOrderPrice = (decimal)value;
                }

                TradeGenerator.Process(message);

                time = l1Msg.ServerTime;
                break;
            }

            case MessageTypes.Execution:
            {
                var execMsg = (ExecutionMessage)message;

                switch (execMsg.ExecutionType)
                {
                case ExecutionTypes.Tick:
                    _lastOrderPrice = execMsg.GetTradePrice();
                    break;

                default:
                    return(null);
                }

                time = execMsg.ServerTime;
                break;
            }

            case MessageTypes.Time:
            {
                var timeMsg = (TimeMessage)message;

                time = timeMsg.ServerTime;

                break;
            }

            default:
                return(null);
            }

            if (!IsTimeToGenerate(time))
            {
                return(null);
            }

            // TODO более реалистичную генерацию, так как сейчас объемы, цены и сделки c потолка

            var action = RandomGen.GetInt(0, 5);

            var isNew = action < 3 || _activeOrders.IsEmpty();

            ExecutionMessage item;

            if (isNew)
            {
                var priceStep = SecurityDefinition.PriceStep ?? 0.01m;

                _lastOrderPrice += RandomGen.GetInt(-MaxPriceStepCount, MaxPriceStepCount) * priceStep;

                if (_lastOrderPrice <= 0)
                {
                    _lastOrderPrice = priceStep;
                }

                item = new ExecutionMessage
                {
                    OrderId       = IdGenerator.GetNextId(),
                    SecurityId    = SecurityId,
                    ServerTime    = time,
                    OrderState    = OrderStates.Active,
                    Volume        = Volumes.Next(),
                    Side          = RandomGen.GetEnum <Sides>(),
                    Price         = _lastOrderPrice,
                    ExecutionType = ExecutionTypes.OrderLog,
                };

                _activeOrders.Enqueue((ExecutionMessage)item.Clone());
            }
            else
            {
                var activeOrder = _activeOrders.Peek();

                item            = (ExecutionMessage)activeOrder.Clone();
                item.ServerTime = time;

                var isMatched = action == 5;

                ExecutionMessage trade = null;

                if (isMatched)
                {
                    trade = (ExecutionMessage)TradeGenerator.Process(message);
                }

                if (isMatched && trade != null)
                {
                    item.Volume = RandomGen.GetInt(1, (int)activeOrder.GetVolume());

                    item.TradeId     = trade.TradeId;
                    item.TradePrice  = trade.TradePrice;
                    item.TradeStatus = trade.TradeStatus;

                    // TODO
                    //quote.Trade = TradeGenerator.Generate(time);
                    //item.Volume = activeOrder.Volume;

                    //if (item.Side == Sides.Buy && quote.Trade.Price > quote.Order.Price)
                    //	item.TradePrice = item.Price;
                    //else if (item.Side == Sides.Sell && quote.Trade.Price < quote.Order.Price)
                    //	item.TradePrice = item.Price;

                    activeOrder.Volume -= item.Volume;

                    if (activeOrder.Volume == 0)
                    {
                        item.OrderState = OrderStates.Done;
                        _activeOrders.Dequeue();
                    }
                    else
                    {
                        item.OrderState = OrderStates.Active;
                    }
                }
                else
                {
                    item.OrderState  = OrderStates.Done;
                    item.IsCancelled = true;
                    _activeOrders.Dequeue();
                }
            }

            LastGenerationTime = time;

            return(item);
        }
        private ExecutionMessage getExeMessage_for_Sell3Contract()
        {
            ExecutionMessage message = new ExecutionMessage(3001, getContract(), getExecution_for_Sell3Contract());

            return(message);
        }
예제 #17
0
        private Message ProcessBuilders(ExecutionMessage execMsg)
        {
            List <long> nonBuilderIds = null;

            foreach (var subscriptionId in execMsg.GetSubscriptionIds())
            {
                if (!_subscriptionIds.TryGetValue(subscriptionId, out var info))
                {
                    if (nonBuilderIds == null)
                    {
                        nonBuilderIds = new List <long>();
                    }

                    nonBuilderIds.Add(subscriptionId);

                    // can be non OL->MB subscription
                    //this.AddDebugLog("OL processing {0}/{1} not found.", execMsg.SecurityId, subscriptionId);
                    continue;
                }

                if (!info.IsTicks)
                {
                    try
                    {
                        QuoteChangeMessage depth;

                        lock (info.Lock)
                        {
                            depth = info.Builder.Update(execMsg);

                            if (info.State != SubscriptionStates.Online)
                            {
                                depth = null;
                            }
                            else
                            {
                                depth = depth?.TypedClone();
                            }
                        }

                        this.AddDebugLog("OL->MD processing {0}={1}.", execMsg.SecurityId, depth != null);

                        if (depth != null)
                        {
                            depth.SetSubscriptionIds(subscriptionId: subscriptionId);
                            base.OnInnerAdapterNewOutMessage(depth);
                        }
                    }
                    catch (Exception ex)
                    {
                        // если ОЛ поврежден, то не нарушаем весь цикл обработки сообщения
                        // а только выводим сообщение в лог
                        base.OnInnerAdapterNewOutMessage(ex.ToErrorMessage());
                    }
                }
                else
                {
                    this.AddDebugLog("OL->TICK processing {0}.", execMsg.SecurityId);
                    base.OnInnerAdapterNewOutMessage(execMsg.ToTick());
                }
            }

            if (nonBuilderIds is null)
            {
                return(null);
            }

            execMsg.SetSubscriptionIds(nonBuilderIds.ToArray());
            return(execMsg);
        }
예제 #18
0
 private static string OrderToString(ExecutionMessage order)
 {
     return string.Format("{0};{1};{2};{3};{4};{5};{6};{7};{8};{9};{10};{11};{12}",
         order.OrderId,
         order.OriginalTransactionId,
         order.ServerTime,
         order.SecurityId.SecurityCode,
         order.PortfolioName,
         order.Volume,
         order.Balance,
         order.Price,
         order.OriginSide,
         order.OrderType,
         order.OrderState,
         order.IsCancelled,
         order.LocalTime);
 }
예제 #19
0
 private static string MyTradeToString(ExecutionMessage trade)
 {
     return $"{trade.SecurityId.SecurityCode};{trade.TradeId};{trade.ServerTime};{trade.TradePrice};{trade.TradeVolume};{trade.Side};{trade.OrderId}";
 }
예제 #20
0
 private static string OrderToString(ExecutionMessage order)
 {
     return $"{order.OrderId};{order.OriginalTransactionId};{order.ServerTime};{order.SecurityId.SecurityCode};{order.PortfolioName};{order.OrderVolume};{order.Balance};{order.OrderPrice};{order.OriginSide};{order.OrderType};{order.OrderState};{order.IsCancelled};{order.LocalTime}";
 }
예제 #21
0
        /// <summary>
        /// To convert the tick trade.
        /// </summary>
        /// <param name="tick">Tick trade.</param>
        /// <returns>Stream <see cref="ExecutionMessage"/>.</returns>
        public IEnumerable <ExecutionMessage> ToExecutionLog(ExecutionMessage tick)
        {
            if (tick == null)
            {
                throw new ArgumentNullException(nameof(tick));
            }

            if (!_priceStepUpdated)
            {
                _securityDefinition.PriceStep = tick.GetTradePrice().GetDecimalInfo().EffectiveScale.GetPriceStep();
                _priceStepUpdated             = true;
            }

            if (!_volumeStepUpdated)
            {
                var tickVolume = tick.TradeVolume;

                if (tickVolume != null)
                {
                    _securityDefinition.VolumeStep = tickVolume.Value.GetDecimalInfo().EffectiveScale.GetPriceStep();
                    _volumeStepUpdated             = true;
                }
            }

            //if (tick.ExecutionType != ExecutionTypes.Tick)
            //	throw new ArgumentOutOfRangeException(nameof(tick), tick.ExecutionType, LocalizedStrings.Str1655);

            //_lastTradeDate = message.LocalTime.Date;

            var retVal = new List <ExecutionMessage>();

            var bestBid = _bids.FirstOrDefault();
            var bestAsk = _asks.FirstOrDefault();

            var tradePrice = tick.GetTradePrice();
            var volume     = tick.TradeVolume ?? 1;
            var time       = tick.LocalTime;

            if (bestBid.Value != null && tradePrice <= bestBid.Key)
            {
                // тик попал в биды, значит была крупная заявка по рынку на продажу,
                // которая возможна исполнила наши заявки

                ProcessMarketOrder(retVal, _bids, tick.ServerTime, tick.LocalTime, Sides.Sell, tradePrice, volume);

                // подтягиваем противоположные котировки и снимаем лишние заявки
                TryCreateOppositeOrder(retVal, _asks, time, tick.ServerTime, tradePrice, volume, Sides.Buy);
            }
            else if (bestAsk.Value != null && tradePrice >= bestAsk.Key)
            {
                // тик попал в аски, значит была крупная заявка по рынку на покупку,
                // которая возможна исполнила наши заявки

                ProcessMarketOrder(retVal, _asks, tick.ServerTime, tick.LocalTime, Sides.Buy, tradePrice, volume);

                TryCreateOppositeOrder(retVal, _bids, time, tick.ServerTime, tradePrice, volume, Sides.Sell);
            }
            else if (bestBid.Value != null && bestAsk.Value != null && bestBid.Key < tradePrice && tradePrice < bestAsk.Key)
            {
                // тик попал в спред, значит в спреде до сделки была заявка.
                // создаем две лимитки с разных сторон, но одинаковой ценой.
                // если в эмуляторе есть наша заявка на этом уровне, то она исполниться.
                // если нет, то эмулятор взаимно исполнит эти заявки друг об друга

                var originSide = GetOrderSide(tick);

                retVal.Add(CreateMessage(time, tick.ServerTime, originSide, tradePrice, volume + (_securityDefinition.VolumeStep ?? 1 * _settings.VolumeMultiplier), tif: TimeInForce.MatchOrCancel));

                var spreadStep = _settings.SpreadSize * GetPriceStep();

                // try to fill depth gaps

                var newBestPrice = tradePrice + spreadStep;

                var depth = _settings.MaxDepth;
                while (--depth > 0)
                {
                    var diff = bestAsk.Key - newBestPrice;

                    if (diff > 0)
                    {
                        retVal.Add(CreateMessage(time, tick.ServerTime, Sides.Sell, newBestPrice, 0));
                        newBestPrice += spreadStep * _priceRandom.Next(1, _settings.SpreadSize);
                    }
                    else
                    {
                        break;
                    }
                }

                newBestPrice = tradePrice - spreadStep;

                depth = _settings.MaxDepth;
                while (--depth > 0)
                {
                    var diff = newBestPrice - bestBid.Key;

                    if (diff > 0)
                    {
                        retVal.Add(CreateMessage(time, tick.ServerTime, Sides.Buy, newBestPrice, 0));
                        newBestPrice -= spreadStep * _priceRandom.Next(1, _settings.SpreadSize);
                    }
                    else
                    {
                        break;
                    }
                }

                retVal.Add(CreateMessage(time, tick.ServerTime, originSide.Invert(), tradePrice, volume, tif: TimeInForce.MatchOrCancel));
            }
            else
            {
                // если у нас стакан был полу пустой, то тик формирует некий ценовой уровень в стакана,
                // так как прошедщая заявка должна была обо что-то удариться. допускаем, что после
                // прохождения сделки на этом ценовом уровне остался объем равный тиковой сделки

                var hasOpposite = true;

                Sides originSide;

                // определяем направление псевдо-ранее существовавшей заявки, из которой получился тик
                if (bestBid.Value != null)
                {
                    originSide = Sides.Sell;
                }
                else if (bestAsk.Value != null)
                {
                    originSide = Sides.Buy;
                }
                else
                {
                    originSide  = GetOrderSide(tick);
                    hasOpposite = false;
                }

                retVal.Add(CreateMessage(time, tick.ServerTime, originSide, tradePrice, volume));

                // если стакан был полностью пустой, то формируем сразу уровень с противоположной стороны
                if (!hasOpposite)
                {
                    var oppositePrice = tradePrice + _settings.SpreadSize * GetPriceStep() * (originSide == Sides.Buy ? 1 : -1);

                    if (oppositePrice > 0)
                    {
                        retVal.Add(CreateMessage(time, tick.ServerTime, originSide.Invert(), oppositePrice, volume));
                    }
                }
            }

            if (!HasDepth(time))
            {
                // если стакан слишком разросся, то удаляем его хвосты (не удаляя пользовательские заявки)
                CancelWorstQuote(retVal, time, tick.ServerTime, Sides.Buy, _bids);
                CancelWorstQuote(retVal, time, tick.ServerTime, Sides.Sell, _asks);
            }

            _prevTickPrice = tradePrice;

            return(retVal);
        }
예제 #22
0
        //public static int GetPermId(this MyTrade trade)
        //{
        //	return trade.GetValue<int>(_permId);
        //}

        internal static void SetPermId(this ExecutionMessage trade, int permId)
        {
            trade.AddValue(_permId, permId);
        }
예제 #23
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);
            }
예제 #24
0
 internal static void SetCumulativeQuantity(this ExecutionMessage trade, int cummVolume)
 {
     trade.AddValue(_cumulativeQuantity, cummVolume);
 }
예제 #25
0
 protected override void WriterFixOrderCondition(IFixWriter writer, ExecutionMessage message)
 {
     writer.WriteOrderCondition((QuikOrderCondition)message.Condition);
 }
예제 #26
0
 internal static void SetAveragePrice(this ExecutionMessage trade, decimal price)
 {
     trade.AddValue(_averagePrice, price);
 }
        private void OnOrdersResponse(OrdersResponse response)
        {
            foreach (var order in response.Orders.Cast <TransaqBaseOrder>().Concat(response.StopOrders))
            {
                var stockSharpTransactionId = _orders.TryGetValue(order.TransactionId);

                if (stockSharpTransactionId == 0)
                {
                    stockSharpTransactionId = order.TransactionId;

                    // если заявка пришла от терминала, то просто идентификатор транзакции ассоциируем как стокшарповский
                    _orders.Add(order.TransactionId, order.TransactionId);

                    _ordersTypes.Add(order.TransactionId, order is TransaqStopOrder ? OrderTypes.Conditional : OrderTypes.Limit);
                }

                var execMsg = new ExecutionMessage
                {
                    SecurityId = new SecurityId {
                        Native = order.SecId
                    },
                    Side = order.BuySell.FromTransaq(),
                    OriginalTransactionId = stockSharpTransactionId,
                    PortfolioName         = order.Client,
                    ExpiryDate            = order.ExpDate == null ? (DateTimeOffset?)null : order.ExpDate.Value.ApplyTimeZone(TimeHelper.Moscow),
                    ExecutionType         = ExecutionTypes.Order,
                };

                var usualOrder = order as TransaqOrder;

                if (usualOrder != null)
                {
                    execMsg.OrderId       = usualOrder.OrderNo;
                    execMsg.Balance       = usualOrder.Balance;
                    execMsg.ServerTime    = usualOrder.WithdrawTime ?? usualOrder.Time ?? usualOrder.AcceptTime ?? DateTimeOffset.MinValue;
                    execMsg.Comment       = usualOrder.BrokerRef;
                    execMsg.SystemComment = usualOrder.Result;
                    execMsg.Price         = usualOrder.Price;
                    execMsg.Volume        = usualOrder.Quantity;
                    execMsg.OrderType     = usualOrder.Price == 0 ? OrderTypes.Market : OrderTypes.Limit;
                    execMsg.Commission    = usualOrder.MaxCommission;

                    if (usualOrder.ConditionType != TransaqAlgoOrderConditionTypes.None)
                    {
                        execMsg.OrderType = OrderTypes.Conditional;

                        execMsg.Condition = new TransaqOrderCondition
                        {
                            AlgoType  = usualOrder.ConditionType,
                            AlgoValue = usualOrder.ConditionValue.To <decimal>(),

                            AlgoValidAfter  = usualOrder.ValidAfter,
                            AlgoValidBefore = usualOrder.ValidBefore,
                        };
                    }
                }
                else
                {
                    var stopOrder = (TransaqStopOrder)order;

                    execMsg.OrderId    = stopOrder.ActiveOrderNo;
                    execMsg.OrderType  = OrderTypes.Conditional;
                    execMsg.ServerTime = stopOrder.AcceptTime == null
                                                ? DateTimeOffset.MinValue
                                                : stopOrder.AcceptTime.Value.ApplyTimeZone(TimeHelper.Moscow);

                    var stopCond = new TransaqOrderCondition
                    {
                        Type          = stopOrder.StopLoss != null && stopOrder.TakeProfit != null ? TransaqOrderConditionTypes.TakeProfitStopLoss : (stopOrder.StopLoss != null ? TransaqOrderConditionTypes.StopLoss : TransaqOrderConditionTypes.TakeProfit),
                        ValidFor      = stopOrder.ValidBefore,
                        LinkedOrderId = stopOrder.LinkedOrderNo,
                    };

                    if (stopOrder.StopLoss != null)
                    {
                        stopCond.StopLossActivationPrice = stopOrder.StopLoss.ActivationPrice;
                        stopCond.StopLossOrderPrice      = stopOrder.StopLoss.OrderPrice;
                        stopCond.StopLossByMarket        = stopOrder.StopLoss.OrderPrice == null;
                        stopCond.StopLossVolume          = stopOrder.StopLoss.Quantity;
                        //stopCond.StopLossUseCredit = stopOrder.StopLoss.UseCredit.To<bool>();

                        if (stopOrder.StopLoss.GuardTime != null)
                        {
                            stopCond.StopLossProtectionTime = (int)stopOrder.StopLoss.GuardTime.Value.TimeOfDay.TotalMinutes;
                        }

                        stopCond.StopLossComment = stopOrder.StopLoss.BrokerRef;
                    }

                    if (stopOrder.TakeProfit != null)
                    {
                        stopCond.TakeProfitActivationPrice = stopOrder.TakeProfit.ActivationPrice;
                        stopCond.TakeProfitByMarket        = stopOrder.TakeProfit.GuardSpread == null;
                        stopCond.TakeProfitVolume          = stopOrder.TakeProfit.Quantity;
                        //stopCond.TakeProfitUseCredit = stopOrder.TakeProfit.UseCredit.To<bool>();

                        if (stopOrder.TakeProfit.GuardTime != null)
                        {
                            stopCond.TakeProfitProtectionTime = (int)stopOrder.TakeProfit.GuardTime.Value.TimeOfDay.TotalMinutes;
                        }

                        stopCond.TakeProfitComment          = stopOrder.TakeProfit.BrokerRef;
                        stopCond.TakeProfitCorrection       = stopOrder.TakeProfit.Correction;
                        stopCond.TakeProfitProtectionSpread = stopOrder.TakeProfit.GuardSpread;
                    }
                }

                execMsg.OrderState = order.Status.ToStockSharpState();
                //execMsg.OrderStatus = order2.Status.ToStockSharpStatus();

                if (order.Status != TransaqOrderStatus.cancelled)
                {
                    if (execMsg.OrderState == OrderStates.Failed && usualOrder != null)
                    {
                        execMsg.Error = new InvalidOperationException(usualOrder.Result);
                    }
                }

                SendOutMessage(execMsg);

                //if (order.Condition != null && order.DerivedOrder == null && order2.ConditionType != TransaqAlgoOrderConditionTypes.None && order2.OrderNo != 0)
                //	AddDerivedOrder(security, order2.OrderNo, order, (stopOrder, limitOrder) => stopOrder.DerivedOrder = limitOrder);
            }
        }
예제 #28
0
 internal static void SetOrderRef(this ExecutionMessage trade, string orderRef)
 {
     trade.AddValue(_orderRef, orderRef);
 }
예제 #29
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));
        }
예제 #30
0
 internal static void SetEvRule(this ExecutionMessage trade, string rule)
 {
     trade.AddValue(_evRule, rule);
 }
예제 #31
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);
        }
예제 #32
0
 internal static void SetEvMultiplier(this ExecutionMessage trade, decimal multiplier)
 {
     trade.AddValue(_evMultiplier, multiplier);
 }
		private void ProcessExecutionMessage(ExecutionMessage message)
		{
			if (message.ExecutionType == null)
				throw new ArgumentException(LocalizedStrings.Str688Params.Put(message));

			switch (message.ExecutionType)
			{
				case ExecutionTypes.Transaction:
				{
					if (_entityCache.IsMassCancelation(message.OriginalTransactionId))
					{
						if (message.Error == null)
							RaiseMassOrderCanceled(message.OriginalTransactionId);
						else
							RaiseMassOrderCancelFailed(message.OriginalTransactionId, message.Error);

						break;
					}

					long transactionId;
					var order = _entityCache.GetOrder(message, out transactionId);

					if (order == null)
					{
						var security = LookupSecurity(message.SecurityId);
						ProcessTransactionMessage(null, security, message, transactionId);
					}
					else
					{
						ProcessTransactionMessage(order, order.Security, message, transactionId);
					}

					break;
				}

				case ExecutionTypes.Tick:
				case ExecutionTypes.OrderLog:
				//case null:
				{
					var security = LookupSecurity(message.SecurityId);

					switch (message.ExecutionType)
					{
						case ExecutionTypes.Tick:
							ProcessTradeMessage(security, message);
							break;
						case ExecutionTypes.OrderLog:
							ProcessOrderLogMessage(security, message);
							break;
					}

					if (CreateAssociatedSecurity && !IsAssociated(message.SecurityId.BoardCode))
					{
						var clone = (ExecutionMessage)message.Clone();
						clone.SecurityId = CreateAssociatedId(clone.SecurityId);
						ProcessExecutionMessage(clone);
					}

					break;
				}
				
				default:
					throw new ArgumentOutOfRangeException(LocalizedStrings.Str1695Params.Put(message.ExecutionType));
			}
		}
예제 #34
0
 internal static void SetLastTradePrice(this ExecutionMessage order, decimal price)
 {
     order.AddValue(_lastTradePrice, price);
 }
예제 #35
0
 void IDisposable.Dispose()
 {
     Current = null;
     _itemsEnumerator.Dispose();
 }
예제 #36
0
 internal static void SetWhyHeld(this ExecutionMessage order, string whyHeld)
 {
     order.AddValue(_whyHeld, whyHeld);
 }