make it a package, get it working with my data

This commit is contained in:
wassname
2022-07-04 13:19:01 +08:00
parent 46efd30e40
commit 6764b03b04
5 changed files with 2274 additions and 2 deletions
+2 -2
View File
@@ -97,8 +97,8 @@ class Backtest:
if sma_days:
self.stocks_data.sma(sma_days)
dates = pd.DataFrame(self.options_data._data[['quotedate',
'volume']]).drop_duplicates('quotedate').set_index('quotedate')
dates = pd.DataFrame(self.options_data._data[['date',
'volume']]).drop_duplicates('date').set_index('date')
rebalancing_days = pd.to_datetime(
dates.groupby(pd.Grouper(freq=str(rebalance_freq) +
'BMS')).apply(lambda x: x.index.min()).values) if rebalance_freq else []
+1
View File
@@ -2,5 +2,6 @@ from .schema import Schema
from .historical_options_data import HistoricalOptionsData
from .tiingo_data import TiingoData
from .option_metrics_data import OptionMetricsData
__all__ = ['Schema', 'HistoricalOptionsData', 'TiingoData']
@@ -0,0 +1,111 @@
import pandas as pd
import os
from .schema import Schema
from bscsi_data.optm_lz.load import load_for_tickers
class OptionMetricsData:
"""Historical Options Data container class."""
def __init__(self, tickers, schema=None, **params):
if schema is None:
self.schema = OptionMetricsData.default_schema()
self._data = load_for_tickers(tickers).reset_index()
# self._data['date']=self._data.date.dt.tz_localize('utc')
# self._data['exdate']=self._data['exdate'].dt.tz_localize('utc')
# print(self._data.head(5))
columns = self._data.columns
for _key, col in self.schema:
assert col in columns, f"missing '{col}' in data"
# assert all((col in columns for _key, col in self.schema))
date_col = self.schema['date']
expiration_col = self.schema['expiration']
self._data['dte'] = (self._data[expiration_col] - self._data[date_col]).dt.days
self.schema.update({'dte': 'dte'})
self.start_date = self._data[date_col].min()
self.end_date = self._data[date_col].max()
def apply_filter(self, f):
"""Apply Filter `f` to the data. Returns a `pd.DataFrame` with the filtered rows."""
return self._data.query(f.query)
def iter_dates(self):
"""Returns `pd.DataFrameGroupBy` that groups contracts by date"""
return self._data.groupby(self.schema['date'])
def iter_months(self):
"""Returns `pd.DataFrameGroupBy` that groups contracts by month"""
date_col = self.schema['date']
iterator = self._data.groupby(pd.Grouper(
key=date_col,
freq="MS")).apply(lambda g: g[g[date_col] == g[date_col].min()]).reset_index(drop=True).groupby(date_col)
return iterator
def __getattr__(self, attr):
"""Pass method invocation to `self._data`"""
method = getattr(self._data, attr)
if hasattr(method, '__call__'):
def df_method(*args, **kwargs):
return method(*args, **kwargs)
return df_method
else:
return method
def __getitem__(self, item):
if isinstance(item, pd.Series):
return self._data[item]
else:
key = self.schema[item]
return self._data[key]
def __setitem__(self, key, value):
self._data[key] = value
if key not in self.schema:
self.schema.update({key: key})
def __len__(self):
return len(self._data)
def __repr__(self):
return self._data.__repr__()
def default_schema():
"""Returns default schema for Historical Options Data"""
schema = Schema.options()
schema.update({
'underlying': 'secid',
'underlying_last': 'forward_price', #last price of underlying
'date': 'date',
'contract': 'optionid',
'type': 'cp_flag',
'expiration': 'exdate',
'strike': 'strike_price',
'bid': 'best_bid',
'ask': 'best_offer',
'volume': 'volume',
'open_interest': 'open_interest',
'last': 'forward_price',
'impliedvol': 'impl_volatility',
'vega': 'vega',
'delta': 'delta',
'gamma': 'gamma',
'theta': 'theta',
})
return schema
# Index(['symbol', 'symbol_flag', 'exdate', 'last_date', 'cp_flag',
# 'strike_price', 'best_bid', 'best_offer', 'volume', 'open_interest',
# 'impl_volatility', 'delta', 'gamma', 'vega', 'theta', 'optionid',
# 'cfadj', 'am_settlement', 'contract_size', 'ss_flag', 'forward_price',
# 'expiry_indicator', 'root', 'suffix', 'secid'],
# dtype='object')
# Schema([Field(name='underlying', mapping='underlying'), Field(name='underlying_last', mapping='underlying_last'), Field(name='date', mapping='quotedate'), Field(name='contract', mapping='optionroot'), Field(name='type', mapping='type'), Field(name='expiration', mapping='expiration'), Field(name='strike', mapping='strike'), Field(name='bid', mapping='bid'), Field(name='ask', mapping='ask'), Field(name='volume', mapping='volume'), Field(name='open_interest', mapping='openinterest'), Field(name='last', mapping='last'), Field(name='impliedvol', mapping='impliedvol'), Field(name='delta', mapping='delta'), Field(name='gamma', mapping='gamma'), Field(name='theta', mapping='theta'), Field(name='vega', mapping='vega')])
File diff suppressed because one or more lines are too long
+10
View File
@@ -0,0 +1,10 @@
from setuptools import find_packages, setup
setup(
name='backtester',
packages=find_packages(),
version='0.1.0',
description='Backtesting moris idea of buying calls 5 qs before earnings, and selling them 1 week before. Apparently 30% annual return',
author='wassname',
license='proprietary',
)