Všem z vás, kdo jste se doklikali až sem, přeji krásný první dubnový den 2021. Nebojte, žádný kurz nechystám, minimálně ne za peníze. Info-podnikatel se ze mě v dohledné době nestává.
Aby však celá moje snaha o drobný vtípek nepřišla úplně vniveč, rád bych v rychlosti okomentoval systém, který jsem v popisu kurzu použil.
Jsem příznivcem co nejjednodušších věcí, tudíž nebylo potřeba chodit pro zajímavý systém příliš daleko. Jedná se o portfolio složené ze dvou aktiv: 50 % index S&P 500 a 50 % 7-10 let vládní dluhopisy USA, rebalancováno vždy ke konci roku. S takovým portfoliem bych ale nikdy nedocílil tak výrazné outperformance vůči samotnému indexu, takže jsem musel sáhnout pro dvě “drobné” úpravy:
- použít ETFka na steroidech, konkrétně SSO (2x leveraged index S&P 500) a UST (2x leveraged 7-10 Year Treasury),
- vyloučit problematická období, konkrétně 10/2008 – 3/2009 a 3/2020 – 4/2020.
Navíc bylo potřeba dokonstruovat pákové ETFka tak, aby pokrývaly delší časové období (SSO mělo inception 2006, UST v roce 2010).
Graf níže znázorňuje průběh equity a drawdownu bez mého malého triku s vyhlazením. I přesto si systém vedl velmi dobře v porovnání buy&hold indexu. Nicméně nezapomínejte na to, že se aktiva drží na páku 2:1, tudíž “pouhý” 50% pokles současně na indexu a bondech pošle obchodní účet do věčných lovišť, ale to byste ještě před tím dostali od brokera margin call.
BONUS
Zde je zdrojový kód pro Amibroker:
// © FinHacker.cz // kód je určen pro Amibroker výhradně ke studijním účelům EnableRotationalTrading(); EachPosPercent = 50; isLastOfYear = TimeframeExpand(1, inYearly, expandPoint); // identifikace posledního dnu v roce PositionScore = 1; PositionSize = -EachPosPercent; SetOption("WorstRankHeld", 10 ); SetOption("MaxOpenPositions", 10 ); SetOption("UseCustomBacktestProc", True ); if( Status("action") == actionPortfolio ) { bo = GetBacktesterObject(); bo.PreProcess(); for(bar=0; bar < BarCount; bar++) { bo.ProcessTradeSignals( bar ); CurEquity = bo.Equity; y = Year(); for( pos = bo.GetFirstOpenPos(); pos; pos = bo.GetNextOpenPos() ) { posval = pos.GetPositionValue(); diff = posval - (EachPosPercent/100 * CurEquity); price = pos.GetPrice( bar, "C" ); if( isLastofYear[bar] AND abs( diff ) > price) bo.ScaleTrade( bar, pos.Symbol, diff < 0, price, abs( diff ) ); // roční rebalancování } } bo.PostProcess(); }