请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  量化平台 帖子:3365817 新帖:24

【策略研发】三进兵策略与研究报告

专门亏损发表于:5 月 10 日 02:35回复(1)

说明:

  • 所谓的三进兵,是指三条EMA均线组合的策略

交易原则:

  • 系统由三条EMA均线组合而成,分别为小均线、中均线、大均线
  • 当小均线金叉大均线、并且中均线位于大均线下方时,买入
  • 当小均线死叉中均线,并且中均线位于大均线上方时,卖出
  • 止损:当买入后,如果收盘价跌破中均线,止损
  • 选股:对个股进行一段时间的回测,得出最优组合,并判断是否可达到正收益,从而判断是否适合本策略
  • 各位宽友如果有想法,可在此基础上做迭代,并分享出来,展示你的才华

提示:核心研究理论在研究报告里。

说明:¶

  • 所谓的三进兵,是指三条EMA均线组合的策略

交易原则:¶

  • 系统由三条EMA均线组合而成,分别为小均线、中均线、大均线
  • 当小均线金叉大均线、并且中均线位于大均线下方时,买入
  • 当小均线死叉中均线,并且中均线位于大均线上方时,卖出
  • 止损:当买入后,如果收盘价跌破中均线,止损
  • 选股:对个股进行一段时间的回测,得出最优组合,并判断是否可达到正收益,从而判断是否适合本策略
  • 各位宽友如果有想法,可在此基础上做迭代,并分享出来,展示你的才华

导入引用模块¶

import numpy as np
import pandas as pd
import datetime
from jqdata import *
from jqlib.technical_analysis import *

设置全局变量¶

# 记录成交历史
trade_history = {}
# 指定股票池,这里默认选择了创业板
stocks_pool = get_index_stocks('399006.XSHE')

编写公用函数¶

# 获取ma_min值
def get_ma(stock, ma_value, end_dt):
    price = get_price(security=stock, 
                      end_date=end_dt, 
                      frequency='daily', 
                      fields=['close'], 
                      skip_paused=False, 
                      fq='pre', 
                      count=ma_value+10)['close']
    ma = price[-ma_value:].mean()
    return ma

# 获取ema值
def get_ema(stock, ma_value, end_dt):
    ema = EMA(stock, check_date=end_dt, timeperiod=ma_value)
    return ema[stock]


# 判断是否出现买入信息
def is_buy(stock, yesterday, before_yesterday, *ema):
    ma_min = ema[0]
    ma_med = ema[1]
    ma_max = ema[2]
    
    # 求出上一个交易日的ma_min,ma_med,ma_max的值
    y_ma_min_value = get_ema(stock, ma_min, yesterday)
    y_ma_med_value = get_ema(stock, ma_med, yesterday)
    y_ma_max_value = get_ema(stock, ma_max, yesterday)

    # 求出上上个交易日的ma_min,ma_med,ma_max的值
    by_ma_min_value = get_ema(trade_stock, ma_min, before_yesterday)
    by_ma_med_value = get_ema(trade_stock, ma_med, before_yesterday)
    by_ma_max_value = get_ema(trade_stock, ma_max, before_yesterday)

    if (y_ma_min_value > y_ma_max_value) and (by_ma_min_value < by_ma_max_value) and (y_ma_med_value < y_ma_max_value):
        return True
    else:
        return False
    
    
# 判断是否有卖出信息
def is_sell(stock, yesterday, before_yesterday, *ema):
    ma_min = ema[0]
    ma_med = ema[1]
    ma_max = ema[2]
    
    # 求出上一个交易日的ma_min,ma_med,ma_max的值
    y_ma_min_value = get_ema(stock, ma_min, yesterday)
    y_ma_med_value = get_ema(stock, ma_med, yesterday)
    y_ma_max_value = get_ema(stock, ma_max, yesterday)

    # 求出上上个交易日的ma_min,ma_med,ma_max的值
    by_ma_min_value = get_ema(stock, ma_min, before_yesterday)
    by_ma_med_value = get_ema(stock, ma_med, before_yesterday)
    by_ma_max_value = get_ema(stock, ma_max, before_yesterday)

    if (y_ma_min_value > y_ma_med_value) and (by_ma_min_value < by_ma_med_value) and (y_ma_med_value > y_ma_max_value):
        return True
    else:
        return False
    
    
