private void ProcessOrderRegister(OrderRegisterMessage regMsg)
        {
            var reply = _client.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.Transaction,
                HasOrderInfo  = true,
            });

            ProcessFunds(reply.Command.Funds);

            _hasActiveOrders = true;
        }
Exemple #2
0
        /// <summary>
        /// Создать <see cref="QuikSessionHolder"/>.
        /// </summary>
        /// <param name="transactionIdGenerator">Генератор идентификаторов транзакций.</param>
        public QuikSessionHolder(IdGenerator transactionIdGenerator)
            : base(transactionIdGenerator)
        {
            CreateTables();

            IsAsyncMode = true;
            Path        = QuikTerminal.GetDefaultPath();

            SecurityClassInfo.Add("SPBOPT", RefTuple.Create(SecurityTypes.Option, ExchangeBoard.Forts.Code));
            SecurityClassInfo.Add("SPBFUT", RefTuple.Create(SecurityTypes.Future, ExchangeBoard.Forts.Code));

            // http://stocksharp.com/forum/yaf_postsm11628_Pozitsii-po-dierivativam.aspx#post11628
            SecurityClassInfo.Add("OPTUX", RefTuple.Create(SecurityTypes.Option, ExchangeBoard.Ux.Code));
            SecurityClassInfo.Add("FUTUX", RefTuple.Create(SecurityTypes.Future, ExchangeBoard.Ux.Code));
            //SecurityClassInfo.Add("GTS", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.UxStock.Code));

            // http://groups.google.ru/group/stocksharp/msg/28518b814c925521
            SecurityClassInfo.Add("RTSST", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.Forts.Code));

            SecurityClassInfo.Add("QJSIM", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.MicexJunior.Code));

            SecurityClassInfo.Add("RTSIDX", RefTuple.Create(SecurityTypes.Index, ExchangeBoard.Forts.Code));

            UtcOffset = TimeHelper.Moscow.BaseUtcOffset;

            IsTransactionEnabled = true;
            IsMarketDataEnabled  = true;
        }
Exemple #3
0
        /// <summary>
        /// To get historical ticks.
        /// </summary>
        /// <param name="securityId">The instrument identifier for which you need to get all trades.</param>
        /// <param name="from">Begin period.</param>
        /// <param name="to">End period.</param>
        /// <param name="isSuccess">Whether all data were obtained successfully or the download process has been interrupted.</param>
        /// <returns>Historical ticks.</returns>
        public IEnumerable <Level1ChangeMessage> GetHistoricalLevel1(SecurityId securityId, DateTimeOffset from, DateTimeOffset to, out bool isSuccess)
        {
            this.AddInfoLog(LocalizedStrings.Str2145Params, securityId, from, to);

            var transactionId = TransactionIdGenerator.GetNextId();

            var info = RefTuple.Create(new List <Level1ChangeMessage>(), new SyncObject(), false, securityId, false);

            _level1Info.Add(transactionId, info);

            SendInMessage(new MarketDataMessage
            {
                SecurityId    = securityId,
                DataType      = MarketDataTypes.Level1,
                From          = from,
                To            = to,
                IsSubscribe   = true,
                TransactionId = transactionId,
            });

            lock (info.Second)
            {
                if (!info.Third)
                {
                    info.Second.Wait();
                }
            }

            isSuccess = info.Fifth;

            return(info.First);
        }
        /// <summary>
        /// Создать <see cref="SmartComMessageAdapter"/>.
        /// </summary>
        /// <param name="transactionIdGenerator">Генератор идентификаторов транзакций.</param>
        public SmartComMessageAdapter(IdGenerator transactionIdGenerator)
            : base(transactionIdGenerator)
        {
            Version = SmartComVersions.V3;

            SecurityClassInfo.Add("OPT", RefTuple.Create(SecurityTypes.Option, ExchangeBoard.Forts.Code));
            SecurityClassInfo.Add("OPTM", RefTuple.Create(SecurityTypes.Option, ExchangeBoard.Forts.Code));
            SecurityClassInfo.Add("FUT", RefTuple.Create(SecurityTypes.Future, ExchangeBoard.Forts.Code));
            SecurityClassInfo.Add("FXMFD", RefTuple.Create(SecurityTypes.Currency, ExchangeBoard.Mfd.Code));
            SecurityClassInfo.Add("WFMFD", RefTuple.Create(SecurityTypes.Index, ExchangeBoard.Mfd.Code));
            SecurityClassInfo.Add("WIMFD", RefTuple.Create(SecurityTypes.Index, ExchangeBoard.Mfd.Code));
            SecurityClassInfo.Add("EQBR", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.MicexEqbr.Code));
            SecurityClassInfo.Add("TQBR", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.MicexTqbr.Code));
            SecurityClassInfo.Add("TQNE", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.MicexTqne.Code));
            SecurityClassInfo.Add("EQNE", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.MicexEqne.Code));
            SecurityClassInfo.Add("EQOB", RefTuple.Create(SecurityTypes.Bond, ExchangeBoard.MicexEqob.Code));
            SecurityClassInfo.Add("EQNB", RefTuple.Create(SecurityTypes.Bond, ExchangeBoard.MicexEqnb.Code));
            SecurityClassInfo.Add("EQDB", RefTuple.Create(SecurityTypes.Bond, ExchangeBoard.MicexEqdb.Code));
            SecurityClassInfo.Add("EQOS", RefTuple.Create(SecurityTypes.Bond, ExchangeBoard.MicexEqos.Code));
            SecurityClassInfo.Add("TQOB", RefTuple.Create(SecurityTypes.Bond, ExchangeBoard.MicexTqob.Code));
            SecurityClassInfo.Add("TQLV", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.MicexTqlv.Code));

            PortfolioBoardCodes = new Dictionary <string, string>
            {
                { "EQ", ExchangeBoard.MicexEqbr.Code },
                { "FOB", ExchangeBoard.MicexFbcb.Code },
                { "RTS_FUT", ExchangeBoard.Forts.Code },
            };

            UpdatePlatform();

            this.AddMarketDataSupport();
            this.AddTransactionalSupport();
            this.RemoveSupportedMessage(MessageTypes.OrderStatus);
        }
        private void SetSource(ChartIndicatorElement element, CandleSeries candleSeries, IIndicator indicator)
        {
            RefPair <DateTimeOffset, IDictionary <IChartElement, object> >[] values = null;

            lock (_syncRoot)
            {
                _indicators[element] = indicator;

                var isNew = !_elementsBySeries.ContainsKey(candleSeries);

                if (!isNew && CanProcess)
                {
                    values = ProcessHistoryCandles(element, candleSeries);
                }
                else if (isNew)
                {
                    SubscribeSeries(candleSeries);
                }

                var lastDate = values == null || values.IsEmpty() ? DateTimeOffset.MinValue : values.Last().First;

                _elementsInfo.SafeAdd(element, e => RefTuple.Create(lastDate, candleSeries));
                _elementsBySeries.SafeAdd(candleSeries).Add(element);
            }

            if (values != null && values.Length > 0)
            {
                new ChartDrawCommand(values).Process(this);
            }
        }
