← Назад

Получение свечки реального времени от Альфа-Директ

Здравствуйте, прочитал всю документацию но никак не получается это реализовать(версия 4.1.1), может кто даст рабочий пример кода...

Комментарии (30)

Вход или Создать аккаунт, Войдите или зарегистрируйтесь, чтобы оставить комментарий

OvcharenkoVI
OvcharenkoVI

var candleManager = new CandleManager(Trader)

var candleSeries = new CandleSeries(typeof(TimeFrameCandle), Security, (TimeSpan)AlfaTimeFrames.Minute1);

candleManager.Start(candleSeries);

candleSeries.CandlesFinished += candle => ;

Перед этим запустить Trader.RegisterTrades(Security);

BBB
BBB Автор

OvcharenkoVI: var candleManager = new CandleManager(Trader)

var candleSeries = new CandleSeries(typeof(TimeFrameCandle), Security, (TimeSpan)AlfaTimeFrames.Minute1);

candleManager.Start(candleSeries);

candleSeries.CandlesFinished += candle => ;

Перед этим запустить Trader.RegisterTrades(Security);

'StockSharp.Algo.Candles.CandleSeries' does not contain a definition for 'CandlesFinished' ???

esper
esper

BBB: 'StockSharp.Algo.Candles.CandleSeries' does not contain a definition for 'CandlesFinished' ??? В последней версии это CandleSeries.ProcessCandle, при вызове события надо смотреть State свечи, чтобы он был Finished.

BBB
BBB Автор

Короче не работает...

А как получать котировки реального времени (желательно несколько раз в секунду)?

Sergey Masyura
Sergey Masyura

BBB: Короче не работает...

А как получать котировки реального времени (желательно несколько раз в секунду)?

Подпись.

BBB
BBB Автор
  1. В общем ни CandleSeries.ProcessCandle, ни Trader.NewTrades, ни CandleManager.Processing у меня не работают. Что может быть не так?
  2. Мне надо получать цену последней сделки по инструменту, какими способами это можно реализовать?
Alexander
Alexander
  1. документация
  2. примеры
  3. поиск по форуму
  4. техническая поддержка от нас
none1
none1

realtime бары могут не приходить в AlfaTest, если на машине часовой пояс не правильный. Например, Exchange.Me = +4 UTC, а на винде без обновлений +3 UTC. Тогда к _ad.GetArchiveFinInfoFromDB будут идти запросы на час больше и новых баров не появится.

UsilaDobry
UsilaDobry

Коллеги, не получается вывести реальные свечи, выдает ошибку в строке _candleManager.Start(_series); "Параметр свечки 00-10-00 не правильный", чтобы это значило, в менеджер свечей передается серия, атрибуты верные, о какой свечке идет речь...??? 00-10-00 это 10-минутный таймфрейм серии, причем тут свечка...

using System;
using System.Collections.Generic;
using System.Windows;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using Ecng.Common;
using Ecng.Collections;
using Ecng.ComponentModel;
using Ecng.Xaml;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Indicators.Trend;
using StockSharp.BusinessEntities;
using StockSharp.AlfaDirect;
using StockSharp.Logging;
using StockSharp.Xaml;
using StockSharp.Xaml.Charting;

