BAR6-Format
Das binäre Datenformat von partiqon für effiziente, transparente Speicherung und schnellen Zugriff auf Marktdaten. Designed für Geschwindigkeit, kompakte Speicherung und keinen Vendor-Lock-in.
Überblick
BAR6 ist ein offenes, dokumentiertes Binärformat für historische Marktdaten. Es unterstützt sowohl Bar-Daten (OHLCV) als auch Rohtick-Daten mit Bid/Ask-Informationen. Anders als proprietäre Formate ist BAR6 vollständig dokumentiert und kann von jedem Werkzeug gelesen werden.
Dateistruktur
Jede BAR6-Datei beginnt mit einem 49 Byte großen Binär-Header, gefolgt von Datensätzen fester Größe:
Datensätze haben eine feste Größe und stehen in aufsteigender Zeitfolge. Datensatz
n liegt damit bei 49 + n × Datensatzgröße. Jedes Werkzeug
kann direkt an eine Stelle einer mehrere Gigabyte großen Datei springen, ohne alles
davor zu lesen.
Header (49 Bytes)
Little-Endian, ohne Padding. Python-Formatstring: <IIBIIqq16s
| Offset | Größe | Typ | Feld | Beschreibung |
|---|---|---|---|---|
| 0 | 4 | uint32 | magic | 0x42415236, die ASCII-Bytes „BAR6" |
| 4 | 4 | uint32 | version | 2 = aktuell |
| 8 | 1 | uint8 | data_type | 0 = Bar-Datensätze, 1 = Tick-Datensätze |
| 9 | 4 | uint32 | timeframe_minutes | z. B. 15 für M15. 0 bei Tick-Dateien, denn Tick-Daten haben keinen Zeitrahmen |
| 13 | 4 | uint32 | record_count | Anzahl der folgenden Datensätze |
| 17 | 8 | int64 | start_ts | Zeitstempel des ersten Datensatzes, Unix-Millisekunden UTC |
| 25 | 8 | int64 | end_ts | Zeitstempel des letzten Datensatzes, Unix-Millisekunden UTC |
| 33 | 16 | char[16] | symbol | Mit Nullbytes aufgefüllter Instrumentenname, z. B. „DEU.IDX-EUR" |
Bar-Datensatz (56 Bytes)
Vorhanden bei data_type = 0. Python-Formatstring: <q6d
| Offset | Größe | Typ | Feld | Beschreibung |
|---|---|---|---|---|
| 0 | 8 | int64 | timestamp | ERÖFFNUNGSzeit der Kerze, Unix-Millisekunden UTC |
| 8 | 8 | double | open | Eröffnungskurs |
| 16 | 8 | double | high | Höchstkurs der Kerze |
| 24 | 8 | double | low | Tiefstkurs der Kerze |
| 32 | 8 | double | close | Schlusskurs |
| 40 | 8 | double | bid | Letzter Bid-Quote der Kerze; zusammen mit Ask der Spread, den ein Fill zahlt |
| 48 | 8 | double | ask | Letzter Ask-Quote der Kerze; zusammen mit Bid der Spread, den ein Fill zahlt |
Ein Bar-Datensatz hat kein Volumenfeld. BAR6 speichert stattdessen Bid und Ask, denn ein Backtest muss wissen, was eine Ausführung gekostet hätte, und das lässt sich aus einer Volumenangabe nicht rekonstruieren.
Tick-Datensatz (32 Bytes)
Vorhanden bei data_type = 1. Python-Formatstring: <q3d
| Offset | Größe | Typ | Feld | Beschreibung |
|---|---|---|---|---|
| 0 | 8 | int64 | timestamp | Unix-Millisekunden UTC |
| 8 | 8 | double | bid | Bid-Kurs |
| 16 | 8 | double | ask | Ask-Kurs |
| 24 | 8 | double | volume | 0, wenn die Quelle keines geliefert hat |
Daten konvertieren
Nutze DataConvert, um deine Historien (CSV, MT4 .hst) in das BAR6-Format zu konvertieren. DataConvert läuft lokal auf deinem Rechner; deine Rohdaten verlassen nie deinen PC.
- Eingabe: CSV (Timestamp, Open, High, Low, Close, Volume) oder MT4 .hst
- Ausgabe: .bin-Datei im BAR6-Format
- Tool: github.com/hangmann/bar6-dataconvert
Warum BAR6?
- Kompakt: 56 Bytes pro Bar, 32 Bytes pro Tick. Effiziente Speicherung und schnelle Lesezugriffe
- Dokumentiert: Vollständige Spezifikation, keine proprietären Geheimnisse
- Transparent: BAR6-Dateien können mit jeder Sprache gelesen werden (C++, Python, Java usw.), ohne Plattform-Lock-in
- Deine Daten, deine Regeln: Einmal konvertiert, überall nutzbar
BAR6 programmatisch lesen
BAR6 ist einfach genug, um in jeder Sprache gelesen zu werden. Dieses Python liest beide Dateiarten und wird in unserer Testsuite gegen echte BAR6-Dateien ausgeführt. Es funktioniert also nachweislich und nicht nur der Absicht nach.
Das Präfix < ist entscheidend: Es legt Little-Endian fest und schaltet
das Padding ab, das Python sonst zwischen Feldern unterschiedlicher Größe einfügt.
Ohne das kommen auf manchen Plattformen falsche Datensatzgrößen heraus.
Direkt zu einem Zeitpunkt springen
Da die Datensätze feste Größe haben und zeitlich sortiert sind, ist das Finden eines Zeitstempels eine binäre Suche über die Datei statt eines Durchlaufs: bei 170 Millionen Datensätzen etwa 28 Lesezugriffe von je 8 Byte.