Пример #1
0
        public static IBSocket SendOrderExpiration(this IBSocket socket, OrderRegisterMessage msg)
        {
            if (msg == null)
            {
                throw new ArgumentNullException("msg");
            }

            if (msg.OrderType != OrderTypes.Conditional)
            {
                switch (msg.TimeInForce)
                {
                case TimeInForce.PutInQueue:
                {
                    if (msg.TillDate == DateTimeOffset.MaxValue)
                    {
                        return(socket.Send("GTC"));
                    }
                    else if (msg.TillDate != DateTimeOffset.Now.Date)
                    {
                        return(socket.Send("GTD"));
                    }
                    else
                    {
                        return(socket.Send("DAY"));
                    }
                }

                case TimeInForce.MatchOrCancel:
                    return(socket.Send("FOK"));

                case TimeInForce.CancelBalance:
                    return(socket.Send("IOC"));

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            else if (msg.OrderType == OrderTypes.Conditional)
            {
                var ibCon = (IBOrderCondition)msg.Condition;

                return(socket.Send(ibCon.IsMarketOnOpen ? "OPG" : "DAY"));
            }
            else
            {
                throw new ArgumentException(LocalizedStrings.Str2501Params.Put(msg.Type), "msg");
            }
        }
Пример #2
0
            static void RemoteTrailingZeros(OrderRegisterMessage regMsg)
            {
                if (regMsg.Price != default)
                {
                    regMsg.Price = regMsg.Price.RemoveTrailingZeros();
                }

                if (regMsg.Volume != default)
                {
                    regMsg.Volume = regMsg.Volume.RemoveTrailingZeros();
                }

                if (regMsg.VisibleVolume != default)
                {
                    regMsg.VisibleVolume = regMsg.VisibleVolume?.RemoveTrailingZeros();
                }
            }
        private void ProcessOrderRegister(OrderRegisterMessage regMsg)
        {
            var order = _httpClient.RegisterOrder(regMsg.Side, regMsg.Price, regMsg.Volume);

            _orderInfo.Add(order.Id, RefTuple.Create(regMsg.TransactionId, regMsg.Volume));

            _hasActiveOrders = true;

            SendOutMessage(new ExecutionMessage
            {
                ExecutionType         = ExecutionTypes.Transaction,
                OrderId               = order.Id,
                ServerTime            = order.Time.ApplyTimeZone(TimeZoneInfo.Utc),
                OriginalTransactionId = regMsg.TransactionId,
                OrderState            = OrderStates.Active,
            });
        }
Пример #4
0
        public static SmartOrderType GetSmartOrderType(this OrderRegisterMessage order)
        {
            if (order == null)
            {
                throw new ArgumentNullException(nameof(order));
            }

            switch (order.OrderType)
            {
            case OrderTypes.Limit:
                return(SmartOrderType.Limit);

            case OrderTypes.Market:
                return(SmartOrderType.Market);

            case OrderTypes.Conditional:
                return(order.Price != 0 ? SmartOrderType.StopLimit : SmartOrderType.Stop);

            default:
                throw new ArgumentOutOfRangeException(nameof(order));
            }
        }
Пример #5
0
        private bool NeedCheckVolume(OrderRegisterMessage message, decimal quotesVolume)
        {
            if (!_settings.IncreaseDepthVolume)
            {
                return(false);
            }

            var orderSide = message.Side;
            var price     = message.Price;

            var quotes = orderSide == Sides.Buy ? _asks : _bids;

            var quote = quotes.FirstOrDefault();

            if (quote.Value == null)
            {
                return(false);
            }

            var bestPrice = quote.Key;

            return((orderSide == Sides.Buy ? price >= bestPrice : price <= bestPrice) &&
                   quotesVolume <= message.Volume);
        }
        private void ProcessOrderRegister(OrderRegisterMessage regMsg)
        {
            var reply = Session.MakeOrder(
                regMsg.SecurityId.SecurityCode.Replace('/', '_').ToLowerInvariant(),
                regMsg.Side.ToBtce(),
                regMsg.Price,
                regMsg.Volume
                );

            _orderInfo.Add(reply.Command.OrderId, RefTuple.Create(regMsg.TransactionId, regMsg.Volume));

            SendOutMessage(new ExecutionMessage
            {
                OriginalTransactionId = regMsg.TransactionId,
                OrderId       = reply.Command.OrderId,
                Balance       = (decimal)reply.Command.Remains,
                OrderState    = OrderStates.Active,
                ExecutionType = ExecutionTypes.Order
            });

            ProcessFunds(reply.Command.Funds);

            _hasActiveOrders = true;
        }
Пример #7
0
        public static Transaction CreateRegisterTransaction(this IMessageSessionHolder sessionHolder, OrderRegisterMessage message, string orderAccount)
        {
            if (sessionHolder == null)
            {
                throw new ArgumentNullException("sessionHolder");
            }

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

            var board           = ExchangeBoard.GetOrCreateBoard(message.SecurityId.BoardCode);
            var needDepoAccount = board.IsMicex || board.IsUxStock;

            if (needDepoAccount)
            {
                if (orderAccount.IsEmpty())
                {
                    throw new ArgumentException(LocalizedStrings.Str1848Params.Put(message.PortfolioName));
                }
            }
            else
            {
                orderAccount = message.PortfolioName;
            }

            var transaction = new Transaction(TransactionTypes.Register, message);

            transaction
            .SetAccount(orderAccount)
            .SetSecurity(sessionHolder, message)
            .SetVolume((int)message.Volume);

            //20-ти символьное составное поле, может содержать код клиента и текстовый комментарий с тем же разделителем, что и при вводе заявки вручную.
            //для ртс код клиента не обязателен
            var clientCode = needDepoAccount ? message.PortfolioName : string.Empty;

            if (!message.Comment.IsEmpty())
            {
                // http://www.quik.ru/forum/import/24383
                var splitter = message.PortfolioName.Contains("/") ? "//" : "/";
                clientCode = clientCode.IsEmpty() ? message.Comment : "{0}{1}{2}".Put(clientCode, splitter, message.Comment);

                if (clientCode.Length > 20)
                {
                    clientCode = clientCode.Remove(20);
                }
            }

            if (!clientCode.IsEmpty())
            {
                transaction.SetClientCode(clientCode);
            }

            transaction.SetExpiryDate(message.TillDate);

            if (message.VisibleVolume != null && message.VisibleVolume != message.Volume)
            {
                return(transaction
                       .SetAction(TransactionActions.Iceberg)
                       .SetVisibleVolume((int)message.VisibleVolume)

                       .SetInstruction("Цена", transaction.GetInstruction(Transaction.Price))
                       .SetInstruction("К/П", message.Side == Sides.Buy ? "Купля" : "Продажа")
                       .SetInstruction("Тип", "Лимитная")
                       .SetInstruction("Тип по цене", "по разным ценам")
                       .SetInstruction("Тип по остатку", "поставить в очередь")
                       .SetInstruction("Тип ввода значения цены", "По цене")

                       .SetInstruction("Торговый счет", transaction.GetInstruction(Transaction.Account))
                       .RemoveInstruction(Transaction.Account)

                       .SetInstruction("Инструмент", transaction.GetInstruction(Transaction.SecurityCode))
                       .RemoveInstruction(Transaction.SecurityCode)

                       .SetInstruction("Лоты", transaction.GetInstruction(Transaction.Volume))
                       .RemoveInstruction(Transaction.Volume)

                       .SetInstruction("Примечание", transaction.GetInstruction(Transaction.ClientCode))
                       .RemoveInstruction(Transaction.ClientCode));
            }

            switch (message.OrderType)
            {
            case OrderTypes.Market:
            case OrderTypes.Limit:
                transaction
                .SetSide(message.Side)
                .SetType(message.OrderType)
                .SetAction(TransactionActions.NewOrder)
                .SetPrice(message.Price);

                var tif = message.TimeInForce ?? TimeInForce.PutInQueue;

                if (!(message.SecurityId.SecurityType == SecurityTypes.Future && tif == TimeInForce.PutInQueue))
                {
                    transaction.SetTimeInForce(tif);
                }

                break;

            case OrderTypes.Conditional:
            {
                var condition = (QuikOrderCondition)message.Condition;

                if (condition.ConditionOrderId != null && condition.ConditionOrderSide != null)
                {
                    message.Side = condition.ConditionOrderSide.Value.Invert();
                }

                transaction
                .SetSide(message.Side)
                .SetAction(TransactionActions.NewStopOrder)
                .SetStopPrice(condition.StopPrice ?? 0);

                if (message.Price != 0)
                {
                    transaction.SetPrice(message.Price);
                }

                string stopOrderKind;
                string stopPriceCondition;

                switch (condition.Type)
                {
                case QuikOrderConditionTypes.LinkedOrder:
                    stopOrderKind = TransactionStopOrderKinds.WithLinkedLimitOrder;
                    transaction
                    .SetLinkedOrderPrice(condition.LinkedOrderPrice ?? 0)
                    .SetLinkedOrderCancel(condition.LinkedOrderCancel ?? false);

                    stopPriceCondition = message.Side == Sides.Buy ? ">=" : "<=";
                    break;

                case QuikOrderConditionTypes.OtherSecurity:
                    var otherSec = condition.OtherSecurityId;

                    if (otherSec == null)
                    {
                        throw new ArgumentException();
                    }

                    stopOrderKind = TransactionStopOrderKinds.ConditionPriceByOtherSecurity;
                    transaction.SetOtherSecurity(sessionHolder, (SecurityId)otherSec);

                    stopPriceCondition = condition.StopPriceCondition == QuikStopPriceConditions.MoreOrEqual ? ">=" : "<=";
                    break;

                case QuikOrderConditionTypes.StopLimit:
                    stopPriceCondition = null;
                    stopOrderKind      = null;
                    break;

                case QuikOrderConditionTypes.TakeProfit:
                    stopPriceCondition = null;
                    stopOrderKind      = TransactionStopOrderKinds.TakeProfit;
                    break;

                case QuikOrderConditionTypes.TakeProfitStopLimit:
                    stopPriceCondition = null;
                    stopOrderKind      = TransactionStopOrderKinds.TakeProfitAndStopLimit;

                    if (condition.ActiveTime != null)
                    {
                        transaction
                        .SetIsActiveInTime(true)
                        .SetActiveFrom(condition.ActiveTime.Min.UtcDateTime)
                        .SetActiveTo(condition.ActiveTime.Max.UtcDateTime);
                    }
                    else
                    {
                        // http://stocksharp.com/forum/yaf_postsm25524_Nie-rabotaiet-razmieshchieniie-ordierov-po-ispolnieniiu.aspx
                        // IS_ACTIVE_IN_TIME	Признак действия заявки типа «Тэйк-профит и стоп-лимит»
                        if (condition.ConditionOrderId == null)
                        {
                            transaction.SetIsActiveInTime(false);
                        }
                    }

                    if (condition.IsMarketTakeProfit != null)
                    {
                        transaction.SetMarketTakeProfit((bool)condition.IsMarketTakeProfit);
                    }

                    if (condition.IsMarketStopLimit != null)
                    {
                        transaction.SetMarketStopLimit((bool)condition.IsMarketStopLimit);
                    }

                    if (condition.StopLimitPrice != null)
                    {
                        transaction.SetStopLimitPrice((decimal)condition.StopLimitPrice);
                    }

                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                if (condition.ConditionOrderId != null)
                {
                    if (stopOrderKind.IsEmpty())
                    {
                        stopOrderKind = TransactionStopOrderKinds.SimpleStopLimit;
                    }

                    stopOrderKind = TransactionStopOrderKinds.ActivatedByOrder + stopOrderKind;

                    transaction
                    .SetConditionOrderId((long)condition.ConditionOrderId)
                    .SetConditionOrderUseMatchedBalance(condition.ConditionOrderUseMatchedBalance ?? false)
                    .SetConditionOrderPartiallyMatched(condition.ConditionOrderPartiallyMatched ?? false);
                }

                if (condition.Type == QuikOrderConditionTypes.TakeProfit || condition.Type == QuikOrderConditionTypes.TakeProfitStopLimit)
                {
                    if (condition.Offset != null)
                    {
                        transaction.SetOffset(condition.Offset);
                    }

                    if (condition.Spread != null)
                    {
                        transaction.SetSpread(condition.Spread);
                    }
                }

                if (!stopOrderKind.IsEmpty())
                {
                    transaction.SetStopOrderKind(stopOrderKind);
                }

                if (!stopPriceCondition.IsEmpty())
                {
                    transaction.SetStopPriceCondition(stopPriceCondition);
                }

                break;
            }

            case OrderTypes.Repo:
            {
                var orderInfo = message.RepoInfo;

                transaction
                .SetAction(TransactionActions.NewRepoNegDeal)
                .SetSide(message.Side)
                .SetPrice(message.Price);

                if (orderInfo.BlockSecurities != null)
                {
                    transaction.SetBlockSecurities((bool)orderInfo.BlockSecurities);
                }

                if (orderInfo.Partner != null)
                {
                    transaction.SetPartner(orderInfo.Partner);
                }

                if (orderInfo.MatchRef != null)
                {
                    transaction.SetMatchRef(orderInfo.MatchRef);
                }

                if (orderInfo.RefundRate != null)
                {
                    transaction.SetRefundRate((int)orderInfo.RefundRate);
                }

                if (orderInfo.Rate != null)
                {
                    transaction.SetRepoRate((int)orderInfo.Rate);
                }

                if (orderInfo.Value != null)
                {
                    transaction.SetRepoValue((decimal)orderInfo.Value);
                }

                if (orderInfo.Term != null)
                {
                    transaction.SetRepoTerm((int)orderInfo.Term);
                }

                if (orderInfo.SecondPrice != null)
                {
                    transaction.SetSecondPrice((decimal)orderInfo.SecondPrice);
                }

                if (orderInfo.SettleCode != null)
                {
                    transaction.SetSettleCode(orderInfo.SettleCode);
                }

                if (orderInfo.SettleDate != null)
                {
                    transaction.SetSettleDate(orderInfo.SettleDate.Value.ToLocalTime(TimeHelper.Moscow));
                }

                if (orderInfo.LowerDiscount != null)
                {
                    transaction.SetLowerDiscount((int)orderInfo.LowerDiscount);
                }

                if (orderInfo.StartDiscount != null)
                {
                    transaction.SetStartDiscount((int)orderInfo.StartDiscount);
                }

                if (orderInfo.UpperDiscount != null)
                {
                    transaction.SetUpperDiscount((int)orderInfo.UpperDiscount);
                }

                break;
            }

            case OrderTypes.Rps:
            {
                var orderInfo = message.RpsInfo;

                transaction
                .SetAction(TransactionActions.NewNegDeal)
                .SetSide(message.Side)
                .SetPrice(message.Price);

                if (orderInfo.Partner != null)
                {
                    transaction.SetPartner(orderInfo.Partner);
                }

                if (orderInfo.MatchRef != null)
                {
                    transaction.SetMatchRef(orderInfo.MatchRef);
                }

                if (orderInfo.SettleCode != null)
                {
                    transaction.SetSettleCode(orderInfo.SettleCode);
                }

                if (orderInfo.SettleDate != null)
                {
                    transaction.SetSettleDate(orderInfo.SettleDate.Value.ToLocalTime(TimeHelper.Moscow));
                }

                if (orderInfo.ForAccount != null)
                {
                    transaction.SetForAccount(orderInfo.ForAccount);
                }

                transaction.SetCurrencyCode(orderInfo.CurrencyType.ToMicexCurrencyName());

                break;
            }

            default:
                throw new NotSupportedException(LocalizedStrings.Str1849Params.Put(message.Type));
            }

            return(transaction);
        }
        private void ProcessRegisterMessage(OrderRegisterMessage regMsg)
        {
            DateTime?expDate;

            if (regMsg.TillDate == null || regMsg.TillDate == DateTimeOffset.MaxValue)
            {
                expDate = null;
            }
            else
            {
                expDate = regMsg.TillDate.Value.ToLocalTime(TimeHelper.Moscow);
            }

            BaseCommandMessage command;

            switch (regMsg.OrderType)
            {
            case OrderTypes.Limit:
            case OrderTypes.Market:
            {
                command = new NewOrderMessage
                {
                    ByMarket  = regMsg.OrderType == OrderTypes.Market,
                    Client    = regMsg.PortfolioName,
                    Quantity  = regMsg.Volume.To <int>(),
                    Unfilled  = regMsg.TimeInForce.ToTransaq(),
                    BuySell   = regMsg.Side.ToTransaq(),
                    Price     = regMsg.Price,
                    SecId     = (int)regMsg.SecurityId.Native,
                    ExpDate   = expDate,
                    BrokerRef = regMsg.Comment,
                    Hidden    = (int)(regMsg.Volume - (regMsg.VisibleVolume ?? regMsg.Volume)),
                };

                break;
            }

            case OrderTypes.Conditional:
            {
                var cond = (TransaqOrderCondition)regMsg.Condition;

                if (cond.Type == TransaqOrderConditionTypes.Algo)
                {
                    command = new NewCondOrderMessage
                    {
                        ByMarket        = regMsg.OrderType == OrderTypes.Market,
                        Client          = regMsg.PortfolioName,
                        Quantity        = regMsg.Volume.To <int>(),
                        BuySell         = regMsg.Side.ToTransaq(),
                        Price           = regMsg.Price,
                        SecId           = (int)regMsg.SecurityId.Native,
                        CondType        = cond.AlgoType ?? TransaqAlgoOrderConditionTypes.None,
                        CondValue       = cond.AlgoValue ?? 0m,
                        ValidAfterType  = cond.AlgoValidAfterType ?? TransaqAlgoOrderValidTypes.TillCancelled,
                        ValidAfter      = cond.AlgoValidAfter,
                        ValidBeforeType = cond.AlgoValidBeforeType ?? TransaqAlgoOrderValidTypes.TillCancelled,
                        ValidBefore     = cond.AlgoValidBefore,
                        ExpDate         = expDate,
                        BrokerRef       = regMsg.Comment,
                        Hidden          = (int)(regMsg.Volume - (regMsg.VisibleVolume ?? regMsg.Volume)),
                    };
                }
                else                        // if (regMsg.Condition is TransaqOrderCondition)
                {
                    if (!cond.CheckConditionUnitType())
                    {
                        throw new InvalidOperationException(LocalizedStrings.Str3549);
                    }

                    var stopOrder = new NewStopOrderMessage
                    {
                        SecId         = (int)regMsg.SecurityId.Native,
                        Client        = regMsg.PortfolioName,
                        BuySell       = regMsg.Side.ToTransaq(),
                        LinkedOrderNo = cond.LinkedOrderId.To <string>(),
                        ExpDate       = expDate,
                        ValidFor      = expDate,
                    };

                    switch (cond.Type)
                    {
                    case TransaqOrderConditionTypes.StopLoss:
                        stopOrder.StopLoss = TransaqHelper.CreateStopLoss(cond);
                        break;

                    case TransaqOrderConditionTypes.TakeProfit:
                        stopOrder.TakeProfit = TransaqHelper.CreateTakeProfit(cond);
                        break;

                    case TransaqOrderConditionTypes.TakeProfitStopLoss:
                        stopOrder.StopLoss   = TransaqHelper.CreateStopLoss(cond);
                        stopOrder.TakeProfit = TransaqHelper.CreateTakeProfit(cond);
                        break;
                    }

                    command = stopOrder;
                }
                //else
                //	throw new InvalidOperationException(LocalizedStrings.Str3550Params.Put(regMsg.Condition, regMsg.TransactionId));

                break;
            }

            case OrderTypes.Repo:
            {
                command = new NewRepoOrderMessage
                {
                    SecId      = (int)regMsg.SecurityId.Native,
                    Client     = regMsg.PortfolioName,
                    BuySell    = regMsg.Side.ToTransaq(),
                    CpFirmId   = regMsg.RepoInfo.Partner,
                    MatchRef   = regMsg.RepoInfo.MatchRef,
                    BrokerRef  = regMsg.Comment,
                    Price      = regMsg.Price,
                    Quantity   = regMsg.Volume.To <int>(),
                    SettleCode = regMsg.RepoInfo.SettleCode,
                    RefundRate = regMsg.RepoInfo.RefundRate,
                    Rate       = regMsg.RepoInfo.Rate,
                };

                break;
            }

            case OrderTypes.ExtRepo:
            {
                command = new NewMRepoOrderMessage
                {
                    SecId           = (int)regMsg.SecurityId.Native,
                    Client          = regMsg.PortfolioName,
                    BuySell         = regMsg.Side.ToTransaq(),
                    CpFirmId        = regMsg.RepoInfo.Partner,
                    MatchRef        = regMsg.RepoInfo.MatchRef,
                    BrokerRef       = regMsg.Comment,
                    Price           = regMsg.Price,
                    Quantity        = regMsg.Volume.To <int>(),
                    SettleCode      = regMsg.RepoInfo.SettleCode,
                    RefundRate      = regMsg.RepoInfo.RefundRate,
                    Value           = regMsg.RepoInfo.Value,
                    Term            = regMsg.RepoInfo.Term,
                    Rate            = regMsg.RepoInfo.Rate,
                    StartDiscount   = regMsg.RepoInfo.StartDiscount,
                    LowerDiscount   = regMsg.RepoInfo.LowerDiscount,
                    UpperDiscount   = regMsg.RepoInfo.UpperDiscount,
                    BlockSecurities = regMsg.RepoInfo.BlockSecurities,
                };

                break;
            }

            case OrderTypes.Rps:
            {
                command = new NewRpsOrderMessage
                {
                    SecId      = (int)regMsg.SecurityId.Native,
                    Client     = regMsg.PortfolioName,
                    BuySell    = regMsg.Side.ToTransaq(),
                    CpFirmId   = regMsg.RpsInfo.Partner,
                    MatchRef   = regMsg.RpsInfo.MatchRef,
                    BrokerRef  = regMsg.Comment,
                    Price      = regMsg.Price,
                    Quantity   = regMsg.Volume.To <int>(),
                    SettleCode = regMsg.RpsInfo.SettleCode,
                };

                break;
            }

            case OrderTypes.Execute:
            {
                //command = new NewReportMessage
                //{
                //	BuySell = regMsg.Side.ToTransaq(),
                //};
                //break;
                throw new NotImplementedException();
            }

            default:
                throw new ArgumentOutOfRangeException();
            }

            var result = SendCommand(command);

            _orders.Add(result.TransactionId, regMsg.TransactionId);
            _ordersTypes.Add(regMsg.TransactionId, command is NewCondOrderMessage ? OrderTypes.Limit : regMsg.OrderType);
        }
Пример #9
0
        private void ProcessOrderRegister(OrderRegisterMessage message)
        {
            var draft = _client.CreateDraft();

            draft.Comments = message.Comment;
            draft.Account  = _client.Accounts[message.PortfolioName];
            draft.Contract = _client.Contracts[message.SecurityId.SecurityCode];
            draft.Route    = _client.Routes[message.SecurityId.BoardCode];
            draft.Side     = message.Side.ToOec();
            draft.Quantity = (int)message.Volume;

            draft.ClearExtData();
            draft.Price  = (double)message.Price;
            draft.Price2 = 0;

            if (message.OrderType == OrderTypes.Conditional)
            {
                var cond      = (OpenECryOrderCondition)message.Condition;
                var stopPrice = (double)(cond.StopPrice ?? 0);

                switch (cond.AssetType)
                {
                case OpenECryOrderCondition.AssetTypeEnum.All:
                    switch (cond.StopType)
                    {
                    case OpenECryStopType.StopLimit:
                        draft.Type   = OrderType.StopLimit;
                        draft.Price2 = draft.Price;
                        draft.Price  = stopPrice;
                        break;

                    case OpenECryStopType.StopMarket:
                        draft.Type   = OrderType.Stop;
                        draft.Price  = stopPrice;
                        draft.Price2 = 0;
                        break;

                    default:
                        throw new ArgumentException(LocalizedStrings.Str2553Params.Put(cond.StopType));
                    }
                    break;

                case OpenECryOrderCondition.AssetTypeEnum.Equity:
                case OpenECryOrderCondition.AssetTypeEnum.Future:

                    //if (!draft.Contract.IsEquityAsset && !draft.Contract.IsFuture)
                    //	throw new NotSupportedException(LocalizedStrings.Str2554);

                    switch (cond.StopType)
                    {
                    case OpenECryStopType.TrailingStopLimit:
                        draft.Type   = OrderType.TrailingStopLimit;
                        draft.Price2 = draft.Price;
                        draft.Price  = stopPrice;
                        break;

                    case OpenECryStopType.TrailingStopMarket:
                        draft.Type   = OrderType.TrailingStopLoss;
                        draft.Price  = stopPrice;
                        draft.Price2 = 0;
                        break;

                    default:
                        throw new ArgumentException(LocalizedStrings.Str2553Params.Put(cond.StopType));
                    }

                    if (cond.AssetType == OpenECryOrderCondition.AssetTypeEnum.Equity)
                    {
                        draft.SetEquityTSData((double)(cond.Delta ?? 0), cond.IsPercentDelta ?? false, cond.TriggerType.ToOec());
                    }
                    else
                    {
                        draft.SetTSData((double)(cond.ReferencePrice ?? 0), (double)(cond.Delta ?? 0));
                    }

                    break;

                default:
                    throw new ArgumentException(LocalizedStrings.Str2555Params.Put(cond.AssetType));
                }
            }
            else
            {
                draft.Type = message.OrderType.ToOec();
            }

            draft.Flags = OrderFlags.None;
            draft.Start = OEC.API.Version.MinimumStart;
            draft.End   = OEC.API.Version.MaximumEnd;

            switch (message.TimeInForce)
            {
            case null:
            case TimeInForce.PutInQueue:
            {
                draft.Flags = OrderFlags.GTC;

                if (message.ExpiryDate != null && message.ExpiryDate.Value.DateTime != DateTime.Today)
                {
                    draft.End = message.ExpiryDate.Value.UtcDateTime;
                }

                break;
            }

            case TimeInForce.MatchOrCancel:
                draft.Flags = OrderFlags.FOK;
                break;

            case TimeInForce.CancelBalance:
                draft.Flags = OrderFlags.IOC;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (message.VisibleVolume != null && message.VisibleVolume < message.Volume)
            {
                draft.SetIcebergData((int)message.VisibleVolume.Value);
            }

            var invalid = draft.GetInvalidParts();

            if (invalid != OrderParts.None)
            {
                throw new OpenECryException(LocalizedStrings.Str2556Params.Put(invalid));
            }

            var newOrder = _client.SendOrder(draft);

            _orderTransactions.Add(newOrder, message.TransactionId);
            ProcessOrder(newOrder, message.TransactionId);
        }
Пример #10
0
        /// <inheritdoc />
        public string ValidateRegistration(OrderRegisterMessage regMsg)
        {
            var info = GetPosition(regMsg.SecurityId);

            if (CheckMoney)
            {
                // если задан баланс, то проверям по нему (для частично исполненных заявок)
                var volume = (regMsg as OrderReplaceMessage)?.OldOrderVolume ?? regMsg.Volume;

                var needBlock = info.GetPrice(regMsg.Side == Sides.Buy ? volume : 0, regMsg.Side == Sides.Sell ? volume : 0);

                if (_currentMoney < needBlock)
                {
                    return(LocalizedStrings
                           .Str1169Params
                           .Put(regMsg.PortfolioName, regMsg.TransactionId, needBlock, _currentMoney, info.TotalPrice));
                }
            }

            if (CheckShortable && regMsg.Side == Sides.Sell)
            {
                var secDef = _getSecurityDefinition(regMsg.SecurityId);

                if (secDef?.Shortable == false)
                {
                    if (info.PositionCurrentValue < regMsg.Volume)
                    {
                        return(LocalizedStrings
                               .CannotShortPosition
                               .Put(regMsg.PortfolioName, regMsg.TransactionId, info.PositionCurrentValue, regMsg.Volume));
                    }
                }
            }

            switch (regMsg.PositionEffect)
            {
            case OrderPositionEffects.OpenOnly:
            {
                if (info.PositionCurrentValue != 0)
                {
                    return(LocalizedStrings.PositionCanBeActionOnly.Put(regMsg.SecurityId, LocalizedStrings.OpenOnly, regMsg.TransactionId));
                }

                break;
            }

            case OrderPositionEffects.CloseOnly:
            {
                if (info.PositionCurrentValue == 0 ||
                    (info.PositionCurrentValue > 0 && (regMsg.Side == Sides.Buy || info.PositionCurrentValue < regMsg.Volume)) ||
                    (info.PositionCurrentValue < 0 && (regMsg.Side == Sides.Sell || info.PositionCurrentValue.Abs() < regMsg.Volume)))
                {
                    return(LocalizedStrings.PositionCanBeActionOnly.Put(regMsg.SecurityId, LocalizedStrings.CloseOnly, regMsg.TransactionId));
                }

                break;
            }
            }

            return(null);
        }
Пример #11
0
        private void ProcessOrderRegisterMessage(OrderRegisterMessage message)
        {
            var condition = (OandaOrderCondition)message.Condition;

            string type;

            if (condition == null)
            {
                type = message.Price == 0 ? "market" : "limit";
            }
            else
            {
                type = condition.IsMarket ? _orderImit : "stop";
            }

            var response = _restClient.CreateOrder(GetAccountId(message.PortfolioName),
                                                   message.SecurityId.ToOanda(), (int)message.Volume, message.Side.To <string>().ToLowerInvariant(),
                                                   type,
                                                   GetExpiryTime(message),
                                                   message.Price,
                                                   condition == null ? null : condition.LowerBound,
                                                   condition == null ? null : condition.UpperBound,
                                                   condition == null ? null : condition.StopLossOffset,
                                                   condition == null ? null : condition.TakeProfitOffset,
                                                   condition == null ? null : condition.TrailingStopLossOffset);

            var execMsg = new ExecutionMessage
            {
                OriginalTransactionId = message.TransactionId,
                ServerTime            = response.Time.FromOanda(),
                ExecutionType         = ExecutionTypes.Order,
                PortfolioName         = message.PortfolioName,
            };

            var tradeData = response.TradeOpened;

            if (tradeData != null)
            {
                execMsg.OrderState = OrderStates.Done;
                execMsg.OrderId    = tradeData.Id;
            }
            else
            {
                execMsg.OrderState = OrderStates.Active;
                execMsg.OrderId    = response.OrderOpened.Id;
            }

            SendOutMessage(execMsg);

            if (tradeData != null)
            {
                SendOutMessage(new ExecutionMessage
                {
                    OriginalTransactionId = message.TransactionId,
                    ExecutionType         = ExecutionTypes.Trade,
                    TradePrice            = (decimal)tradeData.Price,
                    Volume     = tradeData.Units,
                    ServerTime = tradeData.Time.FromOanda(),
                    TradeId    = tradeData.Id,
                });
            }
        }
Пример #12
0
        private void ProcessRegisterMessage(OrderRegisterMessage regMsg)
        {
            OrderParams orderParams;

            switch (regMsg.OrderType)
            {
            case OrderTypes.Limit:
            {
                orderParams = FillParams(regMsg, new OrderParams
                    {
                        Price     = (double)regMsg.Price,
                        OrderType = Constants.ORDER_TYPE_LIMIT,
                    });
                break;
            }

            case OrderTypes.Market:
            {
                orderParams = FillParams(regMsg, new OrderParams
                    {
                        OrderType = Constants.ORDER_TYPE_MARKET,
                    });
                break;
            }

            case OrderTypes.Conditional:
            {
                var condition = (RithmicOrderCondition)regMsg.Condition;

                var triggerPrice = condition.TriggerPrice;

                if (triggerPrice == null)
                {
                    throw new InvalidOperationException(LocalizedStrings.Str3494Params.Put(regMsg.TransactionId));
                }

                if (regMsg.Price == 0)
                {
                    orderParams = FillParams(regMsg, new OrderParams
                        {
                            TriggerPrice = (double)triggerPrice,
                            OrderType    = Constants.ORDER_TYPE_STOP_MARKET,
                        });
                }
                else
                {
                    orderParams = FillParams(regMsg, new OrderParams
                        {
                            TriggerPrice = (double)triggerPrice,
                            Price        = (double)regMsg.Price,
                            OrderType    = Constants.ORDER_TYPE_STOP_LIMIT,
                        });
                }

                break;
            }

            case OrderTypes.Repo:
            case OrderTypes.ExtRepo:
            case OrderTypes.Rps:
            case OrderTypes.Execute:
                throw new NotSupportedException(LocalizedStrings.Str3495Params.Put(regMsg.TransactionId, regMsg.OrderType));

            default:
                throw new ArgumentOutOfRangeException();
            }

            _client.Session.sendOrderList(new List <OrderParams> {
                orderParams
            }.AsReadOnly());
        }
Пример #13
0
        public int RegisterOrder(OrderRegisterMessage message)
        {
            var marketTime = _ad.SessionTime;

            var secCode   = message.SecurityId.SecurityCode;
            var account   = message.PortfolioName.AccountFromPortfolioName();           // Портфель
            var placeCode = _adapter.SecurityClassInfo.GetSecurityClass(message.SecurityType, message.SecurityId.BoardCode);
            var endDate   = (message.TillDate == null || message.TillDate == DateTimeOffset.MaxValue
                                ? marketTime.Date.AddTicks(new TimeSpan(23, 55, 00).Ticks)
                                : message.TillDate.Value).ToLocalTime(TimeHelper.Moscow); // Срок действия поручения.
            var maxEndDate = DateTime.Now + TimeSpan.FromDays(365);

            if (endDate > maxEndDate)
            {
                endDate = maxEndDate;
            }
            var comments = message.TransactionId.To <string>(); // Комментарий.
            var currency = message.Currency == null || message.Currency == CurrencyTypes.RUB ?
                           "RUR" : message.Currency.ToString(); //_securityCurrencies[message.SecurityId.SecurityCode]; // Валюта цены.
            var buySell  = message.Side.ToAlfaDirect();         // Покупка/Продажа
            var quantity = (int)message.Volume;                 // Количество.
            var price    = message.Price;                       // Цена.

            int id;

            _adapter.AddInfoLog("Register: {0} {1}/{2} tran={3}  {4} {5}@{6}, mtime={7}, cur={8}", account, secCode, placeCode, comments, buySell, quantity, price, marketTime, currency);

            if (placeCode == null)
            {
                throw new InvalidOperationException(LocalizedStrings.Str2274Params.Put(message.TransactionId));
            }

            if (message.OrderType == OrderTypes.Conditional)
            {
                var condition = (AlfaOrderCondition)message.Condition;

                if (condition.TargetPrice != 0)
                {
                    id = _ad.CreateStopOrder(account, placeCode, secCode, endDate, comments, currency, buySell, quantity,
                                             (double)condition.StopPrice, (double)condition.Slippage, condition.TargetPrice, -1);
                }
                else if (condition.Level != 0)
                {
                    id = _ad.CreateTrailingOrder(account, placeCode, secCode, endDate, comments, currency, buySell, quantity,
                                                 (double)condition.StopPrice, (double)condition.Level, (double)condition.Slippage, -1);
                }
                else
                {
                    id = _ad.CreateStopOrder(account, placeCode, secCode, endDate, comments, currency, buySell, quantity,
                                             (double)condition.StopPrice, (double)condition.Slippage, null, -1);
                }
            }
            else
            {
                if (message.OrderType == OrderTypes.Market)
                {
                    throw new InvalidOperationException(LocalizedStrings.Str2275);
                }

                id = _ad.CreateLimitOrder(account, placeCode, secCode, endDate, comments, currency, buySell, quantity,
                                          (double)price, null, null, null, null, null, "Y", null, null, null, null, null, null, null, null, null, null, -1);
            }

            if (id == 0)
            {
                ThrowInError(tagStateCodes.stcClientError, LocalizedStrings.Str2276Params.Put(message.TransactionId, _ad.LastResultMsg));
            }

            return(id);
        }
Пример #14
0
 void ProcessRegOrder(OrderRegisterMessage regMsg)
 => EnsureGetInfo(regMsg, regMsg.Side, regMsg.Volume, regMsg.Volume);
Пример #15
0
 /// <summary>
 /// Записать данные по условию заявки.
 /// </summary>
 /// <param name="writer">Писатель FIX данных.</param>
 /// <param name="regMsg">Сообщение, содержащее информацию для регистрации заявки.</param>
 protected override void WriteOrderCondition(IFixWriter writer, OrderRegisterMessage regMsg)
 {
     writer.WriteOrderCondition((QuikOrderCondition)regMsg.Condition, TimeStampFormat);
 }
Пример #16
0
        // create and send message
        private void SendCommand(IReadOnlyDictionary <string, object> actions)
        {
            Message message = null;

            switch (actions["ACTION"].ToString())
            {
            case "NEW_ORDER":
            {
                message = new OrderRegisterMessage
                {
                    SecurityId = _securities.FirstOrDefault(s => s.Code == actions["SECCODE"].ToString() &&
                                                            s.Class == actions["CLASSCODE"].ToString()).ToSecurityId(),
                    ClientCode    = actions["CLIENTCODE"].ToString(),
                    PortfolioName = actions["ACCOUNT"].ToString(),
                    OrderType     = (OrderTypes)actions["TYPE"],
                    Price         = (decimal)actions["PRICE"],
                    Side          = (Sides)actions["OPERATION"],
                    Volume        = (decimal)actions["QUANTITY"],
                    TransactionId = _transAdapter.TransactionIdGenerator.GetNextId(),
                    Comment       = actions["COMMENT"].ToString()
                };
            }
            break;

            case "KILL_ORDER":
            {
                message = new OrderCancelMessage
                {
                    OrderId = (long)actions["ORDER_KEY"],
                    OriginalTransactionId = (long)actions["ORIGINAL_TRANS_ID"],
                    TransactionId         = _transAdapter.TransactionIdGenerator.GetNextId()
                };
            }
            break;

            case "KILL_ALL_ORDERS":
            {
                message = new OrderGroupCancelMessage
                {
                    TransactionId = _transAdapter.TransactionIdGenerator.GetNextId()
                };
            }
            break;

            case "MOVE_ORDERS":
            {
                //TODO
            }
            break;

            case "REGISTER_SECURITY":
            {
                //TODO
            }
            break;

            case "UNREGISTER_SECURITY":
            {
                //TODO
            }
            break;

            case "REGISTER_TRADES":
            {
                //TODO
            }
            break;

            case "UNREGISTER_TRADES":
            {
                //TODO
            }
            break;

            case "REGISTER_MARKETDEPTH":
            {
                //TODO
            }
            break;

            case "UNREGISTER_MARKETDEPTH":
            {
                //TODO
            }
            break;
            }

            if (message != null)
            {
                _transAdapter.SendInMessage(message);
            }
        }
Пример #17
0
        // create and send message
        private void SendCommand(IReadOnlyDictionary<string, object> actions)
        {
            Message message = null;

            switch (actions["ACTION"].ToString())
            {
                case "NEW_ORDER":
                {
                    message = new OrderRegisterMessage
                    {
                        SecurityId = _securities.FirstOrDefault(s => s.Code == actions["SECCODE"].ToString() &&
                                                                     s.Class == actions["CLASSCODE"].ToString()).ToSecurityId(),
                        ClientCode = actions["CLIENTCODE"].ToString(),
                        PortfolioName = actions["ACCOUNT"].ToString(),
                        OrderType = (OrderTypes)actions["TYPE"],
                        Price = (decimal)actions["PRICE"],
                        Side = (Sides)actions["OPERATION"],
                        Volume = (decimal)actions["QUANTITY"],
                        TransactionId = _transAdapter.TransactionIdGenerator.GetNextId(),
                        Comment = actions["COMMENT"].ToString()
                    };
                }
                    break;
                case "KILL_ORDER":
                {
                    message = new OrderCancelMessage
                    {
                        OrderId = (long)actions["ORDER_KEY"],
                        OriginalTransactionId = (long)actions["ORIGINAL_TRANS_ID"],
                        TransactionId = _transAdapter.TransactionIdGenerator.GetNextId()
                    };
                }
                    break;
                case "KILL_ALL_ORDERS":
                {
                    message = new OrderGroupCancelMessage
                    {
                        TransactionId = _transAdapter.TransactionIdGenerator.GetNextId()
                    };
                }
                    break;
                case "MOVE_ORDERS":
                {
                    //TODO
                }
                    break;
                case "REGISTER_SECURITY":
                {
                    //TODO
                }
                    break;
                case "UNREGISTER_SECURITY":
                {
                    //TODO
                }
                    break;
                case "REGISTER_TRADES":
                {
                    //TODO
                }
                    break;
                case "UNREGISTER_TRADES":
                {
                    //TODO
                }
                    break;
                case "REGISTER_MARKETDEPTH":
                {
                    //TODO
                }
                    break;
                case "UNREGISTER_MARKETDEPTH":
                {
                    //TODO
                }
                    break;
            }

            if (message != null)
                _transAdapter.SendInMessage(message);
        }
        /// <summary>
        /// Отправить данные по условию заявки.
        /// </summary>
        /// <param name="writer">Писатель FIX данных.</param>
        /// <param name="regMsg">Сообщение, содержащее информацию для регистрации заявки.</param>
        protected override void SendFixOrderCondition(FixWriter writer, OrderRegisterMessage regMsg)
        {
            var condition = (QuikOrderCondition)regMsg.Condition;

            if (condition.Type != null)
            {
                writer.Write((FixTags)QuikFixTags.Type);
                writer.Write((int)condition.Type.Value);
            }

            if (condition.StopPriceCondition != null)
            {
                writer.Write((FixTags)QuikFixTags.StopPriceCondition);
                writer.Write((int)condition.StopPriceCondition.Value);
            }

            if (condition.ConditionOrderSide != null)
            {
                writer.Write((FixTags)QuikFixTags.ConditionOrderSide);
                writer.Write((int)condition.ConditionOrderSide.Value);
            }

            if (condition.LinkedOrderCancel != null)
            {
                writer.Write((FixTags)QuikFixTags.LinkedOrderCancel);
                writer.Write(condition.LinkedOrderCancel.Value);
            }

            if (condition.Result != null)
            {
                writer.Write((FixTags)QuikFixTags.Result);
                writer.Write((int)condition.Result.Value);
            }

            if (condition.OtherSecurityId != null)
            {
                writer.Write((FixTags)QuikFixTags.OtherSecurityCode);
                writer.Write(condition.OtherSecurityId.Value.SecurityCode);
            }

            if (condition.StopPrice != null)
            {
                writer.Write((FixTags)QuikFixTags.StopPrice);
                writer.Write(condition.StopPrice.Value);
            }

            if (condition.StopLimitPrice != null)
            {
                writer.Write((FixTags)QuikFixTags.StopLimitPrice);
                writer.Write(condition.StopLimitPrice.Value);
            }

            if (condition.IsMarketStopLimit != null)
            {
                writer.Write((FixTags)QuikFixTags.IsMarketStopLimit);
                writer.Write(condition.IsMarketStopLimit.Value);
            }

            if (condition.ActiveTime != null)
            {
                writer.Write((FixTags)QuikFixTags.ActiveTimeFrom);
                writer.Write(condition.ActiveTime.Min.UtcDateTime);

                writer.Write((FixTags)QuikFixTags.ActiveTimeTo);
                writer.Write(condition.ActiveTime.Max.UtcDateTime);
            }

            if (condition.ConditionOrderId != null)
            {
                writer.Write((FixTags)QuikFixTags.ConditionOrderId);
                writer.Write(condition.ConditionOrderId.Value);
            }

            if (condition.ConditionOrderPartiallyMatched != null)
            {
                writer.Write((FixTags)QuikFixTags.ConditionOrderPartiallyMatched);
                writer.Write(condition.ConditionOrderPartiallyMatched.Value);
            }

            if (condition.ConditionOrderUseMatchedBalance != null)
            {
                writer.Write((FixTags)QuikFixTags.ConditionOrderUseMatchedBalance);
                writer.Write(condition.ConditionOrderUseMatchedBalance.Value);
            }

            if (condition.LinkedOrderPrice != null)
            {
                writer.Write((FixTags)QuikFixTags.LinkedOrderPrice);
                writer.Write(condition.LinkedOrderPrice.Value);
            }

            if (condition.Offset != null)
            {
                writer.Write((FixTags)QuikFixTags.Offset);
                writer.Write(condition.Offset.ToString());
            }

            if (condition.Spread != null)
            {
                writer.Write((FixTags)QuikFixTags.StopSpread);
                writer.Write(condition.Spread.ToString());
            }

            if (condition.IsMarketTakeProfit != null)
            {
                writer.Write((FixTags)QuikFixTags.IsMarketTakeProfit);
                writer.Write(condition.IsMarketTakeProfit.Value);
            }
        }