namespace SampleHistoryTesting { using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Windows; using System.Windows.Forms; using System.Windows.Media; using MessageBox = System.Windows.MessageBox; using Ecng.Common; using Ecng.Xaml; using Ecng.Collections; using StockSharp.Algo.Candles; using StockSharp.Algo.Reporting; using StockSharp.Algo.Storages; using StockSharp.Algo.Strategies; using StockSharp.Algo.Testing; using StockSharp.Algo.Logging; using StockSharp.BusinessEntities; using StockSharp.Xaml; /// /// Stock Sharp v4.1.4 /// public partial class MainWindow { private Strategy _strategy; private ICollection _curveItems; private EmulationTrader _trader; private readonly LogManager _logManager = new LogManager (); private DateTime _startEmulationTime; public MainWindow() { InitializeComponent (); _logManager.Listeners.Add ( new FileLogListener ( "log.txt" ) ); } private void FindPathClick( object sender, RoutedEventArgs e ) { var dlg = new FolderBrowserDialog (); if (!HistoryPath.Text.IsEmpty ()) dlg.SelectedPath = HistoryPath.Text; if (dlg.ShowDialog () == System.Windows.Forms.DialogResult.OK) { HistoryPath.Text = dlg.SelectedPath; } } private void StartBtnClick( object sender, RoutedEventArgs e ) { // если процесс был запущен, то его останавливаем if (_trader != null && _trader.State != EmulationStates.Stopped) { StartBtn.IsEnabled = false; _strategy.Stop (); _trader.Stop (); _logManager.Sources.Clear (); return; } HistoryPath.Text = @"E:\Data\"; //!!!! if (HistoryPath.Text.IsEmpty () || !Directory.Exists ( HistoryPath.Text )) { MessageBox.Show ( this, "Неправильный путь." ); return; } // создаем тестовый инструмент, на котором будет производится тестирование // по идентификатору инструмента будет искаться папка с историческими маркет данными var security = new Security { /* Id ="RIU9@RTS", Code ="RIU9", Name ="RTS-9.09", MinStepSize =5, MinStepPrice = 2, Exchange =Exchange.Rts, */ Id = "SBER@EQBR", Code = "SBER", Name = "Sberbank", MinStepSize = 0.01m, MinStepPrice = 1, Exchange = Exchange.Micex, }; // тестовый портфель var portfolio = new Portfolio { Name = "test account", BeginValue = 1000000m }; // хранилище, через которое будет производиться доступ к тиковой и котировочной базе var storageRegistry = new StorageRegistry (); // изменяем путь, используемый по умолчанию ((LocalMarketDataDrive)storageRegistry.DefaultDrive).Path = HistoryPath.Text; var timeFrame = TimeSpan.FromMinutes ( 5 ); // в реальности период может быть другим, и это зависит от объема данных, // хранящихся по пути HistoryPath, // RTS-9.09 /* var startTime = new DateTime ( 2008, 12, 15 ); var stopTime = new DateTime ( 2009, 9, 14 ); */ // SBER var startTime = new DateTime ( 2012, 5, 1 ); var stopTime = new DateTime ( 2012, 8, 10 ); _trader = new EmulationTrader ( new[] { security }, new[] { portfolio } ) { MarketTimeChangedInterval = timeFrame, StorageRegistry = storageRegistry, // необходимо включать только если есть история стаканов и нужно получить более точное тестирование UseMarketDepth = false, }; // история по стакана отсутствует, но стаканы необходимы для стратегии, // то их можно сгенерировать на основании цен последних сделок //_trader.RegisterMarketDepth(new TrendMarketDepthGenerator(security) //{ // // стакан для инструмента в истории обновляется раз в секунду // Interval = TimeSpan.FromSeconds(1), //}); // соединяемся с трейдером и запускаем экспорт, // чтобы инициализировать переданными инструментами и портфелями необходимые свойства EmulationTrader _trader.Connect (); _trader.StartExport (); var candleManager = new CandleManager ( _trader ); var series = new CandleSeries ( typeof ( TimeFrameCandle ), security, timeFrame ); candleManager.Start ( series ); #region Стратегия SMA. /* создаем торговую стратегию, скользящие средние на 80 5-минуток и 10 5-минуток _strategy = new SmaStrategy(series, new SimpleMovingAverage { Length = 80 }, new SimpleMovingAverage { Length = 10 }) { Volume = 1, Portfolio = portfolio, Security = security, Trader = _trader }; */ #endregion _strategy = new MyStopLossStrategy ( series, timeFrame ) { Volume = 1, Portfolio = portfolio, Security = security, Trader = _trader, }; // копируем параметры на визуальную панель ParametersPanel.Parameters.Clear (); ParametersPanel.Parameters.AddRange ( _strategy.StatisticManager.Parameters ); if (_curveItems == null) _curveItems = Curve.CreateCurve ( _strategy.Name, Colors.DarkGreen ); else _curveItems.Clear (); _strategy.PnLChanged += () => { var data = new EquityData { Time = _strategy.GetMarketTime(), Value = _strategy.PnL, }; _strategy.AddInfoLog ( string.Format ( "Time / PnL // {0} / {1} //", _strategy.GetMarketTime(), _strategy.PnL.ToString ( "F5" ) ) ); this.GuiAsync ( () => _curveItems.Add ( data ) ); }; _logManager.Sources.Add ( _strategy ); // задаем шаг ProgressBar var progressStep = ((stopTime - startTime).Ticks / 100).To (); var nextTime = startTime + progressStep; TestingProcess.Maximum = 100; TestingProcess.Value = 0; // и подписываемся на событие изменения времени, чтобы обновить ProgressBar _trader.MarketTimeChanged += diff => { if (_trader.CurrentTime >= nextTime || _trader.CurrentTime >= stopTime) { nextTime += progressStep; this.GuiAsync ( () => TestingProcess.Value++ ); } }; _trader.StateChanged += ( oldState, newState ) => { if (_trader.State == EmulationStates.Stopped) { this.GuiAsync ( () => { StartBtn.IsEnabled = true; if (_trader.IsFinished) { TestingProcess.Value = TestingProcess.Maximum; MessageBox.Show ( "Закончено за " + (DateTime.Now - _startEmulationTime) ); } else MessageBox.Show ( "Отменено" ); } ); } else if (_trader.State == EmulationStates.Started) { // запускаем стратегию когда эмулятор запустился _strategy.Start (); } }; Report.IsEnabled = true; _startEmulationTime = DateTime.Now; // запускаем эмуляцию, задавая период тестирования (startTime, stopTime). _trader.Start ( startTime, stopTime ); } private void ReportClick( object sender, RoutedEventArgs e ) { // сгерерировать отчет по прошедшему тестированию // Внимание! сделок и заявок может быть большое количество, // поэтому Excel отчет может тормозить new ExcelStrategyReport ( _strategy, "sma.xls" ).Generate (); // открыть отчет Process.Start ( "sma.xls" ); } } }