コード例 #1
0
        private void EmulationConnectorOnNewSecurity(Security security)
        {
            var level1Info = new Level1ChangeMessage
            {
                SecurityId = security.ToSecurityId(),
                ServerTime = EmulationSettings.StartTime
            };

            if (security.PriceStep != null)
            {
                level1Info.TryAdd(Level1Fields.PriceStep, security.PriceStep.Value);
            }

            if (security.StepPrice != null)
            {
                level1Info.TryAdd(Level1Fields.StepPrice, security.StepPrice.Value);
            }

            level1Info.TryAdd(Level1Fields.MinPrice, security.MinPrice ?? 1m);
            level1Info.TryAdd(Level1Fields.MaxPrice, security.MaxPrice ?? 1000000m);

            if (security.MarginBuy != null)
            {
                level1Info.TryAdd(Level1Fields.MarginBuy, security.MarginBuy.Value);
            }

            if (security.MarginSell != null)
            {
                level1Info.TryAdd(Level1Fields.MarginSell, security.MarginSell.Value);
            }

            // fill level1 values
            EmulationConnector.SendInMessage(level1Info);
        }
コード例 #2
0
            public void UpdateData(Security sec, decimal price)
            {
                var ps = sec.PriceStep ?? 1;

                var msg = new Level1ChangeMessage
                {
                    SecurityId = sec.ToSecurityId(),
                    ServerTime = DateTimeOffset.Now,
                };

                if (RandomGen.GetBool())
                {
                    msg.Changes.TryAdd(Level1Fields.BestBidPrice, price - RandomGen.GetInt(1, 10) * ps);
                }

                if (RandomGen.GetBool())
                {
                    msg.Changes.TryAdd(Level1Fields.BestAskPrice, price + RandomGen.GetInt(1, 10) * ps);
                }

                foreach (var l1Subscriptions in _l1Subscriptions)
                {
                    _level1Received?.Invoke(l1Subscriptions, msg);
                }
            }
コード例 #3
0
 private void OnConnectorLevel1Received(Subscription subscription, Level1ChangeMessage message)
 {
     if (_subscriptions.ContainsKey(subscription))
     {
         Level1Received?.Invoke(subscription, message);
     }
 }
コード例 #4
0
            public QuoteChangeMessage Process(Level1ChangeMessage message)
            {
                var bidPrice = (decimal?)message.Changes.TryGetValue(Level1Fields.BestBidPrice);
                var askPrice = (decimal?)message.Changes.TryGetValue(Level1Fields.BestAskPrice);

                if (bidPrice == null && askPrice == null)
                {
                    return(null);
                }

                var bidVolume = (decimal?)message.Changes.TryGetValue(Level1Fields.BestBidVolume);
                var askVolume = (decimal?)message.Changes.TryGetValue(Level1Fields.BestAskVolume);

                if (_bidPrice == bidPrice && _askPrice == askPrice && _bidVolume == bidVolume && _askVolume == askVolume)
                {
                    return(null);
                }

                _bidPrice  = bidPrice;
                _askPrice  = askPrice;
                _bidVolume = bidVolume;
                _askVolume = askVolume;

                return(new QuoteChangeMessage
                {
                    SecurityId = SecurityId,
                    ServerTime = message.ServerTime,
                    LocalTime = message.LocalTime,
                    BuildFrom = DataType.Level1,
                    Bids = bidPrice == null?ArrayHelper.Empty <QuoteChange>() : new[] { new QuoteChange(bidPrice.Value, bidVolume ?? 0) },
                    Asks = askPrice == null?ArrayHelper.Empty <QuoteChange>() : new[] { new QuoteChange(askPrice.Value, askVolume ?? 0) },
                });
            }
コード例 #5
0
        private void ProcessLevel1Depth(Level1ChangeMessage message, decimal bestBidPrice, decimal bestBidVolume, decimal bestAskPrice, decimal bestAskVolume, List <ExecutionMessage> retVal)
        {
            if (message.LocalTime.Date == _lastDepthDate)
            {
                return;
            }

            QuoteChange ask = null;
            QuoteChange bid = null;

            if (bestAskPrice != 0 && bestAskVolume != 0)
            {
                ask = new QuoteChange(Sides.Sell, bestAskPrice, bestAskVolume);
            }

            if (bestBidPrice != 0 && bestBidVolume != 0)
            {
                bid = new QuoteChange(Sides.Buy, bestBidPrice, bestBidVolume);
            }

            if (ask == null && bid == null)
            {
                return;
            }

            retVal.AddRange(ProcessQuoteChange(message.LocalTime,
                                               bid != null ? new[] { bid } : ArrayHelper <QuoteChange> .EmptyArray,
                                               ask != null ? new[] { ask } : ArrayHelper <QuoteChange> .EmptyArray));
        }
コード例 #6
0
        /// <summary>
        /// Добавить первый уровень маркет-данных.
        /// </summary>
        /// <param name="security">Инструмент.</param>
        /// <param name="message">Первый уровень маркет-данных.</param>
        protected virtual void AddLevel1Change(Security security, Level1ChangeMessage message)
        {
            if (security == null)
            {
                throw new ArgumentNullException("security");
            }

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

            message = (Level1ChangeMessage)message.Clone();

            foreach (var change in message.Changes.ToArray())
            {
                if (!_task.Settings.SupportedLevel1Fields.Contains(change.Key))
                {
                    message.Changes.Remove(change.Key);
                }
            }

            if (message.Changes.Count > 0)
            {
                _level1Buffer.Add(security, message);
            }
        }
コード例 #7
0
            public QuoteChangeMessage Process(Level1ChangeMessage message)
            {
                if (HasDepth)
                {
                    return(null);
                }

                var bidPrice = (decimal?)message.Changes.TryGetValue(Level1Fields.BestBidPrice);
                var askPrice = (decimal?)message.Changes.TryGetValue(Level1Fields.BestAskPrice);

                if (bidPrice == null && askPrice == null)
                {
                    return(null);
                }

                var bidVolume = (decimal?)message.Changes.TryGetValue(Level1Fields.BestBidVolume);
                var askVolume = (decimal?)message.Changes.TryGetValue(Level1Fields.BestAskVolume);

                return(new QuoteChangeMessage
                {
                    SecurityId = _securityId,
                    ServerTime = message.ServerTime,
                    LocalTime = message.LocalTime,
                    IsByLevel1 = true,
                    Bids = bidPrice == null?Enumerable.Empty <QuoteChange>() : new[] { new QuoteChange(Sides.Buy, bidPrice.Value, bidVolume ?? 0) },
                    Asks = askPrice == null?Enumerable.Empty <QuoteChange>() : new[] { new QuoteChange(Sides.Sell, askPrice.Value, askVolume ?? 0) },
                });
            }
コード例 #8
0
        private void OnProcessLevel1(string[] data)
        {
            var f = Wrapper.FieldsLevel1;

            foreach (var row in data)
            {
                var cols    = row.ToColumns();
                var paperNo = f.PaperNo.GetValue(cols);
                var secId   = new SecurityId {
                    Native = paperNo
                };

                var l1Msg = new Level1ChangeMessage
                {
                    SecurityId = secId,
                    ServerTime = (f.LastUpdateDate.GetValue(cols).Date + f.LastUpdateTime.GetValue(cols).TimeOfDay).ApplyTimeZone(TimeHelper.Moscow)
                };

                l1Msg.Add(Level1Fields.State, f.TradingStatus.GetValue(cols));

                l1Msg.TryAdd(Level1Fields.MarginBuy, f.GoBuy.GetValue(cols));
                l1Msg.TryAdd(Level1Fields.MarginSell, f.GoSell.GetValue(cols));

                l1Msg.TryAdd(Level1Fields.OpenInterest, (decimal)f.OpenPosQty.GetValue(cols));

                var minPrice = f.MinDeal.GetValue(cols);
                var maxPrice = f.MaxDeal.GetValue(cols);

                l1Msg.TryAdd(Level1Fields.OpenPrice, f.OpenPrice.GetValue(cols));
                l1Msg.TryAdd(Level1Fields.ClosePrice, f.ClosePrice.GetValue(cols));
                l1Msg.TryAdd(Level1Fields.HighPrice, maxPrice);
                l1Msg.TryAdd(Level1Fields.LowPrice, minPrice);

                l1Msg.TryAdd(Level1Fields.BestBidPrice, f.Buy.GetValue(cols));
                l1Msg.TryAdd(Level1Fields.BestBidVolume, (decimal)f.BuyQty.GetValue(cols));
                l1Msg.TryAdd(Level1Fields.BestAskPrice, f.Sell.GetValue(cols));
                l1Msg.TryAdd(Level1Fields.BestAskVolume, (decimal)f.SellQty.GetValue(cols));

                l1Msg.TryAdd(Level1Fields.MinPrice, minPrice);
                l1Msg.TryAdd(Level1Fields.MaxPrice, maxPrice);

                l1Msg.TryAdd(Level1Fields.Multiplier, (decimal)f.LotSize.GetValue(cols));

                l1Msg.TryAdd(Level1Fields.ImpliedVolatility, f.Volatility.GetValue(cols));
                l1Msg.TryAdd(Level1Fields.TheorPrice, f.TheorPrice.GetValue(cols));

                l1Msg.TryAdd(Level1Fields.LastTradePrice, f.LastPrice.GetValue(cols));
                l1Msg.TryAdd(Level1Fields.LastTradeVolume, (decimal)f.LastQty.GetValue(cols));

                l1Msg.TryAdd(Level1Fields.PriceStep, f.PriceStep.GetValue(cols));

                l1Msg.TryAdd(Level1Fields.BidsVolume, (decimal)f.BuySQty.GetValue(cols));
                l1Msg.TryAdd(Level1Fields.BidsCount, f.BuyCount.GetValue(cols));
                l1Msg.TryAdd(Level1Fields.AsksVolume, (decimal)f.SellSQty.GetValue(cols));
                l1Msg.TryAdd(Level1Fields.AsksCount, f.SellCount.GetValue(cols));

                SendOutMessage(l1Msg);
            }
        }
コード例 #9
0
        private void OnQuotationsResponse(QuotationsResponse response)
        {
            foreach (var quote in response.Quotations)
            {
                var message = new Level1ChangeMessage
                {
                    SecurityId = new SecurityId {
                        Native = quote.SecId
                    },
                    ServerTime = SessionHolder.CurrentTime.Convert(TimeHelper.Moscow),
                };

                message.TryAdd(Level1Fields.AccruedCouponIncome, quote.AccruedIntValue);
                message.TryAdd(Level1Fields.OpenPrice, quote.Open);
                message.TryAdd(Level1Fields.HighPrice, quote.High);
                message.TryAdd(Level1Fields.LowPrice, quote.Low);
                message.TryAdd(Level1Fields.ClosePrice, quote.ClosePrice);
                message.TryAdd(Level1Fields.BidsCount, quote.BidsCount);
                message.TryAdd(Level1Fields.BidsVolume, (decimal?)quote.BidsVolume);
                message.TryAdd(Level1Fields.AsksCount, quote.AsksCount);
                message.TryAdd(Level1Fields.AsksVolume, (decimal?)quote.AsksVolume);
                message.TryAdd(Level1Fields.HighBidPrice, quote.HighBid);
                message.TryAdd(Level1Fields.LowAskPrice, quote.LowAsk);
                message.TryAdd(Level1Fields.Yield, quote.Yield);
                message.TryAdd(Level1Fields.MarginBuy, quote.BuyDeposit);
                message.TryAdd(Level1Fields.MarginSell, quote.SellDeposit);
                message.TryAdd(Level1Fields.HistoricalVolatility, quote.Volatility);
                message.TryAdd(Level1Fields.TheorPrice, quote.TheoreticalPrice);
                message.TryAdd(Level1Fields.Change, quote.Change);
                message.TryAdd(Level1Fields.Volume, (decimal?)quote.VolToday);
                message.TryAdd(Level1Fields.StepPrice, quote.PointCost);
                message.TryAdd(Level1Fields.OpenInterest, (decimal?)quote.OpenInterest);
                message.TryAdd(Level1Fields.TradesCount, quote.TradesCount);

                if (quote.Status != null)
                {
                    message.Add(Level1Fields.State, quote.Status.Value.FromTransaq());
                }


                // Transaq передает только изменения (например, передать только цену сделки, если объем при этом не изменился)

                message.TryAdd(Level1Fields.LastTradePrice, quote.LastTradePrice);
                message.TryAdd(Level1Fields.LastTradeVolume, (decimal?)quote.LastTradeVolume);

                if (quote.LastTradeTime != null)
                {
                    message.Add(Level1Fields.LastTradeTime, quote.LastTradeTime.Value.ApplyTimeZone(TimeHelper.Moscow));
                }

                message.TryAdd(Level1Fields.BestBidPrice, quote.BestBidPrice);
                message.TryAdd(Level1Fields.BestBidVolume, (decimal?)quote.BestBidVolume);

                message.TryAdd(Level1Fields.BestAskPrice, quote.BestAskPrice);
                message.TryAdd(Level1Fields.BestAskVolume, (decimal?)quote.BestAskVolume);

                SendOutMessage(message);
            }
        }
コード例 #10
0
            protected override void AddLevel1Change(Security security, Level1ChangeMessage message)
            {
                if (_settings.IsDownloadSecurityChangesHistory)
                {
                    return;
                }

                base.AddLevel1Change(security, message);
            }
コード例 #11
0
ファイル: WriteHelpers.cs プロジェクト: progmax/StockSharp
        private static string Level1ToString(Level1ChangeMessage level)
        {
            var sb = new StringBuilder();

            foreach (var kvp in level.Changes)
            {
                sb.Append($"{kvp.Key}:{kvp.Value};");
            }

            return($"{level.ServerTime};{level.SecurityId.SecurityCode};{sb}");
        }
コード例 #12
0
        private static Level1ChangeMessage ToLevel2(string value)
        {
            var parts = value.SplitByComma();

            var isBidValid = parts[10] == "T";
            var isAskValid = parts[11] == "T";

            if (!isBidValid && !isAskValid)
            {
                return(null);
            }

            var date = parts[7].ToDateTime("yyyy-MM-dd");

            var l1Msg = new Level1ChangeMessage
            {
                SecurityId = new SecurityId
                {
                    SecurityCode = parts[0],
                    BoardCode    = parts[1]
                },
            };

            // http://www.iqfeed.net/dev/api/docs/ConditionCodes.cfm
            l1Msg.Add(Level1Fields.IsSystem, parts[8] == "52");

            if (isAskValid)
            {
                l1Msg.ServerTime = date.Add(parts[9].To <TimeSpan>()).ApplyTimeZone(TimeHelper.Est);

                l1Msg
                .TryAdd(Level1Fields.BestAskPrice, parts[3].To <decimal>())
                .TryAdd(Level1Fields.BestAskVolume, parts[5].To <decimal>())
                .Add(Level1Fields.BestAskTime, l1Msg.ServerTime);
            }

            if (isBidValid)
            {
                var bidTime = date.Add(parts[6].To <TimeSpan>()).ApplyTimeZone(TimeHelper.Est);

                if (bidTime > l1Msg.ServerTime)
                {
                    l1Msg.ServerTime = bidTime;
                }

                l1Msg
                .TryAdd(Level1Fields.BestBidPrice, parts[2].To <decimal>())
                .TryAdd(Level1Fields.BestBidVolume, parts[4].To <decimal>())
                .Add(Level1Fields.BestBidTime, bidTime);
            }

            return(l1Msg);
        }
コード例 #13
0
        private void OnValuesChanged(Security security, IEnumerable <KeyValuePair <Level1Fields, object> > changes, DateTimeOffset serverTime, DateTime localTime)
        {
            var msg = new Level1ChangeMessage
            {
                SecurityId = security.ToSecurityId(),
                ServerTime = serverTime,
                LocalTime  = localTime,
            };

            msg.Changes.AddRange(changes);

            AddLevel1Change(security, msg);
        }