namespace MARKET_SUCCESS_ALFA
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow
    {
        private AlfaTrader _trader;
        private CandleManager _candleManager;
        private CandleSeries _series;
        private bool _isExportStarted;
        private readonly ObservableCollection<Security> _securitiesSource = new ObservableCollection<Security>();
        private readonly ObservableCollection<Portfolio> _portfoliosSource = new ObservableCollection<Portfolio>();

        private readonly LogManager _logManager = new LogManager();
        private readonly MonitorWindow _monitor = new MonitorWindow();

        //окно для отображения графика со свечками
        private ChartWindow _chartWindow;
        private ChartCandleElement _candlesElem;
        private ChartIndicatorElement _chartBollingerElement; 

        public MainWindow()
        {
            InitializeComponent();

            var items = HistoryInterval.Items;
            items.Add(new ComboBoxItem { Content = "1 минута", Tag = AlfaTimeFrames.Minute1 });
            items.Add(new ComboBoxItem { Content = "5 минут", Tag = AlfaTimeFrames.Minute5 });
            items.Add(new ComboBoxItem { Content = "10 минут", Tag = AlfaTimeFrames.Minute10 });
            items.Add(new ComboBoxItem { Content = "15 минут", Tag = AlfaTimeFrames.Minute15 });
            items.Add(new ComboBoxItem { Content = "30 минут", Tag = AlfaTimeFrames.Minute30 });
            items.Add(new ComboBoxItem { Content = "1 час", Tag = AlfaTimeFrames.Hour });
            items.Add(new ComboBoxItem { Content = "День", Tag = AlfaTimeFrames.Day });
            items.Add(new ComboBoxItem { Content = "Неделя", Tag = AlfaTimeFrames.Week });
            items.Add(new ComboBoxItem { Content = "Месяц", Tag = AlfaTimeFrames.Month });
            items.Add(new ComboBoxItem { Content = "Год", Tag = AlfaTimeFrames.Year });

            HistoryInterval.SelectedIndex = 2;
            
            From.Value = DateTime.Today - TimeSpan.FromDays(7);
            To.Value = DateTime.Today;

            Security.ItemsSource = _securitiesSource;
            Portfolio.ItemsSource = _portfoliosSource;

            _logManager.Listeners.Add(new FileLogListener());
            _logManager.Listeners.Add(new GuiLogListener(_monitor));
            _monitor.Show();
        }

        private void ConnectClick(object sender, RoutedEventArgs e)
        {
            // создаем шлюз
            _trader = new AlfaTrader();

            _logManager.Sources.Add(_trader);

            _trader.ProcessDataError += error => this.GuiAsync(() => MessageBox.Show(this, error.ToString(), "Ошибка обработки данных"));
            _trader.NewSecurities += securities =>
            {
                this.GuiAsync(() => _securitiesSource.AddRange(securities));

                // начинаем получать текущие сделки (для построения свечек в реальном времени)
                securities.ForEach(_trader.RegisterTrades);
            };
            _trader.NewPortfolios += portfolios => this.GuiAsync(() => _portfoliosSource.AddRange(portfolios));
            _trader.Connected += () => this.GuiAsync(() =>
            {
                ExportBtn.IsEnabled = true;
                ConnectBtn.IsEnabled = false;
            });

            _trader.Connect();
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            if (_trader != null)
            {
                if (_isExportStarted)
                    StopExport();

                _logManager.Sources.Remove(_trader);

                _trader.Dispose();
            }

            base.OnClosing(e);
        }

        private void StartExport()
        {
            _isExportStarted = true;
            _trader.StartExport();
        }

        private void StopExport()
        {
            _trader.StopExport();
            _isExportStarted = false;
        }

        private void ExportClick(object sender, RoutedEventArgs e)
        {
            if (_isExportStarted)
                StopExport();
            else
                StartExport();
        }

        private Security SelectedSecurity
        {
            get { return (Security)Security.SelectedValue; }
        }

        private Portfolio SelectedPortfolio
        {
            get { return (Portfolio)Portfolio.SelectedValue; }
        }

        private void SecuritySelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ShowChart.IsEnabled = SelectedSecurity != null;
        }

        private void PortfolioSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            TradingBtn.IsEnabled = SelectedPortfolio != null;
        }
        private void ShowChartClick(object sender, RoutedEventArgs e)
        {
            var security = SelectedSecurity;

            var timeFrame = (AlfaTimeFrames)((ComboBoxItem)HistoryInterval.SelectedItem).Tag;

            if (From.Value != null)
            {
                var from = From.Value.Value;
                if (To.Value != null)
                {
                    var to = To.Value.Value;

                    if (@from > to)
                    {
                        return;
                    }

                    var candles = _trader.GetHistoryData(security, timeFrame, new Range<DateTime>(@from, to));
                    
                    _chartWindow = new ChartWindow
                    {
                        Title = "{0}, {1}, {2} - {3}".Put(security.Code,
                                                          ((ComboBoxItem)HistoryInterval.SelectedItem).Content,
                                                          @from.ToString(CultureInfo.InvariantCulture), to.ToString(CultureInfo.InvariantCulture))
                    };

                    var area = new ChartArea();
                    _chartWindow.Chart.ChartTheme = "ExpressionDark";
                    _chartWindow.Chart.IsAutoScroll = true;
                    _chartWindow.Chart.Areas.Add(area);

                    _candlesElem = new ChartCandleElement
                    {
                        Antialiasinig = false,
                        UpBodyColor = Colors.Chartreuse,
                        UpWickColor = Colors.Chartreuse,
                        DownBodyColor = Colors.Red,
                        DownWickColor = Colors.Red,
                        IsLegend = true,
                    };

                    _chartBollingerElement = new ChartIndicatorElement
                    {
                        Antialiasinig = false,
                        Color = Colors.DeepSkyBlue,
                        IsLegend = true,
                        Indicator = new BollingerBands
                        {
                            Length = 20,
                            Width = 2
                        },
                        Title = "Bollinger Bands",
                        DrawStyle = ChartIndicatorDrawStyles.Line,
                    };
                    _chartBollingerElement.DrawTemplate.VisualTree.SetValue(Shape.FillProperty, new SolidColorBrush(Colors.DeepSkyBlue));

                    area.Elements.Add(_candlesElem);
                    area.Elements.Add(_chartBollingerElement);

                    this.GuiAsync(() => DrawCandles(candles));

                    _candleManager = new CandleManager(_trader);
                    
                    _series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame);
                    
                    _series.ProcessCandle += Draw;
                    
                    _candleManager.Start(_series);

                    _chartWindow.Show();
                }
            }
        }

        private void DrawCandles(IEnumerable<Candle> candles)
        {
            foreach (var candle in candles)
                _chartWindow.Chart.ProcessCandle(_candlesElem, candle);
        }

        private void Draw(Candle candle)
        {
            if (candle.State == CandleStates.Finished || candle.State == CandleStates.Changed)
            {
                var final = candle.State == CandleStates.Finished;
                
                var val = _chartBollingerElement.Indicator.Process(new DecimalIndicatorValue(candle.ClosePrice) {IsFinal = final});
                var bollingerValue = new ChartIndicatorValue(_chartBollingerElement.Indicator, val);
                
                var timeFrame = (TimeSpan)_series.Arg;
                var time = timeFrame.GetCandleBounds(_series.Security).Min - timeFrame;

                if (candle.State == CandleStates.Finished || (candle.State == CandleStates.Changed && candle.OpenTime >= time))
                {
                    this.GuiAsync(() => _chartWindow.Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
                                                                                          {
                                                                                              {_candlesElem, candle},
                                                                                              {_chartBollingerElement, bollingerValue},
                                                                                          }));
                }
            }
        }
    }
}

