Download src/execution/implementation_shortfall.py from Ypeng12/quant-ai: direct link, hf CLI and curl.
- Browser
- Download file 2.2 kB
-
https://huggingface.co/spaces/Ypeng12/quant-ai/resolve/main/src/execution/implementation_shortfall.py
- Command line
-
hf download hf://spaces/Ypeng12/quant-ai/src/execution/implementation_shortfall.py
-
curl -L -o implementation_shortfall.py https://huggingface.co/spaces/Ypeng12/quant-ai/resolve/main/src/execution/implementation_shortfall.py
2.2 kB
| import pandas as pd | |
| import numpy as np | |
| from typing import Dict, Any | |
| class TransactionCostModel: | |
| """ | |
| Simulates Transaction Costs and Slippage: | |
| - Base Fee: bps (default 2 bps) | |
| - Bid-Ask Spread & Slippage: bps (default 3 bps) -> Total Baseline Friction: 5 bps (0.05%) | |
| - Support for Sensitivity Matrices [2 bps, 5 bps, 10 bps, 15 bps] | |
| """ | |
| def __init__(self, cost_bps: float = 5.0, slippage_bps: float = 2.0): | |
| self.cost_bps = cost_bps | |
| self.slippage_bps = slippage_bps | |
| self.total_bps = cost_bps + slippage_bps | |
| def apply_cost_to_return(self, gross_return: float, turnover: float) -> float: | |
| """ | |
| Subtracts transaction costs from gross rebalance return: | |
| Net Return = Gross Return - Turnover * Total_BPS / 10000 | |
| """ | |
| cost = turnover * (self.total_bps / 10_000.0) | |
| return gross_return - cost | |
| class ImplementationShortfallDecomposer: | |
| """ | |
| Implementation Shortfall (Perold 1988): | |
| IS = side * (P_fill - P_decision) / P_decision + Fees | |
| Decomposed into: | |
| 1. Delay Cost: (P_submission - P_decision) / P_decision | |
| 2. Execution Cost: (P_fill - P_submission) / P_decision | |
| 3. Fee / Slippage Cost | |
| """ | |
| def __init__(self, fee_bps: float = 2.0): | |
| self.fee_bps = fee_bps | |
| def decompose( | |
| self, | |
| side: int, # +1 for Buy, -1 for Sell | |
| p_decision: float, | |
| p_submission: float, | |
| p_fill: float, | |
| quantity: float, | |
| ) -> Dict[str, float]: | |
| if p_decision <= 0: | |
| return {} | |
| delay_cost = side * (p_submission - p_decision) / p_decision | |
| execution_cost = side * (p_fill - p_submission) / p_decision | |
| fee_cost = self.fee_bps / 10_000.0 | |
| total_is = delay_cost + execution_cost + fee_cost | |
| return { | |
| "side": side, | |
| "quantity": quantity, | |
| "p_decision": p_decision, | |
| "p_submission": p_submission, | |
| "p_fill": p_fill, | |
| "delay_cost_bps": delay_cost * 10_000.0, | |
| "execution_cost_bps": execution_cost * 10_000.0, | |
| "fee_cost_bps": fee_cost * 10_000.0, | |
| "total_is_bps": total_is * 10_000.0, | |
| } | |