Пример #1
0
        public UnSubscribeTradeElementCommand(ChartTradeElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            Element = element;
        }
        public FuturesStrategy(IChart chart, ChartCandleElement candlesElem, ChartTradeElement tradesElem,
                               ICollection <Tuple <string, BaseIndicator, ChartIndicatorElement> > indicators, CandleSeries series)
        {
            strategyChart        = chart;
            strategyCandlesChart = candlesElem;
            strategyTradesChart  = tradesElem;

            strategyIndicators = indicators;
            strategySeries     = series;
        }
        private void InitChart()
        {
            Chart.ClearAreas();

            var area = new ChartArea();

            _candleElement = new ChartCandleElement();
            _tradesElem    = new ChartTradeElement {
                FullTitle = "Trade"
            };

            Chart.AddArea(area);
            Chart.AddElement(area, _candleElement);
            Chart.AddElement(area, _tradesElem);
        }
Пример #4
0
        public SubscribeTradeElementCommand(ChartTradeElement element, Security security)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            if (security == null)
            {
                throw new ArgumentNullException(nameof(security));
            }

            Element  = element;
            Security = security;
        }
Пример #5
0
		public SmaStrategy(IChart chart, ChartCandleElement candlesElem, ChartTradeElement tradesElem, 
			SimpleMovingAverage shortMa, ChartIndicatorElement shortElem,
			SimpleMovingAverage longMa, ChartIndicatorElement longElem,
			CandleSeries series)
		{
			_chart = chart;
			_candlesElem = candlesElem;
			_tradesElem = tradesElem;
			_shortElem = shortElem;
			_longElem = longElem;
			
			_series = series;

			ShortSma = shortMa;
			LongSma = longMa;
		}
Пример #6
0
        public SmaStrategy(IChart chart, ChartCandleElement candlesElem, ChartTradeElement tradesElem,
                           SimpleMovingAverage shortMa, ChartIndicatorElement shortElem,
                           SimpleMovingAverage longMa, ChartIndicatorElement longElem,
                           CandleSeries series)
        {
            _chart       = chart;
            _candlesElem = candlesElem;
            _tradesElem  = tradesElem;
            _shortElem   = shortElem;
            _longElem    = longElem;

            _series = series;

            ShortSma = shortMa;
            LongSma  = longMa;
        }
Пример #7
0
        public SmaStrategy(CandleSeries series,
                           SimpleMovingAverage longSma, SimpleMovingAverage shortSma,
                           IChart chart, ChartCandleElement candlesElem, ChartTradeElement tradesElem,
                           ChartIndicatorElement longElem, ChartIndicatorElement shortElem)
        {
            _series = new Subscription(series);

            ShortSma = shortSma;
            LongSma  = longSma;

            _chart       = chart;
            _candlesElem = candlesElem;
            _tradesElem  = tradesElem;
            _shortElem   = shortElem;
            _longElem    = longElem;
        }
Пример #8
0
        public RiskStrategy(IChart chart, ChartCandleElement candlesElem,
                            ChartTradeElement tradesElem, ChartIndicatorElement shortElem, ChartIndicatorElement longElem,
                            CandleSeries series)
        {
            _chart       = chart;
            _candlesElem = candlesElem;
            _tradesElem  = tradesElem;
            _shortElem   = shortElem;
            _longElem    = longElem;

            _series = series;

            LongATR  = (AverageTrueRange)longElem.Indicator;
            ShortATR = (AverageTrueRange)shortElem.Indicator;
            // PLB = new ParabolicSar();
        }
Пример #9
0
        private void InitChart(IChart chart, EquityCurveChart equity, EquityCurveChart position)
        {
            chart.ClearAreas();
            equity.Clear();
            position.Clear();

            _area = new ChartArea();
            chart.AddArea(_area);

            _candlesElem = new ChartCandleElement {
                ShowAxisMarker = false
            };
            chart.AddElement(_area, _candlesElem);

            _tradesElem = new ChartTradeElement {
                FullTitle = LocalizedStrings.Str985
            };
            chart.AddElement(_area, _tradesElem);
        }
Пример #10
0
        private void InitChart()
        {
            _bufferedChart.ClearAreas();
            Curve.Clear();
            PositionCurve.Clear();

            _area = new ChartArea();
            _bufferedChart.AddArea(_area);

            _candlesElem = new ChartCandleElement {
                ShowAxisMarker = false
            };
            _bufferedChart.AddElement(_area, _candlesElem);

            _tradesElem = new ChartTradeElement {
                FullTitle = "Сделки"
            };
            _bufferedChart.AddElement(_area, _tradesElem);
        }
        private void InitChart()
        {
            bufferedChart.ClearAreas();
            Curve.Clear();
            PositionCurve.Clear();

            area = new ChartArea();
            bufferedChart.AddArea(area);

            candlesElem = new ChartCandleElement {
                ShowAxisMarker = false
            };
            bufferedChart.AddElement(area, candlesElem);

            tradesElem = new ChartTradeElement {
                FullTitle = "Сделки",
            };
            bufferedChart.AddElement(area, tradesElem);
        }
Пример #12
0
        private void InitChart()
        {
            Chart.ClearAreas();
            Curve.Clear();
            PositionCurve.Clear();

            _area = new ChartArea();
            Chart.AddArea(_area);

            _candlesElem = new ChartCandleElement {
                ShowAxisMarker = false
            };
            Chart.AddElement(_area, _candlesElem);

            _tradesElem = new ChartTradeElement {
                FullTitle = LocalizedStrings.Str985
            };
            Chart.AddElement(_area, _tradesElem);
        }
Пример #13
0
        private void InitChart(EMAEventModelStrategy strategy)
        {
            _longMA = new ExponentialMovingAverage { Length = strategy.LongMA.Length};
            _shortMA = new ExponentialMovingAverage { Length = strategy.ShortMA.Length };
            _filterMA = new ExponentialMovingAverage { Length = strategy.FilterMA.Length };

            _area.Elements.Clear();

            _candlesElem = new ChartCandleElement()
            {
                DownBodyColor = Color.FromRgb(133, 133, 133),
                UpBodyColor = Color.FromRgb(255, 255, 255)
            };
            _area.Elements.Add(_candlesElem);

            _longMaElem = new ChartIndicatorElement
            {
                Title = "LongMA",
                Indicator = _longMA,
                Color = Color.FromRgb(120, 199, 130)
            };
            _area.Elements.Add(_longMaElem);

            _shortMaElem = new ChartIndicatorElement
            {
                Title = "ShortMA",
                Indicator = _shortMA,
                Color = Color.FromRgb(193, 53, 45)
            };
            _area.Elements.Add(_shortMaElem);

            _filterMaElem = new ChartIndicatorElement
            {
                Title = "FilterMA",
                Indicator = _filterMA,
                Color = Color.FromRgb(0, 124, 207)
            };
            _area.Elements.Add(_filterMaElem);

            _tradeElem = new ChartTradeElement()
            {
                BuyColor = Color.FromRgb(255, 0, 0),
                SellColor = Color.FromRgb(0, 0, 255),
                IsLegend = true
            };
            _area.Elements.Add(_tradeElem);
        }
