Бэктест forex в Python: данные, время и учет
Проверка стратегии в Python требует цепочки от исходных данных и доступной тогда информации к поручениям, исполнениям и сверенной ведомости. Сохраняйте идентификаторы записей вместе со временем. Быстрая кривая средств не показывает, использовал ли сигнал будущий выпуск, незакрытый бар или цену, которой модель исполнения не допускала.
Среда под исследовательский вопрос
Тестер стратегий MT5 поддерживает мультивалютные советники, тестирование и оптимизацию. Python — другой способ организовать данные, собственные расчеты и исследование, а не обязательный выход из ограничения одной парой. Сравнивайте данные, контракт и требования к исполнению. Для поиска расхождений между реализациями сохраняйте один зафиксированный набор и одинаковые правила. Сам термин проверка на истории не устанавливает причинность и качество модели.
Данные вместе с их смыслом
Запишите инструмент и продукт, поставщика, зону, сторону котировки, шаг наблюдений и диапазон выгрузки. Проверьте повторные идентификаторы, порядок и пропуски. Закрытие рынка не означает испорченный файл; заполнение промежутка способно выдумать наблюдения. Сохраняйте оригинал и каждое преобразование.
MetaTrader 5.copy_rates_range возвращает время, OHLC, тиковый объем, спред и реальный объем. Полной исторической тарифной сетки комиссий и финансирования он не дает. Доступные бары зависят от истории терминала и настроек; запрос диапазона не доказывает его полного получения. Временные аргументы и полученные данные используют UTC. До преобразования сессий задавайте зоны явно.
pandas и NumPy поддерживают расчеты данных. Backtrader организует событийный процесс. Симуляция портфеля vectorbt также обновляет деньги и активы; у нее есть режимы поручений, сигналов и пользовательской функции поручения. Название библиотеки не гарантирует реалистичное исполнение или постоянную скорость. Выберите минимально полезный набор, зафиксируйте версии, лицензию, права на данные и поддержанную среду. Данные и развертывание могут стоить отдельно.
Метка записи и позиция в массиве различаются
Три закрытые вымышленные записи цен: A=100, B=102, C=104. Отдельный Series флагов идет в порядке C:1, A:0, B:0. Единица обозначает кандидата для дальнейшей модели, а не поручение или цену исполнения.
Прокрутите схему по горизонтали; с клавиатуры используйте Tab и стрелки.
pandas: Series и выравнивание по меткам (на английском): операции Series выравниваются по меткам. prices * flags дает A:0, B:0, C:104. Умножение двух массивов после to_numpy() —100,0,0; присвоение этого результата порядку A,B,C делает кандидатом A. Проверяйте ID до снятия индекса, а не только равенство длины.
Прокрутите таблицу по горизонтали, чтобы увидеть все столбцы. С клавиатуры используйте Tab и стрелки влево и вправо.
| ID | Цена | Флаг этого ID | Результат |
|---|---|---|---|
| A | 100 | 0 | 0 |
| B | 102 | 0 | 0 |
| C | 104 | 1 | 104 |
Когда запись становится доступной
Бар с меткой открытия еще не полностью наблюден в этот момент. У H1, открытого в 10:00, законченный OHLC доступен только после окончания периода. В resample параметр closed задает принадлежность интервалу, label — подпись края. Изменение подписи не меняет фактическую доступность агрегата.
Макронаблюдения присоединяйте по времени публикации доступной тогда версии, не только по месяцу данных. merge_asof требует отсортированных ключей. backward выбирает более ранний или равный ключ, nearest способен выбрать будущий. Ни один режим не знает, была ли величина впоследствии пересмотрена. Задайте допуск и порядок событий с одинаковой меткой.
Исходная собственная проверка записей: решение 10:04 UTC, сохранены только выпуски 10:00 со значением 50 и 10:05 со значением 60. Без ограничения допуска backward выбирает 50, четыре минуты ранее; nearest выбирает 60, одну минуту спустя. При включительном обратном допуске две минуты совпадения нет. Сохраняйте пропуск: подстановка более близкого будущего выпуска меняет доступную информацию.
Рецепт только для закрытых баров
У первых двадцати вымышленных баров High идет от 100 до 119, каждый Open=High−0.5, Low=High−2, Close=High−1. Бар 21: O 120/H121/L 118/C 120.5; бар 22: O 120.6/H122/L 119/C 121. Это произвольные цены, не рыночные данные и не сделка forex.
previous_high = bars["high"].shift(1).rolling(20).max()
signal = bars["close"] > previous_high
next_bar_signal = signal.shift(1, fill_value=False)На баре 21 максимум предыдущих двадцати равен 119:120.5>119 истинно. Если включить текущий High, порог 121 и условие ложно. Последняя строка переносит наблюденный сигнал в бар 22; она не задает цену, не доказывает принятие поручения и не выбирает выход. Оставляйте закрытые входные бары, отдельно задавайте объем, тип поручения и очередность событий.
Одинаковое время еще не означает известную информацию
Новый отдельный пример добавляет событие с одинаковой временной меткой. Решение имеет время 10:04:00 UTC и порядковый номер события 2. Помимо известного выпуска 10:00 со значением 50 записан выпуск 10:04:00 со значением 55, но его доступность наступает событием 3, после решения. Обычный backward с allow_exact_matches=True выберет 55 по времени, хотя по заданному порядку оно еще неизвестно. allow_exact_matches=False выбирает 50; вместе с обратным допуском две минуты он не найдет запись. Нельзя заменять пропуск будущей или еще недоступной информацией. Это не универсальная рекомендация исключать совпадающие метки: в независимом зеркальном варианте выпуск 55 доступен событием 1 до решения 2, и тогда совпадение времени допустимо. Храните подтвержденный порядок доступности. Номер в этой модели задан явно, а не восстановлен из одной округленной метки времени.
Прокрутите таблицу по горизонтали, чтобы увидеть все столбцы. С клавиатуры используйте Tab и стрелки влево и вправо.
| Модель | Параметры | Значение | Что проверить |
|---|---|---|---|
| Исходные 10:00/10:05 | backward | 50 | Четыре минуты ранее |
| Исходные 10:00/10:05 | nearest | 60 | Одна минута в будущем |
| Исходные 10:00/10:05 | backward, допуск 2 мин | Нет записи | Четыре минуты превышают допуск |
| Новый выпуск 10:04, событие 3 | backward, exact=True | 55 | После решения 2: еще неизвестен |
| Та же новая модель | backward, exact=False | 50 | Более ранняя запись |
| Та же новая модель | backward, exact=False,2 мин | Нет записи | Ранний выпуск за пределом допуска |
Сигнал, исполнение и затраты — разные этапы
В документированной стандартной модели Backtrader поручение Market, созданное после обработки текущего бара, использует Open следующего доступного. Иные настройки или модели могут менять момент. Если стоп и цель находятся внутри одного бара, OHLC не указывает порядок их наблюдения.
Отдельная исходная модель одной сделки: покупка 10 000 EUR по заданной Ask EUR/USD 1.1002 при одновременной Bid 1.1000. Позднее продажа всех единиц по заданной Bid 1.1012 при Ask 1.1014. Пипс 0.0001 USD на EUR. Между исполнениями десять пипсов, или 10 USD. Комиссия равна 1 USD с каждой стороны; чистый результат 8 USD. Финансирование и дополнительное проскальзывание нулевые по условию. Вычесть еще два пипса входного спреда — получить 6 USD и второй раз учесть уже включенную разницу цен.
Для нужного продукта задайте финансирование, конвертацию, размер контракта, маржу и отказанные поручения. Для нескольких инструментов учитывайте общий денежный остаток, свободную маржу и порядок одновременных запросов. Сумма независимых кривых может включить сделки, на которые общему счету не хватило денег. Для случайного проскальзывания нужны распределение, начальное состояние генератора и версия библиотеки.
Ведомость делает результат проверяемым
В отдельном примере размер R одинаков в деньгах на протяжении всей серии. Ровно 40 выигрышей по+2 R и 60 потерь по−1 R дают 80 R выигрышей,60 R потерь, итог 20 R. Profit factor 80/60≈1.33, среднее 0.2 R на сделку. Затрата 0.1 R на каждую из 100 сделок меняет исходы на+1.9 R и−1.1 R: выигрыши 76 R, потери 66 R, итог 10 R, PF 76/66≈1.15, среднее 0.1 R. Это арифметика заданных исходов, не настоящий тест.
Прокрутите таблицу по горизонтали, чтобы увидеть все столбцы. С клавиатуры используйте Tab и стрелки влево и вправо.
| Серия | Сумма плюсов | Модуль минусов | Итог | Отношения |
|---|---|---|---|---|
| 40×(+2 R),60×(−1 R), до затрат | 80 R | 60 R | 20 R | PF 4/3≈1.33; среднее 0.2 R |
| Те же 100 исходов, затрата 0.1 R каждый | 76 R | 66 R | 10 R | PF 38/33≈1.15; среднее 0.1 R |
| 75×(+0.2 R),25×(−1 R), до затрат | 15 R | 25 R | −10 R | PF 0.6;75% положительных |
Отдельный контрпример повторного входа задает условия пяти баров: true,true,true,false,true. Обе политики входят на баре 1. Стоп закрывает позицию на баре 2 до проверки входа; поздних выходов нет. Политика «нет позиции и условие истинно» входит повторно на баре 2 и остается в позиции. Политика, требующая нового false для повторного взведения, ждет на 2/3, взводится на 4 и входит на 5. В обоих случаях два входа, но разные моменты. Это выбранный конечный автомат, не утверждение о стандартном поведении библиотек.
Сохраняйте оценку открытых позиций и результаты закрытых сделок. При измерении просадки включайте начальный капитал, отделяйте пополнения и выводы от доходности стратегии. Не добавляйте доходность, Sharpe или просадку, которые невозможно восстановить из датированной ведомости и ряда средств.
Подбор и отложенные данные
Зафиксируйте хронологические обучающие и проверочные окна до выбора правил. Запишите все инструменты, параметры, фильтры и разбиения, включая отвергнутые варианты. Мало параметров не означает мало проверенных гипотез. Статья Bailey и соавторов рассматривает повторный выбор стратегии и переоптимизацию; по нашим вымышленным примерам вероятность PBO не оценивается.
Высокая доля выигрышей сама не диагностирует ошибку. Другая вымышленная сотня:75 выигрышей по+0.2 R и 25 потерь по−1 R дает 15 R плюсов,25 R минусов,−10 R до расходов и PF 0.6, несмотря на 75% успешных исходов. Проверяйте наблюдения, зависимость выборки, исполнение, затраты и чувствительность. Универсальные пороги процента выигрышей или PF не устанавливают заглядывание в будущее.
Практическая последовательность
- Создайте изолированный проект. Сохраните нетронутые данные с ID, источником, UTC, стороной котировки и версиями. Для этого офлайн-упражнения не нужны живые учетные данные или поручение.
- Разберите несколько заданных записей: когда сигнал доступен, какое следующее событие может исполнить его и что делать с пропуском/пересмотром.
- Определите состояние позиции: повторное true добавляет, разворачивает, повторно входит после стопа или ждет взведения? Проверьте ожидаемые ID входов.
- Сверьте каждую цену и затрату с ведомостью, затем выводите результаты. Сопоставьте зафиксированные правила с явно заданными альтернативными допущениями исполнения.
- Сохраните журнал попыток, отложенные окна, версии и ограничения. Сравнивайте одинаковые периоды и неопределенность; постоянное падение показателя не определяет его причину.
Следующий шаг
Проверьте доступность записей перед каждым окном walk-forward.
Проверьте понимание
Цены идут A,B,C, а флаги C: 1, A: 0, B: 0. Какую запись выбирает выравнивание Series по меткам?
Ответ и объяснения без JavaScript
Правильный ответ: C с ценой 104.
C с ценой 104.
Единственный флаг 1 принадлежит ID C, у которого цена 104.
A с ценой 100.
Это результат позиционного умножения массивов. По меткам первый флаг относится к C, а не A.
Series разного порядка не выравниваются.
Одинаковые уникальные ID позволяют выравнивание независимо от порядка. Пропущенные и повторные ID требуют отдельной проверки.
Вопросы и ответы
Нужен ли продвинутый Python?
Начните с чтения и проверки данных, функций и различия индекса и позиции массива. Воспроизведите небольшую полную модель до масштабирования. Выравнивание в статье — проверка данных, не полная стратегия: время, состояние, выходы и исполнение еще определяются. Ни тридцать строк, ни фиксированное расписание обучения не устанавливают готовность.
Что выбрать: Backtrader или vectorbt?
Сравните документированную модель с задачей. Backtrader использует событийный процесс; стандартный Market исполняется на Open следующего доступного бара. У vectorbt есть поручения, сигналы и пользовательские функции, с обновлением денежных остатков и активов. Векторный ввод не означает независимость исполнения от состояния. Проверяйте настройки, затраты и очередь событий; постоянная скорость и реалистичная валидация не гарантируются.
Где брать надежную историю?
Установите поставщика, продукт, сторону котировки, зону и доступную историю. MetaTrader 5.copy_rates_range дает OHLC и спред, UTC и ограничения истории терминала, но не полный исторический тариф комиссий/финансирования или живые исполнения. yfinance — независимый инструмент данных Yahoo с оговорками использования, CCXT работает с биржевыми данными. Проверяйте конкретный набор и сохраните исходник, не ранжируйте надежность по имени библиотеки.
Как заметить неправдоподобный результат?
Проверяйте причинность и учет: доступные тогда записи, сигналы, исполнения, единицы затрат, журнал подбора и заранее отложенные окна. Win rate и profit factor сами не диагностируют ошибку. В условной сотне 75 выигрышей по+0.2 R и 25 потерь по−1 R получается−10 R до расходов при 75% успеха. Необычное значение требует исследования данных и модели, а не автоматического диагноза по порогу.
Источники и пределы применения
- Backtrader: документация
Исходная документация сохранена. Отдельно прочитана стандартная модель Market с Open следующего бара; все режимы и живое исполнение этим не подтверждаются.
- vectorbt: исходная документация использования
Исходная ссылка сохранена. Выбранное описание Portfolio подтверждает состояние денег/активов и разные режимы, не независимость каждого исполнения и не универсальный выигрыш скорости.
- Python for Finance: 2nd Edition, Yves Hilpisch
Проверены только библиографические сведения издателя: второе издание, автор, декабрь 2018. Полное чтение 720 страниц или личная рецензия не заявляются.
- MQL5: интеграция Python
Исходная официальная интеграция сохранена; выбранные поля и UTC сверены по copy_rates_range. Подключение терминала, получение истории или реальные поручения не выполнялись.
- pandas: временные ряды
Исходная ссылка сохранена; дополнительно прочитана документация resample о closed и label. Полное повторное чтение всех временных функций не заявляется.
- MQL5: copy_rates_range
Прочитаны выбранные поля результата, UTC и ограничения истории/настроек. Функция не предоставляет полный исторический тариф комиссии/свопа и не доказывает полноту выгрузки.
- pandas: merge_asof
Прочитаны выбранные сортировка, backward/nearest, tolerance и allow_exact_matches. Документация 3.1.0 отличается от установленной 3.0.5; описанные случаи дополнительно выполнены в реальной установленной среде.
- vectorbt: Portfolio и режимы симуляции
Прочитаны выбранные последовательная обработка, создание/пропуск/отказ поручения и обновление денег/активов. Не все 5125 строк, исполнение библиотеки или тест быстродействия.
- pandas: метки Series
Выбранное определение Series и автоматическое выравнивание по ID. Исходные A/B/C и массивы проверены реальным pandas/NumPy, не полная стратегия.
- pandas: resample
Выбранные closed и label различают состав интервала и отображаемый край. Подпись не доказывает момент доступности агрегата.
- MT5: мультивалютный тестер
Выбранные положения описывают несколько символов и загрузку истории. MT 5 не ограничен одной парой; терминал здесь не тестировался.
- Backtrader: создание и исполнение поручений
Выбранная стандартная модель Market использует Open следующего доступного бара. Не все настройки, серверные условия или живые цены.
- Bailey и соавторы: вероятность переоптимизации
Выбранные аннотация и повторный подбор на одних данных в 34-страничной работе. Нет расчета PBO/реализации CSCV/полного чтенияPDF или изображений.
- yfinance: назначение и ограничения
Прочитаны выбранные независимость от Yahoo, исследовательское назначение и указание проверять права на данные. Не полная юридическая оценка условий Yahoo или выгрузка данных.
- CCXT: официальное назначение
Выбранное описание общегоAPI бирж. Конкретные наборы, полнота минутных данных, все биржи и руководство не проверены.
Учебные синтетические данные и учет, не полная стратегия, инвестиционная рекомендация или действительный торговый результат. Офлайн выполнены указанные pandas/NumPy-случаи, без подключения MT5, учетных данных, исторической выгрузки или живых поручений; Backtrader/vectorbt не запускались как полноценные движки. Цены A/B/C, OHLC 22 баров, времена выпусков и порядковые события вымышлены. Модель одной EUR/USD-сделки задает 10 000 EUR, пипс 0.0001, обе комиссии 1 USD и нулевые финансирование/дополнительное проскальзывание. Серии R имеют постоянный денежный размер и заданные исходы. Совпадение временных меток не устанавливает порядок доступности; исключение точных совпадений не универсальное правило. Нет обещания быстродействия, готовности за 30 строк, диагностики по 75%/PF 3.5 или права использовать любые данные. Выбранные технические источники, не полные библиотеки/книги/сайты/изображения PDF и не экспертная или независимая акцептация.