Exemple #6
0
        /// <inheritdoc />
        protected override void OnSendInMessage(Message message)
        {
            switch (message.Type)
            {
            case MessageTypes.Reset:
                _states.Clear();
                break;

            case MessageTypes.MarketData:
            {
                var mdMsg = (MarketDataMessage)message;

                if (mdMsg.DataType == MarketDataTypes.MarketDepth)
                {
                    if (mdMsg.IsSubscribe)
                    {
                        if (IsSupportOrderBookIncrements)
                        {
                            _states.Add(mdMsg.TransactionId, RefTuple.Create(new QuotesDict(new BackwardComparer <decimal>()), new QuotesDict(), _none));
                        }
                    }
                    else
                    {
                        _states.Remove(mdMsg.OriginalTransactionId);
                    }
                }

                break;
            }
            }

            base.OnSendInMessage(message);
        }
Exemple #7
0
        public static void Draw(this IChart chart, DateTimeOffset time, IDictionary <IChartElement, object> values)
        {
            if (chart == null)
            {
                throw new ArgumentNullException(nameof(chart));
            }

            chart.Draw(new[] { RefTuple.Create(time, values) });
        }
            public void AddOrder(OrderRegisterMessage message)
            {
                if (message is null)
                {
                    throw new ArgumentNullException(nameof(message));
                }

                _ordersInfo[message.TransactionId] = RefTuple.Create(message.Side, message.Price, (decimal?)message.Volume);
            }
Exemple #9
0
        private MarketDataMessage ProcessMarketDataRequest(MarketDataMessage message)
        {
            if (message.IsSubscribe)
            {
                if (!InnerAdapter.IsMarketDataTypeSupported(DataType.OrderLog))
                {
                    return(message);
                }

                var isBuild = message.BuildMode == MarketDataBuildModes.Build && message.BuildFrom == DataType.OrderLog;

                if (message.DataType2 == DataType.MarketDepth)
                {
                    if (isBuild || !InnerAdapter.IsMarketDataTypeSupported(message.ToDataType()))
                    {
                        var secId = GetSecurityId(message.SecurityId);

                        IOrderLogMarketDepthBuilder builder = null;

                        if (InnerAdapter.IsSecurityRequired(DataType.OrderLog))
                        {
                            builder = message.DepthBuilder ?? InnerAdapter.CreateOrderLogMarketDepthBuilder(secId);
                        }

                        _subscriptionIds.Add(message.TransactionId, RefTuple.Create(true, builder, new SyncObject()));

                        message           = message.TypedClone();
                        message.DataType2 = DataType.OrderLog;

                        this.AddInfoLog("OL->MD subscribed {0}/{1}.", secId, message.TransactionId);
                    }
                }
                else if (message.DataType2 == DataType.Ticks)
                {
                    if (isBuild || !InnerAdapter.IsMarketDataTypeSupported(message.ToDataType()))
                    {
                        var secId = GetSecurityId(message.SecurityId);

                        _subscriptionIds.Add(message.TransactionId, RefTuple.Create(false, (IOrderLogMarketDepthBuilder)null, new SyncObject()));

                        message           = message.TypedClone();
                        message.DataType2 = DataType.OrderLog;

                        this.AddInfoLog("OL->TICK subscribed {0}/{1}.", secId, message.TransactionId);
                    }
                }
            }
            else
            {
                RemoveSubscription(message.OriginalTransactionId);
            }

            return(message);
        }
        private void ProcessOrderRegister(OrderRegisterMessage regMsg)
        {
            var condition = (BitStampOrderCondition)regMsg.Condition;

            switch (regMsg.OrderType)
            {
            case null:
            case OrderTypes.Limit:
            case OrderTypes.Market:
                break;

            case OrderTypes.Conditional:
            {
                if (!condition.IsWithdraw)
                {
                    break;
                }

                var withdrawId = _httpClient.Withdraw(regMsg.SecurityId.SecurityCode, regMsg.Volume, condition.WithdrawInfo);

                SendOutMessage(new ExecutionMessage
                    {
                        ExecutionType         = ExecutionTypes.Transaction,
                        OrderId               = withdrawId,
                        ServerTime            = CurrentTime.ConvertToUtc(),
                        OriginalTransactionId = regMsg.TransactionId,
                        OrderState            = OrderStates.Done,
                        HasOrderInfo          = true,
                    });

                ProcessPortfolioLookup(null);
                return;
            }

            default:
                throw new NotSupportedException(LocalizedStrings.Str1601Params.Put(regMsg.OrderType, regMsg.TransactionId));
            }

            var price = regMsg.OrderType == OrderTypes.Market ? (decimal?)null : regMsg.Price;

            var result = _httpClient.RegisterOrder(regMsg.SecurityId.ToCurrency(), regMsg.Side.ToString().ToLowerInvariant(), price, regMsg.Volume, condition?.StopPrice, regMsg.TillDate == DateTime.Today, regMsg.TimeInForce == TimeInForce.CancelBalance);

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

            SendOutMessage(new ExecutionMessage
            {
                ExecutionType         = ExecutionTypes.Transaction,
                OrderId               = result.Id,
                ServerTime            = result.Time,
                OriginalTransactionId = regMsg.TransactionId,
                OrderState            = OrderStates.Active,
                HasOrderInfo          = true,
            });
        }
Exemple #11
0
        /// <summary>
        /// Создать <see cref="SmartComSessionHolder"/>.
        /// </summary>
        /// <param name="transactionIdGenerator">Генератор идентификаторов транзакций.</param>
        public SmartComSessionHolder(IdGenerator transactionIdGenerator)
            : base(transactionIdGenerator)
        {
            Version = SmartComVersions.V3;

            IsTransactionEnabled = true;
            IsMarketDataEnabled  = true;

            SecurityClassInfo.Add("OPT", RefTuple.Create(SecurityTypes.Option, ExchangeBoard.Forts.Code));
            SecurityClassInfo.Add("OPTM", RefTuple.Create(SecurityTypes.Option, ExchangeBoard.Forts.Code));
            SecurityClassInfo.Add("FUT", RefTuple.Create(SecurityTypes.Future, ExchangeBoard.Forts.Code));
        }
Exemple #12
0
        /// <summary>
        /// Создать <see cref="AlfaDirectSessionHolder"/>.
        /// </summary>
        /// <param name="transactionIdGenerator">Генератор идентификаторов транзакций.</param>
        public AlfaDirectSessionHolder(IdGenerator transactionIdGenerator)
            : base(transactionIdGenerator)
        {
            SecurityClassInfo.Add("FORTS", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.Forts.Code));
            SecurityClassInfo.Add("INDEX", RefTuple.Create(SecurityTypes.Index, ExchangeBoard.Micex.Code));
            SecurityClassInfo.Add("INDEX2", RefTuple.Create(SecurityTypes.Index, "INDEX"));
            SecurityClassInfo.Add("MICEX_SHR_T", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.Micex.Code));
            SecurityClassInfo.Add("RTS_STANDARD", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.Forts.Code));

            IsTransactionEnabled = true;
            IsMarketDataEnabled  = true;
        }
Exemple #13
0
            public void Process(ExecutionMessage message)
            {
                if (message == null)
                {
                    throw new ArgumentNullException(nameof(message));
                }

                var key = Tuple.Create(message.Side, message.OrderPrice);

                switch (message.OrderState)
                {
                case OrderStates.Done:
                case OrderStates.Failed:
                {
                    var pair = _executions.TryGetValue(key);

                    if (pair == null)
                    {
                        break;
                    }

                    var balance = pair.First.TryGetAndRemove(message.OriginalTransactionId);

                    if (pair.First.Count == 0)
                    {
                        _executions.Remove(key);
                    }
                    else
                    {
                        pair.Second -= balance;
                    }

                    break;
                }

                case OrderStates.Active:
                {
                    var balance = message.Balance;

                    if (balance != null)
                    {
                        var pair = _executions.SafeAdd(key, k => RefTuple.Create(new Dictionary <long, decimal>(), 0M));

                        var prev = pair.First.TryGetValue(message.OriginalTransactionId);

                        pair.First[message.OriginalTransactionId] = balance.Value;
                        pair.Second += balance.Value - prev;
                    }

                    break;
                }
                }
            }
        /// <summary>
        /// Создать <see cref="AlfaDirectMessageAdapter"/>.
        /// </summary>
        /// <param name="transactionIdGenerator">Генератор идентификаторов транзакций.</param>
        public AlfaDirectMessageAdapter(IdGenerator transactionIdGenerator)
            : base(transactionIdGenerator)
        {
            Platform = Platforms.x86;

            this.AddMarketDataSupport();
            this.AddTransactionalSupport();

            SecurityClassInfo.Add("FORTS", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.Forts.Code));
            SecurityClassInfo.Add("INDEX", RefTuple.Create(SecurityTypes.Index, ExchangeBoard.Micex.Code));
            SecurityClassInfo.Add("INDEX2", RefTuple.Create(SecurityTypes.Index, "INDEX"));
            SecurityClassInfo.Add("MICEX_SHR_T", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.Micex.Code));
            SecurityClassInfo.Add("RTS_STANDARD", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.Forts.Code));
        }
Exemple #15
0
        private void ProcessInPortfolioMessage(PortfolioMessage message)
        {
            var sendIn = false;
            var pfName = message.PortfolioName;

            RefPair <PortfolioMessage, int> pair;

            lock (_sync)
            {
                pair = _pfSubscribers.TryGetValue(pfName) ?? RefTuple.Create((PortfolioMessage)message.Clone(), 0);

                var subscribersCount = pair.Second;

                if (message.IsSubscribe)
                {
                    subscribersCount++;
                    sendIn = subscribersCount == 1;
                }
                else
                {
                    if (subscribersCount > 0)
                    {
                        subscribersCount--;
                        sendIn = subscribersCount == 0;
                    }
                    //else
                    //	sendOutMsg = NonExist(message);
                }

                if (subscribersCount > 0)
                {
                    pair.Second            = subscribersCount;
                    _pfSubscribers[pfName] = pair;
                }
                else
                {
                    _pfSubscribers.Remove(pfName);
                }
            }

            if (sendIn)
            {
                if (!message.IsSubscribe && message.OriginalTransactionId == 0)
                {
                    message.OriginalTransactionId = pair.First.TransactionId;
                }

                base.SendInMessage(message);
            }
        }
        private void SetSource(ChartCandleElement element, CandleSeries candleSeries)
        {
            lock (_syncRoot)
            {
                var isNew = !_elementsBySeries.ContainsKey(candleSeries);

                if ((isNew || !CanProcess) && isNew)
                {
                    SubscribeSeries(candleSeries);
                }

                _elementsInfo.SafeAdd(element, e => RefTuple.Create(DateTimeOffset.MinValue, candleSeries));
                _elementsBySeries.SafeAdd(candleSeries).Add(element);
            }
        }
        private void ProcessInnerAdapterConnectMessage(IMessageAdapter innerAdapter, ConnectMessage message)
        {
            if (message.Error != null)
            {
                SessionHolder.AddErrorLog(LocalizedStrings.Str625Params, innerAdapter.GetType().Name, message.Error);
            }

            Exception error = null;

            var canProcess = _innerAdapters.SyncGet(c =>
            {
                var connected = message.Error == null;

                _adapterStates[innerAdapter] = RefTuple.Create(connected, message.Error);

                if (_canRaiseConnected && connected)
                {
                    _canRaiseConnected    = false;
                    _canRaiseDisconnected = true;

                    ResetConnectionErrors();

                    return(true);
                }

                if (_adapterStates.Count == c.Count)
                {
                    // произошла ошибка и нет ни одного подключенного коннектора
                    if (_adapterStates.Values.All(p => !p.First))
                    {
                        error = new AggregateException(LocalizedStrings.Str626, _adapterStates.Values.Select(p => p.Second));
                        return(true);
                    }

                    ResetConnectionErrors();
                }

                return(false);
            });

            if (canProcess)
            {
                SendOutMessage(new ConnectMessage {
                    Error = error
                });
            }
        }
Exemple #18
0
        public static void FillDefault(this IDictionary <string, RefPair <SecurityTypes, string> > securityClassInfo)
        {
            securityClassInfo.Add("SPBOPT", RefTuple.Create(SecurityTypes.Option, ExchangeBoard.Forts.Code));
            securityClassInfo.Add("SPBFUT", RefTuple.Create(SecurityTypes.Future, ExchangeBoard.Forts.Code));

            // http://stocksharp.com/forum/yaf_postsm11628_Pozitsii-po-dierivativam.aspx#post11628
            securityClassInfo.Add("OPTUX", RefTuple.Create(SecurityTypes.Option, ExchangeBoard.Ux.Code));
            securityClassInfo.Add("FUTUX", RefTuple.Create(SecurityTypes.Future, ExchangeBoard.Ux.Code));
            //securityClassInfo.Add("GTS", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.UxStock.Code));

            // http://groups.google.ru/group/stocksharp/msg/28518b814c925521
            securityClassInfo.Add("RTSST", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.Forts.Code));

            securityClassInfo.Add("QJSIM", RefTuple.Create(SecurityTypes.Stock, ExchangeBoard.MicexJunior.Code));

            securityClassInfo.Add("RTSIDX", RefTuple.Create(SecurityTypes.Index, ExchangeBoard.Forts.Code));
        }
