1 Νοέμβριος 2026 · έρευνα

Πώς ζεσταίνεις ένα backtest χωρίς να μετράς το lookback ως απόδοση;

Πώς ζεσταίνεις ένα backtest χωρίς να μετράς το lookback ως απόδοση;

Ένα Donchian 20 ημερών φαίνεται ακίνδυνο σε μια προδιαγραφή. Ο πράκτορας γράφει ένα κυλιόμενο μέγιστο 20 μπαρών, το backtest ξεκινά στη γραμμή ένα του αρχείου parquet, και για τις πρώτες δύο εβδομάδες το «υψηλό 20 ημερών» είναι απλώς το τρέχον μέγιστο όσων μπαρών υπάρχουν. Την ημέρα τέσσερα είναι ένα υψηλό τεσσάρων ημερών. Η στρατηγική που νόμιζες ότι δοκίμαζες δεν είναι αυτή που παρήγαγε τις πρώτες δώδεκα εκτελέσεις.

Έχω ένα notebook με ημερήσιες μπάρες ETHUSDT όπου το Sharpe πλήρους δείγματος είναι 1.4. Κόψε τις πρώτες 20 συνεδρίες και πέφτει στο 0.6. Κράτα αυτές τις 20 και πέταξε την υπόλοιπη χρονιά ένα, και τυπώνει 3.1. Κανείς δεν διέρρευσε το αύριο. Η στρατηγική χρησιμοποίησε το παρελθόν, απλώς όχι αρκετό από αυτό, και η αναφορά αντιμετώπισε αυτές τις μισοσχηματισμένες συναλλαγές ως τεκμήρια.

1.4Sharpe πλήρους δείγματος, με ημιτελές παράθυρο μέσα
0.6ίδιος κώδικας μετά από 20 ολοκληρωμένες συνεδρίες
3.1Sharpe αν κρατήσεις μόνο τις συναλλαγές burn-in

Άσε το παράθυρο να κάνει συναλλαγές όσο ακόμα γεμίζει

Η συνηθισμένη καταστροφή είναι min_periods=1. Η Pandas θα υπολογίσει έναν κυλιόμενο μέσο σε μία μόνο μπάρα αν την αφήσεις. Οι πράκτορες το κάνουν αυτό συνεχώς, επειδή ένα NaN στην κορυφή του frame μοιάζει με bug, και το γέμισμά του κάνει το unit test πράσινο.

Ένας στόχος realized-vol 20 ημερών με δύο παρατηρήσεις απόδοσης είναι έκρηξη μεγέθους. Η διακύμανση δύο αριθμών είναι κορώνα-γράμματα, την αντιστρέφεις, και η πρώτη θέση είναι αρκετές φορές τον επιδιωκόμενο κίνδυνο. Ένα z-score έναντι σχεδόν μηδενικής τυπικής απόκλισης κάνει το ίδιο κόλπο με πρόσημο: η στρατηγική φαίνεται να έχει μια κοφτερή είσοδο που δεν εμφανίζεται ποτέ ξανά μόλις το παράθυρο είναι ειλικρινές.

Τα breakout είναι χειρότερα, γιατί μοιάζουν με τον πραγματικό κανόνα. Ένα κανάλι 20 μπαρών στην μπάρα έξι είναι ένα κανάλι έξι μπαρών. Παίρνεις ένα σύμπλεγμα συναλλαγών ακριβώς στην αρχή, συχνά σε ένα ήσυχο διάστημα που δεν θα είχε πυροδοτήσει τον ολοκληρωμένο δείκτη. Οι ήσυχες αγορές παρασύρονται λίγο. Ένα στενό κανάλι πυροδοτεί. Η καμπύλη equity παίρνει ένα προβάδισμα που καμία μεταγενέστερη χρονιά δεν επαναλαμβάνει.

Το zero-fill και το forward-fill επινοούν ένα διαφορετικό ψέμα. Το RSI στο 0 διαβάζεται ως υπερπουλημένο. Ένα ελλείπον ATR ίσο με 0 ανατινάζει το μέγεθος μονάδας, και το backtest υπάκουα αγοράζει μια αποθήκη. Θα προτιμούσα ένα NaN να σκοτώσει την εντολή παρά ένα 0 να επινοήσει μία.

Ακόμα με πιάνω να σχεδιάζω από τη γραμμή 0 επειδή ένας κενός μήνας στα αριστερά του γραφήματος μοιάζει ημιτελής. Ο κενός μήνας είναι το ειλικρινές κομμάτι.

Κόψε την καμπύλη equity, κράτα τη θέση

Αυτό γλιτώνει από το code review. Υπολογίζεις σωστά τα χαρακτηριστικά 20 ημερών, πετάς τις πρώτες 20 γραμμές από την καμπύλη που σχεδιάζεται, και δημοσιεύεις από τις 21 Ιανουαρίου. Η θέση στις 21 Ιανουαρίου άνοιξε στις 14 Ιανουαρίου. Το high-water του trailing stop, ο μετρητής πυραμίδας, τα μετρητά μετά από εκείνα τα burns: όλα μπήκαν στο «καθαρό» δείγμα.

Η καταστροφή είναι μια paper στρατηγική που δεν μπορεί να ξεκινήσει στην ημερομηνία του κειμένου. Επανεκκίνησε από flat στην αναφερόμενη έναρξη και οι εντολές της πρώτης εβδομάδας διαφωνούν. Μερικές φορές το backtest είναι ήδη σε μια συναλλαγή που το σύστημα paper δεν έχει λόγο να ανοίξει. Μερικές φορές το σύστημα paper μπαίνει επειδή το lookback του είναι κρύο, και το backtest κάθεται έξω επειδή ο κρυφός του μήνας έχει ήδη πάρει το breakout. Δύο βιβλία ανοίγματος, μία δημοσιευμένη ημερομηνία έναρξης.

Τα fold του walk-forward το κάνουν αυτό αθόρυβα. Κάθε παράθυρο δοκιμής έχει μια ουρά lookback που δεν σχεδιάζεις. Παράλειψε την προσομοίωση εκείνης της ουράς και οι πρώτες συναλλαγές δοκιμής είναι πάλι συναλλαγές ημιτελούς παραθύρου. Προσομοίωσέ την και ανέφερε μόνο τις ημέρες δοκιμής, και η θέση της ημέρας δοκιμής εξαρτάται από εκτελέσεις που δεν δείχνεις. Αυτή η δεύτερη εκδοχή μπορεί να είναι μια θεμιτή ερευνητική επιλογή. Το να αποκαλείς το πρώτο πρωί του fold cold start, ενώ ένα trailing stop είναι ήδη ενεργό από την ουρά, είναι πώς δύο ερευνητές βγάζουν δύο Sharpe από ένα config.

Αν η επανεκκίνηση από flat στη δημοσιευμένη ημερομηνία έναρξης αλλάζει το P&L, το warmup είναι στο ιστορικό απόδοσης. Τα δεδομένα lookback μπορούν να είναι παρόντα. Οι συναλλαγές lookback όχι.

Κάνε warmup σε ημερολογιακές ημέρες όταν το χαρακτηριστικό δεν είναι ημέρα

«Δώσε του 30 ημέρες» αφήνει το χαρακτηριστικό υποπροσδιορισμένο. Τριάντα ημερολογιακές ημέρες σε ένα Donchian 5 λεπτών είναι χιλιάδες μπάρες πέρα από ένα lookback 20 περιόδων. Τριάντα ημέρες σε ένα ημερήσιο χαρακτηριστικό που χρειάζεται 20 συνεδρίες είναι είτε παχύ είτε λεπτό, ανάλογα με τα σαββατοκύριακα και τις τρύπες.

Ένα z-score funding-rate σε ένα από τα perp venues μας πήρε warmup 30 ημερών επειδή η προδιαγραφή έλεγε 30 περιόδους και κάποιος μετέφρασε τις περιόδους σε ημερολογιακές. Το funding εκεί τυπώνει κάθε οκτώ ώρες. Τριάντα ημέρες είναι περίπου 90 διακανονισμοί. Τριάντα περίοδοι είναι δέκα ημέρες. Οι έξτρα δύο μήνες burn-in έτυχε να περιλαμβάνουν μια εβδομάδα depeg. Η αφαίρεσή του έκανε το live παράθυρο να φαίνεται πιο ήρεμο από την πραγματική ιστορία της στρατηγικής. Ο κόσμος κατηγόρησε την ευαισθησία στην ημερομηνία έναρξης. Το warmup είχε καταπιεί το regime.

Και το crypto έναντι των μετοχών κάνει τον ίδιο αριθμό να αλλάζει νόημα χωρίς να επεξεργαστεί κανείς μια παράμετρο. Είκοσι «ημέρες» ETH περιλαμβάνουν Σάββατα. Είκοσι συνεδρίες μετοχών είναι σχεδόν ένας ημερολογιακός μήνας. Αντιγράψε ένα lookback 20 ημερών από ένα notebook μετοχών πάνω σε ωριαία perpetual κεριά και έχεις ένα κανάλι 20 ωρών με όνομα 20 ημερών. Η πρώτη έγκυρη μπάρα είναι τότε είτε 20 ώρες μέσα, είτε 20 ημέρες μέσα αν κάποια μεταγενέστερη συνάρτηση κάνει resample, και έχω δει και τα δύο στο ίδιο diff του πράκτορα.

Κάρφωσε το πρώτο διαπραγματεύσιμο timestamp

Το warmup είναι απαίτηση δεδομένων, όχι μπόνους δείγμα. Κάθε χαρακτηριστικό ονομάζει τον αριθμό των ολοκληρωμένων παρατηρήσεων που χρειάζεται, στις μονάδες στις οποίες υπολογίζεται. Το πρώτο διαπραγματεύσιμο timestamp είναι η πρώτη μπάρα όπου όλα αυτά ισχύουν και ένας flat λογαριασμός θα είχε επιτραπεί να στείλει εντολή.

ΧαρακτηριστικόΤι λέει συνήθως η προδιαγραφήΤι πρέπει πραγματικά να υπάρχειΣιωπηλό υποκατάστατο
Donchian 20 ημερών20 ημερήσια υψηλά20 ολοκληρωμένες συνεδρίεςΚυλιόμενο μέγιστο με min_periods=1
realized vol 30 ημερώνπαράθυρο 30 ημερών30 αποδόσεις close-to-closeΔιακύμανση δύο ημερών, αντεστραμμένη σε μέγεθος
z-score funding 20 εκτυπώσεων20 ημέρες20 διακανονισμοί funding20 ημερολογιακές ημέρες (~90 εκτυπώσεις), ή 20 μπάρες του λάθος timeframe
RSI 14 περιόδων σε 5m14 περίοδοι14 κλειστές μπάρες πέντε λεπτών14 ημέρες, ή 14 μπάρες με κενά forward-filled

Το P&L πριν από εκείνο το timestamp μένει έξω από το ιστορικό απόδοσης. Η κατάσταση πριν από εκείνο το timestamp μπορεί ακόμα να χρειάζεται προσομοίωση, ώστε ένα trailing stop ή ένα cooldown να είναι πραγματικό όταν το ρολόι χτυπήσει την πρώτη διαπραγματεύσιμη μπάρα, αλλά εκείνες οι εκτελέσεις δεν μπαίνουν στο Sharpe, στον αριθμό συναλλαγών ή στα μαθηματικά του capacity. Μετά τρέξε τον άσχημο έλεγχο: επανεκκίνησε από flat σε εκείνο το timestamp, με το lookback διαθέσιμο μόνο ως δεδομένα. Αν οι εντολές αλλάξουν, έστελνες κρυφές συναλλαγές.

Το paper trading ξεκινά με τον ίδιο όρο. Το ίδιο και κάθε παράθυρο δοκιμής walk-forward. Αν το γράφημα μοιάζει να του λείπει ένας μήνας, άφησέ τον να λείπει.

backtestingμηχανική δεδομένωνwalk-forwardπράκτορες AIpaper trading
ΚοινοποίησηXLinkedInFacebookRedditHacker NewsWhatsAppTelegramEmail
← Όλα τα άρθρα