In [1]:
%matplotlib inline
import os
import pandas as pd
import numpy as np
from matplotlib import rc
from matplotlib import pyplot as plt
from PyFin.api import makeSchedule
from alphamind.api import *
from alphamind.analysis.quantileanalysis import er_quantile_analysis

rc('font', **{'family': 'Microsoft YaHei', 'size': 10})
rc('mathtext', **{'default': 'regular'})
rc('legend', **{'frameon': False})

1. 数据准备


  • 股票池:中证800
  • 因子:ETOP
  • 调仓频率:5个交易日
  • 起始日:2010年1月1日
  • 终止日:2019年1月31日
  • 分位数:5

In [14]:
engine = SqlEngine(os.environ['DB_URI'])
universe = Universe('zz800')
factor = 'ROE'
freq = '5b'
start_date = '2010-01-01'
end_date = '2019-01-31'
n_bins = 5
neutralized_styles = industry_styles # risk_styles + industry_styles

dates = makeSchedule(start_date, end_date, freq, 'china.sse')
horizon = map_freq(freq)

In [15]:
%%time
factor_data = engine.fetch_factor_range(universe, factor, dates=dates)
risk_cov, risk_factors = engine.fetch_risk_model_range(universe, dates=dates)
return_data = engine.fetch_dx_return_range(universe, dates=dates, horizon=horizon)
total_data = pd.merge(factor_data, risk_factors, on=['trade_date', 'code'])
total_data = pd.merge(total_data, return_data, on=['trade_date', 'code']).dropna()


Wall time: 4min 25s

2. 分位数群组收益比较



In [16]:
neutralized_factors = neutralize(total_data[neutralized_styles].values.astype(float),
                                 total_data['ROE'].values,
                                 groups=total_data['trade_date'])
total_data['neutralized_factors'] = neutralized_factors

In [17]:
%%time

df = pd.DataFrame(columns=['q' + str(i) for i in range(1, n_bins+1)])

grouped = total_data.groupby('trade_date')
for k, g in grouped:
    er = g['neutralized_factors'].values
    dx_return = g['dx'].values
    res = er_quantile_analysis(er, n_bins=n_bins, dx_return=dx_return, de_trend=True)
    df.loc[k, :] = res


Wall time: 1.47 s

In [18]:
df.cumsum().plot(figsize=(14, 7))


Out[18]:
<matplotlib.axes._subplots.AxesSubplot at 0x21dce779a58>

In [25]:
ret_yearly = df.groupby(df.index.year).sum()
ret_yearly.plot(kind='bar', figsize=(14, 7))


Out[25]:
<matplotlib.axes._subplots.AxesSubplot at 0x21ddceb3a20>

In [30]:
(df.mean() * 50).plot(kind='bar', figsize=(14, 7), color='orange')


Out[30]:
<matplotlib.axes._subplots.AxesSubplot at 0x21dc96276d8>

In [ ]: