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

量化交易吧 /  量化平台 帖子:3364693 新帖:14

MACD(分钟、日、周、月、年级别)研究

外汇老老法师发表于:5 月 9 日 17:45回复(1)

MACD(分钟、日、周、月、年级别)研究

最近和朋友一直在研究 MACD方面的策略,看到社区里很多人都在问分钟、周级别的MACD如何写,这里我就直接把代码放出来,分享给各位有需求的朋友!今后,将会陆续推出其它指标的不同时段研究主题!

如果对你有帮助,希望点下赞 O(∩_∩)O哈哈~


先上封装好的方法,方便各位复制

import pandas as pd
import numpy as np
import talib as tb
import datetime
import time
def get_macd(stock_list, check_date=None, unit='1d', include_now=False):
    """
    MACD计算函数,返回一个嵌套字典,Key是股票代码,Value是一个字典,不包括当前时间段的值
    stock_list:可以指定单只股票,也可以是股票列表
    check_date: 获取MACD值的日期,注意未来数据值
    unit:支持分钟 xm、天 xd、周 xw 时间段的数据
    include_now: 是否包含当前时间段的bar
    """
    macd_list = {}
    if isinstance(check_date,str):
        check_date = datetime.datetime.strptime(check_date, "%Y-%m-%d %H:%M:%S")

    '''如果股票代码是个字符串而不是一个列表,进行转换'''
    if isinstance(stock_list,str):
        stock_list = [stock_list]

    for stock in stock_list:
        '''获取指定日期之前的300个收盘价信息'''
        array = get_bars(security=stock, 
                         count=500, 
                         unit=unit,
                         fields=['close'],
                         include_now=include_now,
                         end_dt=check_date, 
                         fq_ref_date=check_date)
        close_list = array['close']

        '''求出用300个数据推算出的dif/dea/macd集合'''
        dif, dea, macd = tb.MACD(close_list, 
                                 fastperiod=12, 
                                 slowperiod=26, 
                                 signalperiod=9)

        '''得到最近一个交易时间段的dif/dea/macd'''
        last_dif = dif[-1]
        last_dea = dea[-1]
        last_macd = macd[-1]

        '''字典包装,用于返回'''
        macd_dic = (last_dif, last_dea, last_macd*2)
        macd_list[stock] = macd_dic

    return macd_list

日级别MACD调用

re_value = get_macd(['002024.XSHE', '000001.XSHE'], check_date=datetime.datetime.now(),unit='1d', include_now=False)
dif, dea, macd = re_value['002024.XSHE']
print(dif, dea, macd)
-0.21268269808256157 -0.20345150043898352 -0.018462395287156097

日级别的MACD调用需要注意一下,假如check_date的值是2018-09-04这样的日期形式,默认会按2018-09-04 00:00:00的时间点结算

2018-09-04 00:00:00还没有开盘,所得到的值是上一日收盘后的数据,所以得到MACD的值实际上是上一个交易日的

分钟级别MACD调用

re_value = get_macd('000001.XSHE', check_date='2018-11-12 14:00:00',unit='60m', include_now=True)
dif, dea, macd = re_value['000001.XSHE']
print(dif, dea, macd)
-0.10318188495987535 -0.06846332775628344 -0.06943711440718381

include_now=False指定包含当前分钟级别内的数据

周级别MACD调用

re_value = get_macd(['002024.XSHE', '000001.XSHE'], check_date=datetime.datetime.now(),unit='1w', include_now=False)
dif, dea, macd = re_value['002024.XSHE']
print(dif, dea, macd)
-0.36459699432380077 -0.22657033635361742 -0.2760533159403667

get_bars 的用法

get_bars(security, count, unit='1d',
                 fields=['date', 'open','high','low','close'],
                 include_now=False, end_dt=None, fq_ref_date=None)

获取各种时间周期的 bar 数据, bar 的分割方式与主流股票软件相同, 而且支持返回当前时刻所在 bar 的数据。

