Algoritmické obchodování na burze – Chyby a problémy

iconS železnou nepravidelností se dostáváme k dalšímu článku o algoritmickém obchodování. Původně jsem chtěl sepsat malý update ke konci září, který by shrnoval, jak se dařilo obchodování tento měsíc. Od posledního příspěvku však došlo k několika chybám, které si zaslouží trochu pozornosti.

Od posledního článku uteklo jen pár dní, ale přesto se již vynořilo několik problémů, z nichž všechny souvisí s načítáním dat. Jen pro info, systém funguje tak, že si každý den u předem vybraných akcií v daný čas načte historická data (denní uzavírací ceny) pro více jak 200 obchodních dní nazpět. K tomuto účelu se využívá služba Yahoo Finance, která je poskytována zdarma. Poté se dotáhnou aktuální ceny pro konkrétní den, ty se načítají z placené brány poskytované společností Interactive Brokers, kde mám přihlášená data z balíku „US Value Bundle“. Toliko teorie a teď už k chybám.

Chybná data pro akcii NEE
Jedna z méně závažných chyb se vyskytla u akcie NEE po jejím přidání do seznamu obchodovaných akcií. Jak již bylo řečeno, na začátku obchodování se pro každou akcii načte historie denních uzavíracích cen za více jak 200 posledních obchodních dní. Podle Yahoo Finance má tato firma na burze již dlouholetou historii.
NEE - Yahoo Finance

Při načítání z YahooAPI se ale načtou data jen od 9.6.2016 což znamená pouhých 75+/- obchodních dní nazpět.

Loading NEE history from 2000-01-01 to 2016-09-25
Days loaded: 75
First date: Thu Jun 09 2016 00:00:00 GMT+0200 (CEST), Last date: Fri Sep 23 2016 00:00:00 GMT+0200 (CEST)

To nestačí pro výpočet používaných indikátorů a tak je tato akcie automaticky vyřazena z obchodování. Stejný problém je pak na webu Yahoo zde. Zvláštní je, že na nové verzi webu Yahoo Finance tento problém není, po kliknutí na „Download data“ se ale opět stáhnou jen osekaná data. Na Google Finance zde je dostupná kompletní historie, takže řešením by bylo stahovat data z více zdrojů a poté vzít ty kvalitnější (plus nějak si pořešit adjustaci dat?). Prozatím jsem firmu NEE vyřadil z obchodování.

Nedokončená Yahoo data
Mnohem závažnější chyba se objevila na testovací verzi, která (stejně jako produkce) načítá historická data z YahooApi. Strategie držela 14.9.2016 celkem 90 kusů akcie HON, která se podle pravidel měla ten den prodat viz modrá čára (aktuální cena) překračující červenou (SMA5) v následujícím grafu:Prodej HON 14.9.2016

Ale neprodala. Podle logu se nesplnila podmínka pro výstup, neboli že aktuální cena nebyla vyšší jak SMA5 (pětidenní klouzavý průměr). To ale podle YahooFinance splněno bylo. Po hlubším zkoumání jsem zjistil, že se špatně načetla historická data. Nedotáhly se totiž některé z posledních dní (historická data končila 1.9.2016) a tím se špatně spočítalo SMA5. Přitom na produkčním prostředí se data načetla všechna – viz poslední záznam historických dat načtený dne 14.9.2016 na devu vs produkci:

== DEV ==
dev

== PRODUKCE ==
produkce

Tohle by mě nenapadlo, že se vůbec může stát, každopádně jak již bylo řečeno výše, při používání bezplatných poskytovatelů je potřeba hlídat si kvalitu dat – v tomto případě si projít načtená data a případně je stáhnout znovu.

Ceny LAST vs CLOSE a špatně nakoupené CSCO
Dne 12.9.2016 došlo na produkci k chybnému nákupu akcie CSCO a to i přesto, že podle YahooFinance nebyla splněna nákupní podmínka. Systém načetl tato data:

[2016-09-12 15:56:30.395] [DEBUG] IB-API - Start watching CSCO with ID 3001
[2016-09-12 15:56:31.610] [DEBUG] IB-API - IB API STREAMING: [LAST] CSCO(stock) price=31.42 canAutoExecute=false
[2016-09-12 15:56:31.610] [DEBUG] IB-API - IB API STREAMING: [HIGH] CSCO(stock) price=31.5 canAutoExecute=false
[2016-09-12 15:56:31.610] [DEBUG] IB-API - IB API STREAMING: [LOW] CSCO(stock) price=30.6 canAutoExecute=false
[2016-09-12 15:56:31.611] [DEBUG] IB-API - IB API STREAMING: [CLOSE] CSCO(stock) price=30.85 canAutoExecute=false
[2016-09-12 15:56:31.623] [DEBUG] IB-API - IB API STREAMING: [OPEN] CSCO(stock) price=30.6 canAutoExecute=false
[2016-09-12 15:56:31.847] [ERROR] IB-API - An error for ticker: CSCO Error: Part of requested market data is not subscribed. Subscription-independent ticks are still active.CSCO NASDAQ.NMS/TOP/BID_ASK
[2016-09-12 15:56:31.848] [ERROR] IB-API - An error for ticker: CSCO Error: Requested market data is not subscribed.Error&ISLAND/STK/Top

