Пълно въведение и обратен тест на моделите на свещници с чук и падаща звезда.

Моделите на свещниците заслужават да бъдат проучени задълбочено и въпреки че стратегия, разчитаща единствено на тях, ще бъде нестабилна и нерентабилна, те могат да бъдат ценно допълнение към пълна система за търговия, която използва други техники. В тази статия ще видим пълно представяне и код на модел с една свещ. След това ще го тестваме обратно със и без управление на риска, преди да преценим неговата доходност и как трябва да я тълкуваме.

Току-що публикувах нова книга след успеха на Нови технически индикатори в Python. Той включва по-пълно описание и добавяне на сложни стратегии за търговия със страница в Github, посветена на непрекъснато актуализирания код. Ако смятате, че това ви интересува, не се колебайте да посетите връзката по-долу или ако предпочитате да закупите PDF версията, можете да се свържете с мен в Linkedin.



Графики на свещници

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

Данните на OHLC са съкращение за Open, High, Low и Close price. Те са четирите основни съставки за клеймо за време. Винаги е по-добре тези четири стойности да са заедно, така че нашият анализ да отразява повече реалността. Ето таблица, която обобщава данните от 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, '')

Моделът на чук

Моделът Hammer е конфигурация на бичи свещник, която наподобява буквата T. Основната интуиция е, че мечият натиск е направил ново дъно, но в края не е успял да го задържи, тъй като пазарът е затворил по-близо до върха на деня.

Специфичното за модела Hammer е дълъг нисък фитил и висок, който е равен или на отворения, или на високия. Следователно, в това проучване, Чукът може да бъде възходяща или меча свещ, но прогнозата за ценовото действие след него е възходяща.

Моделът на падащата звезда

Моделът Shooting Star е конфигурация на мечи свещник, която прилича на обърната буква T. Основната интуиция е, че бичият натиск е направил нов връх, но в края не е могъл да го задържи, тъй като пазарът е затворил по-близо до дъното за деня.

Специфичното за модела Shooting Star е дълъг висок фитил и нисък, който е равен или на отворения, или на високия. Следователно, в това проучване, Shooting Star може да бъде възходяща или меча свещ, но прогнозата за ценовото действие след нея е мечи.

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

Нашата цел е да създадем алгоритъм, който открива този модел и поставя теоретични поръчки за покупка и продажба, така че да тестваме стратегията и да я оптимизираме, ако е възможно. Но първо трябва да кодираме интуицията на моделите. Нека прегледаме какво ще ни трябва за Hammer:

  • Дължината трябва да е поне два пъти по-голяма от дължината на тялото.
  • Върхът трябва да е равен на цената на затваряне или цената на отваряне.

По същия начин за падащата звезда се нуждаем от следните условия:

  • Височината трябва да е поне два пъти по-голяма от дължината на тялото.
  • Най-ниската цена трябва да е равна на цената на затваряне или цената на отваряне.

# Defining the minimum width of the candle
body = 0.0004
wick = body * 2
def signal(Data):
    
    for i in range(len(Data)):        
       
       # Hammer
       if abs(Data[i, 3] - Data[i, 0]) < body and abs(Data[i, 2] - Data[i, 0]) > wick and Data[i, 1] == Data[i, 0]:
            
                Data[i, 6] = 1 
           
       # Hammer
       if abs(Data[i, 3] - Data[i, 0]) < body and abs(Data[i, 2] - Data[i, 0]) > wick and Data[i, 1] == Data[i, 3]:
            
                Data[i, 6] = 1 
                
       # Shooting Star
       if abs(Data[i, 3] - Data[i, 0]) < body and abs(Data[i, 1] - Data[i, 0]) > wick and Data[i, 2] == Data[i, 0]:
   
               Data[i, 7] = -1
       # Shooting Star
       if abs(Data[i, 3] - Data[i, 0]) < body and abs(Data[i, 1] - Data[i, 0]) > wick and Data[i, 2] == Data[i, 3]:
   
               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:5, наложено от индикатора за среден истински обхват, откриваме следните резултати, които не променят много интерпретацията:

Както се очакваше, използването на стратегията сама по себе си не носи никаква стойност дори с превъзходни коефициенти на попадение, доказани от горните криви на капитала. Ако се интересувате да видите повече технически индикатори и бек-тестове, не се колебайте да разгледате статията по-долу:



Дума за управление на риска

Когато казвам, че използвам базирана на ATR система за управление на риска (Average True Range), това означава, че алгоритъмът ще направи следните стъпки по отношение на позицията, която заема.

Дълга (купува) позиция:

  • Алгоритъмът инициира поръчка за покупка след генериране на сигнал след определена стратегия.
  • След това алгоритъмът ще следи тиковете и когато най-високата стойност се равнява на определена константа, умножена по стойността на ATR в момента на започване на сделката, се инициира поръчка за изход (на печалба). Едновременно с това, ако се види ниско ниво, равно на определена константа, умножена по стойността на ATR в момента на започване на сделката, се инициира изход (на загуба). Изходът, който се среща първи, естествено е взетото събитие.

Къса (продажба) позиция:

  • Алгоритъмът инициира къса поръчка за продажба след генериране на сигнал след определена стратегия.
  • След това алгоритъмът ще следи тиковете и всеки път, когато най-ниската е равна на определена константа, умножена по стойността на ATR в момента на започване на сделката, се инициира поръчка за изход (на печалба). Едновременно с това, ако се види най-високата стойност, равна на определена константа, умножена по стойността на ATR в момента на започване на търговията, се инициира изход (на загуба). Изходът, който се среща първи, естествено е взетото събитие.