Пример #14
0
        private void Download_OnClick(object sender, RoutedEventArgs e)
        {
            var year = SelectedYear;
            var from = From.Value ?? year.Days.First();
            var to = (To.Value ?? year.Days.Last()).EndOfDay();
            var trader = SelectedTrader;
            var tf = SelectedTimeFrame;

            var seriesSet = _securityCtrls
                .Where(pair => pair.Key.SelectedSecurity != null)
                .Select(pair => Tuple.Create(new CandleSeries(typeof(TimeFrameCandle), pair.Key.SelectedSecurity, tf), pair.Value))
                .ToArray();

            BusyIndicator.BusyContent = "Подготовка данных...";
            BusyIndicator.IsBusy = true;

            _candles.Clear();

            var trades = new Dictionary<Security, Dictionary<DateTimeOffset, Tuple<MyTrade[], MyTrade>>>();

            var worker = new BackgroundWorker { WorkerReportsProgress = true };

            worker.DoWork += (o, ea) =>
            {
                foreach (var series in seriesSet)
                {
                    var security = series.Item1.Security;
                    var candleStorage = _dataRegistry.GetCandleStorage(series.Item1, format: StorageFormats.Csv);
                    var secCandles = _candles.SafeAdd(security);

                    secCandles.Clear();
                    secCandles.AddRange(candleStorage.Load(from, to));

                    var candlesDatesCache = _candlesDates.SafeAdd(Tuple.Create(security, tf), k => new DatesCache(Path.Combine(((LocalMarketDataDrive)candleStorage.Drive.Drive).GetSecurityPath(security.ToSecurityId()), "{0}min_date.bin".Put((int)tf.TotalMinutes))));

                    var minCandleDate = candlesDatesCache.MinValue;
                    var maxCandleDate = candlesDatesCache.MaxValue;

                    if (from >= minCandleDate && to <= maxCandleDate)
                        continue;

                    var finamFrom = from;
                    var finamTo = to;

                    if (maxCandleDate != null && finamFrom >= minCandleDate && finamFrom <= maxCandleDate)
                        finamFrom = maxCandleDate.Value + TimeSpan.FromDays(1);

                    if (minCandleDate != null && finamTo >= minCandleDate && finamTo <= maxCandleDate)
                        finamTo = minCandleDate.Value - TimeSpan.FromDays(1);

                    if (finamTo <= finamFrom)
                        continue;

                    worker.ReportProgress(1, Tuple.Create(security, finamFrom, finamTo));

                    var newCandles = (tf.Ticks == 1
                        ? finamFrom.Range(finamTo, TimeSpan.FromDays(1)).SelectMany(day => _finamHistorySource.GetTrades(security, day, day)).ToEx().ToCandles<TimeFrameCandle>(tf)
                        : _finamHistorySource.GetCandles(security, tf, finamFrom, finamTo)
                        ).ToArray();

                    candleStorage.Save(newCandles);

                    foreach (var date in newCandles.Select(c => c.OpenTime.Date).Distinct())
                        candlesDatesCache.Add(date);

                    candlesDatesCache.Save();

                    // TODO
                    secCandles.AddRange(newCandles);
                }

                var traderDrive = new LocalMarketDataDrive(trader);
                var traderStorage = _traderStorages.SafeAdd(trader, key => new StorageRegistry { DefaultDrive = traderDrive });

                foreach (var series in seriesSet)
                {
                    var security = series.Item1.Security;

                    var olStorage = traderStorage.GetOrderLogStorage(security, format: StorageFormats.Csv);
                    var tradeDatesCache = _tradesDates.SafeAdd(trader, k => new DatesCache(Path.Combine(traderDrive.Path, "dates.bin")));

                    var secTrades = from
                        .Range(to, TimeSpan.FromDays(1))
                        .Intersect(year.Days)
                        .SelectMany(date =>
                        {
                            if (olStorage.Dates.Contains(date))
                                return olStorage.Load(date);

                            if (tradeDatesCache.Contains(date))
                                return Enumerable.Empty<OrderLogItem>();

                            worker.ReportProgress(2, date);

                            var loadedTrades = year.GetTrades(_securityStorage, trader, date);

                            var dateTrades = Enumerable.Empty<OrderLogItem>();

                            foreach (var group in loadedTrades.GroupBy(t => t.Order.Security))
                            {
                                var sec = group.Key;

                                traderStorage
                                    .GetOrderLogStorage(sec, format: StorageFormats.Csv)
                                    .Save(group.OrderBy(i => i.Order.Time));

                                if (group.Key == security)
                                    dateTrades = group;
                            }

                            tradeDatesCache.Add(date);
                            tradeDatesCache.Save();

                            return dateTrades;
                        })
                        .GroupBy(ol =>
                        {
                            var time = ol.Order.Time;

                            var period = security.Board.WorkingTime.GetPeriod(time.ToLocalTime(security.Board.Exchange.TimeZoneInfo));
                            if (period != null && period.Times.Length > 0)
                            {
                                var last = period.Times.Last().Max;

                                if (time.TimeOfDay >= last)
                                    time = time.AddTicks(-1);
                            }

                            return time.Truncate(tf);
                        })
                        .ToDictionary(g => g.Key, g =>
                        {
                            var candleTrades = g.Select(ol => new MyTrade
                            {
                                Order = ol.Order,
                                Trade = ol.Trade
                            })
                            .ToArray();

                            if (candleTrades.Length == 0)
                                return null;

                            var order = candleTrades[0].Order;
                            var volume = candleTrades.Sum(t1 => t1.Trade.Volume * (t1.Order.Direction == Sides.Buy ? 1 : -1));

                            if (volume == 0)
                                return Tuple.Create(candleTrades, (MyTrade)null);

                            var side = volume > 0 ? Sides.Buy : Sides.Sell;

                            volume = volume.Abs();

                            var availableVolume = volume;
                            var avgPrice = 0m;

                            foreach (var trade in candleTrades.Where(t1 => t1.Order.Direction == side))
                            {
                                var tradeVol = trade.Trade.Volume.Min(availableVolume);
                                avgPrice += trade.Trade.Price * tradeVol;

                                availableVolume -= tradeVol;

                                if (availableVolume <= 0)
                                    break;
                            }

                            avgPrice = avgPrice / volume;

                            return Tuple.Create(candleTrades, new MyTrade
                            {
                                Order = new Order
                                {
                                    Security = order.Security,
                                    Direction = side,
                                    Time = g.Key,
                                    Portfolio = order.Portfolio,
                                    Price = avgPrice,
                                    Volume = volume,
                                },
                                Trade = new Trade
                                {
                                    Security = order.Security,
                                    Time = g.Key,
                                    Volume = volume,
                                    Price = avgPrice
                                }
                            });
                        });

                    trades.Add(security, secTrades);
                }
            };

            worker.ProgressChanged += (o, ea) =>
            {
                switch (ea.ProgressPercentage)
                {
                    case 1:
                        BusyIndicator.BusyContent = "Скачивание {Item1.Id} свечей с {Item2:yyyy-MM-dd} по {Item3:yyyy-MM-dd}...".PutEx(ea.UserState);
                        break;

                    default:
                        BusyIndicator.BusyContent = "Скачивание сделок за {0:yyyy-MM-dd}...".Put(ea.UserState);
                        break;
                }
            };

            worker.RunWorkerCompleted += (o, ea) =>
            {
                BusyIndicator.IsBusy = false;

                if (ea.Error == null)
                {
                    Chart.ClearAreas();

                    _statisticManager.Reset();

                    var candlesArea = new ChartArea();
                    Chart.AddArea(candlesArea);

                    var positionArea = new ChartArea { Height = 200 };
                    Chart.AddArea(positionArea);
                    positionArea.YAxises.Clear();

                    const string equityYAxis = "Equity";

                    candlesArea.YAxises.Clear();
                    candlesArea.YAxises.Add(new ChartAxis
                    {
                        Id = equityYAxis,
                        AutoRange = true,
                        AxisType = ChartAxisType.Numeric,
                        AxisAlignment = ChartAxisAlignment.Left,
                    });
                    var equityElem = new ChartIndicatorElement
                    {
                        YAxisId = equityYAxis,
                        FullTitle = LocalizedStrings.PnL,
                        IndicatorPainter = new PnlPainter()
                    };
                    var equityInd = new SimpleMovingAverage { Length = 1 };
                    Chart.AddElement(candlesArea, equityElem);

                    var chartValues = new SortedDictionary<DateTimeOffset, IDictionary<IChartElement, object>>();
                    var pnlValues = new Dictionary<DateTimeOffset, decimal>();

                    foreach (var series in seriesSet)
                    {
                        var security = series.Item1.Security;

                        var candleYAxis = "Candles_Y_" + security.Id;

                        candlesArea.YAxises.Add(new ChartAxis
                        {
                            Id = candleYAxis,
                            AutoRange = true,
                            AxisType = ChartAxisType.Numeric,
                            AxisAlignment = ChartAxisAlignment.Right,
                        });

                        var candlesElem = new ChartCandleElement
                        {
                            ShowAxisMarker = false,
                            YAxisId = candleYAxis,
                        };
                        Chart.AddElement(candlesArea, candlesElem, series.Item1);

                        var tradesElem = new ChartTradeElement
                        {
                            BuyStrokeColor = Colors.Black,
                            SellStrokeColor = Colors.Black,
                            BuyColor = series.Item2.Buy,
                            SellColor = series.Item2.Sell,
                            FullTitle = LocalizedStrings.Str985 + " " + security.Id,
                            YAxisId = candleYAxis,
                        };
                        Chart.AddElement(candlesArea, tradesElem);

                        var posYAxis = "Pos_Y_" + security.Id;
                        positionArea.YAxises.Add(new ChartAxis
                        {
                            Id = posYAxis,
                            AutoRange = true,
                            AxisType = ChartAxisType.Numeric,
                            AxisAlignment = ChartAxisAlignment.Right,
                        });
                        var positionElem = new ChartIndicatorElement
                        {
                            FullTitle = LocalizedStrings.Str862 + " " + security.Id,
                            YAxisId = posYAxis,
                            Color = series.Item2.Position
                        };
                        var positionInd = new SimpleMovingAverage { Length = 1 };
                        Chart.AddElement(positionArea, positionElem);

                        var pnlQueue = new PnLQueue(security.ToSecurityId());
                        //var level1Info = new Level1ChangeMessage
                        //{
                        //	SecurityId = pnlQueue.SecurityId,
                        //}
                        //.TryAdd(Level1Fields.PriceStep, security.PriceStep)
                        //.TryAdd(Level1Fields.StepPrice, security.StepPrice);

                        //pnlQueue.ProcessLevel1(level1Info);

                        var pos = 0m;

                        var secTrades = trades[security];

                        var secValues = _candles[security]
                            .Select(c =>
                            {
                                if (c.State != CandleStates.Finished)
                                    c.State = CandleStates.Finished;

                                pnlQueue.ProcessLevel1(new Level1ChangeMessage
                                {
                                    SecurityId = security.ToSecurityId(),
                                }.TryAdd(Level1Fields.LastTradePrice, c.ClosePrice));

                                var values = new Dictionary<IChartElement, object>
                                {
                                    { candlesElem, c },
                                };

                                var candleTrade = secTrades.TryGetValue(c.OpenTime);

                                if (candleTrade != null)
                                {
                                    if (candleTrade.Item2 != null)
                                        values.Add(tradesElem, candleTrade.Item2);

                                    foreach (var myTrade in candleTrade.Item1)
                                    {
                                        pos += myTrade.Order.Direction == Sides.Buy ? myTrade.Trade.Volume : -myTrade.Trade.Volume;
                                        var pnl = pnlQueue.Process(myTrade.ToMessage());

                                        _statisticManager.AddMyTrade(pnl);
                                    }

                                    _statisticManager.AddPosition(c.OpenTime, pos);
                                    _statisticManager.AddPnL(c.OpenTime, pnlQueue.RealizedPnL + pnlQueue.UnrealizedPnL);
                                }

                                pnlValues[c.OpenTime] = pnlValues.TryGetValue(c.OpenTime) + (pnlQueue.RealizedPnL + pnlQueue.UnrealizedPnL);
                                values.Add(positionElem, positionInd.Process(pos));

                                return new RefPair<DateTimeOffset, IDictionary<IChartElement, object>>
                                {
                                    First = c.OpenTime,
                                    Second = values
                                };
                            })
                            .ToArray();

                        foreach (var pair in secValues)
                        {
                            var dict = chartValues.SafeAdd(pair.First, key => new Dictionary<IChartElement, object>());

                            foreach (var pair2 in pair.Second)
                            {
                                dict[pair2.Key] = pair2.Value;
                            }
                        }
                    }

                    foreach (var pair in pnlValues)
                    {
                        chartValues[pair.Key].Add(equityElem, equityInd.Process(pair.Value));
                    }

                    Chart.IsAutoRange = true;

                    try
                    {
                        Chart.Draw(chartValues.Select(p => RefTuple.Create(p.Key, p.Value)));
                    }
                    finally
                    {
                        Chart.IsAutoRange = false;
                    }
                }
                else
                {
                    new MessageBoxBuilder()
                        .Error()
                        .Owner(this)
                        .Text(ea.Error.ToString())
                        .Show();
                }
            };

            worker.RunWorkerAsync();
        }
