Полное введение и тест на истории бутылок.

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

Я только что опубликовал новую книгу после успеха New Technical Indicators in Python. Он содержит более полное описание и добавление сложных торговых стратегий со страницей Github, посвященной постоянно обновляемому коду. Если вы считаете, что это вас заинтересует, не стесняйтесь перейти по приведенной ниже ссылке или, если вы предпочитаете купить версию в формате PDF, вы можете связаться со мной в Linkedin.



Свечные графики

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

Данные OHLC - это аббревиатура для цен открытия, максимума, минимума и закрытия. Это четыре основных ингредиента метки времени. Всегда лучше объединить эти четыре ценности вместе, чтобы наш анализ больше отражал реальность. Вот таблица, которая суммирует данные OHLC гипотетической безопасности:

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

Обратите внимание, что вы можете загрузить данные вручную или с помощью Python. Если у вас есть файл Excel, который содержит данные только OHLC, начиная с первой строки и столбца, вы можете импортировать его, используя приведенный ниже фрагмент кода:

import numpy as np
import pandas as pd
# Importing the Data
my_ohlc_data = pd.read_excel('my_ohlc_data.xlsx')
# Converting to Array
my_ohlc_data = np.array(my_ohlc_data)

Построение базовых линейных графиков в Python чрезвычайно просто, и для этого требуется всего одна строка кода. Мы должны убедиться, что импортировали библиотеку под названием matplotlib, а затем мы вызовем функцию, которая строит для нас данные.

# Importing the necessary charting library
import matplotlib.pyplot as plt
# The syntax to plot a line chart
plt.plot(my_ohlc_data, color = 'black', label = 'EURUSD')
# The syntax to add the label created above
plt.legend()
# The syntax to add a grid
plt.grid()

Теперь, когда мы увидели, как создавать нормальные линейные графики, пора перейти на следующий уровень с помощью свечных графиков. Чтобы сделать это без каких-либо сложностей, подумайте о вертикальных линиях. Вот интуиция (с последующим применением функции ниже):

  • Выберите период ретроспективного анализа. Это количество значений, которые вы хотите отобразить на диаграмме.
  • Постройте вертикальные линии для каждой строки, представляющей максимумы и минимумы. Например, для данных OHLC мы будем использовать функцию matplotlib, называемую vlines, которая строит вертикальную линию на диаграмме, используя минимальное (низкое) значение и максимальное (высокое значение).
  • Создайте цветовое условие, которое гласит, что если цена закрытия больше, чем цена открытия, выполнить выбранный блок кода (который, естественно, содержит зеленый цвет). Сделайте это с красным цветом (медвежья свеча) и черным цветом (свеча доджи).
  • Постройте вертикальные линии, используя условия с минимальным и максимальным значениями, представляющими цены закрытия и цены открытия. Убедитесь, что ширина линии слишком велика, чтобы тело свечи выглядело достаточно, чтобы график считался свечным.

def ohlc_plot(Data, window, name):
    
    Chosen = Data[-window:, ]
    
    for i in range(len(Chosen)):
 
      plt.vlines(x = i, ymin = Chosen[i, 2], ymax = Chosen[i, 1], color = 'black', linewidth = 1)
        
      if Chosen[i, 3] > Chosen[i, 0]:
            color_chosen = 'green'
            plt.vlines(x = i, ymin = Chosen[i, 0], ymax = Chosen[i, 3], color = color_chosen, linewidth = 4)              
      if Chosen[i, 3] < Chosen[i, 0]:
            color_chosen = 'red'
            plt.vlines(x = i, ymin = Chosen[i, 3], ymax = Chosen[i, 0], color = color_chosen, linewidth = 4)  
            
      if Chosen[i, 3] == Chosen[i, 0]:
            color_chosen = 'black'
            plt.vlines(x = i, ymin = Chosen[i, 3], ymax = Chosen[i, 0], color = color_chosen, linewidth = 4)  
          
    plt.grid()
    plt.title(name)
# Using the function
ohlc_plot(my_ohlc_data, 50, '')

Паттерн бычьей бутылки

Паттерн «Бычья бутылка» состоит из свечи без фитиля на нижней стороне, но с фитилем на высокой стороне. Цвет первой свечи может быть бычьим или медвежьим.

