3 Σεπτέμβριος 2026 · μηχανική δεδομένων

Τα λεπτά που δεν υπάρχουν: κενά, διακοπές και μπάρες μηδενικού όγκου στο ιστορικό OHLCV

Τα λεπτά που δεν υπάρχουν: κενά, διακοπές και μπάρες μηδενικού όγκου στο ιστορικό OHLCV

Ένα ημερολογιακό έτος με μπάρες 1-minute θα πρέπει να έχει 525,600 γραμμές. Η λήψη μας για το 2025 από perpetual συμβόλαια BTCUSDT επέστρεψε 525,557 — 43 λεπτά λιγότερα, ποσοστό πληρότητας 99.992%. Ένα perpetual altcoin μεσαίας κεφαλαιοποίησης στο ίδιο venue, με την ίδια λήψη και την ίδια διαδρομή κώδικα, επέστρεψε 1,247 λιγότερα: 99.76%. Και μια λεπτοσειρά μετοχής ΗΠΑ για το ίδιο έτος είχε περίπου 427,000 λιγότερες γραμμές από την αντίστοιχη των κρυπτονομισμάτων, κάτι που δεν είναι καθόλου κενό, απλώς μια αγορά που κλείνει.

Τρεις από αυτούς τους αριθμούς είναι βαρετοί. Αυτός που αξίζει όσο χίλιες λέξεις είναι το 43.

525,600μπάρες 1-minute σε μη δίσεκτο έτος
0.008%λείπουν από το BTCUSDT, το 2025
61%αυτών των λεπτών συνέπεσαν με ώρες μεταβλητότητας στο ανώτερο δεκατημόριο

Τέσσερα διαφορετικά πράγματα που μοιάζουν με κενό στο dataframe σας

Πριν από τα 43 λεπτά, λίγη ορολογία, γιατί ο περισσότερος κώδικας διαχείρισης κενών είναι ήδη λανθασμένος σε αυτό το επίπεδο. Όταν λείπει μια γραμμή από το τοπικό σας parquet, δεν ξέρετε ποιο από τα παρακάτω συνέβη, και η σωστή αντιμετώπιση διαφέρει σε κάθε περίπτωση.

ΚατηγορίαΤι συνέβη στην πραγματικότηταΠώς εμφανίζεταιΣωστή αντιμετώπιση
Χωρίς συναλλαγέςΗ αγορά ήταν ανοιχτή· κανείς δεν πέρασε το spread εκείνο το λεπτόΜπάρα μηδενικού όγκου (OHLC όλα ίσα, trades=0) σε ορισμένα endpoints, απούσα γραμμή σε άλλαΚρατήστε τη. Είναι πραγματική πληροφορία: κανείς δεν ήθελε να συναλλαχθεί.
Το venue εκτός λειτουργίαςΜη διαθέσιμη μηχανή αντιστοίχισης εντολών, προγραμματισμένα ή όχιΑπούσα γραμμή, μερικές φορές μια ολόκληρη σειρά από αυτέςΣημειώστε την ως παρωχημένη. Μην κάνετε συναλλαγές μέσα σε αυτό το διάστημα.
Αναστολή διαπραγμάτευσης του τίτλουΠαραβίαση ορίου LULD, εκκρεμείς ειδήσεις, ειδοποίηση διαγραφήςΑπούσα γραμμή και στη συνέχεια εκτύπωση δημοπρασίας επαναλειτουργίαςΣημειώστε την ως παρωχημένη και αντιμετωπίστε την επαναλειτουργία ως ασυνέχεια.
Δικό σας λάθοςΣελιδοποίηση με όριο ρυθμού, επανάληψη που παρέλειψε μια σελίδα, σφάλμα ορίου ζώνης ώρας στον βρόχοΑπούσα γραμμή, αδύνατο να διακριθεί από τις παραπάνω περιπτώσειςΕντοπίστε το και ξανακάντε λήψη. Αυτό μπορείτε να το διορθώσετε.

