Source code for frds.measures.price_impact

import numpy as np


[docs] def simple_price_impact( price: np.ndarray, midpoint_later: np.ndarray, midpoint: np.ndarray, volume: np.ndarray, trade_direction: np.ndarray = None, pct_spread=True, ) -> float: """Simple Price Impact (dollar volume weighted) Args: price (np.ndarray): ``(N,)`` array of ``N`` trade prices midpoint_later (np.ndarray): ``(N,)`` array of ``N`` bid-ask midpoints some time (e.g., 5min) after corresponding trade midpoint (np.ndarray): ``(N,)`` array of ``N`` bid-ask midpoints at trade volume (np.ndarray): ``(N,)`` array of ``N`` trade sizes trade_direction (np.ndarray, optional): ``(N,)`` array of ``N`` trade directions. Defaults to None. If None, use equation :math:numref:`simple-price-impact` or :math:numref:`simple-price-impact-log`. If set, use equation :math:numref:`simple-price-impact-with-direction` or :math:numref:`simple-price-impact-log-with-direction`. pct_spread (bool, optional): whether to return percentage spread. Defaults to True. If False, return log spread. Returns: float: simple price impact """ midpoint_later = np.asarray(midpoint_later) midpoint = np.asarray(midpoint) volume = np.asarray(volume) assert midpoint_later.shape == midpoint.shape == volume.shape if not isinstance(trade_direction, np.ndarray): # No trade direction if pct_spread: spread = 2 * np.absolute(midpoint_later - midpoint) / midpoint * 100 else: spread = 2 * np.absolute(np.log(midpoint_later) - np.log(midpoint)) else: # Use trade direction assert midpoint.shape == trade_direction.shape if pct_spread: spread = 2 * trade_direction * (midpoint_later - midpoint) / midpoint * 100 else: spread = 2 * trade_direction * (np.log(midpoint_later) - np.log(midpoint)) dollar_volume = volume * price if all(dollar_volume == 0): return np.nanmean(spread) return np.average(spread, weights=dollar_volume)