# 判断是否有卖出信息
def is_loss(stock, yesterday, *ema):
    ma_min = ema[0]
    ma_med = ema[1]
    ma_max = ema[2]
    
    # 昨日收盘价
    close = get_price(security=stock, 
                          end_date=yesterday,
                          frequency='daily', 
                          fields=['open','close'], 
                          skip_paused=False, 
                          fq='pre', 
                          count=10)['close'][-1] 
    
    
    # 求出上一个交易日的ma_min,ma_med,ma_max的值
    y_ma_min_value = get_ema(stock, ma_min, yesterday)
    y_ma_med_value = get_ema(stock, ma_med, yesterday)
    y_ma_max_value = get_ema(stock, ma_max, yesterday)
    
    if (close < y_ma_med_value) and (y_ma_med_value < y_ma_max_value):
        return True
    else:
        return False

    
# 过滤掉有止影线和小实体阳线的时刻
def is_high_line(stock, end_dt):
    price = get_price(security=stock, 
                          end_date=end_dt, 
                          frequency='daily', 
                          fields=['open', 'close', 'high', 'low', 'volume', 'money'], 
                          skip_paused=False, 
                          fq='pre', 
                          count=1)
    open = price['open'][0]
    close = price['close'][0]
    high = price['high'][0]
    low = price['low'][0]

    o_c_ratio = (open-close)/close
    h_c_ratio = (high-close)/close

    if o_c_ratio > 0 and h_c_ratio < 0.02:
        return True
    else:
        return False

交易函数¶

def trade(stock,ma_min,ma_med,ma_max,trade_days):
    # 记录盈利
    wine_loss_history = []
    # 持仓
    hold_list = {}
    # 权重
    weight = 0
    # 总权重
    last_weihgt = len(trade_days)
    
    # 因为回测的是历史
    for trade_day in trade_days:
        # 权重累加
        weight += 1
        # 将要被使用的日期集合
        the_days = get_trade_days(end_date=trade_day, count=5)
        # 回测当天
        today = the_days[-1]
        # 上一个交易日
        yesterday = the_days[-2]
        # 上上个交易日
        before_yesterday = the_days[-4]

        # ========================卖出操作========================
        sell_list = []
        for stock,info in hold_list.items():
            trade_day = info[0]
            buy_price = info[1]

            # 判断是否有卖出信号 
            re_value = is_sell(stock, yesterday, before_yesterday, ma_min,ma_med,ma_max)
            # 判断是否触发止损信号
            loss = is_loss(stock, yesterday, ma_min,ma_med,ma_max)
            
            # 进行卖出操作
            if re_value or loss:
                sell_list.append(stock)
                price = get_price(security=stock, 
                          end_date=today,  # 现实中成交按当天的开盘价交易
                          frequency='daily', 
                          fields=['open','close'], 
                          skip_paused=False, 
                          fq='pre', 
                          count=10)['open'][-1] 
                
                # 进行记录
                trade_dic = {'stock':stock,
                             'buy_date':trade_day,
                             'buy_price':buy_price,
                             'sell_date':today,
                             'sell_price':price,
                             'ratio':(price-buy_price)/buy_price,
                             'MA':(ma_min,ma_med,ma_max),
                             'weight':weight,
                             'count':last_weihgt}
                wine_loss_history.append(trade_dic)
        
        # 从持仓中删除已经卖出的股票
        for stock in sell_list:
            del hold_list[stock]
        # ========================卖出操作========================

            
        # ========================买入操作========================
        # 判断是否有买入信号
        re_value = is_buy(stock, yesterday, before_yesterday, ma_min,ma_med,ma_max)
        # 如果有买入信号,则买入
        if re_value:
            # 在今天的开盘时买入,参考的买入价格是昨天的收盘价
            price = get_price(security=stock, 
                          end_date=today, # 现实中按当天的开盘价交易 
                          frequency='daily', 
                          fields=['open','close'], 
                          skip_paused=False, 
                          fq='pre', 
                          count=10)['open'][-1]
            hold_list[stock] = [today, price]
        # ========================买入操作========================
    
    #========================将最后一次未卖出的也记录==========================
    if stock in hold_list.keys():
        sell_list.append(stock)
        price = get_price(security=stock, 
                  end_date=today,  # 现实中成交按当天的开盘价交易
                  frequency='daily', 
                  fields=['open','close'], 
                  skip_paused=False, 
                  fq='pre', 
                  count=10)['open'][-1] 

        # 进行记录
        trade_dic = {'stock':stock,
                     'buy_date':trade_day,
                     'buy_price':buy_price,
                     'sell_date':today,
                     'sell_price':price,
                     'ratio':(price-buy_price)/buy_price,
                     'MA':(ma_min,ma_med,ma_max),
                     'weight':weight,
                     'count':last_weihgt}
        wine_loss_history.append(trade_dic)
    #========================将最后一次未卖出的也记录==========================
        
    # 返回交易记录
    return wine_loss_history
