Jednou z ne úplně zanedbatelných věcí, na které se v automatických obchodních systémech musí myslet, jsou splity a reverse splity. Zároveň kolem sebe vnímám spoustu dotazů, jak se tohle dá řešit, takže zde shrnu tři teoretické možnosti, jak na to.
Systém nákupu a prodeje akcií v mém případě funguje tak, že se každý den stáhnou historická data uzavíracích cen, spočítají se indikátory a podle nich se nakoupí akcie. To, za jaké peníze a kolik kusů jsme nakoupili, se pak zapíše do databáze. Při dalším běhu se načtou data z databáze, opět se stáhnou historická data, spočítají indikátory a podle nich se určí, zda se akcie má prodat a případně i kolik kusů.
Problém u splitů pak je ten, že pokud držíme například 10 akcií a během jejich držení přijde split/reverse split, pak se nám jednak změní počet držených akcií a z druhé strany se změní i cena, za kterou jsme akcie nakoupili. Pro vysvětlení je tu příklad:
1.2. jsme nakoupili 10 kusů ABC za 100 USD / kus – celková cena tedy byla 1’000 USD
5.2. přišel split 2:1 a my tak dostali dalších 10 kusů akcie (nyní máme celkem 20 kusů), zároveň se ale snížila cena na 50USD / kus -> a celková cena zůstala na 1’000 USD.
Celková cena je sice zachována, v databázi obchodního systému nám ale zůstalo jen 10 kusů, takže si systém při dalším načtení dat bude myslet, že cena spadla na polovic. Jak se tohle dá řešit?
Prvním a ne úplně optimální způsobem je synchronizovat si počet kusů akcie oproti API brokera. Tam totiž bude již upravených 20 kusů a při prodeji si tak můžeme načíst novou – aktuální – hodnotu z API a podle té se řídit. Obrovskou nevýhodou pak ale je, že na účtu s danou akcií nesmí obchodovat nic dalšího, jinak by automatický obchodní systém prodal například i manuálně nakoupené akcie.
Druhým a už o trochu lepším způsobem je najít si kvalitní splitový kalendář, který systém bude sledovat a v případě splitu přepočítá počet kusů oproti splitnutému poměru. To je celkem fajn řešení, ale přidává se tím další externí strana, na které bude naše aplikace závislá.
Třetím způsobem pak může být třeba to, že si při zpracování načteme historickou adjustovanou cenu ze dne nákupu (tady z 1.2.), porovnáme cenu s nákupní cenou v databázi a pokud se bude výrazně lišit (třeba o 2%?) tak zřejmě došlo ke splitu. V takovém případě pak můžeme vzít nákupní cenu z databázi, podělit ji historickou adjustovanou cenou v tom samém dni a to nám dá poměr splitu. Tím už stačí jen vynásobit počet akcií uvedených v databázi, čímž dostanem počet aktuálně držených akcií. Nevýhodou zde mohou být dividendy, které budou historická data zkreslovat, a proto by bylo fajn odebírat pouze data adjustovaná o splity.
A tudíž, nejlepším přístupem by bylo všechny způsoby spojit do jednoho a udělat tak vícenásobnou kontrolu, aby například vlivem špatných dat nedošlo k prodeji více akcií, než vůbec fyzicky držíme.
Máte to taky tak nějak?
Ja bych to API brokera nezavrhoval, je to preci jenom golden source of data. A urcite maji pristup k velmi kvalitnim splitovym kalendarum. A prepocet adjustovane ceny delaji za tebe. Manualne nakoupene akcie by slo osetrit rozdelenim na poducty. V investicni bance co jsem delal to bylo u klientu bezne ze meli ruzna portfolia separovana poducty. Mrknu do IB jestli to taky nejak neresi.
API Brokera je špatná varianta mimo jiné pokud obchodujete více strategií současně. IB neumí tagovat pozice, takže se nedozvíte, která strategie pozici nakoupila.
Vidím to na variantu 3. Asi ani není potřeba nic počítat, některá API umí vrátit poměr, např. záložka Yahoo Statistics.
Ahoj.. tohle rozdeleni na poducty na IB jde, ale i tak tam sdilis cely kapital. Zkousel jsem tedka i vypsat vsechny pozice z poductu a vypsaly se mi uplne vsechny (i ty nakoupene z hlavniho uctu). Kazdopadne pokud ma clovek kvalitni zdroj splitovych dat, tak to je nej.. o tom zadna.
Můžeš mě pls nasměrovat, o čem mluvíš? Oba mluvíte o „poducty“..? Ideálně odkaz na IB web? Nejsem schopen nic dohledat. Díky!
Ahoj, mrkni na IB do Manage Account > Access Rights > Users
Muzes si tam vytvorit dalsi ucet, kteremu das napr. jen prava na obchodovani a povolis pristup jen z jedne IP adresy.
Tak po dlouhém pátrání a drobné pomoci od Petra(?) winpsa chci informovat, že je tagování orderů (ne pozic) řešitelné pomocí Order.orderRef (custom string), který se dá pověsit nejen na MKT, ale i na každý (leg?) order z bracket orderu.
V Node je to
let mkt = ib.order.market(action=’BUY‘, quantity=1, transmitOrder=false);
mkt.orderRef = „MKT“;
ib.placeOrder(
let lmt = ib.order.stop(action=’SELL‘, quantity=1, price=100, transmitOrder=true, parentId=mktId, tif=null);
lmt.orderRef = „LMT“;
ib.placeOrder(
Důležitý je ten transmitOrder=false u MKT a transmitOrder=true u LMT.
Poté stačí 1x denně provést
ib.reqExecutions(orderd, {});
a to vypíše otevřené a zavřené ordery za posledních 24 hodin, včetně orderRef, a pak jen orderRef porovnat s vlastními pozicemi z databáze. Tzn. pokud zavřelo IB pozici na základě stoplossu, dá se tu zjistit.
Druhá varianta je subscribovat se na ib.reqAccountUpdates(true, “); a pokud dojde k updatu pozic (opět např. kvůli stoplossu), srovnat s vlastními pozicemi pomocí tickeru, popř. volume.
Snad tím někomu ušetřím čas, který jsem na tom zabil já.