Пример #15
0
		private void OnChartPanelSubscribeTradeElement(ChartTradeElement element, Security security)
		{
			new SubscribeTradeElementCommand(element, security).Process(this);
		}
Пример #16
0
        private void Download_OnClick(object sender, RoutedEventArgs e)
        {
            var year     = SelectedYear;
            var from     = From.Value ?? year.Days.First();
            var to       = (To.Value ?? year.Days.Last()).EndOfDay();
            var trader   = SelectedTrader;
            var security = SelectedSecurity;
            var tf       = SelectedTimeFrame;
            var series   = new CandleSeries(typeof(TimeFrameCandle), security, tf);

            BusyIndicator.BusyContent = "Подготовка данных...";
            BusyIndicator.IsBusy      = true;

            Dictionary <DateTimeOffset, Tuple <MyTrade[], MyTrade> > trades = null;

            var worker = new BackgroundWorker {
                WorkerReportsProgress = true
            };

            worker.DoWork += (o, ea) =>
            {
                var candleStorage = _dataRegistry.GetCandleStorage(series, format: StorageFormats.Csv);

                _candles = candleStorage.Load(from, to);

                var candlesDatesCache = _candlesDates.SafeAdd(Tuple.Create(security, tf), k => new DatesCache(Path.Combine(((LocalMarketDataDrive)candleStorage.Drive.Drive).GetSecurityPath(security.ToSecurityId()), "{0}min_date.bin".Put((int)tf.TotalMinutes))));

                var minCandleDate = candlesDatesCache.MinValue;
                var maxCandleDate = candlesDatesCache.MaxValue;

                if (from < minCandleDate || to > maxCandleDate)
                {
                    var finamFrom = from;
                    var finamTo   = to;

                    if (maxCandleDate != default(DateTime) && finamFrom >= minCandleDate && finamFrom <= maxCandleDate)
                    {
                        finamFrom = maxCandleDate + TimeSpan.FromDays(1);
                    }

                    if (minCandleDate != default(DateTime) && finamTo >= minCandleDate && finamTo <= maxCandleDate)
                    {
                        finamTo = minCandleDate - TimeSpan.FromDays(1);
                    }

                    if (finamTo > finamFrom)
                    {
                        worker.ReportProgress(1);

                        var newCandles = (tf.Ticks == 1
                                                        ? finamFrom.Range(finamTo, TimeSpan.FromDays(1)).SelectMany(day => _finamHistorySource.GetTrades(security, day, day)).ToEx().ToCandles <TimeFrameCandle>(tf)
                                                        : _finamHistorySource.GetCandles(security, tf, finamFrom, finamTo)
                                          ).ToArray();

                        candleStorage.Save(newCandles);

                        foreach (var date in newCandles.Select(c => c.OpenTime.Date).Distinct())
                        {
                            candlesDatesCache.Add(date);
                        }

                        candlesDatesCache.Save();

                        _candles = _candles.Concat(newCandles);
                    }
                }

                var traderDrive   = new LocalMarketDataDrive(trader);
                var traderStorage = _traderStorages.SafeAdd(trader, key => new StorageRegistry {
                    DefaultDrive = traderDrive
                });

                var olStorage       = traderStorage.GetOrderLogStorage(security, format: StorageFormats.Csv);
                var tradeDatesCache = _tradesDates.SafeAdd(trader, k => new DatesCache(Path.Combine(traderDrive.Path, "dates.bin")));

                trades = from
                         .Range(to, TimeSpan.FromDays(1))
                         .Intersect(year.Days)
                         .SelectMany(date =>
                {
                    if (olStorage.Dates.Contains(date))
                    {
                        return(olStorage.Load(date));
                    }

                    if (tradeDatesCache.Contains(date))
                    {
                        return(Enumerable.Empty <OrderLogItem>());
                    }

                    worker.ReportProgress(2, date);

                    var loadedTrades = year.GetTrades(_securityStorage, trader, date);

                    var secTrades = Enumerable.Empty <OrderLogItem>();

                    foreach (var group in loadedTrades.GroupBy(t => t.Order.Security))
                    {
                        var sec = group.Key;

                        traderStorage
                        .GetOrderLogStorage(sec, format: StorageFormats.Csv)
                        .Save(group.OrderBy(i => i.Order.Time));

                        if (group.Key == security)
                        {
                            secTrades = group;
                        }
                    }

                    tradeDatesCache.Add(date);
                    tradeDatesCache.Save();

                    return(secTrades);
                })
                         .GroupBy(ol =>
                {
                    var time = ol.Order.Time;

                    var period = security.Board.WorkingTime.GetPeriod(time.DateTime);
                    if (period != null && period.Times.Length > 0)
                    {
                        var last = period.Times.Last().Max;

                        if (time.TimeOfDay >= last)
                        {
                            time = time.AddTicks(-1);
                        }
                    }

                    return(time.Truncate(tf));
                })
                         .ToDictionary(g => g.Key, g =>
                {
                    var candleTrades = g
                                       .Select(order => new MyTrade
                    {
                        Order = order.Order,
                        Trade = order.Trade
                    })
                                       .ToArray();

                    if (candleTrades.Length > 0)
                    {
                        var order  = candleTrades[0].Order;
                        var volume = candleTrades.Sum(t1 => t1.Trade.Volume * (t1.Order.Direction == Sides.Buy ? 1 : -1));

                        if (volume == 0)
                        {
                            return(Tuple.Create(candleTrades, (MyTrade)null));
                        }

                        var side = volume > 0 ? Sides.Buy : Sides.Sell;

                        volume = volume.Abs();

                        var availableVolume = volume;
                        var avgPrice        = 0m;

                        foreach (var trade in candleTrades.Where(t1 => t1.Order.Direction == side))
                        {
                            var tradeVol = trade.Trade.Volume.Min(availableVolume);
                            avgPrice    += trade.Trade.Price * tradeVol;

                            availableVolume -= tradeVol;

                            if (availableVolume <= 0)
                            {
                                break;
                            }
                        }

                        avgPrice = avgPrice / volume;

                        return(Tuple.Create(candleTrades, new MyTrade
                        {
                            Order = new Order
                            {
                                Security = order.Security,
                                Direction = side,
                                Time = g.Key,
                                Portfolio = order.Portfolio,
                                Price = avgPrice,
                                Volume = volume,
                            },
                            Trade = new Trade
                            {
                                Security = order.Security,
                                Time = g.Key,
                                Volume = volume,
                                Price = avgPrice
                            }
                        }));
                    }

                    return(null);
                });
            };

            worker.ProgressChanged += (o, ea) =>
            {
                switch (ea.ProgressPercentage)
                {
                case 1:
                    BusyIndicator.BusyContent = "Скачивание свечей...";
                    break;

                default:
                    BusyIndicator.BusyContent = "Скачивание сделок за {0:yyyy-MM-dd}...".Put(ea.UserState);
                    break;
                }
            };

            worker.RunWorkerCompleted += (o, ea) =>
            {
                BusyIndicator.IsBusy = false;

                if (ea.Error == null)
                {
                    Chart.ClearAreas();
                    _statisticManager.Reset();

                    var area = new ChartArea();
                    area.YAxises.Add(new ChartAxis
                    {
                        Id            = "equity",
                        AutoRange     = true,
                        AxisType      = ChartAxisType.Numeric,
                        AxisAlignment = ChartAxisAlignment.Left,
                    });
                    Chart.AddArea(area);

                    var candlesElem = new ChartCandleElement {
                        ShowAxisMarker = false
                    };
                    Chart.AddElement(area, candlesElem, series);

                    var tradesElem = new ChartTradeElement
                    {
                        BuyStrokeColor  = Colors.Black,
                        SellStrokeColor = Colors.Black,
                        FullTitle       = "trades",
                    };
                    Chart.AddElement(area, tradesElem);

                    var equityElem = new ChartIndicatorElement {
                        YAxisId = "equity", FullTitle = "equity", IndicatorPainter = new PnlPainter()
                    };
                    var equityInd = new SimpleMovingAverage {
                        Length = 1
                    };
                    Chart.AddElement(area, equityElem);

                    var positionArea = new ChartArea {
                        Height = 200
                    };
                    Chart.AddArea(positionArea);

                    var positionElem = new ChartIndicatorElement {
                        FullTitle = "position"
                    };
                    var positionInd = new SimpleMovingAverage {
                        Length = 1
                    };
                    Chart.AddElement(positionArea, positionElem);

                    Chart.IsAutoRange = true;

                    var pnlQueue = new PnLQueue(security.ToSecurityId());
                    //var level1Info = new Level1ChangeMessage
                    //{
                    //	SecurityId = pnlQueue.SecurityId,
                    //}
                    //.TryAdd(Level1Fields.PriceStep, security.PriceStep)
                    //.TryAdd(Level1Fields.StepPrice, security.StepPrice);

                    //pnlQueue.ProcessLevel1(level1Info);

                    var pos = 0m;

                    var chartValues = _candles
                                      .Select(c =>
                    {
                        c.State = CandleStates.Finished;

                        pnlQueue.ProcessLevel1(new Level1ChangeMessage
                        {
                            SecurityId = security.ToSecurityId(),
                        }.TryAdd(Level1Fields.LastTradePrice, c.ClosePrice));

                        var values = new Dictionary <IChartElement, object>
                        {
                            { candlesElem, c },
                        };

                        var candleTrade = trades.TryGetValue(c.OpenTime);

                        if (candleTrade != null)
                        {
                            if (candleTrade.Item2 != null)
                            {
                                values.Add(tradesElem, candleTrade.Item2);
                            }

                            foreach (var myTrade in candleTrade.Item1)
                            {
                                pos    += myTrade.Order.Direction == Sides.Buy ? myTrade.Trade.Volume : -myTrade.Trade.Volume;
                                var pnl = pnlQueue.Process(myTrade.ToMessage());

                                _statisticManager.AddMyTrade(pnl);
                            }

                            _statisticManager.AddPosition(c.OpenTime, pos);
                            _statisticManager.AddPnL(c.OpenTime, pnlQueue.RealizedPnL + pnlQueue.UnrealizedPnL);
                        }

                        values.Add(equityElem, equityInd.Process(pnlQueue.RealizedPnL + pnlQueue.UnrealizedPnL));
                        values.Add(positionElem, positionInd.Process(pos));

                        return(new RefPair <DateTimeOffset, IDictionary <IChartElement, object> >
                        {
                            First = c.OpenTime,
                            Second = values
                        });
                    })
                                      .ToArray();

                    Chart.Draw(chartValues);

                    Chart.IsAutoRange = false;
                }
                else
                {
                    new MessageBoxBuilder()
                    .Error()
                    .Owner(this)
                    .Text(ea.Error.ToString())
                    .Show();
                }
            };

            worker.RunWorkerAsync();
        }