コード例 #14
0
        /// <summary>
        /// Преобразовать первый уровень маркет-данных.
        /// </summary>
        /// <param name="message">Первый уровень маркет-данных.</param>
        /// <returns>Поток <see cref="ExecutionMessage"/>.</returns>
        public IEnumerable <ExecutionMessage> ToExecutionLog(Level1ChangeMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            var retVal = new List <ExecutionMessage>();

            var bestBidPrice    = 0m;
            var bestBidVolume   = 0m;
            var bestAskPrice    = 0m;
            var bestAskVolume   = 0m;
            var lastTradePrice  = 0m;
            var lastTradeVolume = 0m;

            foreach (var change in message.Changes)
            {
                switch (change.Key)
                {
                case Level1Fields.LastTradePrice:
                    lastTradePrice = (decimal)change.Value;
                    break;

                case Level1Fields.LastTradeVolume:
                    lastTradeVolume = (decimal)change.Value;
                    break;

                case Level1Fields.BestBidPrice:
                    bestBidPrice = (decimal)change.Value;
                    break;

                case Level1Fields.BestBidVolume:
                    bestBidVolume = (decimal)change.Value;
                    break;

                case Level1Fields.BestAskPrice:
                    bestAskPrice = (decimal)change.Value;
                    break;

                case Level1Fields.BestAskVolume:
                    bestAskVolume = (decimal)change.Value;
                    break;
                }
            }

            ProcessLevel1Depth(message, bestBidPrice, bestBidVolume, bestAskPrice, bestAskVolume, retVal);
            ProcessLevel1Trade(message, lastTradePrice, lastTradeVolume, retVal);

            return(retVal);
        }
コード例 #15
0
        /// <summary>
        /// To process the message, containing market data.
        /// </summary>
        /// <param name="levelMsg">The message, containing market data.</param>
        public void ProcessLevel1(Level1ChangeMessage levelMsg)
        {
            var priceStep = levelMsg.Changes.TryGetValue(Level1Fields.PriceStep);

            if (priceStep != null)
            {
                PriceStep            = (decimal)priceStep;
                _recalcUnrealizedPnL = true;
            }

            var stepPrice = levelMsg.Changes.TryGetValue(Level1Fields.StepPrice);

            if (stepPrice != null)
            {
                StepPrice            = (decimal)stepPrice;
                _recalcUnrealizedPnL = true;
            }

            var lotMultiplier = levelMsg.Changes.TryGetValue(Level1Fields.Multiplier);

            if (lotMultiplier != null)
            {
                LotMultiplier        = (decimal)lotMultiplier;
                _recalcUnrealizedPnL = true;
            }

            var tradePrice = levelMsg.Changes.TryGetValue(Level1Fields.LastTradePrice);

            if (tradePrice != null)
            {
                TradePrice           = (decimal)tradePrice;
                _recalcUnrealizedPnL = true;
            }

            var bidPrice = levelMsg.Changes.TryGetValue(Level1Fields.BestBidPrice);

            if (bidPrice != null)
            {
                BidPrice             = (decimal)bidPrice;
                _recalcUnrealizedPnL = true;
            }

            var askPrice = levelMsg.Changes.TryGetValue(Level1Fields.BestAskPrice);

            if (askPrice != null)
            {
                AskPrice             = (decimal)askPrice;
                _recalcUnrealizedPnL = true;
            }
        }
コード例 #16
0
        private void SessionOnStiQuoteSnap(ref structSTIQuoteSnap structQuoteSnap)
        {
            var l1CngMsg = new Level1ChangeMessage
            {
                SecurityId = new SecurityId
                {
                    SecurityCode = structQuoteSnap.bstrSymbol,
                    BoardCode    = structQuoteSnap.bstrExch
                },
                ServerTime = structQuoteSnap.bstrUpdateTime.StrToTime(),
            };

            l1CngMsg.TryAdd(Level1Fields.BestAskPrice, (decimal)structQuoteSnap.fAskPrice);
            l1CngMsg.TryAdd(Level1Fields.BestBidPrice, (decimal)structQuoteSnap.fAskPrice);
            l1CngMsg.TryAdd(Level1Fields.BestAskVolume, (decimal)structQuoteSnap.nAskSize);
            l1CngMsg.TryAdd(Level1Fields.BestBidVolume, (decimal)structQuoteSnap.nBidSize);

            l1CngMsg.TryAdd(Level1Fields.OpenPrice, (decimal)structQuoteSnap.fOpenPrice);
            l1CngMsg.TryAdd(Level1Fields.HighPrice, (decimal)structQuoteSnap.fHighPrice);
            l1CngMsg.TryAdd(Level1Fields.LowPrice, (decimal)structQuoteSnap.fLowPrice);

            l1CngMsg.TryAdd(Level1Fields.LastTradePrice, (decimal)structQuoteSnap.fLastPrice);
            l1CngMsg.TryAdd(Level1Fields.LastTradeVolume, (decimal)structQuoteSnap.nLastSize);

            l1CngMsg.TryAdd(Level1Fields.OpenInterest, (decimal)structQuoteSnap.nOpenInterest);
            l1CngMsg.TryAdd(Level1Fields.Volume, (decimal)structQuoteSnap.nCumVolume);
            l1CngMsg.TryAdd(Level1Fields.VWAP, (decimal)structQuoteSnap.fVwap);

            l1CngMsg.TryAdd(Level1Fields.ClosePrice, (decimal)structQuoteSnap.fClosePrice);             // цена закрытия прошлого дня.

            SendOutMessage(l1CngMsg);

            if (_subscribedSecuritiesToTrade.Cache.Contains(structQuoteSnap.bstrSymbol) && structQuoteSnap.fLastPrice != 0)
            {
                var tickMsg = new ExecutionMessage
                {
                    ExecutionType = ExecutionTypes.Tick,
                    SecurityId    = new SecurityId {
                        SecurityCode = structQuoteSnap.bstrSymbol, BoardCode = structQuoteSnap.bstrExch
                    },
                    //TradeId = structQuoteSnap.,
                    TradePrice = (decimal)structQuoteSnap.fLastPrice,
                    Volume     = structQuoteSnap.nLastSize,
                    //OriginSide = action.ToSide(),
                    ServerTime = structQuoteSnap.bstrUpdateTime.StrToTime()
                };

                SendOutMessage(tickMsg);
            }
        }
コード例 #17
0
        /// <summary>
        /// To convert first level of market data.
        /// </summary>
        /// <param name="message">Level 1.</param>
        /// <returns>Stream <see cref="Message"/>.</returns>
        public IEnumerable <Message> ToExecutionLog(Level1ChangeMessage message)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            if (message.IsContainsTick())
            {
                yield return(message.ToTick());
            }

            if (message.IsContainsQuotes() && !HasDepth(message.LocalTime))
            {
                var prevBidPrice  = _prevBidPrice;
                var prevBidVolume = _prevBidVolume;
                var prevAskPrice  = _prevAskPrice;
                var prevAskVolume = _prevAskVolume;

                _prevBidPrice  = (decimal?)message.Changes.TryGetValue(Level1Fields.BestBidPrice) ?? _prevBidPrice;
                _prevBidVolume = (decimal?)message.Changes.TryGetValue(Level1Fields.BestBidVolume) ?? _prevBidVolume;
                _prevAskPrice  = (decimal?)message.Changes.TryGetValue(Level1Fields.BestAskPrice) ?? _prevAskPrice;
                _prevAskVolume = (decimal?)message.Changes.TryGetValue(Level1Fields.BestAskVolume) ?? _prevAskVolume;

                if (_prevBidPrice == 0)
                {
                    _prevBidPrice = null;
                }

                if (_prevAskPrice == 0)
                {
                    _prevAskPrice = null;
                }

                if (prevBidPrice == _prevBidPrice && prevBidVolume == _prevBidVolume && prevAskPrice == _prevAskPrice && prevAskVolume == _prevAskVolume)
                {
                    yield break;
                }

                yield return(new QuoteChangeMessage
                {
                    SecurityId = message.SecurityId,
                    LocalTime = message.LocalTime,
                    ServerTime = message.ServerTime,
                    Bids = _prevBidPrice == null?ArrayHelper.Empty <QuoteChange>() : new[] { new QuoteChange(_prevBidPrice.Value, _prevBidVolume ?? 0) },
                    Asks = _prevAskPrice == null?ArrayHelper.Empty <QuoteChange>() : new[] { new QuoteChange(_prevAskPrice.Value, _prevAskVolume ?? 0) },
                });
            }
        }
コード例 #18
0
ファイル: WriteHelpers.cs プロジェクト: zhangxia85/StockSharp
        private static string Level1ToString(Level1ChangeMessage level)
        {
            var sb = new StringBuilder();

            foreach (var kvp in level.Changes)
            {
                sb.Append(string.Format("{0}:{1};", kvp.Key, kvp.Value));
            }

            return(string.Format("{0};{1};{2}",
                                 level.ServerTime,
                                 level.SecurityId.SecurityCode,
                                 sb
                                 ));
        }
コード例 #19
0
        private void OnSecInfoResponse(SecInfoResponse response)
        {
            var securityId = new SecurityId
            {
                Native       = response.SecId,
                SecurityCode = response.SecCode,
                BoardCode    = _boards[response.Market],
            };

            SendOutMessage(new SecurityMessage
            {
                SecurityId = securityId,
                ExpiryDate = response.MatDate == null ? (DateTimeOffset?)null : response.MatDate.Value.ApplyTimeZone(TimeHelper.Moscow),
                OptionType = response.PutCall == null ? (OptionTypes?)null : response.PutCall.Value.FromTransaq(),
            });

            var l1Msg = new Level1ChangeMessage
            {
                SecurityId = new SecurityId {
                    Native = response.SecId
                },
                ServerTime = SessionHolder.CurrentTime.Convert(TimeHelper.Moscow),
            };

            l1Msg.TryAdd(Level1Fields.MinPrice, response.MinPrice);
            l1Msg.TryAdd(Level1Fields.MaxPrice, response.MaxPrice);

            var marginBuy = response.BuyDeposit;

            if (marginBuy == null || marginBuy == 0m)
            {
                marginBuy = response.BgoBuy;
            }

            var marginSell = response.SellDeposit;

            if (marginSell == null || marginSell == 0m)
            {
                marginSell = response.BgoC;
            }

            l1Msg.TryAdd(Level1Fields.MarginBuy, marginBuy);
            l1Msg.TryAdd(Level1Fields.MarginSell, marginSell);

            SendOutMessage(l1Msg);
        }
コード例 #20
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Level1ChangeCandleBuilderSourceValue"/>.
        /// </summary>
        /// <param name="message">The message containing the level1 market data.</param>
        /// <param name="field">Level one market-data field, which is used as an candle value.</param>
        public Level1ChangeCandleBuilderSourceValue(Level1ChangeMessage message, Level1Fields field)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            Level1Change = message;
            Field        = field;

            _volume = null;

            switch (field)
            {
            case Level1Fields.BestBidPrice:
            case Level1Fields.BestAskPrice:
            {
                var price = GetValue(message, field);

                if (price != null)
                {
                    _price = price.Value;
                }

                break;
            }

            case Level1Fields.SpreadMiddle:
            {
                var bid = GetValue(message, Level1Fields.BestBidPrice);
                var ask = GetValue(message, Level1Fields.BestAskPrice);

                if (bid != null && ask != null)
                {
                    _price = (ask.Value + bid.Value) / 2;
                }

                break;
            }

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #21
0
        private void OnSessionMarketDataChanged(OrderBookEvent orderBookEvent)
        {
            var time  = TimeHelper.GregorianStart.AddMilliseconds(orderBookEvent.Timestamp).ApplyTimeZone(TimeZoneInfo.Utc);
            var secId = new SecurityId {
                Native = orderBookEvent.InstrumentId
            };

            var l1Msg = new Level1ChangeMessage
            {
                ServerTime = time,
                SecurityId = secId,
            };

            if (orderBookEvent.HasMarketClosePrice)
            {
                l1Msg.Add(Level1Fields.ClosePrice, orderBookEvent.MktClosePrice);
            }

            if (orderBookEvent.HasDailyHighestTradedPrice)
            {
                l1Msg.Add(Level1Fields.HighPrice, orderBookEvent.DailyHighestTradedPrice);
            }

            if (orderBookEvent.HasDailyLowestTradedPrice)
            {
                l1Msg.Add(Level1Fields.LowPrice, orderBookEvent.DailyLowestTradedPrice);
            }

            if (orderBookEvent.HasLastTradedPrice)
            {
                l1Msg.Add(Level1Fields.LastTradePrice, orderBookEvent.LastTradedPrice);
            }

            SendOutMessage(l1Msg);

            SendOutMessage(new QuoteChangeMessage
            {
                SecurityId = secId,
                Bids       = orderBookEvent.BidPrices.Select(p => new QuoteChange(Sides.Buy, p.Price, p.Quantity)),
                Asks       = orderBookEvent.AskPrices.Select(p => new QuoteChange(Sides.Sell, p.Price, p.Quantity)),
                ServerTime = time
            });
        }
コード例 #22
0
        private void TraderOnValuesChanged(Security security, IEnumerable <KeyValuePair <Level1Fields, object> > changes, DateTimeOffset serverTime, DateTime localTime)
        {
            var wnd = _level1Windows.TryGetValue(security);

            if (wnd == null)
            {
                return;
            }

            var msg = new Level1ChangeMessage
            {
                SecurityId = security.ToSecurityId(),
                ServerTime = serverTime,
                LocalTime  = localTime
            };

            msg.Changes.AddRange(changes);
            wnd.Level1Grid.Messages.Add(msg);
        }
コード例 #23
0
ファイル: PnLQueue.cs プロジェクト: trevor5gs/StockSharp
        /// <summary>
        /// To process the message, containing market data.
        /// </summary>
        /// <param name="levelMsg">The message, containing market data.</param>
        public void ProcessLevel1(Level1ChangeMessage levelMsg)
        {
            var priceStep = levelMsg.Changes.TryGetValue(Level1Fields.PriceStep);

            if (priceStep != null)
            {
                PriceStep      = (decimal)priceStep;
                _unrealizedPnL = null;
            }

            var stepPrice = levelMsg.Changes.TryGetValue(Level1Fields.StepPrice);

            if (stepPrice != null)
            {
                StepPrice      = (decimal)stepPrice;
                _unrealizedPnL = null;
            }

            var tradePrice = levelMsg.Changes.TryGetValue(Level1Fields.LastTradePrice);

            if (tradePrice != null)
            {
                TradePrice     = (decimal)tradePrice;
                _unrealizedPnL = null;
            }

            var bidPrice = levelMsg.Changes.TryGetValue(Level1Fields.BestBidPrice);

            if (bidPrice != null)
            {
                BidPrice       = (decimal)bidPrice;
                _unrealizedPnL = null;
            }

            var askPrice = levelMsg.Changes.TryGetValue(Level1Fields.BestAskPrice);

            if (askPrice != null)
            {
                AskPrice       = (decimal)askPrice;
                _unrealizedPnL = null;
            }
        }
コード例 #24
0
		private void ProcessLevel1ChangeMessage(Level1ChangeMessage message)
		{
			var security = LookupSecurity(message.SecurityId);

			if (UpdateSecurityByLevel1)
			{
				security.ApplyChanges(message);
				RaiseSecurityChanged(security);
			}

			var values = GetSecurityValues(security);

			lock (values.SyncRoot)
			{
				foreach (var change in message.Changes)
					values[(int)change.Key] = change.Value;	
			}

			RaiseValuesChanged(security, message.Changes, message.ServerTime, message.LocalTime);
		}
コード例 #25
0
		private void ProcessLevel1ChangeMessage(Level1ChangeMessage message)
		{
			var security = LookupSecurity(message.SecurityId);

			if (UpdateSecurityByLevel1)
			{
				security.ApplyChanges(message);
				RaiseSecurityChanged(security);
			}

			var values = GetSecurityValues(security);

			lock (values.SyncRoot)
			{
				foreach (var change in message.Changes)
					values[(int)change.Key] = change.Value;	
			}

			RaiseValuesChanged(security, message.Changes, message.ServerTime, message.LocalTime);

			if (CreateDepthFromLevel1)
			{
				// генерация стакана из Level1
				var quoteMsg = GetBuilder(message.SecurityId).Process(message);

				if (quoteMsg != null)
				{
					ProcessQuotesMessage(security, quoteMsg, true);
					CreateAssociatedSecurityQuotes(quoteMsg);
				}
			}

			if (CreateAssociatedSecurity && !IsAssociated(message.SecurityId.BoardCode))
			{
				// обновление BestXXX для ALL из конкретных тикеров
				var clone = (Level1ChangeMessage)message.Clone();
				clone.SecurityId = CreateAssociatedId(clone.SecurityId);
				ProcessLevel1ChangeMessage(clone);
			}
		}
コード例 #26
0
        private void FlushQuotes(SecurityId secId)
        {
            var quotes = _quotes.TryGetValue(secId);

            if (quotes == null)
            {
                return;
            }

            _quotes.Remove(secId);

            foreach (var pair in quotes.CachedPairs)
            {
                var message = new Level1ChangeMessage
                {
                    SecurityId = secId,
                    ServerTime = pair.Key
                };

                var bid = pair.Value.First;

                if (bid != null)
                {
                    message
                    .TryAdd(Level1Fields.BestBidPrice, bid.Price.ToDecimal())
                    .TryAdd(Level1Fields.BestBidVolume, (decimal)bid.Size);
                }

                var ask = pair.Value.Second;

                if (ask != null)
                {
                    message
                    .TryAdd(Level1Fields.BestAskPrice, ask.Price.ToDecimal())
                    .TryAdd(Level1Fields.BestAskVolume, (decimal)ask.Size);
                }

                SendOutMessage(message);
            }
        }
コード例 #27
0
        private void SessionOnStiGreeksUpdate(ref structSTIGreeksUpdate structGreeksUpdate)
        {
            var message = new Level1ChangeMessage
            {
                SecurityId = new SecurityId
                {
                    SecurityCode = structGreeksUpdate.bstrSymbol,
                    BoardCode    = AssociatedBoardCode,
                },
                ServerTime = CurrentTime,
            };

            message.TryAdd(Level1Fields.Delta, (decimal)structGreeksUpdate.fDelta);
            message.TryAdd(Level1Fields.Gamma, (decimal)structGreeksUpdate.fGamma);
            message.TryAdd(Level1Fields.Theta, (decimal)structGreeksUpdate.fTheta);
            message.TryAdd(Level1Fields.Vega, (decimal)structGreeksUpdate.fVega);
            message.TryAdd(Level1Fields.Rho, (decimal)structGreeksUpdate.fRho);
            message.TryAdd(Level1Fields.TheorPrice, (decimal)structGreeksUpdate.fTheoPrice);
            message.TryAdd(Level1Fields.ImpliedVolatility, (decimal)structGreeksUpdate.fImpVol);

            SendOutMessage(message);
        }
コード例 #28
0
        private void ProcessLevel1Trade(Level1ChangeMessage message, decimal lastTradePrice, decimal lastTradeVolume, List <ExecutionMessage> retVal)
        {
            if (message.LocalTime.Date == _lastTradeDate)
            {
                return;
            }

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

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

            retVal.AddRange(ProcessExecution(exec));
        }
コード例 #29
0
		private void OnQuotationsResponse(QuotationsResponse response)
		{
			foreach (var quote in response.Quotations)
			{
				var message = new Level1ChangeMessage
				{
					SecurityId = new SecurityId { Native = quote.SecId },
					ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
				};

				message.TryAdd(Level1Fields.AccruedCouponIncome, quote.AccruedIntValue);
				message.TryAdd(Level1Fields.OpenPrice, quote.Open);
				message.TryAdd(Level1Fields.HighPrice, quote.High);
				message.TryAdd(Level1Fields.LowPrice, quote.Low);
				message.TryAdd(Level1Fields.ClosePrice, quote.ClosePrice);
				message.TryAdd(Level1Fields.BidsCount, quote.BidsCount);
				message.TryAdd(Level1Fields.BidsVolume, (decimal?)quote.BidsVolume);
				message.TryAdd(Level1Fields.AsksCount, quote.AsksCount);
				message.TryAdd(Level1Fields.AsksVolume, (decimal?)quote.AsksVolume);
				message.TryAdd(Level1Fields.HighBidPrice, quote.HighBid);
				message.TryAdd(Level1Fields.LowAskPrice, quote.LowAsk);
				message.TryAdd(Level1Fields.Yield, quote.Yield);
				message.TryAdd(Level1Fields.MarginBuy, quote.BuyDeposit);
				message.TryAdd(Level1Fields.MarginSell, quote.SellDeposit);
				message.TryAdd(Level1Fields.HistoricalVolatility, quote.Volatility);
				message.TryAdd(Level1Fields.TheorPrice, quote.TheoreticalPrice);
				message.TryAdd(Level1Fields.Change, quote.Change);
				message.TryAdd(Level1Fields.Volume, (decimal?)quote.VolToday);
				message.TryAdd(Level1Fields.StepPrice, quote.PointCost);
				message.TryAdd(Level1Fields.OpenInterest, (decimal?)quote.OpenInterest);
				message.TryAdd(Level1Fields.TradesCount, quote.TradesCount);

				if (quote.Status != null)
					message.Add(Level1Fields.State, quote.Status.Value.FromTransaq());

				
				// Transaq передает только изменения (например, передать только цену сделки, если объем при этом не изменился)

				message.TryAdd(Level1Fields.LastTradePrice, quote.LastTradePrice);
				message.TryAdd(Level1Fields.LastTradeVolume, (decimal?)quote.LastTradeVolume);

				if (quote.LastTradeTime != null)
					message.Add(Level1Fields.LastTradeTime, quote.LastTradeTime.Value.ToDto());

				message.TryAdd(Level1Fields.BestBidPrice, quote.BestBidPrice);
				message.TryAdd(Level1Fields.BestBidVolume, (decimal?)quote.BestBidVolume);

				message.TryAdd(Level1Fields.BestAskPrice, quote.BestAskPrice);
				message.TryAdd(Level1Fields.BestAskVolume, (decimal?)quote.BestAskVolume);

				SendOutMessage(message);
			}
		}
コード例 #30
0
		private void OnProcessSecurities(long transactionId, string[] data)
		{
			var f = Wrapper.FieldsSecurities;
			var secMessages = new List<Tuple<int, SecurityMessage>>();
			var level1Messages = new List<Level1ChangeMessage>();

			foreach (var row in data)
			{
				var cols = row.ToColumns();

				var secType = f.ATCode.GetValue(cols);
				if(secType == null)
					continue;

				var paperNo = f.PaperNo.GetValue(cols);
				var code = f.PaperCode.GetValue(cols);
				var name = f.AnsiName.GetValue(cols);
				var time = f.ILastUpdate.GetValue(cols);

				_securityCodes[paperNo] = code;

				var secId = new SecurityId
				{
					Native = paperNo,
					SecurityCode = code,
					BoardCode = this.GetBoardCode(f.PlaceCode.GetValue(cols))
				};

				var msg = new SecurityMessage
				{
					SecurityId = secId,
					Name = name,
					ShortName = name,
					SecurityType = secType,
					Multiplier = f.LotSize.GetValue(cols),
					PriceStep = f.PriceStep.GetValue(cols),
					//LocalTime = time,
					Currency = f.CurrCode.GetValue(cols),
					Strike = f.Strike.GetValue(cols)
				};

				if(msg.SecurityType == SecurityTypes.Option || msg.SecurityType == SecurityTypes.Future)
					msg.ExpiryDate = f.MatDate.GetValue(cols).ApplyTimeZone(TimeHelper.Moscow);

				if (msg.SecurityType == SecurityTypes.Option)
				{
					msg.OptionType = f.ATCode.GetStrValue(cols).ATCodeToOptionType();
					msg.Strike = f.Strike.GetValue(cols);
				}

				secMessages.Add(Tuple.Create(f.BasePaperNo.GetValue(cols), msg));

				var l1Msg = new Level1ChangeMessage
				{
					SecurityId = secId,
					ServerTime = time.ApplyTimeZone(TimeHelper.Moscow)
				};

				l1Msg.TryAdd(Level1Fields.MarginBuy, f.GoBuy.GetValue(cols));
				l1Msg.TryAdd(Level1Fields.MarginSell, f.GoSell.GetValue(cols));
				l1Msg.TryAdd(Level1Fields.StepPrice, f.PriceStepCost.GetValue(cols));

				level1Messages.Add(l1Msg);
			}

			secMessages.Where(t => t.Item2.SecurityType == SecurityTypes.Option).ForEach(t => 
				t.Item2.UnderlyingSecurityCode = _securityCodes.TryGetValue(t.Item1));

			secMessages.ForEach(t => SendOutMessage(t.Item2));
			level1Messages.ForEach(SendOutMessage);

			if (transactionId > 0)
			{
				SendOutMessage(new SecurityLookupResultMessage
				{
					OriginalTransactionId = transactionId,
				});
			}
		}
コード例 #31
0
		private static Level1ChangeMessage ToLevel2(string value)
		{
			var parts = value.SplitByComma();

			var isBidValid = parts[10] == "T";
			var isAskValid = parts[11] == "T";

			if (!isBidValid && !isAskValid)
				return null;

			var date = parts[7].ToDateTime("yyyy-MM-dd");

			var l1Msg = new Level1ChangeMessage
			{
				SecurityId = new SecurityId
				{
					SecurityCode = parts[0],
					BoardCode = parts[1]
				},
			};

			// http://www.iqfeed.net/dev/api/docs/ConditionCodes.cfm
			l1Msg.Add(Level1Fields.IsSystem, parts[8] == "52");

			if (isAskValid)
			{
				l1Msg.ServerTime = date.Add(parts[9].To<TimeSpan>()).ApplyTimeZone(TimeHelper.Est);

				l1Msg
					.TryAdd(Level1Fields.BestAskPrice, parts[3].To<decimal>())
					.TryAdd(Level1Fields.BestAskVolume, parts[5].To<decimal>())
					.Add(Level1Fields.BestAskTime, l1Msg.ServerTime);
			}

			if (isBidValid)
			{
				var bidTime = date.Add(parts[6].To<TimeSpan>()).ApplyTimeZone(TimeHelper.Est);

				if (bidTime > l1Msg.ServerTime)
					l1Msg.ServerTime = bidTime;

				l1Msg
					.TryAdd(Level1Fields.BestBidPrice, parts[2].To<decimal>())
					.TryAdd(Level1Fields.BestBidVolume, parts[4].To<decimal>())
					.Add(Level1Fields.BestBidTime, bidTime);
			}

			return l1Msg;
		}
コード例 #32
0
		private void StartButtonOnClick(object sender, RoutedEventArgs e)
		{
			_logManager.Sources.Clear();
			_bufferedChart.ClearAreas();

			Curve.Clear();
			PositionCurve.Clear();

			if (HistoryPathTextBox.Text.IsEmpty() || !Directory.Exists(HistoryPathTextBox.Text))
			{
				MessageBox.Show("Wrong path.");
				return;
			}

			if (_connector != null && _connector.State != EmulationStates.Stopped)
			{
				MessageBox.Show("Already launched.");
				return;
			}

			if (Composition == null)
			{
				MessageBox.Show("No strategy selected.");
				return;
			}

			var secGen = new SecurityIdGenerator();
			var secIdParts = secGen.Split(SecusityTextBox.Text);
			var secCode = secIdParts.SecurityCode;
			var board = ExchangeBoard.GetOrCreateBoard(secIdParts.BoardCode);
			var timeFrame = (TimeSpan)TimeFrameComboBox.SelectedItem;
			var useCandles = (string)MarketDataTypeComboBox.SelectedItem != "Ticks";

			// create test security
			var security = new Security
			{
				Id = SecusityTextBox.Text, // sec id has the same name as folder with historical data
				Code = secCode,
				Board = board,
			};

			// storage to historical data
			var storageRegistry = new StorageRegistry
			{
				// set historical path
				DefaultDrive = new LocalMarketDataDrive(HistoryPathTextBox.Text)
			};

			var startTime = ((DateTime)FromDatePicker.Value).ChangeKind(DateTimeKind.Utc);
			var stopTime = ((DateTime)ToDatePicke.Value).ChangeKind(DateTimeKind.Utc);

			// ProgressBar refresh step
			var progressStep = ((stopTime - startTime).Ticks / 100).To<TimeSpan>();

			// set ProgressBar bounds
			TicksAndDepthsProgress.Value = 0;
			TicksAndDepthsProgress.Maximum = 100;

			var level1Info = new Level1ChangeMessage
			{
				SecurityId = security.ToSecurityId(),
				ServerTime = startTime,
			}
			.TryAdd(Level1Fields.PriceStep, secIdParts.SecurityCode == "RIZ2" ? 10m : 1)
			.TryAdd(Level1Fields.StepPrice, 6m)
			.TryAdd(Level1Fields.MinPrice, 10m)
			.TryAdd(Level1Fields.MaxPrice, 1000000m)
			.TryAdd(Level1Fields.MarginBuy, 10000m)
			.TryAdd(Level1Fields.MarginSell, 10000m);

			// test portfolio
			var portfolio = new Portfolio
			{
				Name = "test account",
				BeginValue = 1000000,
			};

			// create backtesting connector
			_connector = new HistoryEmulationConnector(
				new[] { security },
				new[] { portfolio })
			{
				EmulationAdapter =
				{
					Emulator =
					{
						Settings =
						{
							// match order if historical price touched our limit order price. 
							// It is terned off, and price should go through limit order price level
							// (more "severe" test mode)
							MatchOnTouch = false,
						}
					}
				},

				UseExternalCandleSource = useCandles,

				HistoryMessageAdapter =
				{
					StorageRegistry = storageRegistry,

					// set history range
					StartDate = startTime,
					StopDate = stopTime,
				},

				// set market time freq as time frame
				MarketTimeChangedInterval = timeFrame,
			};

			//((ILogSource)_connector).LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info;

			_logManager.Sources.Add(_connector);

			var candleManager = !useCandles
					? new CandleManager(new TradeCandleBuilderSourceEx(_connector))
					: new CandleManager(_connector);

			// create strategy based on 80 5-min и 10 5-min
			var strategy = new DiagramStrategy
			{
				Volume = 1,
				Portfolio = portfolio,
				Security = security,
				Connector = _connector,
				//LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info,

				Composition = Composition,

				// by default interval is 1 min,
				// it is excessively for time range with several months
				UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To<TimeSpan>()
			};

			strategy.SetChart(_bufferedChart);
			strategy.SetCandleManager(candleManager);

			_logManager.Sources.Add(strategy);

			strategy.OrderRegistering += OnStrategyOrderRegistering;
			strategy.OrderReRegistering += OnStrategyOrderReRegistering;
			strategy.OrderRegisterFailed += OnStrategyOrderRegisterFailed;
			
			strategy.StopOrderRegistering += OnStrategyOrderRegistering;
			strategy.StopOrderReRegistering += OnStrategyOrderReRegistering;
			strategy.StopOrderRegisterFailed += OnStrategyOrderRegisterFailed;

			strategy.NewMyTrades += OnStrategyNewMyTrade;

			var pnlCurve = Curve.CreateCurve(LocalizedStrings.PnL + " " + strategy.Name, Colors.DarkGreen, EquityCurveChartStyles.Area);
			var unrealizedPnLCurve = Curve.CreateCurve(LocalizedStrings.PnLUnreal + strategy.Name, Colors.Black);
			var commissionCurve = Curve.CreateCurve(LocalizedStrings.Str159 + " " + strategy.Name, Colors.Red, EquityCurveChartStyles.DashedLine);
			
			strategy.PnLChanged += () =>
			{
				var pnl = new EquityData
				{
					Time = strategy.CurrentTime,
					Value = strategy.PnL - strategy.Commission ?? 0
				};

				var unrealizedPnL = new EquityData
				{
					Time = strategy.CurrentTime,
					Value = strategy.PnLManager.UnrealizedPnL
				};

				var commission = new EquityData
				{
					Time = strategy.CurrentTime,
					Value = strategy.Commission ?? 0
				};

				pnlCurve.Add(pnl);
				unrealizedPnLCurve.Add(unrealizedPnL);
				commissionCurve.Add(commission);
			};

			var posItems = PositionCurve.CreateCurve(strategy.Name, Colors.DarkGreen);

			strategy.PositionChanged += () => posItems.Add(new EquityData { Time = strategy.CurrentTime, Value = strategy.Position });

			_connector.NewSecurities += securities =>
			{
				if (securities.All(s => s != security))
					return;

				// fill level1 values
				_connector.SendInMessage(level1Info);

				//_connector.RegisterMarketDepth(security);
				if (!useCandles)
					_connector.RegisterTrades(security);

				// start strategy before emulation started
				strategy.Start();

				// start historical data loading when connection established successfully and all data subscribed
				_connector.Start();
			};

			var nextTime = startTime + progressStep;

			// handle historical time for update ProgressBar
			_connector.MarketTimeChanged += d =>
			{
				if (_connector.CurrentTime < nextTime && _connector.CurrentTime < stopTime)
					return;

				var steps = (_connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1;
				nextTime = startTime + (steps * progressStep.Ticks).To<TimeSpan>();
				this.GuiAsync(() => TicksAndDepthsProgress.Value = steps);
			};

			_connector.StateChanged += () =>
			{
				switch (_connector.State)
				{
					case EmulationStates.Stopped:
						strategy.Stop();
						SetIsEnabled(false);

						this.GuiAsync(() =>
						{
							if (_connector.IsFinished)
							{
								TicksAndDepthsProgress.Value = TicksAndDepthsProgress.Maximum;
								MessageBox.Show("Done.");
							}
							else
								MessageBox.Show("Cancelled.");
						});
						break;
					case EmulationStates.Started:
						SetIsEnabled(true);
						break;
				}
			};

			TicksAndDepthsProgress.Value = 0;

			// raise NewSecurities and NewPortfolio for full fill strategy properties
			_connector.Connect();

			// 1 cent commission for trade
			_connector.SendInMessage(new CommissionRuleMessage
			{
				Rule = new CommissionPerTradeRule { Value = 0.01m }
			});
		}
コード例 #33
0
		private void OnSecInfoResponse(SecInfoResponse response)
		{
			var securityId = new SecurityId
			{
				Native = response.SecId,
				SecurityCode = response.SecCode,
				BoardCode = _boards[response.Market],
			};

			SendOutMessage(new SecurityMessage
			{
				SecurityId = securityId,
				ExpiryDate = response.MatDate?.ApplyTimeZone(TimeHelper.Moscow),
				OptionType = response.PutCall?.FromTransaq(),
			});

			var l1Msg = new Level1ChangeMessage
			{
				SecurityId = new SecurityId { Native = response.SecId },
				ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
			};

			l1Msg.TryAdd(Level1Fields.MinPrice, response.MinPrice);
			l1Msg.TryAdd(Level1Fields.MaxPrice, response.MaxPrice);

			var marginBuy = response.BuyDeposit;

			if (marginBuy == null || marginBuy == 0m)
				marginBuy = response.BgoBuy;

			var marginSell = response.SellDeposit;

			if (marginSell == null || marginSell == 0m)
				marginSell = response.BgoC;

			l1Msg.TryAdd(Level1Fields.MarginBuy, marginBuy);
			l1Msg.TryAdd(Level1Fields.MarginSell, marginSell);

			SendOutMessage(l1Msg);
		}
コード例 #34
0
		private void StartBtnClick(object sender, RoutedEventArgs e)
		{
			if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text))
			{
				MessageBox.Show(this, LocalizedStrings.Str3014);
				return;
			}

			if (Math.Abs(TestingProcess.Value - 0) > double.Epsilon)
			{
				MessageBox.Show(this, LocalizedStrings.Str3015);
				return;
			}

			var logManager = new LogManager();
			var fileLogListener = new FileLogListener("sample.log");
			logManager.Listeners.Add(fileLogListener);

			// SMA periods
			var periods = new[]
			{
				new Tuple<int, int, Color>(80, 10, Colors.DarkGreen),
				new Tuple<int, int, Color>(70, 8, Colors.Red),
				new Tuple<int, int, Color>(60, 6, Colors.DarkBlue)
			};

			// storage to historical data
			var storageRegistry = new StorageRegistry
			{
				// set historical path
				DefaultDrive = new LocalMarketDataDrive(HistoryPath.Text)
			};

			var timeFrame = TimeSpan.FromMinutes(5);

			// create test security
			var security = new Security
			{
				Id = "RIZ2@FORTS", // sec id has the same name as folder with historical data
				Code = "RIZ2",
				Name = "RTS-12.12",
				Board = ExchangeBoard.Forts,
			};

			var startTime = new DateTime(2012, 10, 1);
			var stopTime = new DateTime(2012, 10, 31);

			var level1Info = new Level1ChangeMessage
			{
				SecurityId = security.ToSecurityId(),
				ServerTime = startTime,
			}
			.TryAdd(Level1Fields.PriceStep, 10m)
			.TryAdd(Level1Fields.StepPrice, 6m)
			.TryAdd(Level1Fields.MinPrice, 10m)
			.TryAdd(Level1Fields.MaxPrice, 1000000m)
			.TryAdd(Level1Fields.MarginBuy, 10000m)
			.TryAdd(Level1Fields.MarginSell, 10000m);

			// test portfolio
			var portfolio = new Portfolio
			{
				Name = "test account",
				BeginValue = 1000000,
			};

			// create backtesting connector
			var batchEmulation = new BatchEmulation(new[] { security }, new[] { portfolio }, storageRegistry)
			{
				EmulationSettings =
				{
					MarketTimeChangedInterval = timeFrame,
					StartTime = startTime,
					StopTime = stopTime,

					// count of parallel testing strategies
					BatchSize = periods.Length,
				}
			};

			// handle historical time for update ProgressBar
			batchEmulation.ProgressChanged += (curr, total) => this.GuiAsync(() => TestingProcess.Value = total);

			batchEmulation.StateChanged += (oldState, newState) =>
			{
				if (batchEmulation.State != EmulationStates.Stopped)
					return;

				this.GuiAsync(() =>
				{
					if (batchEmulation.IsFinished)
					{
						TestingProcess.Value = TestingProcess.Maximum;
						MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
					}
					else
						MessageBox.Show(this, LocalizedStrings.cancelled);
				});
			};

			// получаем подключение для эмуляции
			var connector = batchEmulation.EmulationConnector;

			logManager.Sources.Add(connector);

			connector.NewSecurities += securities =>
			{
				if (securities.All(s => s != security))
					return;

				// fill level1 values
				connector.SendInMessage(level1Info);

				connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security))
				{
					// order book freq refresh is 1 sec
					Interval = TimeSpan.FromSeconds(1),
				});
			};

			TestingProcess.Maximum = 100;
			TestingProcess.Value = 0;

			_startEmulationTime = DateTime.Now;

			var strategies = periods
				.Select(period =>
				{
					var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

					// create strategy based SMA
					var strategy = new SmaStrategy(series, new SimpleMovingAverage { Length = period.Item1 }, new SimpleMovingAverage { Length = period.Item2 })
					{
						Volume = 1,
						Security = security,
						Portfolio = portfolio,
						Connector = connector,

						// by default interval is 1 min,
						// it is excessively for time range with several months
						UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To<TimeSpan>()
					};

					strategy.SetCandleManager(new CandleManager(connector));

					var curveItems = Curve.CreateCurve(LocalizedStrings.Str3026Params.Put(period.Item1, period.Item2), period.Item3);
					strategy.PnLChanged += () =>
					{
						var data = new EquityData
						{
							Time = strategy.CurrentTime,
							Value = strategy.PnL,
						};

						this.GuiAsync(() => curveItems.Add(data));
					};

					Stat.AddStrategies(new[] { strategy });

					return strategy;
				})
				.ToEx(periods.Length);

			// start emulation
			batchEmulation.Start(strategies);
		}