value = trade('300059.XSHE',5,20,60) df = pd.DataFrame(value,columns=['stock', 'buy_date', 'buy_price', 'sell_date', 'sell_price', 'ratio', 'MA','b_ma','y_ma']) df

回测¶

# 获利近三年的交易日期
days = get_trade_days(end_date=datetime.datetime.now(), count=250*2+100)
train_days = days[:-100]
trade_days = days[-100:]

s_time = datetime.datetime.now()
# 回测股票
trade_stock = '600600.XSHG'
# 保存回测记录
all_list = []

# 三进兵的三个值集合
ma_min1 = [3, 5, 7]
ma_med1 = [10, 20, 30]
ma_max1 = [40, 50, 60]

# 回测不同的三进兵组合 
for ma1 in ma_min1:
    for ma2 in ma_med1:
        for ma3 in ma_max1:
            re_dic = trade(trade_stock,ma1,ma2,ma3,train_days)
            all_list = all_list + re_dic

# 输出各三进兵组合的值
df = pd.DataFrame(all_list,columns=['stock', 
                                    'buy_date', 
                                    'buy_price', 
                                    'sell_date', 
                                    'sell_price', 
                                    'ratio', 
                                    'MA', 
                                    'weight', 
                                    'count'])
e_time = datetime.datetime.now()
print(e_time-s_time)
df
0:02:44.335545
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }
stock buy_date buy_price sell_date sell_price ratio MA weight count
0 600600.XSHG 2016-11-30 30.67 2016-12-01 30.24 -0.014020 (3, 10, 40) 95 500
1 600600.XSHG 2017-01-24 30.06 2017-03-13 32.65 0.086161 (3, 10, 40) 161 500
2 600600.XSHG 2017-05-24 31.63 2017-05-25 31.08 -0.017389 (3, 10, 40) 211 500
3 600600.XSHG 2017-08-02 32.94 2017-08-03 32.36 -0.017608 (3, 10, 40) 259 500
4 600600.XSHG 2017-10-17 32.23 2017-11-28 30.82 -0.043748 (3, 10, 40) 337 500
5 600600.XSHG 2017-12-14 34.23 2018-02-09 36.00 0.051709 (3, 10, 40) 389 500
6 600600.XSHG 2018-07-20 46.11 2018-07-30 45.02 -0.023639 (3, 10, 40) 500 500
7 600600.XSHG 2016-11-30 30.67 2016-12-01 30.24 -0.014020 (3, 10, 50) 95 500
8 600600.XSHG 2017-01-25 30.06 2017-03-13 32.65 0.086161 (3, 10, 50) 161 500
9 600600.XSHG 2017-05-24 31.63 2017-05-25 31.08 -0.017389 (3, 10, 50) 211 500
10 600600.XSHG 2017-08-02 32.94 2017-08-03 32.36 -0.017608 (3, 10, 50) 259 500
11 600600.XSHG 2017-10-17 32.23 2017-11-28 30.82 -0.043748 (3, 10, 50) 337 500
12 600600.XSHG 2017-12-14 34.23 2018-02-13 36.63 0.070114 (3, 10, 50) 391 500
13 600600.XSHG 2018-02-27 38.52 2018-02-28 37.40 -0.029076 (3, 10, 50) 397 500
14 600600.XSHG 2018-02-28 37.40 2018-03-01 37.35 -0.001337 (3, 10, 50) 398 500
15 600600.XSHG 2018-07-20 46.11 2018-07-30 45.02 -0.023639 (3, 10, 50) 500 500
16 600600.XSHG 2017-01-25 30.06 2017-03-13 32.65 0.086161 (3, 10, 60) 161 500
17 600600.XSHG 2017-05-24 31.63 2017-05-25 31.08 -0.017389 (3, 10, 60) 211 500
18 600600.XSHG 2017-08-02 32.94 2017-08-03 32.36 -0.017608 (3, 10, 60) 259 500
19 600600.XSHG 2017-10-17 32.23 2017-11-28 30.82 -0.043748 (3, 10, 60) 337 500
20 600600.XSHG 2017-12-14 34.23 2018-02-26 38.32 0.119486 (3, 10, 60) 395 500
21 600600.XSHG 2018-03-12 39.27 2018-03-13 40.36 0.027757 (3, 10, 60) 406 500
22 600600.XSHG 2018-07-17 45.46 2018-07-30 45.02 -0.009679 (3, 10, 60) 500 500
23 600600.XSHG 2017-01-24 30.06 2017-03-22 32.12 0.068530 (3, 20, 40) 168 500
24 600600.XSHG 2017-05-24 31.63 2017-05-25 31.08 -0.017389 (3, 20, 40) 211 500
25 600600.XSHG 2017-05-31 33.15 2017-07-19 31.72 -0.043137 (3, 20, 40) 248 500
26 600600.XSHG 2017-08-01 32.99 2017-08-04 32.23 -0.023037 (3, 20, 40) 260 500
27 600600.XSHG 2017-10-17 32.23 2017-11-30 30.56 -0.051815 (3, 20, 40) 339 500
28 600600.XSHG 2017-12-15 35.03 2018-03-13 40.36 0.152155 (3, 20, 40) 406 500
29 600600.XSHG 2018-07-17 45.46 2018-07-18 45.17 -0.006379 (3, 20, 40) 492 500
... ... ... ... ... ... ... ... ... ...
114 600600.XSHG 2017-10-19 31.75 2017-11-28 30.82 -0.029291 (7, 10, 50) 337 500
115 600600.XSHG 2018-07-20 46.11 2018-07-30 45.02 -0.023639 (7, 10, 50) 500 500
116 600600.XSHG 2017-01-25 30.06 2017-03-13 32.65 0.086161 (7, 10, 60) 161 500
117 600600.XSHG 2017-05-24 31.63 2017-05-25 31.08 -0.017389 (7, 10, 60) 211 500
118 600600.XSHG 2018-07-19 47.25 2018-07-30 45.02 -0.047196 (7, 10, 60) 500 500
119 600600.XSHG 2017-01-25 30.06 2017-04-24 32.84 0.092482 (7, 20, 40) 189 500
120 600600.XSHG 2017-05-31 33.15 2017-07-19 31.72 -0.043137 (7, 20, 40) 248 500
121 600600.XSHG 2017-10-18 31.80 2017-11-30 30.56 -0.038994 (7, 20, 40) 339 500
122 600600.XSHG 2017-12-15 35.03 2018-03-13 40.36 0.152155 (7, 20, 40) 406 500
123 600600.XSHG 2018-07-19 47.25 2018-07-20 46.11 -0.024127 (7, 20, 40) 494 500
124 600600.XSHG 2017-01-26 30.34 2017-04-24 32.84 0.082399 (7, 20, 50) 189 500
125 600600.XSHG 2017-10-20 32.11 2017-11-30 30.56 -0.048272 (7, 20, 50) 339 500
126 600600.XSHG 2017-12-15 35.03 2018-03-13 40.36 0.152155 (7, 20, 50) 406 500
127 600600.XSHG 2018-07-20 46.11 2018-07-30 45.02 -0.023639 (7, 20, 50) 500 500
128 600600.XSHG 2017-01-26 30.34 2017-04-24 32.84 0.082399 (7, 20, 60) 189 500
129 600600.XSHG 2017-05-24 31.63 2017-05-25 31.08 -0.017389 (7, 20, 60) 211 500
130 600600.XSHG 2017-10-23 31.77 2017-11-30 30.56 -0.038086 (7, 20, 60) 339 500
131 600600.XSHG 2017-12-15 35.03 2018-03-13 40.36 0.152155 (7, 20, 60) 406 500
132 600600.XSHG 2017-01-25 30.06 2017-04-24 32.84 0.092482 (7, 30, 40) 189 500
133 600600.XSHG 2017-05-31 33.15 2017-07-19 31.72 -0.043137 (7, 30, 40) 248 500
134 600600.XSHG 2017-10-18 31.80 2017-12-01 30.38 -0.044654 (7, 30, 40) 340 500
135 600600.XSHG 2017-12-18 35.30 2018-02-22 37.96 0.075354 (7, 30, 40) 393 500
136 600600.XSHG 2018-07-19 47.25 2018-07-20 46.11 -0.024127 (7, 30, 40) 494 500
137 600600.XSHG 2017-01-26 30.34 2017-04-24 32.84 0.082399 (7, 30, 50) 189 500
138 600600.XSHG 2017-10-20 32.11 2017-12-01 30.38 -0.053877 (7, 30, 50) 340 500
139 600600.XSHG 2017-12-18 35.30 2018-03-13 40.36 0.143343 (7, 30, 50) 406 500
140 600600.XSHG 2018-07-20 46.11 2018-07-30 45.02 -0.023639 (7, 30, 50) 500 500
141 600600.XSHG 2017-01-26 30.34 2017-04-24 32.84 0.082399 (7, 30, 60) 189 500
142 600600.XSHG 2017-10-23 31.77 2017-12-01 30.38 -0.043752 (7, 30, 60) 340 500
143 600600.XSHG 2017-12-18 35.30 2018-03-13 40.36 0.143343 (7, 30, 60) 406 500

