σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademySkills
Ctrl K
AO
+1,2 Tsd. Lernende
AnmeldenBeitreten ↗
Skills
AO
+1,2 Tsd. Lernende
Anmelden
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python-Skill›Modul 9 · Marktdaten und Mikrostruktur›Thema 9.2·~50 Min.Fortgeschritten

Orderfluss-Ungleichgewicht

Position in der SkillModul 9 von 11 · Thema 2 von 5
9.2 Orderfluss-Ungleichgewicht
—Lab-Punkte— / 100XP gesamt—Serie—

Druck, bevor sich der Preis bewegt

Ein Preis bewegt sich selten von allein; er bewegt sich, weil Orders eintreffen und Liquidität entziehen. Nur auf Trades zu schauen, verfehlt einen großen Teil der Geschichte, denn das meiste Geschehen sind Orders, die an der Spitze des Buchs platziert und storniert werden. Das Order-Flow-Ungleichgewicht (OFI) fasst jede Aktualisierung des besten Gebots und Angebots in einer vorzeichenbehafteten Zahl zusammen: positiv, wenn Käufer hinzufügen oder Verkäufer sich zurückziehen, negativ im umgekehrten Fall. Auf kurzen Horizonten sagt es die nächsten Preisänderungen bemerkenswert gut voraus.

def book_imbalance(bid_size, ask_size):
    total = bid_size + ask_size
    if total == 0:
        return 0.0
    return (bid_size - ask_size) / total

print(book_imbalance(450, 200))        # 0.3846  more size on the bid: upward pressure
print(book_imbalance(100, 400))        # -0.6    sellers dominate
print(book_imbalance(0, 0))            # 0.0     an empty top does not divide by zero

Ein Update, eine Zahl

Vergleichen Sie zwei aufeinanderfolgende Quotes. Beim Bid: Steigt oder bleibt der Bid-Preis, wird seine neue Größe addiert; fällt oder bleibt er, wird seine alte Größe abgezogen (bei unverändertem Preis gelten beide, es zählt also die Größenänderung). Beim Ask sind die Vorzeichen umgekehrt: Ein niedrigerer oder gleicher Ask fügt Verkaufsdruck hinzu (- neue Ask-Größe), ein höherer oder gleicher nimmt die alte weg (+ alte Ask-Größe). Die vier Terme sind (b >= pb) * bs - (b <= pb) * pbs - (a <= pa) * as + (a >= pa) * pas, jeder Vergleich ist 1 oder 0.

# The order-flow imbalance of one quote update, tried on four changes of the top of the book
def ofi_event(prev, cur):
    pb, pbs, pa, pas_ = prev
    b, bs, a, as_ = cur
    return (b >= pb) * bs - (b <= pb) * pbs - (a <= pa) * as_ + (a >= pa) * pas_

q0 = (99.5, 300, 100.0, 200)
print(ofi_event(q0, (99.5, 450, 100.0, 200)))     # 150   more size on the same bid
print(ofi_event(q0, (99.6, 100, 100.0, 200)))     # 100   a higher bid: the whole new size counts
print(ofi_event(q0, (99.4, 300, 100.0, 200)))     # -300  the bid price fell: the old size is gone
print(ofi_event(q0, (99.5, 300, 100.1, 200)))     # 200   the ask retreated: less selling pressure

Eine Reihe und was sie erklärt

Wendet man die Regel auf jedes aufeinanderfolgende Quote-Paar an, erhält man eine OFI-Reihe. Über ein kurzes Fenster, etwa eine Sekunde, summiert man die Ereignisse und vergleicht mit der Änderung des Mittelkurses: Der Zusammenhang ist nahezu linear, d_mid = slope * OFI. Die Steigung sagt, wie viel Preis jede Flusseinheit bewegt, und sie sinkt bei tiefem Buch. Man passt sie als Kleinste-Quadrate-Gerade durch den Ursprung an: sum(ofi * dmid) / sum(ofi ** 2).

# A series of events from consecutive quotes, set beside the change of the mid price
import numpy as np