Пример #17
0
        private void InitCharts()
        {
            Chart.ClearAreas();

            _area = new ChartArea {
                ShowPerfStats = true
            };

            var yAxis = _area.YAxises.First();

            yAxis.AutoRange    = true;
            Chart.IsAutoRange  = true;
            Chart.IsAutoScroll = true;

            Chart.AddArea(_area);

            var series = new CandleSeries(
                typeof(TimeFrameCandle),
                _security,
                TimeSpan.FromMinutes(Timeframe));

            _indicatorElement = null;
            _tradeElement     = null;

            _candleElement = new ChartCandleElement(Timeframe, PriceStep)
            {
                FullTitle = "Candles", YAxisId = yAxis.Id
            };
            Chart.AddElement(_area, _candleElement, series);

            if (AddIndicator)
            {
                _indicator = new MyMovingAverage(200)
                {
                    Name = "MyMA"
                };

                _indicatorElement = new ChartIndicatorElement
                {
                    DrawStyle       = ChartIndicatorDrawStyles.Line,
                    Antialiasing    = true,
                    StrokeThickness = 1,
                    Color           = Colors.Blue,
                    YAxisId         = yAxis.Id,
                };

                Chart.AddElement(_area, _indicatorElement, series, _indicator);
            }

            if (AddTrades)
            {
                _tradeElement = new ChartTradeElement {
                    FullTitle = "Trades"
                };
                Chart.AddElement(_area, _tradeElement, _security);
            }

            var ns = typeof(IIndicator).Namespace;

            var rendererTypes = typeof(Chart).Assembly
                                .GetTypes()
                                .Where(t => !t.IsAbstract && typeof(BaseChartIndicatorPainter).IsAssignableFrom(t))
                                .ToDictionary(t => t.Name);

            var indicators = typeof(IIndicator).Assembly
                             .GetTypes()
                             .Where(t => t.Namespace == ns && !t.IsAbstract && typeof(IIndicator).IsAssignableFrom(t))
                             .Select(t =>
            {
                var name = t.Name;
                var p    = rendererTypes.TryGetValue(name + "Painter");
                if (p == null)
                {
                    if (t.Name.EndsWith("Indicator"))
                    {
                        name = name.Substring(0, name.Length - "Indicator".Length);
                    }

                    p = rendererTypes.TryGetValue(name + "Painter");
                }

                return(new IndicatorType(t, p));
            })
                             .ToArray();

            Chart.IndicatorTypes.AddRange(indicators);
        }
