factor model

## Project description

This programme is built for back-testing factors.

## Dependencies

• python 3.5
• pandas 0.23.0
• numba 0.38.0
• empyrical 0.5.0
• data_box
• pickle
• multiprocessing
• joblib

## Basic definitions

1. v_t,s_t,c_t: total value, stock value and cash value at time t after trading
2. v^f_t,s^f_t,c^f_t: total value, stock value and cash value at time t before trading
3. ss,sv: suspended stock value and valid stock value
4. r_t: return at time t
5. cost_t: cost to trade at time t

Note: s,ss,sv are all vectors while others are numbers

## Equations

1. v_t = |s_t| + c_t
2. s^f_t = s_{t-1} * (1 + r_t) = ss^f_t + sv^f_t = ss_t + sv^f_t
3. ss_t <- suspend, s^f_t
4. c_{t-1} + |sv^f_t| = |sv_t| + c_t + cost_t ( where c_t, cost_t >= 0 )
5. cost_t =|sv_t - sv^f_t| * costRate
6. weight_t <- factor_{t-1},industry_t,suspend_t ( |weight_t| = 1 or 0 if there is no valid stocks or factors or industries)
7. define cost^f_t = (2|sv^f_t| + c_{t-1}) * costRate s.t. cost^f_t >= cost_t, which is greater than the maximum cost we may have during the trade
8. define available_value^f_t = c_{t-1} + |sv^f_t| - cost^f_t, which means the value ( = |sv_t| if weight_t != 0) we have in stocks after trading
9. let sv_t = weight_t * available_value^f_t s.t. c_t = c_{t-1} + |sv^f_t| - |sv_t| - cost_t >=0

Thus to update v_t, we would start with calculating s^f_t, ss, sv^f_t, then cost^f_t, available_value^f_t, then sv_t, cost_t and c_t, and finally v_t

## Data Box: pre-process

```from data_box import data_box
db=data_box()\
.calc_indweight()\
.set_lag(freq='d',day_lag=1)\
.align_data()
# freq can be 'd' or 'm', for detail please refer to db.set_lag doc.
```

Where price,ind,ind_weight,sus,factor0,factor1 are all dataframes with index as date (yyyymmdd,int) and column as tickers. You can save and load this data box object by db.save('path') and db.load('path'). You can find more in data_box project.

### Back Test

```from single_factor_model import run_back_test
```

single process

```Value,Turnover=run_back_test(data_box=db,back_end=None,n=5,weight_path=None,double_side_cost=0.003)
```

multi process

```Value,Turnover=run_back_test(data_box=db,back_end='loky',n=5,weight_path=None,verbose=50)
```

or

```with __name__=='__main__':
Value,Turnover=run_back_test(data_box=db,back_end='multiprocessing',n=5,weight_path=None)
```

To check detailed position of each portfolio each day, just assign weight_path.

### Summary and Plot

calculate return including long short portfolio(and reverse)

```from single_factor_model import calc_return
Return = calc_return(Value,Turnover,long_short,double_side_cost=0.003)
```

summary

```from single_factor_model import summary
S=summary(Return)
```

plot

```run_plot(Return,show=True)
```

## Project details 0.3.2

This version 0.3.0 0.3.0a0 pre-release 0.2.1 0.2.0 0.1.8 0.1.7 0.1.6 0.1.4 0.1.3 0.1.2 0.1.1 0.1.0 0.0.7 0.0.6 0.0.5 0.0.4 0.0.3 0.0.2