0

如果你们能提供一个接收 pandas df、函数名、需要的输入列和参数/kwargs 的函数,将不胜感激

import talib

df 的形式为:

                  Open        High         Low       Close     Volume 
Date                                                                          
1993-01-29   43.970001   43.970001   43.750000   43.939999    1003200   
1993-02-01   43.970001   44.250000   43.970001   44.250000     480500
1993-02-02   44.220001   44.380001   44.130001   44.340000     201300

以下代码是可以的:

def ApplyIndicator(df, data_col, indicator_func,period):
    df_copy = df.copy()
    col_name = indicator_func.__name__
    df_copy[col_name]=df_copy[data_col].apply(lambda x:indicator_func(x,period))

    return df_copy

样本:

new_df = ApplyIndicator(df,['Close'],talib.SMA,10)

但是,如果我想要一个可以采用不同列的通用 ApplyIndi​​cator,例如 talib.STOCH,它需要超过 1 个参数并且需要不同的列:

slowk, slowd = STOCH(input_arrays, 5, 3, 0, 3, 0, prices=['high', 'low', 'open'])

对于这种情况,假设所有必需的列都在 df 中,我该如何做一个通用的 ApplyIndi​​cator 函数,该函数在通用 talib 函数上执行。

谢谢你。

有关这两个功能的更多详细信息:

SMA(real[, timeperiod=?])

STOCH(high, low, close[, fastk_period=?, slowk_period=?, slowk_matype=?, slowd_period=?, slowd_matype=?])
4

1 回答 1

0

使用原始的ApplyIndicator,可以这样做:

def slowk(arr, per):
    return STOCH(arr, 5, 3, 0, 3, 0, prices=['high', 'low', 'open'])[0]

new_df = ApplyIndicator(df,['Close'], slowk, None)

Lambda 在这里不起作用,因为它的名称始终是“”,但是使用一些更智能的列命名它们也应该没问题。

为了让它稍微优雅一点,我们可以让任意数量的属性:

def ApplyIndicator(df, indicator_func, *args):
    col_name = indicator_func.__name__
    df[col_name] = df.apply(lambda x:indicator_func(x, *args))
    return df

new_df = ApplyIndicator(df[['Close']], talib.SMA, 10)
new_df = ApplyIndicator(df[...], STOCH, 5, 3, 0, 3, 0, ['high', 'low', 'open'])

但事实上,整个函数是如此微不足道,用这样的单个调用替换它可能更容易:

df[['slowk', 'slowd']] = df.apply(
    lambda idx, row: STOCH(row, 5, 3, 0, 3, 0, ['high', 'low', 'open']))
于 2018-03-23T17:53:13.093 回答