使用ta-lib计算macd,如何取近几天的历史值

策略分享
标签: #<Tag:0x00007f4cdb6ebca0>

(tianshangrenjian) #1

查看官网,关于使用ta-lib计算macd的macd、signal、hist值,有2种写法
1、df[‘macd’], df[‘signal’], df[‘hist’] = talib.MACD(np.array(prices), 12, 26, 9)
2、macd, signal, hist = talib.MACD(np.array(prices), 12, 26, 9)

方法2可以 使用macd[-1]取近一天的历史值,

请问方法1 ,在M.input_features.v1()函数中,如何取 近几天的指标值呢


(iQuant) #2

您好,收到您的提问,已提交至策略工程师,会尽快给您回复。


(xgl891) #3

取一段时间的数据计算MACD,比如:

date macd
01-01 1
01-02 2
01-03 3
01-04 4

然后对macd那列数据shift()一下得到一列新的数据

date macd shift(macd)
01-01 1 null
01-02 2 1
01-03 3 2
01-04 4 3

这列新的数据就相当于macd(-1)
不知道你问的是不是这个意思呀?


(tianshangrenjian) #4

就是需要利用macd、signal、hist这3个值查找金叉、死叉些情况

比如,方法2 获取这3个值后,可以直接 if macd[-1] - signal[-1] < 0 and macd[-2] - signal[-2] > 0 进行判断

但方法1 获取这3个值后,在M.input_features.v1函数里 使用macd[-1]就会报错

是不是 数据类型 需要转换一下


(xgl891) #6

np.array(df[‘macd’])[-1]


(xgl891) #7

或者您也可以选择使用平台的可视化模块,在输入特征列表模块的属性栏中输入如下特征:
1
提取特征之后即可得到您想要的数据列表。
更多相关的技术因子详见 因子库


(tianshangrenjian) #8

谢谢啦。还是报错:

module name: derived_feature_extractor, module version: v3, trackeback: Traceback (most recent call last):
Exception: invalid expression: Subscript(value=Call(func=Attribute(value=Name(id='np', ctx=Load()), attr='array', ctx=Load()), args=[Name(id='macd', ctx=Load())], keywords=[]), slice=Index(value=UnaryOp(op=USub(), operand=Num(n=1))), ctx=Load())

(小Q) #9

您能将你完成一点的策略分享到社区我们看看吗?只看截图的话,不是很好debug.


(tianshangrenjian) #10

初学,代码、思路都不成熟。。。谢谢啦


# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
def m1_run(input_1, input_2, input_3):
    # 示例代码如下。在这里编写您的代码
    df = input_1.read_df()
    prices = df['close'].map(np.float)  # 转化成float格式
#     print('====',prices)
    
    import talib
    df['macd'], df['signal'], df['hist'] = talib.MACD(np.array(prices), 12, 26, 9)  # 计算macd各个指标,国内常用的参数12、26、9    
    data_1 = DataSource.write_df(df)
    
    pd.set_option('display.max_rows', 200)  
#     print( df['macd'] )
    
    return Outputs(data_1=data_1, data_2=None, data_3=None)

# 后处理函数
def m2_post_run(outputs):
    return outputs



# 证券代码列表
m2 = M.instruments.v2(
    m_cached=False,
    
    start_date='2018-01-01',
    end_date='2019-08-23',
    market='CN_STOCK_A',
    instrument_list='',
    max_count=0
)

# 输入特征列表
m3 = M.input_features.v1(
    m_cached=False,
    
    features="""
# #号开始的表示注释,注释需单独一行
# 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征
    high
    open
    low
    close
    amount
"""
)

# 读取基本特征
m1 = M.use_datasource.v1(
    m_cached=False,
    
    instruments=m2.data,     #代码
    features=m3.data,        #特征
    
    datasource_id='bar1d_CN_STOCK_A',          #a股日线
    start_date='',
    end_date=''
)




# M.cached本质还是 函数调用
m6 = M.cached.v3(
    m_cached=False,
    
    input_1=m1.data,                    #使用datasource格式数据
    
    run=m1_run,                         #调用 主函数
    post_run=m2_post_run,               #调用 数据传递函数
    
    input_ports='',
    params='{}',
    output_ports=''
)



# 42,输入特征列表
m5 = M.input_features.v1(
    m_cached=False,                 
    
    features="""
# #号开始的表示注释,注释需单独一行
# 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征
#     选出满足以下条件的股票:


    cond101 = hist<0
    cond102 = macd < 0 
    cond103 = signal < 0 
    cond104 = signal - macd >0
    cond105 = signal - macd <0.1
    
    

#    cond106 = signal[-1] - macd[-1] > signal - macd
#    此行 调用“昨日”数据报错有报错,
    np.array(df['macd'])[-1] < 0

"""
)

# 衍生特征抽取
m4 = M.derived_feature_extractor.v3(
    input_data=m6.data_1,
    features=m5.data,
    
    date_col='date',
    instrument_col='instrument',
    
    drop_na=False,
    remove_extra_columns=False,
    user_functions={}
)

