一、网格交易
1、百分比法
2、固定金额法
二、MACD
1、金叉买入,死叉卖出,以6,13,5为参数计算的MACD
三、KDJ
1、kdj线中k的值向上,买入,向下卖出
2、kdj的k,值大于50买入,小于50卖出
3、kdj金叉买入,死叉卖出
测试数据:开始日期选择20180605(MACD回测时去掉前三十条数据,KDJ回测时去掉前十条数据)
test_data={"1":['中国移动','daily','600941.SH'],
"2":['百大集团','daily','600865.SH'],
"3":['爱尔眼科','daily','300015.SZ'],
"4":['捷佳伟创','daily','300724.SZ'],
"5":['食品ETF','fund_daily','515710.SH'],
"6":['钢铁ETF','fund_daily','515210.SH'],
"7":['汽车ETF','fund_daily','516110.SH'],
"8":['影视ETF','fund_daily','159855.SZ'],
"9":['上证指数','index_daily','000001.SH'],
"10":['创业板指数','index_daily','399006.SZ'],
"11":['蓝天转债','cb_daily','111017.SH'],
"12":['华源转债','cb_daily','128049.SZ'],
"13":['本钢转债','cb_daily','127018.SZ'],
"14":['帝欧转债','cb_daily','127047.SZ'],
"15":['金浦转债','cb_daily','123198.SZ'],
"16":['','',''],
"17":['','','']}
#所有方式回测
def huice_by_all_ways(test_data,need_to_test,start_date='20180605'):
for i in need_to_test:
tgname,data_type,ts_code=test_data[i]
print('===========================================================%s' % tgname)
df=get_stock_data(data_type=data_type,ts_code=ts_code,start_date=start_date)
#网格交易
# get_actual_benefit_by_different_strategy(df,strategy_type='1')
#macd
huice_by_macd(make_macd(df,6,13,5))
#kdj
huice_by_kdj(make_kdj(df),strategy='1',need_print='N')
huice_by_kdj(make_kdj(df),strategy='2',need_print='N')
huice_by_kdj(make_kdj(df),strategy='3',need_print='N')
测试结果:
'''
===========================================================中国移动
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 44
总利润 -11.39
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 45
总利润 69.51
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 29
总利润 5.06
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 51
总利润 55.23
===========================================================百大集团
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 97
总利润 0.08
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 113
总利润 20.09
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 71
总利润 3.83
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 128
总利润 18.21
===========================================================爱尔眼科
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 111
总利润 -38.15
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 109
总利润 78.68
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 61
总利润 16.13
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 136
总利润 69.77
===========================================================捷佳伟创
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 99
总利润 58.72
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 97
总利润 476.31
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 65
总利润 165.65
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 123
总利润 484.06
===========================================================食品ETF
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 53
总利润 -0.13
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 61
总利润 0.7
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 44
总利润 0.0
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 64
总利润 0.65
===========================================================钢铁ETF
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 79
总利润 0.09
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 81
总利润 2.09
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 51
总利润 0.75
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 87
总利润 1.97
===========================================================汽车ETF
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 65
总利润 -0.49
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 65
总利润 0.81
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 37
总利润 0.32
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 68
总利润 0.79
===========================================================影视ETF
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 57
总利润 -0.09
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 63
总利润 1.12
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 35
总利润 0.45
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 67
总利润 1.04
===========================================================上证指数
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 105
总利润 443.44
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 112
总利润 3914.17
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 70
总利润 553.1
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 126
总利润 2872.35
===========================================================创业板指数
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 103
总利润 303.12
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 111
总利润 4768.09
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 67
总利润 2314.71
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 125
总利润 3963.18
===========================================================蓝天转债
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 9
总利润 2.33
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 10
总利润 20.44
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 10
总利润 -5.6
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 9
总利润 14.48
===========================================================华源转债
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 90
总利润 14.09
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 92
总利润 116.89
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 60
总利润 64.65
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 95
总利润 124.57
===========================================================本钢转债
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 60
总利润 14.62
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 65
总利润 96.51
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 48
总利润 43.59
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 73
总利润 70.95
===========================================================帝欧转债
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 38
总利润 -27.53
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 38
总利润 23.58
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 27
总利润 -15.29
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 41
总利润 15.46
===========================================================金浦转债
采取策略-----macd1-----macd金叉买入、死叉卖出
总交易次数 13
总利润 -18.06
采取策略-----kdj1-----kdj线中k的值向上,买入,向下卖出
总交易次数 14
总利润 8.82
采取策略-----kdj2-----kdj的k,值大于50买入,小于50卖出
总交易次数 9
总利润 -7.89
采取策略-----kdj3-----kdj金叉买入,死叉卖出
总交易次数 15
总利润 6.65
'''
注意:为了简化计算,不考虑佣金等费用。交易量也以1个单位计算。
结论:
最佳策略:KDJ中k值向上时,买入,k值向下时,卖出。
其次策略:KDJ金叉买入,死叉卖出。
较差策略:KDJ中k值大于50买入,小于50卖出。
最差策略:MACD金叉买入,死叉卖出。
其实还有更差的策略,网格交易,之所以称为更差,是因为资金闲置最严重。
//20240503更新:代码有误,在趋势下行卖出时,采用了当天的开盘价,而变盘往往是下跌行情中,收盘价会低于开盘价。所以计算时,应该以当天的收盘价计算。
更新为如下:
def huice_by_kdj(data,strategy='1',need_print='N'):
#使用的策略是,当今天的kdj指标的k值比昨天的大,则以当天收盘价买入
#当k值比昨天小,则以开盘价卖出
date=list(data['trade_date'])
open=list(data['open'])
close=list(data['close'])
kdj_k=list(data['K'])
kdj_j=list(data['J'])
pre_k=0
buy_price=0
total_exchange=0
sum_benefit=0
#是否持仓
is_hold=False
benefit_list=[]
pre_buy_price=0
if strategy=='1':
for i in range(10,len(open)):
if kdj_k[i]>pre_k+5:
if is_hold is False:
buy_price=close[i]
print_exchange(date[i],'buy',buy_price,need_print)
is_hold=True
#设置止损点,如果股价开盘价低于买入价,卖出
elif kdj_k[i]<pre_k-5 or open[i]<pre_buy_price:
if is_hold is True:
sale_price=close[i]
total_exchange+=1
benefit=round(sale_price-buy_price,2)
benefit_list.append((date[i],benefit))
sum_benefit+=benefit
print_exchange(date[i],'sale',sale_price,need_print)
is_hold=False
else:
#如果当天的k值仅仅比前一天大一点点,可以视为约等于,不做处理
pass
pre_k=kdj_k[i]
pre_buy_price=buy_price
elif strategy=='2':
for i in range(10,len(open)):
if kdj_k[i]>50:
if is_hold is False:
buy_price=close[i]
print_exchange(date[i],'buy',buy_price,need_print)
is_hold=True
elif kdj_k[i]<50:
if is_hold is True:
sale_price=close[i]
total_exchange+=1
benefit=round(sale_price-buy_price,2)
benefit_list.append((date[i],benefit))
sum_benefit+=benefit
print_exchange(date[i],'sale',sale_price,need_print)
is_hold=False
else:
pass
pre_k=kdj_k[i]
elif strategy=='3':
for i in range(10,len(open)):
#金叉是j值大于k值,死叉是k值大于j值
if kdj_k[i]>pre_k and kdj_j[i]>=kdj_k[i]:
if is_hold is False:
buy_price=close[i]
print_exchange(date[i],'buy',buy_price,need_print)
is_hold=True
elif kdj_k[i]<pre_k and kdj_j[i]<=kdj_k[i]:
if is_hold is True:
sale_price=close[i]
total_exchange+=1
benefit=round(sale_price-buy_price,2)
benefit_list.append((date[i],benefit))
sum_benefit+=benefit
print_exchange(date[i],'sale',sale_price,need_print)
is_hold=False
else:
pass
pre_k=kdj_k[i]
else:
pass
if strategy=='1':
strategycn='kdj线中k的值向上,买入,向下卖出'
elif strategy=='2':
strategycn='kdj的k,值大于50买入,小于50卖出'
elif strategy=='3':
strategycn='kdj金叉买入,死叉卖出'
else:
strategycn='未定义'
benefit_list.sort(key=lambda x:(x[1],x[0]))
[print(i) for i in benefit_list]
print('采取策略-----kdj%s-----%s' % (strategy,strategycn))
print('股价变化,%.2f,%.2f' % (open[0],close[-1]))
print('总交易次数',total_exchange)
print('总利润',round(sum_benefit,2))
更新之后用于回测,多次得到亏损的结果。说明使用kdj指标卖出存在问题,需要优化。