Skip to content

Commit

Permalink
fix #1009
Browse files Browse the repository at this point in the history
  • Loading branch information
rob committed Jul 4, 2023
1 parent 5eef3bf commit 1c5017e
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 76 deletions.
17 changes: 17 additions & 0 deletions sysobjects/instruments.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,23 @@ def percentage_cost(self):
def value_of_pertrade_commission(self):
return self._value_of_pertrade_commission

def calculate_sr_cost(
self,
block_price_multiplier: float,
price: float,
ann_stdev_price_units: float,
blocks_traded: float = 1.0,
) -> float:
cost_instrument_currency = self.calculate_cost_instrument_currency(
blocks_traded=blocks_traded,
block_price_multiplier=block_price_multiplier,
price=price,
)

ann_stdev_instrument_currency = ann_stdev_price_units * block_price_multiplier

return cost_instrument_currency / ann_stdev_instrument_currency

def calculate_cost_percentage_terms(
self, blocks_traded: float, block_price_multiplier: float, price: float
) -> float:
Expand Down
20 changes: 20 additions & 0 deletions sysproduction/data/risk.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,26 @@ def get_perc_of_strategy_capital_for_instrument_per_contract(
return exposure_per_contract / capital_base_fx


def get_current_ann_stdev_of_prices(data, instrument_code):
try:
current_stdev_ann_price_units = get_ann_ts_stdev_of_prices(
data=data, instrument_code=instrument_code
)[-1]
except:
## can happen for brand new instruments not properly loaded
return np.nan

return current_stdev_ann_price_units


def get_ann_ts_stdev_of_prices(data, instrument_code):
stdev_ann_price_units = get_daily_ts_stdev_of_prices(
data=data, instrument_code=instrument_code
)

return stdev_ann_price_units * ROOT_BDAYS_INYEAR


def get_daily_ts_stdev_of_prices(data, instrument_code):
dailyreturns = get_daily_returns_for_risk(data, instrument_code)
volconfig = copy(vol_config(data))
Expand Down
56 changes: 19 additions & 37 deletions sysproduction/reporting/data/costs.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
get_recent_broker_orders,
create_raw_slippage_df,
)
from sysproduction.data.risk import get_current_annualised_perc_stdev_for_instrument
from sysproduction.data.risk import get_current_ann_stdev_of_prices


def get_current_configured_spread_cost(data) -> pd.Series:
Expand All @@ -35,34 +35,8 @@ def get_SR_cost_calculation_for_instrument(
include_spread: bool = True,
):

percentage_cost = get_percentage_cost_for_instrument(
data,
instrument_code,
include_spread=include_spread,
include_commission=include_commission,
)
avg_annual_vol_perc = get_percentage_ann_stdev(data, instrument_code)

# cost per round trip
SR_cost = 2.0 * percentage_cost / avg_annual_vol_perc

return dict(
percentage_cost=percentage_cost,
avg_annual_vol_perc=avg_annual_vol_perc,
SR_cost=SR_cost,
)


def get_percentage_cost_for_instrument(
data: dataBlob,
instrument_code: str,
include_spread: bool = True,
include_commission: bool = True,
):
diag_instruments = diagInstruments(data)
costs_object = diag_instruments.get_cost_object(instrument_code)
if not include_spread and not include_commission:
return 0
if not include_spread:
costs_object = costs_object.commission_only()