参数

  • security: 股票代码
  • count: 大于0的整数,表示获取bar的个数。如果行情数据的bar不足count个,返回的长度则小于count个数。
  • unit: bar的时间单位, 支持如下周期:'1m', '5m', '15m', '30m', '60m', '120m', '1d', '1w', '1M'。'1w' 表示一周,‘1M' 表示一月。
  • fields: 获取数据的字段, 支持如下值:'date', 'open', 'close', 'high', 'low', 'volume', 'money'
  • include_now: 取值True 或者False。 表示是否包含当前bar, 比如策略时间是9:33,unit参数为5m, 如果 include_now=True,则返回9:30-9:33这个分钟 bar。
  • end_dt:查询的截止时间,支持的类型为datetime.datetime或None。为None在回测模拟环境下默认为context.current_dt,在研究环境下默认为datetime.now(),支持的格式为。
  • fq_ref_date:复权基准日期,为None时为不复权数据。注意在回测及模拟交易中,默认为None,即不复权数据;在研究环境中,默认复权基准日期为当天。

返回一个 numpy.ndarray 对象。可以通过 array['close'] 的方式直接访问列数据。

示例

array = get_bars('000001.XSHG', 5, unit='1d',fields=['open','close'],include_now=False)
array['close']

日级别的金叉与死叉求法(不包含当天)

'''平安银行'''
stocks = '000001.XSHE'
start_day = datetime.datetime.now().date() - datetime.timedelta(days=300)
date_list = [start_day   datetime.timedelta(days=i) for i in range(30) if (start_day.weekday() != 5 or start_day.weekday() != 6)]

for date in date_list:
    '''跳过周六周日'''
    _day = date - datetime.timedelta(days=1)
    if date.weekday() == 0 or date.weekday() == 1:
        _day = date - datetime.timedelta(days=3)
    last_day_dic = get_macd(stocks, 
                        check_date=date,
                        unit='1d', 
                        include_now=False)
    action_day_dic = get_macd(stocks, 
                                 check_date=_day,
                                 unit='1d', 
                                 include_now=False)

    l_dif, l_dea, l_macd = last_day_dic[stocks]
    a_dif, a_dea, a_macd = action_day_dic[stocks]

    if a_dif < a_dea and l_dif > l_dea:
        print(date, '的前一个交易日 金叉形成')
    elif a_dif > a_dea and l_dif < l_dea:
        print(date, '的前一个交易日 死叉形成')
    else:
        print(date, '的前一个交易日 维持不变')
2018-01-17 的前一个交易日 维持不变
2018-01-18 的前一个交易日 维持不变
2018-01-19 的前一个交易日 维持不变
2018-01-20 的前一个交易日 维持不变
2018-01-21 的前一个交易日 维持不变
2018-01-22 的前一个交易日 维持不变
2018-01-23 的前一个交易日 维持不变
2018-01-24 的前一个交易日 维持不变
2018-01-25 的前一个交易日 维持不变
2018-01-26 的前一个交易日 维持不变
2018-01-27 的前一个交易日 维持不变
2018-01-28 的前一个交易日 维持不变
2018-01-29 的前一个交易日 维持不变
2018-01-30 的前一个交易日 死叉形成
2018-01-31 的前一个交易日 维持不变
2018-02-01 的前一个交易日 维持不变
2018-02-02 的前一个交易日 维持不变
2018-02-03 的前一个交易日 维持不变
2018-02-04 的前一个交易日 维持不变
2018-02-05 的前一个交易日 维持不变
2018-02-06 的前一个交易日 维持不变
2018-02-07 的前一个交易日 维持不变
2018-02-08 的前一个交易日 维持不变
2018-02-09 的前一个交易日 维持不变
2018-02-10 的前一个交易日 维持不变
2018-02-11 的前一个交易日 维持不变
2018-02-12 的前一个交易日 维持不变
2018-02-13 的前一个交易日 维持不变
2018-02-14 的前一个交易日 维持不变
2018-02-15 的前一个交易日 维持不变

分钟级别的金叉与死叉求法(包含当前运算时间点[分钟级别])?