Τα venues διαφωνούν ως προς την πρώτη γραμμή αυτού του πίνακα, κι εκεί βρίσκεται η παγίδα. Το endpoint κεριών του Coinbase παραλείπει εντελώς τα κενά χρονικά διαστήματα, οπότε το ιστορικό ενός μη ρευστού ζεύγους είναι γεμάτο κυριολεκτικά κενά. Τα klines του Binance συνήθως επιστρέφουν μια συνθετική μπάρα με όγκο 0 και open=high=low=close καθηλωμένα στην προηγούμενη συναλλαγή. Το ίδιο υποκείμενο γεγονός, δύο διαφορετικές μορφές· κι ένας loader που κάνει reindex σε πλήρες πλέγμα λεπτών μετατρέπει τη μία στην άλλη χωρίς να σας ενημερώσει. Ελέγξτε τι κάνει το venue σας πριν γράψετε τον κώδικα συμπλήρωσης κενών, όχι αφού τον γράψετε.

Τα 1,247 λεπτά που έλειπαν από το alt ανήκαν σχεδόν όλα στην πρώτη κατηγορία: ρηχό βιβλίο εντολών στις 04:00 UTC μια Κυριακή, χωρίς συναλλαγές. Ενοχλητικό, εύκολο να το κατανοήσεις και σε μεγάλο βαθμό ακίνδυνο, γιατί η στρατηγική ούτως ή άλλως δεν θα συναλλασσόταν τότε. Κι αυτός ακριβώς είναι ο λόγος που σταμάτησα να το κοιτάζω και επέστρεψα στα 43.

Τα 43 λεπτά δεν ήταν διάσπαρτα

Αν οι ελλείψεις ήταν ομοιόμορφα κατανεμημένες, τα 43 λεπτά μέσα σε ένα έτος θα εμφανίζονταν ως 43 μεμονωμένα κενά, ένα κάθε οκτώμισι ημέρες, το καθένα αμελητέο. Δεν συνέβη αυτό. Εμφανίστηκαν σε έξι συνεχόμενα διαστήματα: ένα 19 λεπτών, ένα 11 λεπτών, δύο των 4 λεπτών και δυο ζεύγη. Έξι συμβάντα, όχι 43 ατυχή περιστατικά.

Και τα συμβάντα εξαρτώνται από αυτό που σας ενδιαφέρει. Τα venues πέφτουν όταν πιέζονται από τον φόρτο, και ο φόρτος αυξάνεται όταν κινείται η τιμή. Κατηγοριοποίησα κάθε ώρα του έτους βάσει πραγματοποιηθείσας μεταβλητότητας και εξέτασα πού βρίσκονταν τα λεπτά που έλειπαν: το 61% τους ήταν στο ανώτερο δεκατημόριο. Η άνευ όρων πιθανότητα να λείπει ένα δεδομένο λεπτό είναι 0.008%. Αν περιοριστούμε σε ώρες μεταβλητότητας του ανώτερου δεκατημορίου, είναι περίπου 0.05% — έξι φορές μεγαλύτερη, και επιπλέον οι ελλείψεις συγκεντρώνονται σε συστάδες.

Άρα, η μέτρηση πληρότητας στον πίνακα ελέγχου ποιότητας δεδομένων σας μετρά το λάθος πράγμα. Το 99.992% μοιάζει με dataset που δεν χρειάζεται να σας απασχολεί άλλο. Στην πραγματικότητα περιγράφει μια σειρά πλήρη τις ώρες που η στρατηγική σας δεν κάνει τίποτα και γεμάτη κενά τις ώρες που κάνει τα πάντα. Ένα σύστημα momentum που ενεργοποιείται όταν διευρύνεται η μεταβλητότητα έχει ουσιαστικά μεγαλύτερη πιθανότητα να συναντήσει κενό απ’ όσο υποδηλώνει ο συνοπτικός αριθμός, και το συναντά εν μέσω συναλλαγής.

Τι κάνει το forward-fill λίγες γραμμές παρακάτω

Να το σφάλμα που με έκανε να γράψω αυτό το κείμενο. Ας πάρουμε το διάστημα των 19 λεπτών. Συνήθης τακτοποίηση: κάνετε reindex στο πλήρες πλέγμα λεπτών, εφαρμόζετε forward-fill στις τιμές OHLC από το τελευταίο κλείσιμο και ορίζετε τον όγκο σε μηδέν. Η σειρά είναι πλέον συνεχής και οι δείκτες σας εκτελούνται χωρίς ούτε ένα NaN.