# 按  选股条件 过滤
m7 = M.filter.v3(
    input_data=m4.data,
#     expr='cond1==True and cond2==True and cond3==True and cond4==True',
    expr=' cond101 == True and cond102==True and cond103==True and cond104==True and cond105==True and cond106==True',
    output_left_data=False
)


m7.data.read_df().head()



(tianshangrenjian) #11

已贴代码,麻烦看下


(iQuant) #12

您好,已提交至策略工程师,会尽快给您回复。


(xgl891) #13

把cond106那行改成:

cond106 = shift(signal,1)-shift(macd,1)> signal - macd
克隆策略
In [1]:
# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
def m1_run(input_1, input_2, input_3):
    # 示例代码如下。在这里编写您的代码
    df = input_1.read_df()
    prices = df['close'].map(np.float)  # 转化成float格式
#     print('====',prices)
    
    import talib
    df['macd'], df['signal'], df['hist'] = talib.MACD(np.array(prices), 12, 26, 9)  # 计算macd各个指标,国内常用的参数12、26、9    
    data_1 = DataSource.write_df(df)
    
    pd.set_option('display.max_rows', 200)  
#     print( df['macd'] )
    
    return Outputs(data_1=data_1, data_2=None, data_3=None)

# 后处理函数
def m2_post_run(outputs):
    return outputs



# 证券代码列表
m2 = M.instruments.v2(
    m_cached=False,
    
    start_date='2018-01-01',
    end_date='2019-08-23',
    market='CN_STOCK_A',
    instrument_list='',
    max_count=0
)

# 输入特征列表
m3 = M.input_features.v1(
    m_cached=False,
    
    features="""
# #号开始的表示注释,注释需单独一行
# 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征
    high
    open
    low
    close
    amount
"""
)

# 读取基本特征
m1 = M.use_datasource.v1(
    m_cached=False,
    
    instruments=m2.data,     #代码
    features=m3.data,        #特征
    
    datasource_id='bar1d_CN_STOCK_A',          #a股日线
    start_date='',
    end_date=''
)




# M.cached本质还是 函数调用
m6 = M.cached.v3(
    m_cached=False,
    
    input_1=m1.data,                    #使用datasource格式数据
    
    run=m1_run,                         #调用 主函数
    post_run=m2_post_run,               #调用 数据传递函数
    
    input_ports='',
    params='{}',
    output_ports=''
)



# 42,输入特征列表
m5 = M.input_features.v1(
    m_cached=False,                 
    
    features="""
# #号开始的表示注释,注释需单独一行
# 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征
#     选出满足以下条件的股票:


    cond101 = hist<0
    cond102 = macd < 0 
    cond103 = signal < 0 
    cond104 = signal - macd >0
    cond105 = signal - macd <0.1
    
    

#    cond106 = signal[-1] - macd[-1] > signal - macd
#    此行 调用“昨日”数据报错有报错,
    cond106 = shift(signal,1)-shift(macd,1)> signal - macd

"""
)

# 衍生特征抽取
m4 = M.derived_feature_extractor.v3(
    input_data=m6.data_1,
    features=m5.data,
    
    date_col='date',
    instrument_col='instrument',
    
    drop_na=False,
    remove_extra_columns=False,
    user_functions={}
)

# 按  选股条件 过滤
m7 = M.filter.v3(
    input_data=m4.data,
#     expr='cond1==True and cond2==True and cond3==True and cond4==True',
    expr=' cond101 == True and cond102==True and cond103==True and cond104==True and cond105==True and cond106==True',
    output_left_data=False
)


m7.data.read_df().head()
Out[1]:
date instrument low open high close amount macd signal hist cond101 cond102 cond103 cond104 cond105 cond106
3812 2018-01-03 601949.SHA 7.490000 7.610000 7.620000 7.540000 113007452.0 -15.092707 -15.007944 -0.084763 True True True True True True
5442 2018-01-03 601566.SHA 18.230566 18.230566 18.409674 18.384087 41040368.0 -7.446358 -7.376319 -0.070039 True True True True True True
6029 2018-01-03 601208.SHA 13.922673 13.989717 14.079107 14.056760 14952870.0 -37.650981 -37.561218 -0.089763 True True True True True True
6097 2018-01-03 603527.SHA 28.520000 29.850000 29.850000 29.139999 145278363.0 -14.229126 -14.178874 -0.050251 True True True True True True
7194 2018-01-04 002641.SZA 26.458820 26.635214 26.811605 26.576416 6770737.0 -17.138321 -17.078331 -0.059990 True True True True True True

(xgl891) #14

如果你是直接在代码框里可以用np.array()改数据格式,但因为你是在 M.input_features.v1这个模块的参数里面用这个数据,所以表达式需要符合模块的表达式引擎,这里可以用shift()函数,参考可视化模块里的用法。
具体的代码及运行结果刚刚已经回复你啦,你可以直接克隆策略使用。


(tianshangrenjian) #15

谢谢,可以运行了

再问下,代码内容或逻辑是不是有问题。为何筛选出来的股票都基本是同一天的,
个人觉得选股结果的 日期应该是分散的,才符合常理


(yangziriver) #16

你将代码中的
m7.data.read_df().head()
改成
m7.data.read_df()
就可以看到更多的结果了,基本上每天都有。再把数据保存成文件。