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 VolBar
em (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.