我有一个包含股票数据并按股票分组的数据框(例如,参见附图),索引是每只股票的每分钟数据,第二列是股票代码。
我正在尝试使用 groupby 将“Pandas TA”指标应用于数据框,以便单独处理每只股票的数据,并使用 Pandas TA 的内置多重处理。我有一个主要的回测文件,它调用此函数向原始数据添加指标(原始数据是开盘价、最高价、最低价、收盘价、成交量),但此代码仅返回一个空白数据框。
import pandas_ta as ta
def simple_strategy(df):
CustomStrategy = ta.Strategy(
name="Momo and Volatility",
description="SMA 50,200, BBANDS, RSI, MACD and Volume SMA 20",
ta=[
{"kind": "sma", "length": 20},
{"kind": "sma", "length": 60},
{"kind": "bbands", "length": 20},
]
)
df = df.groupby(['symbol']).apply(lambda x:
df.ta.strategy(CustomStrategy) ).reset_index(0,drop=True)
print(df)
这是我的主程序的一部分,它调用上述函数将指标应用于数据帧。
import numpy as np
import pandas as pd
from alpaca_trade_api.rest import REST, TimeFrame
import os
from datetime import datetime, timedelta, date
import time
import pandas_ta as ta
from strategies import simple_strategy
if __name__ == '__main__':
stocks = ['TSLA', 'AAPL', 'V', 'MSFT', 'TQQQ', 'SQQQ', 'ARKK', 'TLRY', 'XELA']
start = "2021-06-01"
end = "2021-12-22"
#Retrieve raw dataframe****************************************************
total_data = access_dataframe(start, end, stocks, dates)
#Apply indicators to dataframe *************************************
total_data = simple_strategy(total_data)
任何使用 groupby 将“Pandas TA”应用到数据帧的解决方案都将受到极大的重视。
两个选项 1)使用
apply()
,2)迭代组。对于只有三个符号和形状 df.shape (12096, 7)
的数据框,两种方法都使用 %%timeit - 3.4 seconds
花费相同的时间。您可以对较大的数据帧进行一些测试,看看一种方法是否比其他方法更快。
选项1
CustomStrategy = ta.Strategy(
name="Momo and Volatility",
description="SMA 50,200, BBANDS, RSI, MACD and Volume SMA 20",
ta=[
{"kind": "sma", "length": 20},
{"kind": "sma", "length": 60},
{"kind": "bbands", "length": 20}
]
)
def apply_strat(x):
x.ta.strategy(CustomStrategy)
return x
newdf = df.groupby(['Symbol']).apply(apply_strat)
选项2
df_list = []
dfg = df.groupby(['Symbol'])
for grp in dfg.groups:
x = dfg.get_group(grp).copy()
x.ta.strategy(CustomStrategy)
df_list.append(x)
newdf = pd.concat(df_list)
这应该可行:
将 pandas 导入为 pd 导入 pandas_ta
df.groupby('symbol')[['symbol','open','high','low','close']].apply(lambda x: x.ta.atr(length=14))[ 0].bfill().reset_index(drop=True)