Здесь _series = new CandleSeries(typeof(TimeFrameCandle), security, timeFrame); поменял timeFrame _series = new CandleSeries(typeof(TimeFrameCandle), security, (TimeSpan)AlfaTimeFrames.Minute10);

предыдущая ошибка пропала, но появилась новая:

UsilaDobry
UsilaDobry

Немного изменил код, но ошибка прежняя, вроде бы всё прозрачно, не пойму... Добавил в примере SampleAlfaCandles к коду вывода истории candleManager

private void ShowChartClick(object sender, RoutedEventArgs e)
        {
            try
            {
                var security = SelectedSecurity;
                
                var timeFrame = (AlfaTimeFrames)((ComboBoxItem)HistoryInterval.SelectedItem).Tag;
                                
                if (From.Value != null)
                {
                    var from = From.Value.Value;
                    if (To.Value != null)
                    {
                        var to = To.Value.Value;
                
                        if (@from > to)
                        {
                            return;
                        }
                
                        var candles = _trader.GetHistoryData(security, timeFrame, new Range<DateTime>(@from, to));
                        
                        _chartWindow = new ChartWindow
                        {
                            Title = "{0}, {1}, {2} - {3}".Put(security.Code,
                                                              ((ComboBoxItem)HistoryInterval.SelectedItem).Content,
                                                              @from.ToString(CultureInfo.InvariantCulture),                                                                      to.ToString(CultureInfo.InvariantCulture))
                        };

                        this.GuiAsync(() => 
                            {
                                foreach (var candle in candles)
                                    _chartWindow.Chart.ProcessCandle(_candlesElem, candle);
                            });
                
                        _candleManager = new CandleManager(_trader);
                
                        _series = new CandleSeries(typeof(TimeFrameCandle), security, (TimeSpan)AlfaTimeFrames.Minute10);
                        
                        _series.ProcessCandle += candle =>
                            {
                                if (candle.State == CandleStates.Finished)
                                {
                                    var val = _chartBollingerElement.Indicator.Process(new DecimalIndicatorValue(candle.ClosePrice));
                                    var bollingerValue = new ChartIndicatorValue(_chartBollingerElement.Indicator, val);
                                    this.GuiAsync(() => _chartWindow.Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
                                                                                          {
                                                                                              {_candlesElem, candle},
                                                                                              {_chartBollingerElement, bollingerValue},
                                                                                          }));
                                }
                            };
                        
                        _candleManager.Start(_series);
                
                        _chartWindow.Show();
                    }
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.ToString());
            }
        }

Mikhail Sukhov
Mikhail Sukhov

Приведите пожалуйста StackTrace. Картинки с ошибками и сам код не несут практически никакой полезной информации.

UsilaDobry
UsilaDobry

Михаил Сухов: Приведите пожалуйста StackTrace. Картинки с ошибками и сам код не несут практически никакой полезной информации.

StackTrace? Это трассировка исключения? Не знаю правильно ли я понял, Вы имеете ввиду вот эту информацию?

Mikhail Sukhov
Mikhail Sukhov

UsilaDobry:

Михаил Сухов: Приведите пожалуйста StackTrace. Картинки с ошибками и сам код не несут практически никакой полезной информации.

StackTrace? Это трассировка исключения? Не знаю правильно ли я понял, Вы имеете ввиду вот эту информацию?

Да это. А теперь нажмите на это окно Ctrl+C и вставьте сообщение как текст на форум. Спасибо.

UsilaDobry
UsilaDobry


System.InvalidCastException: Не удалось привести тип объекта "StockSharp.Algo.Candles.TimeFrameCandle[]" к типу "System.Collections.Generic.List`1[StockSharp.Algo.Candles.Candle]".

в StockSharp.AlfaDirect.AlfaTrader.#=qNmkP6QzBPHM7MSi3K7zNb8hpEPmvaemYv5w1q7pSlzs=(CandleSeries #=qw2Ij9lcQ52_YjUxYlygqJQ==, AlfaTimeFrames #=qmt9jajmekZJ3lvX4EWDlsw==, Range`1 #=qUa$g1WHcmZt7GKP9MHGYdQ==, Boolean #=qyMqxPE6iw9OG3w187t$YJg==, #=qrYpFuQVysBZ8IKEVqMgJNeOJnek4Tqt17H5Lhdsr7oOl5WXmF$V4OcRiLRkcvZGh& #=qdyEgQw5_gfsmxp61TgMHpQ==)

в StockSharp.AlfaDirect.AlfaTrader.SubscribeHistoricalCandles(CandleSeries series, DateTime from, DateTime to)