コード例 #35
0
ファイル: WriteHelpers.cs プロジェクト: hbwjz/StockSharp
        private static string Level1ToString(Level1ChangeMessage level)
        {
            var sb = new StringBuilder();
            foreach (var kvp in level.Changes)
                sb.Append(string.Format("{0}:{1};", kvp.Key, kvp.Value));

            return string.Format("{0};{1};{2}",
                level.ServerTime,
                level.SecurityId.SecurityCode,
                sb
                );
        }
コード例 #36
0
		private void FlushQuotes(SecurityId secId)
		{
			var quotes = _quotes.TryGetValue(secId);

			if (quotes == null)
				return;

			_quotes.Remove(secId);

			foreach (var pair in quotes.CachedPairs)
			{
				var message = new Level1ChangeMessage
				{
					SecurityId = secId,
					ServerTime = pair.Key
				};

				var bid = pair.Value.First;

				if (bid != null)
				{
					message
						.TryAdd(Level1Fields.BestBidPrice, bid.Price.ToDecimal())
						.TryAdd(Level1Fields.BestBidVolume, (decimal)bid.Size);
				}

				var ask = pair.Value.Second;

				if (ask != null)
				{
					message
						.TryAdd(Level1Fields.BestAskPrice, ask.Price.ToDecimal())
						.TryAdd(Level1Fields.BestAskVolume, (decimal)ask.Size);
				}

				SendOutMessage(message);
			}
		}
コード例 #37
0
		private void SessionOnStiQuoteSnap(ref structSTIQuoteSnap structQuoteSnap)
		{
			var l1CngMsg = new Level1ChangeMessage
			{
				SecurityId = new SecurityId
				{
					SecurityCode = structQuoteSnap.bstrSymbol,
					BoardCode = structQuoteSnap.bstrExch
				},
				ServerTime = structQuoteSnap.bstrUpdateTime.StrToTime(),
			};

			if (structQuoteSnap.bAskPrice != 0)
				l1CngMsg.TryAdd(Level1Fields.BestAskPrice, (decimal)structQuoteSnap.fAskPrice);

			if (structQuoteSnap.bBidPrice != 0)
				l1CngMsg.TryAdd(Level1Fields.BestBidPrice, (decimal)structQuoteSnap.fBidPrice);

			l1CngMsg.TryAdd(Level1Fields.BestAskVolume, (decimal)structQuoteSnap.nAskSize);
			l1CngMsg.TryAdd(Level1Fields.BestBidVolume, (decimal)structQuoteSnap.nBidSize);

			if (structQuoteSnap.bOpenPrice != 0)
				l1CngMsg.TryAdd(Level1Fields.OpenPrice, (decimal)structQuoteSnap.fOpenPrice);

			if (structQuoteSnap.bHighPrice != 0)
				l1CngMsg.TryAdd(Level1Fields.HighPrice, (decimal)structQuoteSnap.fHighPrice);

			if (structQuoteSnap.bLowPrice != 0)
				l1CngMsg.TryAdd(Level1Fields.LowPrice, (decimal)structQuoteSnap.fLowPrice);

			if (structQuoteSnap.bLastPrice != 0)
				l1CngMsg.TryAdd(Level1Fields.LastTradePrice, (decimal)structQuoteSnap.fLastPrice);

			l1CngMsg.TryAdd(Level1Fields.LastTradeVolume, (decimal)structQuoteSnap.nLastSize);

			l1CngMsg.TryAdd(Level1Fields.OpenInterest, (decimal)structQuoteSnap.nOpenInterest);
			l1CngMsg.TryAdd(Level1Fields.Volume, (decimal)structQuoteSnap.nCumVolume);
			l1CngMsg.TryAdd(Level1Fields.VWAP, (decimal)structQuoteSnap.fVwap);

			l1CngMsg.TryAdd(Level1Fields.ClosePrice, (decimal)structQuoteSnap.fClosePrice); // öåíà çàêðûòèÿ ïðîøëîãî äíÿ.

			SendOutMessage(l1CngMsg);

			if (_subscribedSecuritiesToTrade.Cache.Contains(structQuoteSnap.bstrSymbol) && structQuoteSnap.fLastPrice != 0)
			{
				var tickMsg= new ExecutionMessage
				{
					ExecutionType = ExecutionTypes.Tick,
					SecurityId = new SecurityId{SecurityCode = structQuoteSnap.bstrSymbol,BoardCode = structQuoteSnap.bstrExch},
					//TradeId = structQuoteSnap.,
					TradePrice = (decimal)structQuoteSnap.fLastPrice,
					TradeVolume = structQuoteSnap.nLastSize,
					//OriginSide = action.ToSide(),
					ServerTime = structQuoteSnap.bstrUpdateTime.StrToTime()
				};

				SendOutMessage(tickMsg);
			}
		}
