Version 0.1.0 Quantitative Analysis Framework
Overview of Created Modules
yggdrasil.py
Contains the class Yggdrasil, which is the root of other classes and modules; it creates an
instance of a strategy which acts on a set of stocks. Combines the classes StockAnalyzer and
StrategyHelper (see below).
market_analy.py
Contains a detailed retrieval method which obtains either live data or
previously stored personal data given a set of parameters
useful_methods.py
Module of helper functions which helps display code and
results easier and assists in both time series and results analysis
strategy_analy .py
Contains the class StockAnalyzer which defines factors to use in classification of provided assets.
strategy_helper.py
Contains class StrategyHelper which creates an instance of a
working strategy.
It contains no classification parameters
but only the strategy logic
test_live_helper.py
Runs the automated trading agent based on the tested strategy logic of
the other modules.
yggdrasil.py and strategy_helper.py will be explained in this and the next part while the rest are on GitHub.
Module: yggdrasil.py
- Contains the class Yggdrasil
- This is the root of all my strategies and analysis. Creates a general
instance of a test.
- Instance variables:
stock_universe: StockUniverse object which contains the list of stocks that will be used in this test
cur_strat: StrategyHelper object which sets and executes the basic framework of the given strategy in this test
strat_list: List of available executable strategies; mostly for convenience.
analysis: Various aspects of the stock list and the method being used; mostly for convenience
title: Defines the various aspects of the strategy being used; mostly for convenience
- Constructor
__init__(self, freq, strategy_,custom,shift_= 0, num_points = 500, stock_list = None)
- Creates an instance of a test which is made of a strategy and a list of stocks. Executes this test upon instantiation
- Parameters:
freq: the frequency of the strategy being used
strategy_: the type of strategy being used
custom: the type being used, if custom or live
shift: how much the data is shifted in its extraction. Measured in days regardless of the units of freq. Default value of 0.
num_points: number of data points in the extracted data. Note that this does not always return the exact number passed,but has a minimal error range in most cases ( ± 10 ). Default value is 500.
stock_list: the list of stocks the strategy as defined by the previous parameters will act on
- Instance methods:
__set_title(self): Private method called upon instantiation which sets the title of the strategy if needed
- Example: Saves the results of an example test run in a JSON file.
- The set of parameters is defined first and then the strategy is tested upon a list of various stocks. In the given example, the set of parameters is the shift of the data and the parameters of the strategy being used, which is Mean Reversion in this case defined by two metrics.
- These are the size of the rolling data used to compute metrics like the mean, and the cutoff z-score used to enter/exit the strategy. Everything else is held constant.
- Note that in this example, I'm currently in the process of creating viable classes for stock classification, meaning that each allocation of stocks being tested the last parameter is merely just each individual stock only. The classification in the example given is simply that the number of completed trades is above 30 in the given data set and the profit is positive.
import useful_methods
from market_analy import full_stocks
from strategy_analy import StockAnalyzer
from strategy_helper import StrategyHelper
class Yggdrasil :
def __init__(self, freq, strategy_, custom, shift_= 0, num_points= 500, stock_list=None):
self.strat_list=[]
self.cur_strat=StrategyHelper(freq, strategy_, custom=custom, shift=shift_, num_points=num_points)
self.stock_universe=StockAnalyzer(stock_list, self.cur_strat )
self.cur_strat.run_method(stock_list)
self.analysis=None
self.title=self.__set_title()
def __set_title(self):
title= ('freq: ' + self.cur_strat.freq + '_ ' + 'num of data points: '+ str(self.cur_strat.num_points)+
'_custom: '+ str(self.cur_strat.custom) + '_ shift: ' + str(self.cur_strat.shift)
'_start_date: '+ str (self.cur_strat.start) + '_end_date: ' + str (self.cur_strat.end)
+ '_strategy: ' + str(self.cur_strat.strategy) + ' ')
return title
# Generates the various parameters which can be tested
para_test= []
for shift in range (1):
for roll in range (10,21, 5):
for cutoff in range (11,13, 1):
for stock in full_stocks [0:100]:
para_test.append([stock , shift , roll , cutoff/ 10])
#Example which run the tests for various combinations of the parameters. Only two full stock iterations are ran below for brevity.
stock_pass_test= []
stock_pass_condition= False
for x in para_test:
strategy= ['Mean Rev']+ x [2:4]
ygg= Yggdrasil ('5m' , strategy , True , shift_=x[1], num_points= 250, stock_list= [x[0]])
# Condition for stock classification to filter the backtests
results= [ygg.cur_strat.results[x] for x in ['Profit', 'Number of Completed Trades']]
if results [0] > 0 and results [1] > 30 :
stock_pass_test.append(ygg.cur_strat.get_params())
# Data from all the tests is stored in a JSON file for easy viewing and extraction
with open ('example_data.json', 'w' ) as pdf:
json.dump(stock_pass_test, pdf, indent= 2)