Решил перевести свой тестер на 4.2.2.1 до этого сидел на 4.1.19. И наткнулся на проблемы прорисовки графика. Может логика так изменилась, и я сообразить не могу. Либо баг.
Свечи на график выводит, сделки тоже выводит(порадовало что теперь не надо разницу во времени настраивать, за что отдельное спасибо), вторая ось Y тоже работает.
Не работает следующее
Выдает 2 свечки, крутишь колесо мыши ноль реакции. Жмешь двойным щелчком, выдает те что успел нарисовать, крутишь колесо мыши начинает масштабировать, увеличивает, уменьшает. Но увеличив до нужного масштаба прокрутить график нельзя, на 4.1.19 можно было захватить кнопкой мыши влево вправо прокрутить. Еще на 4.1.19 можно было колесом мыши уменьшить масштаб до того момента когда на графике видишь все свечи, да еще кусок пустого места который потихоньку заполняется вновь поступившими свечами. А сейчас даже если знаешь, что есть новые свечи, то прокруткой колеса мыши их не достать, только двойным щелчком. По поводу IsAutoScroll можно сделать вот так
Но тогда график заполняется свечами, и никакое масштабирование не работает. В итоге на графике все свечи и ни чего не видно.
Еще пробовал Отображение объема в виде профиля. Не понял как график вывести. Подскажите как?
Обрезал как мог SampleHistoryTesting и на нем экспериментировал. Вот код, если что не так делал подскажите.
using StockSharp.Algo.Indicators;
using StockSharp.Algo.Indicators.Misc;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Collections.Generic;
using Ecng.Xaml;
using Ecng.Collections;
using StockSharp.Algo;
using StockSharp.Algo.Candles;
using StockSharp.Algo.Storages;
using StockSharp.Algo.Testing;
using StockSharp.Algo.Indicators.Trend;
using StockSharp.BusinessEntities;
using StockSharp.Xaml.Charting;
using StockSharp.Xaml.Charting.IndicatorPainters;
namespace SampleHistoryTesting
{
public partial class MainWindow
{
private ChartCandleElement _candlesElem;
private ChartTradeElement _tradeElement;
private ChartIndicatorElement _volumeElement;
private ChartIndicatorElement el;
private readonly ChartArea main;
private DateTime _startEmulationTime;
public MainWindow()
{
InitializeComponent();
main = new ChartArea()
{
YAxises =
{
new ChartAxis
{
Id = "Y2",
AxisType = ChartAxisType.Numeric,
AxisAlignment = ChartAxisAlignment.Left,
Group = "G1",
AutoRange = true,
}
},
XAxises =
{
new ChartAxis
{
Id = "X2",
Group = "G1",
AutoRange = true,
AxisType = ChartAxisType.Numeric,
AxisAlignment = ChartAxisAlignment.Top,
FlipCoordinates = true,
DrawMajorGridLines = false,
DrawMajorTicks = false,
DrawMinorGridLines = false,
DrawMinorTicks = false,
DrwaLables = false
}
},
};
CandleChart.Areas.Add(main);
_candlesElem = new ChartCandleElement();
_tradeElement = new ChartTradeElement();
_volumeElement = new ChartIndicatorElement
{
Color = Colors.DarkRed,
IsLegend = true,
Indicator = new VolumeIndicator(),
Title = "Volume",
YAxisId = "Y2",
};
el = new ChartIndicatorElement
{
Color = Colors.Red,
IsLegend = true,
Indicator = new VolumeProfileIndicator {UseTotalVolume = true, Step = 5, },
Title = "VolumeProfile",
DrawStyle = ChartIndicatorDrawStyles.StackedBar,
StrokeThickness = 3,
IndicatorPainter = new VolumeProfilePainter(),
YAxisId = "Y2",
XAxisId = "X2",
};
CandleChart.IsAutoScroll = true;
main.XAxises[0].AutoRange = true;
main.Elements.Add(_candlesElem);
main.Elements.Add(_tradeElement);
main.Elements.Add(_volumeElement);
main.Elements.Add(el);
}
private void StartBtnClick(object sender, RoutedEventArgs e)
{
var path = @"f:\History\";
var timeFrame = TimeSpan.FromMinutes(5);
var security = new Security
{
//Id = "RIZ2@FORTS", // по идентификатору инструмента будет искаться папка с историческими маркет данными
//Code = "RIZ2",
Name = "RTS-12.12",
Id = "SPFB.RTS@FORTS",
Code = "SPFB.RTS",
Class = "SPFB",
MinStepSize = 10,
MinStepPrice = 2,
MinPrice = 10,
MaxPrice = 1000000,
MarginBuy = 10000, // задаем ГО
MarginSell = 10000,
ExchangeBoard = ExchangeBoard.Forts,
};
// тестовый портфель
var portfolio = new Portfolio
{
Name = "test account",
BeginValue = 1000000,
};
// хранилище, через которое будет производиться доступ к тиковой и котировочной базе
/*-------------- Хранилище-------------------------------------*/
var storageRegistry = new StorageRegistry();
// Добавление в источник свечек TimeFrameCandleBuilder источник данных в виде файлов гидры
((LocalMarketDataDrive) storageRegistry.DefaultDrive).Path = path;
var startTime = new DateTime(2013, 1, 1);
var stopTime = new DateTime(2013, 1, 30);
// создаем шлюз для эмуляции
// инициализируем настройки (инструмент в истории обновляется раз в секунду)
var trader = new HistoryEmulationTrader(new[] {security}, new[] {portfolio})
{
StorageRegistry = storageRegistry,
MarketEmulator =
{
Settings =
{
// использовать стаканы
UseMarketDepth = true,
// использовать свечки
UseCandlesTimeFrame = TimeSpan.FromMinutes(5),
// проверка что стаканы соответствуют сделкам. Улучшает реалистичность тестирования.
SyncDepthToTrades = true,
// сведение сделки в эмуляторе если цена коснулась нашей лимитной заявки.
// Если выключено - требуется "прохождение цены сквозь уровень"
// (более "суровый" режим тестирования.)
FillOnTouch = false,
}
}
};
((MessageAdapter) trader.MarketDataAdapter).MarketTimeChangedInterval = timeFrame;
trader.RegisterMarketDepth(new TrendMarketDepthGenerator(trader.GetSecurityId(security)));
trader.Connect();
trader.StartExport();
var candleManager = new CandleManager(trader);
var series = new CandleSeries(typeof (TimeFrameCandle), security, timeFrame);
// создаем торговую стратегию, скользящие средние на 80 5-минуток и 10 5-минуток
var strategy = new SmaStrategy(series, new SimpleMovingAverage {Length = 80},
new SimpleMovingAverage {Length = 10})
{
Volume = 1,
Portfolio = portfolio,
Security = security,
Trader = trader,
};
// копируем параметры на визуальную панель
ParameterGrid.Parameters.Clear();
ParameterGrid.Parameters.AddRange(strategy.StatisticManager.Parameters);
// и подписываемся на событие изменения времени, чтобы обновить ProgressBar
trader.MarketTimeChanged += a =>
{
var aa = a;
};
trader.NewMyTrades += (trade) =>
{
var t = timeFrame.GetCandleBounds(trade.Last().Trade.Time).Min;
this.GuiAsync(() =>CandleChart.ProcessValues(t,new Dictionary<IChartElement, object>{{_tradeElement, trade.Last()},}));
};
candleManager.Processing += (send, candle) =>
{
var vol1 = new ChartIndicatorValue(_volumeElement.Indicator, candle.TotalVolume) { IsFormed = true };
var vol2 = new VolumeProfileIndicatorValue();
if (candle.State == CandleStates.Finished)
{
this.GuiAsync(() => CandleChart.ProcessValues(candle.OpenTime, new Dictionary<IChartElement, object>
{
{_candlesElem, candle},
{_volumeElement, vol1},
// {el,vol2}
}));
}
};
candleManager.ProcessDataError += (a) =>
{
var aa = a;
};
candleManager.Stopped += (a) =>
{
var aa = a;
};
candleManager.Log += (a) =>
{
var aa = a;
};
trader.StateChanged += (oldState, newState) =>
{
if (trader.State == EmulationStates.Started)
{
// запускаем стратегию когда эмулятор запустился
strategy.Start();
candleManager.Start(series);
}
};
trader.ExportStarted += () =>
{
// strategy.Start();
// candleManager.Start(series);
};
// запускаем эмуляцию
// указываем даты начала и конца тестирования
trader.Start(startTime, stopTime);
}
}
}
Еще проект прикрепляю.