Свечной график
Chart - графический компонет, который позволяет строить биржевые графики: свечи, индикаторы, и отображать на графиках маркеры заявок и сделок.
Ниже приведен пример построения графика при помощи компонета Chart. За основу взят пример из Samples/Common/SampleConnection, в который внесены некоторые изменения.
Пример построения графика при помощи Chart
В XAML создаем окно и добавляем в него графический компонент Chart. Присваиваем компоненту имя Chart. Обратите внимание, что при создании окна нужно добавить пространство имен http://schemas.stocksharp.com/xaml.
<Window x:Class="SampleCandles.ChartWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:charting="http://schemas.stocksharp.com/xaml" Title="ChartWindow" Height="300" Width="300"> <charting:Chart x:Name="Chart" x:FieldModifier="public" /> </Window>
В коде главного окна декларируем переменные для областей графика, элементов графика, индикаторов и подписок.
private readonly Dictionary<Subscription, ChartWindow> _chartWindows = new Dictionary<Subscription, ChartWindow>(); private readonly Connector _connector = new Connector(); private readonly LogManager _logManager; private ChartArea _candlesArea; private ChartArea _indicatorsArea; private ChartIndicatorElement _smaChartElement; private ChartIndicatorElement _macdChartElement; private ChartCandleElement _candlesElem; private SimpleMovingAverage _sma; private MovingAverageConvergenceDivergence _macd;
В обработчике события Click кнопки Connect, наряду с подпиской на события коннектора и вызовом метода IConnector.Connect, подписываемся на событие Connector.CandleReceived. В обработчике этого события при получении новой свечи будет выполнятся отрисовка графика.
private void ConnectClick(object sender, RoutedEventArgs e) { _connector.CandleReceived += OnCandleReceived; // Подписываемся на другие необходимые события _connector.Connected += () => this.GuiAsync(() => { /* Обработка подключения */ }); _connector.Disconnected += () => this.GuiAsync(() => { /* Обработка отключения */ }); // Подключаемся к торговой системе _connector.Connect(); }
В обработчике кнопки ShowChart создаем объекты индикаторов, областей и элементов графика. Добавляем элементы к областям, а области к чарту. Открываем окно графика и запускаем подписку на свечи.
private void ShowChartClick(object sender, RoutedEventArgs e) { var security = SelectedSecurity; // Создаем подписку на свечи var subscription = new Subscription( DataType.TimeFrame(TimeSpan.FromMinutes(5)), security) { MarketData = { // Запрашиваем исторические данные за 30 дней From = DateTime.Today.Subtract(TimeSpan.FromDays(30)), To = DateTime.Now, // Получаем только завершенные свечи IsFinishedOnly = true } }; // Создаем окно графика _chartWindows.SafeAdd(subscription, key => { var wnd = new ChartWindow { Title = $"{security.Code} {TimeSpan.FromMinutes(5)}" }; wnd.MakeHideable(); // Инициализируем индикаторы _sma = new SimpleMovingAverage() { Length = 11 }; _macd = new MovingAverageConvergenceDivergence(); // Инициализируем элементы графика _smaChartElement = new ChartIndicatorElement(); _macdChartElement = new ChartIndicatorElement(); _candlesElem = new ChartCandleElement(); // Устанавливаем стиль отображения MACD в виде гистограммы _macdChartElement.DrawStyle = DrawStyles.Histogram; // Инициализируем области графика _candlesArea = new ChartArea(); _indicatorsArea = new ChartArea(); // Добавляем области к чарту wnd.Chart.Areas.Add(_candlesArea); wnd.Chart.Areas.Add(_indicatorsArea); // Добавляем элементы к областям _candlesArea.Elements.Add(_candlesElem); _candlesArea.Elements.Add(_smaChartElement); _indicatorsArea.Elements.Add(_macdChartElement); // Привязываем элементы графика к подписке для автоматической отрисовки wnd.Chart.AddElement(_candlesArea, _candlesElem, subscription); wnd.Chart.AddElement(_candlesArea, _smaChartElement, subscription); wnd.Chart.AddElement(_indicatorsArea, _macdChartElement, subscription); return wnd; }).Show(); // Запускаем подписку на свечи _connector.Subscribe(subscription); }
В обработчике события Connector.CandleReceived производим отрисовку свечи и значений индикаторов для каждой завершенной свечи.
private void OnCandleReceived(Subscription subscription, ICandleMessage candle) { var wnd = _chartWindows.TryGetValue(subscription); if (wnd == null) return; // Обрабатываем только завершенные свечи if (candle.State != CandleStates.Finished) return; // Вычисляем значения индикаторов var smaValue = _sma.Process(candle); var macdValue = _macd.Process(candle); // Создаем данные для отрисовки var data = new ChartDrawData(); data .Group(candle.OpenTime) .Add(_candlesElem, candle) .Add(_smaChartElement, smaValue) .Add(_macdChartElement, macdValue); // Отрисовываем данные на графике в потоке пользовательского интерфейса this.GuiAsync(() => wnd.Chart.Draw(data)); }
Пример с автоматической отрисовкой графика
Начиная с последних версий StockSharp, имеется возможность настроить автоматическую отрисовку графика без необходимости явного вызова метода Draw. Для этого при настройке Chart используется метод AddElement, который связывает элемент графика с подпиской:
private void SetupAutoDrawingChart()
{
var security = SelectedSecurity;
// Создаем элементы графика
var candleElement = new ChartCandleElement();
var smaElement = new ChartIndicatorElement { Title = "SMA" };
// Создаем области графика
var area = new ChartArea();
// Добавляем область к графику
Chart.Areas.Add(area);
// Создаем подписку на свечи
var subscription = new Subscription(
DataType.TimeFrame(TimeSpan.FromMinutes(5)),
security)
{
MarketData =
{
From = DateTime.Today.Subtract(TimeSpan.FromDays(30)),
To = DateTime.Now
}
};
// Привязываем элементы к области графика и подписке
Chart.AddElement(area, candleElement, subscription);
Chart.AddElement(area, smaElement, subscription);
// Создаем индикатор
var sma = new SimpleMovingAverage { Length = 14 };
// Подписываемся на событие получения свечей для обработки индикатором
_connector.CandleReceived += (sub, candle) =>
{
if (sub == subscription && candle.State == CandleStates.Finished)
{
// Обрабатываем свечу индикатором и получаем значение
var smaValue = sma.Process(candle);
// Отрисовываем значение индикатора
var data = new ChartDrawData();
data
.Group(candle.OpenTime)
.Add(smaElement, smaValue);
this.GuiAsync(() => Chart.Draw(data));
}
};
// Запускаем подписку
_connector.Subscribe(subscription);
}
Отображение заявок и сделок на графике
Можно отображать маркеры заявок и сделок непосредственно на графике:
// Создаем элементы для отображения заявок и сделок
var orderElement = new ChartOrderElement();
var tradeElement = new ChartTradeElement();
// Добавляем элементы на область графика
_candlesArea.Elements.Add(orderElement);
_candlesArea.Elements.Add(tradeElement);
// Подписываемся на события получения заявок и сделок
_connector.OrderReceived += (sub, order) =>
{
if (order.Security != _security)
return;
// Отрисовываем заявку на графике
var data = new ChartDrawData();
data.Group(order.Time).Add(orderElement, order);
this.GuiAsync(() => Chart.Draw(data));
};
_connector.OwnTradeReceived += (sub, trade) =>
{
if (trade.Order.Security != _security)
return;
// Отрисовываем сделку на графике
var data = new ChartDrawData();
data.Group(trade.Time).Add(tradeElement, trade);
this.GuiAsync(() => Chart.Draw(data));
};
Очистка графика
Для очистки графика можно использовать метод Reset:
// Очистка всего графика
Chart.Reset();
// Очистка конкретной области
_candlesArea.Reset();
// Очистка конкретного элемента
_candlesElem.Reset();