в StockSharp.Algo.Candles.CandleManager.#=qMxwX6RCGPPukCh3ls8RxBpA7IM61KWm0NtodaOEzPbw=.#=q6S9eoetqGa49tVuWloNQCnRypxcDn7PYNPl2C$RaYnkKcnu1wUHa2NHB6vFg6y0WaNoYZQe4eQyVPI8HWrXBIyz4LMDluX5GlBYwdeY220k=(CandleSeries #=q1SVIqTyklP0v2Vmdbxf5pQ==, DateTime #=qv2yp$YhyUweWh$XfcRdgUw==, DateTime #=qHyx5tP4ns5E8bwaA97HB6A==)

в #=qX3OhqnqEph0ylOwbVoprdaRyUdFykOOlTJqNaUikiywB2d5GxCHY1J7pgbbIcyah1whRfbIIDuqG1CROSXDxrw==.#=qXRmgGHeIzniBfKG_gUxziw==()

в StockSharp.Algo.Candles.CandleManager.Start(CandleSeries series, DateTime from, DateTime to)

в StockSharp.Algo.Candles.CandleHelper.Start(ICandleManager manager, CandleSeries series)

в MARKET_SUCCESS_ALFA.MainWindow.ShowChartClick(Object sender, RoutedEventArgs e) в c:\Users\UsilaDobry\Documents\Visual Studio 2012\Projects\MARKET SUCCESS ALFA\MainWindow.xaml.cs:строка 241


ОК

Mikhail Sukhov
Mikhail Sukhov

Ошибка найдена и поправлена. Я постучался в скайп. Давайте проведем тестирование, может там еще что-то есть. Демо у Альфы теперь не предоставляется, а ради небольшой ошибки ехать к ним в офис нет совсем времени.

UsilaDobry
UsilaDobry

Благодарю, реальные свечи выводятся корректно. Красота. Вот только значения индикатора BollingerBands выводятся странно. Это мой код

private void ShowChartClick(object sender, RoutedEventArgs e)
        {
            try
            {
                var security = SelectedSecurity;
                
                var timeFrame = (AlfaTimeFrames)((ComboBoxItem)HistoryInterval.SelectedItem).Tag;
                
                if (From.Value != null)
                {
                    var from = From.Value.Value;
                    if (To.Value != null)
                    {
                        var to = To.Value.Value;
                
                        if (@from > to)
                        {
                            return;
                        }
                
                        var candles = _trader.GetHistoryData(security, timeFrame, new Range<DateTime>(@from, to));
                        
                        _chartWindow = new ChartWindow
                        {
                            Title = "{0}, {1}, {2} - {3}".Put(security.Code,
                                                              ((ComboBoxItem)HistoryInterval.SelectedItem).Content,
                                                              @from.ToString(CultureInfo.InvariantCulture), to.ToString(CultureInfo.InvariantCulture))
                        };
                
                        var area = new ChartArea();
                        _chartWindow.Chart.ChartTheme = "ExpressionDark";
                        _chartWindow.Chart.IsAutoScroll = true;
                        _chartWindow.Chart.Areas.Add(area);
                
                        _candlesElem = new ChartCandleElement
                        {
                            Antialiasinig = false,
                            UpBodyColor = Colors.Chartreuse,
                            UpWickColor = Colors.Chartreuse,
                            DownBodyColor = Colors.Red,
                            DownWickColor = Colors.Red,
                            IsLegend = true,
                        };
                
                        _chartBollingerElement = new ChartIndicatorElement
                        {
                            Antialiasinig = false,
                            Color = Colors.DeepSkyBlue,
                            IsLegend = true,
                            Indicator = new BollingerBands
                            {
                                Length = 20,
                                Width = 2
                            },
                            Title = "Bollinger Bands",
                            DrawStyle = ChartIndicatorDrawStyles.Line,
                        };
                        _chartBollingerElement.DrawTemplate.VisualTree.SetValue(Shape.FillProperty, new SolidColorBrush(Colors.DeepSkyBlue));
                
                        area.Elements.Add(_candlesElem);
                        area.Elements.Add(_chartBollingerElement);

                        this.GuiAsync(() =>
                            {
                                foreach (var candle in candles)
                                    _chartWindow.Chart.ProcessCandle(_candlesElem, candle);
                            });
                                                        
                        _candleManager = new CandleManager(_trader);
                        
                        _series = new CandleSeries(typeof(TimeFrameCandle), security, (TimeSpan)AlfaTimeFrames.Minute10);
                        
                        _series.ProcessCandle += candle =>
                            {
                                if (candle.State == CandleStates.Finished || candle.State == CandleStates.Changed)
                                {
                                    var final = candle.State == CandleStates.Finished;
                                    
                                    var val = _chartBollingerElement.Indicator.Process(new DecimalIndicatorValue(candle.ClosePrice) { IsFinal = final });
                                    var bollingerValue = new ChartIndicatorValue(_chartBollingerElement.Indicator, val);

                                        this.GuiAsync(() => _chartWindow.Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
                                                                                          {
                                                                                              {_candlesElem, candle},
                                                                                              {_chartBollingerElement, bollingerValue},
                                                                                          }));
                                }
                            };
                        
                        _candleManager.Start(_series);
                
                        _chartWindow.Show();
                    }
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.ToString());
            }
        }
UsilaDobry
UsilaDobry