144 rows × 9 columns

df.to_csv('2018-12-23.csv')

计算最最优组合值¶

group = df.groupby(by=['MA'])
print('组合收益之和')
max_sum = group.sum()
max_sum = max_sum.sort_values(by=['ratio'],ascending=False).loc[:,['ratio']].head()
value = {'stock':trade_stock, 'MA':max_sum.index[0]}
print(value)
max_sum
组合收益之和
{'MA': (7, 30, 60), 'stock': '600600.XSHG'}
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }
ratio
MA
(7, 30, 60) 0.181990
(7, 20, 60) 0.179080
(3, 30, 60) 0.171834
(5, 30, 60) 0.168070
(5, 20, 60) 0.164303
print('各组合总收益对比图')
import matplotlib.pylab as plt
max_sum.T.plot(kind='bar')
plt.show()
各组合总收益对比图
print('组合收益标准差')
min_std = group.std()
min_std = min_std.loc[max_sum.index,['ratio']]
min_std = min_std.sort_values(by=['ratio'])
value = {'stock':trade_stock, 'MA':min_std.index[0]}
print(value)
min_std
组合收益标准差
{'MA': (3, 30, 60), 'stock': '600600.XSHG'}
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }
ratio
MA
(3, 30, 60) 0.050805
(5, 20, 60) 0.087410
(7, 20, 60) 0.088838
(5, 30, 60) 0.090379
(7, 30, 60) 0.095422
print('各组合收益拆线图')
for name in max_sum.index:
    table = df[df['MA']==name][['ratio']]
    x = range(len(table.index))
    plt.plot(x,table)
