Python/Pandas 计算 Ichimoku 图表组件
Python/Pandas calculate Ichimoku chart components
我有 Pandas DataFrame 对象,其中包含每日股票数据的日期、开盘价、收盘价、最低价和最高价。我想计算 Ichimoku 图表的组成部分。我可以使用以下代码获取我的数据:
high_prices = data['High']
close_prices = data['Close']
low_prices = data['Low']
dates = data['Date'] # contains datetime objects
我需要计算以下系列(Ichimoku 称之为 Tenkan-Sen 线):
(9 期高点 + 9 期低点)/ 2
- 9 期最高价 = 最近 9 天的最高价,
- 9 期低价 = 最近 9 天的最低价,
所以两者都应该在第 9 天开始。
我找到了 R 语言的解决方案 here,但我很难将其翻译成 Python/Pandas 代码。
Ichimoku 图表包含更多组件,但是当我知道如何在 Pandas 中计算 Tenkan-Sen 线时,我将能够计算所有这些(我将共享代码)。
我不是金融专家或绘图专家,但以下显示了示例金融数据以及如何使用 rolling_max
and rolling_min
:
In [60]:
import pandas.io.data as web
import datetime
start = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2013, 1, 27)
data=web.DataReader("F", 'yahoo', start, end)
high_prices = data['High']
close_prices = data['Close']
low_prices = data['Low']
dates = data.index
nine_period_high = df['High'].rolling(window=9).max()
nine_period_low = df['Low'].rolling(window=9).min()
ichimoku = (nine_period_high + nine_period_low) /2
ichimoku
Out[60]:
Date
2010-01-04 NaN
2010-01-05 NaN
2010-01-06 NaN
2010-01-07 NaN
2010-01-08 NaN
2010-01-11 NaN
2010-01-12 NaN
2010-01-13 NaN
2010-01-14 11.095
2010-01-15 11.270
2010-01-19 11.635
2010-01-20 11.730
2010-01-21 11.575
2010-01-22 11.275
2010-01-25 11.220
...
2013-01-04 12.585
2013-01-07 12.685
2013-01-08 13.005
2013-01-09 13.030
2013-01-10 13.230
2013-01-11 13.415
2013-01-14 13.540
2013-01-15 13.675
2013-01-16 13.750
2013-01-17 13.750
2013-01-18 13.750
2013-01-22 13.845
2013-01-23 13.990
2013-01-24 14.045
2013-01-25 13.970
Length: 771
调用 data[['High', 'Low', 'Close', 'ichimoku']].plot()
结果如下图:
更新
在@PedroLobito 的评论指出 incomplete/incorrect 公式后,我采用了@chilliq 的答案并针对 pandas 0.16.1 及更高版本进行了修改:
import pandas as pd
from pandas_datareader import data, wb
import datetime
start = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2013, 1, 27)
d=data.DataReader("F", 'yahoo', start, end)
high_prices = d['High']
close_prices = d['Close']
low_prices = d['Low']
dates = d.index
nine_period_high = df['High'].rolling(window=9).max()
nine_period_low = df['Low'].rolling(window=9).min()
d['tenkan_sen'] = (nine_period_high + nine_period_low) /2
# Kijun-sen (Base Line): (26-period high + 26-period low)/2))
period26_high = high_prices.rolling(window=26).max()
period26_low = low_prices.rolling(window=26).min()
d['kijun_sen'] = (period26_high + period26_low) / 2
# Senkou Span A (Leading Span A): (Conversion Line + Base Line)/2))
d['senkou_span_a'] = ((d['tenkan_sen'] + d['kijun_sen']) / 2).shift(26)
# Senkou Span B (Leading Span B): (52-period high + 52-period low)/2))
period52_high = high_prices.rolling(window=52).max()
period52_low = low_prices.rolling(window=52).min()
d['senkou_span_b'] = ((period52_high + period52_low) / 2).shift(26)
# The most current closing price plotted 22 time periods behind (optional)
d['chikou_span'] = close_prices.shift(-22) # 22 according to investopedia
d.plot()
以下情节的结果,不清楚,因为如前所述,我不是金融专家:
感谢前面的回答,有代码:
# Tenkan-sen (Conversion Line): (9-period high + 9-period low)/2))
period9_high = pd.rolling_max(high_prices, window=9)
period9_low = pd.rolling_min(low_prices, window=9)
tenkan_sen = (period9_high + period9_low) / 2
# Kijun-sen (Base Line): (26-period high + 26-period low)/2))
period26_high = pd.rolling_max(high_prices, window=26)
period26_low = pd.rolling_min(low_prices, window=26)
kijun_sen = (period26_high + period26_low) / 2
# Senkou Span A (Leading Span A): (Conversion Line + Base Line)/2))
senkou_span_a = ((tenkan_sen + kijun_sen) / 2).shift(26)
# Senkou Span B (Leading Span B): (52-period high + 52-period low)/2))
period52_high = pd.rolling_max(high_prices, window=52)
period52_low = pd.rolling_min(low_prices, window=52)
senkou_span_b = ((period52_high + period52_low) / 2).shift(26)
# The most current closing price plotted 22 time periods behind (optional)
chikou_span = close_prices.shift(-22) # 22 according to investopedia
我希望编写 Ichimoku 书籍的人在计算中的说明更加明确。查看上面的代码,我假设如下:
- tenkan-sen:(9 个周期的最高价 + 9 个周期的最低价)/2
选择一个日期。查看前九个时期的最高价。
寻找相同九个时期内的最低低价。添加两个价格
一起并除以二。在日期的 Y 轴上绘制结果。
- kiju-sen:(26 个周期的最高价 + 26 个周期的最低价)/2
使用与 tenkan-sen 相同的日期。寻找最高价超过
前二十六期。寻找相同的最低低价
二十六期。将两个价格相加并除以二。绘制结果
日期的 Y 轴。
- chikou 跨度:在 Y 轴上绘制日期的收盘价二十六个周期
在所选日期的左侧。
- senkou span A: (tenkan-sen + kiju-sen)/2 向右移动了 26 个周期。
从情节最左边的日期开始。添加的值
tenkan-sen 和 kiju-sen。将总和除以 2。将结果值绘制在
右边二十六个时期的日期。继续这个直到你到达
今天的日期。
- senkou跨度B:(52期最高价+52期最低价)/2
向右移动 26 个句点。
再次从情节最左边的日期开始。找到最高点
前 52 期的价格。求同52的最低低价
期间。将总和除以 2。将结果值绘制在
右边二十六个时期的日期。继续这个直到你到达
今天的日期。
绘制从所选日期到今天日期的前三个结果会得到三行。最后两个给出了绘图区域 ("cloud") 以及定义 upper/lower "cloud" 边界的两条可能的 support/resistance 行。所有这些都假设 'periods' 是日期(对于日间交易者来说,它们可能是 15 分钟的周期,作为其他周期的例子)。此外,有些书有 senkou 计划 B 转移 26 个周期,有些转移它 22 个周期。我知道Goichi Hosoda的原著有二十六期,所以我用那个值。
感谢您编写程序。虽然我认为我理解了关于这个主题的书籍作者的意思,但直到看到代码我才确定。显然,作者不是程序员或做证明的数学家。我想我太线性了!
EdChum 的答案在计算 Ichimoku 云的组件时非常接近。
方法是正确的,但未能适应 leading_spans 的未来日期。当我们将前导跨度移动 26 时,pandas 只是移动到最后一个日期或最后一个索引,并且忽略额外(或未来)26 个值。
这是一个适应未来日期或未来云形成的实现
from datetime import timedelta
high_9 = df['High'].rolling(window= 9).max()
low_9 = df['Low'].rolling(window= 9).min()
df['tenkan_sen'] = (high_9 + low_9) /2
high_26 = df['High'].rolling(window= 26).max()
low_26 = df['Low'].rolling(window= 26).min()
df['kijun_sen'] = (high_26 + low_26) /2
# this is to extend the 'df' in future for 26 days
# the 'df' here is numerical indexed df
last_index = df.iloc[-1:].index[0]
last_date = df['Date'].iloc[-1].date()
for i in range(26):
df.loc[last_index+1 +i, 'Date'] = last_date + timedelta(days=i)
df['senkou_span_a'] = ((df['tenkan_sen'] + df['kijun_sen']) / 2).shift(26)
high_52 = df['High'].rolling(window= 52).max()
low_52 = df['Low'].rolling(window= 52).min()
df['senkou_span_b'] = ((high_52 + low_52) /2).shift(26)
# most charting softwares dont plot this line
df['chikou_span'] = df['Close'].shift(-22) #sometimes -26
tmp = df[['Close','senkou_span_a','senkou_span_b','kijun_sen','tenkan_sen']].tail(300)
a1 = tmp.plot(figsize=(15,10))
a1.fill_between(tmp.index, tmp.senkou_span_a, tmp.senkou_span_b)
high_9 = pd.rolling_max(df.high, window= 9)
low_9 = pd.rolling_min(df.low, window= 9)
df['conversion_line'] = (high_9 + low_9) /2
high_26 = pd.rolling_max(df.high, window= 26)
low_26 = pd.rolling_min(df.low, window= 26)
df['base_line'] = (high_26 + low_26) / 2
df['leading_span_A'] = ((df.conversion_line + df.base_line) / 2).shift(30)
high_52 = pd.rolling_max(df.high, window= 52)
low_52 = pd.rolling_min(df.high, window= 52)
df['leading_span_B'] = ((high_52 + low_52) / 2).shift(30)
df['lagging_span'] = df.close.shift(-30)
fig,ax = plt.subplots(1,1,sharex=True,figsize = (20,9)) #share x axis and set a figure size
ax.plot(df.index, df.close,linewidth=4) # plot Close with index on x-axis with a line thickness of 4
# use the fill_between call of ax object to specify where to fill the chosen color
# pay attention to the conditions specified in the fill_between call
ax.fill_between(df.index,leading_span_A,df.leading_span_B,where = df.leading_span_A >= df.leading_span_B, color = 'lightgreen')
ax.fill_between(df.index,df.leading_span_A,df.leading_span_B,where = leading_span_A < df.leading_span_B, color = 'lightcoral')
import mplfinance as mpf
import pandas as pd
#Import the data into a "df", with headers, with the name of the stock like "stk = 'AAPL'"
#MPLFinance does not fill-in-between,hence there is no cloud.
#Tenkan Sen
tenkan_max = df['High'].rolling(window = 9, min_periods = 0).max()
tenkan_min = df['Low'].rolling(window = 9, min_periods = 0).min()
df['tenkan_avg'] = (tenkan_max + tenkan_min) / 2
#Kijun Sen
kijun_max = df['High'].rolling(window = 26, min_periods = 0).max()
kijun_min = df['Low'].rolling(window = 26, min_periods = 0).min()
df['kijun_avg'] = (kijun_max + kijun_min) / 2
#Senkou Span A
#(Kijun + Tenkan) / 2 Shifted ahead by 26 periods
df['senkou_a'] = ((df['kijun_avg'] + df['tenkan_avg']) / 2).shift(26)
#Senkou Span B
#52 period High + Low / 2
senkou_b_max = df['High'].rolling(window = 52, min_periods = 0).max()
senkou_b_min = df['Low'].rolling(window = 52, min_periods = 0).min()
df['senkou_b'] = ((senkou_b_max + senkou_b_min) / 2).shift(52)
#Chikou Span
#Current close shifted -26
df['chikou'] = (df['Close']).shift(-26)
#Plotting Ichimoku
#m_plots = ['kijun_avg', 'tenkan_avg',df[df.columns[5:]][-250:] ]
add_plots= [
mpf.make_addplot(df['kijun_avg'][-250:]),
mpf.make_addplot(df['tenkan_avg'][-250:]),
mpf.make_addplot(df['chikou'][-250:]),
mpf.make_addplot(df['senkou_a'][-250:]),
mpf.make_addplot(df['senkou_b'][-250:])
]
mpf.plot(df[-250:], type = 'candle', mav= 200, volume = True, ylabel = "Price", ylabel_lower = 'Volume', style = 'nightclouds', figratio=(15,10), figscale = 1.5, addplot = add_plots, title = '%s' %stk)
我对@chilliq 的代码进行了更改,并制作了一个实时工作示例,该示例现在可以在 2021 年 7 月运行。为了使用实时数据,您需要按相反的顺序对其进行排序,以便最近的值不会NaN
.
def Ichimoku_Cloud(df):
'''
Get the values of Lines for Ichimoku Cloud
args:
df: Dataframe
'''
d = df.sort_index(ascending=False) # my Live NSE India data is in Recent -> Oldest order
# Tenkan-sen (Conversion Line): (9-period high + 9-period low)/2))
period9_high = d['HIGH'].rolling(window=9).max()
period9_low = d['LOW'].rolling(window=9).min()
tenkan_sen = (period9_high + period9_low) / 2
# Kijun-sen (Base Line): (26-period high + 26-period low)/2))
period26_high = d['HIGH'].rolling(window=26).max()
period26_low = d['LOW'].rolling(window=26).min()
kijun_sen = (period26_high + period26_low) / 2
# Senkou Span A (Leading Span A): (Conversion Line + Base Line)/2))
senkou_span_a = ((tenkan_sen + kijun_sen) / 2).shift(26)
# Senkou Span B (Leading Span B): (52-period high + 52-period low)/2))
period52_high = d['HIGH'].rolling(window=52).max()
period52_low = d['LOW'].rolling(window=52).min()
senkou_span_b = ((period52_high + period52_low) / 2).shift(26)
# The most current closing price plotted 22 time periods behind (optional)
chikou_span = d['CLOSE'].shift(-22) # Given at Trading View.
d['blue_line'] = tenkan_sen
d['red_line'] = kijun_sen
d['cloud_green_line_a'] = senkou_span_a
d['cloud_red_line_b'] = senkou_span_b
d['lagging_line'] = chikou_span
return d.sort_index(ascending=True)
这是我的 Numba / Numpy 版本的 Ichimoku。您可以更改参数,它会计算未来的云。我不知道这个转变是否与tenkansen,kinjunsen或senkou b有关,但我把它放在一边,因为我懒得去查。
import numpy as np
from numba import jit
@jit(nopython=True)
def ichimoku_calc(data, period, shift=0):
size = len(data)
calc = np.array([np.nan] * (size + shift))
for i in range(period - 1, size):
window = data[i + 1 - period:i + 1]
calc[i + shift] = (np.max(window) + np.min(window)) / 2
return calc
@jit(nopython=True)
def ichimoku(data, tenkansen=9, kinjunsen=26, senkou_b=52, shift=26):
size = len(data)
n_tenkansen = ichimoku_calc(data, tenkansen)
n_kinjunsen = ichimoku_calc(data, kinjunsen)
n_chikou = np.concatenate(((data[shift:]), (np.array([np.nan] * (size - shift)))))
n_senkou_a = np.concatenate((np.array([np.nan] * shift), ((n_tenkansen + n_kinjunsen) / 2)))
n_senkou_b = ichimoku_calc(data, senkou_b, shift)
return n_tenkansen, n_kinjunsen, n_chikou, n_senkou_a, n_senkou_b
您必须将输入数据转换为 numpy 数组,并确保您的最终时间索引长度为 len(data) + shift,并使用正确的时间步长计算期货日期。 Ichimoku 工作量很大...
我的交易机器人的结果:
Ichimoku on ETHUSDT pair
我有 Pandas DataFrame 对象,其中包含每日股票数据的日期、开盘价、收盘价、最低价和最高价。我想计算 Ichimoku 图表的组成部分。我可以使用以下代码获取我的数据:
high_prices = data['High']
close_prices = data['Close']
low_prices = data['Low']
dates = data['Date'] # contains datetime objects
我需要计算以下系列(Ichimoku 称之为 Tenkan-Sen 线):
(9 期高点 + 9 期低点)/ 2
- 9 期最高价 = 最近 9 天的最高价,
- 9 期低价 = 最近 9 天的最低价, 所以两者都应该在第 9 天开始。
我找到了 R 语言的解决方案 here,但我很难将其翻译成 Python/Pandas 代码。
Ichimoku 图表包含更多组件,但是当我知道如何在 Pandas 中计算 Tenkan-Sen 线时,我将能够计算所有这些(我将共享代码)。
我不是金融专家或绘图专家,但以下显示了示例金融数据以及如何使用 rolling_max
and rolling_min
:
In [60]:
import pandas.io.data as web
import datetime
start = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2013, 1, 27)
data=web.DataReader("F", 'yahoo', start, end)
high_prices = data['High']
close_prices = data['Close']
low_prices = data['Low']
dates = data.index
nine_period_high = df['High'].rolling(window=9).max()
nine_period_low = df['Low'].rolling(window=9).min()
ichimoku = (nine_period_high + nine_period_low) /2
ichimoku
Out[60]:
Date
2010-01-04 NaN
2010-01-05 NaN
2010-01-06 NaN
2010-01-07 NaN
2010-01-08 NaN
2010-01-11 NaN
2010-01-12 NaN
2010-01-13 NaN
2010-01-14 11.095
2010-01-15 11.270
2010-01-19 11.635
2010-01-20 11.730
2010-01-21 11.575
2010-01-22 11.275
2010-01-25 11.220
...
2013-01-04 12.585
2013-01-07 12.685
2013-01-08 13.005
2013-01-09 13.030
2013-01-10 13.230
2013-01-11 13.415
2013-01-14 13.540
2013-01-15 13.675
2013-01-16 13.750
2013-01-17 13.750
2013-01-18 13.750
2013-01-22 13.845
2013-01-23 13.990
2013-01-24 14.045
2013-01-25 13.970
Length: 771
调用 data[['High', 'Low', 'Close', 'ichimoku']].plot()
结果如下图:
更新
在@PedroLobito 的评论指出 incomplete/incorrect 公式后,我采用了@chilliq 的答案并针对 pandas 0.16.1 及更高版本进行了修改:
import pandas as pd
from pandas_datareader import data, wb
import datetime
start = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2013, 1, 27)
d=data.DataReader("F", 'yahoo', start, end)
high_prices = d['High']
close_prices = d['Close']
low_prices = d['Low']
dates = d.index
nine_period_high = df['High'].rolling(window=9).max()
nine_period_low = df['Low'].rolling(window=9).min()
d['tenkan_sen'] = (nine_period_high + nine_period_low) /2
# Kijun-sen (Base Line): (26-period high + 26-period low)/2))
period26_high = high_prices.rolling(window=26).max()
period26_low = low_prices.rolling(window=26).min()
d['kijun_sen'] = (period26_high + period26_low) / 2
# Senkou Span A (Leading Span A): (Conversion Line + Base Line)/2))
d['senkou_span_a'] = ((d['tenkan_sen'] + d['kijun_sen']) / 2).shift(26)
# Senkou Span B (Leading Span B): (52-period high + 52-period low)/2))
period52_high = high_prices.rolling(window=52).max()
period52_low = low_prices.rolling(window=52).min()
d['senkou_span_b'] = ((period52_high + period52_low) / 2).shift(26)
# The most current closing price plotted 22 time periods behind (optional)
d['chikou_span'] = close_prices.shift(-22) # 22 according to investopedia
d.plot()
以下情节的结果,不清楚,因为如前所述,我不是金融专家:
感谢前面的回答,有代码:
# Tenkan-sen (Conversion Line): (9-period high + 9-period low)/2))
period9_high = pd.rolling_max(high_prices, window=9)
period9_low = pd.rolling_min(low_prices, window=9)
tenkan_sen = (period9_high + period9_low) / 2
# Kijun-sen (Base Line): (26-period high + 26-period low)/2))
period26_high = pd.rolling_max(high_prices, window=26)
period26_low = pd.rolling_min(low_prices, window=26)
kijun_sen = (period26_high + period26_low) / 2
# Senkou Span A (Leading Span A): (Conversion Line + Base Line)/2))
senkou_span_a = ((tenkan_sen + kijun_sen) / 2).shift(26)
# Senkou Span B (Leading Span B): (52-period high + 52-period low)/2))
period52_high = pd.rolling_max(high_prices, window=52)
period52_low = pd.rolling_min(low_prices, window=52)
senkou_span_b = ((period52_high + period52_low) / 2).shift(26)
# The most current closing price plotted 22 time periods behind (optional)
chikou_span = close_prices.shift(-22) # 22 according to investopedia
我希望编写 Ichimoku 书籍的人在计算中的说明更加明确。查看上面的代码,我假设如下:
- tenkan-sen:(9 个周期的最高价 + 9 个周期的最低价)/2 选择一个日期。查看前九个时期的最高价。 寻找相同九个时期内的最低低价。添加两个价格 一起并除以二。在日期的 Y 轴上绘制结果。
- kiju-sen:(26 个周期的最高价 + 26 个周期的最低价)/2 使用与 tenkan-sen 相同的日期。寻找最高价超过 前二十六期。寻找相同的最低低价 二十六期。将两个价格相加并除以二。绘制结果 日期的 Y 轴。
- chikou 跨度:在 Y 轴上绘制日期的收盘价二十六个周期 在所选日期的左侧。
- senkou span A: (tenkan-sen + kiju-sen)/2 向右移动了 26 个周期。 从情节最左边的日期开始。添加的值 tenkan-sen 和 kiju-sen。将总和除以 2。将结果值绘制在 右边二十六个时期的日期。继续这个直到你到达 今天的日期。
- senkou跨度B:(52期最高价+52期最低价)/2 向右移动 26 个句点。 再次从情节最左边的日期开始。找到最高点 前 52 期的价格。求同52的最低低价 期间。将总和除以 2。将结果值绘制在 右边二十六个时期的日期。继续这个直到你到达 今天的日期。
绘制从所选日期到今天日期的前三个结果会得到三行。最后两个给出了绘图区域 ("cloud") 以及定义 upper/lower "cloud" 边界的两条可能的 support/resistance 行。所有这些都假设 'periods' 是日期(对于日间交易者来说,它们可能是 15 分钟的周期,作为其他周期的例子)。此外,有些书有 senkou 计划 B 转移 26 个周期,有些转移它 22 个周期。我知道Goichi Hosoda的原著有二十六期,所以我用那个值。
感谢您编写程序。虽然我认为我理解了关于这个主题的书籍作者的意思,但直到看到代码我才确定。显然,作者不是程序员或做证明的数学家。我想我太线性了!
EdChum 的答案在计算 Ichimoku 云的组件时非常接近。
方法是正确的,但未能适应 leading_spans 的未来日期。当我们将前导跨度移动 26 时,pandas 只是移动到最后一个日期或最后一个索引,并且忽略额外(或未来)26 个值。
这是一个适应未来日期或未来云形成的实现
from datetime import timedelta
high_9 = df['High'].rolling(window= 9).max()
low_9 = df['Low'].rolling(window= 9).min()
df['tenkan_sen'] = (high_9 + low_9) /2
high_26 = df['High'].rolling(window= 26).max()
low_26 = df['Low'].rolling(window= 26).min()
df['kijun_sen'] = (high_26 + low_26) /2
# this is to extend the 'df' in future for 26 days
# the 'df' here is numerical indexed df
last_index = df.iloc[-1:].index[0]
last_date = df['Date'].iloc[-1].date()
for i in range(26):
df.loc[last_index+1 +i, 'Date'] = last_date + timedelta(days=i)
df['senkou_span_a'] = ((df['tenkan_sen'] + df['kijun_sen']) / 2).shift(26)
high_52 = df['High'].rolling(window= 52).max()
low_52 = df['Low'].rolling(window= 52).min()
df['senkou_span_b'] = ((high_52 + low_52) /2).shift(26)
# most charting softwares dont plot this line
df['chikou_span'] = df['Close'].shift(-22) #sometimes -26
tmp = df[['Close','senkou_span_a','senkou_span_b','kijun_sen','tenkan_sen']].tail(300)
a1 = tmp.plot(figsize=(15,10))
a1.fill_between(tmp.index, tmp.senkou_span_a, tmp.senkou_span_b)
high_9 = pd.rolling_max(df.high, window= 9)
low_9 = pd.rolling_min(df.low, window= 9)
df['conversion_line'] = (high_9 + low_9) /2
high_26 = pd.rolling_max(df.high, window= 26)
low_26 = pd.rolling_min(df.low, window= 26)
df['base_line'] = (high_26 + low_26) / 2
df['leading_span_A'] = ((df.conversion_line + df.base_line) / 2).shift(30)
high_52 = pd.rolling_max(df.high, window= 52)
low_52 = pd.rolling_min(df.high, window= 52)
df['leading_span_B'] = ((high_52 + low_52) / 2).shift(30)
df['lagging_span'] = df.close.shift(-30)
fig,ax = plt.subplots(1,1,sharex=True,figsize = (20,9)) #share x axis and set a figure size
ax.plot(df.index, df.close,linewidth=4) # plot Close with index on x-axis with a line thickness of 4
# use the fill_between call of ax object to specify where to fill the chosen color
# pay attention to the conditions specified in the fill_between call
ax.fill_between(df.index,leading_span_A,df.leading_span_B,where = df.leading_span_A >= df.leading_span_B, color = 'lightgreen')
ax.fill_between(df.index,df.leading_span_A,df.leading_span_B,where = leading_span_A < df.leading_span_B, color = 'lightcoral')
import mplfinance as mpf
import pandas as pd
#Import the data into a "df", with headers, with the name of the stock like "stk = 'AAPL'"
#MPLFinance does not fill-in-between,hence there is no cloud.
#Tenkan Sen
tenkan_max = df['High'].rolling(window = 9, min_periods = 0).max()
tenkan_min = df['Low'].rolling(window = 9, min_periods = 0).min()
df['tenkan_avg'] = (tenkan_max + tenkan_min) / 2
#Kijun Sen
kijun_max = df['High'].rolling(window = 26, min_periods = 0).max()
kijun_min = df['Low'].rolling(window = 26, min_periods = 0).min()
df['kijun_avg'] = (kijun_max + kijun_min) / 2
#Senkou Span A
#(Kijun + Tenkan) / 2 Shifted ahead by 26 periods
df['senkou_a'] = ((df['kijun_avg'] + df['tenkan_avg']) / 2).shift(26)
#Senkou Span B
#52 period High + Low / 2
senkou_b_max = df['High'].rolling(window = 52, min_periods = 0).max()
senkou_b_min = df['Low'].rolling(window = 52, min_periods = 0).min()
df['senkou_b'] = ((senkou_b_max + senkou_b_min) / 2).shift(52)
#Chikou Span
#Current close shifted -26
df['chikou'] = (df['Close']).shift(-26)
#Plotting Ichimoku
#m_plots = ['kijun_avg', 'tenkan_avg',df[df.columns[5:]][-250:] ]
add_plots= [
mpf.make_addplot(df['kijun_avg'][-250:]),
mpf.make_addplot(df['tenkan_avg'][-250:]),
mpf.make_addplot(df['chikou'][-250:]),
mpf.make_addplot(df['senkou_a'][-250:]),
mpf.make_addplot(df['senkou_b'][-250:])
]
mpf.plot(df[-250:], type = 'candle', mav= 200, volume = True, ylabel = "Price", ylabel_lower = 'Volume', style = 'nightclouds', figratio=(15,10), figscale = 1.5, addplot = add_plots, title = '%s' %stk)
我对@chilliq 的代码进行了更改,并制作了一个实时工作示例,该示例现在可以在 2021 年 7 月运行。为了使用实时数据,您需要按相反的顺序对其进行排序,以便最近的值不会NaN
.
def Ichimoku_Cloud(df):
'''
Get the values of Lines for Ichimoku Cloud
args:
df: Dataframe
'''
d = df.sort_index(ascending=False) # my Live NSE India data is in Recent -> Oldest order
# Tenkan-sen (Conversion Line): (9-period high + 9-period low)/2))
period9_high = d['HIGH'].rolling(window=9).max()
period9_low = d['LOW'].rolling(window=9).min()
tenkan_sen = (period9_high + period9_low) / 2
# Kijun-sen (Base Line): (26-period high + 26-period low)/2))
period26_high = d['HIGH'].rolling(window=26).max()
period26_low = d['LOW'].rolling(window=26).min()
kijun_sen = (period26_high + period26_low) / 2
# Senkou Span A (Leading Span A): (Conversion Line + Base Line)/2))
senkou_span_a = ((tenkan_sen + kijun_sen) / 2).shift(26)
# Senkou Span B (Leading Span B): (52-period high + 52-period low)/2))
period52_high = d['HIGH'].rolling(window=52).max()
period52_low = d['LOW'].rolling(window=52).min()
senkou_span_b = ((period52_high + period52_low) / 2).shift(26)
# The most current closing price plotted 22 time periods behind (optional)
chikou_span = d['CLOSE'].shift(-22) # Given at Trading View.
d['blue_line'] = tenkan_sen
d['red_line'] = kijun_sen
d['cloud_green_line_a'] = senkou_span_a
d['cloud_red_line_b'] = senkou_span_b
d['lagging_line'] = chikou_span
return d.sort_index(ascending=True)
这是我的 Numba / Numpy 版本的 Ichimoku。您可以更改参数,它会计算未来的云。我不知道这个转变是否与tenkansen,kinjunsen或senkou b有关,但我把它放在一边,因为我懒得去查。
import numpy as np
from numba import jit
@jit(nopython=True)
def ichimoku_calc(data, period, shift=0):
size = len(data)
calc = np.array([np.nan] * (size + shift))
for i in range(period - 1, size):
window = data[i + 1 - period:i + 1]
calc[i + shift] = (np.max(window) + np.min(window)) / 2
return calc
@jit(nopython=True)
def ichimoku(data, tenkansen=9, kinjunsen=26, senkou_b=52, shift=26):
size = len(data)
n_tenkansen = ichimoku_calc(data, tenkansen)
n_kinjunsen = ichimoku_calc(data, kinjunsen)
n_chikou = np.concatenate(((data[shift:]), (np.array([np.nan] * (size - shift)))))
n_senkou_a = np.concatenate((np.array([np.nan] * shift), ((n_tenkansen + n_kinjunsen) / 2)))
n_senkou_b = ichimoku_calc(data, senkou_b, shift)
return n_tenkansen, n_kinjunsen, n_chikou, n_senkou_a, n_senkou_b
您必须将输入数据转换为 numpy 数组,并确保您的最终时间索引长度为 len(data) + shift,并使用正确的时间步长计算期货日期。 Ichimoku 工作量很大...
我的交易机器人的结果:
Ichimoku on ETHUSDT pair