Z nich poté vzal poslední LAST nebo CLOSE cenu – v tomto případě CLOSE 30.85, což je veliký pokles oproti předchozím cenám, čímž se splnila podmínka pro nákup. Akcie byla prodána o 3 dny později se smutnou ztrátou něco pod 7USD.

screen-shot-2016-09-25-at-17-09-25Načítání realtime dat jsem proto upravil tak, aby bralo pouze LAST ceny. Zároveň chyba „Requested market data is not subscribed“ se objevuje pro akcie CSCO, MSFT a INTC a podle této diskuze, souvisí s tím, že jsou akcie obchodovány na více burzách. Jako řešení se navrhuje přidat primární burzu před jméno akcie (takže něco jako ISLAND:CSCO?), což zatím ale nemám vyzkoušené.

Neotevřené pozice – pokračování
Toto je už sice starší chyba zméněná také v předchozím článku, ale pro umocnění následující myšlenky ještě jednou zopakuji. Dne 1.9.2016 se chybně nenakoupilo hned několik akcií kvůli chybě „Duplicate order ID“. Tyto akcie by se o pár dní později prodaly za cca 100USD. To je hned polovina předpokládaných 2%, které tato strategie má měsíčně generovat! Strategii se tento měsíc zatím daří dobře, ale i tak to zabolelo.

Moudro na závěr
Závěrem proto chci říci, že některé problémy jsem vůbec nepředvídal. Zároveň věřím, že jich ještě pár přijde a jako u každého softu chvíli potrvá, než se to celé vyladí. Je však třeba zmínit, že hodně z těchto chyb způsobí nějakou formu ztráty (ne nutně celého kapitálu) nebo ušlého zisku (což je ve výsledku ale také ztráta). Je proto důležité, naplánovat si provoz systému tak, aby výnosy (alespoň ty předpokládané) vytvořily nějaký ten budget na pokrytí těchto ztrát.

Dodatek 11.10.
Chyba s hláškou „Requested market data is not subscribed“ byla vyřešena nastavením exchange pro trojici tickerů na BATS.

