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" );
}
}
}