Графиката по-горе показва средния истински диапазон, който обикновено използвам. Базира се на експоненциална пълзяща средна за разлика от оригиналната изгладена пълзяща средна.

Разгледайте най-новата стойност на ATR. Тя е около 0,0014 (14 пипса). Ако инициираме поръчка за покупка, следвайки просто съотношение риск-възнаграждение 2,00 (рискувайки половината от това, което очакваме да спечелим), можем да направим поръчка по следния начин:

  • Купете на текущата пазарна цена.
  • Вземете печалба при текуща пазарна цена + (2 x 14 пипса).
  • Спрете позицията на текущата пазарна цена — (1 x 14 пипса).

Кодът, който използвам за индикатора Average True Range, е както следва:

def ema(Data, alpha, lookback, what, where):
    
    # alpha is the smoothing factor
    # window is the lookback period
    # what is the column that needs to have its average calculated
    # where is where to put the exponential moving average
    
    alpha = alpha / (lookback + 1.0)
    beta  = 1 - alpha
    
    # First value is a simple SMA
    Data = ma(Data, lookback, what, where)
    
    # Calculating first EMA
    Data[lookback + 1, where] = (Data[lookback + 1, what] * alpha) + (Data[lookback, where] * beta)
# Calculating the rest of EMA
    for i in range(lookback + 2, len(Data)):
            try:
                Data[i, where] = (Data[i, what] * alpha) + (Data[i - 1, where] * beta)
        
            except IndexError:
                pass
    return Datadef eATR(Data, lookback, high, low, close, where):
    
    # TR
    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)
return Data

Заключение

Ако следите редовно моите статии, ще откриете, че много от индикаторите, които разработвам или оптимизирам, имат висок коефициент на попадение и средно са печеливши. Това се дължи най-вече наметода за управление на риска, който използвам. Но какво да кажем за пазарната случайност и факта, че много по-слабо представящи се обвиняват техническия анализ за своя провал?

На първо място, постоянно публикувам своите търговски дневници в Twitter преди започване и след започване, за да покажа резултатите. Това гарантира прозрачност. Публикувам също постижения в Twitter на всеки 1–3 месеца. Въпреки това азникога негарантирам възвръщаемостнито превъзходни умения. Що се отнася до индикаторите, които разработвам, постоянно ги използвам в личната си търговия. Следователно нямам мотив да публикувам тенденциозни изследвания. Моята цел е да споделя това, което съм научил от онлайн общността.

Не забравяйте винаги да правите вашите бек-тестове. Въпреки че предоставям функцията на индикатора (вместо просто да се хваля с него и да казвам, че е светият граал и функцията му е тайна), винаги трябва да вярвате, че другите хора грешат. Моите индикатори и стил на търговия работят за мен, но може би не за всеки. Разчитам на това правило:

Пазарната цена не може да бъде предвидена или е много трудно да бъде предвидена в повече от 50% от времето. Но реакциите на пазара могат да бъдат предвидени.

Горният цитат означава, че можем да формираме малка зона около дадена област и да кажем с известна степен на увереност, че пазарната цена ще покаже реакция около тази област. Но не можем да кажем, че ще падне с 4% оттук нататък, след което ще го тестваме отново и ще пробием при третия опит, за да стигнем до $103,85. Членът на грешката става експоненциално по-висок, защото предвиждаме повече от прогнозите.

Докато обсъждаме тази тема, трябва да отбележа няколко неща относно моите бек-тестове и статии:

  • Спредът, който използвам, се основава на институционални котировки от малка част от пипса. Като цяло търговците на дребно получават огромен спред от 1-2 пипса на сделка. Това е огромно и несправедливо спрямо тях. Използвам 0,2–0,5 спрей. Въпреки това, повечето от стратегиите, които използват почасовата времева рамка, все още работят с 1 пипс спред. За тези, които използват времеви рамки M15 или M5, те не могат да бъдат печеливши със спред от 1 пипс.
  • Изчисляването на периода на задържане, което използвам, е близко до близко, в случай че няма процес за управление на риска.
  • Въпреки че не препоръчвам да търгувате въз основа само на един индикатор, числата не лъжат. Това, което представям, е какво можеше да се случи, като се вземе предвид нисък спред.
  • Някои от бек-тестовете, които предоставям, са губещи и се публикуват или за да демистифицират мит за търговия, или за да представят интересни функции, които да бъдат кодирани от читателите.
  • Накрая, аз съм твърдо привърженик на това да не храня обучаемите с лъжичка. Научих се чрез правене, а не чрез копиране. Трябва да получите идеята, функцията, интуицията, условията на стратегията и след това сами да разработите (още по-добра) такава, така че да я тествате обратно и да я подобрите, преди да решите да я приложите на живо или да я премахнете.

За да обобщим, реалистични ли са стратегиите, които предоставям? Да, но само чрез оптимизиране на средата (стабилен алгоритъм, ниски разходи, честен брокер, правилно управление на риска и управление на поръчките). Стратегиите предоставени ли са единствено за търгуване? Не, това е за стимулиране на мозъчна атака и получаване на повече идеи за търговия, тъй като на всички ни е писнало да слушаме за свръхпродаден RSI като причина за късо или надминаване на съпротива като причина да отида дълго. Опитвам се да въведа нова област, наречена Обективен технически анализ, където използваме твърди данни, за да преценим нашите техники, вместо да разчитаме на остарели класически методи.