Създаване и обратно тестване на индикатора за двойна разлика.

Когато извършваме статистически анализ, през повечето време сме принудени да разграничаваме данните от времевите редове, за да ги направим по-стационарни. Разликата е актът на изчисляване на разликата между текущата цена на затваряне и предишната цена на затваряне. Като оставим настрана статистиката, може ли това да ни даде по-развита идея за индикатор? Ами ако направим разлика между вече различаващите се данни? И какво, ако използваме забавяне, различно от само 1 (предишен период). В тази статия ще създадем индикатора за двойна разлика, който се занимава с двата въпроса по-горе.

Ако също се интересувате от повече технически индикатори и използването на Python за създаване на стратегии, тогава последната ми книга може да ви заинтересува:



Създаване на индикатор за двойна разлика

Цените на акциите и валутните котировки са нестационарни, докато тяхната възвръщаемост (или разлики) са предимно стационарни. Данните от времевия ред са стационарни, ако имат постоянна средна стойност и дисперсия, т.е. средната им стойност не се променя много с времето. Същото важи и за неговата дисперсия (волатилност).

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

За да симулирате шум, който се върти около нула (като по този начин го прави неподвижен), можете да използвате кодовия фрагмент по-долу:

import numpy as np
import matplotlib.pyplot as plt
noise = np.random.normal(0, 1, 200)
plt.plot(noise, color = 'red', linewidth = 1, label = 'Noise')
plt.axhline(y = 0, color = 'black', linewidth = 1)
plt.grid()
plt.legend()

Сега идеята за индикатора за двойна разлика е изключително проста:

  • Ние ще вземем разликите в пазарната цена. Това означава, че ще изчислим разликите между цените и предишните им стойности
  • След това ще изчислим разликите на разликите, открити в горната стъпка. В момента ще вземем разликите от предишния период, но по-късно ще се опитаме да оптимизираме стратегията, като вземем разликите на периодите по-далеч в миналото.

За да кодираме индикатора, трябва да имаме OHLC масив (не рамка от данни) и да дефинираме следните три малки манипулационни функции:

# The function to add a certain number of columns
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
# The function to deleter a certain number of columns
def deleter(Data, index, times):
    
    for i in range(1, times + 1):
    
        Data = np.delete(Data, index, axis = 1)        
    return Data
# The function to delete a certain number of rows from the beginning
def jump(Data, jump):
    
    Data = Data[jump:, ]
    
    return Data

И тогава можем да напишем неговата функция и да я използваме:

def double_differencing_indicator(Data, lag, what, where):
# Adding columns
    Data = adder(Data, 2)
    
    for i in range(len(Data)):
        Data[i, where] = (Data[i, what] - Data[i - lag, what])
for i in range(len(Data)):
        Data[i, where + 1] = (Data[i, where] - Data[i - lag, where])
        
    Data = deleter(Data, where, 1)
    Data = jump(Data, lag * 2)
return Data
# Using the function with a lag of 1 (default)
my_data = double_differencing_indicator(my_data, 1, 3, 4)

Какво ще стане, ако видим как изглежда, когато удвоим разликата, използвайки забавяне от 2? Това означава, че ще изчислим разликите между цените и цените отпреди 2 периода и след това ще направим същото с разликите.

# Using the function with a lag of 2
my_data = double_differencing_indicator(my_data, 2, 3, 4)

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



Обратно тестване на индикатора за двойна разлика

Процесът на обратно тестване е доста прост, тъй като ще приемем, че има субективни бариери около -0,002 и 0,002, откъдето ще инициираме противоположни сделки въз основа на следните условия:

  • Отидете на дълга позиция (Купете), когато индикаторът за двойна разлика за 1 период достигне -0,002 с предишните две показания над -0,002. Задръжте тази позиция, докато получите нов сигнал или бъдете спрян от системата за управление на риска за средния истински диапазон.
  • Отидете на късо (продавате), когато индикаторът за двойна разлика за 1 период достигне 0,002 с предишните две показания над 0,002. Задръжте тази позиция, докато получите нов сигнал или бъдете спрян от системата за управление на риска за средния истински диапазон.
  • Цената на сделка е 0,5 пипса на кръгла сделка на почасови стойности от 2010 г. насам.
  • Индикацията за среден истински диапазон налага спиране при 5x ATR и печалба при 1x ATR.
def signal(Data, what, buy, sell):
    
    for i in range(len(Data)):
            
        if Data[i, what] < lower_barrier and Data[i - 1, what] > lower_barrier and Data[i - 2, what] > lower_barrier :
            Data[i, buy] = 1
            
        if Data[i, what] > upper_barrier and Data[i - 1, what] < upper_barrier and Data[i - 2, what] < upper_barrier :
            Data[i, sell] = -1

Горните условия дадоха долните криви на капитала, които изглежда добавят известна стойност. Казвам „изглежда добавям“, защото използваната от нас структура на разходите е много ниска предвид търговията на дребно, поради което точните резултати по-долу не са лесни за получаване, освен ако нямате лична връзка с брокера.

Опит за оптимизация

Ами ако използваме забавяне, различно от 1? Като променим променливата на 2, изглежда получаваме по-добри резултати. Имайте предвид, че резултатите по-долу са получени при абсолютно същите условия по-горе, с изключение на забавянето.

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

  • Различните валутни пресичания, тъй като различните статистически свойства водят до различни резултати. Ключът е да намерите най-много двойки за реверсия на средна стойност.
  • Бариерите. Кой казва, че трябва да се придържаме към -0,002 и 0,002? Винаги можем да се стремим да ги оптимизираме.
  • Системата за управление на риска може да бъде подобрена, за да отчете по-малък риск чрез увеличаване на теоретичното възнаграждение за риск или да отчете по-голяма доходност чрез намаляването му.

Ако се интересувате да видите повече технически индикатори и бек-тестове, не се колебайте да разгледате статията по-долу:



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

Когато казвам, че използвам базирана на 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 Data
def 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 като причина да отидем на къси позиции или надминато съпротивление като причина да отидем дълго. Опитвам се да въведа нова област, наречена Обективен технически анализ, където използваме твърди данни, за да преценим нашите техники, вместо да разчитаме на остарели класически методи.