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

量化交易吧 /  数理科学 帖子:3364680 新帖:1

KDJ指标在指数上的趋势与择时效应

汇市江湖百晓生发表于:5 月 9 日 19:20回复(1)
"""导入常用模块"""import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport datetimefrom environment import * # 导入大树工作室开发的回测模块

KDJ指标计算函数

import talib as tlfrom functools import reduce# SMA计算函数def SMA(close, timeperiod) :close = np.nan_to_num(close)return reduce(lambda x, y: ((timeperiod - 1) * x   y) / timeperiod, close)# KDJ计算函数def KDJ(high, low, close, fastk_period, slowk_period, fastd_period) :kValue, dValue = tl.STOCHF(high, low, close, fastk_period, fastd_period=1, fastd_matype=0)

    kValue = np.array(list(map(lambda x : SMA(kValue[:x], slowk_period), range(1, len(kValue)   1))))
    dValue = np.array(list(map(lambda x : SMA(kValue[:x], fastd_period), range(1, len(kValue)   1))))

    jValue = 3 * kValue - 2 * dValue

    func = lambda arr : np.array([0 if x < 0 else (100 if x > 100 else x) for x in arr])

    kValue = func(kValue)
    dValue = func(dValue)
    jValue = func(jValue)return kValue, dValue, jValue# 获取某标的的KDJ信息def get_kdj(stock, count, end_date, unit):data = get_bars(security=stock, count=count, unit=unit,
                        include_now=False, 
                        end_dt=end_date, fq_ref_date=None)
    close = data['close']
    open = data['open']
    high = data['high']
    low = data['low']return KDJ(high, low, close, 9, 3, 3)


KDJ指标使用方法 一

KDJ是一种摆动指标,20与80的位置是我们对当前超买超卖状态的最基本判断。接下来的择时条件如下:

  • 当D线处于20位置以下时,买进;

  • 当D线处于80位置以上时,卖出;

另外,20与80的位置并不是硬性指标,我们可以为其指定一个浮动范围;我们将这个范围N值定在1%~9%之间,然后做回测,并查看其结果。