コード例 #38
0
ファイル: MainWindow.xaml.cs プロジェクト: yoykiee/StockSharp
		private void StartBtnClick(object sender, RoutedEventArgs e)
		{
			InitChart();

			if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text))
			{
				MessageBox.Show(this, LocalizedStrings.Str3014);
				return;
			}

			if (_connectors.Any(t => t.State != EmulationStates.Stopped))
			{
				MessageBox.Show(this, LocalizedStrings.Str3015);
				return;
			}

			var secIdParts = SecId.Text.Split('@');

			if (secIdParts.Length != 2)
			{
				MessageBox.Show(this, LocalizedStrings.Str3016);
				return;
			}

			var timeFrame = TimeSpan.FromMinutes(5);

			// create backtesting modes
			var settings = new[]
			{
				Tuple.Create(
					TicksCheckBox,
					TicksTestingProcess,
					TicksParameterGrid,
					// ticks
					new EmulationInfo {UseTicks = true, CurveColor = Colors.DarkGreen, StrategyName = LocalizedStrings.Ticks}),

				Tuple.Create(
					TicksAndDepthsCheckBox,
					TicksAndDepthsTestingProcess,
					TicksAndDepthsParameterGrid,
					// ticks + order book
					new EmulationInfo {UseTicks = true, UseMarketDepth = true, CurveColor = Colors.Red, StrategyName = LocalizedStrings.XamlStr757}),

				Tuple.Create(
					DepthsCheckBox,
					DepthsTestingProcess,
					DepthsParameterGrid,
					// order book
					new EmulationInfo {UseMarketDepth = true, CurveColor = Colors.OrangeRed, StrategyName = LocalizedStrings.MarketDepths}),


				Tuple.Create(
					CandlesCheckBox,
					CandlesTestingProcess,
					CandlesParameterGrid,
					// candles
					new EmulationInfo {UseCandleTimeFrame = timeFrame, CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.Candles}),
				
				Tuple.Create(
					CandlesAndDepthsCheckBox,
					CandlesAndDepthsTestingProcess,
					CandlesAndDepthsParameterGrid,
					// candles + orderbook
					new EmulationInfo {UseMarketDepth = true, UseCandleTimeFrame = timeFrame, CurveColor = Colors.Cyan, StrategyName = LocalizedStrings.XamlStr635}),
			
				Tuple.Create(
					OrderLogCheckBox,
					OrderLogTestingProcess,
					OrderLogParameterGrid,
					// order log
					new EmulationInfo {UseOrderLog = true, CurveColor = Colors.CornflowerBlue, StrategyName = LocalizedStrings.OrderLog})
			};

			// storage to historical data
			var storageRegistry = new StorageRegistry
			{
				// set historical path
				DefaultDrive = new LocalMarketDataDrive(HistoryPath.Text)
			};

			var startTime = ((DateTime)From.Value).ChangeKind(DateTimeKind.Utc);
			var stopTime = ((DateTime)To.Value).ChangeKind(DateTimeKind.Utc);

			// ОЛ необходимо загружать с 18.45 пред дня, чтобы стаканы строились правильно
			if (OrderLogCheckBox.IsChecked == true)
				startTime = startTime.Subtract(TimeSpan.FromDays(1)).AddHours(18).AddMinutes(45).AddTicks(1);

			// ProgressBar refresh step
			var progressStep = ((stopTime - startTime).Ticks / 100).To<TimeSpan>();

			// set ProgressBar bounds
			_progressBars.ForEach(p =>
			{
				p.Value = 0;
				p.Maximum = 100;
			});
			
			var logManager = new LogManager();
			var fileLogListener = new FileLogListener("sample.log");
			logManager.Listeners.Add(fileLogListener);
			//logManager.Listeners.Add(new DebugLogListener());	// for track logs in output window in Vusial Studio (poor performance).

			var generateDepths = GenDepthsCheckBox.IsChecked == true;
			var maxDepth = MaxDepth.Text.To<int>();
			var maxVolume = MaxVolume.Text.To<int>();

			var secCode = secIdParts[0];
			var board = ExchangeBoard.GetOrCreateBoard(secIdParts[1]);

			foreach (var set in settings)
			{
				if (set.Item1.IsChecked == false)
					continue;

				var progressBar = set.Item2;
				var statistic = set.Item3;
				var emulationInfo = set.Item4;

				// create test security
				var security = new Security
				{
					Id = SecId.Text, // sec id has the same name as folder with historical data
					Code = secCode,
					Board = board,
				};

				var level1Info = new Level1ChangeMessage
				{
					SecurityId = security.ToSecurityId(),
					ServerTime = startTime,
				}
				.TryAdd(Level1Fields.PriceStep, 10m)
				.TryAdd(Level1Fields.StepPrice, 6m)
				.TryAdd(Level1Fields.MinPrice, 10m)
				.TryAdd(Level1Fields.MaxPrice, 1000000m)
				.TryAdd(Level1Fields.MarginBuy, 10000m)
				.TryAdd(Level1Fields.MarginSell, 10000m);

				// test portfolio
				var portfolio = new Portfolio
				{
					Name = "test account",
					BeginValue = 1000000,
				};

				// create backtesting connector
				var connector = new HistoryEmulationConnector(
					new[] { security },
					new[] { portfolio })
				{
					MarketEmulator =
					{
						Settings =
						{
							// match order if historical price touched our limit order price. 
							// It is terned off, and price should go through limit order price level
							// (more "severe" test mode)
							MatchOnTouch = false,
						}
					},

					UseExternalCandleSource = emulationInfo.UseCandleTimeFrame != null,

					CreateDepthFromOrdersLog = emulationInfo.UseOrderLog,
					CreateTradesFromOrdersLog = emulationInfo.UseOrderLog,

					HistoryMessageAdapter =
					{
						StorageRegistry = storageRegistry,

						// set history range
						StartDate = startTime,
						StopDate = stopTime,
					},

					// set market time freq as time frame
					MarketTimeChangedInterval = timeFrame,
				};

				((ILogSource)connector).LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info;

				logManager.Sources.Add(connector);

				var candleManager = emulationInfo.UseCandleTimeFrame == null
					? new CandleManager(new TradeCandleBuilderSourceEx(connector))
					: new CandleManager(connector);

				var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

				_shortMa = new SimpleMovingAverage { Length = 10 };
				_shortElem = new ChartIndicatorElement
				{
					Color = Colors.Coral,
					ShowAxisMarker = false,
					FullTitle = _shortMa.ToString()
				};
				_bufferedChart.AddElement(_area, _shortElem);

				_longMa = new SimpleMovingAverage { Length = 80 };
				_longElem = new ChartIndicatorElement
				{
					ShowAxisMarker = false,
					FullTitle = _longMa.ToString()
				};
				_bufferedChart.AddElement(_area, _longElem);

				// create strategy based on 80 5-min и 10 5-min
				var strategy = new SmaStrategy(_bufferedChart, _candlesElem, _tradesElem, _shortMa, _shortElem, _longMa, _longElem, series)
				{
					Volume = 1,
					Portfolio = portfolio,
					Security = security,
					Connector = connector,
					LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info,

					// by default interval is 1 min,
					// it is excessively for time range with several months
					UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To<TimeSpan>()
				};

				logManager.Sources.Add(strategy);

				connector.NewSecurities += securities =>
				{
					if (securities.All(s => s != security))
						return;

					// fill level1 values
					connector.SendInMessage(level1Info);

					if (emulationInfo.UseMarketDepth)
					{
						connector.RegisterMarketDepth(security);

						if (
								// if order book will be generated
								generateDepths ||
								// of backtesting will be on candles
								emulationInfo.UseCandleTimeFrame != TimeSpan.Zero
							)
						{
							// if no have order book historical data, but strategy is required,
							// use generator based on last prices
							connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security))
							{
								Interval = TimeSpan.FromSeconds(1), // order book freq refresh is 1 sec
								MaxAsksDepth = maxDepth,
								MaxBidsDepth = maxDepth,
								UseTradeVolume = true,
								MaxVolume = maxVolume,
								MinSpreadStepCount = 2,	// min spread generation is 2 pips
								MaxSpreadStepCount = 5,	// max spread generation size (prevent extremely size)
								MaxPriceStepCount = 3	// pips size,
							});
						}
					}

					if (emulationInfo.UseOrderLog)
					{
						connector.RegisterOrderLog(security);
					}

					if (emulationInfo.UseTicks)
					{
						connector.RegisterTrades(security);
					}

					// start strategy before emulation started
					strategy.Start();
					candleManager.Start(series);

					// start historical data loading when connection established successfully and all data subscribed
					connector.Start();
				};

				// fill parameters panel
				statistic.Parameters.Clear();
				statistic.Parameters.AddRange(strategy.StatisticManager.Parameters);

				var pnlCurve = Curve.CreateCurve("P&L " + emulationInfo.StrategyName, emulationInfo.CurveColor, EquityCurveChartStyles.Area);
				var unrealizedPnLCurve = Curve.CreateCurve(LocalizedStrings.PnLUnreal + emulationInfo.StrategyName, Colors.Black);
				var commissionCurve = Curve.CreateCurve(LocalizedStrings.Str159 + " " + emulationInfo.StrategyName, Colors.Red, EquityCurveChartStyles.DashedLine);
				var posItems = PositionCurve.CreateCurve(emulationInfo.StrategyName, emulationInfo.CurveColor);
				strategy.PnLChanged += () =>
				{
					var pnl = new EquityData
					{
						Time = strategy.CurrentTime,
						Value = strategy.PnL - strategy.Commission ?? 0
					};

					var unrealizedPnL = new EquityData
					{
						Time = strategy.CurrentTime,
						Value = strategy.PnLManager.UnrealizedPnL
					};

					var commission = new EquityData
					{
						Time = strategy.CurrentTime,
						Value = strategy.Commission ?? 0
					};

					pnlCurve.Add(pnl);
					unrealizedPnLCurve.Add(unrealizedPnL);
					commissionCurve.Add(commission);
				};

				strategy.PositionChanged += () => posItems.Add(new EquityData { Time = strategy.CurrentTime, Value = strategy.Position });

				var nextTime = startTime + progressStep;

				// handle historical time for update ProgressBar
				connector.MarketTimeChanged += d =>
				{
					if (connector.CurrentTime < nextTime && connector.CurrentTime < stopTime)
						return;

					var steps = (connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1;
					nextTime = startTime + (steps * progressStep.Ticks).To<TimeSpan>();
					this.GuiAsync(() => progressBar.Value = steps);
				};

				connector.StateChanged += () =>
				{
					if (connector.State == EmulationStates.Stopped)
					{
						candleManager.Stop(series);
						strategy.Stop();

						logManager.Dispose();
						_connectors.Clear();

						SetIsEnabled(false);

						this.GuiAsync(() =>
						{
							if (connector.IsFinished)
							{
								progressBar.Value = progressBar.Maximum;
								MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
							}
							else
								MessageBox.Show(this, LocalizedStrings.cancelled);
						});
					}
					else if (connector.State == EmulationStates.Started)
					{
						SetIsEnabled(true);
					}
				};

				if (ShowDepth.IsChecked == true)
				{
					MarketDepth.UpdateFormat(security);

					connector.NewMessage += message =>
					{
						var quoteMsg = message as QuoteChangeMessage;

						if (quoteMsg != null)
							MarketDepth.UpdateDepth(quoteMsg);
					};
				}

				_connectors.Add(connector);

				progressBar.Value = 0;
			}

			_startEmulationTime = DateTime.Now;

			// start emulation
			foreach (var connector in _connectors)
			{
				// raise NewSecurities and NewPortfolio for full fill strategy properties
				connector.Connect();

				// 1 cent commission for trade
				connector.SendInMessage(new CommissionRuleMessage
				{
					Rule = new CommissionPerTradeRule { Value = 0.01m }
				});
			}

			TabControl.Items.Cast<TabItem>().First(i => i.Visibility == Visibility.Visible).IsSelected = true;
		}
コード例 #39
0
		/// <summary>
		/// To convert first level of market data.
		/// </summary>
		/// <param name="message">Level 1.</param>
		/// <returns>Stream <see cref="Message"/>.</returns>
		public IEnumerable<Message> ToExecutionLog(Level1ChangeMessage message)
		{
			if (message == null)
				throw new ArgumentNullException(nameof(message));

			if (message.IsContainsTick())
				yield return message.ToTick();

			if (message.IsContainsQuotes())
			{
				var prevBidPrice = _prevBidPrice;
				var prevBidVolume = _prevBidVolume;
				var prevAskPrice = _prevAskPrice;
				var prevAskVolume = _prevAskVolume;

				_prevBidPrice = (decimal?)message.Changes.TryGetValue(Level1Fields.BestBidPrice) ?? _prevBidPrice;
				_prevBidVolume = (decimal?)message.Changes.TryGetValue(Level1Fields.BestBidVolume) ?? _prevBidVolume;
				_prevAskPrice = (decimal?)message.Changes.TryGetValue(Level1Fields.BestAskPrice) ?? _prevAskPrice;
				_prevAskVolume = (decimal?)message.Changes.TryGetValue(Level1Fields.BestAskVolume) ?? _prevAskVolume;

				if (_prevBidPrice == 0)
					_prevBidPrice = null;

				if (_prevAskPrice == 0)
					_prevAskPrice = null;

				if (prevBidPrice == _prevBidPrice && prevBidVolume == _prevBidVolume && prevAskPrice == _prevAskPrice && prevAskVolume == _prevAskVolume)
					yield break;

				yield return new QuoteChangeMessage
				{
					SecurityId = message.SecurityId,
					LocalTime = message.LocalTime,
					ServerTime = message.ServerTime,
					Bids = _prevBidPrice == null ? Enumerable.Empty<QuoteChange>() : new[] { new QuoteChange(Sides.Buy, _prevBidPrice.Value, _prevBidVolume ?? 0) },
					Asks = _prevAskPrice == null ? Enumerable.Empty<QuoteChange>() : new[] { new QuoteChange(Sides.Sell, _prevAskPrice.Value, _prevAskVolume ?? 0) },
				};
			}
		}
コード例 #40
0
		private void SessionOnStiGreeksUpdate(ref structSTIGreeksUpdate structGreeksUpdate)
		{
			var message = new Level1ChangeMessage
			{
				SecurityId = new SecurityId
				{
					SecurityCode = structGreeksUpdate.bstrSymbol,
					BoardCode = AssociatedBoardCode,
				},
				ServerTime = CurrentTime,
			};

			message.TryAdd(Level1Fields.Delta, (decimal)structGreeksUpdate.fDelta);
			message.TryAdd(Level1Fields.Gamma, (decimal)structGreeksUpdate.fGamma);
			message.TryAdd(Level1Fields.Theta, (decimal)structGreeksUpdate.fTheta);
			message.TryAdd(Level1Fields.Vega, (decimal)structGreeksUpdate.fVega);
			message.TryAdd(Level1Fields.Rho, (decimal)structGreeksUpdate.fRho);
			message.TryAdd(Level1Fields.TheorPrice, (decimal)structGreeksUpdate.fTheoPrice);
			message.TryAdd(Level1Fields.ImpliedVolatility, (decimal)structGreeksUpdate.fImpVol);

			SendOutMessage(message);			
		}
コード例 #41
0
ファイル: PnLQueue.cs プロジェクト: zjxbetter/StockSharp
		/// <summary>
		/// To process the message, containing market data.
		/// </summary>
		/// <param name="levelMsg">The message, containing market data.</param>
		public void ProcessLevel1(Level1ChangeMessage levelMsg)
		{
			var priceStep = levelMsg.Changes.TryGetValue(Level1Fields.PriceStep);
			if (priceStep != null)
			{
				PriceStep = (decimal)priceStep;
				_unrealizedPnL = null;
			}

			var stepPrice = levelMsg.Changes.TryGetValue(Level1Fields.StepPrice);
			if (stepPrice != null)
			{
				StepPrice = (decimal)stepPrice;
				_unrealizedPnL = null;
			}

			var tradePrice = levelMsg.Changes.TryGetValue(Level1Fields.LastTradePrice);
			if (tradePrice != null)
			{
				TradePrice = (decimal)tradePrice;
				_unrealizedPnL = null;
			}

			var bidPrice = levelMsg.Changes.TryGetValue(Level1Fields.BestBidPrice);
			if (bidPrice != null)
			{
				BidPrice = (decimal)bidPrice;
				_unrealizedPnL = null;
			}

			var askPrice = levelMsg.Changes.TryGetValue(Level1Fields.BestAskPrice);
			if (askPrice != null)
			{
				AskPrice = (decimal)askPrice;
				_unrealizedPnL = null;
			}
		}
コード例 #42
0
		private void StartEmulation()
		{
			if (_connector != null && _connector.State != EmulationStates.Stopped)
				throw new InvalidOperationException(LocalizedStrings.Str3015);

			if (Strategy == null)
				throw new InvalidOperationException("Strategy not selected.");

			var strategy = (EmulationDiagramStrategy)Strategy;

			if (strategy.DataPath.IsEmpty() || !Directory.Exists(strategy.DataPath))
				throw new InvalidOperationException(LocalizedStrings.Str3014);

			strategy
				.Composition
				.Parameters
				.ForEach(p =>
				{
					if (p.Type == typeof(Security) && p.Value == null)
						throw new InvalidOperationException(LocalizedStrings.Str1380);
				});

			strategy.Reset();
			Reset();

			var securityId = "empty@empty";
			var secGen = new SecurityIdGenerator();
			var secIdParts = secGen.Split(securityId);
			var secCode = secIdParts.SecurityCode;
			var board = ExchangeBoard.GetOrCreateBoard(secIdParts.BoardCode);
			var timeFrame = strategy.CandlesTimeFrame;
			var useCandles = strategy.MarketDataSource == MarketDataSource.Candles;

			// create test security
			var security = new Security
			{
				Id = securityId, // sec id has the same name as folder with historical data
				Code = secCode,
				Board = board,
			};

			// storage to historical data
			var storageRegistry = new StorageRegistry
			{
				// set historical path
				DefaultDrive = new LocalMarketDataDrive(strategy.DataPath)
			};

			var startTime = strategy.StartDate.ChangeKind(DateTimeKind.Utc);
			var stopTime = strategy.StopDate.ChangeKind(DateTimeKind.Utc);

			// ProgressBar refresh step
			var progressStep = ((stopTime - startTime).Ticks / 100).To<TimeSpan>();

			// set ProgressBar bounds
			TicksAndDepthsProgress.Value = 0;
			TicksAndDepthsProgress.Maximum = 100;

			// test portfolio
			var portfolio = new Portfolio
			{
				Name = "test account",
				BeginValue = 1000000,
			};

			var securityProvider = ConfigManager.GetService<ISecurityProvider>();

			// create backtesting connector
			_connector = new HistoryEmulationConnector(securityProvider, new[] { portfolio }, new StorageRegistry())
			{
				EmulationAdapter =
				{
					Emulator =
					{
						Settings =
						{
							// match order if historical price touched our limit order price. 
							// It is terned off, and price should go through limit order price level
							// (more "severe" test mode)
							MatchOnTouch = false,
						}
					}
				},

				UseExternalCandleSource = useCandles,

				HistoryMessageAdapter =
				{
					StorageRegistry = storageRegistry,

					// set history range
					StartDate = startTime,
					StopDate = stopTime,
				},

				// set market time freq as time frame
				MarketTimeChangedInterval = timeFrame,
			};

			//((ILogSource)_connector).LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info;

			ConfigManager.GetService<LogManager>().Sources.Add(_connector);

			var candleManager = new CandleManager(_connector);

			strategy.Volume = 1;
			strategy.Portfolio = portfolio;
			strategy.Security = security;
			strategy.Connector = _connector;
			//LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info,

			// by default interval is 1 min,
			// it is excessively for time range with several months
			strategy.UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To<TimeSpan>();

			strategy.SetCandleManager(candleManager);

			_connector.NewSecurity += s =>
			{
				var level1Info = new Level1ChangeMessage
				{
					SecurityId = s.ToSecurityId(),
					ServerTime = startTime,
				}
					.TryAdd(Level1Fields.PriceStep, secIdParts.SecurityCode == "RIZ2" ? 10m : 1)
					.TryAdd(Level1Fields.StepPrice, 6m)
					.TryAdd(Level1Fields.MinPrice, 10m)
					.TryAdd(Level1Fields.MaxPrice, 1000000m)
					.TryAdd(Level1Fields.MarginBuy, 10000m)
					.TryAdd(Level1Fields.MarginSell, 10000m);

				// fill level1 values
				_connector.SendInMessage(level1Info);

				//_connector.RegisterMarketDepth(security);

				//if (!useCandles)
				//	_connector.RegisterTrades(s);
			};

			var nextTime = startTime + progressStep;

			// handle historical time for update ProgressBar
			_connector.MarketTimeChanged += d =>
			{
				if (_connector.CurrentTime < nextTime && _connector.CurrentTime < stopTime)
					return;

				var steps = (_connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1;
				nextTime = startTime + (steps * progressStep.Ticks).To<TimeSpan>();
				this.GuiAsync(() => TicksAndDepthsProgress.Value = steps);
			};

			_connector.LookupSecuritiesResult += (ss) =>
			{
				if (strategy.ProcessState != ProcessStates.Stopped)
					return;

				// start strategy before emulation started
				strategy.Start();

				// start historical data loading when connection established successfully and all data subscribed
				_connector.Start();
			};

			_connector.StateChanged += () =>
			{
				switch (_connector.State)
				{
					case EmulationStates.Stopped:
						strategy.Stop();

						this.GuiAsync(() =>
						{
							if (_connector.IsFinished)
								TicksAndDepthsProgress.Value = TicksAndDepthsProgress.Maximum;
						});
						break;
					case EmulationStates.Started:
						break;
				}
			};

			TicksAndDepthsProgress.Value = 0;

			DiagramDebuggerControl.Debugger.IsEnabled = true;

			// raise NewSecurities and NewPortfolio for full fill strategy properties
			_connector.Connect();

			// 1 cent commission for trade
			_connector.SendInMessage(new CommissionRuleMessage
			{
				Rule = new CommissionPerTradeRule
				{
					Value = 0.01m
				}
			});
		}
コード例 #43
0
		private void OnSecurityChanged(string smartId, Tuple<decimal, decimal, DateTime> lastTrade, decimal open, decimal high, decimal low, decimal close, decimal volume, QuoteChange bid, QuoteChange ask,
			decimal openInt, Tuple<decimal, decimal> goBuySell, Tuple<decimal, decimal> goBase, Tuple<decimal, decimal> limits, int tradingStatus, Tuple<decimal, decimal> volatTheorPrice)
		{
			var secId = new SecurityId { Native = smartId };

			var message = new Level1ChangeMessage
			{
				SecurityId = secId,
				ExtensionInfo = new Dictionary<object, object>
				{
					{ SmartComExtensionInfoHelper.SecurityOptionsMargin, goBase.Item1 },
					{ SmartComExtensionInfoHelper.SecurityOptionsSyntheticMargin, goBase.Item2 }
				},
				ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
			};

			message.TryAdd(Level1Fields.LastTradePrice, lastTrade.Item1);
			message.TryAdd(Level1Fields.LastTradeVolume, lastTrade.Item2);
			message.Add(Level1Fields.LastTradeTime, lastTrade.Item3.ApplyTimeZone(TimeHelper.Moscow));

			var prevQuotes = _bestQuotes.TryGetValue(secId);

			if (bid.Price != 0)
			{
				message.Add(Level1Fields.BestBidPrice, bid.Price);

				if (prevQuotes != null && prevQuotes.First != null && prevQuotes.First.Item1 == bid.Price)
					message.Add(Level1Fields.BestBidVolume, prevQuotes.First.Item2);
			}

			if (ask.Price != 0)
			{
				message.Add(Level1Fields.BestAskPrice, ask.Price);

				if (prevQuotes != null && prevQuotes.Second != null && prevQuotes.Second.Item1 == ask.Price)
					message.Add(Level1Fields.BestAskVolume, prevQuotes.Second.Item2);
			}

			message.TryAdd(Level1Fields.BidsVolume, bid.Volume);
			message.TryAdd(Level1Fields.AsksVolume, ask.Volume);

			message.TryAdd(Level1Fields.OpenPrice, open);
			message.TryAdd(Level1Fields.LowPrice, low);
			message.TryAdd(Level1Fields.HighPrice, high);
			message.TryAdd(Level1Fields.ClosePrice, close);

			message.TryAdd(Level1Fields.MinPrice, limits.Item1);
			message.TryAdd(Level1Fields.MaxPrice, limits.Item2);

			message.TryAdd(Level1Fields.MarginBuy, goBuySell.Item1);
			message.TryAdd(Level1Fields.MarginSell, goBuySell.Item2);
			message.TryAdd(Level1Fields.OpenInterest, openInt);

			message.TryAdd(Level1Fields.ImpliedVolatility, volatTheorPrice.Item1);
			message.TryAdd(Level1Fields.TheorPrice, volatTheorPrice.Item2);

			message.TryAdd(Level1Fields.Volume, volume);

			message.Add(Level1Fields.State, tradingStatus == 0 ? SecurityStates.Trading : SecurityStates.Stoped);

			SendOutMessage(message);
		}
コード例 #44
0
        private static string Level1ToString(Level1ChangeMessage level)
        {
            var sb = new StringBuilder();

            foreach (var kvp in level.Changes)
                sb.Append($"{kvp.Key}:{kvp.Value};");

            return $"{level.ServerTime};{level.SecurityId.SecurityCode};{sb}";
        }
コード例 #45
0
		private void ProcessLevel1Trade(Level1ChangeMessage message, decimal lastTradePrice, decimal lastTradeVolume, List<ExecutionMessage> retVal)
		{
			if (message.LocalTime.Date == _lastTradeDate)
				return;

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

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

			retVal.AddRange(ProcessExecution(exec));
		}
コード例 #46
0
		private void StartEmulation()
		{
			if (_connector != null && _connector.State != EmulationStates.Stopped)
				throw new InvalidOperationException(LocalizedStrings.Str3015);

			if (Strategy == null)
				throw new InvalidOperationException("Strategy not selected.");

			var strategy = (EmulationDiagramStrategy)Strategy;
			var settings = strategy.EmulationSettings;

			if (settings.MarketDataSettings == null)
				throw new InvalidOperationException(LocalizedStrings.Str3014);

			new SetDefaultEmulationSettingsCommand(settings).Process(this);

			strategy
				.Composition
				.Parameters
				.ForEach(p =>
				{
					if (p.Type == typeof(Security) && p.Value == null)
						throw new InvalidOperationException(LocalizedStrings.Str1380);
				});

			strategy.Reset();
			Reset();

			var securityId = "empty@empty";
			var secGen = new SecurityIdGenerator();
			var secIdParts = secGen.Split(securityId);
			var secCode = secIdParts.SecurityCode;
			var board = ExchangeBoard.GetOrCreateBoard(secIdParts.BoardCode);
			var timeFrame = settings.CandlesTimeFrame;
			var useCandles = settings.MarketDataSource == MarketDataSource.Candles;

			// create test security
			var security = new Security
			{
				Id = securityId, // sec id has the same name as folder with historical data
				Code = secCode,
				Board = board,
			};

			// storage to historical data
			var storageRegistry = new StudioStorageRegistry
			{
				MarketDataSettings = settings.MarketDataSettings
			};

			var startTime = settings.StartDate.ChangeKind(DateTimeKind.Utc);
			var stopTime = settings.StopDate.ChangeKind(DateTimeKind.Utc);

			// ProgressBar refresh step
			var progressStep = ((stopTime - startTime).Ticks / 100).To<TimeSpan>();

			// set ProgressBar bounds
			TicksAndDepthsProgress.Value = 0;
			TicksAndDepthsProgress.Maximum = 100;

			// test portfolio
			var portfolio = new Portfolio
			{
				Name = "test account",
				BeginValue = 1000000,
			};

			var securityProvider = ConfigManager.GetService<ISecurityProvider>();

			// create backtesting connector
			_connector = new HistoryEmulationConnector(securityProvider, new[] { portfolio }, new StorageRegistry())
			{
				EmulationAdapter =
				{
					Emulator =
					{
						Settings =
						{
							// match order if historical price touched our limit order price. 
							// It is terned off, and price should go through limit order price level
							// (more "severe" test mode)
							MatchOnTouch = settings.MatchOnTouch, 
							IsSupportAtomicReRegister = settings.IsSupportAtomicReRegister,
							Latency = settings.EmulatoinLatency,
						}
					}
				},

				UseExternalCandleSource = useCandles,

				HistoryMessageAdapter =
				{
					StorageRegistry = storageRegistry,
					StorageFormat = settings.StorageFormat,

					// set history range
					StartDate = startTime,
					StopDate = stopTime,
				},

				// set market time freq as time frame
				MarketTimeChangedInterval = timeFrame,
			};

			((ILogSource)_connector).LogLevel = settings.DebugLog ? LogLevels.Debug : LogLevels.Info;

			ConfigManager.GetService<LogManager>().Sources.Add(_connector);

			strategy.Volume = 1;
			strategy.Portfolio = portfolio;
			strategy.Security = security;
			strategy.Connector = _connector;
			strategy.LogLevel = settings.DebugLog ? LogLevels.Debug : LogLevels.Info;

			// by default interval is 1 min,
			// it is excessively for time range with several months
			strategy.UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To<TimeSpan>();

			strategy.SetCandleManager(new CandleManager(_connector));

			_connector.NewSecurity += s =>
			{
				//TODO send real level1 message
				var level1Info = new Level1ChangeMessage
				{
					SecurityId = s.ToSecurityId(),
					ServerTime = startTime,
				}
					.TryAdd(Level1Fields.PriceStep, secIdParts.SecurityCode == "RIZ2" ? 10m : 1)
					.TryAdd(Level1Fields.StepPrice, 6m)
					.TryAdd(Level1Fields.MinPrice, 10m)
					.TryAdd(Level1Fields.MaxPrice, 1000000m)
					.TryAdd(Level1Fields.MarginBuy, 10000m)
					.TryAdd(Level1Fields.MarginSell, 10000m);

				// fill level1 values
				_connector.SendInMessage(level1Info);

				if (settings.UseMarketDepths)
				{
					_connector.RegisterMarketDepth(security);

					if (
							// if order book will be generated
							settings.GenerateDepths ||
							// of backtesting will be on candles
							useCandles
						)
					{
						// if no have order book historical data, but strategy is required,
						// use generator based on last prices
						_connector.RegisterMarketDepth(new TrendMarketDepthGenerator(_connector.GetSecurityId(s))
						{
							Interval = TimeSpan.FromSeconds(1), // order book freq refresh is 1 sec
							MaxAsksDepth = settings.MaxDepths,
							MaxBidsDepth = settings.MaxDepths,
							UseTradeVolume = true,
							MaxVolume = settings.MaxVolume,
							MinSpreadStepCount = 2, // min spread generation is 2 pips
							MaxSpreadStepCount = 5, // max spread generation size (prevent extremely size)
							MaxPriceStepCount = 3   // pips size,
						});
					}
				}
			};

			var nextTime = startTime + progressStep;

			// handle historical time for update ProgressBar
			_connector.MarketTimeChanged += d =>
			{
				if (_connector.CurrentTime < nextTime && _connector.CurrentTime < stopTime)
					return;

				var steps = (_connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1;
				nextTime = startTime + (steps * progressStep.Ticks).To<TimeSpan>();
				this.GuiAsync(() => TicksAndDepthsProgress.Value = steps);
			};

			_connector.LookupSecuritiesResult += (ss) =>
			{
				if (strategy.ProcessState != ProcessStates.Stopped)
					return;

				// start strategy before emulation started
				strategy.Start();

				// start historical data loading when connection established successfully and all data subscribed
				_connector.Start();
			};

			_connector.StateChanged += () =>
			{
				switch (_connector.State)
				{
					case EmulationStates.Stopped:
						strategy.Stop();

						this.GuiAsync(() =>
						{
							if (_connector.IsFinished)
								TicksAndDepthsProgress.Value = TicksAndDepthsProgress.Maximum;
						});
						break;
					case EmulationStates.Started:
						break;
				}
			};

			_connector.Disconnected += () =>
			{
				this.GuiAsync(() => _connector.Dispose());
			};

			TicksAndDepthsProgress.Value = 0;

			DiagramDebuggerControl.Debugger.IsEnabled = true;

			// raise NewSecurities and NewPortfolio for full fill strategy properties
			_connector.Connect();

			// 1 cent commission for trade
			_connector.SendInMessage(new CommissionRuleMessage
			{
				Rule = new CommissionPerTradeRule
				{
					Value = 0.01m
				}
			});
		}
コード例 #47
0
		private void ProcessLevel1Depth(Level1ChangeMessage message, decimal bestBidPrice, decimal bestBidVolume, decimal bestAskPrice, decimal bestAskVolume, List<ExecutionMessage> retVal)
		{
			if (message.LocalTime.Date == _lastDepthDate)
				return;

			QuoteChange ask = null;
			QuoteChange bid = null;

			if (bestAskPrice != 0 && bestAskVolume != 0)
				ask = new QuoteChange(Sides.Sell, bestAskPrice, bestAskVolume);

			if (bestBidPrice != 0 && bestBidVolume != 0)
				bid = new QuoteChange(Sides.Buy, bestBidPrice, bestBidVolume);

			if (ask == null && bid == null)
				return;

			retVal.AddRange(ProcessQuoteChange(message.LocalTime, message.ServerTime,
				bid != null ? new[] { bid } : ArrayHelper.Empty<QuoteChange>(),
				ask != null ? new[] { ask } : ArrayHelper.Empty<QuoteChange>()));
		}
コード例 #48
0
		private void TraderOnValuesChanged(Security security, IEnumerable<KeyValuePair<Level1Fields, object>> changes, DateTimeOffset serverTime, DateTime localTime)
		{
			var wnd = _level1Windows.TryGetValue(security);

			if (wnd == null)
				return;

			var msg = new Level1ChangeMessage
			{
				SecurityId = security.ToSecurityId(),
				ServerTime = serverTime,
				LocalTime = localTime
			};
			msg.Changes.AddRange(changes);
			wnd.Level1Grid.Messages.Add(msg);
		}
コード例 #49
0
ファイル: MainWindow.xaml.cs プロジェクト: hbwjz/StockSharp
		private void StartBtnClick(object sender, RoutedEventArgs e)
		{
			// if process was already started, will stop it now
			if (_connector != null && _connector.State != EmulationStates.Stopped)
			{
				_strategy.Stop();
				_connector.Disconnect();
				_logManager.Sources.Clear();

				_connector = null;
				return;
			}

			// create test security
			var security = new Security
			{
				Id = "AAPL@NASDAQ",
				Code = "AAPL",
				Name = "AAPL Inc",
				Board = ExchangeBoard.Nasdaq,
			};

			var startTime = new DateTime(2009, 6, 1);
			var stopTime = new DateTime(2009, 9, 1);

			var level1Info = new Level1ChangeMessage
			{
				SecurityId = security.ToSecurityId(),
				ServerTime = startTime,
			}
			.TryAdd(Level1Fields.PriceStep, 10m)
			.TryAdd(Level1Fields.StepPrice, 6m)
			.TryAdd(Level1Fields.MinPrice, 10m)
			.TryAdd(Level1Fields.MaxPrice, 1000000m)
			.TryAdd(Level1Fields.MarginBuy, 10000m)
			.TryAdd(Level1Fields.MarginSell, 10000m);

			// test portfolio
			var portfolio = new Portfolio
			{
				Name = "test account",
				BeginValue = 1000000,
			};

			var timeFrame = TimeSpan.FromMinutes(5);

			// create backtesting connector
			_connector = new HistoryEmulationConnector(
				new[] { security },
				new[] { portfolio })
			{
				HistoryMessageAdapter =
				{
					// set history range
					StartDate = startTime,
					StopDate = stopTime,
				},

				// set market time freq as time frame
				MarketTimeChangedInterval = timeFrame,
			};

			_logManager.Sources.Add(_connector);

			var candleManager = new CandleManager(_connector);

			var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);

			// create strategy based on 80 5-min и 10 5-min
			_strategy = new SmaStrategy(series, new SimpleMovingAverage { Length = 80 }, new SimpleMovingAverage { Length = 10 })
			{
				Volume = 1,
				Security = security,
				Portfolio = portfolio,
				Connector = _connector,
			};

			_connector.NewSecurities += securities =>
			{
				if (securities.All(s => s != security))
					return;

				// fill level1 values
				_connector.SendInMessage(level1Info);

				_connector.RegisterTrades(new RandomWalkTradeGenerator(_connector.GetSecurityId(security)));
				_connector.RegisterMarketDepth(new TrendMarketDepthGenerator(_connector.GetSecurityId(security)) { GenerateDepthOnEachTrade = false });

				// start strategy before emulation started
				_strategy.Start();
				candleManager.Start(series);

				// start historical data loading when connection established successfully and all data subscribed
				_connector.Start();
			};

			// fill parameters panel
			ParameterGrid.Parameters.Clear();
			ParameterGrid.Parameters.AddRange(_strategy.StatisticManager.Parameters);

			_strategy.PnLChanged += () =>
			{
				var data = new EquityData
				{
					Time = _strategy.CurrentTime,
					Value = _strategy.PnL,
				};

				this.GuiAsync(() => _curveItems.Add(data));
			};

			_logManager.Sources.Add(_strategy);

			// ProgressBar refresh step
			var progressStep = ((stopTime - startTime).Ticks / 100).To<TimeSpan>();
			var nextTime = startTime + progressStep;

			TestingProcess.Maximum = 100;
			TestingProcess.Value = 0;

			// handle historical time for update ProgressBar
			_connector.MarketTimeChanged += diff =>
			{
				if (_connector.CurrentTime < nextTime && _connector.CurrentTime < stopTime)
					return;

				var steps = (_connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1;
				nextTime = startTime + (steps * progressStep.Ticks).To<TimeSpan>();
				this.GuiAsync(() => TestingProcess.Value = steps);
			};

			_connector.StateChanged += () =>
			{
				if (_connector.State == EmulationStates.Stopped)
				{
					this.GuiAsync(() =>
					{
						Report.IsEnabled = true;

						if (_connector.IsFinished)
						{
							TestingProcess.Value = TestingProcess.Maximum;
							MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime));
						}
						else
							MessageBox.Show(this, LocalizedStrings.cancelled);
					});
				}
			};

			_curveItems.Clear();

			Report.IsEnabled = false;

			_startEmulationTime = DateTime.Now;

			// raise NewSecurities and NewPortfolio for full fill strategy properties
			_connector.Connect();
		}