'''苏宁易购'''
stocks = '000001.XSHE'
'''定义一个开始时间'''
start_time = datetime.datetime.strptime('2018-11-12 09:30:00', "%Y-%m-%d %H:%M:%S")

for i in range(12):
    now = start_time   datetime.timedelta(minutes=i*5)
    action_time = now - datetime.timedelta(minutes=5)

    last_day_dic = get_macd(stocks, 
                        check_date=now,
                        unit='5m', 
                        include_now=True)
    action_day_dic = get_macd(stocks, 
                                 check_date=action_time,
                                 unit='5m', 
                                 include_now=False)

    l_dif, l_dea, l_macd = last_day_dic[stocks]
    a_dif, a_dea, a_macd = action_day_dic[stocks]
#     print(action_time,a_dif, a_dea, a_macd,now,l_dif, l_dea, l_macd)
    if a_dif < a_dea and l_dif > l_dea:
        print(now, '金叉形成')
    elif a_dif > a_dea and l_dif < l_dea:
        print(now,'死叉形成')
    else:
        print(now, '维持不变')
2018-11-12 09:30:00 维持不变
2018-11-12 09:35:00 维持不变
2018-11-12 09:40:00 维持不变
2018-11-12 09:45:00 维持不变
2018-11-12 09:50:00 维持不变
2018-11-12 09:55:00 死叉形成
2018-11-12 10:00:00 死叉形成
2018-11-12 10:05:00 维持不变
2018-11-12 10:10:00 维持不变
2018-11-12 10:15:00 维持不变
2018-11-12 10:20:00 维持不变
2018-11-12 10:25:00 金叉形成

周、月、年级别的MACD使用方法同上,又因MACD的延迟性,在该时间使用的人较少,这里不再列出调用代码,使用者可改变参数使用。

由于在研究中使用代码,常常使用到非交易日期,如果在回测中使用,则不会出现非交易日期。

敝人能力有限,如有错误的地方,还请指证,欢迎提出更正建议!O(∩_∩)O~~

MACD(分钟、日、周、月、年级别)研究¶

最近和朋友一直在研究 MACD方面的策略,看到社区里很多人都在问分钟、周级别的MACD如何写,这里我就直接把代码放出来,分享给各位有需求的朋友!今后,将会陆续推出其它指标的不同时段研究主题!

如果对你有帮助,希望点下赞 O(∩_∩)O哈哈~¶


先上封装好的方法,方便各位复制¶

import pandas as pd
import numpy as np
import talib as tb
import datetime
import time
def get_macd(stock_list, check_date=None, unit='1d', include_now=False):
    """
    MACD计算函数,返回一个嵌套字典,Key是股票代码,Value是一个字典,不包括当前时间段的值
    stock_list:可以指定单只股票,也可以是股票列表
    check_date: 获取MACD值的日期,注意未来数据值
    unit:支持分钟 xm、天 xd、周 xw 时间段的数据
    include_now: 是否包含当前时间段的bar
    """
    macd_list = {}
    if isinstance(check_date,str):
        check_date = datetime.datetime.strptime(check_date, "%Y-%m-%d %H:%M:%S")
    
    '''如果股票代码是个字符串而不是一个列表,进行转换'''
    if isinstance(stock_list,str):
        stock_list = [stock_list]
    
    for stock in stock_list:
        '''获取指定日期之前的300个收盘价信息'''
        array = get_bars(security=stock, 
                         count=500, 
                         unit=unit,
                         fields=['close'],
                         include_now=include_now,
                         end_dt=check_date, 
                         fq_ref_date=check_date)
        close_list = array['close']

        '''求出用300个数据推算出的dif/dea/macd集合'''
        dif, dea, macd = tb.MACD(close_list, 
                                 fastperiod=12, 
                                 slowperiod=26, 
                                 signalperiod=9)

        '''得到最近一个交易时间段的dif/dea/macd'''
        last_dif = dif[-1]
        last_dea = dea[-1]
        last_macd = macd[-1]

        '''字典包装,用于返回'''
        macd_dic = (last_dif, last_dea, last_macd*2)
        macd_list[stock] = macd_dic
        
    return macd_list