Изменил немного код вывода значений индикатора, картинка без изменений...

_series.ProcessCandle += candle =>
                            {
                                try
                                {
                                    if (candle.State == CandleStates.Finished)
                                    {
                                        var valueBb = _chartBollingerElement.Indicator.Process(new CandleIndicatorValue(candle) { IsFinal = true });
                                        this.GuiAsync(() => _chartWindow.Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
                                                    {
                                                        {_candlesElem, candle},
                                                        {_chartBollingerElement, new ChartIndicatorValue(_chartBollingerElement.Indicator, valueBb)},
                                                    }));
                                    }
                                    else
                                    {
                                        this.GuiAsync(() => _chartWindow.Chart.ProcessCandle(_candlesElem, candle));
                                    }
                                }
                                catch (Exception exc)
                                {
                                    MessageBox.Show(exc.ToString());
                                }
                            };
Mikhail Sukhov
Mikhail Sukhov

UsilaDobry: Изменил немного код вывода значений индикатора, картинка без изменений...

IIndicator.IsFormed проверяется?

UsilaDobry
UsilaDobry

Михаил Сухов:

UsilaDobry: Изменил немного код вывода значений индикатора, картинка без изменений...

IIndicator.IsFormed проверяется?

Разве свойство значения индикатора IsFinal = true не решает эту проверку? Значение окончательное, более неизменное в данный момент времени... У меня такое чувство, что значения индикатора считаются каждые 5 секунд по мере поступления исторических тиков, это как-то пересекается с моим предыдущим постом...

_series.ProcessCandle += candle =>
                            {
                                    if (candle.State == CandleStates.Finished)
                                    {
                                        var valueBb = _chartBollingerElement.Indicator.Process(new CandleIndicatorValue(candle) { IsFinal = true });
                                        this.GuiAsync(() => _chartWindow.Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
                                                    {
                                                        {_candlesElem, candle},
                                                        {_chartBollingerElement, new ChartIndicatorValue(_chartBollingerElement.Indicator, valueBb)},
                                                    }));
                                    }
                                    else
                                    {
                                        this.GuiAsync(() => _chartWindow.Chart.ProcessCandle(_candlesElem, candle));
                                    }
                            };
Mikhail Sukhov
Mikhail Sukhov

UsilaDobry:

Михаил Сухов:

UsilaDobry: Изменил немного код вывода значений индикатора, картинка без изменений...

IIndicator.IsFormed проверяется?

Разве свойство значения индикатора IsFinal = true не решает эту проверку?

IsFinal - это свойство, определяющее что данные окончательные в текущем ТФ. IsFormed - что индикатор сформировался и готов к работе (в т.ч. и отрисовки на графике). Посмотрите математическую формулу скользящих (я так понимаю Полосы на основе них сделаны). Все станет понятно.

UsilaDobry
UsilaDobry

При выводе реальных свечек AlfaTrader засыпает logFile каждые 5 секунд сообщениями

2013/06/21 10:15:08.168|       |AlfaTrader|StartExport()
2013/06/21 10:15:08.169|       |AlfaTrader|Экспорт в процессе запуска.
2013/06/21 10:15:08.174|       |AlfaTrader|Экспорт запущен.
2013/06/21 10:15:09.204|       |AlfaTrader|RegisterTrades: RTSI-9.13@FORTS
2013/06/21 10:15:09.236|       |AlfaTrader|create order: id = 117646314, tr. id = 853345110
2013/06/21 10:15:09.236|       |AlfaTrader|Создание ордера из терминала, tr. id 853345110
2013/06/21 10:15:09.244|       |AlfaTrader|update order: id = 117646314
2013/06/21 10:15:09.246|       |AlfaTrader|Order changed: 853345110/117646314 Покупка Цена=121000 Объем=1 Сост=Done Бал=1 
2013/06/21 10:15:09.249|       |AlfaTrader|New order: 853345110/117646314 Покупка Цена=121000 Объем=1 Сост=Done Бал=1 
2013/06/21 10:15:15.662|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 01.01.0001 0:00:00 - 21.06.2013 10:15:15
2013/06/21 10:15:17.308|       |AlfaTrader|RegisterQuotes: RTSI-9.13@FORTS
2013/06/21 10:15:18.185|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 01.01.0001 0:01:00 - 21.06.2013 10:16:18
2013/06/21 10:16:32.576|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:16:00 - 21.06.2013 10:17:32
2013/06/21 10:16:32.629|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:32
2013/06/21 10:16:32.677|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:32
2013/06/21 10:16:32.725|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:32
2013/06/21 10:16:32.772|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:32
2013/06/21 10:16:32.819|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:32
2013/06/21 10:16:32.874|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:32
2013/06/21 10:16:32.928|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:32
2013/06/21 10:16:32.976|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:32
2013/06/21 10:16:33.024|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:33
2013/06/21 10:16:33.130|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:33
2013/06/21 10:16:33.183|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:33
2013/06/21 10:16:33.230|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:33
2013/06/21 10:16:33.278|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:33
2013/06/21 10:16:33.325|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:33
2013/06/21 10:16:38.326|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:38
2013/06/21 10:16:43.328|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:43
2013/06/21 10:16:48.336|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:48
2013/06/21 10:16:53.346|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:53
2013/06/21 10:16:58.352|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:17:58
2013/06/21 10:17:03.359|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:18:03
2013/06/21 10:17:08.366|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:17:00 - 21.06.2013 10:18:08
2013/06/21 10:17:13.376|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:18:13
2013/06/21 10:17:18.382|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:18:18
2013/06/21 10:17:23.388|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:18:23
2013/06/21 10:17:28.401|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:18:28
2013/06/21 10:17:33.407|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:18:33
2013/06/21 10:17:38.416|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:18:38
2013/06/21 10:17:43.419|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:18:43
2013/06/21 10:17:48.428|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:18:48
2013/06/21 10:17:53.438|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:18:53
2013/06/21 10:17:58.442|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:18:58
2013/06/21 10:18:03.451|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:19:03
2013/06/21 10:18:08.462|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:19:08
2013/06/21 10:18:13.468|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:19:13
2013/06/21 10:18:18.473|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:19:18
2013/06/21 10:18:23.480|       |AlfaTrader|GetLocalHistoryData: RTSI-9.13@FORTS, 21.06.2013 10:18:00 - 21.06.2013 10:19:23

