Example #1
0
        private void InfoClient_OnInfoTrade(InfoTrade trade)
        {
            if (trade.acc_id == 0 || !mapAccountIdToAccount.ContainsKey(trade.acc_id))
            {
                return;
            }

            var code       = trade.security + "|" + trade.board;
            var instrument = connector.ResolveSymbolAsync(code).Result;

            if (instrument == null)
            {
                Logger.Error().Print($"Unable to resolve instrument for {code}");
                return;
            }

            var fill = new FillMessage
            {
                Account         = mapAccountIdToAccount[trade.acc_id].code,
                Instrument      = instrument,
                ExchangeId      = trade.code,
                Operation       = trade.buy_sell == BuySell.BUY ? OrderOperation.Buy : OrderOperation.Sell,
                Price           = PriceHelper.ToPrice(trade.price),
                Quantity        = trade.qty,
                DateTime        = DateTime.FromFileTime((long)trade.trade_time),
                ExchangeOrderId = trade.order_id
            };

            OnMessageReceived(fill);
        }
Example #2
0
        private void InfoClient_OnInfoHolding(InfoHolding holding)
        {
            if (!accounts.ContainsKey(holding.account))
            {
                return;
            }

            var code       = holding.security + "|BRD-NORMAL";
            var instrument = connector.ResolveSymbolAsync(code).Result;

            if (instrument == null)
            {
                Logger.Error().Print($"Unable to resolve instrument for {code}");
                return;
            }

            if (!mapAccountIdToAccount.ContainsKey(holding.acc_id))
            {
                mapAccountIdToAccount.Add(holding.acc_id, accounts[holding.account]);
            }

            var position = new PositionMessage
            {
                Account    = holding.account,
                Instrument = instrument,
                Quantity   = (int)holding.trade_buy_qty - (int)holding.trade_sell_qty,
                Price      = PriceHelper.ToPrice(holding.settle_price)
            };

            OnMessageReceived(position);
        }
Example #3
0
        public bool ProcessOrder(InfoOrder order)
        {
            var code  = order.code;
            var price = PriceHelper.ToPrice(order.price);

            var sorted = order.buy_sell == BuySell.BUY ? bids : asks;

            if (!mapOrders.TryGetValue(code, out var info))
            {
                //if (string.IsNullOrEmpty(order.security))
                //{
                //    //Logger.DebugFormat("Получено обновление заявки с пустым полем security. OrderId: {0}", order.code);
                //    return false;
                //}

                if (order.qtyLeft == 0 ||
                    order.status == OrderStatus.CANCELED ||
                    order.status == OrderStatus.MATCHED)
                {
                    // TODO Проверить частичное
                    return(false);
                }

                info = new ShortOrderInfo(code, price, order.buy_sell);

                mapOrders[order.code] = info;

                List <ShortOrderInfo> list;
                if (!sorted.TryGetValue(price, out list))
                {
                    sorted[price] = list = new List <ShortOrderInfo>();
                }
                list.Add(info);
            }

            info.Quantity = order.qtyLeft;

            // Очищаем лишние заявки (в статусах Matched и Cancelled)
            if (order.qtyLeft == 0 ||
                order.status == OrderStatus.CANCELED ||
                order.status == OrderStatus.MATCHED)
            // TODO Проверить частичное
            {
                mapOrders.Remove(order.code);

                if (sorted.TryGetValue(price, out var list))
                {
                    list.Remove(info);
                    if (!list.Any())
                    {
                        sorted.Remove(price);
                    }
                }
            }

            return(true);
        }
Example #4
0
        private void InfoClient_OnInfoOrder(InfoOrder order)
        {
            if (!accounts.ContainsKey(order.account))
            {
                return;
            }

            var activeQuantity = order.qtyLeft;

            OrderState state;

            switch (order.status)
            {
            case OrderStatus.CANCELED:
                state = !string.IsNullOrEmpty(order.res_code) && order.res_code != "ENF_CANC"     // TODO Hardcode волшебной строки
                        ? OrderState.Error
                        : OrderState.Cancelled;
                activeQuantity = 0;
                break;

            case OrderStatus.MATCHED:
                state = OrderState.Filled;
                break;

            case OrderStatus.FREEZED:
            case OrderStatus.QUEUED:
                state = order.qty_executed > 0 ? OrderState.PartiallyFilled : OrderState.Active;
                break;

            case OrderStatus.WAIT_APPROVAL:
            default:
                return;
            }

            //long filledQty = order.ActiveQty - (long)infoOrder.qtyLeft;

            Guid.TryParseExact(order.trn, "N", out var trId);

            var oscm = new OrderStateChangeMessage
            {
                TransactionId   = trId,
                OrderExchangeId = order.code,
                Quantity        = order.qty,
                ActiveQuantity  = activeQuantity,
                FilledQuantity  = order.qty_executed, // TODO
                Price           = PriceHelper.ToPrice(order.price),
                ChangeTime      = DateTime.Now,       // TODO
                State           = state
            };

            OnMessageReceived(oscm);
        }