Exemple #19
0
        /// <summary>
        /// To get historical candles.
        /// </summary>
        /// <param name="security">The instrument for which you need to get candles.</param>
        /// <param name="candleMessageType">The candle message type.</param>
        /// <param name="arg">The candle parameter (for example, time-frame).</param>
        /// <param name="count">Maximum ticks count.</param>
        /// <param name="isSuccess">Whether all data were obtained successfully or the download process has been interrupted.</param>
        /// <returns>Historical candles.</returns>
        public IEnumerable <CandleMessage> GetHistoricalCandles(Security security, Type candleMessageType, object arg, long count, out bool isSuccess)
        {
            if (security == null)
            {
                throw new ArgumentNullException(nameof(security));
            }

            //if (timeFrame <= TimeSpan.Zero)
            //	throw new ArgumentException("Тайм-фрейм должен быть больше 0.");

            var transactionId = TransactionIdGenerator.GetNextId();

            var series = new CandleSeries(candleMessageType.ToCandleType(), security, arg);

            this.AddInfoLog(LocalizedStrings.Str2146Params, series, count);

            var info = RefTuple.Create(new List <CandleMessage>(), new SyncObject(), false, series, false);

            _candleInfo.Add(transactionId, info);

            var mdMsg = new MarketDataMessage
            {
                //SecurityId = GetSecurityId(series.Security),
                DataType      = GetCandleType(series.CandleType),
                TransactionId = transactionId,
                Count         = count,
                Arg           = arg,
                IsSubscribe   = true,
            }.FillSecurityInfo(this, series.Security);

            _candleSeries.Add(transactionId, series);

            SendInMessage(mdMsg);

            lock (info.Second)
            {
                if (!info.Third)
                {
                    info.Second.Wait();
                }
            }

            isSuccess = info.Fifth;

            return(info.First);
        }
        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,
            });
        }
        private void ProcessSubscribeAction(MarketDataMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            var key = Tuple.Create(message.SecurityId, message.DataType);

            if (_subscriptionQueue.ContainsKey(key))
            {
                return;
            }

            var enumerator = GetConnectedAdapters().ToArray().Cast <IMessageAdapter>().GetEnumerator();

            _subscriptionQueue.Add(key, RefTuple.Create(enumerator, false));

            ProcessSubscriptionAction(enumerator, message);
        }
        private void ProcessInnerAdapterDisconnectMessage(IMessageAdapter innerAdapter, DisconnectMessage message)
        {
            if (message.Error != null)
            {
                SessionHolder.AddErrorLog(LocalizedStrings.Str627Params, innerAdapter.GetType().Name, message.Error);
            }

            Exception error = null;

            var canProcess = _innerAdapters.SyncGet(c =>
            {
                _adapterStates[innerAdapter] = RefTuple.Create(false, message.Error);

                if (_canRaiseDisconnected && _adapterStates.Values.All(p => !p.First))
                {
                    _canRaiseConnected    = true;
                    _canRaiseDisconnected = false;

                    var errors = _adapterStates.Values.Where(p => p.Second != null).Select(p => p.Second).ToArray();

                    if (errors.Length != 0)
                    {
                        error = new AggregateException(LocalizedStrings.Str628, errors);
                        ResetConnectionErrors();
                    }

                    DisposeInnerAdapters();

                    return(true);
                }

                return(false);
            });

            if (canProcess)
            {
                SendOutMessage(new DisconnectMessage {
                    Error = error
                });
            }
        }
Exemple #23
0
        /// <summary>
        /// To get historical candles.
        /// </summary>
        /// <param name="security">The instrument for which you need to get candles.</param>
        /// <param name="candleType">The candle type.</param>
        /// <param name="arg">The candle parameter (for example, time-frame).</param>
        /// <param name="from">Begin period.</param>
        /// <param name="to">End period.</param>
        /// <param name="isSuccess">Whether all data were obtained successfully or the download process has been interrupted.</param>
        /// <returns>Historical candles.</returns>
        public IEnumerable <CandleMessage> GetHistoricalCandles(Security security, Type candleType, object arg, DateTimeOffset from, DateTimeOffset to, out bool isSuccess)
        {
            if (security == null)
            {
                throw new ArgumentNullException(nameof(security));
            }

            //if (timeFrame <= TimeSpan.Zero)
            //	throw new ArgumentException("Тайм-фрейм должен быть больше 0.");

            if (from > to)
            {
                throw new ArgumentException(LocalizedStrings.Str2147);
            }

            var id = TransactionIdGenerator.GetNextId();

            var series = new CandleSeries(candleType, security, arg);

            this.AddInfoLog(LocalizedStrings.Str2148Params, series, from, to);

            var info = RefTuple.Create(new List <CandleMessage>(), new SyncObject(), false, series, false);

            _candleInfo.Add(id, info);

            SubscribeCandles(series, from, to, id);

            lock (info.Second)
            {
                if (!info.Third)
                {
                    info.Second.Wait();
                }
            }

            isSuccess = info.Fifth;

            return(info.First);
        }
        /// <summary>
        /// Создать <see cref="SmartComMessageAdapter"/>.
        /// </summary>
        /// <param name="transactionIdGenerator">Генератор идентификаторов транзакций.</param>
        public SmartComMessageAdapter(IdGenerator transactionIdGenerator)
            : base(transactionIdGenerator)
        {
            Version = SmartComVersions.V3;

            SecurityClassInfo.Add("OPT", RefTuple.Create(SecurityTypes.Option, ExchangeBoard.Forts.Code));
            SecurityClassInfo.Add("OPTM", RefTuple.Create(SecurityTypes.Option, ExchangeBoard.Forts.Code));
            SecurityClassInfo.Add("FUT", RefTuple.Create(SecurityTypes.Future, ExchangeBoard.Forts.Code));

            PortfolioBoardCodes = new Dictionary <string, string>
            {
                { "EQ", ExchangeBoard.MicexEqbr.Code },
                { "FOB", ExchangeBoard.MicexFbcb.Code },
                { "RTS_FUT", ExchangeBoard.Forts.Code },
            };

            UpdatePlatform();

            this.AddMarketDataSupport();
            this.AddTransactionalSupport();
            this.RemoveSupportedMessage(MessageTypes.OrderStatus);
        }