日级别MACD调用¶

re_value = get_macd(['002024.XSHE', '000001.XSHE'], check_date=datetime.datetime.now(),unit='1d', include_now=False)
dif, dea, macd = re_value['002024.XSHE']
print(dif, dea, macd)
-0.21268269808256157 -0.20345150043898352 -0.018462395287156097

日级别的MACD调用需要注意一下,假如check_date的值是2018-09-04这样的日期形式,默认会按2018-09-04 00:00:00的时间点结算

2018-09-04 00:00:00还没有开盘,所得到的值是上一日收盘后的数据,所以得到MACD的值实际上是上一个交易日的

分钟级别MACD调用¶

re_value = get_macd('000001.XSHE', check_date='2018-11-12 14:00:00',unit='60m', include_now=True)
dif, dea, macd = re_value['000001.XSHE']
print(dif, dea, macd)
-0.10318188495987535 -0.06846332775628344 -0.06943711440718381

include_now=False指定包含当前分钟级别内的数据

周级别MACD调用¶

re_value = get_macd(['002024.XSHE', '000001.XSHE'], check_date=datetime.datetime.now(),unit='1w', include_now=False)
dif, dea, macd = re_value['002024.XSHE']
print(dif, dea, macd)
-0.36459699432380077 -0.22657033635361742 -0.2760533159403667

get_bars 的用法¶

get_bars(security, count, unit='1d',
                 fields=['date', 'open','high','low','close'],
                 include_now=False, end_dt=None, fq_ref_date=None)

获取各种时间周期的 bar 数据, bar 的分割方式与主流股票软件相同, 而且支持返回当前时刻所在 bar 的数据。

参数¶

  • security: 股票代码
  • count: 大于0的整数,表示获取bar的个数。如果行情数据的bar不足count个,返回的长度则小于count个数。
  • unit: bar的时间单位, 支持如下周期:'1m', '5m', '15m', '30m', '60m', '120m', '1d', '1w', '1M'。'1w' 表示一周,‘1M' 表示一月。
  • fields: 获取数据的字段, 支持如下值:'date', 'open', 'close', 'high', 'low', 'volume', 'money'
  • include_now: 取值True 或者False。 表示是否包含当前bar, 比如策略时间是9:33,unit参数为5m, 如果 include_now=True,则返回9:30-9:33这个分钟 bar。
  • end_dt:查询的截止时间,支持的类型为datetime.datetime或None。为None在回测模拟环境下默认为context.current_dt,在研究环境下默认为datetime.now(),支持的格式为。
  • fq_ref_date:复权基准日期,为None时为不复权数据。注意在回测及模拟交易中,默认为None,即不复权数据;在研究环境中,默认复权基准日期为当天。

返回一个 numpy.ndarray 对象。可以通过 array['close'] 的方式直接访问列数据。

示例¶

array = get_bars('000001.XSHG', 5, unit='1d',fields=['open','close'],include_now=False)
array['close']

日级别的金叉与死叉求法(不包含当天)¶

'''平安银行'''
stocks = '000001.XSHE'
start_day = datetime.datetime.now().date() - datetime.timedelta(days=300)
date_list = [start_day + datetime.timedelta(days=i) for i in range(30) if (start_day.weekday() != 5 or start_day.weekday() != 6)]

for date in date_list:
    '''跳过周六周日'''
    _day = date - datetime.timedelta(days=1)
    if date.weekday() == 0 or date.weekday() == 1:
        _day = date - datetime.timedelta(days=3)
    last_day_dic = get_macd(stocks, 
                        check_date=date,
                        unit='1d', 
                        include_now=False)
    action_day_dic = get_macd(stocks, 
                                 check_date=_day,
                                 unit='1d', 
                                 include_now=False)

    l_dif, l_dea, l_macd = last_day_dic[stocks]
    a_dif, a_dea, a_macd = action_day_dic[stocks]
    
    if a_dif < a_dea and l_dif > l_dea:
        print(date, '的前一个交易日 金叉形成')
    elif a_dif > a_dea and l_dif < l_dea:
        print(date, '的前一个交易日 死叉形成')
    else:
        print(date, '的前一个交易日 维持不变')
