namespace SampleSpreadHistoryTesting
{
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 StockSharp.Algo.Equity;
using StockSharp.Algo.Logging;
using StockSharp.Algo.Reporting;
using StockSharp.Algo.Storages;
using StockSharp.Algo.Strategies;
using StockSharp.Algo.Testing;
using StockSharp.BusinessEntities;
using Ecng.Collections;
using Ecng.Common;
using Ecng.Serialization;
using Ecng.Xaml;
public partial class MainWindow
{
private ICollection<EquityData> _curveItems;
private readonly LogManager _logManager = new LogManager();
private DateTime _lastUpdateDate;
private DateTime _startEmulationTime;
public void LogManager()
{
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;
}
}
public void StartBtnClick(object sender, RoutedEventArgs e)
{
// создаем хранилище для работы с базой данных котировок
var storage =
new TradingStorage(new InMemoryStorage())
{
BasePath = HistoryPath.Text
};
if (HistoryPath.Text.IsEmpty() || !Directory.Exists(HistoryPath.Text))
{
MessageBox.Show(this, "Неправильный путь");
return;
}
// выбираем интервал времени для тестирования (таймфрейм)
var timeFrame = TimeSpan.FromTicks(1);
// устанавливаем период тестирования (зависит от объема данных, хранящихся по пути HistoryPath)
var startTime = new DateTime(2012, 1, 1);
var stopTime = new DateTime(2012, 2, 1);
// создаем тестовый портфель
var portfolio =
new Portfolio
{
BeginAmount = 1000000m,
Name = "Test account"
};
// создаем первый инструмент спреда
var security1 =
new Security
{
Code = "SBER",
Exchange = Exchange.Test,
// идентификатор инструмента, по которому будет осуществлен поиск папки с историей стаканов
Id = "SBER@EQBR",
MinStepPrice = 0.01m,
MinStepSize = 0.01m,
Name = "Сбербанк России ОАО ао"
};
// создаем второй инструмент спреда
var security2 =
new Security
{
Code = "SRH2",
Exchange = Exchange.Test,
// идентификатор инструмента, по которому будет осуществлен поиск папки с историей стаканов
Id = "SRH2@RTS",
MinStepPrice = 1,
MinStepSize = 1,
Name = "SBRF-3.12"
};
// создаем стратегию для торговли спредом
var spreadStrategy =
new SpreadStrategy(security1, security2)
{
Security1 = security1,
Security2 = security2
};
// создаем шлюз для торговли
var trader =
new EmulationTrader(new[] {security1, security2}, new[] {portfolio})
{
// параметр влияет на занимаемую память (в случае достаточного объема памяти лучше увеличить)
DaysInMemory = 2,
MarketTimeChangedInterval = timeFrame,
Storage = storage,
WorkingTime = Exchange.Micex.WorkingTime
};
// если процесс был запущен, останавливаем его
if (trader.State != EmulationStates.Stopped)
{
StartBtn.IsEnabled = false;
spreadStrategy.Stop();
trader.Stop();
_logManager.Sources.Clear();
return;
}
trader.DepthGenerators[security1] =
new TrendMarketDepthGenerator(security1)
{
// время обновления стакана в базе данных для первого инструмента
Interval = TimeSpan.FromTicks(1)
};
trader.DepthGenerators[security2] =
new TrendMarketDepthGenerator(security2)
{
// время обновления стакана в базе данных для второго инструмента
Interval = TimeSpan.FromTicks(1)
};
// копируем параметры на визуальную панель
ParametersPanel.Parameters.Clear();
ParametersPanel.Parameters.AddRange(spreadStrategy.EquityManager.Parameters);
if (_curveItems == null)
_curveItems = Curve.CreateCurve(spreadStrategy.Name, Colors.DarkGreen);
else
_curveItems.Clear();
spreadStrategy.EquityManager.NewEquityData += data => this.GuiAsync(() => _curveItems.Add(data));
_logManager.Sources.Add(spreadStrategy);
// подписываемся на событие изменения времени, чтобы обновить ProgressBar
trader.MarketTimeChanged +=
() =>
{
// для оптимизации обновляем ProgressBar только при начале нового дня
if (trader.MarketTime.Date == _lastUpdateDate && trader.MarketTime < stopTime) return;
_lastUpdateDate = trader.MarketTime.Date;
this.GuiAsync(() => TestingProcess.Value = (trader.MarketTime - startTime).Ticks);
};
trader.StateChanged +=
() =>
{
switch (trader.State)
{
case EmulationStates.Stopped:
this.GuiAsync(
() =>
{
StartBtn.IsEnabled = true;
if (Convert.ToDecimal(TestingProcess.Value) ==
Convert.ToDecimal(TestingProcess.Maximum))
MessageBox.Show("Закончено за " + (DateTime.Now - _startEmulationTime));
else
MessageBox.Show("Отменено");
});
break;
case EmulationStates.Started:
// запускаем стратегию, когда эмулятор запустился
spreadStrategy.Start();
break;
}
};
// устанавливаем в визуальный элемент ProgressBar максимальное количество итераций
TestingProcess.Maximum = (stopTime - startTime).Ticks;
TestingProcess.Value = 0;
Report.IsEnabled = true;
_startEmulationTime = DateTime.Now;
// устанавливаем соединение и запускаем экспорт
trader.Connect();
trader.StartExport();
// задаем период тестирования (startTime, stopTime) и запускаем эмуляцию
trader.Start(startTime, stopTime);
}
private void ReportClick(object sender, RoutedEventArgs e)
{
// генерируем отчет по прошедшему тестированию (Excel может тормозить из-за большого количества данных)
new ExcelStrategyReport(ExcelStrategy, "sma.xls").Generate();
// открываем отчет
Process.Start("sma.xls");
}
public Strategy ExcelStrategy { get; set; }
}
}