Αυτές οι 19 μπάρες έχουν high == low == close. Το true range είναι μηδέν σε καθεμία. Το ATR(14) που υπολογίζεται σε αυτό το παράθυρο, με αρχική τιμή περίπου 240 USDT πριν από τη διακοπή, υποχωρεί προς το περίπου 34 μέχρι να επανέλθει το venue — οι πέντε πραγματικές μπάρες που απομένουν στο παράθυρο σηκώνουν όλο τον μέσο όρο. Τροφοδοτήστε τώρα αυτή την τιμή σε έναν υπολογισμό μεγέθους θέσης κλιμακωμένο ως προς τη μεταβλητότητα, του συνηθισμένου τύπου size = risk_budget / ATR. Το μέγεθος αυξάνεται επταπλάσια.

Η επόμενη πραγματική μπάρα είναι η τιμή επαναλειτουργίας, και δεν είναι ήρεμη μπάρα. Στην περίπτωσή μας άνοιξε 1.8% μακριά από το τελευταίο κλείσιμο πριν από τη διακοπή. Το backtest άνοιξε χωρίς δισταγμό θέση 7x μέσα σε κενό 1.8%, με εκτέλεση που δεν θα μπορούσε να έχει υπάρξει, σε τιμή που κανείς δεν προσέφερε. Αυτή η μία συνθετική συναλλαγή άξιζε περισσότερο από έναν μήνα νόμιμων κερδών και ζημιών στην καμπύλη κεφαλαίου, προς τη λάθος κατεύθυνση — και γεννήθηκε εξ ολοκλήρου από μια γραμμή καθαρισμού δεδομένων που γράφτηκε για να τακτοποιήσει το dataframe.

Το να διαγράψετε τις γραμμές αντί να τις συμπληρώσετε δεν διορθώνει το πρόβλημα· είναι το ίδιο σφάλμα με άλλη μεταμφίεση. Αν τις διαγράψετε, οι δείκτες αναδρομής με βάση ακέραιο δείκτη σάς παραπλανούν: ένας «EMA 20 μπαρών» καλύπτει πλέον 39 λεπτά ρολογιού μέσα από τη διακοπή, η απόδοση από μπάρα σε μπάρα στο όριο είναι ολόκληρο το άλμα 1.8% μετρημένο σαν κίνηση ενός λεπτού, και κάθε εκτίμηση μεταβλητότητας ανά μπάρα το διαβάζει ως συμβάν 60-sigma. Τίποτα δεν σας προειδοποιεί. Ο δείκτης παραμένει μονότονος.

Με την επαναδειγματοληψία το πρόβλημα γίνεται αόρατο

Οι περισσότερες έρευνες δεν εκτελούνται σε μπάρες 1-minute, αλλά σε συγκεντρωτικά δεδομένα, και η συγκέντρωση συγκαλύπτει το πρόβλημα. Αν κάνετε resample σε 5-minute, ένα κενό 19 λεπτών γίνεται τέσσερις μπάρες, από τις οποίες η πρώτη και η τελευταία είναι μερικές. Η Pandas υπολογίζει OHLC που δείχνει απολύτως εύλογο, με βάση δύο λεπτά που έχουν διασωθεί, και το επισημαίνει ακριβώς όπως μια μπάρα που χτίστηκε από πέντε. Τίποτα στην έξοδο δεν τις ξεχωρίζει.

Η φθηνότερη διόρθωση που ξέρω: μεταφέρετε μια στήλη bars_in_window σε κάθε βήμα resample και μην την πετάτε ποτέ. Μία ακέραια τιμή ανά γραμμή αρκεί ώστε να μπορείτε να απαντήσετε σε κάθε επόμενη ερώτηση για την αξιοπιστία μιας μπάρας. Μεταφέρουμε επίσης το seconds_since_last_real_print, που περιέχει την ίδια πληροφορία σε μορφή αξιοποιήσιμη από το επίπεδο εκτέλεσης.

Η πολιτική μας, όσο υπάρχει