2018-01-17 的前一个交易日 维持不变
2018-01-18 的前一个交易日 维持不变
2018-01-19 的前一个交易日 维持不变
2018-01-20 的前一个交易日 维持不变
2018-01-21 的前一个交易日 维持不变
2018-01-22 的前一个交易日 维持不变
2018-01-23 的前一个交易日 维持不变
2018-01-24 的前一个交易日 维持不变
2018-01-25 的前一个交易日 维持不变
2018-01-26 的前一个交易日 维持不变
2018-01-27 的前一个交易日 维持不变
2018-01-28 的前一个交易日 维持不变
2018-01-29 的前一个交易日 维持不变
2018-01-30 的前一个交易日 死叉形成
2018-01-31 的前一个交易日 维持不变
2018-02-01 的前一个交易日 维持不变
2018-02-02 的前一个交易日 维持不变
2018-02-03 的前一个交易日 维持不变
2018-02-04 的前一个交易日 维持不变
2018-02-05 的前一个交易日 维持不变
2018-02-06 的前一个交易日 维持不变
2018-02-07 的前一个交易日 维持不变
2018-02-08 的前一个交易日 维持不变
2018-02-09 的前一个交易日 维持不变
2018-02-10 的前一个交易日 维持不变
2018-02-11 的前一个交易日 维持不变
2018-02-12 的前一个交易日 维持不变
2018-02-13 的前一个交易日 维持不变
2018-02-14 的前一个交易日 维持不变
2018-02-15 的前一个交易日 维持不变

分钟级别的金叉与死叉求法(包含当前运算时间点[分钟级别])¶¶

'''苏宁易购'''
stocks = '000001.XSHE'
'''定义一个开始时间'''
start_time = datetime.datetime.strptime('2018-11-12 09:30:00', "%Y-%m-%d %H:%M:%S")

for i in range(12):
    now = start_time + datetime.timedelta(minutes=i*5)
    action_time = now - datetime.timedelta(minutes=5)
    
    last_day_dic = get_macd(stocks, 
                        check_date=now,
                        unit='5m', 
                        include_now=True)
    action_day_dic = get_macd(stocks, 
                                 check_date=action_time,
                                 unit='5m', 
                                 include_now=False)

    l_dif, l_dea, l_macd = last_day_dic[stocks]
    a_dif, a_dea, a_macd = action_day_dic[stocks]
#     print(action_time,a_dif, a_dea, a_macd,now,l_dif, l_dea, l_macd)
    if a_dif < a_dea and l_dif > l_dea:
        print(now, '金叉形成')
    elif a_dif > a_dea and l_dif < l_dea:
        print(now,'死叉形成')
    else:
        print(now, '维持不变')
2018-11-12 09:30:00 维持不变
2018-11-12 09:35:00 维持不变
2018-11-12 09:40:00 维持不变
2018-11-12 09:45:00 维持不变
2018-11-12 09:50:00 维持不变
2018-11-12 09:55:00 死叉形成
2018-11-12 10:00:00 死叉形成
2018-11-12 10:05:00 维持不变
2018-11-12 10:10:00 维持不变
2018-11-12 10:15:00 维持不变
2018-11-12 10:20:00 维持不变
2018-11-12 10:25:00 金叉形成

周、月、年级别的MACD使用方法同上,又因MACD的延迟性,在该时间使用的人较少,这里不再列出调用代码,使用者可改变参数使用。

由于在研究中使用代码,常常使用到非交易日期,如果在回测中使用,则不会出现非交易日期。

敝人能力有限,如有错误的地方,还请指证,欢迎提出更正建议!O(∩_∩)O~~¶

全部回复

0/140

量化课程

    移动端课程