【金融】【python】使用python处理多种期货数据指标
featureExtraction.py
自己在网上搜的然后复现的,可能不是很准确。
包括:Relative Strength Index(相对强度指数)Stochastic Oscillator(随机振荡器)Williams %R(威廉指数)Moving Average Convergence Divergence(移动平均收敛发散)Price Rate of Change(价格变化率)Simple 10-day moving averageWeighted 10-day moving averageMomentumA/D (Accumulation/Distribution) OscillatorCCI (Commodity Channel Index)
import numpy as np
def RSI(data):
"""
Relative Strength Index(相对强度指数):
选择`14天`RSI,平均上涨为0则RSI=0,平均下跌为0则RSI=100
参考https://blog.csdn.net/pureszgd/article/details/83661531
Params:
----------
data: np.array, columns rank as `Open, High, Low, Close`.
"""
data = data[:, 3]
length = data.size
diff = np.zeros(length)
rsi = np.zeros(length)
n = 14
for i in range(1, length):
diff[i] = data[i] - data[i-1]
up_avg = sum(diff[0:n][diff[0:n] > 0]) / n
down_avg = sum(-1 * diff[0:n][diff[0:n] < 0]) / n
rs = up_avg / down_avg
rsi[n-1] = 100 - 100 / (1 + rs)
for i in range(n, length):
# if len(diff[i-14:i] >= 0) == 0:
# rsi[i] = 100
# continue
up = 0
down = 0
if diff[i] > 0:
up = diff[i]
else:
down = -1 * diff[i]
# RS = np.mean(diff[i-14:i][diff[i-14:i] > 0]) / abs(np.mean(diff[i-14:i][diff[i-14:i] < 0]))
up_avg = (up_avg * (n - 1) + up) / n
down_avg = (down_avg * (n - 1) + down) / n
RS = up_avg / down_avg
rsi[i] = 100 - 100 / (1 + RS)
if np.isnan(rsi[i]):
print('RSI get nan', diff[i-14:i])
return rsi
def SO(data):
"""
Stochastic K%
Stochastic Oscillator(随机振荡器):
主要研究高低价位与收市价的关系,反映价格走势的强弱和超买超卖现象。
采用`14天`Stochastic Oscillator(随机振荡器)
Stochastic D% 由于按照定义, Stochastic K%实际与William’s R%相关。
因而取Stochastic D%,即Stochastic K%的`3天`移动平均
Params:
----------
data: np.array, columns rank as `Open, High, Low, Close`.
"""
length = data[:, 3].size
K = np.zeros(length)
D = np.zeros(length)
n = 14
for i in range(n-1, length):
C = data[i, 3]
L14 = min(data[i-n+1:i+1, 2])
H14 = max(data[i-n+1:i+1, 1])
K[i] = 100 * (C - L14) / (H14 - L14)
D[i] = sum(K[i-2:i+1]) / 3
return D
def WR(data):
"""
(Larry William’s R%)
Williams %R(威廉指数):
采用`14天`Williams %R
-100 * (H14 - C) / (H14 - L14)
Params:
----------
data: np.array, columns rank as `Open, High, Low, Close`.
"""
length = data[:, 3].size
R = np.zeros(length)
n = 14
for i in range(n-1, length):
C = data[i, 3]
L14 = min(data[i-n+1:i+1, 2])
H14 = max(data[i-n+1:i+1, 1])
R[i] = -100 * (H14 - C) / (H14 - L14)
return R
def MACD(data):
"""
Moving Average Convergence Divergence(移动平均收敛发散):
MACD = `EMA_12`(C) − `EMA_26`(C)
EMA: v(t) = β⋅v(t−1) + (1−β)⋅θ(t), 取 `β = 0.9`
则EMA12的 β = 1 - 1/12 = 0.9167, EMA26的 β = 1 - 1/26 = 0.9615
Params:
----------
data: np.array, columns rank as `Open, High, Low, Close`.
"""
data = data[:, 3]
length = data.size
macd = np.zeros(length)
EMA12 = np.zeros(length)
EMA26 = np.zeros(length)
EMA12[0] = data[0]
EMA26[0] = data[0]
for i in range(1, length):
EMA12[i] = 0.9167 * EMA12[i-1] + 0.0833 * data[i]
EMA26[i] = 0.9615 * EMA26[i-1] + 0.0385 * data[i]
macd[i] = EMA12[i] - EMA26[i]
return macd
def PROC(data):
"""
Price Rate of Change(价格变化率):
采用`1天`Price Rate of Change
Params:
----------
data: np.array, columns rank as `Open, High, Low, Close`.
"""
data = data[:, 3]
length = data.size
proc = np.zeros(length)
# TODO: 注意data中不能有0值
proc[1:] = (data[1:] - data[:-1]) / data[:-1]
return proc
def Simple10MA(data):
"""
Simple 10-day moving average
"""
data = data[:, 3]
length = data.size
simple10MA = np.zeros(length)
n = 10
sum10 = np.sum(data[0:n])
simple10MA[n-1] = sum10 / n
for i in range(n, length):
sum10 = sum10 - data[i-n] + data[i]
simple10MA[i] = sum10 / n
return simple10MA
def Weighted10MA(data):
"""
Weighted 10-day moving average
Params:
----------
data: np.array, columns rank as `Open, High, Low, Close`.
"""
data = data[:, 3]
length = data.size
weighted10MA = np.zeros(length)
n = 10
sumN = (n + 1) * n / 2
for i in range(n-1, length):
weightedSum = 0
for j in range(n):
weightedSum += (n-j) * data[i-j]
weighted10MA[i] = weightedSum / sumN
return weighted10MA
def Momentum(data):
"""
Momentum
C_t - C_{t-n}
Params:
----------
data: np.array, columns rank as `Open, High, Low, Close`.
"""
n = 10
data = data[:, 3]
length = data.size
momentum = np.zeros(length)
for i in range(n-1, length):
momentum[i] = data[i] - data[i - n + 1]
return momentum
def ADOscillator(data):
"""
A/D (Accumulation/Distribution) Oscillator
(H_t - C_{t-1}) / (H_t - L_t)
Params:
----------
data: np.array, columns rank as `Open, High, Low, Close`.
"""
length = data[:,3].size
ado = np.zeros(length)
for i in range(1, length):
ado[i] = (data[i,1] - data[i-1,3]) / (data[i,1] - data[i,2])
return ado
def CCI(data):
"""
CCI (Commodity Channel Index)
CCI_t = (M_t - SM_t) / (0.015 * D_t)
M_t = (H_t + L_t + C_t) / 3
SM_t = (Σn M_{t-i+1}) / n
D_t = (Σn |M_{t-i+1} - SM_t|) / n
Params:
----------
data: np.array, columns rank as `Open, High, Low, Close`.
"""
length = data[:,3].size
cci = np.zeros(length)
m = np.zeros(length)
n = 14
for i in range(n-1):
m[i] = (data[i,1] + data[i,2] + data[i,3]) / 3
for i in range(n-1, length):
m[i] = (data[i,1] + data[i,2] + data[i,3]) / 3
SM = sum(m[i-n+1:i+1]) / n
D = sum(abs(m[i-n+1:i+1] - SM)) / n
cci[i] = (m[i] - SM) / (0.015 * D)
return cci
if __name__ == '__main__':
data = np.random.randint(0,10,(30,4))
rsi = RSI(data)
print('rsi', rsi)
so = SO(data)
print('so', so)
wr = WR(data)
print('wr', wr)
macd = MACD(data)
print('macd', macd)
proc = PROC(data)
print('proc', proc)
simpleMA = Simple10MA(data)
print('simpleMA', simpleMA)
weightedMA = Weighted10MA(data)
print('weightedMA', weightedMA)
momentum = Momentum(data)
print('momentum', momentum)
ado = ADOscillator(data)
print('ado', ado)
cci = CCI(data)
print('cci', cci)
pandas_techinal_indicators.py
采用jmartinezheras/reproduce-stock-market-direction-random-forests实现的文件。
包括:moving_averageexponential_moving_averagemomentumrate_of_change(ROC)average_true_range(真实波动幅度均值 Average True Range)bollinger_bandsppsr(Pivot Points, Supports and Resistances)stochastic_oscillator_k(stochastic oscillator %K)stochastic_oscillator_d(stochastic oscillator %D)trix(三重指数平滑平均线(TRIX))average_directional_movement_index(Average Directional Movement Index)macd(MACD, MACD Signal and MACD difference)mass_indexvortex_indicator(涡旋指标(VI))kst_oscillator(KST Oscillator)relative_strength_index(RSI)true_strength_index(TSI)accumulation_distribution(A/D 累计派发指标)chaikin_oscillatormoney_flow_index(Money FLOW Index资金流量指标又被称为相对强弱指标)on_balance_volume(能量潮指标)force_indexease_of_movement(简易波动指标-Ease of Movement)commodity_channel_index(CCI指标/顺势指标)coppock_curvekeltner_channelultimate_oscillatordonchian_channelstandard_deviation
"""
Indicators as shown by Peter Bakker at:
https://www.quantopian.com/posts/technical-analysis-indicators-without-talib-code
"""
"""
25-Mar-2018: Fixed syntax to support the newest version of Pandas. Warnings should no longer appear.
Fixed some bugs regarding min_periods and NaN.
If you find any bugs, please report to github.com/palmbook
"""
# Import Built-Ins
import logging
# Import Third-Party
import pandas as pd
import numpy as np
# Import Homebrew
# Init Logging Facilities
log = logging.getLogger(__name__)
def moving_average(df, n):
"""Calculate the moving average for the given data.
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
MA = pd.Series(df['Close'].rolling(n, min_periods=n).mean(), name='MA_' + str(n))
df = df.join(MA)
return df
def exponential_moving_average(df, n):
"""
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
EMA = pd.Series(df['Close'].ewm(span=n, min_periods=n).mean(), name='EMA_' + str(n))
df = df.join(EMA)
return df
def momentum(df, n):
"""
【使用】Momentum
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
M = pd.Series(df['Close'].diff(n), name='Momentum_' + str(n))
df = df.join(M)
return df
def rate_of_change(df, n):
"""
【使用】ROC
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
M = df['Close'].diff(n - 1)
N = df['Close'].shift(n - 1)
ROC = pd.Series(M / N, name='ROC_' + str(n))
df = df.join(ROC)
return df
def average_true_range(df, n):
"""
【使用】真实波动幅度均值 Average True Range 简介
平均真实波动范围(Average true range)简称ATR指标,是由J.Welles Wilder 发明的,
ATR指标主要是用来衡量市场波动的强烈度,即为了显示市场变化率的指标。
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
i = 0
TR_l = [0]
while i < df.index[-1]:
TR = max(df.loc[i + 1, 'High'], df.loc[i, 'Close']) - min(df.loc[i + 1, 'Low'], df.loc[i, 'Close'])
TR_l.append(TR)
i = i + 1
TR_s = pd.Series(TR_l)
ATR = pd.Series(TR_s.ewm(span=n, min_periods=n).mean(), name='ATR_' + str(n))
df = df.join(ATR)
return df
def bollinger_bands(df, n):
"""
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
MA = pd.Series(df['Close'].rolling(n, min_periods=n).mean())
MSD = pd.Series(df['Close'].rolling(n, min_periods=n).std())
b1 = 4 * MSD / MA
B1 = pd.Series(b1, name='BollingerB_' + str(n))
df = df.join(B1)
b2 = (df['Close'] - MA + 2 * MSD) / (4 * MSD)
B2 = pd.Series(b2, name='Bollinger%b_' + str(n))
df = df.join(B2)
return df
def ppsr(df):
"""Calculate Pivot Points, Supports and Resistances for given data
:param df: pandas.DataFrame
:return: pandas.DataFrame
"""
PP = pd.Series((df['High'] + df['Low'] + df['Close']) / 3)
R1 = pd.Series(2 * PP - df['Low'])
S1 = pd.Series(2 * PP - df['High'])
R2 = pd.Series(PP + df['High'] - df['Low'])
S2 = pd.Series(PP - df['High'] + df['Low'])
R3 = pd.Series(df['High'] + 2 * (PP - df['Low']))
S3 = pd.Series(df['Low'] - 2 * (df['High'] - PP))
psr = {'PP': PP, 'R1': R1, 'S1': S1, 'R2': R2, 'S2': S2, 'R3': R3, 'S3': S3}
PSR = pd.DataFrame(psr)
df = df.join(PSR)
return df
def stochastic_oscillator_k(df):
"""Calculate stochastic oscillator %K for given data.
:param df: pandas.DataFrame
:return: pandas.DataFrame
"""
SOk = pd.Series((df['Close'] - df['Low']) / (df['High'] - df['Low']), name='SO%k')
df = df.join(SOk)
return df
def stochastic_oscillator_d(df, n):
"""Calculate stochastic oscillator %D for given data.
【使用】
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
SOk = pd.Series((df['Close'] - df['Low']) / (df['High'] - df['Low']), name='SO%k')
SOd = pd.Series(SOk.ewm(span=n, min_periods=n).mean(), name='SO%d_' + str(n))
df = df.join(SOd)
return df
def trix(df, n):
"""Calculate TRIX for given data.
【使用】三重指数平滑平均线(TRIX)
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
EX1 = df['Close'].ewm(span=n, min_periods=n).mean()
EX2 = EX1.ewm(span=n, min_periods=n).mean()
EX3 = EX2.ewm(span=n, min_periods=n).mean()
i = 0
ROC_l = [np.nan]
while i + 1 <= df.index[-1]:
ROC = (EX3[i + 1] - EX3[i]) / EX3[i]
ROC_l.append(ROC)
i = i + 1
Trix = pd.Series(ROC_l, name='Trix_' + str(n))
df = df.join(Trix)
return df
def average_directional_movement_index(df, n, n_ADX):
"""Calculate the Average Directional Movement Index for given data.
:param df: pandas.DataFrame
:param n:
:param n_ADX:
:return: pandas.DataFrame
"""
i = 0
UpI = []
DoI = []
while i + 1 <= df.index[-1]:
UpMove = df.loc[i + 1, 'High'] - df.loc[i, 'High']
DoMove = df.loc[i, 'Low'] - df.loc[i + 1, 'Low']
if UpMove > DoMove and UpMove > 0:
UpD = UpMove
else:
UpD = 0
UpI.append(UpD)
if DoMove > UpMove and DoMove > 0:
DoD = DoMove
else:
DoD = 0
DoI.append(DoD)
i = i + 1
i = 0
TR_l = [0]
while i < df.index[-1]:
TR = max(df.loc[i + 1, 'High'], df.loc[i, 'Close']) - min(df.loc[i + 1, 'Low'], df.loc[i, 'Close'])
TR_l.append(TR)
i = i + 1
TR_s = pd.Series(TR_l)
ATR = pd.Series(TR_s.ewm(span=n, min_periods=n).mean())
UpI = pd.Series(UpI)
DoI = pd.Series(DoI)
PosDI = pd.Series(UpI.ewm(span=n, min_periods=n).mean() / ATR)
NegDI = pd.Series(DoI.ewm(span=n, min_periods=n).mean() / ATR)
ADX = pd.Series((abs(PosDI - NegDI) / (PosDI + NegDI)).ewm(span=n_ADX, min_periods=n_ADX).mean(),
name='ADX_' + str(n) + '_' + str(n_ADX))
df = df.join(ADX)
return df
def macd(df, n_fast, n_slow):
"""Calculate MACD, MACD Signal and MACD difference
:param df: pandas.DataFrame
:param n_fast:
:param n_slow:
:return: pandas.DataFrame
"""
EMAfast = pd.Series(df['Close'].ewm(span=n_fast, min_periods=n_slow).mean())
EMAslow = pd.Series(df['Close'].ewm(span=n_slow, min_periods=n_slow).mean())
MACD = pd.Series(EMAfast - EMAslow, name='MACD_' + str(n_fast) + '_' + str(n_slow))
MACDsign = pd.Series(MACD.ewm(span=9, min_periods=9).mean(), name='MACDsign_' + str(n_fast) + '_' + str(n_slow))
MACDdiff = pd.Series(MACD - MACDsign, name='MACDdiff_' + str(n_fast) + '_' + str(n_slow))
df = df.join(MACD)
df = df.join(MACDsign)
df = df.join(MACDdiff)
return df
def mass_index(df):
"""Calculate the Mass Index for given data.
:param df: pandas.DataFrame
:return: pandas.DataFrame
"""
Range = df['High'] - df['Low']
EX1 = Range.ewm(span=9, min_periods=9).mean()
EX2 = EX1.ewm(span=9, min_periods=9).mean()
Mass = EX1 / EX2
MassI = pd.Series(Mass.rolling(25).sum(), name='Mass Index')
df = df.join(MassI)
return df
def vortex_indicator(df, n):
"""Calculate the Vortex Indicator for given data.
【使用】涡旋指标(VI)
Vortex Indicator described here:
http://www.vortexindicator.com/VFX_VORTEX.PDF
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
i = 0
TR = [0]
while i < df.index[-1]:
Range = max(df.loc[i + 1, 'High'], df.loc[i, 'Close']) - min(df.loc[i + 1, 'Low'], df.loc[i, 'Close'])
TR.append(Range)
i = i + 1
i = 0
VM = [0]
while i < df.index[-1]:
Range = abs(df.loc[i + 1, 'High'] - df.loc[i, 'Low']) - abs(df.loc[i + 1, 'Low'] - df.loc[i, 'High'])
VM.append(Range)
i = i + 1
VI = pd.Series(pd.Series(VM).rolling(n).sum() / pd.Series(TR).rolling(n).sum(), name='Vortex_' + str(n))
df = df.join(VI)
return df
def kst_oscillator(df, r1, r2, r3, r4, n1, n2, n3, n4):
"""Calculate KST Oscillator for given data.
:param df: pandas.DataFrame
:param r1:
:param r2:
:param r3:
:param r4:
:param n1:
:param n2:
:param n3:
:param n4:
:return: pandas.DataFrame
"""
M = df['Close'].diff(r1 - 1)
N = df['Close'].shift(r1 - 1)
ROC1 = M / N
M = df['Close'].diff(r2 - 1)
N = df['Close'].shift(r2 - 1)
ROC2 = M / N
M = df['Close'].diff(r3 - 1)
N = df['Close'].shift(r3 - 1)
ROC3 = M / N
M = df['Close'].diff(r4 - 1)
N = df['Close'].shift(r4 - 1)
ROC4 = M / N
KST = pd.Series(
ROC1.rolling(n1).sum() + ROC2.rolling(n2).sum() * 2 + ROC3.rolling(n3).sum() * 3 + ROC4.rolling(n4).sum() * 4,
name='KST_' + str(r1) + '_' + str(r2) + '_' + str(r3) + '_' + str(r4) + '_' + str(n1) + '_' + str(
n2) + '_' + str(n3) + '_' + str(n4))
df = df.join(KST)
return df
def relative_strength_index(df, n):
"""Calculate Relative Strength Index(RSI) for given data.
【使用】
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
i = 0
UpI = [0]
DoI = [0]
while i + 1 <= df.index[-1]:
UpMove = df.loc[i + 1, 'High'] - df.loc[i, 'High']
DoMove = df.loc[i, 'Low'] - df.loc[i + 1, 'Low']
if UpMove > DoMove and UpMove > 0:
UpD = UpMove
else:
UpD = 0
UpI.append(UpD)
if DoMove > UpMove and DoMove > 0:
DoD = DoMove
else:
DoD = 0
DoI.append(DoD)
i = i + 1
UpI = pd.Series(UpI)
DoI = pd.Series(DoI)
PosDI = pd.Series(UpI.ewm(span=n, min_periods=n).mean())
NegDI = pd.Series(DoI.ewm(span=n, min_periods=n).mean())
RSI = pd.Series(PosDI / (PosDI + NegDI), name='RSI_' + str(n))
df = df.join(RSI)
return df
def true_strength_index(df, r, s):
"""Calculate True Strength Index (TSI) for given data.
:param df: pandas.DataFrame
:param r:
:param s:
:return: pandas.DataFrame
"""
M = pd.Series(df['Close'].diff(1))
aM = abs(M)
EMA1 = pd.Series(M.ewm(span=r, min_periods=r).mean())
aEMA1 = pd.Series(aM.ewm(span=r, min_periods=r).mean())
EMA2 = pd.Series(EMA1.ewm(span=s, min_periods=s).mean())
aEMA2 = pd.Series(aEMA1.ewm(span=s, min_periods=s).mean())
TSI = pd.Series(EMA2 / aEMA2, name='TSI_' + str(r) + '_' + str(s))
df = df.join(TSI)
return df
def accumulation_distribution(df, n):
"""Calculate Accumulation/Distribution for given data.
【使用】A/D 累计派发指标
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
ad = (2 * df['Close'] - df['High'] - df['Low']) / (df['High'] - df['Low']) * df['Volume']
M = ad.diff(n - 1)
N = ad.shift(n - 1)
ROC = M / N
AD = pd.Series(ROC, name='Acc/Dist_ROC_' + str(n))
df = df.join(AD)
return df
def chaikin_oscillator(df):
"""Calculate Chaikin Oscillator for given data.
:param df: pandas.DataFrame
:return: pandas.DataFrame
"""
ad = (2 * df['Close'] - df['High'] - df['Low']) / (df['High'] - df['Low']) * df['Volume']
Chaikin = pd.Series(ad.ewm(span=3, min_periods=3).mean() - ad.ewm(span=10, min_periods=10).mean(), name='Chaikin')
df = df.join(Chaikin)
return df
def money_flow_index(df, n):
"""Calculate Money Flow Index and Ratio for given data.
Money FLOW Index资金流量指标又被称为相对强弱指标
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
PP = (df['High'] + df['Low'] + df['Close']) / 3
i = 0
PosMF = [0]
while i < df.index[-1]:
if PP[i + 1] > PP[i]:
PosMF.append(PP[i + 1] * df.loc[i + 1, 'Volume'])
else:
PosMF.append(0)
i = i + 1
PosMF = pd.Series(PosMF)
TotMF = PP * df['Volume']
MFR = pd.Series(PosMF / TotMF)
MFI = pd.Series(MFR.rolling(n, min_periods=n).mean(), name='MFI_' + str(n))
df = df.join(MFI)
return df
def on_balance_volume(df, n):
"""Calculate On-Balance Volume for given data.
【使用】能量潮指标
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
i = 0
OBV = [0]
while i < df.index[-1]:
if df.loc[i + 1, 'Close'] - df.loc[i, 'Close'] > 0:
OBV.append(df.loc[i + 1, 'Volume'])
if df.loc[i + 1, 'Close'] - df.loc[i, 'Close'] == 0:
OBV.append(0)
if df.loc[i + 1, 'Close'] - df.loc[i, 'Close'] < 0:
OBV.append(-df.loc[i + 1, 'Volume'])
i = i + 1
OBV = pd.Series(OBV)
OBV_ma = pd.Series(OBV.rolling(n, min_periods=n).mean(), name='OBV_' + str(n))
df = df.join(OBV_ma)
return df
def force_index(df, n):
"""Calculate Force Index for given data.
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
F = pd.Series(df['Close'].diff(n) * df['Volume'].diff(n), name='Force_' + str(n))
df = df.join(F)
return df
def ease_of_movement(df, n):
"""Calculate Ease of Movement for given data.
【使用】简易波动指标-Ease of Movement
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
EoM = (df['High'].diff(1) + df['Low'].diff(1)) * (df['High'] - df['Low']) / (2 * df['Volume'])
Eom_ma = pd.Series(EoM.rolling(n, min_periods=n).mean(), name='EoM_' + str(n))
df = df.join(Eom_ma)
return df
def commodity_channel_index(df, n):
"""Calculate Commodity Channel Index for given data.
【使用】CCI指标又叫顺势指标,其英文全名为Commodity Channel Index
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
PP = (df['High'] + df['Low'] + df['Close']) / 3
CCI = pd.Series((PP - PP.rolling(n, min_periods=n).mean()) / PP.rolling(n, min_periods=n).std(),
name='CCI_' + str(n))
df = df.join(CCI)
return df
def coppock_curve(df, n):
"""Calculate Coppock Curve for given data.
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
M = df['Close'].diff(int(n * 11 / 10) - 1)
N = df['Close'].shift(int(n * 11 / 10) - 1)
ROC1 = M / N
M = df['Close'].diff(int(n * 14 / 10) - 1)
N = df['Close'].shift(int(n * 14 / 10) - 1)
ROC2 = M / N
Copp = pd.Series((ROC1 + ROC2).ewm(span=n, min_periods=n).mean(), name='Copp_' + str(n))
df = df.join(Copp)
return df
def keltner_channel(df, n):
"""Calculate Keltner Channel for given data.
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
KelChM = pd.Series(((df['High'] + df['Low'] + df['Close']) / 3).rolling(n, min_periods=n).mean(),
name='KelChM_' + str(n))
KelChU = pd.Series(((4 * df['High'] - 2 * df['Low'] + df['Close']) / 3).rolling(n, min_periods=n).mean(),
name='KelChU_' + str(n))
KelChD = pd.Series(((-2 * df['High'] + 4 * df['Low'] + df['Close']) / 3).rolling(n, min_periods=n).mean(),
name='KelChD_' + str(n))
df = df.join(KelChM)
df = df.join(KelChU)
df = df.join(KelChD)
return df
def ultimate_oscillator(df):
"""Calculate Ultimate Oscillator for given data.
:param df: pandas.DataFrame
:return: pandas.DataFrame
"""
i = 0
TR_l = [0]
BP_l = [0]
while i < df.index[-1]:
TR = max(df.loc[i + 1, 'High'], df.loc[i, 'Close']) - min(df.loc[i + 1, 'Low'], df.loc[i, 'Close'])
TR_l.append(TR)
BP = df.loc[i + 1, 'Close'] - min(df.loc[i + 1, 'Low'], df.loc[i, 'Close'])
BP_l.append(BP)
i = i + 1
UltO = pd.Series((4 * pd.Series(BP_l).rolling(7).sum() / pd.Series(TR_l).rolling(7).sum()) + (
2 * pd.Series(BP_l).rolling(14).sum() / pd.Series(TR_l).rolling(14).sum()) + (
pd.Series(BP_l).rolling(28).sum() / pd.Series(TR_l).rolling(28).sum()),
name='Ultimate_Osc')
df = df.join(UltO)
return df
def donchian_channel(df, n):
"""Calculate donchian channel of given pandas data frame.
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
i = 0
dc_l = []
while i < n - 1:
dc_l.append(0)
i += 1
i = 0
while i + n - 1 < df.index[-1]:
dc = max(df['High'].ix[i:i + n - 1]) - min(df['Low'].ix[i:i + n - 1])
dc_l.append(dc)
i += 1
donchian_chan = pd.Series(dc_l, name='Donchian_' + str(n))
donchian_chan = donchian_chan.shift(n - 1)
return df.join(donchian_chan)
def standard_deviation(df, n):
"""Calculate Standard Deviation for given data.
:param df: pandas.DataFrame
:param n:
:return: pandas.DataFrame
"""
df = df.join(pd.Series(df['Close'].rolling(n, min_periods=n).std(), name='STD_' + str(n)))
return df