Exemple #25
0
        /// <summary>
        /// To get historical ticks.
        /// </summary>
        /// <param name="security">The instrument for which you need to get all trades.</param>
        /// <param name="from">Begin period.</param>
        /// <param name="to">End period.</param>
        /// <param name="isSuccess">Whether all data were obtained successfully or the download process has been interrupted.</param>
        /// <returns>Historical ticks.</returns>
        public IEnumerable <ExecutionMessage> GetHistoricalTicks(Security security, DateTime from, DateTime to, out bool isSuccess)
        {
            if (security == null)
            {
                throw new ArgumentNullException(nameof(security));
            }

            this.AddInfoLog(LocalizedStrings.Str2145Params, security, from, to);

            var transactionId = TransactionIdGenerator.GetNextId();

            var info = RefTuple.Create(new List <ExecutionMessage>(), new SyncObject(), false, security, false);

            _ticksInfo.Add(transactionId, info);

            SendInMessage(new MarketDataMessage
            {
                SecurityId    = security.ToSecurityId(),
                DataType      = MarketDataTypes.Trades,
                From          = from,
                To            = to,
                IsSubscribe   = true,
                TransactionId = transactionId,
            });

            lock (info.Second)
            {
                if (!info.Third)
                {
                    info.Second.Wait();
                }
            }

            isSuccess = info.Fifth;

            return(info.First);
        }
Exemple #26
0
        private void ProcessMessage <TMessage>(SecurityId securityId, TMessage message, Func <TMessage, TMessage, TMessage> processSuspend)
            where TMessage : Message
        {
            var native = securityId.Native;

            if (native != null)
            {
                SecurityId?fullSecurityId;

                lock (_syncRoot)
                    fullSecurityId = _securityIds.TryGetValue2(native);

                if (fullSecurityId == null)
                {
                    lock (_syncRoot)
                    {
                        var tuple = _suspendedOutMessages.SafeAdd(securityId, key => RefTuple.Create((List <Message>)null, (Dictionary <MessageTypes, Message>)null));

                        var clone = message.Clone();

                        if (processSuspend == null)
                        {
                            if (tuple.First == null)
                            {
                                tuple.First = new List <Message>();
                            }

                            tuple.First.Add(clone);
                        }
                        else
                        {
                            if (tuple.Second == null)
                            {
                                tuple.Second = new Dictionary <MessageTypes, Message>();
                            }

                            var prev = tuple.Second.TryGetValue(clone.Type);

                            tuple.Second[clone.Type] = prev == null
                                                                ? clone
                                                                : processSuspend((TMessage)prev, (TMessage)clone);
                        }
                    }

                    return;
                }

                message.ReplaceSecurityId(fullSecurityId.Value);
            }
            else
            {
                var securityCode = securityId.SecurityCode;
                var boardCode    = securityId.BoardCode;

                var isSecCodeEmpty = securityCode.IsEmpty();

                if (isSecCodeEmpty && message.Type != MessageTypes.Execution)
                {
                    throw new InvalidOperationException();
                }

                if (!isSecCodeEmpty && boardCode.IsEmpty())
                {
                    SecurityId?foundId = null;

                    lock (_syncRoot)
                    {
                        foreach (var id in _securityIds.Values)
                        {
                            if (!id.SecurityCode.CompareIgnoreCase(securityCode))
                            {
                                continue;
                            }

                            if (securityId.SecurityType != null && securityId.SecurityType != id.SecurityType)
                            {
                                continue;
                            }

                            foundId = id;
                        }

                        if (foundId == null)
                        {
                            var tuple = _suspendedOutMessages.SafeAdd(securityId, key => RefTuple.Create(new List <Message>(), (Dictionary <MessageTypes, Message>)null));
                            tuple.First.Add(message.Clone());
                            return;
                        }
                    }

                    message.ReplaceSecurityId(foundId.Value);

                    //// если указан код и тип инструмента, то пытаемся найти инструмент по ним
                    //if (securityId.SecurityType != null)
                    //{

                    //}
                    //else
                    //	throw new ArgumentException(nameof(securityId), LocalizedStrings.Str682Params.Put(securityCode, securityId.SecurityType));
                }
            }

            base.OnInnerAdapterNewOutMessage(message);
        }