Expand All @@ -72,23 +46,31 @@ def get_percentage_cost_for_instrument(
blocks_traded = 1
block_price_multiplier = get_block_size(data, instrument_code)
price = recent_average_price(data, instrument_code)
percentage_cost = costs_object.calculate_cost_percentage_terms(

stdev_ann_price_units = get_current_ann_stdev_of_prices(
data=data, instrument_code=instrument_code
)

SR_cost = costs_object.calculate_sr_cost(
blocks_traded=blocks_traded,
block_price_multiplier=block_price_multiplier,
ann_stdev_price_units=stdev_ann_price_units,
price=price,
)

return percentage_cost

percentage_cost = costs_object.calculate_cost_percentage_terms(
blocks_traded=blocks_traded,
block_price_multiplier=block_price_multiplier,
price=price,
)

def get_percentage_ann_stdev(data, instrument_code):
try:
perc = get_current_annualised_perc_stdev_for_instrument(data, instrument_code)
except:
## can happen for brand new instruments not properly loaded
return np.nan
avg_annual_vol_perc = stdev_ann_price_units / price

return perc
return dict(
percentage_cost=percentage_cost,
avg_annual_vol_perc=avg_annual_vol_perc,
SR_cost=SR_cost,
)


def adjust_df_costs_show_ticks(
Expand Down
62 changes: 23 additions & 39 deletions systems/accounts/account_costs.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,38 +315,40 @@ def get_SR_cost_per_trade_for_instrument(self, instrument_code: str) -> float:
0.0065584086244069775
"""

cost_in_percentage_terms = self.get_SR_cost_per_trade_for_instrument_percentage(
instrument_code
)
avg_annual_vol_perc = self._recent_average_annual_perc_vol(instrument_code)

# cost per round trip so double
SR_cost = 2.0 * cost_in_percentage_terms / avg_annual_vol_perc

return SR_cost

@diagnostic()
def get_SR_cost_per_trade_for_instrument_percentage(
self, instrument_code: str
) -> float:
raw_costs = self.get_raw_cost_data(instrument_code)
block_price_multiplier = self.get_value_of_block_price_move(instrument_code)
average_price = self._recent_average_price(instrument_code)
notional_blocks_traded = 1
average_price = self._recent_average_price(instrument_code)
ann_stdev_price_units = self._recent_average_annual_price_vol(instrument_code)

cost_in_percentage_terms = raw_costs.calculate_cost_percentage_terms(
blocks_traded=notional_blocks_traded,
SR_cost = raw_costs.calculate_sr_cost(
block_price_multiplier=block_price_multiplier,
ann_stdev_price_units=ann_stdev_price_units,
blocks_traded=notional_blocks_traded,
price=average_price,
)

return cost_in_percentage_terms
return SR_cost

@diagnostic()
def _recent_average_annual_price_vol(self, instrument_code: str) -> float:
average_vol = self._recent_average_daily_vol(instrument_code)

avg_annual_vol = average_vol * ROOT_BDAYS_INYEAR

return avg_annual_vol

@diagnostic()
def _recent_average_daily_vol(self, instrument_code: str) -> float:
daily_vol = self.get_daily_returns_volatility(instrument_code)
start_date = self._date_one_year_before_end_of_price_index(instrument_code)
average_vol = float(daily_vol[start_date:].mean())

return average_vol

@diagnostic()
def _recent_average_price(self, instrument_code: str) -> float:
daily_price = self.get_instrument_prices_for_position_or_forecast(
instrument_code
)
daily_price = self.get_daily_prices(instrument_code)
start_date = self._date_one_year_before_end_of_price_index(instrument_code)
average_price = float(daily_price[start_date:].mean())

Expand All @@ -363,24 +365,6 @@ def _date_one_year_before_end_of_price_index(self, instrument_code: str):

return start_date

@diagnostic()
def _recent_average_annual_perc_vol(self, instrument_code: str) -> float:
average_vol = self._recent_average_daily_vol(instrument_code)

avg_annual_vol = average_vol * ROOT_BDAYS_INYEAR
average_price = self._recent_average_price(instrument_code)
avg_annual_vol_perc = avg_annual_vol / average_price

return avg_annual_vol_perc

@diagnostic()
def _recent_average_daily_vol(self, instrument_code: str) -> float:
daily_vol = self.get_daily_returns_volatility(instrument_code)
start_date = self._date_one_year_before_end_of_price_index(instrument_code)
average_vol = float(daily_vol[start_date:].mean())

return average_vol

@property
def use_SR_costs(self) -> bool:
return str2Bool(self.config.use_SR_costs)

0 comments on commit 1c5017e

Please sign in to comment.