コード例 #50
0
ファイル: MainWindow.xaml.cs プロジェクト: zli69/StockSharp
        private void StartBtnClick(object sender, RoutedEventArgs e)
        {
            if (_connectors.Count > 0)
            {
                foreach (var connector in _connectors)
                {
                    connector.Start();
                }

                return;
            }

            if (HistoryPath.Folder.IsEmpty() || !Directory.Exists(HistoryPath.Folder))
            {
                MessageBox.Show(this, LocalizedStrings.Str3014);
                return;
            }

            if (_connectors.Any(t => t.State != EmulationStates.Stopped))
            {
                MessageBox.Show(this, LocalizedStrings.Str3015);
                return;
            }

            var id = SecId.Text.ToSecurityId();

            //if (secIdParts.Length != 2)
            //{
            //	MessageBox.Show(this, LocalizedStrings.Str3016);
            //	return;
            //}

            var timeFrame = TimeSpan.FromMinutes(TimeFrame.SelectedIndex == 0 ? 1 : 5);

            var secCode = id.SecurityCode;
            var board   = _exchangeInfoProvider.GetOrCreateBoard(id.BoardCode);

            // create test security
            var security = new Security
            {
                Id    = SecId.Text,              // sec id has the same name as folder with historical data
                Code  = secCode,
                Board = board,
            };

            if (FinamCandlesCheckBox.IsChecked == true)
            {
                _finamHistorySource.Refresh(new FinamSecurityStorage(security), security, s => {}, () => false);
            }

            // create backtesting modes
            var settings = new[]
            {
                Tuple.Create(
                    TicksCheckBox,
                    TicksProgress,
                    TicksParameterGrid,
                    // ticks
                    new EmulationInfo {
                    UseTicks = true, CurveColor = Colors.DarkGreen, StrategyName = LocalizedStrings.Ticks
                },
                    TicksChart,
                    TicksEquity,
                    TicksPosition),

                Tuple.Create(
                    TicksAndDepthsCheckBox,
                    TicksAndDepthsProgress,
                    TicksAndDepthsParameterGrid,
                    // ticks + order book
                    new EmulationInfo {
                    UseTicks = true, UseMarketDepth = true, CurveColor = Colors.Red, StrategyName = LocalizedStrings.XamlStr757
                },
                    TicksAndDepthsChart,
                    TicksAndDepthsEquity,
                    TicksAndDepthsPosition),

                Tuple.Create(
                    DepthsCheckBox,
                    DepthsProgress,
                    DepthsParameterGrid,
                    // order book
                    new EmulationInfo {
                    UseMarketDepth = true, CurveColor = Colors.OrangeRed, StrategyName = LocalizedStrings.MarketDepths
                },
                    DepthsChart,
                    DepthsEquity,
                    DepthsPosition),

                Tuple.Create(
                    CandlesCheckBox,
                    CandlesProgress,
                    CandlesParameterGrid,
                    // candles
                    new EmulationInfo {
                    UseCandleTimeFrame = timeFrame, CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.Candles
                },
                    CandlesChart,
                    CandlesEquity,
                    CandlesPosition),

                Tuple.Create(
                    CandlesAndDepthsCheckBox,
                    CandlesAndDepthsProgress,
                    CandlesAndDepthsParameterGrid,
                    // candles + orderbook
                    new EmulationInfo {
                    UseMarketDepth = true, UseCandleTimeFrame = timeFrame, CurveColor = Colors.Cyan, StrategyName = LocalizedStrings.XamlStr635
                },
                    CandlesAndDepthsChart,
                    CandlesAndDepthsEquity,
                    CandlesAndDepthsPosition),

                Tuple.Create(
                    OrderLogCheckBox,
                    OrderLogProgress,
                    OrderLogParameterGrid,
                    // order log
                    new EmulationInfo {
                    UseOrderLog = true, CurveColor = Colors.CornflowerBlue, StrategyName = LocalizedStrings.OrderLog
                },
                    OrderLogChart,
                    OrderLogEquity,
                    OrderLogPosition),

                Tuple.Create(
                    Level1CheckBox,
                    Level1Progress,
                    Level1ParameterGrid,
                    // order log
                    new EmulationInfo {
                    UseLevel1 = true, CurveColor = Colors.Aquamarine, StrategyName = LocalizedStrings.Level1
                },
                    Level1Chart,
                    Level1Equity,
                    Level1Position),

                Tuple.Create(
                    FinamCandlesCheckBox,
                    FinamCandlesProgress,
                    FinamCandlesParameterGrid,
                    // candles
                    new EmulationInfo {
                    UseCandleTimeFrame = timeFrame, HistorySource = d => _finamHistorySource.GetCandles(security, timeFrame, d.Date, d.Date), CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.FinamCandles
                },
                    FinamCandlesChart,
                    FinamCandlesEquity,
                    FinamCandlesPosition),

                Tuple.Create(
                    YahooCandlesCheckBox,
                    YahooCandlesProgress,
                    YahooCandlesParameterGrid,
                    // candles
                    new EmulationInfo {
                    UseCandleTimeFrame = timeFrame, HistorySource = d => new YahooHistorySource(_exchangeInfoProvider).GetCandles(security, timeFrame, d.Date, d.Date), CurveColor = Colors.DarkBlue, StrategyName = LocalizedStrings.YahooCandles
                },
                    YahooCandlesChart,
                    YahooCandlesEquity,
                    YahooCandlesPosition),
            };

            // storage to historical data
            var storageRegistry = new StorageRegistry
            {
                // set historical path
                DefaultDrive = new LocalMarketDataDrive(HistoryPath.Folder)
            };

            var startTime = ((DateTime)From.Value).ChangeKind(DateTimeKind.Utc);
            var stopTime  = ((DateTime)To.Value).ChangeKind(DateTimeKind.Utc);

            // (ru only) ОЛ необходимо загружать с 18.45 пред дня, чтобы стаканы строились правильно
            if (OrderLogCheckBox.IsChecked == true)
            {
                startTime = startTime.Subtract(TimeSpan.FromDays(1)).AddHours(18).AddMinutes(45).AddTicks(1).ApplyTimeZone(TimeHelper.Moscow).UtcDateTime;
            }

            // ProgressBar refresh step
            var progressStep = ((stopTime - startTime).Ticks / 100).To <TimeSpan>();

            // set ProgressBar bounds
            _progressBars.ForEach(p =>
            {
                p.Value   = 0;
                p.Maximum = 100;
            });

            var logManager      = new LogManager();
            var fileLogListener = new FileLogListener("sample.log");

            logManager.Listeners.Add(fileLogListener);
            //logManager.Listeners.Add(new DebugLogListener());	// for track logs in output window in Vusial Studio (poor performance).

            var generateDepths = GenDepthsCheckBox.IsChecked == true;
            var maxDepth       = MaxDepth.Text.To <int>();
            var maxVolume      = MaxVolume.Text.To <int>();
            var secId          = security.ToSecurityId();

            SetIsEnabled(false, false, false);

            foreach (var set in settings)
            {
                if (set.Item1.IsChecked == false)
                {
                    continue;
                }

                var title = (string)set.Item1.Content;

                InitChart(set.Item5, set.Item6, set.Item7);

                var progressBar   = set.Item2;
                var statistic     = set.Item3;
                var emulationInfo = set.Item4;

                var level1Info = new Level1ChangeMessage
                {
                    SecurityId = secId,
                    ServerTime = startTime,
                }
                .TryAdd(Level1Fields.PriceStep, secCode == "RIZ2" ? 10m : 1)
                .TryAdd(Level1Fields.StepPrice, 6m)
                .TryAdd(Level1Fields.MinPrice, 10m)
                .TryAdd(Level1Fields.MaxPrice, 1000000m)
                .TryAdd(Level1Fields.MarginBuy, 10000m)
                .TryAdd(Level1Fields.MarginSell, 10000m);

                // test portfolio
                var portfolio = new Portfolio
                {
                    Name       = "test account",
                    BeginValue = 1000000,
                };

                // create backtesting connector
                var connector = new HistoryEmulationConnector(
                    new[] { security },
                    new[] { portfolio })
                {
                    EmulationAdapter =
                    {
                        Emulator             =
                        {
                            Settings         =
                            {
                                // match order if historical price touched our limit order price.
                                // It is terned off, and price should go through limit order price level
                                // (more "severe" test mode)
                                MatchOnTouch = false,
                            }
                        }
                    },

                    //UseExternalCandleSource = emulationInfo.UseCandleTimeFrame != null,

                    CreateDepthFromOrdersLog  = emulationInfo.UseOrderLog,
                    CreateTradesFromOrdersLog = emulationInfo.UseOrderLog,

                    HistoryMessageAdapter =
                    {
                        StorageRegistry             = storageRegistry,

                        // set history range
                        StartDate = startTime,
                        StopDate  = stopTime,

                        OrderLogMarketDepthBuilders =
                        {
                            {
                                secId,
                                LocalizedStrings.ActiveLanguage == Languages.Russian
                                                                        ? (IOrderLogMarketDepthBuilder) new PlazaOrderLogMarketDepthBuilder(secId)
                                                                        : new ItchOrderLogMarketDepthBuilder(secId)
                            }
                        }
                    },

                    // set market time freq as time frame
                    MarketTimeChangedInterval = timeFrame,
                };

                ((ILogSource)connector).LogLevel = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info;

                logManager.Sources.Add(connector);

                var candleManager = new CandleManager(connector);

                var series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame)
                {
                    BuildCandlesMode = emulationInfo.UseCandleTimeFrame == null ? BuildCandlesModes.Build : BuildCandlesModes.Load
                };

                _shortMa = new SimpleMovingAverage {
                    Length = 10
                };
                _shortElem = new ChartIndicatorElement
                {
                    Color          = Colors.Coral,
                    ShowAxisMarker = false,
                    FullTitle      = _shortMa.ToString()
                };

                var chart = set.Item5;

                chart.AddElement(_area, _shortElem);

                _longMa = new SimpleMovingAverage {
                    Length = 80
                };
                _longElem = new ChartIndicatorElement
                {
                    ShowAxisMarker = false,
                    FullTitle      = _longMa.ToString()
                };
                chart.AddElement(_area, _longElem);

                // create strategy based on 80 5-min и 10 5-min
                var strategy = new SmaStrategy(chart, _candlesElem, _tradesElem, _shortMa, _shortElem, _longMa, _longElem, candleManager, series)
                {
                    Volume    = 1,
                    Portfolio = portfolio,
                    Security  = security,
                    Connector = connector,
                    LogLevel  = DebugLogCheckBox.IsChecked == true ? LogLevels.Debug : LogLevels.Info,

                    // by default interval is 1 min,
                    // it is excessively for time range with several months
                    UnrealizedPnLInterval = ((stopTime - startTime).Ticks / 1000).To <TimeSpan>()
                };

                logManager.Sources.Add(strategy);

                connector.NewSecurity += s =>
                {
                    if (s != security)
                    {
                        return;
                    }

                    // fill level1 values
                    connector.HistoryMessageAdapter.SendOutMessage(level1Info);

                    if (emulationInfo.HistorySource != null)
                    {
                        if (emulationInfo.UseCandleTimeFrame != null)
                        {
                            connector.RegisterHistorySource(security, MarketDataTypes.CandleTimeFrame, emulationInfo.UseCandleTimeFrame.Value, emulationInfo.HistorySource);
                        }

                        if (emulationInfo.UseTicks)
                        {
                            connector.RegisterHistorySource(security, MarketDataTypes.Trades, null, emulationInfo.HistorySource);
                        }

                        if (emulationInfo.UseLevel1)
                        {
                            connector.RegisterHistorySource(security, MarketDataTypes.Level1, null, emulationInfo.HistorySource);
                        }

                        if (emulationInfo.UseMarketDepth)
                        {
                            connector.RegisterHistorySource(security, MarketDataTypes.MarketDepth, null, emulationInfo.HistorySource);
                        }
                    }
                    else
                    {
                        if (emulationInfo.UseMarketDepth)
                        {
                            connector.RegisterMarketDepth(security);

                            if (
                                // if order book will be generated
                                generateDepths ||
                                // of backtesting will be on candles
                                emulationInfo.UseCandleTimeFrame != TimeSpan.Zero
                                )
                            {
                                // if no have order book historical data, but strategy is required,
                                // use generator based on last prices
                                connector.RegisterMarketDepth(new TrendMarketDepthGenerator(connector.GetSecurityId(security))
                                {
                                    Interval           = TimeSpan.FromSeconds(1),                           // order book freq refresh is 1 sec
                                    MaxAsksDepth       = maxDepth,
                                    MaxBidsDepth       = maxDepth,
                                    UseTradeVolume     = true,
                                    MaxVolume          = maxVolume,
                                    MinSpreadStepCount = 2,                                     // min spread generation is 2 pips
                                    MaxSpreadStepCount = 5,                                     // max spread generation size (prevent extremely size)
                                    MaxPriceStepCount  = 3                                      // pips size,
                                });
                            }
                        }

                        if (emulationInfo.UseOrderLog)
                        {
                            connector.RegisterOrderLog(security);
                        }

                        if (emulationInfo.UseTicks)
                        {
                            connector.RegisterTrades(security);
                        }

                        if (emulationInfo.UseLevel1)
                        {
                            connector.RegisterSecurity(security);
                        }
                    }

                    // start strategy before emulation started
                    strategy.Start();
                    candleManager.Start(series);

                    // start historical data loading when connection established successfully and all data subscribed
                    connector.Start();
                };

                // fill parameters panel
                statistic.Parameters.Clear();
                statistic.Parameters.AddRange(strategy.StatisticManager.Parameters);

                var equity = set.Item6;

                var pnlCurve           = equity.CreateCurve(LocalizedStrings.PnL + " " + emulationInfo.StrategyName, emulationInfo.CurveColor, LineChartStyles.Area);
                var unrealizedPnLCurve = equity.CreateCurve(LocalizedStrings.PnLUnreal + " " + emulationInfo.StrategyName, Colors.Black);
                var commissionCurve    = equity.CreateCurve(LocalizedStrings.Str159 + " " + emulationInfo.StrategyName, Colors.Red, LineChartStyles.DashedLine);
                var posItems           = set.Item7.CreateCurve(emulationInfo.StrategyName, emulationInfo.CurveColor);
                strategy.PnLChanged += () =>
                {
                    var pnl = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.PnL - strategy.Commission ?? 0
                    };

                    var unrealizedPnL = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.PnLManager.UnrealizedPnL ?? 0
                    };

                    var commission = new EquityData
                    {
                        Time  = strategy.CurrentTime,
                        Value = strategy.Commission ?? 0
                    };

                    pnlCurve.Add(pnl);
                    unrealizedPnLCurve.Add(unrealizedPnL);
                    commissionCurve.Add(commission);
                };

                strategy.PositionChanged += () => posItems.Add(new EquityData {
                    Time = strategy.CurrentTime, Value = strategy.Position
                });

                var nextTime = startTime + progressStep;

                // handle historical time for update ProgressBar
                connector.MarketTimeChanged += d =>
                {
                    if (connector.CurrentTime < nextTime && connector.CurrentTime < stopTime)
                    {
                        return;
                    }

                    var steps = (connector.CurrentTime - startTime).Ticks / progressStep.Ticks + 1;
                    nextTime = startTime + (steps * progressStep.Ticks).To <TimeSpan>();
                    this.GuiAsync(() => progressBar.Value = steps);
                };

                connector.StateChanged += () =>
                {
                    if (connector.State == EmulationStates.Stopped)
                    {
                        candleManager.Stop(series);
                        strategy.Stop();

                        SetIsChartEnabled(chart, false);

                        if (_connectors.All(c => c.State == EmulationStates.Stopped))
                        {
                            logManager.Dispose();
                            _connectors.Clear();

                            SetIsEnabled(true, false, false);
                        }

                        this.GuiAsync(() =>
                        {
                            if (connector.IsFinished)
                            {
                                progressBar.Value = progressBar.Maximum;
                                MessageBox.Show(this, LocalizedStrings.Str3024.Put(DateTime.Now - _startEmulationTime), title);
                            }
                            else
                            {
                                MessageBox.Show(this, LocalizedStrings.cancelled, title);
                            }
                        });
                    }
                    else if (connector.State == EmulationStates.Started)
                    {
                        if (_connectors.All(c => c.State == EmulationStates.Started))
                        {
                            SetIsEnabled(false, true, true);
                        }

                        SetIsChartEnabled(chart, true);
                    }
                    else if (connector.State == EmulationStates.Suspended)
                    {
                        if (_connectors.All(c => c.State == EmulationStates.Suspended))
                        {
                            SetIsEnabled(true, false, true);
                        }
                    }
                };

                if (ShowDepth.IsChecked == true)
                {
                    MarketDepth.UpdateFormat(security);

                    connector.NewMessage += message =>
                    {
                        var quoteMsg = message as QuoteChangeMessage;

                        if (quoteMsg != null)
                        {
                            MarketDepth.UpdateDepth(quoteMsg);
                        }
                    };
                }

                _connectors.Add(connector);

                progressBar.Value = 0;
            }

            _startEmulationTime = DateTime.Now;

            // start emulation
            foreach (var connector in _connectors)
            {
                // raise NewSecurities and NewPortfolio for full fill strategy properties
                connector.Connect();

                // 1 cent commission for trade
                connector.SendInMessage(new CommissionRuleMessage
                {
                    Rule = new CommissionPerTradeRule {
                        Value = 0.01m
                    }
                });
            }

            TabControl.Items.Cast <TabItem>().First(i => i.Visibility == Visibility.Visible).IsSelected = true;
        }
