Анализ бинарных опционов, мартингейл и карманный event-driven бэктестер

И всё же, теоретически, Мартингейл «в вакууме» не может проиграть. Исключение лишь при остановке игры в неудачное время. Для доказательства, рассмотрим перспективы игры на минутном таймфрейме за июль 2018 года на паре EUR/USD. Поможет нам в этом простой event-driven бэктестер, написанный в Jupyter на Python 3.6.

Можно ли обыграть казино? Можно. Но на чьей стороне статистика?

Напоминание: Бинарные опционы — это азартная игра. Опасно надеяться на честность брокера и удачу. Возможна манипуляция с потоком истории цен. Поехали!

Анализ бинарных опционов, мартингейл и карманный event-driven бэктестер

Условия «вакуума»

Казино всегда накладывает дополнительные ограничения на игроков. Иногда ограничения связаны с внешними обстоятельствами. Всё это мы будем игнорировать.

  • Минимальная ставка 1000 руб.
  • Коэффициент прибыли 0.82%.
  • Пара EUR/USD.
  • Пробуем делать ставку каждую минуту.
  • Дожи фильтруем при разнице менее 0,005%.
  • Мартингейл должен покрыть убыток и принести прибыль первой ставки.
  • Условия принимаются по текущей свече. Если свеча зелёная, делаем ставку на рост, если красная — на падение.

Тесты

Историю цен можно найти в интернете бесплатно. Ниже на графиках минутные свечи за первую неделю и распределение величины свечей для фильтрации дожи.

бары за неделю и величина свечи

Первые тесты без Мартингейла пропуская дожи показывают стабильное поражение. Слева — баланс, справа — просадка в долях.

без всего

Добавим Мартингейл и видим стабильный рост баланса. Только всё омрачает пикирование в периоды увеличения ставки на проигрышах.
мартингейл

На графиках видно, что падение может достигать 40х кратной просадки. Сказать, что это много, ничего не сказать. Но есть периоды, когда в течение недели баланс сопровождает удача. Кому-то везёт, кому нет.

Теперь к Мартингейлу добавим простые технические индикаторы, показывающие направление тренда. Они запаздывают, но помогают фильтровать неблагоприятные моменты.

Отфильтруем по RSI(10): выше 60 — разрешено ставить на рост, ниже 40 — на падение.

мартингейл+rsi

Как мы видим максимальная просадка незначительно сократилась, а ставки стали безобиднее. Всего лишь миллион.

Последний тест с пересечением средних. Короткая над длинной — рост, наоборот — падение.

мартингейл+sma

Всё хорошо, если бы не один раз и на повал.

Таблица с результатами:

результаты

  • 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)

Заключение

Мы рассмотрели грааль на основе Мартингейла, при условии бесконечного капитала. В реальности результаты будут чуть хуже. Брокеры, предлагающие подобное развлечение находятся вне регулируемого поля и у них существует множество методов обмана игрока.

Рассмотренный бэктестер можно использовать для тестирования простых стратегий на любых финансовых инструментах. Необходимо лишь доработать метод исполнения и проверки решения.

 
Источник

python

Читайте также