Пример #18
0
		private void InitChart()
		{
			_bufferedChart.ClearAreas();
			Curve.Clear();
			PositionCurve.Clear();

			_area = new ChartArea();
			_bufferedChart.AddArea(_area);

			_candlesElem = new ChartCandleElement { ShowAxisMarker = false };
			_bufferedChart.AddElement(_area, _candlesElem);

			_tradesElem = new ChartTradeElement { FullTitle = "Сделки" };
			_bufferedChart.AddElement(_area, _tradesElem);
		}
Пример #19
0
        private void Download_OnClick(object sender, RoutedEventArgs e)
        {
            var settings = new Settings
            {
                Year      = SelectedYear.Year,
                Trader    = Trader.Text,
                From      = From.Value,
                To        = To.Value,
                Security1 = Security1.Text,
                Security2 = Security2.Text,
                Security3 = Security3.Text,
                Security4 = Security4.Text,
                TimeFrame = SelectedTimeFrame,
                Apart     = Apart.IsChecked == true,
            };

            CultureInfo.InvariantCulture.DoInCulture(() => new XmlSerializer <SettingsStorage>().Serialize(settings.Save(), _settingsFile));

            var year   = SelectedYear;
            var from   = From.Value ?? year.Days.First();
            var to     = (To.Value ?? year.Days.Last()).EndOfDay();
            var trader = SelectedTrader;
            var tf     = SelectedTimeFrame;
            var apart  = Apart.IsChecked == true;

            var seriesSet = _securityCtrls
                            .Where(pair => pair.Key.SelectedSecurity != null)
                            .Select(pair => Tuple.Create(new CandleSeries(typeof(TimeFrameCandle), pair.Key.SelectedSecurity, tf), pair.Value))
                            .ToArray();

            BusyIndicator.BusyContent = "Подготовка данных...";
            BusyIndicator.IsBusy      = true;

            _candles.Clear();

            var trades = new Dictionary <Security, Dictionary <DateTimeOffset, Tuple <MyTrade[], MyTrade> > >();

            var worker = new BackgroundWorker {
                WorkerReportsProgress = true
            };

            worker.DoWork += (o, ea) =>
            {
                foreach (var series in seriesSet)
                {
                    var security      = series.Item1.Security;
                    var candleStorage = _dataRegistry.GetCandleStorage(series.Item1, format: StorageFormats.Csv);
                    var secCandles    = _candles.SafeAdd(security);

                    secCandles.Clear();
                    secCandles.AddRange(candleStorage.Load(from, to));

                    var candlesDatesCache = _candlesDates.SafeAdd(Tuple.Create(security, tf), k => new DatesCache(Path.Combine(((LocalMarketDataDrive)candleStorage.Drive.Drive).GetSecurityPath(security.ToSecurityId()), "{0}min_date.bin".Put((int)tf.TotalMinutes))));

                    var minCandleDate = candlesDatesCache.MinValue;
                    var maxCandleDate = candlesDatesCache.MaxValue;

                    if (from >= minCandleDate && to <= maxCandleDate)
                    {
                        continue;
                    }

                    var finamFrom = from;
                    var finamTo   = to;

                    if (maxCandleDate != null && finamFrom >= minCandleDate && finamFrom <= maxCandleDate)
                    {
                        finamFrom = maxCandleDate.Value + TimeSpan.FromDays(1);
                    }

                    if (minCandleDate != null && finamTo >= minCandleDate && finamTo <= maxCandleDate)
                    {
                        finamTo = minCandleDate.Value - TimeSpan.FromDays(1);
                    }

                    if (finamTo <= finamFrom)
                    {
                        continue;
                    }

                    TimeFrameCandle[] newCandles;

                    if (tf.Ticks == 1)
                    {
                        newCandles = finamFrom.Range(finamTo, TimeSpan.FromDays(1)).SelectMany(day =>
                        {
                            worker.ReportProgress(1, Tuple.Create(security, day));

                            var candles = _finamHistorySource.GetTrades(security, day, day).ToEx().ToCandles <TimeFrameCandle>(tf).ToArray();
                            candleStorage.Save(candles);
                            candlesDatesCache.Add(day);
                            return(candles);
                        }).ToArray();
                    }
                    else
                    {
                        worker.ReportProgress(1, Tuple.Create(security, finamFrom, finamTo));
                        newCandles = _finamHistorySource.GetCandles(security, tf, finamFrom, finamTo).ToArray();

                        candleStorage.Save(newCandles);
                        candlesDatesCache.Add(newCandles.Select(c => c.OpenTime.Date).Distinct().ToArray());
                    }

                    // TODO
                    secCandles.AddRange(newCandles);
                }

                var traderDrive   = new LocalMarketDataDrive(Path.Combine(_settingsDir, trader));
                var traderStorage = _traderStorages.SafeAdd(trader, key => new StorageRegistry {
                    DefaultDrive = traderDrive
                });

                foreach (var series in seriesSet)
                {
                    var security = series.Item1.Security;

                    var olStorage       = traderStorage.GetOrderLogStorage(security, format: StorageFormats.Csv);
                    var tradeDatesCache = _tradesDates.SafeAdd(trader, k => new DatesCache(Path.Combine(traderDrive.Path, "dates.xml")));

                    var secTrades = from
                                    .Range(to, TimeSpan.FromDays(1))
                                    .Intersect(year.Days)
                                    .SelectMany(date =>
                    {
                        if (olStorage.Dates.Contains(date))
                        {
                            return(olStorage.Load(date));
                        }

                        if (tradeDatesCache.Contains(date))
                        {
                            return(Enumerable.Empty <OrderLogItem>());
                        }

                        worker.ReportProgress(2, date);

                        var loadedTrades = year.GetTrades(_securityStorage, trader, date);

                        var dateTrades = Enumerable.Empty <OrderLogItem>();

                        foreach (var group in loadedTrades.GroupBy(t => t.Order.Security))
                        {
                            var sec = group.Key;

                            traderStorage
                            .GetOrderLogStorage(sec, format: StorageFormats.Csv)
                            .Save(group.OrderBy(i => i.Order.Time));

                            if (group.Key == security)
                            {
                                dateTrades = group;
                            }
                        }

                        tradeDatesCache.Add(date);

                        return(dateTrades);
                    })
                                    .GroupBy(ol =>
                    {
                        var time = ol.Order.Time;

                        var period = security.Board.WorkingTime.GetPeriod(time.ToLocalTime(security.Board.Exchange.TimeZoneInfo));
                        if (period != null && period.Times.Length > 0)
                        {
                            var last = period.Times.Last().Max;

                            if (time.TimeOfDay >= last)
                            {
                                time = time.AddTicks(-1);
                            }
                        }

                        if (tf == TimeSpan.FromDays(1) && period != null && period.Times.Length > 0)
                        {
                            return(new DateTimeOffset(time.Date + period.Times[0].Min, time.Offset));
                        }

                        return(time.Truncate(tf));
                    })
                                    .ToDictionary(g => g.Key, g =>
                    {
                        var candleTrades = g.Select(ol => new MyTrade
                        {
                            Order = ol.Order,
                            Trade = ol.Trade
                        })
                                           .ToArray();

                        if (candleTrades.Length == 0)
                        {
                            return(null);
                        }

                        var order  = candleTrades[0].Order;
                        var volume = candleTrades.Sum(t1 => t1.Trade.Volume * (t1.Order.Direction == Sides.Buy ? 1 : -1));

                        if (volume == 0)
                        {
                            return(Tuple.Create(candleTrades, (MyTrade)null));
                        }

                        var side = volume > 0 ? Sides.Buy : Sides.Sell;

                        volume = volume.Abs();

                        var availableVolume = volume;
                        var avgPrice        = 0m;

                        foreach (var trade in candleTrades.Where(t1 => t1.Order.Direction == side))
                        {
                            var tradeVol = trade.Trade.Volume.Min(availableVolume);
                            avgPrice    += trade.Trade.Price * tradeVol;

                            availableVolume -= tradeVol;

                            if (availableVolume <= 0)
                            {
                                break;
                            }
                        }

                        avgPrice = avgPrice / volume;

                        return(Tuple.Create(candleTrades, new MyTrade
                        {
                            Order = new Order
                            {
                                Security = order.Security,
                                Direction = side,
                                Time = g.Key,
                                Portfolio = order.Portfolio,
                                Price = avgPrice,
                                Volume = volume,
                            },
                            Trade = new Trade
                            {
                                Security = order.Security,
                                Time = g.Key,
                                Volume = volume,
                                Price = avgPrice
                            }
                        }));
                    });

                    trades.Add(security, secTrades);
                }
            };

            worker.ProgressChanged += (o, ea) =>
            {
                switch (ea.ProgressPercentage)
                {
                case 1:
                {
                    if (ea.UserState is Tuple <Security, DateTime> )
                    {
                        BusyIndicator.BusyContent = "Скачивание {Item1.Id} тиков за {Item2:yyyy-MM-dd}...".PutEx(ea.UserState);
                    }
                    else
                    {
                        BusyIndicator.BusyContent = "Скачивание {Item1.Id} свечей с {Item2:yyyy-MM-dd} по {Item3:yyyy-MM-dd}...".PutEx(ea.UserState);
                    }

                    break;
                }

                default:
                    BusyIndicator.BusyContent = "Скачивание сделок за {0:yyyy-MM-dd}...".Put(ea.UserState);
                    break;
                }
            };

            worker.RunWorkerCompleted += (o, ea) =>
            {
                BusyIndicator.IsBusy = false;

                if (ea.Error == null)
                {
                    Chart.ClearAreas();

                    _statisticManager.Reset();

                    var equityInd = new SimpleMovingAverage {
                        Length = 1
                    };
                    ChartIndicatorElement equityElem;
                    var candlesAreas = new Dictionary <CandleSeries, ChartArea>();

                    if (apart)
                    {
                        foreach (var series in seriesSet)
                        {
                            var area = new ChartArea {
                                Title = series.Item1.Security.Id
                            };
                            Chart.AddArea(area);
                            area.YAxises.Clear();
                            candlesAreas.Add(series.Item1, area);
                        }

                        var equityArea = new ChartArea {
                            Title = LocalizedStrings.PnL
                        };
                        Chart.AddArea(equityArea);

                        equityElem = new ChartIndicatorElement
                        {
                            FullTitle        = LocalizedStrings.PnL,
                            IndicatorPainter = new PnlPainter()
                        };
                        Chart.AddElement(equityArea, equityElem);
                    }
                    else
                    {
                        var candlesArea = new ChartArea();
                        Chart.AddArea(candlesArea);

                        foreach (var tuple in seriesSet)
                        {
                            candlesAreas.Add(tuple.Item1, candlesArea);
                        }

                        const string equityYAxis = "Equity";

                        candlesArea.YAxises.Clear();
                        candlesArea.YAxises.Add(new ChartAxis
                        {
                            Id            = equityYAxis,
                            AutoRange     = true,
                            AxisType      = ChartAxisType.Numeric,
                            AxisAlignment = ChartAxisAlignment.Left,
                        });
                        equityElem = new ChartIndicatorElement
                        {
                            YAxisId          = equityYAxis,
                            FullTitle        = LocalizedStrings.PnL,
                            IndicatorPainter = new PnlPainter()
                        };
                        Chart.AddElement(candlesArea, equityElem);
                    }

                    var positionArea = new ChartArea {
                        Height = 100
                    };
                    Chart.AddArea(positionArea);
                    positionArea.YAxises.Clear();

                    var chartValues = new SortedDictionary <DateTimeOffset, IDictionary <IChartElement, object> >();
                    var pnlValues   = new Dictionary <DateTimeOffset, decimal>();

                    foreach (var series in seriesSet)
                    {
                        var security = series.Item1.Security;

                        var candleYAxis = "Candles_Y_" + security.Id;

                        var candlesArea = candlesAreas[series.Item1];

                        candlesArea.YAxises.Add(new ChartAxis
                        {
                            Id            = candleYAxis,
                            AutoRange     = true,
                            AxisType      = ChartAxisType.Numeric,
                            AxisAlignment = ChartAxisAlignment.Right,
                        });

                        var candlesElem = new ChartCandleElement
                        {
                            ShowAxisMarker = false,
                            YAxisId        = candleYAxis,
                        };
                        Chart.AddElement(candlesArea, candlesElem, series.Item1);

                        var tradesElem = new ChartTradeElement
                        {
                            BuyStrokeColor  = Colors.Black,
                            SellStrokeColor = Colors.Black,
                            BuyColor        = series.Item2.Buy,
                            SellColor       = series.Item2.Sell,
                            FullTitle       = LocalizedStrings.Str985 + " " + security.Id,
                            YAxisId         = candleYAxis,
                        };
                        Chart.AddElement(candlesArea, tradesElem);

                        var posYAxis = "Pos_Y_" + security.Id;
                        positionArea.YAxises.Add(new ChartAxis
                        {
                            Id            = posYAxis,
                            AutoRange     = true,
                            AxisType      = ChartAxisType.Numeric,
                            AxisAlignment = ChartAxisAlignment.Right,
                        });
                        var positionElem = new ChartIndicatorElement
                        {
                            FullTitle = LocalizedStrings.Str862 + " " + security.Id,
                            YAxisId   = posYAxis,
                            Color     = series.Item2.Position
                        };
                        var positionInd = new SimpleMovingAverage {
                            Length = 1
                        };
                        Chart.AddElement(positionArea, positionElem);

                        var pnlQueue = new PnLQueue(security.ToSecurityId());
                        //var level1Info = new Level1ChangeMessage
                        //{
                        //	SecurityId = pnlQueue.SecurityId,
                        //}
                        //.TryAdd(Level1Fields.PriceStep, security.PriceStep)
                        //.TryAdd(Level1Fields.StepPrice, security.StepPrice);

                        //pnlQueue.ProcessLevel1(level1Info);

                        var pos = 0m;

                        var secTrades = trades[security];

                        var secValues = _candles[security]
                                        .Select(c =>
                        {
                            if (c.State != CandleStates.Finished)
                            {
                                c.State = CandleStates.Finished;
                            }

                            pnlQueue.ProcessLevel1(new Level1ChangeMessage
                            {
                                SecurityId = security.ToSecurityId(),
                            }.TryAdd(Level1Fields.LastTradePrice, c.ClosePrice));

                            var values = new Dictionary <IChartElement, object>
                            {
                                { candlesElem, c },
                            };

                            var candleTrade = secTrades.TryGetValue(c.OpenTime);

                            if (candleTrade != null)
                            {
                                if (candleTrade.Item2 != null)
                                {
                                    values.Add(tradesElem, candleTrade.Item2);
                                }

                                foreach (var myTrade in candleTrade.Item1)
                                {
                                    pos    += myTrade.Order.Direction == Sides.Buy ? myTrade.Trade.Volume : -myTrade.Trade.Volume;
                                    var pnl = pnlQueue.Process(myTrade.ToMessage());

                                    _statisticManager.AddMyTrade(pnl);
                                }

                                _statisticManager.AddPosition(c.OpenTime, pos);
                                _statisticManager.AddPnL(c.OpenTime, pnlQueue.RealizedPnL + pnlQueue.UnrealizedPnL);
                            }

                            pnlValues[c.OpenTime] = pnlValues.TryGetValue(c.OpenTime) + (pnlQueue.RealizedPnL + pnlQueue.UnrealizedPnL);
                            values.Add(positionElem, positionInd.Process(pos));

                            return(new RefPair <DateTimeOffset, IDictionary <IChartElement, object> >
                            {
                                First = c.OpenTime,
                                Second = values
                            });
                        })
                                        .ToArray();

                        foreach (var pair in secValues)
                        {
                            var dict = chartValues.SafeAdd(pair.First, key => new Dictionary <IChartElement, object>());

                            foreach (var pair2 in pair.Second)
                            {
                                dict[pair2.Key] = pair2.Value;
                            }
                        }
                    }

                    foreach (var pair in pnlValues)
                    {
                        chartValues[pair.Key].Add(equityElem, equityInd.Process(pair.Value));
                    }

                    Chart.IsAutoRange = true;

                    try
                    {
                        Chart.Draw(chartValues.Select(p => RefTuple.Create(p.Key, p.Value)));
                    }
                    finally
                    {
                        Chart.IsAutoRange = false;
                    }
                }
                else
                {
                    new MessageBoxBuilder()
                    .Error()
                    .Owner(this)
                    .Text(ea.Error.ToString())
                    .Show();
                }
            };

            worker.RunWorkerAsync();
        }
Пример #20
0
 private void OnChartPanelSubscribeTradeElement(ChartTradeElement element, Security security)
 {
     new SubscribeTradeElementCommand(element, security).Process(this);
 }
Пример #21
0
		public UnSubscribeTradeElementCommand(ChartTradeElement element)
		{
			if (element == null)
				throw new ArgumentNullException(nameof(element));

			Element = element;
		}
Пример #22
0
		public SubscribeTradeElementCommand(ChartTradeElement element, Security security)
		{
			if (element == null)
				throw new ArgumentNullException(nameof(element));

			if (security == null)
				throw new ArgumentNullException(nameof(security));

			Element = element;
			Security = security;
		}