コード例 #51
0
		/// <summary>
		/// Преобразовать первый уровень маркет-данных.
		/// </summary>
		/// <param name="message">Первый уровень маркет-данных.</param>
		/// <returns>Поток <see cref="ExecutionMessage"/>.</returns>
		public IEnumerable<ExecutionMessage> ToExecutionLog(Level1ChangeMessage message)
		{
			if (message == null)
				throw new ArgumentNullException("message");

			var retVal = new List<ExecutionMessage>();

			var bestBidPrice = 0m;
			var bestBidVolume = 0m;
			var bestAskPrice = 0m;
			var bestAskVolume = 0m;
			var lastTradePrice = 0m;
			var lastTradeVolume = 0m;

			foreach (var change in message.Changes)
			{
				switch (change.Key)
				{
					case Level1Fields.LastTradePrice:
						lastTradePrice = (decimal)change.Value;
						break;
					case Level1Fields.LastTradeVolume:
						lastTradeVolume = (decimal)change.Value;
						break;
					case Level1Fields.BestBidPrice:
						bestBidPrice = (decimal)change.Value;
						break;
					case Level1Fields.BestBidVolume:
						bestBidVolume = (decimal)change.Value;
						break;
					case Level1Fields.BestAskPrice:
						bestAskPrice = (decimal)change.Value;
						break;
					case Level1Fields.BestAskVolume:
						bestAskVolume = (decimal)change.Value;
						break;
				}
			}

			ProcessLevel1Depth(message, bestBidPrice, bestBidVolume, bestAskPrice, bestAskVolume, retVal);
			ProcessLevel1Trade(message, lastTradePrice, lastTradeVolume, retVal);

			return retVal;
		}
コード例 #52
0
		private void ProcessSubscriptions()
		{
			if (_subscribedLevel1.Count > 0)
			{
				var tickerReply = _client.GetTickers(_subscribedLevel1.Cache.Select(id => id.SecurityCode.ToBtceCode()));

				foreach (var ticker in tickerReply.Items.Values)
				{
					var l1Msg = new Level1ChangeMessage
					{
						SecurityId = new SecurityId
						{
							SecurityCode = ticker.Instrument.ToStockSharpCode(),
							BoardCode = _boardCode,
						},
						ServerTime = ticker.Timestamp.ApplyTimeZone(TimeHelper.Moscow)
					}
					.TryAdd(Level1Fields.Volume, (decimal)ticker.Volume)
					.TryAdd(Level1Fields.HighPrice, (decimal)ticker.HighPrice)
					.TryAdd(Level1Fields.LowPrice, (decimal)ticker.LowPrice)
					.TryAdd(Level1Fields.LastTradePrice, (decimal)ticker.LastPrice)

					// BTCE транслирует потенциальные цену для покупки и продажи
					.TryAdd(Level1Fields.BestBidPrice, (decimal)ticker.Ask)
					.TryAdd(Level1Fields.BestAskPrice, (decimal)ticker.Bid)
					.TryAdd(Level1Fields.AveragePrice, (decimal)ticker.AveragePrice);

					if (l1Msg.Changes.Count > 0)
						SendOutMessage(l1Msg);
				}
			}

			if (_subscribedDepths.Count > 0)
			{
				foreach (var group in _subscribedDepths.CachedPairs.GroupBy(p => p.Value))
				{
					var depthReply = _client.GetDepths(group.Key, group.Select(p => p.Key).Select(id => id.SecurityCode.ToBtceCode()));

					foreach (var pair in depthReply.Items)
					{
						SendOutMessage(new QuoteChangeMessage
						{
							SecurityId = new SecurityId
							{
								SecurityCode = pair.Key.ToStockSharpCode(),
								BoardCode = _boardCode,
							},
							Bids = pair.Value.Bids.Select(vp => vp.ToStockSharp(Sides.Buy)).ToArray(),
							Asks = pair.Value.Asks.Select(vp => vp.ToStockSharp(Sides.Sell)).ToArray(),
							ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
						});
					}
				}
			}

			if (_subscribedTicks.Count > 0)
			{
				var tradeReply = _client.GetTrades(_tickCount, _subscribedTicks.Cache.Select(id => id.SecurityCode.ToBtceCode()));

				// меняем на глубину 50
				_tickCount = 50;

				foreach (var pair in tradeReply.Items)
				{
					foreach (var trade in pair.Value.OrderBy(t => t.Id))
					{
						if (_lastTickId >= trade.Id)
							continue;

						_lastTickId = trade.Id;

						SendOutMessage(new ExecutionMessage
						{
							SecurityId = new SecurityId
							{
								SecurityCode = pair.Key.ToStockSharpCode(),
								BoardCode = _boardCode,
							},
							ExecutionType = ExecutionTypes.Tick,
							TradePrice = (decimal)trade.Price,
							Volume = (decimal)trade.Volume,
							TradeId = trade.Id,
							ServerTime = trade.Timestamp.ApplyTimeZone(TimeHelper.Moscow),
							OriginSide = trade.Side.ToStockSharp()
						});
					}
				}
			}
		}
コード例 #53
0
		private void OnProcessLevel1(string[] data)
		{
			var f = Wrapper.FieldsLevel1;

			foreach (var row in data)
			{
				var cols = row.ToColumns();
				var paperNo = f.PaperNo.GetValue(cols);
				var secId = new SecurityId { Native = paperNo };

				var l1Msg = new Level1ChangeMessage
				{
					SecurityId = secId,
					ServerTime = (f.LastUpdateDate.GetValue(cols).Date + f.LastUpdateTime.GetValue(cols).TimeOfDay).ApplyTimeZone(TimeHelper.Moscow)
				};

				l1Msg.Add(Level1Fields.State, f.TradingStatus.GetValue(cols));

				l1Msg.TryAdd(Level1Fields.MarginBuy, f.GoBuy.GetValue(cols));
				l1Msg.TryAdd(Level1Fields.MarginSell, f.GoSell.GetValue(cols));

				l1Msg.TryAdd(Level1Fields.OpenInterest, (decimal)f.OpenPosQty.GetValue(cols));

				var minPrice = f.MinDeal.GetValue(cols);
				var maxPrice = f.MaxDeal.GetValue(cols);

				l1Msg.TryAdd(Level1Fields.OpenPrice, f.OpenPrice.GetValue(cols));
				l1Msg.TryAdd(Level1Fields.ClosePrice, f.ClosePrice.GetValue(cols));
				l1Msg.TryAdd(Level1Fields.HighPrice, maxPrice);
				l1Msg.TryAdd(Level1Fields.LowPrice, minPrice);

				l1Msg.TryAdd(Level1Fields.BestBidPrice, f.Buy.GetValue(cols));
				l1Msg.TryAdd(Level1Fields.BestBidVolume, (decimal)f.BuyQty.GetValue(cols));
				l1Msg.TryAdd(Level1Fields.BestAskPrice, f.Sell.GetValue(cols));
				l1Msg.TryAdd(Level1Fields.BestAskVolume, (decimal)f.SellQty.GetValue(cols));

				l1Msg.TryAdd(Level1Fields.MinPrice, minPrice);
				l1Msg.TryAdd(Level1Fields.MaxPrice, maxPrice);

				l1Msg.TryAdd(Level1Fields.Multiplier, (decimal)f.LotSize.GetValue(cols));

				l1Msg.TryAdd(Level1Fields.ImpliedVolatility, f.Volatility.GetValue(cols));
				l1Msg.TryAdd(Level1Fields.TheorPrice, f.TheorPrice.GetValue(cols));

				l1Msg.TryAdd(Level1Fields.LastTradePrice, f.LastPrice.GetValue(cols));
				l1Msg.TryAdd(Level1Fields.LastTradeVolume, (decimal)f.LastQty.GetValue(cols));

				l1Msg.TryAdd(Level1Fields.PriceStep, f.PriceStep.GetValue(cols));

				l1Msg.TryAdd(Level1Fields.BidsVolume, (decimal)f.BuySQty.GetValue(cols));
				l1Msg.TryAdd(Level1Fields.BidsCount, f.BuyCount.GetValue(cols));
				l1Msg.TryAdd(Level1Fields.AsksVolume, (decimal)f.SellSQty.GetValue(cols));
				l1Msg.TryAdd(Level1Fields.AsksCount, f.SellCount.GetValue(cols));

				SendOutMessage(l1Msg);
			}
		}
コード例 #54
0
        private void OnSecurityChanged(string smartId, Tuple <decimal?, decimal?, DateTime> lastTrade, decimal?open, decimal?high, decimal?low, decimal?close, decimal?volume, QuoteChange bid, QuoteChange ask,
                                       decimal?openInt, Tuple <decimal?, decimal?> goBuySell, Tuple <decimal?, decimal?> goBase, Tuple <decimal?, decimal?> limits, int tradingStatus, Tuple <decimal?, decimal?> volatTheorPrice)
        {
            var secId = new SecurityId {
                Native = smartId
            };

            var message = new Level1ChangeMessage
            {
                SecurityId    = secId,
                ExtensionInfo = new Dictionary <object, object>
                {
                    { SmartComExtensionInfoHelper.SecurityOptionsMargin, goBase.Item1 },
                    { SmartComExtensionInfoHelper.SecurityOptionsSyntheticMargin, goBase.Item2 }
                },
                ServerTime = CurrentTime.Convert(TimeHelper.Moscow),
            };

            message.TryAdd(Level1Fields.LastTradePrice, lastTrade.Item1);
            message.TryAdd(Level1Fields.LastTradeVolume, lastTrade.Item2);
            message.Add(Level1Fields.LastTradeTime, lastTrade.Item3.ApplyTimeZone(TimeHelper.Moscow));

            var prevQuotes = _bestQuotes.TryGetValue(secId);

            if (bid.Price != 0)
            {
                message.Add(Level1Fields.BestBidPrice, bid.Price);

                if (prevQuotes != null && prevQuotes.First != null && prevQuotes.First.Item1 == bid.Price)
                {
                    message.Add(Level1Fields.BestBidVolume, prevQuotes.First.Item2);
                }
            }

            if (ask.Price != 0)
            {
                message.Add(Level1Fields.BestAskPrice, ask.Price);

                if (prevQuotes != null && prevQuotes.Second != null && prevQuotes.Second.Item1 == ask.Price)
                {
                    message.Add(Level1Fields.BestAskVolume, prevQuotes.Second.Item2);
                }
            }

            message.TryAdd(Level1Fields.BidsVolume, bid.Volume);
            message.TryAdd(Level1Fields.AsksVolume, ask.Volume);

            message.TryAdd(Level1Fields.OpenPrice, open);
            message.TryAdd(Level1Fields.LowPrice, low);
            message.TryAdd(Level1Fields.HighPrice, high);
            message.TryAdd(Level1Fields.ClosePrice, close);

            message.TryAdd(Level1Fields.MinPrice, limits.Item1);
            message.TryAdd(Level1Fields.MaxPrice, limits.Item2);

            message.TryAdd(Level1Fields.MarginBuy, goBuySell.Item1);
            message.TryAdd(Level1Fields.MarginSell, goBuySell.Item2);
            message.TryAdd(Level1Fields.OpenInterest, openInt);

            message.TryAdd(Level1Fields.ImpliedVolatility, volatTheorPrice.Item1);
            message.TryAdd(Level1Fields.TheorPrice, volatTheorPrice.Item2);

            message.TryAdd(Level1Fields.Volume, volume);

            message.Add(Level1Fields.State, tradingStatus == 0 ? SecurityStates.Trading : SecurityStates.Stoped);

            SendOutMessage(message);
        }
コード例 #55
0
		private void OnSessionMarketDataChanged(OrderBookEvent orderBookEvent)
		{
			var time = TimeHelper.GregorianStart.AddMilliseconds(orderBookEvent.Timestamp).ApplyTimeZone(TimeZoneInfo.Utc);
			var secId = new SecurityId { Native = orderBookEvent.InstrumentId };

			var l1Msg = new Level1ChangeMessage
			{
				ServerTime = time,
				SecurityId = secId,
			};

			if (orderBookEvent.HasMarketClosePrice)
				l1Msg.Add(Level1Fields.ClosePrice, orderBookEvent.MktClosePrice);

			if (orderBookEvent.HasDailyHighestTradedPrice)
				l1Msg.Add(Level1Fields.HighPrice, orderBookEvent.DailyHighestTradedPrice);

			if (orderBookEvent.HasDailyLowestTradedPrice)
				l1Msg.Add(Level1Fields.LowPrice, orderBookEvent.DailyLowestTradedPrice);

			if (orderBookEvent.HasLastTradedPrice)
			{
				l1Msg.Add(Level1Fields.LastTradePrice, orderBookEvent.LastTradedPrice);
			}

			SendOutMessage(l1Msg);

			SendOutMessage(new QuoteChangeMessage
			{
				SecurityId = secId,
				Bids = orderBookEvent.BidPrices.Select(p => new QuoteChange(Sides.Buy, p.Price, p.Quantity)),
				Asks = orderBookEvent.AskPrices.Select(p => new QuoteChange(Sides.Sell, p.Price, p.Quantity)),
				ServerTime = time
			});
		}