Запустил простую стратегию для пробы, для контроля вывожу законченные свечи в debug, но законченные свечи не выводятся, свечи выводятся в debug каждые 5 секунд... И стратегия не понимает состояние свечки Finished, срабатывает на каждые 5 секунд... Возможно из-за этого и индикатор выводится не корректно?..

Код запуска стратегии

private void TradingBtn_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (_strategyFirst == null)
                {
                    var security = SelectedSecurity;

                    _candleManager = new CandleManager(_trader);

                    _series = new CandleSeries(typeof(TimeFrameCandle), security, (TimeSpan)AlfaTimeFrames.Minute1);

                    _candleManager.Start(_series);

                    _series.ProcessCandle += candle =>
                    {
                        if (candle.State != CandleStates.Finished)
                            return;

                        Debug.WriteLine("{0}", candle.ToString());
                    };

                    _strategyFirst = new StrategyFirst(_series)
                        {
                            Trader = _trader,
                            Security = SelectedSecurity,
                            Portfolio = SelectedPortfolio,
                            Volume = 1
                        };

                    _strategyFirst.WhenOrderRegistered()
                                  .Do(order => this.GuiAsync(() => _chartWindow.Chart.ProcessValues(order.Time, new Dictionary<IChartElement, object> { { _chartOrderElement, order }, })))
                                  .Apply();
                    _strategyFirst.WhenNewMyTrades()
                                  .Do(trades => trades.ForEach(t => this.GuiAsync(() => _chartWindow.Chart.ProcessValues(t.Trade.Time, new Dictionary<IChartElement, object> { { _chartTradeElement, t }, }))))
                                  .Apply();

                    _strategyFirst.ProcessStateChanged += s =>
                                  {
                                      TradingBtn.Content = s.ProcessState == ProcessStates.Started
                                                                             ? "Cтоп"
                                                                             : "Старт";
                                  };

                    _trader.RegisterMarketDepth(SelectedSecurity);

                    _logManager.Sources.Add(_strategyFirst);

                    _strategyFirst.Start();

                }
                else if (_strategyFirst.ProcessState == ProcessStates.Stopping ||
                             _strategyFirst.ProcessState == ProcessStates.Stopped)
                {
                    // в ином случаем запускаем стратегию
                    _strategyFirst.Start();
                }
                else
                {
                    //или останавливаем
                    if (_strategyFirst.Position != 0)
                        _strategyFirst.ClosePosition();
                    _strategyFirst.Stop();
                }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.ToString());
            }
        }

Код стратегии

using System;
using System.Windows;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Strategies;
using StockSharp.Logging;

namespace MARKET_SUCCESS_ALFA
{
    class StrategyFirst : Strategy
    {
        private readonly CandleSeries _candleSeries;

        public StrategyFirst(CandleSeries series)
        {
            _candleSeries = series;
        }