Η σειρά ενεργειών που εφαρμόζουν πλέον οι agents μας:

  1. Ποτέ reindex χωρίς ειδοποίηση. Ο loader παράγει ένα μανιφέστο κενών — αρχή, τέλος, διάρκεια και ποια από τις τέσσερις κατηγορίες θεωρεί πιθανότερη. Αν ένα διάστημα ελλειπόντων λεπτών είναι κάτω από 3 μπάρες και ο όγκος στις γειτονικές μπάρες είναι χαμηλός, το αντιμετωπίζουμε ως λεπτό χωρίς συναλλαγές. Οτιδήποτε μεγαλύτερο σε ώρες λειτουργίας θεωρείται διακοπή μέχρι να αποδειχθεί το αντίθετο.
  2. Ξανακάντε τη λήψη πριν βγάλετε συμπεράσματα. Τα μισά από τα αρχικά μας κενά οφείλονταν σε σφάλματα σελιδοποίησης. Μια δεύτερη λήψη από διαφορετικό endpoint ή διαφορετικό πάροχο επιλύει την τέταρτη κατηγορία και περιορίζει το πρόβλημα πριν χρειαστεί οποιαδήποτε κρίση.
  3. Φραγή λόγω παρωχημένων δεδομένων, όχι συμπλήρωση κενών. Η στρατηγική δέχεται είσοδο data_age και έναν αυστηρό κανόνα: καμία νέα είσοδος όταν η τελευταία πραγματική εκτύπωση είναι παλαιότερη από N μπάρες, και οι ανοιχτές θέσεις κλείνουν στην επαναλειτουργία μόνο με εντολή αγοράς, με ρητή προσαρμογή της τιμής για τον κίνδυνο κενού. Οι εκτελέσεις που δεν θα μπορούσαν να έχουν συμβεί είναι χειρότερες από συναλλαγές που δεν έγιναν.
  4. Οι δείκτες βλέπουν NaN, όχι φανταστικά δεδομένα. Οι τιμές με forward-fill δεν φτάνουν ποτέ στο επίπεδο χαρακτηριστικών. Αν δεν μπορεί να υπολογιστεί το ATR, μένει απροσδιόριστο, και το απροσδιόριστο σημαίνει μηδενική θέση. Μια ξεκάθαρη αποτυχία είναι προτιμότερη από ένα αθόρυβο 7x.
  5. Αναφέρετε την απόδοση υπό συνθήκη κενών. Κάθε backtest που παραδίδουμε παρουσιάζει τα κέρδη και τις ζημίες τόσο με εξαίρεση των συναλλαγών κοντά σε διακοπές όσο και με το συνολικό αποτέλεσμα. Αν αυτές οι συναλλαγές καθορίζουν το αποτέλεσμα, τότε το αποτέλεσμα είναι τεχνούργημα των δεδομένων.

Ένας γρήγορος έλεγχος που μπορείτε να κάνετε σήμερα: ομαδοποιήστε τα ελλείποντα λεπτά σε συνεχόμενα διαστήματα και έπειτα υπολογίστε τι ποσοστό των συναλλαγών του backtest ανοίγει ή κλείνει εντός 30 λεπτών από το όριο κάποιου διαστήματος. Αν είναι κάτω από 1%, τα κενά μάλλον δεν επηρεάζουν τίποτα. Αν είναι 5% ή περισσότερο, η καμπύλη κεφαλαίου αφηγείται εν μέρει την ιστορία της διακοπής λειτουργίας του ανταλλακτηρίου.

Το σημάδι που έχω μάθει να εμπιστεύομαι είναι το μοτίβο των ελλείψεων και όχι το μέγεθός τους. Ένα dataset με χιλιάδες διάσπαρτα κενά σε ώρες αδράνειας συνήθως είναι εντάξει. Ένα dataset με λίγες πυκνές συστάδες σάς λέει ότι κάτι χαλάει υπό φόρτο, και εκεί όπου χαλάει κάτι υπό φόρτο βρίσκεται η στρατηγική σας.

κενά OHLCVμηχανική δεδομένωνbacktestingεπαναδειγματοληψίασυμβόλαια μελλοντικής εκπλήρωσης κρυπτονομισμάτων
ΚοινοποίησηXLinkedInFacebookRedditHacker NewsWhatsAppTelegramEmail
← Όλα τα άρθρα