Jde o příklad, jak hledat vztah konkrétní podmínky na výsledek. V následujícím článku popisuji, jaký má vliv volatilní úsečka, popsaná v předchozím článku, na následující cenovou úsečku. Zároveň se budu snažit odpovědět na následující otázky:
Pro analýzu jsem použil následující moduly:
In [1]:
import sys
import pandas as pd
import pandas_datareader as pdr
import pandas_datareader.data as web
import matplotlib
import seaborn as sns
import datetime
print('Python', sys.version)
print('Pandas', pd.__version__)
print('Pandas-datareader', pdr.__version__)
print('Matplotlib', matplotlib.__version__)
print('Seaborn', sns.__version__)
In [2]:
start = datetime.datetime(2005, 1, 1)
end = datetime.datetime(2018, 12, 31)
spy_data = web.DataReader('SPY', 'yahoo', start, end)
spy_data = spy_data.drop(['Volume', 'Adj Close'], axis=1) # sloupce 'Volume' a 'Adj Close' nebudu potřebovat
spy_data.tail()
Out[2]:
V předchozím článku jsem definoval, jak najdu volatilní svíčku. Připomínám, že se jedná o svíčku, která je větší než 4 předchozí svíčky.
Abych tento kód nemusel psát pořád dokola, vytvořil jsem si osobní balíček, obsahující mé používané analýzy. Zde je jednoznačná výhoda pythonu a jiných programovacích jazyků. Funkce volatile_bars přebírá jako první parametr tabulku dat typu pandas.DataFrame, která musí obsahovat sloupečky Open, High, Low, Close. Jako jednotlivé řádky bere data svíček trhů, takže tam klidně můžu mít data jiného timeframe.
Funkce volatile_bars vytvoří nový sloupeček s názvem VolBar, ve kterém označí volatilní svíčky hodnotou True a všechny ostatní svíčky hodnotou False.
In [3]:
# vhat je můj osobní balíček analytických funkcí, které nechci psát pokaždé znovu a znovu
from vhat.analyse.volbars import volatile_bars
volatile_bars(spy_data, N=4, drop_calculations=False)
spy_data.tail()
Out[3]:
Pandas.DataFrame má jednoduchou funkci, která se nazývá pct_change. Ta mi zjistí procentuální změnu hodnoty aktuálního řádku od přechozího. V mém případě to v jednoduchosti znamená, že zjistím, jak se dnešní Close procentuálně změnilo od včerejška. Výsledek vložím do nového sloupečku s názvem pct_change.
Pozn.: Uvažuji obchodování na Close cenách jednotlivých svíček.
In [4]:
spy_data['pct_change'] = spy_data.Close.pct_change()
spy_data.head()
Out[4]:
Nyní přichází na řadu princip analýzy, na který chci tímhle článkem upozornit.
Jako podmínku beru volatilní úsečku, tu mám označenou ve sloupci VolBar a změnu ceny v procentech mám ve sloupečku pct_change. Nyní můžu posunout data ve sloupečku pct_change o jeden řádek výše a získám tak procentuální změnu Close ceny (výsledek) v následující svíčce v řádku s označeným VolBarem (podmínka).
In [5]:
spy_data['pct_change-1'] = spy_data['pct_change'].shift(-1)
spy_data[spy_data['VolBar']].head()
Out[5]:
Ještě pomocí filtru rozdělím na stoupající volatilní úsečku a klesající volatilní úsečku.
In [6]:
upcandle_filter = spy_data['C-O'] >= 0 # long
up_volbars = spy_data[spy_data['VolBar'] & upcandle_filter]
down_volbars = spy_data[spy_data['VolBar'] & ~upcandle_filter]
down_volbars.head()
Out[6]:
Proměnná up_volbars nyní obsahuje pouze řádky stoupajících volatilních úseček => jejich uzavírací cena Close je výšší než otevírací cena Open. Pro klesající volatilní úsečky v proměnné down_volbars platí opačná podmínka.
Příprava filtrů definujících reverzní pohyb po volatilní úsečce. Kladný pct_change-1 znamená, že je následující svíčka stoupající a záporný klesající.
In [7]:
down_revers_filter = up_volbars['pct_change-1']<0
up_revers_filter = down_volbars['pct_change-1']>0
In [8]:
perc = up_volbars[down_revers_filter].shape[0] / up_volbars.shape[0]
print('Probability of the following short bar after the volatile up bar:', f'{perc*100:.2f}%')
In [9]:
perc = down_volbars[up_revers_filter].shape[0] / down_volbars.shape[0]
print('Probability of the following up bar after the volatile short bar:', f'{perc*100:.2f}%')
In [10]:
BINS = 50 # pouze pomocná proměnná, která určuje, kolik maximálně má být zobrazeno sloupečků v histogramu
Velikosti výnosů (procentuální změny close) pro reverz po volatilní stoupající úsečce si můžu zobrazit pomocí histogramu. Pandas.DataFrame.hist() je funkce, která využívá knihovnu matplotlib pro zobrazení dat.
In [11]:
up_volbars.loc[down_revers_filter,'pct_change-1'].hist(bins=BINS);
Více se mi ale líbí možnosti knihovny seaborn, která využívá pandas.DataFrame a pandas.Series jako vstupní data a pro statistické účely je dokáže pěkně zobrazit.
Funkce Pandas.DataFrame.describe() vypočítá pro dané data základní statistické údaje jako jsou průměr, směrodatná odchylka, atd.
In [13]:
import seaborn as sns
sns.distplot(up_volbars.loc[down_revers_filter,'pct_change-1'], bins=BINS)
up_volbars.loc[down_revers_filter,'pct_change-1'].describe()
Out[13]:
Podobný rozbor pro reverzní pohyb po volatilní klesající úsečce:
In [14]:
down_volbars.loc[up_revers_filter,'pct_change-1'].hist(bins=BINS);
In [15]:
sns.distplot(down_volbars.loc[up_revers_filter,'pct_change-1'], bins=BINS)
down_volbars.loc[up_revers_filter,'pct_change-1'].describe()
Out[15]:
Z výše popsané analýzy jsem zjistil následující charakteristiku pro volatilní svíčky v trhu SPY v časovém období od 1.1.2005 do 31.12.2018:
Už tenhle první výsledek nám ukazuje, že:
Má větší smysl hledat v trhu SPY reverz po klesající volatilní úsečce směrem nahoru.
Samozřejmě je to dáno charakterem trhu SPY. Na grafu SPY je možné vidět na první pohled, že má spíše tendenci stoupat:
In [16]:
spy_data.Close.plot();
V případě, že se na základě výsledků předchozí analýzy rozhodnu obchodovat nákupem na Close klesající volatilní úsečky, můžu pomocí analýzy výnosů zjistit, kam až se v následujícím dnu může trh dostat a mířit tam profit target.
Uzavírací cena po klesající volatilní úsečce se v 57,89% případů dosáhne zhodnocení průměrně k 1.21% (mean=0.012079), směrodatná odchylka je 1,22%.
Pokud chci uzavřít obchod hned druhý den, nemá smysl mířit s profit targetem dál než ke zhodnocení 2.43% (průměr + směrodatná odchylka).
V obchodování není třeba obrovské výhody, i nepatrná výhoda může mít vliv na úplně odlišný výsledek z dlouhodobého pohledu.
Tento článek slouží jako inspirace jak analyzovat vliv jedné podmínky na budoucí výsledek. Základ je mít jak data při vstupu, tak při výstupu, v tabulce na jednom řádku a pak zkoumat vliv vstupní a výstupní podmínky.
Pro příklad jsem analyzoval vliv volatilních svíček na budoucí vývoj ceny v další cenové úsečce. Napadají mě hned další možnosti, jak tuhle analýzu upravit pro reálnější použití:
Pozn.: Pro jednoduchost a vysvětlení základního principu zde neuvádím žádné ověření kvality dat, žádné ověření kvality výsledků a další důležité aspekty, k celkovému obchodnímu systému. Jde pouze o inspiraci a v žádném případě nenesu odpovědnost za nesprávně interpretované a použité zde obsažené informace.