21 comments

  1. Jen myšlenka:
    Chyba s daty – nedokončená data – nevyplatilo by se uchovávat si historická data na disku a každý den si stáhnout jen předchozí den z yahoo i goog, pokud se data liší vyvolat poplašný error.
    Historická data se mohou stahovat klidně přes den, takže by bylo dost času vyřešit problém než se přiblíží close hodina?

    1. To by slo, jen by to pak chtelo poresit adjustaci dat o splity a dividendy. Pokud ma akcie cenu 100USD za kus a dojde ke splitu 2:1, pak bude dalsi den stat jen 50USD a zaroven bude v obehu dvojnasobek akcii. Jenze to by system nevedel a chybne by nakoupil akcii, takze proto nacitam celou historii kazdy den znova.

      1. ok, to jsem si neuvědomil. Jednodušší je tedy data stahovat denně. Předpokládám, že výhodnější je stahovat je hned po open a provést testy porovnáním yahoo/google, aby byl čas v případě chyby to pořešit ručně.

  2. u IB dat pouzivej ASK, preci jen to cena za kterou min budes obchodovat cili veskere vypocty by meli vychazet z ni…. a ano pri stahovani dat je nutne u nekterych tickeru uvadet primary exchange (viz property m_primaryExch -> Contract class)

    1. Mensi dodatek – ASK cena je vhodna jen v pripade, ze by se akcie nakupovala/dokupovala. V pripade nakoupene akcie a ceny nad SMA5 (alias prodejniho signalu) by se mela pouzit naopak BID cena … Jednodussi mi rozhodne prijde sledovat jen jednu cenu a jet podle ni.

  3. Ty se na datech yahoo trefuješ na xzajícovy obchody? Mě to už třetí den otevírá jiný ticker.

    1. Treba dneska:
      Ticker: SO | RSI: 0.17 | Price: 49.46 | Sma200: 50.45 | Sma5: 50.17
      Ticker: CMCSA | RSI: 3.23 | Price: 65.43 | Sma200: 61.99 | Sma5: 65.92
      Ticker: WMT | RSI: 3.51 | Price: 69.28 | Sma200: 69.14 | Sma5: 71.37
      Ticker: LMT | RSI: 3.64 | Price: 234.97 | Sma200: 233.55 | Sma5: 237.79
      Ticker: UNH | RSI: 6.29 | Price: 136.5 | Sma200: 130.47 | Sma5: 138.15
      Ticker: DUK | RSI: 6.32 | Price: 77.14 | Sma200: 79.23 | Sma5: 78.16
      Ticker: BIIB | RSI: 9.31 | Price: 306.19 | Sma200: 276.53 | Sma5: 310.40

      SO je na max, takze jako dalsi to melo vzit CMCSA

      1. Tak chyba je v tom, že já jsem počítal indikátory z Adjusted close a Ty z close. V postu s chybama jsi psal, že nelze ukládat si historická data, protože potřebuješ adjusted close, ale zdá se, že z nich nepočítáš. K čemu tedy používáš adjusted close?

        1. Ja to mam tedka tak, ze backtesty jedu na adjClose kvuli splitum. Ostry provoz ale jedu na close a hlidam si planovane splity (nebo se alespon snazim) a v takovem pripade bych presel na adjClose. Do toho se snazim sehnat spolehlivejsiho poskytovatele dat, ktery by neadjustoval o dividendy, abych si je mohl resit sam. Kazdopadne musim uprimne priznat, ze v tomhle se ucim za behu a mam tak jeste nejakou cestu pred sebou..

          1. Pak ale jedeš live něco jiného, než jsi backtestoval. To není úplně správně.

            Dobrá zpráva ale je, že tahle metodická chybka nemá výrazný vliv na výsledky. Dokonce to vypadá, že ani splity nejsou zásadní problém, protože pokles ceny vyřadí akcii z obchodování a jen se místo ní zobchoduje druhá nejlepší RSI..

            Divi i split způsobí, že klesne cena . SMA 200 ale raguje na pokles ceny s velký,m zpožděním, takže akcie nějakou dobu nemůže z principu splnit filtr na bulish trend.

            Já jsem chvilku jel live poloautomatické testování opcí podle adjusted close, ale teď jsem přepnul na close, abych si to mohl kontrolovat vůči xzajícovi. Nicméně se možná vrátím zpátky na adjusted close kvůli konzistenci s backtestem.

          2. Za me.. testoval jsem oboji – close i adjClose a pri neadjustovanych cenach mi prijde, ze by je split vychylil tak, ze cena by spadla pod SMA200, takze se akcie proste nenakoupi.

          3. Ahoj,
            jak prosim ziskavas ta adjClose data pro backtesty? Pokud pouzijes Yahoo endpoint a budes chtit backtestovat dejme tomu k 1.10.2016, tedy rok zpet, vrati ti Yahoo adjClose k dnesnimu dni. To znamena, ze bude cena snizena o vsechny dividendy a potazmo budou zapocitany splity ktere nastaly od 1.10.2016 do dneska a to nechces. Potrebujes ajdustovana data tak, jak by je endpoint vratil pred tim rokem…

            Lze tato data nejak ziskat nebo si je pro backtesty pocitas sam?

    2. Ahoj, jak tu adjustaci chapu ja – adjustovat data o splity a dividendy znamena, ze se jednak nasobi historicka data o splitovy pomer, coz zvetsi/zmensi ceny (takze pokud akcie vyrostla z 10USD o 5USD, pak pridala 50% pred, ale i po splitu). Horsi pak je adjustace o divi, kde se cena odecita, takze v predchozim prikladu by po divi 5USD vyrostla akcie z 10USD na 15USD (po adjustaci z 5USD na 10USD, coz je najednou narust 100% oproti puvodni padesatce)

      Nejlepsi by tedy bylo testovat strategii na datech adjustovanych pouze o splity. K otazce tedy – v backtestech si nijak neupravuji data. V pripade dividend si rikam, ze by tak mala zmena na portfoliu 100 akcii nemela udelat vyrazny rozdil (kdyby udelala, tak by to smrdelo curve fittingem). Zaroven strategii testuji na datech z vice zdroju, kde napriklad ty z google finance by nemely byt adjustovane o divi.

  4. Souhlas, to jsem také psal. To se ale děje na close datech i při každé větší dividendě – akcie na nějakou dobu vypadne z tradingu.
    Každopádně tedy nepotřebuješ pro live trading adjustovaná data, takže si můžeš historická data ukládat a nemusíš je stahovat.

  5. Ahoj, jen jsem se chtel zeptat jestli je nutne mit zakoupena data od IB, aby mi chodily spravne ceny v orderStatus metode? Pri zkouseni v Paper Account jsou tyto ceny avgFillPrice a lastFillPrice zpozdene o 15 minut.

    1. Ahoj, ja mel data subscribnuta uz kdyz, jsem to zkousel, takze nevim jiste, jak by se to chovalo bez toho, ale dava mi smysl, aby to bylo posunute i tam, kdyz jsou vsechna data zpozdena..

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *