Επανεκκινήσαμε μια paper στρατηγική στη μέση μιας συναλλαγής και πήραμε διαφορετική ακολουθία εντολών από εκείνη που είχε παράγει πριν από την επανεκκίνηση. Ίδια δεδομένα αγοράς, ίδια έκδοση στρατηγικής, ίδιο υπόλοιπο λογαριασμού. Ο υπολογισμός του σήματος ταίριαζε. Η μνήμη της στρατηγικής για τη θέση της και τις εκκρεμείς εντολές δεν ταίριαζε.
Εντοπίσαμε την αιτία της απόκλισης μέσα από μια μέρα εργασίας με επαναλήψεις. Το χρήσιμο συμπέρασμα ήταν απλό: για το λογισμικό σας, η επανεκκίνηση είναι ένα συμβάν της αγοράς. Αν δεν ελέγξετε πώς η στρατηγική ανασυγκροτεί την κατάστασή της, ένα καθαρό backtest μπορεί να κρύψει ένα paper σύστημα που ξεχνά τι έχει στην κατοχή του.
09:10 — Επιλέξαμε μια συνηθισμένη θέση
Η δοκιμαστική στρατηγική διαπραγματευόταν ένα ρευστό perpetual: άνοιγε long θέση όταν ένας βραχυπρόθεσμος κινητός μέσος όρος περνούσε πάνω από έναν μακροπρόθεσμο και έκλεινε τη θέση στην αντίστροφη διασταύρωση. Ξεκινήσαμε την επανάληψη με μια μικρή ανοιχτή θέση και μια reduce-only limit εντολή σε αναμονή για να τη μειώσει. Έτσι, η ανάκαμψη έπρεπε να ανασυγκροτήσει 2 δεδομένα: τι είχαμε στην κατοχή μας και τι είχαμε ήδη ζητήσει από το ανταλλακτήριο να κάνει.
Στο σημείο ελέγχου, ο λογαριασμός είχε 0.04 συμβόλαια. Η εντολή ήταν ανοιχτή για 0.01. Η διεργασία της στρατηγικής είχε αποθηκεύσει και τις 2 τιμές στη μνήμη, αλλά κατά την εκκίνηση ανακτούσε μόνο τη θέση. Θεώρησε ότι η αποθηκευμένη εντολή δεν υπήρχε πλέον.
09:25 — Εμφανίστηκε η πρώτη διπλή εντολή
Μετά την επανεκκίνηση, η στρατηγική εντόπισε την υπάρχουσα long θέση, εκτέλεσε τη λογική των σημάτων της και υπέβαλε άλλη μία εντολή μείωσης 0.01. Τώρα το paper ανταλλακτήριο είχε 2 ενεργές εντολές. Καθεμία από μόνη της ήταν έγκυρη. Μαζί, όμως, μπορούσαν να πουλήσουν διπλάσια ποσότητα από την προβλεπόμενη, αν εκτελούνταν και οι 2.
Αρχικά κατηγορήσαμε τον βρόχο σημάτων. Δεν έφταιγε ο βρόχος· έφταιγε το ελλιπές στιγμιότυπο κατάστασης. Η στρατηγική ρώτησε «Τι θέση έχω;» αλλά δεν ρώτησε ποτέ «Ποιες εντολές παραμένουν ενεργές;»
| Κατάσταση μετά την επανεκκίνηση | Τι πίστευε η διεργασία | Τι είχε ο λογαριασμός |
|---|---|---|
| Θέση | Long 0.04 | Long 0.04 |
| Ανοιχτές εντολές μείωσης | Καμία | 2 εντολές των 0.01 |
| Προβλεπόμενη έκθεση μετά από 1 εκτέλεση | Long 0.03 | Θα μπορούσε να γίνει long 0.02 |
10:00 — Διορθώσαμε την ανάκαμψη και μετά εντοπίσαμε πρόβλημα χρονισμού
Αλλάξαμε τη διαδικασία εκκίνησης, ώστε να ανασυγκροτεί την κατάσταση από τις θέσεις του λογαριασμού και τις ανοιχτές εντολές πριν επιτρέψει νέες αποφάσεις. Έτσι εξαλείψαμε τη διπλή εντολή. Έπειτα κάναμε την αποσύνδεση λιγότερο ομαλή: μία εντολή εκτελέστηκε ενώ η στρατηγική ήταν εκτός σύνδεσης και η ειδοποίηση εκτέλεσης έφτασε μετά την επανασύνδεση.
Το στιγμιότυπο του λογαριασμού περιλάμβανε ήδη την εκτέλεση. Η καθυστερημένη ειδοποίηση μείωσε ξανά την τοπική θέση. Για λίγα δευτερόλεπτα, η στρατηγική πίστευε ότι είχε 0.02 συμβόλαια, ενώ ο λογαριασμός είχε 0.03. Η επόμενη αναπροσαρμογή της βασίστηκε σε ένα ανύπαρκτο έλλειμμα.
Προσθέσαμε κανόνες συμφωνίας κατάστασης: να θεωρούμε το στιγμιότυπο του λογαριασμού ως αφετηρία, να χρησιμοποιούμε αναγνωριστικά συμβάντων για να αγνοούμε εκτελέσεις που έχουν ήδη αποτυπωθεί εκεί και να μην υποβάλλουμε εντολές μέχρι να ολοκληρωθεί ο αρχικός συγχρονισμός. Μια ειδοποίηση μπορεί να φτάσει καθυστερημένα ή 2 φορές. Η ανάκαμψη πρέπει να αντέχει και τα 2.
13:40 — Η επανάληψη εντόπισε μια διακριτική απόκλιση
Επαναλάβαμε την ίδια πορεία τιμών στην αρχική εκτέλεση και στην εκτέλεση μετά την επανεκκίνηση. Η σύγκριση του τελικού P&L δεν θα αποκάλυπτε το πρόβλημα: οι 2 εκδοχές κατέληξαν στην ίδια θέση μετά την αντιστροφή της αγοράς. Η σύγκριση των συμβάντων εντολών το αποκάλυψε.
Καταγράψαμε κάθε απόφαση μαζί με την κατάσταση που διάβασε: θέση, ανοιχτές εντολές, αναγνωριστικό τελευταίας επεξεργασμένης εκτέλεσης, τιμή σήματος και έκδοση στρατηγικής. Έτσι, η πρώτη απόκλιση είχε εξήγηση. Η μία εκτέλεση είδε μια ενεργή εντολή· η άλλη είδε κενή λίστα. Αργότερα, η μία πέρασε την ίδια εκτέλεση 2 φορές.
Το ίδιο τελικό υπόλοιπο δεν αποδεικνύει ότι η συμπεριφορά ήταν ίδια. Συγκρίνετε την ακολουθία αποφάσεων και εντολών, ειδικά στα σημεία ανάκαμψης.
16:20 — Τι θα κάναμε διαφορετικά την επόμενη φορά
Χάσαμε πολύ χρόνο επαναλαμβάνοντας τα δεδομένα τιμών πριν ελέγξουμε τις μεταβάσεις κατάστασης του λογαριασμού. Την επόμενη φορά, θα εισάγαμε πρώτα τις περιπτώσεις αστοχίας και θα κρατούσαμε την πορεία της αγοράς σχεδόν επίπεδη. Έτσι, το σφάλμα του λογισμικού φαίνεται καθαρά, χωρίς μια απότομη κίνηση να θολώνει τη διάγνωση.
- Επανεκκινήστε με ανοιχτή θέση και εντολή μερικής εκτέλεσης.
- Αποσυνδεθείτε μετά την υποβολή και επανασυνδεθείτε πριν φτάσει η ειδοποίηση εκτέλεσης.
- Παραδώστε το ίδιο συμβάν εκτέλεσης 2 φορές και επιβεβαιώστε ότι αλλάζει την κατάσταση μόνο 1 φορά.
- Μπλοκάρετε τις νέες εντολές μέχρι να συμφωνηθούν τόσο οι θέσεις όσο και οι ανοιχτές εντολές.
- Συγκρίνετε τα αρχεία καταγραφής αποφάσεων και εντολών μεταξύ εκτελέσεων χωρίς διακοπή και μετά από επανεκκίνηση.
Μάθαμε επίσης να αποθηκεύουμε ένα στιγμιότυπο ανάκαμψης μαζί με την έκδοση της στρατηγικής και το αρχείο συμβάντων. Έτσι, μπορούσαμε να αναπαράγουμε την αστοχία μέσα σε λίγα λεπτά, χωρίς να βασιζόμαστε στη μνήμη κάποιου για την ακριβή ακολουθία επανασύνδεσης.
Μια paper στρατηγική που συμπεριφέρεται σωστά μόνο όσο η διεργασία της παραμένει ενεργή δεν έχει ολοκληρώσει μια πλήρη πρόβα. Επανεκκινήστε τη στη μέση μιας θέσης, αφήστε τις εκτελέσεις να φτάσουν καθυστερημένα και ελέγξτε κάθε εντολή που στέλνει μετά. Στόχος δεν είναι να αποδείξετε ότι δεν θα αποτύχει ποτέ. Είναι να κάνετε ορατή την ανάκαμψή της, προτού ο paper λογαριασμός σάς διδάξει το ίδιο μάθημα απροειδοποίητα.
← Όλα τα άρθρα