Exemple #27
0
        private void ProcessOrderStatus()
        {
            if (_requestOrderFirst)
            {
                _requestOrderFirst = false;

                var orders = _httpClient.RequestOpenOrders().ToArray();

                foreach (var o in orders)
                {
                    var order = o;
                    _orderInfo.SafeAdd(order.Id, key => RefTuple.Create(TransactionIdGenerator.GetNextId(), (decimal)order.Amount));
                }

                var trades = _httpClient.RequestUserTransactions().ToArray();

                foreach (var trade in trades.OrderBy(t => t.Id))
                {
                    var info = _orderInfo.TryGetValue(trade.OrderId);

                    if (info == null)
                    {
                        continue;
                    }

                    info.Second -= (decimal)trade.BtcAmount;
                }

                _hasActiveOrders = false;

                foreach (var order in orders)
                {
                    _hasActiveOrders = true;
                    ProcessOrder(order);
                }

                _hasMyTrades = false;

                foreach (var trade in trades)
                {
                    ProcessExecution(trade);
                }

                return;
            }

            if (_hasMyTrades)
            {
                var transactions = _httpClient.RequestUserTransactions();

                _hasMyTrades = false;

                foreach (var trade in transactions.Where(t => t.Type == 2).OrderBy(t => t.Id))
                {
                    ProcessExecution(trade);
                }
            }

            if (_hasActiveOrders)
            {
                var orders = _httpClient.RequestOpenOrders();

                _hasActiveOrders = false;

                foreach (var order in orders)
                {
                    _hasActiveOrders = true;
                    ProcessOrder(order);
                }
            }
        }
        /// <inheritdoc />
        protected override bool OnSendInMessage(Message message)
        {
            switch (message.Type)
            {
            case MessageTypes.Reset:
                ClearState();
                break;

            case MessageTypes.MarketData:
            {
                var mdMsg = (MarketDataMessage)message;

                if (mdMsg.IsSubscribe)
                {
                    var transId = mdMsg.TransactionId;

                    lock (_sync)
                    {
                        if (_allChilds.TryGetValue(transId, out var tuple))
                        {
                            if (tuple.Second != SubscriptionStates.Stopped)
                            {
                                if (tuple.Second == SubscriptionStates.Finished)
                                {
                                    RaiseNewOutMessage(new SubscriptionFinishedMessage
                                        {
                                            OriginalTransactionId = transId,
                                        });
                                }
                                else
                                {
                                    RaiseNewOutMessage(new SubscriptionResponseMessage
                                        {
                                            OriginalTransactionId = transId,
                                            Error = new InvalidOperationException(LocalizedStrings.SubscriptionInvalidState.Put(transId, tuple.Second)),
                                        });
                                }

                                return(true);
                            }

                            var child = _parents[tuple.First].Child[mdMsg.SecurityId];
                            child.State = SubscriptionStates.Active;
                            _toFlush.AddRange(child.Suspended.CopyAndClear());

                            this.AddDebugLog("New ALL map (active): {0}/{1} TrId={2}", child.Origin.SecurityId, child.Origin.DataType2, mdMsg.TransactionId);

                            RaiseNewOutMessage(new SubscriptionResponseMessage {
                                    OriginalTransactionId = transId
                                });
                            return(true);
                        }
                        else
                        {
                            if (!IsSecurityRequired(mdMsg.DataType2) || mdMsg.SecurityId == default)
                            {
                                var existing = _parents.FirstOrDefault(p => p.Value.Origin.DataType2 == mdMsg.DataType2).Value;

                                if (existing == null)
                                {
                                    var parent = new ParentSubscription(mdMsg.TypedClone());
                                    _parents.Add(transId, parent);

                                    // first child is parent
                                    _allChilds.Add(transId, RefTuple.Create(transId, SubscriptionStates.Stopped));

                                    // do not specify security cause adapter doesn't require it
                                    mdMsg.SecurityId = default;
                                    Extensions.AllSecurity.CopyEx(mdMsg, false);
                                }
                                else
                                {
                                    var childs = existing.Child;

                                    if (mdMsg.SecurityId != default)
                                    {
                                        var child = childs.SafeAdd(mdMsg.SecurityId, key => new ChildSubscription(mdMsg.TypedClone()));
                                        child.Subscribers.Add(transId, mdMsg.TypedClone());
                                    }
                                    else
                                    {
                                        foreach (var pair in childs)
                                        {
                                            pair.Value.Subscribers.Add(transId, mdMsg.TypedClone());
                                        }
                                    }

                                    RaiseNewOutMessage(new SubscriptionResponseMessage {
                                            OriginalTransactionId = transId
                                        });
                                    return(true);
                                }
                            }
                        }
                    }
                }
                else
                {
                    var childIds = ArrayHelper.Empty <long>();

                    lock (_sync)
                    {
                        if (_allChilds.TryGetAndRemove(mdMsg.OriginalTransactionId, out var tuple))
                        {
                            this.AddDebugLog("Sec ALL child {0} unsubscribe.", mdMsg.OriginalTransactionId);

                            Exception error = null;

                            if (!tuple.Second.IsActive())
                            {
                                error = new InvalidOperationException(LocalizedStrings.SubscriptionInvalidState.Put(mdMsg.OriginalTransactionId, tuple.Second));
                            }
                            else
                            {
                                var childs = _parents[tuple.First].Child;

                                var pair = childs.FirstOrDefault(p => p.Value.Origin.TransactionId == mdMsg.OriginalTransactionId);
                                var childSubscription = pair.Value;

                                if (childSubscription == null)
                                {
                                    error = new InvalidOperationException(LocalizedStrings.SubscriptionNonExist.Put(mdMsg.OriginalTransactionId));
                                }
                                else
                                {
                                    if (childSubscription.Subscribers.Remove(mdMsg.OriginalTransactionId))
                                    {
                                        if (childSubscription.Subscribers.Count == 0)
                                        {
                                            childs.Remove(pair.Key);
                                        }
                                    }
                                    else
                                    {
                                        error = new InvalidOperationException(LocalizedStrings.SubscriptionNonExist.Put(mdMsg.OriginalTransactionId));
                                    }
                                }
                            }

                            RaiseNewOutMessage(new SubscriptionResponseMessage
                                {
                                    OriginalTransactionId = mdMsg.TransactionId,
                                    Error = error,
                                });

                            return(true);
                        }

                        if (_parents.TryGetAndRemove(mdMsg.OriginalTransactionId, out var tuple2))
                        {
                            childIds = tuple2.Child.Values.Select(s => s.Origin.TransactionId).ToArray();
                        }
                    }

                    foreach (var id in childIds)
                    {
                        RaiseNewOutMessage(new SubscriptionFinishedMessage {
                                OriginalTransactionId = id
                            });
                    }
                }

                break;
            }
            }

            return(base.OnSendInMessage(message));
        }
        private SubscriptionSecurityAllMessage CheckSubscription(ref Message message)
        {
            lock (_sync)
            {
                if (_toFlush.Count > 0)
                {
                    var toFlush = _toFlush.CopyAndClear();

                    this.AddDebugLog("Flush {0} suspended.", toFlush.Length);

                    foreach (var msg in toFlush)
                    {
                        RaiseNewOutMessage(msg);
                    }
                }

                if (_parents.Count == 0)
                {
                    return(null);
                }

                if (message is ISubscriptionIdMessage subscrMsg && message is ISecurityIdMessage secIdMsg)
                {
                    foreach (var parentId in subscrMsg.GetSubscriptionIds())
                    {
                        if (_parents.TryGetValue(parentId, out var parent))
                        {
                            // parent subscription has security id (not null)
                            if (parent.Origin.SecurityId == secIdMsg.SecurityId)
                            {
                                return(null);
                            }

                            SubscriptionSecurityAllMessage allMsg = null;

                            if (!parent.Child.TryGetValue(secIdMsg.SecurityId, out var child))
                            {
                                allMsg = new SubscriptionSecurityAllMessage();

                                parent.Origin.CopyTo(allMsg);

                                allMsg.ParentTransactionId = parentId;
                                allMsg.TransactionId       = TransactionIdGenerator.GetNextId();
                                allMsg.SecurityId          = secIdMsg.SecurityId;

                                child = new ChildSubscription(allMsg.TypedClone());
                                child.Subscribers.Add(allMsg.TransactionId, child.Origin);

                                parent.Child.Add(secIdMsg.SecurityId, child);

                                allMsg.LoopBack(this, MessageBackModes.Chain);
                                _allChilds.Add(allMsg.TransactionId, RefTuple.Create(parentId, SubscriptionStates.Stopped));

                                this.AddDebugLog("New ALL map: {0}/{1} TrId={2}-{3}", child.Origin.SecurityId, child.Origin.DataType2, allMsg.ParentTransactionId, allMsg.TransactionId);
                            }

                            //var subscriptionIds = subscrMsg.GetSubscriptionIds().Where(i => i != parentId).Concat(child.Subscribers.Cache);
                            subscrMsg.SetSubscriptionIds(child.Subscribers.CachedKeys);

                            if (!child.State.IsActive())
                            {
                                child.Suspended.Add(message);
                                message = null;

                                this.AddDebugLog("ALL suspended: {0}/{1}, cnt={2}", child.Origin.SecurityId, child.Origin.DataType2, child.Suspended.Count);
                            }

                            return(allMsg);
                        }
                    }
                }
            }

            return(null);
        }
Exemple #30
0
        private MarketDataMessage ProcessMarketDataRequest(MarketDataMessage message)
        {
            if (message.IsSubscribe)
            {
                if (!InnerAdapter.IsMarketDataTypeSupported(MarketDataTypes.OrderLog))
                {
                    return(message);
                }

                var isBuild = message.BuildMode == MarketDataBuildModes.Build && message.BuildFrom == MarketDataTypes.OrderLog;

                switch (message.DataType)
                {
                case MarketDataTypes.MarketDepth:
                {
                    if (isBuild || !InnerAdapter.IsMarketDataTypeSupported(message.DataType))
                    {
                        var secId = GetSecurityId(message.SecurityId);

                        IOrderLogMarketDepthBuilder builder = null;

                        if (InnerAdapter.IsSecurityRequired(DataType.OrderLog))
                        {
                            builder = InnerAdapter.CreateOrderLogMarketDepthBuilder(secId);
                        }

                        _subscriptionIds.Add(message.TransactionId, RefTuple.Create(secId, true, builder));

                        message          = (MarketDataMessage)message.Clone();
                        message.DataType = MarketDataTypes.OrderLog;

                        this.AddInfoLog("OL->MD subscribed {0}/{1}.", secId, message.TransactionId);
                    }

                    break;
                }

                case MarketDataTypes.Trades:
                {
                    if (isBuild || !InnerAdapter.IsMarketDataTypeSupported(message.DataType))
                    {
                        var secId = GetSecurityId(message.SecurityId);

                        _subscriptionIds.Add(message.TransactionId, RefTuple.Create(secId, false, (IOrderLogMarketDepthBuilder)null));

                        message          = (MarketDataMessage)message.Clone();
                        message.DataType = MarketDataTypes.OrderLog;

                        this.AddInfoLog("OL->TICK subscribed {0}/{1}.", secId, message.TransactionId);
                    }

                    break;
                }
                }
            }
            else
            {
                var tuple = _subscriptionIds.TryGetAndRemove(message.OriginalTransactionId);

                if (tuple != null)
                {
                    this.AddInfoLog("OL->{0} unsubscribed {1}/{2}.", tuple.Second ? "MD" : "TICK", tuple.First, message.OriginalTransactionId);
                }
            }

            return(message);
        }