Skip to content

Commit

Permalink
Added cumulative additive flag
Browse files Browse the repository at this point in the history
  • Loading branch information
saeedamen committed Nov 11, 2020
1 parent 47037a1 commit 05aea71
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 12 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ In finmarketpy/examples you will find several examples, including some simple tr

# finmarketpy log

* 11 Nov 2020
* Added cumulative additive index flag for backtests
* 20 Oct 2020
* Fixed missing GBP depo tickers
* Fixed startup on newer MacOS
Expand Down
38 changes: 27 additions & 11 deletions finmarketpy/backtest/backtestengine.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,23 +446,33 @@ def calculate_trading_PnL(self, br, asset_a_df, signal_df, contract_value_df, ru
self._portfolio_cum = resultsC.get()

else:
# calculate return statistics of the each asset/signal after signal leverage (but before portfolio level constraints)
# Calculate return statistics of the each asset/signal after signal leverage (but before portfolio level constraints)
# self._ret_stats_pnl.calculate_ret_stats()

# calculate return statistics of the each asset/signal after signal leverage AND after portfolio level constraints
# Calculate return statistics of the each asset/signal after signal leverage AND after portfolio level constraints
# self._ret_stats_pnl_components.calculate_ret_stats()

# calculate return statistics of the final portfolio
# Calculate return statistics of the final portfolio
# self._ret_stats_portfolio.calculate_ret_stats()

# calculate individual signals cumulative P&L after signal leverage but before portfolio level constraints
self._pnl_cum = calculations.create_mult_index(self._pnl)
# Calculate final portfolio cumulative P&L
if br.cum_index == 'mult':
# Calculate individual signals cumulative P&L after signal leverage but before portfolio level constraints
self._pnl_cum = calculations.create_mult_index(self._pnl)

# calculate individual signals cumulative P&L after signal leverage AND after portfolio level constraints
self._components_pnl_cum = calculations.create_mult_index(self._components_pnl)
# Calculate individual signals cumulative P&L after signal leverage AND after portfolio level constraints
self._components_pnl_cum = calculations.create_mult_index(self._components_pnl)

# calculate final portfolio cumulative P&L
self._portfolio_cum = calculations.create_mult_index(self._portfolio) # portfolio cumulative P&L
self._portfolio_cum = calculations.create_mult_index(self._portfolio) # portfolio cumulative P&L

elif br.cum_index == 'add':
# Calculate individual signals cumulative P&L after signal leverage but before portfolio level constraints
self._pnl_cum = calculations.create_add_index(self._pnl)

# Calculate individual signals cumulative P&L after signal leverage AND after portfolio level constraints
self._components_pnl_cum = calculations.create_add_index(self._components_pnl)

self._portfolio_cum = calculations.create_add_index(self._portfolio) # portfolio cumulative P&L

logger.info("Completed cumulative index calculations")

Expand Down Expand Up @@ -1329,7 +1339,10 @@ def compare_strategy_vs_benchmark(self, br, strategy_df, benchmark_df):
strategy_benchmark_df = filter.filter_time_series_by_date(br.plot_start, br.finish_date,
strategy_benchmark_df)

strategy_benchmark_df = calculations.create_mult_index_from_prices(strategy_benchmark_df)
if br.cum_index == 'mult':
strategy_benchmark_df = calculations.create_mult_index_from_prices(strategy_benchmark_df)
elif br.cum_index == 'add':
strategy_benchmark_df = calculations.create_add_index_from_prices(strategy_benchmark_df)

self._strategy_benchmark_pnl = benchmark_df
self._strategy_benchmark_pnl_ret_stats = ret_stats
Expand Down Expand Up @@ -1957,7 +1970,10 @@ def calculate_vol_adjusted_index_from_prices(self, prices_df, br):

returns_df, leverage_df = self.calculate_vol_adjusted_returns(prices_df, br, returns=False)

return calculations.create_mult_index(returns_df)
if br.cum_index == 'mult':
return calculations.create_mult_index(returns_df)
elif br.cum_index == 'add':
return calculations.create_add_index(returns_df)

def calculate_vol_adjusted_returns(self, returns_df, br, returns=True):
"""Adjusts returns for a vol target
Expand Down
13 changes: 13 additions & 0 deletions finmarketpy/backtest/backtestrequest.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ def __init__(self):
# annualization factor for return stats (and should we resample data first before calculating it?)
self.__ann_factor = 252
self.__resample_ann_factor = None

# how do we create a cumulative index of strategy returns
# either multiplicative starting a 100
# or additive starting at 0
self.__cum_index = 'mult' # 'mult' or 'add'

##### properties for output of the backtest
@property
Expand Down Expand Up @@ -376,3 +381,11 @@ def resample_ann_factor(self):
@resample_ann_factor.setter
def resample_ann_factor(self, resample_ann_factor):
self.__resample_ann_factor = resample_ann_factor

@property
def cum_index(self):
return self.__cum_index

@cum_index.setter
def cum_index(self, cum_index):
self.__cum_index = cum_index
7 changes: 6 additions & 1 deletion finmarketpy/economics/quickchart.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def __init__(self, engine='plotly', data_source='bloomberg', market_data_generat
def plot_chart(self, tickers=None, tickers_rhs=None, start_date=None, finish_date=None,
chart_file=None, chart_type='line', title='',
fields={'close' : 'PX_LAST'}, freq='daily', source='Web', brand_label='Cuemacro', display_brand_label=True,
reindex=False, yoy=False, plotly_plot_mode='offline_png',
reindex=False, additive_index=False, yoy=False, plotly_plot_mode='offline_png',
quandl_api_key=dataconstants.quandl_api_key,
fred_api_key=dataconstants.fred_api_key,
alpha_vantage_api_key=dataconstants.alpha_vantage_api_key, df=None):
Expand Down Expand Up @@ -98,6 +98,11 @@ def plot_chart(self, tickers=None, tickers_rhs=None, start_date=None, finish_dat

style.y_title = 'Reindexed from 100'

if additive_index:
df = (df - df.shift(1)).cumsum()

style.y_title = 'Additive changes from 0'

if yoy:
if freq == 'daily':
obs_in_year = 252
Expand Down
3 changes: 3 additions & 0 deletions finmarketpy_examples/tradingmodelfxtrend_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ def load_parameters(self, br = None):
# Tech params
br.tech_params.sma_period = 200

# To make additive indices
# br.cum_index = 'add'

return br

def load_assets(self, br = None):
Expand Down

0 comments on commit 05aea71

Please sign in to comment.