成交量类指标
成交量指标主要用于衡量金融证券的价格变动幅度和速度,可以帮助投资者理解市场的稳定性和可能的风险。
本文介绍以下几个技术指标:
累计派发指标(AD)、能量潮(OBV)、资金流量指标(MFI)、简易波动指标(EOM)、成交量均线(MAAMT)、强力指数(FI)
本系列中的各项指标都可以通过调用 MyTT 库来实现。获取源码后台回复'32’。
1 默认参数
计算净值,绘制净值曲线
计算:夏普比率、年化收益、年化超额、年化波动、持仓胜率、最大回撤
技术指标 | 默认参数 | 信号规则 |
---|
AD | N1=3,N2=10 | 当 ADOSC>0 且收盘价在 90 日均线上方,产生买入信号; 当 ADOSC<0 且收盘价在 90 日均线下方,产生卖出信号。 |
OBV | N1=10,N2=20 | 当 OBV_HISTOGRAM 大于 0 时,产生买入信号; 当 OBV_HISTOGRAM 小于 0 时, 产生卖出信号。 |
MFI | N1=14,H=80,L=100-H | MFI 掉头向上突破20,买入信号;MFI掉头向下突破80,卖出信号 |
EOM | N1=20 | 当 EOM 大于 0 时产生买入信号,当 EOM<0 时,产生卖出信号 |
MAAMT | N1=30 | 当成交量短期均线上穿长期均线,产生买入信号; 成交量短期均线下穿上长期均 线,产生卖出信号。 |
FI | N1=13,N2=0 | 当 FI>0,市场多头强劲,产生买入信号; 当 FI<0 时,市场空头强劲,产生卖出信号。 |
benchmarks_dict = {'399006':'创业板指数'
,'399300':'沪深300'
,'399303':'国证2000'
,'399852':'中证1000'
,'399905':'中证500'}
benchmark = '399006'
benchmark_cn = benchmarks_dict[benchmark]
# 趋势策略指标
trend_following_strategys = ['SMA','EMA','KAMA','MACD','ADX','DPO']
# 动量策略指标
momentum_indicator_strategys = ['MOM','BIAS','RSI','ROC','KDJ','WR','CCI','CMO','UO','TRIX']
# 波动类指标 Volatility Indicators
volatility_indicator_strategys = ['ATR','BOLL','DC','ACCBANDS','MASSI','RVI','UDVD']
# Volume Indicators(交易量指标)
volume_indicator_strategys = ['AD','OBV','MFI','EOM','MAAMT','FI']
## 遍历多个策略,返回rtn、sharp
strategy_Parameters_dict = {
'AD' : {'N1':20,'N2':20}# N1 ,N2 = 120,20
,'OBV' : {'N1':20,'N2':30} # N1,N2 = 120,120
,'MFI': {'N1':20,'N2':0} # N1 =120,N2=0
,'EOM':{'N1':40,'N2':0} # N1 ,N2 = 120,0
,'MAAMT':{'N1':20,'N2':20}# N1 ,N2 = 120,120
,'FI':{'N1':30,'N2':0}# N1 = 90
#,'UDVD':{'N1':20,'N2':0}# N1 = 90
}
# 获取行情数据
df = techInd.getData('./data/{}-daily.csv'.format(benchmark)).head(300)
base_df = df[['open','close','high','low','vol']].copy()
# 计算中国节假日
holidays_china_list = techInd.holidays_china(df)
strategys = volume_indicator_strategys
strategy_name = 'FI'
## benckmark
benckmark_rtn_df = llstats.simple_rtns(df[['close']])
benckmark_rtn_df = benckmark_rtn_df.rename(columns={'close':benchmark})
# 计算策略指标、交易信号
strategy_df,isMainPlotly,signal_df = tiStrategy.selectStrategy(
strategy_name,
base_df)
K线图
title_text = '{}({})'.format(benchmark_cn,benchmark)
tiPlotly.plotly_K(base_df
,strategy_df
,signal_df
,isMainPlotly
,holidays_china_list
,title_text)
png# 回测
tmp_result_df = tiStrategy.backtest(base_df,signal_df)
result_df = tmp_result_df[['capital']]
signal_df = tmp_result_df[['signal']]
## 计算收益率
stock_rtn_df = llstats.simple_rtns(result_df[['capital']])
stock_rtn_df = stock_rtn_df.rename(columns={'capital':strategy_name})
# 根据singnal 计算 B-S 对
signal_B_df = pd.DataFrame()
signal_B_df = signal_df[signal_df['signal'] == 1].reset_index()
signal_B_df = signal_B_df.rename(columns={'datetime':'B_Date','signal':'B'})
signal_S_df = pd.DataFrame()
signal_S_df = signal_df[signal_df['signal'] == -1].reset_index()
signal_S_df = signal_S_df.rename(columns={'datetime':'S_Date','signal':'S'})
signal_bs_df = pd.concat([signal_B_df,signal_S_df],axis=1).loc[:,['B_Date','S_Date']]
signal_bs_df = signal_bs_df.dropna().apply(lambda x: x.dt.strftime('%Y-%m-%d'))
signal_bs_list = signal_bs_df.values
净值趋势图
单个技术指标净值趋势图
# 绘制净值趋势图
title_text = '{}({})-{}'.format(benchmark_cn,benchmark,strategy_name)
tiPlotly.plotly_netVal(stock_rtn_df
,benckmark_rtn_df
,holidays_china_list
,title_text)
png绩效评估
计算:夏普比率、年化收益、年化超额、年化波动、持仓胜率、最大回撤
.1 单技术指标绩效评估
t = tiStrategy.cal_Strategy_Performance(stock_rtn_df,benckmark_rtn_df).T
t = t.rename(columns={'sharp':'夏普比率',
'annual_rtn':'年化收益率',
'annual_vol':'年化波动率',
'annual_excess':'年化超额',
'max_drawdown':'最大回撤'})
## 胜率
# 胜率 = 盈利的所有次数/总交易场次
win = 0
for i in signal_bs_list:
_buy = result_df.loc[i[0]].capital
_sell = result_df.loc[i[1]].capital
if _sell - _buy > 0 :
win = win + 1
#print('{} - {} = {}'.format(_buy,_sell,_buy-_sell))
if len(signal_bs_list) > 0:
win_rate = win / len(signal_bs_list)
else:
win_rate = 0
t['胜率'] = win_rate
t = t.applymap(lambda x:format(x,'.2f'))
t['买卖方向'] = '买入'
t['次数'] = len(signal_bs_list)
t = t[['买卖方向','次数','夏普比率','年化收益率','年化波动率','年化超额','最大回撤','胜率']]
tiPlotly.plotly_Table_FF(t)
png2 参数稳定性检验
从参数选择标准上来看要尽量贴近“参数高原”,远离“参数孤岛。所谓“参数高原”指的是技术指标在较宽参数范围能取得不错的策略效果,而“参数孤岛”指只能在某个很小范围内表现不错,当参数稍微偏离时,技术指标的表现显著变差。
利用给定的参数池,对不同的参数组合的技术指标进行遍历回归.
在遍历回测中,我们遵循以下规则:
参数的选择范围符合技术指标本身构建的逻辑,当参数超过两个的,对其 中超过两个的周期参数等比例缩放,以便于结果的展示,并且周期参数呈 比例也在一定程度上符合我们对于参数的使用原则。
为了减少参数的过拟合效应,参数中关于超买超卖阈值的选择符合对称原 则或者相加互补原则。
.0 遍历参数组合
技术指标 | 默认参数 | 取值范围 | 信号规则 |
---|
AD | N1=3,N2=10 | N1:1,120 N2:1,120 | 当 ADOSC>0 且收盘价在 90 日均线上方,产生买入信号; 当 ADOSC<0 且收盘价在 90 日均线下方,产生卖出信号。 |
OBV | N1=10,N2=20 | N1:1,120 N2:1,120 | 当 OBV_HISTOGRAM 大于 0 时,产生买入信号; 当 OBV_HISTOGRAM 小于 0 时, 产生卖出信号。 |
MFI | N1=14,H=80,L=100-H | N1:1,120 | MFI 掉头向上突破20,买入信号;MFI掉头向下突破80,卖出信号 |
EOM | N1=20 | N1:1,120 | 当 EOM 大于 0 时产生买入信号,当 EOM<0 时,产生卖出信号 |
MAAMT | N1=30 | N1:1,120 | 当成交量短期均线上穿长期均线,产生买入信号; 成交量短期均线下穿上长期均 线,产生卖出信号。 |
FI | N1=13 | N1:1,120 | 当 FI>0,市场多头强劲,产生买入信号; 当 FI<0 时,市场空头强劲,产生卖出信号。 |
.1 单技术指标(默认参数)
single_strategy_Parameters_dict = {}
single_strategy_Parameters_dict[strategy_name] = strategy_Parameters_dict[strategy_name]
strategy_sharp_ratio_dict = tiStrategy.ergodic_Strategys_Parameter(
single_strategy_Parameters_dict,
base_df)
# 计算sharpe值
sharpe_ratio_df = strategy_sharp_ratio_dict[strategy_name]
.1 热力图
# 判断绘制热力图还是柱状图
N1_MAX = strategy_Parameters_dict[strategy_name]['N1']
N2_MAX = strategy_Parameters_dict[strategy_name]['N2']
#sharp_ratio_df = pd.read_csv('trend_following_sharp_ratio.csv')
title_text = '{}({})-{}'.format(benchmark_cn,benchmark,strategy_name)
if N2_MAX != 0:
# 绘制sharp ratio 热力图
tiPlotly.plotly_heatmap(sharpe_ratio_df,title_text)
else:
tiPlotly.plotly_bar(sharpe_ratio_df.T,title_text)
png.2 最优组合
strategy_Para_max_df = tiStrategy.cal_Optimal_Parameter(base_df,
strategy_sharp_ratio_dict)
净值图
# 1. 获得N1,N2
optimal_N1 = int(strategy_Para_max_df.loc[strategy_name,'N1'])
optimal_N2 = int(strategy_Para_max_df.loc[strategy_name,'N2'])
print('{} - {}, {}'.format(strategy_name,optimal_N1,optimal_N2))
# 2. 计算收益率
# 计算策略指标、交易信号
strategy_df,isMainPlotly,signal_df = tiStrategy.selectStrategy(
strategy_name,
base_df,
optimal_N1,
optimal_N2)
# 回测
result_df = tiStrategy.backtest(base_df,signal_df)
## 计算收益率
stock_rtn_df = llstats.simple_rtns(result_df[['capital']])
stock_rtn_df = stock_rtn_df.rename(columns={'capital':strategy_name})
# 绘制净值趋势图
title_text = '{}({})-{}'.format(benchmark_cn,benchmark,strategy_name)
tiPlotly.plotly_netVal(stock_rtn_df
,benckmark_rtn_df
,holidays_china_list
,title_text)
png绩效评估(Table)
strategy_Para_optimal_df = tiStrategy.cal_Strategy_Performance(stock_rtn_df,benckmark_rtn_df).T
strategy_Para_optimal_df = strategy_Para_optimal_df.rename(columns={'sharp':'夏普比率',
'annual_rtn':'年化收益率',
'annual_vol':'年化波动率','annual_excess':'年化超额',
'max_drawdown':'最大回撤'})
strategy_Para_optimal_df = strategy_Para_optimal_df.applymap(lambda x:format(x,'.2f'))
# 夏普比率、年化收益、年化波动、最大回撤
title_text = '{}({})'.format(benchmark_cn,benchmark)
tiPlotly.plotly_Table_FF(strategy_Para_optimal_df,title_text)
png.2 技术指标
## 遍历多个策略,返回rtn、sharp
strategys_sharpe_ratio_dict = tiStrategy.ergodic_Strategys_Parameter(
strategy_Parameters_dict,
base_df)
热力图
title_text = '{}({})'.format(benchmark_cn,benchmark)
tiPlotly.plotly_Sub_Indicators(strategys_sharpe_ratio_dict,title_text)
png最优组合
strategy_Para_max_df = tiStrategy.cal_Optimal_Parameter(base_df,
strategys_sharpe_ratio_dict)
净值图
strategies_rtn = pd.DataFrame(index=base_df.index)
for idx,bar in strategy_Para_max_df.iterrows():
_N1 = int(bar['N1'])
_N2 = int(bar['N2'])
rtn = tiStrategy.ergodic_Parameter(base_df,idx,_N1,_N2)
strategies_rtn[idx] = rtn
title_text = '{}({})'.format(benchmark_cn,benchmark)
tiPlotly.plotly_Sub_NetVal(strategies_rtn,
benckmark_rtn_df,
holidays_china_list,
title_text)
png绩效评估(Table)
# 夏普比率、年化收益、年化波动、最大回撤
title_text = '{}({})'.format(benchmark_cn,benchmark)
tiPlotly.plotly_Table_FF(strategy_Para_max_df,title_text)
png3 总结
成交量指标主要用于衡量金融证券的价格变动幅度和速度,可以帮助投资者理解市场的稳定性和可能的风险。选择了6个动量类指标,对沪深300、中证500、中证1000、国证2000和创业板指进行回测分析,大部分技术指标在长期都能获得超额收益,具备一定的择时能力。