Бычья бутылка - это модель продолжения движения вверх. Его можно использовать для подтверждения продолжения роста. Психология модели заключается в том, что рынок не смог достичь нового минимума после открытия, что свидетельствует о сильном бычьем давлении.

Паттерн Медвежья бутылка (перевернутая бутылка)

Паттерн «Медвежья бутылка» состоит из свечи без фитиля на высокой стороне, но с фитилем на нижней стороне. Цвет первой свечи может быть бычьим или медвежьим.

«Медвежья бутылка» - это модель продолжения движения вниз. Его можно использовать для подтверждения продолжения движения вниз. Психология модели заключается в том, что рынок не смог достичь нового максимума после открытия, что свидетельствует о сильном медвежьем давлении.

Сходство с другими моделями свечей

Молоток возникает при нисходящем тренде и обычно является сигналом о том, что покупатели берут на себя контроль. Название происходит от того, что он похож на молоток. Перевернутый молот - тоже бычий паттерн, но перевернутый. Это похоже на молот, направленный в землю. Паттерн повешенный выглядит как молот, но является медвежьей свечой и встречается в бычьих тенденциях, он сигнализирует о медвежьем развороте. Наконец, падающую звезду можно рассматривать как перевернутого повешенного человека, а также свечу медвежьего разворота.

Итак, в чем разница между паттерном «Перевёрнутый молоток» и паттерном «Бутылка»? Точно так же, в чем разница между рисунком «Повешенный» и узором «перевернутая бутылка»?

Ну, попросту Бутылка - это продолжение модели, где мы должны ожидать дальнейшего усиления после Бутылки и дальнейшего ослабления после Перевернутой Бутылки. Это может показаться запутанным, но, как мы ранее обсуждали в предыдущих статьях, цель состоит в том, чтобы создать более объективный технический анализ, подкрепленный большей интуицией, исследованиями и результатами. Таким образом, я считаю, что, используя форму управления рисками и надлежащего тестирования на истории, мы можем бросить вызов некоторым классическим шаблонам и проверить нашу собственную интуицию на истории и посмотреть, работают они или нет.

Это ни в коем случае не метод защиты от дурака, а просто попытка сделать это своими руками, которая может дать хорошую или плохую стратегию. Поэтому я настоятельно рекомендую вам поступить так же, и если вы обнаружите другие результаты, мы сможем обсудить их вместе, чтобы поделиться знаниями и улучшить эту очень недооцененную область.

Создание алгоритма сканирования

Наша цель - создать алгоритм, который обнаруживает эту закономерность и размещает теоретические ордера на покупку и продажу, чтобы мы тестировали стратегию на исторических данных и, если возможно, оптимизировали ее. Но сначала нам нужно закодировать интуицию паттернов. Давайте рассмотрим, что нам понадобится для бычьего паттерна бутылки:

  • Цена закрытия должна быть выше цены открытия.
  • Цена открытия должна равняться минимальной цене.

Точно так же для медвежьего паттерна Бутылка (перевернутая бутылка) нам потребуются следующие условия:

  • Цена закрытия должна быть ниже цены открытия.
  • Цена открытия должна равняться максимальной цене.

def signal(Data):
    
    for i in range(len(Data)):        
       
       # Bullish Bottle
       if Data[i, 3] > Data[i, 0] and Data[i, 0] == Data[i, 2]: 
                Data[i, 6] = 1 
           
       # Bearish Bottle
       if Data[i, 3] < Data[i, 0] and Data[i, 0] == Data[i, 1]: 
                Data[i, 7] = -1

Вышеупомянутая функция принимает массив данных OHLC с несколькими пустыми столбцами для резервирования и заполняет столбцы 6 (покупка) и 7 (продажа) условиями, которые мы обсуждали ранее.

Мы хотим ввести 1 в столбец, который мы называем «купить», и -1 в столбец, который мы называем «продать». Позже это позволит вам создать функцию, которая вычисляет прибыль и убыток, обходя эти два столбца и принимая разницу в рыночной цене, чтобы найти прибыль и убыток для стратегии «близко-к-закрытию». Затем вы можете использовать функцию управления рисками, которая использует стопы и ордера на прибыль.

Чтобы добавить несколько столбцов в массив, вы можете использовать следующий код:

def adder(Data, times):
    
    for i in range(1, times + 1):
    
        z = np.zeros((len(Data), 1), dtype = float)
        Data = np.append(Data, z, axis = 1)        
    return Data
# Using the function to add 10 columns
my_data = adder(my_data, 10)

Если вас также интересуют другие технические индикаторы и использование Python для создания стратегий, то мой бестселлер по техническим индикаторам может вас заинтересовать:



Бэк-тестирование бутылочной стратегии

Как и в случае с любым подходящим методом исследования, цель состоит в том, чтобы протестировать индикатор на исторических данных и убедиться, что он стоит в качестве дополнения к уже существующей торговой структуре. Обратите внимание, что ниже проводится бэк-тестирование только одного временного интервала только для 10 валютных пар за последние 10 лет. Возможно, это не оптимальные временные рамки для стратегии, но мы просто пытаемся найти стратегию, подходящую почти для всех.

Условия первой стратегии - это теоретические, которые подразумеваются как техника следования за трендом:

  • Открывайте длинную позицию (Покупайте), когда бычий паттерн подтверждается покупкой на закрытии свечи. Удерживайте эту позицию до получения другого сигнала или до тех пор, пока система управления рисками не остановит вас.
  • Открывайте короткую позицию (продавайте) всякий раз, когда медвежий паттерн подтверждается продажей на закрытии свечи. Удерживайте эту позицию до получения другого сигнала или до тех пор, пока система управления рисками не остановит вас.

Когда мы добавляем соотношение риска и прибыли 1:10, обусловленное индикатором среднего истинного диапазона, мы получаем следующие результаты:

Если вы хотите увидеть больше технических индикаторов и тестов на истории, ознакомьтесь со статьей ниже:



Слово об управлении рисками

В техническом анализе индикатор под названием Средний истинный диапазон -ATR- может использоваться в качестве индикатора исторической волатильности. Хотя он считается запаздывающим индикатором, он дает некоторое представление о том, где сейчас волатильность и где она была в последний период (день, неделя, месяц и т. Д.).

Но сначала мы должны понять, как рассчитывается Истинный диапазон (ATR - это просто среднее значение этого расчета). Рассмотрим данные OHLC, состоящие из своевременно упорядоченных цен открытия, максимума, минимума и закрытия. Для каждого временного периода (бара) истинный диапазон - это просто наибольшая из трех ценовых разниц:

  • Высокая - Низкая
  • Максимум - Предыдущее закрытие
  • Предыдущее закрытие - минимум

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

Когда я говорю, что использую систему управления рисками на основе ATR (средний истинный диапазон), это означает, что алгоритм будет выполнять следующие шаги в отношении занимаемой позиции.

Длинная позиция (покупка):

  • Алгоритм инициирует ордер на покупку после того, как был сгенерирован сигнал по определенной стратегии.
  • Затем алгоритм будет отслеживать тики, и всякий раз, когда максимум равен определенной константе, умноженной на значение ATR во время открытия сделки, инициируется ордер выхода (с прибылью). Одновременно, если виден минимум, равный определенной константе, умноженной на значение ATR на момент открытия сделки, инициируется выход (с убытком). Первым встреченный выход является, естественно, принятым событием.

Короткая (продажа) позиция:

  • Алгоритм инициирует короткий ордер на продажу после того, как был сгенерирован сигнал в соответствии с определенной стратегией.
  • Затем алгоритм будет отслеживать тики, и всякий раз, когда минимум равен определенной константе, умноженной на значение ATR во время открытия сделки, инициируется ордер выхода (с прибылью). Одновременно, если виден максимум, равный определенной константе, умноженной на значение ATR на момент открытия сделки, инициируется выход (с убытком). Первым встреченный выход является, естественно, принятым событием.

График выше показывает средний истинный диапазон. Взгляните на последнее значение ATR. Это около 0,0006 (6 пунктов). Если мы инициируем ордер на покупку, следуя простому соотношению риска и прибыли 2,00 (рискуя половиной того, что мы ожидаем получить), мы можем разместить ордер следующим образом:

  • Купить по текущей рыночной цене.
  • Тейк-профит по текущей рыночной цене + (2 x 6 пунктов).
  • Остановите позицию по текущей рыночной цене - (1 x 6 пунктов).
def ATR(Data, lookback, high, low, close, where):                  
    # From exponential to smoothed moving average   
    lookback = (lookback * 2) - 1                    
    # True Range
    for i in range(len(Data)):
     try:
            
      Data[i, where] = max(Data[i, high] - Data[i, low],
                       abs(Data[i, high] - Data[i - 1, close]),
                       abs(Data[i, low] - Data[i - 1, close]))
            
        except ValueError:
            pass
        
    Data[0, where] = 0    
    Data = ema(Data, 2, lookback, where, where + 1)
    Data = deleter(Data, where, 1)
    Data = jump(Data, lookback)                    
    return Data

Вывод

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

Прежде всего, я постоянно публикую свои торговые журналы в Твиттере до и после запуска, чтобы показать результаты. Это обеспечивает прозрачность. Я также публикую в Твиттере каждые 1–3 месяца. Тем не менее, я никогда не гарантирую ни возврата ни превосходного мастерства. Что касается индикаторов, которые я разрабатываю, я постоянно использую их в своей личной торговле. Следовательно, у меня нет мотива публиковать предвзятые исследования. Моя цель - поделиться тем, что я узнал от онлайн-сообщества.

Не забывайте всегда проводить тесты на исторических данных. Несмотря на то, что я раскрываю функцию индикатора (а не просто хвастаюсь им и говорю, что это Святой Грааль, а его функция - секрет), вы всегда должны верить, что другие люди ошибаются. Мои индикаторы и стиль торговли работают для меня, но, возможно, не для всех. Я полагаюсь на это правило:

Рыночную цену невозможно предсказать или ее очень трудно предсказать более чем в 50% случаев. Но реакцию рынка можно предсказать.

Приведенная выше цитата означает, что мы можем сформировать небольшую зону вокруг области и сказать с некоторой степенью уверенности, что рыночная цена покажет реакцию вокруг этой области. Но мы не можем сказать, что он упадет оттуда на 4%, затем снова протестирует его и пробьет с третьей попытки до 103,85 доллара. Параметр ошибки становится экспоненциально выше, потому что мы делаем прогнозы, а не прогнозы.

Пока мы обсуждаем эту тему, я должен отметить несколько моментов в моих тестах на истории и статьях:

  • Я использую спред, основанный на институциональных котировках небольшой доли пунктов. Как правило, розничным трейдерам предоставляется колоссальный спред в 1-2 пункта за сделку. Это огромно и несправедливо по отношению к ним. Я использую спред 0,2–0,5. Однако большинство стратегий, использующих часовой таймфрейм, по-прежнему работают со спредом в 1 пункт. Для тех, кто использует таймфреймы M15 или M5, они не могут быть прибыльными со спредом в 1 пункт.
  • Я использую расчет периода удержания, близкий к близкому, если нет процесса управления рисками.
  • Хотя я не рекомендую торговать только по одному индикатору, цифры не лгут. Я представляю то, что могло произойти, если принять во внимание низкий спред.
  • Некоторые из представленных мною тестов на истории неудачны, и они публикуются либо для того, чтобы развенчать миф о торговле, либо для того, чтобы представить интересные функции, которые читатели могут запрограммировать.
  • Наконец, я твердо убежден, что нельзя кормить учащихся с ложечки. Я научился на практике, а не копируя. Вы должны понять идею, функцию, интуицию, условия стратегии, а затем разработать (даже лучше) одну из них самостоятельно, чтобы вы протестировали ее на исторических данных и улучшили, прежде чем принять решение о том, чтобы применить ее вживую или отменить.

Подводя итог, можно ли сказать, что стратегии, которые я предлагаю, реалистичны? Да, но только путем оптимизации среды (надежный алгоритм, низкие затраты, честный брокер, надлежащее управление рисками и управление заказами). Предусмотрены ли стратегии исключительно для торговли? Нет, это нужно для стимулирования мозгового штурма и получения новых торговых идей, поскольку мы все устали слышать о перепроданности RSI как о причине для открытия короткой позиции или о преодолении сопротивления как о причине идти долго. Я пытаюсь представить новую область под названием «Объективный технический анализ», в которой мы используем достоверные данные для оценки наших методов, а не полагаемся на устаревшие классические методы.