Built a practical Multi-Factor Backtesting Framework from scratch based on Huatai Security's(One of China's largest sell side) financial engineering report. Steps include factor data collection and preprocessing, factor combination, portfolio optimization and risk return analysis.
Multifactor project

Description
This is a practical multi-factor backtesting framework from scratch based on Huatai Security's(one of China's largest sell side) financial engineering report, as a part of the quantitative finance research project development in ETC Investment Group. Steps include factor data collection and preprocessing, single factor testing, building return model, building risk model, and result analysis.Do not distribute for use without explicit consent from contributing members of ETC Quant.
Project environment
To set up the project, first install anaconda and github cli. (Currently only compatible with windows)- Open CMD/bash
cdto navtigate to desired folder location
git clone https://github.com/etccapital/MultiFactorto clone the lastest version of the repo
- (Linux/MacOS)
conda env create -f environment.ymlto download configure the all packages needed \
./makefile_win.bat "setup" to download configure the all packages needed
- Use
conda env listto list all conda packages available. Make sure environmentmultifactoris in the list
- Download
rq_crendential.jsonand save it to root project folder
- Convert target python files into jupyter notebooks. See "Version Control of .ipynb Files" section below.
- Open CMD/bash
- Use
conda activate multifactor
Workflow
- Download zipped price data and extract them to
.data/price
- Download factor data from ricequant with
datadownloadand_process.ipynb
- Or download zipped factor data and extract them to
.data/factor
Project structure
Use commandtree in command line to generate the following folder structure.
Whenever you change the folder structure, please update the following diagram and update the corresponding file to the OneDrive folder.
.
โโโ Data
โย ย โโโ factor
โย ย โย ย โโโ cashflow
โย ย โย ย โย ย โโโ cashflowpersharettm.h5
โย ย โย ย โย ย โโโ cashflowratio_ttm.h5
โย ย โย ย โโโ dividend
โย ย โย ย โโโ financial_quality
โย ย โย ย โย ย โโโ debttoassetratiottm.h5
โย ย โย ย โย ย โโโ fixedassetratio_ttm.h5
โย ย โย ย โย ย โโโ returnonequity_ttm.h5
โย ย โย ย โโโ growth
โย ย โย ย โย ย โโโ increvenuettm.h5
โย ย โย ย โโโ momentum
โย ย โย ย โโโ size
โย ย โย ย โย ย โโโ marketcap3.h5
โย ย โย ย โโโ technical
โย ย โย ย โโโ value
โย ย โย ย โย ย โโโ booktomarketratiottm.h5
โย ย โย ย โย ย โโโ ev_ttm.h5
โย ย โย ย โย ย โโโ pbratiottm.h5
โย ย โย ย โย ย โโโ pcfratiottm.h5
โย ย โย ย โย ย โโโ peratiottm.h5
โย ย โย ย โย ย โโโ pegratiottm.h5
โย ย โย ย โย ย โโโ psratiottm.h5
โย ย โย ย โโโ volatility
โย ย โโโ index_data
โย ย โย ย โโโ sh000300.csv
โย ย โโโ raw_data
โย ย โย ย โโโ dfbasicinfo.h5
โย ย โย ย โโโ industry_mapping.h5
โย ย โย ย โโโ is_st.h5
โย ย โย ย โโโ is_suspended.h5
โย ย โย ย โโโ listed_dates.h5
โย ย โย ย โโโ stock_names.h5
โย ย โย ย โโโ rebalancing_dates.h5
โย ย โย ย โโโ industrycodeto_names.xlsx
โย ย โโโ stock_data
โย ย โย ย โโโ sh600000.csv
โย ย โย ย ...
โย ย โย ย โโโ sz301039.csv
โโโ README.md
โโโ environment.yml
โโโ makefiles
โย ย โโโ makefilemacnotebooktopy.sh
โย ย โโโ makefilemacpytonotebook.sh
โย ย โโโ makefile_win.bat
โโโ not useful temporarily
โย ย โโโ Dataloader.py
โย ย โโโ Ricequant API.ipynb
โโโ notebook
โย ย โโโ Alphalens_new.ipynb
โย ย โโโ Alphalenssinglefactor_testing.ipynb
โย ย โโโ data_download.ipynb
โย ย โโโ datadownloadand_process.ipynb
โย ย โโโ factor_combination.ipynb
โย ย โโโ portfolio_optimization.ipynb
โย ย โโโ singlefactoranalysis.ipynb
โโโ rq_credential.json
โโโ scripted_notebook
โย ย โโโ Alphalens_new.py
โย ย โโโ Alphalenssinglefactor_testing.py
โย ย โโโ data_download.py
โย ย โโโ datadownloadand_process.py
โย ย โโโ factor_combination.py
โย ย โโโ portfolio_optimization.py
โย ย โโโ singlefactoranalysis.py
โโโ src
โโโ init.py
โโโ constants.py
โโโ dataloader.py
โโโ factor_combinator.py
โโโ portfolio_optimizer.py
โโโ preprocess.py
โโโ utils.py
Version Control of .ipynb Files
Currently, we have the following notebooks on our local laptops:datadownloadandprocess.ipynb Alphalenssinglefactortesting.ipynb
However, version control will be impossible if we directly push them to the repo in the form of .ipynb files. This is because jupyter notebooks are json files and cannot be displayed properly in github. As a result, we will use jupytext(pip install jupytext --upgrade) to convert between .ipynb and .py files, and store only .py files in the shared repo. Taking datadownloadandprocess.ipynb as an example, when you finish editing it on your local laptop, run jupytext --to py:percent datadownloadandprocess.ipynb in CMD and the changes will be updated to datadownloadandprocess.py. Then you can merge changes and resolve conflicts in datadownloadandprocess.py as in other python files. To fetch changes from datadownloadandprocess.py to datadownloadandprocess.ipynb, run jupytext --to notebook --update datadownloadand_process.py in CMD. Note that the --update option is essential as it will only update the code and comments in the .ipynb file while preserving graphs and outputs. \
To save your time, we have made the following shell scripts/makefiles:
(On Windows) \ ./makefiles/makefilewin.bat "scriptto_notebook" to covert scripts to notebooks \ ./makefiles/makefilewin.bat "notebookto_script" to covert notebooks to scripts
(On Mac) \ sh ./makefiles/makefilemacpytonotebook.sh to covert scripts to notebooks \ sh ./makefiles/makefilemacnotebooktopy.sh to covert notebooks to scripts
Note: make sure to update the makefile script if more notebooks are added