Add VVIX regime filter for backtesting options

This commit is contained in:
moshferatu 2024-05-12 05:07:29 -07:00
parent 3926429751
commit a804dcc7b1
2 changed files with 57 additions and 1 deletions

View File

@ -1,2 +1,3 @@
from .backtest_filter import BacktestFilter
from .volatility_regime_filter import VolatilityRegimeFilter
from .volatility_regime_filter import VolatilityRegimeFilter
from .vvix_regime_filter import VVIXRegimeFilter

View File

@ -0,0 +1,55 @@
from datetime import datetime, timedelta
from dotenv import load_dotenv
from os import getenv
from pandas import concat, DataFrame, Series
from database.ohlc import ohlc
from .backtest_filter import BacktestFilter
load_dotenv()
class VVIXRegimeFilter(BacktestFilter):
def __init__(self):
self.backtest_filter = self.filter()
def filter(self) -> DataFrame:
data_start_date = datetime.strptime(getenv('OPTION_DATA_START_DATE'), '%Y-%m-%d')
now = datetime.now()
vvix_data = ohlc(
symbol = 'VVIX.XO',
timeframe = '1d',
start_date = data_start_date - timedelta(weeks = 52),
end_date = now
)
vvix_data.rename(columns = {'Timestamp': 'Date'}, inplace = True)
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Filtering is based on the previous day's close, so the current date can be included even though the
data may not be availble yet.
This allows for utilizing the filter in live trading to decide whether to trade prior to market open.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
vvix_data = concat([
vvix_data,
DataFrame({
'Date': [datetime.combine(now, datetime.min.time())],
'Open': [0.0],
'High': [0.0],
'Low': [0.0],
'Close': [0.0],
'Volume': [0.0]
})],
ignore_index = True
)
percent_rank = lambda x: Series(x).rank(pct = True).iloc[-1]
vvix_data['Percent Rank'] = vvix_data['Close'].shift(1).rolling(window = 252).apply(percent_rank)
filtered_data = vvix_data[vvix_data['Date'] >= data_start_date].copy()
filtered_data['Trade Allowed'] = filtered_data['Percent Rank'] < 0.50
filtered_data = filtered_data[['Date', 'Trade Allowed']].reset_index(drop = True)
return filtered_data