plt.legend(max_sum.index)
plt.show()
各组合收益拆线图
print('各组合收益对比图')
series = []
for name in max_sum.index:
    table = df[df['MA']==name]['ratio'].values
    series.append(table) 

bar_df = pd.DataFrame(series,max_sum.index).T
bar_df.plot(kind='bar')
plt.show()

print('交易次数表')
bar_df.T
各组合收益对比图
交易次数表
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }
0 1 2 3 4
MA
(7, 30, 60) 0.082399 -0.043752 0.143343 NaN NaN
(7, 20, 60) 0.082399 -0.017389 -0.038086 0.152155 NaN
(3, 30, 60) 0.073852 -0.017608 0.022339 0.099629 -0.006379
(5, 30, 60) 0.078177 -0.017608 -0.044654 0.152155 NaN
(5, 20, 60) 0.068530 -0.017389 -0.038994 0.152155 NaN
print('求加权后的表现-平均到每一次交易')
dic = []

for name, g in group:
    weight_df = df[df['MA']==name]
    w = weight_df['weight']
    r = weight_df['ratio']
    c = weight_df['weight'].sum()
    v = w*r/c
    dic.append({'ma':name, 'ratio':sum(v)})
    
w_df = pd.DataFrame(dic)
w_df = w_df.sort_values(by=['ratio'], ascending=False)
w_df.head()
求加权后的表现-平均到每一次交易
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }
ma ratio
26 (7, 30, 60) 0.062989
23 (7, 20, 60) 0.053073
14 (5, 20, 60) 0.050178
17 (5, 30, 60) 0.047552
22 (7, 20, 50) 0.034285
print('求加权后的表现-平均到每天')
dic = []
count = int(df['count'].mean())
l = list(range(1,count))

for name, g in group:
    weight_df = df[df['MA']==name]
    w = weight_df['weight']
    r = weight_df['ratio']
    v = w*r/sum(l)
    dic.append({'ma':name, 'ratio':sum(v)})
    
