Une exécution n'est pas une certitude
Un backtest naïf suppose qu'un ordre de n'importe quelle taille est exécuté au prix des données. Les ordres réels posent trois questions. Quelle est la profondeur du carnet : un ordre au marché prend d'abord la meilleure offre, puis la suivante, donc un gros ordre paie un prix moyen moins bon. Le marché a-t-il atteint ma limite : un ordre à cours limité obtient le prix demandé ou mieux, mais seulement si les échanges l'atteignent. Et combien puis-je prendre : un gros ordre ne peut être qu'une fraction du volume de la barre, donc il est exécuté par morceaux dans le temps.
def fill_market_order(book, quantity):
remaining = quantity
cost = 0.0
filled = 0
for price, size in book: # cheapest offer first
if remaining <= 0:
break
take = min(size, remaining)
cost += take * price
filled += take
remaining -= take
if filled == 0:
return 0.0, 0
return cost / filled, filled
book = [(50.00, 300), (50.02, 500), (50.05, 1000)]
print(fill_market_order(book, 200)) # (50.0, 200) inside the first level
print(fill_market_order(book, 600)) # (50.01, 600) 300 at 50.00 and 300 at 50.02
print(fill_market_order(book, 5000)) # (50.0333, 1800) the whole book; 3,200 shares stay unfilled# The average price and the slippage against the best offer grow with the size
def average_price(book, quantity):
remaining, cost, filled = quantity, 0.0, 0
for price, size in book:
take = min(size, remaining)
cost += take * price
filled += take
remaining -= take
return cost / filled
book = [(50.00, 300), (50.02, 500), (50.05, 1000)]
for quantity in (100, 300, 800, 1800):
avg = average_price(book, quantity)
print(quantity, round(avg, 4), round((avg - 50.00) / 50.00 * 10000, 2), "bps above the best offer")Ordres à cours limité et écarts
Avec des barres (ouverture, plus bas, plus haut), on ne voit pas le chemin à l'intérieur de la barre, seulement ses extrêmes. Un achat à cours limité L est exécuté si le plus bas de la barre a atteint L ou moins. Le prix est L, sauf si la barre a ouvert sous L : le marché a alors sauté votre limite et vous êtes exécuté à l'ouverture, ce qui est meilleur. Une vente à cours limité est l'image miroir. Un ordre limité simplement touché peut ne pas être exécuté en réalité, car la file devant vous a été servie d'abord ; c'est donc la borne optimiste.
def limit_fill(side, limit, bar_open, bar_low, bar_high):
if side == "buy" and bar_low <= limit:
return min(bar_open, limit) # a gap below the limit fills at the better open
if side == "sell" and bar_high >= limit:
return max(bar_open, limit)
return None
print(limit_fill("buy", 49.95, 50.10, 49.90, 50.20)) # 49.95 traded down through the limit
print(limit_fill("buy", 49.95, 49.90, 49.80, 50.20)) # 49.9 opened below: filled at the open
print(limit_fill("buy", 49.95, 50.10, 50.00, 50.20)) # None never reached
print(limit_fill("sell", 50.15, 50.00, 49.90, 50.20)) # 50.15Travailler un gros ordre
Beaucoup de tables d'exécution utilisent une limite de participation : ne pas prendre plus de, disons, 10 % du volume. Dans une barre de 40 000 titres échangés, c'est 4 000, arrondi à l'inférieur. Un ordre de 5 000 titres prend alors deux barres, pas une. Parcourir les barres est une boucle qui porte la quantité restante : chaque barre exécute min(remaining, int(volume * participation)), et les barres suivant la fin de l'ordre n'exécutent rien.
def partial_fill(quantity, bar_volume, participation):
return min(quantity, int(bar_volume * participation))
def fill_over_bars(quantity, volumes, participation):
remaining = quantity
fills = []
for volume in volumes:
filled = partial_fill(remaining, volume, participation)
fills.append(filled)
remaining -= filled
return fills
fills = fill_over_bars(5000, [40000, 30000, 80000, 100000], 0.1)
print(fills, sum(fills)) # [4000, 1000, 0, 0] 5000- Un ordre au marché parcourt le carnet niveau par niveau ; le prix moyen est pondéré par les volumes et se dégrade avec la taille, et un carnet mince n'exécute qu'une partie.
- Un ordre limité est exécuté si la barre atteint la limite, à l'ouverture si la barre l'a sautée ; un simple contact peut ne pas être exécuté en réalité.
- Les plafonds de participation limitent chaque barre à
int(volume * participation); une boucle porte la quantité restante d'une barre à l'autre.
À suivre : le MEDAF et le bêta, mesurer la part d'un rendement qui vient du marché.
Lab : ce qui est noté
- Parcourir le carnet avec
fill_market_order25 pts - Décider si la limite est atteinte avec
limit_fill25 pts - Respecter le volume avec
partial_fill25 pts - Travailler l'ordre dans le temps avec
fill_over_bars25 pts