Видео-уроки: Тестирование стратегий
[vk]http://vk.com/video_ext.php?oid=-66650972&id=167470538&hash=5489cd9b16a7da27&hd=3[/vk]
Темы занятия:
- Общие понятия о тестировании.
- Тестирование на исторических данных.
- Тестирование на рыночных данных.
Полезные ссылки: О тестировании Тетирование на историческиз данных Тестирование на рыночных данных Тестирование на случайных данных Настройки тестирования Тестирование торговой системы
Домашнее задание: [Основное] Провести полное тестирование на случайных данных. [Дополнительное] В проекте, приложенному к данному уроку, реализовать возможность выбора режима тестирования на случайных данных.
Вложения: Скачать проекты
Изменения в проектах:
Проект TestingAndTrading Файл MainWindow.cs
Начиная с версии S# 4.1.19.1 статус подключения коннектора вынесен в специальное свойство ExportState, которое может принимать значения: Disconnected - Не активно, Disconnecting - В процессе отключения, Connected - В процессе подключения, Connecting - Подключение активно, Failed - Ошибка подключения
Таким образом, теперь нет свойства IsExportStarted, а статус экспорта данных мы можем получать от свойства ExportState.
Было:
protected override void OnClosing(CancelEventArgs e)
{
if (_trader != null && _trader.IsExportStarted)
_trader.StopExport();
_myTradesWindow.Close();
base.OnClosing(e);
}
Стало:
protected override void OnClosing(CancelEventArgs e)
{
if (_trader != null && _trader.ExportState == ConnectionStates.Connected)
_trader.StopExport();
_myTradesWindow.Close();
base.OnClosing(e);
}
В версии S# 4.1.19.1 конструктор класса RealTimeEmulationTrader принимает еще и список портфелей, которыми он будет оперировать, кроме экземпляра коннектора. Мы просто создаем список и в качестве элемента этого списка передаем портфель, который был выбран пользователем.
Было:
private void ConnectBtn_Click(object sender, RoutedEventArgs e)
{
if (!_isRealTimeTesting && !_isHistoricalDataTesting)
// создаем обычного трейдера
_trader = new QuikTrader(QuikTerminal.GetDefaultPath());
else if (_isRealTimeTesting)
// создаем RealTimeEmulationTrader для тестирования на рыночных данных
_trader = new RealTimeEmulationTrader<QuikTrader>(new QuikTrader(QuikTerminal.GetDefaultPath()));
else if (_isHistoricalDataTesting)
{
// создаем хранилище
var storage = new StorageRegistry();
// указываем путь к хранилищу
((LocalMarketDataDrive) storage.DefaultDrive).Path = @"C:\HistoryData";
((LocalMarketDataDrive) storage.DefaultDrive).UseAlphabeticPath = true;
// создаем инструмент для тестирования
_security = new Security
{
Id = "RIU3@FORTS",
Code = "RIU3",
Name = "RTS-9.13",
MinStepSize = 10,
MinStepPrice = 2,
ExchangeBoard = ExchangeBoard.Forts
};
// создаем портфель для тестирования
_portfolio = new Portfolio {Name = "test account"};
// создаем EmulationTrader для тестирования на исторических данных
_trader = new EmulationTrader(new[] {_security}, new[] {_portfolio})
{
StorageRegistry = storage, // передаем хранилище EmulationTrader
MarketTimeChangedInterval = _timeFrame, // указываем интервал прихода события о смене времени
UseMarketDepth = true, // указываем использовать стаканы для эмуляции
UseCandlesTimeFrame = _timeFrame // загружаем свечи с указаным тайм - фрэймом
};
// если данные по стаканам отсутствуют,
// генерируем стакан для эмуляции на основании
// цен последних сделок или свечек
var mdGenerator = new TrendMarketDepthGenerator(_security)
{
Interval = TimeSpan.FromSeconds(1), // время обновления стакана
MaxAsksDepth = 1, // максимальное количество асков в стакане
MaxBidsDepth = 1, // максимальное количество бидов в стакане
UseTradeVolume = true, // использовать обьем последней сделки для генерации обьема лучших котировок
MaxSpreadStepCount = 5, // максимальный размер спрэда
MinSpreadStepCount = 2 // минимальный размер спрэда
};
// регистрируем стакан
((EmulationTrader) _trader).RegisterMarketDepth(mdGenerator);
}
_trader.NewSecurities += securities => this.GuiAsync(() => MySecurities.ItemsSource = securities);
_trader.NewPortfolios += portfolios => this.GuiAsync(() => MyPortfolios.ItemsSource = portfolios);
_trader.NewOrders += orders => this.GuiAsync(() => _myTradesWindow.MyOrders.Orders.AddRange(orders));
_trader.Connected += _trader.StartExport;
_trader.Connect();
}
Стало:
private void ConnectBtn_Click(object sender, RoutedEventArgs e)
{
if (!_isRealTimeTesting && !_isHistoricalDataTesting)
// создаем обычного трейдера
_trader = new QuikTrader(QuikTerminal.GetDefaultPath());
else if (_isRealTimeTesting)
// создаем RealTimeEmulationTrader для тестирования на рыночных данных
_trader = new RealTimeEmulationTrader(new QuikTrader(QuikTerminal.GetDefaultPath()),
new List<Portfolio> { (Portfolio)MyPortfolios.SelectedItem });
else if (_isHistoricalDataTesting)
{
// создаем хранилище
var storage = new StorageRegistry();
// указываем путь к хранилищу
((LocalMarketDataDrive) storage.DefaultDrive).Path = @"C:\HistoryData";
((LocalMarketDataDrive) storage.DefaultDrive).UseAlphabeticPath = true;
// создаем инструмент для тестирования
_security = new Security
{
Id = "RIU3@FORTS",
Code = "RIU3",
Name = "RTS-9.13",
MinStepSize = 10,
MinStepPrice = 2,
ExchangeBoard = ExchangeBoard.Forts
};
// создаем портфель для тестирования
_portfolio = new Portfolio {Name = "test account"};
// создаем EmulationTrader для тестирования на исторических данных
_trader = new EmulationTrader(new[] {_security}, new[] {_portfolio})
{
StorageRegistry = storage, // передаем хранилище EmulationTrader
MarketTimeChangedInterval = _timeFrame, // указываем интервал прихода события о смене времени
UseMarketDepth = true, // указываем использовать стаканы для эмуляции
UseCandlesTimeFrame = _timeFrame // загружаем свечи с указаным тайм - фрэймом
};
// если данные по стаканам отсутствуют,
// генерируем стакан для эмуляции на основании
// цен последних сделок или свечек
var mdGenerator = new TrendMarketDepthGenerator(_security)
{
Interval = TimeSpan.FromSeconds(1), // время обновления стакана
MaxAsksDepth = 1, // максимальное количество асков в стакане
MaxBidsDepth = 1, // максимальное количество бидов в стакане
UseTradeVolume = true, // использовать обьем последней сделки для генерации обьема лучших котировок
MaxSpreadStepCount = 5, // максимальный размер спрэда
MinSpreadStepCount = 2 // минимальный размер спрэда
};
// регистрируем стакан
((EmulationTrader) _trader).RegisterMarketDepth(mdGenerator);
}
_trader.NewSecurities += securities => this.GuiAsync(() => MySecurities.ItemsSource = securities);
_trader.NewPortfolios += portfolios => this.GuiAsync(() => MyPortfolios.ItemsSource = portfolios);
_trader.NewOrders += orders => this.GuiAsync(() => _myTradesWindow.MyOrders.Orders.AddRange(orders));
_trader.Connected += _trader.StartExport;
_trader.Connect();
}
Версия 4.1.19 требует явного указания размера начальной позиции портфеля, на момент тестирования, иначе, просто не будет хватать средств для выполнения тестирования. Было:
// создаем портфель для тестирования
_portfolio = new Portfolio { Name = "test account"};
Стало:
// создаем портфель для тестирования
_portfolio = new Portfolio { Name = "test account", BeginValue = 1000000};
Comments (18)
Login or Create account, Log in or register to leave a comment
Добрый день.
нет доступа к вложенному файлу (проект) для моего логина. Проверьте, пожалуйста.
Все права доступа у Вас есть. Очень странно.
Господа, похоже были какие-то проблемы у меня в браузере или куках. Проблема пропала когда я разлогинился и залогинился снова. Прошу прощения за ложную тревогу ))
Подключился к проекту
И что там делать ?
Куда идти и что нажимать, что бы получить указанные вами картинки и их исходные коды http://stocksharp.com/products/shell/
к сожалению повторить весь код что был приведен на уроке не смог, к тому же он отличается от того что приведен по ссылке (картинки точно другие)
Где и как прочитать что выводиться там на картинках? (очень часто встречал что многие параметры разработчики считают по разному) Как при тестировании найти оптимальные параметры стратегии ? Как протестировать стратегию, не на свечках, а к примеру на графике ренко и найти оптимальные параметры стратегии ? Как при тестировании и поиске оптимальный параметров указать, свою целевую функцию и искать её максимум (минимум), к примеру max(MAE) и т. д.
Куда идти и что нажимать, что бы получить указанные вами картинки и их исходные коды http://stocksharp.com/products/shell/ к сожалению повторить весь код что был приведен на уроке не смог, к тому же он отличается от того что приведен по ссылке (картинки точно другие)
Для этого достаточно подключиться к tfs через Visual studio и скачать проект shell.
Где и как прочитать что выводиться там на картинках? (очень часто встречал что многие параметры разработчики считают по разному) Информация о статистике доступна на этой странице http://stocksharp.com/doc/html/N_StockSharp_Algo_Statistics.htm Также вы можете самостоятельно закодировать необходимую вам метрику и сравнить её с нашей что бы убедиться, что всё рассчитывается правильно, если же значения будут сильно расходиться то вы можете использовать свою реализацию.
Как при тестировании найти оптимальные параметры стратегии ?
Контроль за нахождением оптимально значения для стратегии находится полностью в ваших руках, то есть вы самостоятельно можете реализовать нужный алгоритм поиска оптимального значения.
Как протестировать стратегию, не на свечках, а к примеру на графике ренко и найти оптимальные параметры стратегии ?
Для этого достаточно сделать стратегию основанную не на TimeFrameCandle , а на RenkoCandle
Как при тестировании и поиске оптимальный параметров указать, свою целевую функцию и искать её максимум (минимум), к примеру max(MAE) и т. д.
Как я уже говорил у вас есть полный контроль за нахождение оптимально значения. Соответственно вы можете самостоятельно реализовать любую целевую функцию для нахождения оптимальных параметров.
Для этого достаточно подключиться к tfs через Visual studio и скачать проект shell.
Скачал, сам не понял как но вроде получилось. Есть ли видео урок посвященный использованию Robot 4.0 ?
Информация о статистике доступна на этой странице http://stocksharp.com/do...harp_Algo_Statistics.htm Также вы можете самостоятельно закодировать необходимую вам метрику и сравнить её с нашей что бы убедиться, что всё рассчитывается правильно, если же значения будут сильно расходиться то вы можете использовать свою реализацию.
не смог там найти MFE, MAE и примеров их использования. Вообще примеров очень мало. Было бы великолепно увидеть несколько уроков посвященных построению роботов и поиску оптимальных значений.
Контроль за нахождением оптимально значения для стратегии находится полностью в ваших руках, то есть вы самостоятельно можете реализовать нужный алгоритм поиска оптимального значения.
Очень рад что Ваша вера в меня, столь огромна. Но я только изучаю С# (хотя и программирую роботов очень давно). Писать на С# генетическую оптимизацию даже не мечтаю. Но возможно эта ссылка поможет тем кто может это сделать http://www.mql5.com/ru/articles/55
Для этого достаточно сделать стратегию основанную не на TimeFrameCandle , а на RenkoCandle
А как увидеть эти графики ? Очень интересует RenkoCandle, как он реализован ? последний бар перерисовывается или нет ? как происходит его построение во время ГЭПа ? Есть ли кирпичи с нулевым объемом ? Кирпичи перекрываются, накладываются друг на друга или идут с гэпом ? и т.д.
Как я уже говорил у вас есть полный контроль за нахождение оптимально значения. Соответственно вы можете самостоятельно реализовать любую целевую функцию для нахождения оптимальных параметров.
Жизни не хватит, мне и так уже 48 лет и первую свою программу я написал в 1985 году (28 лет назад :-(().
З.Ы. Я четко знаю что я хочу запрограммировать. могу показать как это реализовано в NinjaTrader (исходные коды + математику, как это я делал в МТ4 и МТ5). Но даже после просмотра всех видео уроков не представляю как это сделать на С#(((
Добрый день.
Я скачал данный урок и запустил на выполнение на тестовых данных (предварительно скачав данные с помощью Hydra за 01.07.2013 по 12.07.2013) и изменил путь в программе на мой.
При отработке программы на графике PnL ничего не отображается. Захожу в MyTrades (Отдельное окно) и вижу, что сделок у меня нет вообще( верхняя половина окошка), а в нижней много информации по заявкам, однако у всех у них статус "Ошибка".
Пример из второго окна MyTradesWindow:
Подскажите в чем может быть дело и почему не происходят сделки?
Может кто подсказать, почему при тестировании стратегии на исторических данных не совершаются сделки?
Более детальный анализ показал, что стратегия срабатывает и выставляет заявки тогда когда нужно, однако после этого в статусе появляется состояние "Ошибка". После чего все повторяется, когда стратегия срабатывает во второй и последующие разы. При этом номер у заявок у всех 0.
Буду благодарен за ответ. Дальше как-то тяжело разбираться, когда пример из урока не отрабатывает.
С уважением, Николай.
Вы пробовали работать с проектами, предложенными в качестве примеров библиотеки S# или проектов из уроков S#? Там такие проблемы есть?
Иван, проблема как раз именно в проекте из урока S# номер 8 (08_lesson(Testing)).
Я запускаю именно проект, скаченные из StockSharp.Edu и меняю лишь путь данных на мой.
Я об этом уже писал чуть выше.
Запустить пример из Samples не получилось, не нашел библиотеку StockSharp.Messages, но посмотрев код она не особо отличается от того что в уроке 8.
Поэтому вопрос остается актуален.
Николай, причина была в том, что на торги не хватало средств в портфеле:
если изменить:
Либо по новой закачайте проект с сервера, там он исправлен, либо сами измените так, как показано выше.
Иван, спасибо. Действительно данное изменение помогло.
В версии API 4.2.1.7 уже не работает конструктов класса TrendMarketDepthGenerator с параметром Security, как это указано в примере для версии 4.1.19.1:var mdGenerator = new TrendMarketDepthGenerator(_security)
Согласно описанию конструктор требует объект типа StockSharp.Messages.SecurityId:
public TrendMarketDepthGenerator(StockSharp.Messages.SecurityId securityId)
Но наиболее очевидный вариант создания этого объекта, который вроде не вызывает ошибок с т.зр. VS2012: var mdGenerator = new TrendMarketDepthGenerator(new SecurityId(_security)); в дальнейшем при попытке зарегистрировать стакан в трейдере через метод RegisterMarketDepth(mdGenerator) дает ошибку {"Значение не может быть неопределенным.\r\nИмя параметра: secCode"}. См. принт-скрин.
Прошу сообшить как в версии API 4.2.1.7 правильно создать TrendMarketDepthGenerator.
Здравствуйте!
С помощью Гидры скачал сделки и свечи по Сбербанку с сайта Финама за 2013-й и 2014-й года. Взял пример SampleHistoryTesting из StockSharp 4.2.2.6, в коде окна MainWindow.xaml.cs поменял инструмент с RIZ2@FORTS на SBER@EQBR.
Поменял даты начала и окончания тестирования на соответствующие загруженной истории. Запустил тестирование на тиках, нет не одной сделки. Такое впечатление, что HistoryEmulationTrader вообще не видит историю.
И еще один момент. Когда Гидра показывает мне список загруженных сделок за дату, направление сделок (Buy/Sell) пустое. Это нормально, особенность Гидры, изменения на стороне Финама?
Кто нибудь сталкивался с подобным? Подскажите, пожалуйста, в какую сторону копать.
Спасибо!
Здравствуйте! Предыдущий вопрос по историческому тестированию снимается. Скачал с сайта версию 4.2.2.15, все заработало.
Ребята, верните доступ к курсам.
Не одно видео не отображается не из S#, не из C#.
http://stocksharp.com/forum/4346/My-pierieiekhali-v-sots-siet--Vkontaktie/