w_avge_df = pd.DataFrame(dic)
w_avge_df = w_avge_df.sort_values(by=['ratio'], ascending=False)
w_avge_df.head()
求加权后的表现-平均到每天
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }
ma ratio
23 (7, 20, 60) 0.000487
26 (7, 30, 60) 0.000472
17 (5, 30, 60) 0.000455
14 (5, 20, 60) 0.000452
8 (3, 30, 60) 0.000424
print('输出各组合的统计一览表\n') for name in min_std.index: x = df[df['MA']==name] print(name) print(x.describe()) print('='*50)

结果比较¶

result_dic = []
print('最大收益组合回测本年',max_sum.index[0])
ma1,ma2,ma3 = max_sum.index[0]
re_dic = trade(trade_stock,ma1,ma2,ma3,trade_days)
re_dic = pd.DataFrame(re_dic)
print('总盈利', re_dic.sum()['ratio'])
result_dic.append({'收益':re_dic.sum()['ratio']})
re_dic
最大收益组合回测本年 (7, 30, 60)
总盈利 0.004999999999999992
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }
MA buy_date buy_price count ratio sell_date sell_price stock weight
0 (7, 30, 60) 2018-12-17 36.0 100 0.005 2018-12-25 36.18 600600.XSHG 100
print('最小标准差组合回测本年',min_std.index[0])
ma1,ma2,ma3 = min_std.index[0]
re_dic = trade(trade_stock,ma1,ma2,ma3,trade_days)
re_dic = pd.DataFrame(re_dic)
print('总盈利', re_dic.sum()['ratio'])
result_dic.append({'收益':re_dic.sum()['ratio']})
re_dic
最小标准差组合回测本年 (3, 30, 60)
总盈利 0.019154929577464782
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }
MA buy_date buy_price count ratio sell_date sell_price stock weight
0 (3, 30, 60) 2018-12-14 35.5 100 0.019155 2018-12-25 36.18 600600.XSHG 100
print('最优加权组合回测本年',w_df['ma'].iloc[0])
ma1,ma2,ma3 = w_df['ma'].iloc[0]
re_dic = trade(trade_stock,ma1,ma2,ma3,trade_days)
re_dic = pd.DataFrame(re_dic)
print('总盈利', re_dic.sum()['ratio'])
result_dic.append({'收益':re_dic.sum()['ratio']})
re_dic
最优加权组合回测本年 (7, 30, 60)
总盈利 0.004999999999999992
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }
MA buy_date buy_price count ratio sell_date sell_price stock weight
0 (7, 30, 60) 2018-12-17 36.0 100 0.005 2018-12-25 36.18 600600.XSHG 100
df = pd.DataFrame(result_dic,index=['最大收益组合'+str(max_sum.index[0]),
                                    '最小标准差组合'+str(min_std.index[0]),
                                    '最优加权组合'+str(w_df['ma'].iloc[0])])
df.T.plot(kind='bar')
plt.show()
df
.dataframe thead tr:only-child th { text-align: right; } .dataframe thead th { text-align: left; } .dataframe tbody tr th { vertical-align: top; }
收益
最大收益组合(7, 30, 60) 0.005000
最小标准差组合(3, 30, 60) 0.019155
最优加权组合(7, 30, 60) 0.005000

改进方案¶

  • ma1[3,5,9] ma2[10,20,30] ma3[40,50,60]
  • 不同的股票,将拥有不同的ma1,ma2,ma3值
  • 求出收益波动最小的方案
  • 添加选股函数
  • 增加更换代码的函数,要求可以空仓,可以更新ma三个值
  • 在选股票或测试的时候,不添加止损
  • 在收盘的时候买进或卖出,而不是在次日开盘交易
  • 将可变的股票池变为外部可读取文件
  • 从市场里筛选,有收盘价上穿ma60的,进行提醒
  • 尝试结合macd等其他指标
  • 提醒可以通过邮件的方式发送
  • 如果能在平台运行,自动发送信息,那是再好不过
  • 在卖出的时候,可以使用分钟回测,一旦卖出条件成熟,就下达卖出指令,避免大阴线下穿
  • 对于不同时期成交的历史,做出加权,越靠近当前的,权值越重,这样才会越符合当前的模型参数值
  • 为回测的数据增加窗口宽度
  • 止损位的设置,如果中线不大于长线,但收盘价跌破了中线,则止损(一来可以停止亏损,二来在二次进攻时还可进入)
 
 
 

全部回复

0/140

量化课程

    移动端课程