        protected override void OnStarted()
        {
            try
            {
                _candleSeries.ProcessCandle += candle =>
                    {
                        if (candle.State != CandleStates.Finished) return;
                        //Получаем последнюю свечу
                        Candle candleLastFinish = _candleSeries.GetCandle<TimeFrameCandle>(0);
                        //Получаем предпослежнюю свечу
                        Candle candlePenultFinish = _candleSeries.GetCandle<TimeFrameCandle>(1);

                        //Сигнал на покупку
                        bool signalBuy = candleLastFinish.OpenPrice <
                                         candleLastFinish.ClosePrice;
                        signalBuy = signalBuy &&
                                    candlePenultFinish.OpenPrice <
                                    candlePenultFinish.ClosePrice;
                        signalBuy = signalBuy && Position == 0;

                        //Сигнал на закрытие длинной позиции
                        bool signalStopBuy = Position > 0;
                        signalStopBuy = signalStopBuy &&
                                        candleLastFinish.OpenPrice >
                                        candleLastFinish.ClosePrice;

                        //Сигнал на продажу
                        bool signalSell = candleLastFinish.OpenPrice >
                                          candleLastFinish.ClosePrice;
                        signalSell = signalSell &&
                                     candlePenultFinish.OpenPrice >
                                     candlePenultFinish.ClosePrice;
                        signalSell = signalSell && Position == 0;

                        //Сигнал на закрытие короткой позиции
                        bool signalStopSell = Position < 0;
                        signalStopSell = signalStopSell &&
                                         candleLastFinish.OpenPrice <
                                         candleLastFinish.ClosePrice;
                        //Реагируем на сигнал покупки
                        if (signalBuy)
                        {
                            //RegisterOrder(this.BuyAtLimit(Security.MaxPrice));
                            this.AddInfoLog("ОТКРЫВАЕМ ДЛИННУЮ позицию {0}.", candleLastFinish.CloseTime);
                        }
                        //Реагируем на сигнал закрытия позиции
                        if (signalStopBuy)
                        {
                            //RegisterOrder(this.SellAtLimit(Security.MinPrice));
                            this.AddInfoLog("ЗАКРЫВАЕМ ДЛИННУЮ позицию {0}.", candleLastFinish.CloseTime);
                        }
                        //Реагируем на сигнал продажи
                        if (signalSell)
                        {
                            //RegisterOrder(this.SellAtLimit(Security.MinPrice));
                            this.AddInfoLog("ОТКРЫВАЕМ КОРОТКУЮ позицию {0}.", candleLastFinish.CloseTime);
                        }
                        //Реагируем на сигнал закрытия позиции
                        if (signalStopSell)
                        {
                            //RegisterOrder(this.BuyAtLimit(Security.MaxPrice));
                            this.AddInfoLog("ЗАКРЫВАЕМ КОРОТКУЮ позицию {0}.", candleLastFinish.CloseTime);
                        }
                    };
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.ToString());  
            }
        }

        protected override void OnStopped()
        {

        }
    }
}

Вывод в debug

UsilaDobry
UsilaDobry

Проверка на IsFormed вообще не пропускает исполнение кода в ветку оператора if, выводятся только свечи по оператору else...

_series.ProcessCandle += candle =>
                            {
                                    if (candle.State == CandleStates.Finished && _chartBollingerElement.Indicator.IsFormed)
                                    {
                                        var valueBb = _chartBollingerElement.Indicator.Process(new CandleIndicatorValue(candle) { IsFinal = true });
                                        this.GuiAsync(() => _chartWindow.Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
                                                    {
                                                        {_candlesElem, candle},
                                                        {_chartBollingerElement, new ChartIndicatorValue(_chartBollingerElement.Indicator, valueBb)},
                                                    }));
                                    }
                                    else
                                    {
                                        this.GuiAsync(() => _chartWindow.Chart.ProcessCandle(_candlesElem, candle));
                                    }
                            };

И почему же я указываю выводить в debug значения законченных свечей, а выводятся 5-секундные значения изменяемой свечи?..

_series.ProcessCandle += candle =>
                    {
                        if (candle.State != CandleStates.Finished)
                            return;

                        Debug.WriteLine("{0}", candle.ToString());
                    };
Mikhail Sukhov
Mikhail Sukhov

UsilaDobry: Проверка на IsFormed вообще не пропускает исполнение кода в ветку оператора if, выводятся только свечи по оператору else...

Сейчас код неправильно написан в корне... Мне кажется надо не игнорировать, а понять, что такое IsFormed. Давайте резберем формулу скользящей средней.

UsilaDobry
UsilaDobry

Михаил Сухов:

UsilaDobry: Проверка на IsFormed вообще не пропускает исполнение кода в ветку оператора if, выводятся только свечи по оператору else...

Сейчас код неправильно написан в корне... Мне кажется надо не игнорировать, а понять, что такое IsFormed. Давайте резберем формулу скользящей средней.

Простая скользящая средняя цены закрытия это среднее арифметическое значений цены закрытия за период. В нашем случае период = 20. В моем понимании свойство SMA.IsFormed = true, т.е. индикатор сформирован, значит есть минимум 20 значений цены закрытия, которые позволяют рассчитать первое значение индикатора, до тех пор, пока не будут получены 20 значений цены закрытия свойство SMA.IsFormed = false.

Mikhail Sukhov
Mikhail Sukhov

UsilaDobry: Простая скользящая средняя цены закрытия это среднее арифметическое значений цены закрытия за период. В нашем случае период = 20. В моем понимании свойство SMA.IsFormed = true, т.е. индикатор сформирован, значит есть минимум 20 значений цены закрытия, которые позволяют рассчитать первое значение индикатора, до тех пор, пока не будут получены 20 значений цены закрытия свойство SMA.IsFormed = false.

Ну вот, а вы индикатор то в своем коде не заполняете. Как ему сформироваться при этом?

UsilaDobry
UsilaDobry

