I am doing these calculations across multiple stocks, so I created a dictionary which I then concatenate. Here is the code:
stocklist=["^SPX", "^DJI"]
d={}
def averageGain14(dailyGain):
if dailyGain>= 0:
gain = dailyGain
return gain
for name in stocklist:
d[name]= pd.DataFrame()
data = yf.Ticker(name)
data = data.history(start=myStart, end=myEnd)
d[name]= pd.DataFrame(data)
d[name]["Daily Gain"]=d[name]["Close"].diff()
d[name]['Average Gain'] = d[name]["Daily Gain"].apply(averageGain14)
d[name] = d[name].add_prefix(name)
modelData = pd.concat(d.values(), axis=1)
如您所见,我尝试在顶部为averagegain14定义一个函数,该函数当前尚未执行任何操作,但会在一天结束时返回增益值(使其正常工作的步骤1)。在 For 循环中,我尝试将“平均增益”列设置为计算字段,将该函数应用于“每日增益”列,但我似乎遇到了错误。我尝试了一些方法,但没有效果。首先我尝试过
d[name]['Average Gain'] = d[name].rolling(14).mean().where(d[name]['Daily Gain'] >= 0, 0)
rolling
返回多个值很棘手,因此拥有两个函数可能更容易。您可以控制
min_periods
以及是否想要使用
.ge
和
.le
而不是 .
gt
和
.lt
(例如:大于或等于与大于)。
import numpy as np
import pandas as pd
def gain_avg(p):
return p.loc[p.gt(p.shift())].mean()
def loss_avg(p):
return p.loc[p.lt(p.shift())].mean()
prices = np.random.randint(10,20,100)
df = pd.DataFrame(prices, columns=['prices'])
df['gain_avg'] = df.prices.rolling(14, min_periods=1).apply(lambda x: gain_avg(x))
df['loss_avg'] = df.prices.rolling(14, min_periods=1).apply(lambda x: loss_avg(x))
输出
prices gain_avg loss_avg
0 17 NaN NaN
1 19 19.00 NaN
2 17 19.00 17.000000
3 13 19.00 15.000000
4 17 18.00 15.000000
5 13 18.00 14.333333
6 15 17.00 14.333333
7 11 17.00 13.500000
8 18 17.25 13.500000
9 15 17.25 13.800000