Example #5
0
        private InstrumentParams CreateParams(InfoSecboard secboard)
        {
            var instrument = connector.ResolveSymbolAsync(secboard.code).Result;

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

            var security = securitiesMap[secboard.security];

            return(new InstrumentParams
            {
                Instrument = instrument,
                //ExpirationDate = security.execution_day,
                PriceStep = PriceHelper.ToPrice(security.price_step),
                LotSize = security.lot_size
            });
        }
Example #6
0
        private void InfoClient_OnInfoSecboard(InfoSecboard secboard)
        {
            using (allInstrumentLock.WriteLock())
            {
                var code = secboard.code;
                InstrumentParams ip;
                if (!instrumentsParams.TryGetValue(code, out ip))
                {
                    allInstruments.Add(code);

                    ip = CreateParams(secboard);
                    if (ip == null)
                    {
                        return;
                    }

                    instrumentsParams[code] = ip;
                }

                ip.TopPriceLimit    = PriceHelper.ToPrice(secboard.price_max);
                ip.BottomPriceLimit = PriceHelper.ToPrice(secboard.price_min);

                ip.Settlement         = PriceHelper.ToPrice(secboard.market_price);
                ip.PreviousSettlement = PriceHelper.ToPrice(secboard.prev_market_price);
                ip.LastPrice          = PriceHelper.ToPrice(secboard.last_trade_price);

                //ip.SessionEndTime = secboard.finish_trade_time;

                ip.BestBidPrice   = PriceHelper.ToPrice(secboard.best_buy);
                ip.BestOfferPrice = PriceHelper.ToPrice(secboard.best_sell);

                if (subscribedInstruments.Contains(code))
                {
                    OnMessageReceived(ip);
                }
            }
        }
Example #7
0
        public async void Visit(NewOrderTransaction transaction)
        {
            try
            {
                //internal async Task<string> ResolveInstrumentAsync(Instrument instrument)
                //{
                //    var data = await instrumentConverter.ResolveInstrumentAsync(this, instrument);
                //    return data?.Symbol;
                //}

                var data = await connector.ResolveInstrumentDataAsync(transaction.Instrument);

                if (data == null)
                {
                    OnMessageReceived(TransactionReply.Rejected(transaction, $"Unable to get symbol of {transaction.Instrument}"));
                    return;
                }

                if (!accounts.TryGetValue(transaction.Account, out var account))
                {
                    OnMessageReceived(TransactionReply.Rejected(transaction, $"Не найден счет {transaction.Account}"));
                    return;
                }

                var order = new SpimexAdapter.FTE.Order
                {
                    account = account.code,
                    firm    = account.firm,
                    client  = account.client,

                    security = data.Symbol,
                    board    = data.Board,

                    @type    = transaction.GetOrderType(),
                    @params  = transaction.GetOrderParams(),
                    buy_sell = transaction.GetOperation(),

                    price         = PriceHelper.FromPrice(transaction.Price),
                    qty           = transaction.Quantity,
                    trn           = transaction.TransactionId.ToString("N"),
                    isMarketMaker = transaction.IsMarketMakerOrder,
                    comment       = transaction.Comment,
                };


                var reply = await transClient.SendOrder(order);

                OnMessageReceived(TransactionReply.Accepted(transaction, reply.code));

                OrderState?state = null;
                switch (reply.status)
                {
                case OrderStatus.CANCELED:
                    state = OrderState.Cancelled;
                    break;

                case OrderStatus.MATCHED:
                    state = OrderState.Filled;
                    break;

                case OrderStatus.FREEZED:
                case OrderStatus.QUEUED:
                    state = reply.qty_executed > 0 ? OrderState.PartiallyFilled : OrderState.Active;
                    break;
                }

                var oscm = new OrderStateChangeMessage
                {
                    TransactionId   = transaction.TransactionId,
                    OrderExchangeId = reply.code,
                    Quantity        = order.qty,
                    ActiveQuantity  = reply.qtyLeft,
                    FilledQuantity  = reply.qty_executed,
                    Price           = PriceHelper.ToPrice(order.price),
                    ChangeTime      = DateTime.Now,
                    State           = state
                };
                OnMessageReceived(oscm);
            }
            catch (FTEException e)
            {
                OnMessageReceived(TransactionReply.Rejected(transaction, e.Message));
            }
        }