Изменил код, индикатор сначала выводится корректно (вложение 1), а потом с приходом нового тика сжимается и на последней свечке стягивается в точку (вложение 2)...? Хотя, согласно кода на последней свечке вообще не должно быть вычисление индикатора пока она в состоянии изменения...

                     ////////////////////ОТРИСОВКА ИСТОРИЧЕСКИХ СВЕЧЕЙ/////////////////////////////////////////////////////////////////////

                        this.GuiAsync(() =>
                            {
                                foreach (var candle in candles)
                                {
                                    var valueBb = _chartBollingerElement.Indicator.Process(new CandleIndicatorValue(candle) { IsFinal = true });
                                    var candle1 = candle;
                                    this.GuiAsync(() => _chartWindow.Chart.ProcessValues(candle1.OpenTime, new Dictionary<IChartElement, object>
                                                    {
                                                        {_candlesElem, candle1},
                                                        {_chartBollingerElement, new ChartIndicatorValue(_chartBollingerElement.Indicator, valueBb)},
                                                    }));
                                }
                            });
                
                        ///////////////////ОТРИСОВКА РЕАЛЬНЫХ СВЕЧЕЙ/////////////////////////////////////////////////////////////////////
                
                        _candleManager = new CandleManager(_trader);
                        
                        _series = new CandleSeries(typeof(TimeFrameCandle), security, (TimeSpan)AlfaTimeFrames.Minute10);

                        _series.ProcessCandle += candle => this.GuiAsync(() =>
                            {
                                if (candle.State == CandleStates.Finished)
                                {
                                    var valueBb = _chartBollingerElement.Indicator.Process(new CandleIndicatorValue(candle){IsFinal = true});
                                    if (_chartBollingerElement.Indicator.IsFormed)
                                    {
                                        var candle1 = candle;
                                        this.GuiAsync(() =>_chartWindow.Chart.ProcessValues(candle1.OpenTime,new Dictionary<IChartElement, object>
                                                            {
                                                                {_candlesElem, candle1},
                                                                {_chartBollingerElement,new ChartIndicatorValue(_chartBollingerElement.Indicator,valueBb)
                                                                },
                                                            }));
                                    }
                                }
                                else
                                {
                                    var candle1 = candle;
                                    this.GuiAsync(() => _chartWindow.Chart.ProcessCandle(_candlesElem, candle1));
                                }
                            });
Mikhail Sukhov
Mikhail Sukhov

UsilaDobry: Изменил код, индикатор сначала выводится корректно (вложение 1), а потом с приходом нового тика сжимается и на последней свечке стягивается в точку (вложение 2)...?

А теперь изучайте что такое IsFinal😂

UsilaDobry
UsilaDobry

Михаил Сухов:

UsilaDobry: Изменил код, индикатор сначала выводится корректно (вложение 1), а потом с приходом нового тика сжимается и на последней свечке стягивается в точку (вложение 2)...?

А теперь изучайте что такое IsFinal😂

🤨 Как я понимаю, IsFinal=true например для 10-минутного графика означает, что после формирования 10-минутной свечи (когда она примет состояние Finished) значение индикатора больше не будет изменяться, оно будет окончательным.

UsilaDobry
UsilaDobry

Странно...Вернул всё в первоначальный вид, (топик #18), убрал проверку на IsFormed, ничего не изменилось...Всё также, как в топике #27. Я уже закипаю...

////////////////////////ОТРИСОВКА ИСТОРИЧЕСКИХ СВЕЧЕЙ/////////////////////////////////////////////////////////////////////

                        this.GuiAsync(() =>
                            {
                                foreach (var candle in candles)
                                {
                                    var valueBb = _chartBollingerElement.Indicator.Process(new CandleIndicatorValue(candle));
                                    var candle1 = candle;
                                    this.GuiAsync(() => _chartWindow.Chart.ProcessValues(candle1.OpenTime, new Dictionary<IChartElement, object>
                                                    {
                                                        {_candlesElem, candle1},
                                                        {_chartBollingerElement, new ChartIndicatorValue(_chartBollingerElement.Indicator, valueBb)},
                                                    }));
                                }
                            });
                
                        ///////////ОТРИСОВКА РЕАЛЬНЫХ СВЕЧЕЙ/////////////////////////////////////////////////////////////////////
                
                        _candleManager = new CandleManager(_trader);
                        
                        _series = new CandleSeries(typeof(TimeFrameCandle), security, (TimeSpan)AlfaTimeFrames.Minute10);

                        _series.ProcessCandle += candle => this.GuiAsync(() =>
                            {
                                if (candle.State == CandleStates.Finished)
                                {
                                    var valueBb = _chartBollingerElement.Indicator.Process(new CandleIndicatorValue(candle));
                                    this.GuiAsync(() =>_chartWindow.Chart.ProcessValues(candle.OpenTime,new Dictionary<IChartElement, object>
                                                            {
                                                                {_candlesElem, candle},
                                                                {_chartBollingerElement,new ChartIndicatorValue(_chartBollingerElement.Indicator,valueBb)},
                                                            }));
                                }
                                else
                                {
                                    this.GuiAsync(() => _chartWindow.Chart.ProcessCandle(_candlesElem, candle));
                                }
                            });
UsilaDobry
UsilaDobry

Почему с AlfaDirect выводятся график завершенные и последняя незавершенная свечи? В Quik такого нет, при исполнении такого кода выводятся только завершенные свечи... Или это особенность терминала AlfaDirect?

_series.ProcessCandle += candle => 
                    {
                        if (candle.State == CandleStates.Finished)
                        {
                            this.GuiAsync(() =>_chartWindow.Chart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
                                                                         {
                                                                             {_candlesElem, candle},
                                                                         }));
                            
                        }
                        
                    };