SeitenKalenderdaten · 13 / 29
Kalendermodul
Das Kalendermodul gibt Ihrer Strategie die Dividendenhistorie, Split-Historie, Ergebnistermine, das IPO-Datum und aktuelle SEC-Einreichungen eines Unternehmens — und lässt den Backtest Splits und Dividenden automatisch auf Ihre Positionen anwenden.
Aktivieren Sie Include calendar data im Tab Symbol & data des Dialogs Run backtest. Es ist standardmäßig aktiviert, und Ihre Wahl (plus die beiden Unteroptionen) wird für den nächsten Lauf gemerkt. Kalender werden automatisch für jedes Symbol geladen, das der Lauf handelt, einschließlich eines vom Screener aufgelösten Universums — es gibt keine Auswahl pro Ticker. Der Test-Dialog eines Agenten hat dieselbe Option — Include calendar data (dividends, splits) (siehe Agenten).
Nur Backtests. Kalenderdaten werden für Backtests, Debug Test und Agententests geladen. Forward-Läufe — Chart-Forward-Tests, Bulk-Läufe in AutoTrading und QuantCloud — erhalten nie einen Kalender, daher ist calendar dort immer None.
Warum es wichtig ist: Kursbalken sind roh
Backtest-Kerzen sind nicht adjustiert. Ohne Kalenderdaten:
- Ein 4-zu-1-Split sieht aus wie ein nächtlicher Kurseinbruch um 75 %, und Ihre simulierte Position bricht mit ein.
- Dividenden kommen nie an, was die Gesamtrendite jeder lange gehaltenen Position stillschweigend unterschätzt — grob 2 %/Jahr bei einem typischen Dividendenzahler.
Die beiden Unteroptionen beheben beides, ohne dass Codeänderungen nötig sind.
Der Callback-Parameter calendar
Fügen Sie einem beliebigen Callback einen Parameter calendar hinzu, und das Handle wird übergeben:
def on_bar(bar_index, bar, calendar=None, symbol=None):
if calendar is None: # always guard — not every run enables calendar data
return
days = calendar.days_to_earnings(bar["t"], symbol)
if days is not None and days <= 2:
return # sit out the earnings print
divs = calendar.dividends(bar["t"], symbol)
if divs and (divs[-1].amount or 0) > 0.5: # amount can be None
...Funktioniert bei on_bar, on_tick und on_timer. Das Argument calendar wird über den Namen zugeordnet, sodass sich ein Skript ohne calendar-Parameter genau wie bisher verhält und ein deklariertes calendar entweder das Handle oder None erhält — nie ein anderes Objekt, was auch immer Ihre Signatur sonst aufnimmt. Lesen Sie zusätzlich Fundamentaldaten, lautet die empfohlene Signatur def on_bar(bar_index, bar, fundamentals=None, calendar=None, symbol=None).
Sie können dasselbe Handle auch ohne Parameter erreichen: die Skript-Global qc_calendar oder quantcraft.process.runtime.qc_calendar.
Methoden
| Methode | Gibt zurück |
|---|---|
dividends(bar_time, symbol=None) | An diesem Balken öffentliche Dividenden |
splits(bar_time, symbol=None) | Bis zu diesem Balken angekündigte Splits |
filings(bar_time, symbol=None) | An diesem Balken öffentliche SEC-Einreichungen |
next_earnings(bar_time, symbol=None) | {date, basis, estimated, …} oder None |
days_to_earnings(bar_time, symbol=None) | int oder None |
ipo_date(symbol=None) | date oder None |
current(bar_time, symbol=None) | Ein Snapshot-Dict von allem oben an diesem Balken oder None |
dividends_between(start, end, symbol=None) | Dividenden, deren Ex-Tag in (start, end] fällt |
splits_between(start, end, symbol=None) | Splits, deren Wirksamkeitsdatum in (start, end] fällt |
has(symbol=None) | Ob dieses Symbol überhaupt Kalenderdaten hat |
symbols / primary_symbol() / get(symbol=None) | Die geladenen Symbole, das Standardsymbol und der rohe Kalender je Symbol (oder None) |
Die _between-Methoden verwenden die Wirkungsdaten („wann trifft es meine Position?“), anders als die Balkenzeit-Methoden oben, die die „Hätte ich es wissen können?“-Daten verwenden — siehe nächster Abschnitt.
bar_time akzeptiert bar["t"], bar.t[0], ein datetime, ein date oder Epoch-Sekunden.
Listen sind aufsteigend nach Alter sortiert (älteste zuerst) — dividends(...)[-1] ist die jüngste. Das ist das Gegenteil der Fundamentaldaten, bei denen Index 0 die neueste Periode ist.
Ein Symbol ohne Kalenderdaten gibt [] oder None zurück, nie einen Fehler. Die meisten Ticker außerhalb der Large Caps haben auf dem Server keinen Kalender; prüfen Sie daher auf Leere, statt Ausnahmen zu erwarten.
Zwei Daten pro Ereignis — verwenden Sie das richtige
Jede Dividende und jeder Split trägt zwei Daten, und die Wahl des falschen führt Look-ahead ein:
| „Hätte ich es wissen können?“ | „Wann betrifft es meine Position?“ | |
|---|---|---|
| Dividende | declaration_date | ex_date |
| Split | filing_date | effective_date |
dividends() / splits() / filings() filtern nach der ersten Spalte — sie geben nur zurück, was an Ihrem Balken öffentlich war. Ein Split ist oft Wochen vor seiner Wirksamkeit sichtbar, weil das 8-K im Voraus eingereicht wird:
from datetime import date
bar_date = date.fromisoformat(str(bar["t"])[:10])
splits = calendar.splits(bar["t"], symbol)
upcoming = [s for s in splits
if s.effective_date and s.effective_date > bar_date] # announced, not yet effectiveEreignisfelder
DividendEvent: ex_date, amount, estimated, type, declaration_date,
record_date, payment_date, period_end
SplitEvent: effective_date, ratio, type ("forward" | "reverse"), filing_date, form
FilingEvent: form, filing_date, report_date, items, category,
accession_number, primary_document, primary_document_description
IpoInfo: date, first_trade_date, sourceamount (Dividenden) und effective_date (Splits) können None sein — prüfen Sie vor dem Vergleich.
Die category einer Einreichung ist eine von earnings, acquisition, officer-director, charter-amendment, agreement, regulation-fd, auditor-change, shareholder-vote, cybersecurity, other.
Das Flag estimated
EDGAR veröffentlicht keine Ex-Dividenden-Tage. Sofern keine Börsendaten vorlagen, wird der Ex-Tag als Deklarationsdatum + 10 Tage geschätzt und ist auf etwa ±7 Tage genau, mit estimated is True. Standardmäßig schreibt die Simulation geschätzte Dividenden trotzdem gut (Richtlinie best_available); eine Ausführungsvorlage (.qcs) kann dividendDatePolicy auf exact_only (geschätzte überspringen) oder off setzen — dafür gibt es kein Bedienelement im Dialog. Filtern Sie in Ihrer eigenen Logik danach, wenn Ihre Strategie ex-datum-sensitiv ist:
exact = [d for d in calendar.dividends(bar["t"], symbol) if not d.estimated]Kapitalmaßnahmen in der Simulation
Beide Unteroptionen sind standardmäßig aktiviert, wenn Kalenderdaten aktiviert sind, und beide laufen bei jedem Balken vor Ihren Callbacks — on_bar sieht also immer eine bereits angepasste Position.
Positionen für Aktiensplits anpassen — am Wirksamkeitsdatum wird die Aktienanzahl mit dem Verhältnis multipliziert und der Einstandspreis dadurch geteilt. Stop- und Zielkurse werden ebenfalls umskaliert. Da qty × entry_price unverändert bleibt, bleibt Ihre Eigenkapitalkurve über den Split hinweg stetig.
Kursbalken bleiben absichtlich unadjustiert, sodass bar["close"] der echte historische Kurs ist. Ein über die rohe Schlusskursreihe berechneter Indikator sieht weiterhin die Split-Lücke — passen Sie Ihre eigene Reihe mit calendar.splits(...) an, falls das wichtig ist.
Dividenden als Bargeld gutschreiben — am Ex-Tag wird qty × amount bei Long-Positionen zum Bargeld addiert und bei Short-Positionen abgezogen (ein Leerverkäufer schuldet dem Verleiher die Dividende). Das fließt in das Eigenkapital und alle Renditekennzahlen ein, aber nicht in realized_pnl, das nur Trades umfasst. Lesen Sie die Summen aus den Kontokennzahlen:
def on_finish(bars, symbol=None, bars_by_symbol=None):
from quantcraft.process.runtime import account
m = account.refresh_metrics({})
print(m["total_dividend_income"], m["total_splits_applied"])Wo Sie Kapitalmaßnahmen sehen
Nichts ändert Ihre Position oder Ihr Bargeld stillschweigend:
- Ausgabebereich — eine
[calendar]-Zeile pro angewandter Kapitalmaßnahme, plus eine Zusammenfassung am Ende:[calendar] 2024-01-10 AAPL — SPLIT 4:1 applied to 1 position(s): 100 -> 400 shares (cost basis unchanged; bars stay unadjusted) [calendar] 2024-02-09 AAPL — DIVIDEND $0.2400/share on 400 share(s): +$96.00 cash … [calendar] corporate actions — 1 split(s) applied; 1 dividend(s) applied (0 exact ex-date, 1 estimated +/-7d) - Test Results — eine Zeile Split oder Dividend erscheint mitten unter den abgeschlossenen Trades (die Karte heißt dann Closed trades & events) und zeigt Verhältnis bzw. Betrag je Aktie und die Bargeldauswirkung. Ein geschätzter Ex-Tag ist mit
est.markiert. Diese Zeilen tragen keine#-Chart-Markierung und sind vom CSV-Export ausgeschlossen.
next_earnings ist stichtagsbezogen
In einem Backtest gibt next_earnings niemals den „nächsten Ergebnistermin“ des Servers zurück, der zum heutigen Datum berechnet wurde — das wäre Look-ahead an einem historischen Balken. Er wird aus der letzten an Ihrem Balken sichtbaren Ergebniseinreichung plus dem Berichtsrhythmus des Unternehmens rekonstruiert, sodass basis == "filing-cadence" und estimated is True.
Er gibt None zurück, wenn noch keine Ergebniseinreichung sichtbar ist — früh im Lauf oder bei einem Symbol, dessen Einreichungshistorie nicht so weit zurückreicht. Prüfen Sie dies immer.
Wenn Sie keine Dividenden sehen
Ein Lauf, der nichts anwendet, nennt im Ausgabebereich den Grund:
| Das Log sagt | Bedeutung |
|---|---|
loaded 3/5 symbol(s); 2 without calendar data | Am Anfang ausgegeben: wie viele Symbole einen Kalender erhielten |
none of 5 symbol(s) returned calendar data: … | Kein Symbol im Lauf hat Kalenderdaten — nichts kann angewandt werden |
no calendar data on the server | Der Kalenderjob ist für dieses Symbol nicht gelaufen |
calendar has no dividend or split history | Zahlt nichts, keine Splits verzeichnet |
… ex-dates 2019-05-10..2020-05-08 | Zahlt, aber nicht in Ihrem getesteten Zeitraum |
N with no ex-date, which can never be applied | Historie vorhanden, lässt sich aber nicht auf der Uhr platzieren |
no positions were held … | Nichts war offen, als eine Maßnahme fällig wurde |
Erscheinen gar keine [calendar]-Zeilen, wurden dem Lauf keine Kalenderdaten angehängt — prüfen Sie den Schalter Include calendar data im Tab Symbol & data.
Siehe auch
- Backtests — der Dialog Run backtest und die Option Include calendar data
- Strategie-Lebenszyklus — Callback-Parameter
calendar, Laufzeit-Globalqc_calendar - Kontomodell — wo Dividenden-Bargeld und Split-Anpassungen landen
- Screener — wie Kalender geladen werden, wenn ein Screener die Tickerliste auflöst
- Testergebnisse — Split-/Dividend-Zeilen in der Tabelle abgeschlossener Trades
- Ausgabebereich —
[calendar]-Log-Zeilen