def ofi_event(prev, cur):
    pb, pbs, pa, pas_ = prev
    b, bs, a, as_ = cur
    return (b >= pb) * bs - (b <= pb) * pbs - (a <= pa) * as_ + (a >= pa) * pas_

quotes = [(99.5, 300, 100.0, 200), (99.5, 450, 100.0, 200), (99.6, 100, 100.0, 150), (99.6, 100, 100.1, 400)]
events = np.array([ofi_event(prev, cur) for prev, cur in zip(quotes, quotes[1:])], dtype=float)
print(events)                                                       # [150. 150. 150.]

mid = np.array([(q[0] + q[2]) / 2 for q in quotes])
dmid = np.diff(mid)
print(np.round(dmid, 3))                                            # the mid moved in the direction of the flow
# Recover the price impact of the flow with a slope through the origin
import numpy as np

def impact_slope(ofi, dmid):
    return float(np.sum(ofi * dmid) / np.sum(ofi ** 2))

rng = np.random.default_rng(1)
flow = rng.normal(0, 200, size=500)                                  # order-flow imbalance per second
price_change = 0.00005 * flow + rng.normal(0, 0.004, size=500)       # the mid moves with the flow, plus noise
print(round(impact_slope(flow, price_change), 6))                    # 5e-05, the true impact per unit of flow
Prädiktiv, aber kein Geld geschenktOFI sagt Bewegungen voraus, die kleiner als der Spread sind und auf die schnelle Teilnehmer vor Kosten schon handeln. Sein Wert für die meisten liegt in der Ausführung: Er zeigt, ob man bei einer Kauforder geduldig sein kann, weil das Buch zu den eigenen Gunsten neigt, oder sich beeilen muss, weil der Preis davonläuft. Er hängt auch vom Markt ab: Die Steigung unterscheidet sich zwischen Aktien und Tageszeiten.
  • Das Buch-Ungleichgewicht (bid - ask) / (bid + ask) liegt zwischen -1 und +1; sichern Sie den Leerfall ab.
  • OFI eines Updates: (b >= pb) * bs - (b <= pb) * pbs - (a <= pa) * as + (a >= pa) * pas; eine Reihe wendet es auf jedes aufeinanderfolgende Paar an.
  • Änderungen des Mittelkurses sind nahezu linear im OFI: slope = sum(ofi * dmid) / sum(ofi**2); ein Kurzfristsignal, vor allem für die Ausführung nützlich.

Als Nächstes: asynchroner Code mit asyncio, viele Datenströme verarbeiten, ohne auf jeden zu warten.

Lab: Was bewertet wird

  • Mit book_imbalance beide Seiten vergleichen25 Pkt.
  • Mit ofi_event ein Update bewerten25 Pkt.
  • Mit ofi_series den Druck fortlaufend verfolgen25 Pkt.
  • Mit impact_slope den Fluss bepreisen25 Pkt.
Explorer · lab-113-1
▾ lab-113-1
…
bash · im Browser
learner@quantcraft:~/lab-113-1$
Python noch nicht geladenPythonLn 1, Col 1Spaces: 4UTF-8

Dieses Thema zurücksetzen?

Alles in lab-113-1 wird auf die Startdateien zurückgesetzt und das Terminal geleert. Ihre aktuelle Lösung geht verloren – das lässt sich nicht rückgängig machen.

Wird zurückgesetzt
  • main.py → Startcode
  • Terminal-Verlauf und Testausgabe
  • Nicht eingereichte Änderungen
Bleibt erhalten
  • Beste Lab-Punktzahl
  • Ihre XP und Ihre Serie
  • Vorlesungsfortschritt und Notizen

Melde dich an, um deinen Code auszuführen.

Alle Lektionen kannst du kostenlos lesen. Erstelle ein Konto oder melde dich an, um Code auszuführen, Tests zu starten und dieses Lab abzugeben.

  • IDE im Browser mit Bash-Terminal — nichts zu installieren
  • Sofortige Bewertung, XP und dein Platz auf der Skill
Konto erstellenAnmelden
ODER
Weiter mit GitHub