trade_list = []
N =[n/100 for n in range(1, 10)]for n in N:"""初始化以下内容"""context = Context() # 账户对象order = Order(context) # 下单对象trade = Trade(context, order) # 回测对旬context.start_date = '2005-05-01'context.end_date = '2019-02-22'context.universe = ['000300.XSHG']
    context.base = '000300.XSHG'"""策略主体"""def handle(context, order):stock = context.universe[0]
        current_date = trade.context.current_dt
        kdj_day = get_kdj(stock, 30, current_date, '1d')

        line_bottm = 20 * (1 n)
        line_top = 80 * (1-n)

        k1 = kdj_day[0][-1]
        d1 = kdj_day[1][-1]
        j1 = kdj_day[2][-1]

        k2 = kdj_day[0][-2]
        d2 = kdj_day[1][-2]
        j2 = kdj_day[2][-2]

        close = get_price(security=stock, 
                          end_date=context.current_dt,
                          frequency='daily', 
                          fields=None, 
                          skip_paused=False, 
                          fq='pre',
                          count=5)['close']if d2 > line_bottm and d1 < line_bottm :if stock in context.position.keys():returnorder.buy(stock, close[-1], context.cash // close[-1])elif d2 < line_top and d1 > line_top:if stock not in context.position.keys():returnorder.sell(stock, close[-1], context.position[stock]['count'])"""执行策略"""trade.trade(handle, show=False, log=True)
    trade_list.append(trade)# 展示Trade.show_ratio_compare('n', N, trade_list, 3, 3)
End Time : 2019-03-10 16:01:27.192853, Elapsed Time: 0:00:18.351210End Time : 2019-03-10 16:01:45.031913, Elapsed Time: 0:00:17.838861End Time : 2019-03-10 16:02:02.843599, Elapsed Time: 0:00:17.811513End Time : 2019-03-10 16:02:20.318987, Elapsed Time: 0:00:17.475214End Time : 2019-03-10 16:02:38.392089, Elapsed Time: 0:00:18.072942End Time : 2019-03-10 16:02:55.567773, Elapsed Time: 0:00:17.175470End Time : 2019-03-10 16:03:13.802732, Elapsed Time: 0:00:18.234765End Time : 2019-03-10 16:03:32.918843, Elapsed Time: 0:00:19.115479End Time : 2019-03-10 16:03:51.401436, Elapsed Time: 0:00:18.482391

Trade.show_result('n', N, trade_list)

从上图来看,kdj在超买与超卖区的反应对于沪深300指数来说,反应并不好。

KDJ使用方法 二

  • 当k线与d线形成金叉时买进;

  • 当k线与d线形成死叉时卖出;

金叉与死叉形成时,最小的时间段是前天与当天的值的比较,这个时间段也可以被当作一种参数D,其取值范围是1~9天。查看回测结果:

trade_list = []
D = range(1, 10)for d in D:"""初始化以下内容"""context = Context() # 账户对象order = Order(context) # 下单对象trade = Trade(context, order) # 回测对旬context.start_date = '2005-05-01'context.end_date = '2019-02-22'context.universe = ['000300.XSHG']
    context.base = '000300.XSHG'"""策略主体"""def handle(context, order):stock = context.universe[0]
        current_date = trade.context.current_dt
        kdj_day = get_kdj(stock, 30, current_date, '1d')

        k1 = kdj_day[0][-1]
        d1 = kdj_day[1][-1]
        j1 = kdj_day[2][-1]

        k2 = kdj_day[0][-d-1]
        d2 = kdj_day[1][-d-1]
        j2 = kdj_day[2][-d-1]

        close = get_price(security=stock, 
                          end_date=context.current_dt,
                          frequency='daily', 
                          fields=None, 
                          skip_paused=False, 
                          fq='pre',
                          count=5)['close']if k2 < d2 and k1 > d1:if stock in context.position.keys():returnorder.buy(stock, close[-1], context.cash // close[-1])elif k2 > d2 and k1 < d1:if stock not in context.position.keys():returnorder.sell(stock, close[-1], context.position[stock]['count'])"""执行策略"""trade.trade(handle, show=False, log=True)
    trade_list.append(trade)# 展示Trade.show_ratio_compare('d', D, trade_list, 3, 3)
End Time : 2019-03-10 16:04:13.577469, Elapsed Time: 0:00:20.034098End Time : 2019-03-10 16:04:33.005696, Elapsed Time: 0:00:19.428044End Time : 2019-03-10 16:04:52.154929, Elapsed Time: 0:00:19.149037End Time : 2019-03-10 16:05:12.142793, Elapsed Time: 0:00:19.987659End Time : 2019-03-10 16:05:31.073016, Elapsed Time: 0:00:18.930031End Time : 2019-03-10 16:05:51.557113, Elapsed Time: 0:00:20.483901End Time : 2019-03-10 16:06:10.902478, Elapsed Time: 0:00:19.345159End Time : 2019-03-10 16:06:29.924519, Elapsed Time: 0:00:19.021839End Time : 2019-03-10 16:06:48.871547, Elapsed Time: 0:00:18.946834

Trade.show_result('d', D, trade_list)

从上面结果来看,当d=2时回测的效果比较好,但整体看来,仍旧没有跑赢大盘。因此,效果也并不理想。

KDJ使用方法 三

  • 当j线与价格发生底背离时,买进;

  • 当j线与价格发生顶背离时,卖出;

背离计算的是一段时间内,j线的趋势与价格的趋势在方向上不一致,把时间段设为D值,取值范围是1~9天。回测并查看结果:

trade_list = []
D = range(1, 10)for d in D:"""初始化以下内容"""context = Context() # 账户对象order = Order(context) # 下单对象trade = Trade(context, order) # 回测对旬context.start_date = '2005-05-01'context.end_date = '2019-02-22'context.universe = ['000300.XSHG']
    context.base = '000300.XSHG'"""策略主体"""def handle(context, order):stock = context.universe[0]
        current_date = trade.context.current_dt
        kdj_day = get_kdj(stock, 30, current_date, '1d')

        k1 = kdj_day[0][-1]
        d1 = kdj_day[1][-1]
        j1 = kdj_day[2][-1]

        k2 = kdj_day[0][-d-1]
        d2 = kdj_day[1][-d-1]
        j2 = kdj_day[2][-d-1]

        close = get_price(security=stock, 
                          end_date=context.current_dt,
                          frequency='daily', 
                          fields=None, 
                          skip_paused=False, 
                          fq='pre',
                          count=20)['close']if j1 > j2 and close[-1] < close[-d-1]:if stock in context.position.keys():returnorder.buy(stock, close[-1], context.cash // close[-1])elif j1 < j2 and close[-1] > close[-d-1]:if stock not in context.position.keys():returnorder.sell(stock, close[-1], context.position[stock]['count'])"""执行策略"""trade.trade(handle, show=False, log=True)
    trade_list.append(trade)# 展示Trade.show_ratio_compare('d', D, trade_list, 3, 3)
End Time : 2019-03-10 16:07:10.097162, Elapsed Time: 0:00:19.401507End Time : 2019-03-10 16:07:30.041172, Elapsed Time: 0:00:19.943802End Time : 2019-03-10 16:07:51.642053, Elapsed Time: 0:00:21.600708End Time : 2019-03-10 16:08:12.491229, Elapsed Time: 0:00:20.848990End Time : 2019-03-10 16:08:32.879961, Elapsed Time: 0:00:20.388533End Time : 2019-03-10 16:08:53.409177, Elapsed Time: 0:00:20.528626End Time : 2019-03-10 16:09:12.488550, Elapsed Time: 0:00:19.079192End Time : 2019-03-10 16:09:32.450308, Elapsed Time: 0:00:19.961573End Time : 2019-03-10 16:09:52.517584, Elapsed Time: 0:00:20.067092

Trade.show_result('d', D, trade_list)

从上图来看,j线的背离效果也不好,k线与d线的背离效果这里就不做加测了。

下面展示本次研究效果最好的参数,即金叉与死叉条件下,d=2时的结果。

"""初始化以下内容"""context = Context() # 账户对象order = Order(context) # 下单对象trade = Trade(context, order) # 回测对旬context.start_date = '2005-05-01'context.end_date = '2019-02-22'context.universe = ['000300.XSHG']
context.base = '000300.XSHG'"""策略主体"""def handle(context, order):stock = context.universe[0]
    current_date = trade.context.current_dt
    kdj_day = get_kdj(stock, 30, current_date, '1d')

    k1 = kdj_day[0][-1]
    d1 = kdj_day[1][-1]
    j1 = kdj_day[2][-1]

    k2 = kdj_day[0][-2-1]
    d2 = kdj_day[1][-2-1]
    j2 = kdj_day[2][-2-1]

    close = get_price(security=stock, 
                      end_date=context.current_dt,
                      frequency='daily', 
                      fields=None, 
                      skip_paused=False, 
                      fq='pre',
                      count=20)['close']if k2 < d2 and k1 > d1:if stock in context.position.keys():returnorder.buy(stock, close[-1], context.cash // close[-1])elif k2 > d2 and k1 < d1:if stock not in context.position.keys():returnorder.sell(stock, close[-1], context.position[stock]['count'])"""执行策略"""trade.trade(handle, show=True, log=True)
End Time : 2019-03-10 16:11:04.901546, Elapsed Time: 0:00:20.362267

全部回复

0/140

量化课程

    移动端课程