И всё же, теоретически, Мартингейл «в вакууме» не может проиграть. Исключение лишь при остановке игры в неудачное время. Для доказательства, рассмотрим перспективы игры на минутном таймфрейме за июль 2018 года на паре EUR/USD. Поможет нам в этом простой event-driven бэктестер, написанный в Jupyter на Python 3.6.
Можно ли обыграть казино? Можно. Но на чьей стороне статистика?
Напоминание: Бинарные опционы — это азартная игра. Опасно надеяться на честность брокера и удачу. Возможна манипуляция с потоком истории цен. Поехали!
![eurusd + мартингейл&rsi](https://habrastorage.org/getpro/habr/post_images/20f/6aa/35f/20f6aa35f06754faf339f8dfdc940498.png)
Казино всегда накладывает дополнительные ограничения на игроков. Иногда ограничения связаны с внешними обстоятельствами. Всё это мы будем игнорировать.
Историю цен можно найти в интернете бесплатно. Ниже на графиках минутные свечи за первую неделю и распределение величины свечей для фильтрации дожи.
![бары за неделю и величина свечи](https://habrastorage.org/getpro/habr/post_images/003/d0d/f1c/003d0df1c6160563c3fea9222e00db63.png)
Первые тесты без Мартингейла пропуская дожи показывают стабильное поражение. Слева — баланс, справа — просадка в долях.
![без всего](https://habrastorage.org/getpro/habr/post_images/69b/345/9c0/69b3459c0448b092158cc94f97b6f333.png)
Добавим Мартингейл и видим стабильный рост баланса. Только всё омрачает пикирование в периоды увеличения ставки на проигрышах.
![мартингейл](https://habrastorage.org/getpro/habr/post_images/a71/abe/86b/a71abe86bdaa61ff6df7c2e41f51c3ac.png)
На графиках видно, что падение может достигать 40х кратной просадки. Сказать, что это много, ничего не сказать. Но есть периоды, когда в течение недели баланс сопровождает удача. Кому-то везёт, кому нет.
Теперь к Мартингейлу добавим простые технические индикаторы, показывающие направление тренда. Они запаздывают, но помогают фильтровать неблагоприятные моменты.
Отфильтруем по RSI(10): выше 60 — разрешено ставить на рост, ниже 40 — на падение.
![мартингейл+rsi](https://habrastorage.org/getpro/habr/post_images/4c5/873/4d5/4c58734d5a9c4e8516b6746867ecb905.png)
Как мы видим максимальная просадка незначительно сократилась, а ставки стали безобиднее. Всего лишь миллион.
Последний тест с пересечением средних. Короткая над длинной — рост, наоборот — падение.
![мартингейл+sma](https://habrastorage.org/getpro/habr/post_images/e7f/a1c/e6d/e7fa1ce6d33a8e5693f61ba820957ba1.png)
Всё хорошо, если бы не один раз и на повал.
Таблица с результатами:
![результаты](https://habrastorage.org/getpro/habr/post_images/9f2/d47/db0/9f2d47db029bb34388eaaea21cdb1b3d.png)
Это относительно медленный бэктестер, который позволяет тестировать историю цен исключая заглядывание в будущее. За счёт топорности содействует легкому поиску ошибок. Для его работы нам требуется:
Здесь всё просто. Следим за балансом, принимаем и проверяем ставки.
Эту функцию мы передадим в метод pd.Dataframe().apply(), чтобы через неё прошли все имеющиеся ценовые бары. Дополнительно, сопроводим каждый бар объектом account и полной историей цен. В начале функции добавим фильтр данных по дате текущего бара, чтобы отсечь будущее.
Осталось подготовить данные и запустить.
Мы рассмотрели грааль на основе Мартингейла, при условии бесконечного капитала. В реальности результаты будут чуть хуже. Брокеры, предлагающие подобное развлечение находятся вне регулируемого поля и у них существует множество методов обмана игрока.
Рассмотренный бэктестер можно использовать для тестирования простых стратегий на любых финансовых инструментах. Необходимо лишь доработать метод исполнения и проверки решения.
Можно ли обыграть казино? Можно. Но на чьей стороне статистика?
Напоминание: Бинарные опционы — это азартная игра. Опасно надеяться на честность брокера и удачу. Возможна манипуляция с потоком истории цен. Поехали!
![eurusd + мартингейл&rsi](https://habrastorage.org/getpro/habr/post_images/20f/6aa/35f/20f6aa35f06754faf339f8dfdc940498.png)
Условия «вакуума»
Казино всегда накладывает дополнительные ограничения на игроков. Иногда ограничения связаны с внешними обстоятельствами. Всё это мы будем игнорировать.
- Минимальная ставка 1000 руб.
- Коэффициент прибыли 0.82%.
- Пара EUR/USD.
- Пробуем делать ставку каждую минуту.
- Дожи фильтруем при разнице менее 0,005%.
- Мартингейл должен покрыть убыток и принести прибыль первой ставки.
- Условия принимаются по текущей свече. Если свеча зелёная, делаем ставку на рост, если красная — на падение.
Тесты
Историю цен можно найти в интернете бесплатно. Ниже на графиках минутные свечи за первую неделю и распределение величины свечей для фильтрации дожи.
![бары за неделю и величина свечи](https://habrastorage.org/getpro/habr/post_images/003/d0d/f1c/003d0df1c6160563c3fea9222e00db63.png)
Первые тесты без Мартингейла пропуская дожи показывают стабильное поражение. Слева — баланс, справа — просадка в долях.
![без всего](https://habrastorage.org/getpro/habr/post_images/69b/345/9c0/69b3459c0448b092158cc94f97b6f333.png)
Добавим Мартингейл и видим стабильный рост баланса. Только всё омрачает пикирование в периоды увеличения ставки на проигрышах.
![мартингейл](https://habrastorage.org/getpro/habr/post_images/a71/abe/86b/a71abe86bdaa61ff6df7c2e41f51c3ac.png)
На графиках видно, что падение может достигать 40х кратной просадки. Сказать, что это много, ничего не сказать. Но есть периоды, когда в течение недели баланс сопровождает удача. Кому-то везёт, кому нет.
Теперь к Мартингейлу добавим простые технические индикаторы, показывающие направление тренда. Они запаздывают, но помогают фильтровать неблагоприятные моменты.
Отфильтруем по RSI(10): выше 60 — разрешено ставить на рост, ниже 40 — на падение.
![мартингейл+rsi](https://habrastorage.org/getpro/habr/post_images/4c5/873/4d5/4c58734d5a9c4e8516b6746867ecb905.png)
Как мы видим максимальная просадка незначительно сократилась, а ставки стали безобиднее. Всего лишь миллион.
Последний тест с пересечением средних. Короткая над длинной — рост, наоборот — падение.
![мартингейл+sma](https://habrastorage.org/getpro/habr/post_images/e7f/a1c/e6d/e7fa1ce6d33a8e5693f61ba820957ba1.png)
Всё хорошо, если бы не один раз и на повал.
Таблица с результатами:
![результаты](https://habrastorage.org/getpro/habr/post_images/9f2/d47/db0/9f2d47db029bb34388eaaea21cdb1b3d.png)
- profit/loss — итоговый результат.
- max drawdown, % — максимальная просадка в процентах.
- max win — максимальный выигрыш.
- max loss — максимальный проигрыш.
- bets — количество ставок.
- wins — количество выигрышных ставок.
- loss — количество проигрышных ставок.
- candles — количество баров.
Событийно-ориентированный бэктестер
Это относительно медленный бэктестер, который позволяет тестировать историю цен исключая заглядывание в будущее. За счёт топорности содействует легкому поиску ошибок. Для его работы нам требуется:
- Класс (Account), отвечающий за баланс и обработку ставки.
- Функция (simple), вызываемая на каждой свече, работающая с прошлой историей.
- Pandas датафрейм с OHLC историей цен.
Account
Здесь всё просто. Следим за балансом, принимаем и проверяем ставки.
Код на Python
class Account(object):
def __init__(self, bet_profit=0.82):
self._bet = None
self.equity = []
self.loss = []
self.bet_profit = 0.82
def bet(self, direction=None, amount=None, ts=None):
self._bet = {'direction': direction, 'amount': amount, 'ts': ts}
def tick(self, ticks):
result = 0
if self._bet is not None and self._bet['direction'] is not None:
if self._bet['direction'] > 0 and ticks.close[-1] > ticks.close[-2]:
result = self._bet['amount'] * self.bet_profit
self.equity.append({'ts': ticks.index[-1], 'amount': result})
self.loss = []
elif self._bet['direction'] < 0 and ticks.close[-1] < ticks.close[-2]:
result = self._bet['amount'] * self.bet_profit
self.equity.append({'ts': ticks.index[-1], 'amount': result})
self.loss = []
else:
result = -self._bet['amount']
self.equity.append({'ts': ticks.index[-1], 'amount': result})
self.loss.append(result)
# reset bet
self.bet()
return result, np.sum(self.loss)
Побарный цикл
Эту функцию мы передадим в метод pd.Dataframe().apply(), чтобы через неё прошли все имеющиеся ценовые бары. Дополнительно, сопроводим каждый бар объектом account и полной историей цен. В начале функции добавим фильтр данных по дате текущего бара, чтобы отсечь будущее.
Код на Python
def simple(tick, data=None, account=None, skip_dogi=False, martingale=False):
if account is None:
print('Account is not available')
return 0
fltr = data.index <= tick.ts
# send last ticks to account
result, loss = account.tick(data[fltr][-5:].copy())
amount = 1000
if martingale:
if loss < 0:
amount += abs(loss) / account.bet_profit
if skip_dogi and tick.dogi <= 0.00005:
pass
elif tick.open > tick.close:
# sell on red
account.bet(-1, amount=amount, ts=tick.ts)
elif tick.open < tick.close:
# buy on green
account.bet(1, amount=amount, ts=tick.ts)
return result
Запуск
Осталось подготовить данные и запустить.
Код на Python
df = pd.read_csv('DAT_MT_EURUSD_M1_201807.csv', names=['date', 'time', 'open', 'high', 'low', 'close', 'volume'])
# ...
df = df[['ts', 'open', 'high', 'low', 'close']].set_index('ts', drop=False).sort_index()
df['dogi'] = (df.close / df.open - 1).abs()
account = Account()
results = df.apply(partial(simple, data=df, account=account, skip_dogi=True), raw=False, axis=1)
Заключение
Мы рассмотрели грааль на основе Мартингейла, при условии бесконечного капитала. В реальности результаты будут чуть хуже. Брокеры, предлагающие подобное развлечение находятся вне регулируемого поля и у них существует множество методов обмана игрока.
Рассмотренный бэктестер можно использовать для тестирования простых стратегий на любых финансовых инструментах. Необходимо лишь доработать метод исполнения и проверки решения.