← Terug naar artikelen
July 8, 2026
5 min leestijd

Bewijzen dat multi-timeframe backtests geen look-ahead vertonen: verstoor de toekomst, bewijs dat het verleden de toekomst niet kan zien

Bewijzen dat multi-timeframe backtests geen look-ahead vertonen: verstoor de toekomst, bewijs dat het verleden de toekomst niet kan zien
#algotrading
#backtest
#look-ahead bias
#multi-timeframe
#datalekkage
#validatie
🎯
Part 2 of 9 · Collection
Backtesting Without Fooling Yourself

Onderdeel van de serie "Backtests zonder illusies".

Het vorige artikel eindigde met een diagnostische test: de one-bar shift test. Verplaats elke fill één bar later; als de performance instort, handelde je in het verleden. Die test volstaat voor een single-timeframe strategie, waar look-ahead zich verbergt in de executie — je nam een beslissing op bar i en kreeg een fill op bar i.

Multi-timeframe strategieën hebben een tweede, stillere plek om te lekken, en de shift test bereikt die niet. Wanneer een beslissing op een 1-minuut bar een 1-uurs trend raadpleegt, zit het lek niet meer in de fill — het zit in de indicator, berekend uit een higher-timeframe bar die nog niet klaar is met vormen. Dit artikel gaat over dat lek, en over hoe je mechanisch bewijst — niet door naar code te staren — dat jouw engine het niet heeft.

De bewering die we aan het eind maken is stevig: onze multi-TF engine heeft 25 van de 25 parity- en lekkage-checks doorstaan op 86,400 bars aan echte ETHUSDT 1m-data, inclusief een shifted-future probe die elke toekomstige bar verstoort en bevestigt dat geen enkele beslissing uit het verleden beweegt. En omdat de engine bit-identiek is aan de canonieke kern van de live bot, is het bewijs een eigenschap van het live systeem, niet alleen van de backtest.

Het multi-timeframe mijnenveld

Een 1-minuut beslissing die tegelijk omhoog reikt naar drie timeframes, waarbij de candle van de hoogste timeframe nog aan het vormen is en de uiteindelijke close verborgen zit achter een tijdgrens

Een multi-timeframe (multi-TF) strategie neemt een beslissing op een snelle klok terwijl ze langzame klokken raadpleegt. Onze engine is een concreet voorbeeld: een triple-TF momentumregel waarbij een higher-timeframe (HTF) trend en een mid-timeframe (MTF) trend als gate fungeren voor entries, en een lower-timeframe (LTF) cross ze triggert. Op de 1m-basisklok vuurt een entry alleen af wanneer een 1m HMA/HMA3-cross overeenkomt met de richting van de 1h-trend en de 15m-trend; een exit vuurt af wanneer een higher-timeframe trend tegen de positie in omkeert, of de LTF terugkruist.

Het gevaar is structureel. Elk van die higher-timeframe waarden moet op elke 1m-bar beantwoord worden — 60 keer per uur — en elk antwoord mag alleen gebruikmaken van wat een live bot op dat moment zou weten. Zodra ook maar één van die ruim 180 per-bar reads (drie timeframes, entry- en exit-trends, separation gates) een bar raakt die nog niet geprint is, heb je look-ahead. Het oppervlak voor een off-by-one fout is enorm, en anders dan bij een executielek kondigt het zich niet aan door de fill te verschuiven.

Een vormende bar heeft nog geen uiteindelijke close

Dit is precies de valkuil. Stel het is 10:37 en je neemt een beslissing op de 1m-bar die net gesloten is. Je regel wil de 1h-trend weten. De 1h-candle die 10:00–11:00 beslaat is nog aan het vormen — de uiteindelijke close ervan is pas bekend om 10:59:59. Wat weet je op dat moment, om 10:37, eigenlijk? Alleen de lopende close van die candle tot nu toe, wat gelijk is aan de close van de 10:37-bar. De uiteindelijke close van de candle ligt 23 minuten in de toekomst.

De naïeve multi-TF backtest doet iets wat volkomen onschuldig oogt: hij resamplet de hele 1m-reeks één keer, vooraf, naar 1h, en leest vervolgens voor elke 1m-bar "de 1h close." Maar de waarde die hij leest voor elke 1m-bar tussen 10:00 en 11:00 is de uiteindelijke close van 10:00–11:00 — een getal dat in real time pas bestaat als het uur voorbij is. Elke beslissing binnen dat uur krijgt stilletjes tot 59 minuten van de toekomst in handen geschoven. En dit is geen klein lek: de close van de higher-timeframe is ongeveer de sterkst mogelijke voorspeller van de nabije-toekomst 1m-returns die je zo meteen gaat verhandelen, dus dit lek komt bijna neer op het lezen van het antwoordenblad. Dit is het indicator-lekkagekanaal uit de taxonomie, maar dan versterkt: de blik vooruit is niet één bar, maar kan oplopen tot een volledige HTF-periode.

De one-bar shift test uit het vorige deel vangt dit niet. Je kunt de fill één bar later zetten en de geresamplede 1h-reeks blijft toch besmet — het lek zit in hoe de indicator is opgebouwd, niet in het moment waarop je transacteerde.

De regel van de live bot, exact gereproduceerd: closed-bar semantiek

De higher-timeframe buffer op bar i: een rij van afgesloten closed-candle closes gevolgd door één vormende candle waarvan de waarde de huidige base close is, met de nog verborgen uiteindelijke close doorgestreept

De correcte regel is degene die de live bot al uitvoert. In onze codebase is dat een kleine klasse, RunningCandleBuffer, letterlijk overgenomen uit de live tick-simulator. Hij streamt basisbars in candles met een vaste periode en berekent op elke basisbar de HTF-indicator uit een heel specifieke array:

all_closes = np.array(self.closes + [self.current_close], dtype=np.float64)

Lees dat letterlijk. self.closes zijn de uiteindelijke closes van candles die al gesloten zijn — een candle wordt pas toegevoegd wanneer een nieuwe periodegrens wordt overschreden, en de opgeslagen waarde is de close van de laatste basisbar binnen die periode (candle_buffer.py:39–44). De vormende candle levert precies één getal, self.current_close, de lopende close — de close van de meest recente basisbar, base_close[i]. Dat is per definitie een grootheid die bekend is op bar i. De uiteindelijke close van de vormende candle wordt nooit gebruikt, omdat die nog niet bestaat.

Dus de HTF-indicator om 10:37 ziet [..., close(9:00 candle), close(10:37 so far)]. Wanneer 10:38 print, wordt de laatste positie bijgewerkt naar close(10:38). Wanneer 11:00 wordt overschreden, wordt close(10:59) de uiteindelijke waarde van de net gesloten candle en opent er een nieuwe vormende positie. Op geen enkel moment raakt een beslissing binnen het uur de uiteindelijke close van 10:00–11:00 aan. Dat is closed-bar semantiek: gesloten candles leveren afgeronde closes, de vormende candle levert alleen zijn lopende close.

Onze snelle engine (engine_multitf.py) is een gevectoriseerde, numba-gecompileerde herimplementatie hiervan. In plaats van een Python-lus met een groeiende lijst berekent hij voor elke basisbar i vooraf hoeveel candles volledig gesloten zijn (n_closed[i]) en legt hij het HMA/HMA3-venster aan als [closed candle closes…, base_close[i]] — de lopende close vastgezet in de laatste positie (engine_multitf.py:168–169). Het is dezelfde wiskunde, uitgerold voor snelheid over drie timeframes met directionele separation gates. Het contract is expliciet: de waarde op bar i hangt alleen af van base_close[0..i].

Dat is de bewering. De rest van dit artikel gaat over hoe we haar bewijzen, want een bewering in een docstring is niets waard.

Parity is noodzakelijk maar niet voldoende

Een gevectoriseerde numba-engine die een streaming-klasse uitrolt tot expliciete lussen is precies de plek waar off-by-one fouten ontstaan. Daarom is de eerste poort een bit-for-bit parity-test tegen de canonieke referentie, op een echte slice — ETHUSDT 1m, januari–februari 2024, 86,400 bars.

We toetsen twee onafhankelijke dingen tegen twee onafhankelijke referenties:

  • Indicatoren en crosses vs RunningCandleBuffer bar-voor-bar uitgevoerd. Voor elke timeframe spelen we de live klasse opnieuw af over alle 86,400 bars en vergelijken we cross-events — de bar, de richting, de separation — op een exacte match, plus de HMA/HMA3-waarden binnen floating-point tolerantie (de referentie gebruikt np.dot, de engine expliciete lussen, dus de sommatievolgorde verschilt met ~1e-15). De crosses komen exact overeen: 408 crosses op de HTF (1h, HMA-lengte 21), 2,792 op de MTF (15m/14), 3,691 op de LTF (1m/50). Niet één cross-event verschilt in bar of richting.
  • Trades vs een onafhankelijke pure-Python-simulatie van de handelsregels, aangedreven door de eigen crosses van de referentie. Dit reproduceert de lus van de live backtest — entry-trends fungeren als gate voor entries, een omkering van de exit-trend of een tegengestelde LTF-cross sluit de positie, fills op open[i+1], 0.09% round-trip fee, force-close op de laatste bar — zonder enige numba-machinerie van de engine. Vervolgens vergelijken we trade-voor-trade: entry-/exit-bars, richtingen, entry-/exit-prijzen, PnL, exit-redenen en totale active-time in positie.

De separation thresholds in de test zijn geen onschuldige standaardwaarden. Ze zijn gekozen om precies een lastige hoek te raken — een MTF exit-threshold die hoger is ingesteld dan de bijbehorende entry-threshold — wat de tak "eerste definitie van een exit-trend terwijl een positie open staat" forceert, die de referentie als een omkering behandelt. Parity moet standhouden op de randgevallen, niet alleen op het makkelijke pad.

Veld voor veld zijn de trades identiek: 466 trades voor de dual-configuratie, 211 trades voor de triple, waarbij de totale PnL overeenkomt tot op 1e-12 en elk veld van elke trade gelijk is binnen tolerantie. Twee implementaties die geen code delen — een gecompileerde gevectoriseerde engine en een naïeve Python-lus op de crosses van een derde implementatie — leveren dezelfde trades tot op de laatste decimaal.

Dat is een sterk resultaat, en het is geen bewijs van afwezigheid van look-ahead. Parity zegt dat de snelle engine de referentie getrouw reproduceert. Als de referentie zelf lekte — als RunningCandleBuffer vooruitkeek — zou parity dat lek getrouw reproduceren en slagen. Overeenstemming tussen implementaties vertelt je dat ze hetzelfde zijn, niet dat ze causaal zijn. Voor causaliteit heb je een ander soort test nodig, een die de engine rechtstreeks vraagt of het verleden de toekomst kan zien.

De shifted-future probe: het eigenlijke bewijs

Een verticale snede op 60 procent van de reeks: alles rechts ervan vermenigvuldigd en door elkaar geschud, alles links ervan bevroren en bit-for-bit identiek

De definitie van look-ahead is operationeel, dus test hem operationeel. Look-ahead betekent dat een beslissing uit het verleden afhangt van toekomstige data. De contrapositie is een test die je kunt uitvoeren: als je de toekomst verandert en er een beslissing uit het verleden beweegt, dan las het verleden de toekomst. Verander dus de toekomst — meedogenloos — en kijk naar het verleden.

Kies een snijpunt j op 60% van de reeks (bar 51,840 van 86,400). Verstoor elke bar vanaf j: vermenigvuldig alle toekomstige closes en opens met 1.05. Herbereken de volledige signaalstack voor alle drie de timeframes op de verstoorde data. Toon vervolgens aan dat alles strikt vóór j bitwise identiek is aan de onverstoorde run:

j = int(n * 0.6)                       # bar 51,840
cl2 = cl.copy(); cl2[j:] *= 1.05       # shove the future up 5%
op2 = op.copy(); op2[j:] *= 1.05

base = [precompute_tf_signals(cl,  ts, p, L) for (p, L) in tf_params]
pert = [precompute_tf_signals(cl2, ts, p, L) for (p, L) in tf_params]

for s0, s1 in zip(base, pert):
    assert eq_nan(s0.hma[:j],  s1.hma[:j])      # HMA identical, NaNs included
    assert eq_nan(s0.hma3[:j], s1.hma3[:j])
    assert np.array_equal(s0.cross[:j], s1.cross[:j])   # every cross event
    assert np.array_equal(s0.sep[:j],   s1.sep[:j])     # every separation

Niet "in de buurt." Niet "binnen tolerantie." np.array_equal, waarbij NaNs moeten overeenkomen met NaNs — elke HMA-waarde, elke HMA3-waarde, elke cross-vlag en elke separation op de 51,840 bars uit het verleden moet exact dezelfde float zijn. Daarna dezelfde toets op trades: elke trade waarvan de exit vóór j valt, moet veld voor veld ongewijzigd zijn. Als een schok van 5% op de toekomst ook maar één HMA uit het verleden verandert op de twaalfde decimaal, dan raadpleegde een beslissing uit het verleden de toekomst, en faalt de probe.

Onze engine doorstaat hem — voor alle drie de timeframes, en voor zowel de dual- als de triple-trade-simulaties. Het verstoren van 34,560 toekomstige bars laat 51,840 bars uit het verleden en elke trade die daarbinnen sloot precies zoals ze waren. Dat is geen overeenstemming tussen implementaties; het is een directe demonstratie dat de informatiegrens in tijd standhoudt.

Een test die niet kan falen bewijst niets

Er is een manier om de bovenstaande probe te doorstaan die helemaal niets bewijst: als de verstoring een no-op zou zijn — als het vermenigvuldigen van de toekomst met 1.05 nergens iets zou veranderen — dan is "het verleden is ongewijzigd" triviaal waar en volkomen ongeïnformeerd. Een groen vinkje op een test die niet kan falen is erger dan geen test, omdat het vals vertrouwen creëert. Daarom draagt de probe nog twee extra assertions die haar tanden geven.

De toekomst moet daadwerkelijk veranderen. We tonen aan dat de verstoring ergens in [j, n) wel degelijk crosses heeft veranderd:

assert not np.array_equal(s0.cross[j:], s1.cross[j:])   # probe has teeth

Nu is het resultaat betekenisvol: dezelfde schok van 5% die de toekomst herschreef, liet het verleden bit-for-bit identiek. De verstoring is echt, ze plant zich voorwaarts voort, en ze stopt abrupt bij de snede. Een eenzijdig lek — het verleden leest de toekomst — zou achterwaarts over j heen zijn gebloed; dat gebeurt niet.

De grens ligt precies op de huidige bar — niet één te vroeg, niet één te laat. Een subtielere fout zou een engine zijn die wel causaal is maar verouderd: hij negeert de lopende close van de huidige bar en reageert een bar te laat (geen lek, maar een vertraging die live trading niet zou hebben), of hij reageert een bar te vroeg (een lek van één bar). Daarom verstoren we één enkele bar j (met 1.02) en tonen we twee dingen tegelijk aan: het verleden [0, j) blijft onaangeroerd, en hma[j] reageert onmiddellijk.

cl3 = cl.copy(); cl3[j] *= 1.02        # nudge exactly one bar
s3 = precompute_tf_signals(cl3, ts, p_ltf, L_ltf)
assert eq_nan(s0.hma[:j], s3.hma[:j])  # nothing before j moves
assert s0.hma[j] != s3.hma[j]          # bar j reacts on the same bar

Dit fixeert de grens precies. De lopende close van de vormende candle komt de indicator binnen op bar j met nul vertraging en nul vooruitziendheid: bar j ziet zijn eigen close ogenblikkelijk, en geen enkele eerdere bar ziet hem ooit. Dat is precies het scherpe snijvlak waarop closed-bar semantiek hoort te balanceren, en de test bevestigt dat de engine daar precies op staat.

Hier is de volledige poort — alle 25 checks die tussen deze engine en een gefabriceerde backtest in staan:

Groep Wat elke check toetst Aantal
Indicatoren & crosses (×3 timeframes) cross-events exact vs RunningCandleBuffer; separation bij crosses; HMA/HMA3-waarden (rtol 1e-9) 9
Trades (dual + triple) aantal trades; veld voor veld identiek; totale PnL tot 1e-12; active-time in positie 8
Shifted-future probe (dual + triple) signalen uit het verleden bitwise ongewijzigd; probe heeft tanden (toekomst is wel veranderd); trades vóór j ongewijzigd; single-bar verstoring gelokaliseerd 8
Totaal 25

De eerste twee groepen tonen aan dat de snelle engine dezelfde is als de live referentie. De derde toont aan dat de referentie causaal is. Je hebt alle drie nodig: een snelle engine die lekt, een lekkende engine die causaal is, en een causale engine die vertraagt zijn drie verschillende faalmodi, en de poort sluit ze elk uit.

Waarom de probe timeframe-agnostisch is

De elegantie van de shifted-future probe is dat ze niet weet en zich er niet om bekommert waar een lek zou huizen. Ze noemt nergens timeframes, resampling of candle-grenzen. Ze vraagt alleen: verstoort het aanpassen van de toekomst het verleden? Dat maakt haar precies het juiste gereedschap voor het multi-TF-lek, dat een shift-the-fill test mist.

Bekijk de naïeve resample-de-hele-reeks-bug rechtstreeks. Als de 1h-stream vooraf werd opgebouwd door de volledige reeks te resamplen, zou de "1h close" die op bar j-1000 gelezen wordt (ruim binnen het uur dat na j sluit) de uiteindelijke close zijn van een candle waarvan de uiteindelijke close afhangt van bars op en voorbij j. Vermenigvuldig de toekomst met 1.05 en die uiteindelijke close verandert — dus de HTF-indicator op j-1000 verandert, de gate op j-1000 verandert, en een beslissing uit het verleden beweegt. De probe zou onmiddellijk oplichten op de HTF-stream, op een bar duizend stappen vóór de snede.

De HTF-stream van onze engine beweegt niet, omdat op j-1000 de vormende candle alleen base_close[j-1000] bijdraagt — een close uit het verleden — en de uiteindelijke close van de candle simpelweg nooit geraadpleegd wordt totdat de grens gepasseerd is. De probe is blind voor het mechanisme en vangt de bug toch, wat precies is wat je van een bewijs wilt: het beperkt het gedrag (geen beslissing uit het verleden hangt af van toekomstige data) in plaats van de implementatie te controleren (hebben we de resample correct geïndexeerd?). Gedrag is wat verhandeld wordt; implementatie is waarvan je hoopt dat het ermee overeenkomt.

Backtest en live delen één waarheid

Twee panelen die één gemeenschappelijke ruggengraat delen met het label RunningCandleBuffer: een backtest-sweep aan de ene kant, een live bot aan de andere kant, beide aangesloten op dezelfde kern

Er is nog een reden waarom dit meer betekent dan een typische backtest-audit. De referentie waartegen de engine bewezen wordt — RunningCandleBuffer — is geen testfixture geschreven om de backtest er goed uit te laten zien. Het is de eigen candle-logica van de live bot, letterlijk overgenomen uit de tick-simulator die in productie draait. De closed-bar regel die de probe valideert, is de regel die de live bot uitvoert, bar voor bar.

De parity-poort doet dus dubbel werk. Ze bewijst dat de snelle engine overeenkomt met de referentie, en omdat de referentie de live kern is, bewijst ze dat de snelle engine overeenkomt met live. Het vorige artikel waarschuwde dat een lek de schoonste verklaring is voor een backtest-live parity-gat — de live bot is de ene plek waar je mechanisch niet vooruit kunt kijken, dus een backtest die dat wel doet, wijkt af zodra hij live gaat. Hier wordt dat gat door constructie gedicht: backtest en bot delen één candle-buffer, één cross-regel, één definitie van "bekend op bar i." Het getal dat de zoektocht optimaliseert, is het getal dat de bot daadwerkelijk kan verhandelen.

Dat is precies het punt van het bewijzen van de afwezigheid van look-ahead in plaats van die aan te nemen. Een multi-TF-zoektocht doorloopt duizenden configuraties; als de engine lekte, zou de zoektocht de configuratie vinden die het lek het agressiefst uitbuit en je een gefabriceerde winnaar overhandigen — de faalmodus die de taxonomie mat op een Sharpe van 15 uit pure ruis. De probe is wat je in staat stelt te vertrouwen dat de winnaar echt is voordat je hem aansluit op kapitaal.

Wat de probe wel en niet bewijst

Rigueur over de test werkt in twee richtingen, dus wees precies over de reikwijdte ervan. De shifted-future probe bewijst één enkele, specifieke eigenschap: op deze data hangt geen signaal- of trade-beslissing op of vóór bar j af van enige bar na j — de informatiegrens in tijd houdt stand door het indicator-, cross- en trade-pad heen. Dat is precies het multi-TF-lek dat we wilden elimineren, en het is de eigenschap die een code review niet kan vaststellen.

Ze bewijst niet dat de strategie een edge heeft. Een volkomen causale engine kan eerlijk geld verliezen, en de probe zwijgt daarover — zoals het hoort; bewijzen dat er geen lekkage is en een echte edge vinden zijn twee gescheiden opdrachten, en ze door elkaar halen is hoe gelekte backtests uiteindelijk live gaan. Ze dekt de niet-temporele biases niet af: survivorship in het instrument, selectiebias doordat de probe pas gedraaid wordt nadat de engine er goed uitzag, of een fee-model dat te vriendelijk is. En ze bewijst op zichzelf niet dat live fills overeenkomen met backtest-fills — slippage en latency zijn echte gaten die de probe niet kan zien, omdat ze opereert op het beslissingspad, niet op de executieplek. Wat dat gat dicht, is het aparte feit dat de candle-kern van de engine bit-identiek is aan die van de live bot.

Eén eerlijk voorbehoud over het ontwerp van de probe zelf: ze snijdt op één enkele j (60% van de reeks). De eigenschap die ze verifieert is uniform in j — er is niets bijzonders aan bar 51,840 — dus één snede is een eerlijke test van een structurele eigenschap, maar een paranoïde versie zou j over de hele reeks laten schuiven. Wij beschouwen één goed gekozen snede plus de single-bar lokalisatiecheck als voldoende, omdat een lek dat zich verbergt voor een verstoring van 34,560 toekomstige bars maar wel verschijnt bij een andere snede, een heel merkwaardige bug zou moeten zijn. Het punt is de grenzen van je bewijs te kennen, niet te doen alsof één test een universele kwantor is.

Kernpunten

  1. Multi-timeframe strategieën lekken via de vormende bar, niet via de fill. Een beslissing binnen een onafgeronde HTF-periode mag alleen de lopende close van die candle gebruiken (de laatste base close), nooit de uiteindelijke close. Resample-de-hele-reeks-backtests geven elke intra-periode beslissing tot een volledige HTF-periode van de toekomst cadeau.
  2. De one-bar shift test bereikt dit lek niet. Hij vangt executie-look-ahead; het multi-TF-lek zit in hoe de indicator is opgebouwd. Daarvoor heb je een andere probe nodig.
  3. Reproduceer de live regel exact, en bewijs hem dan. We hebben de closed-bar semantiek van RunningCandleBuffer van de bot herbouwd als een gevectoriseerde engine en er 25 checks voor gezet: crosses exact tegen de referentie (408 / 2,792 / 3,691), trades veld voor veld identiek (466 dual, 211 triple), PnL tot op 1e-12.
  4. Parity is noodzakelijk maar niet voldoende. Overeenkomen met een referentie bewijst dat je hetzelfde bent, niet dat je causaal bent. Een lekkende referentie die getrouw gereproduceerd wordt, lekt nog steeds.
  5. De shifted-future probe is het eigenlijke bewijs. Verstoor elke bar op of na j; toon aan dat elk signaal en elke trade vóór j bitwise ongewijzigd blijft. Als de toekomst het verleden kan bewegen, heb je look-ahead.
  6. Geef de probe tanden. Toon aan dat de toekomst wel degelijk is veranderd (de verstoring is geen no-op) en dat een single-bar duw op diezelfde bar reageert (geen lek, geen vertraging). Een test die niet kan falen bewijst niets.
  7. Wanneer backtest en live één kern delen, gaat het bewijs mee over. Omdat de engine bit-identiek is aan de candle-logica van de live bot, is de afwezigheid van look-ahead ook een eigenschap van het live systeem — en het backtest-live parity-gat sluit door constructie.

Het vorige deel liet zien hoe één regel lek een Sharpe van 15 fabriceert. Dit deel toont de tegenovergestelde discipline: niet "hoe lekken je voor de gek houden," maar hoe je mechanisch en op echte data bewijst dat een specifieke engine niet lekt. Verstoor de toekomst. Als het verleden niet knippert, handel je in het heden.

Disclaimer: De informatie in dit artikel is uitsluitend bedoeld voor educatieve en informatieve doeleinden en vormt geen financieel, beleggings- of handelsadvies. Het handelen in cryptovaluta brengt een aanzienlijk risico op verlies met zich mee.

Auteurs

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

Blijf de markt voor

Abonneer je op onze nieuwsbrief voor exclusieve AI-handelsinzichten, marktanalyses en platformupdates.

We respecteren je privacy. Je kunt je op elk moment afmelden.