Python/Pandas 计算 Ichimoku 图表组件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28477222/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 22:56:45  来源:igfitidea点击:

Python/Pandas calculate Ichimoku chart components

pythonpandas

提问by chilliq

I have Pandas DataFrame object with Date, Open, Close, Low and High daily stock data. I want to calculate components of Ichimokuchart. I can get my data using the following code:

我有 Pandas DataFrame 对象,其中包含 Date、Open、Close、Low 和 High 每日股票数据。我想计算Ichimoku图的分量。我可以使用以下代码获取我的数据:

high_prices = data['High']
close_prices = data['Close']
low_prices = data['Low']
dates = data['Date']  # contains datetime objects

I need to calculate the following series (Ichimoku calls it Tenkan-Sen line):

我需要计算以下系列(Ichimoku 称其为 Tenkan-Sen 线):

(9-period high + 9-period low) / 2

(9 期高价 + 9 期低价)/ 2

  • 9-period high = the highest High value of last 9 days,
  • 9-period low = the lowest Low value of last 9 days, so both should begin on 9th day.
  • 9 期高点 = 过去 9 天的最高高值,
  • 9 周期低点 = 过去 9 天的最低低值,因此两者都应从第 9 天开始。

enter image description here

在此处输入图片说明

I've found a solution in R language here, but it's difficult for me to translate it to Python/Pandas code.

我在这里找到了 R 语言的解决方案,但我很难将其转换为 Python/Pandas 代码。

Ichimoku chart contains of more components, but when I will know how to count Tenkan-Sen line in Pandas, I will be able to count all of them (I will share the code).

Ichimoku 图包含更多组件,但是当我知道如何计算 Pandas 中的 Tenkan-Sen 线时,我将能够计算所有这些(我将分享代码)。

回答by chilliq

Thanks to the previous answer, there is the code:

感谢前面的回答,有代码:

# 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

回答by EdChum

I'm no financial expert or plotting expert but the following shows sample financial data and how to use rolling_maxand rolling_min:

我不是金融专家或绘图专家,但以下显示了示例财务数据以及如何使用rolling_maxrolling_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

Calling data[['High', 'Low', 'Close', 'ichimoku']].plot()results in the following plot:

调用data[['High', 'Low', 'Close', 'ichimoku']].plot()结果如下图:

enter image description here

在此处输入图片说明

update

更新

After @PedroLobito's comments pointing out the incomplete/incorrect formula I took @chilliq's answer and modified it for pandas versions 0.16.1 and above:

在@PedroLobito 的评论指出不完整/不正确的公式后,我接受了@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()

results in the following plot, unclear because as stated already I'm not a financial expert:

结果如下图,不清楚,因为如前所述,我不是金融专家:

enter image description here

在此处输入图片说明

回答by Naveen

EdChum's answer was very close in calculating the components for the Ichimoku Cloud.

EdChum 的答案在计算 Ichimoku 云的组件方面非常接近。

The methodologies are correct but it missed to accommodate for the future dates for both leading_spans . When we are shifting the leading spans by 26 , pandas just shifts till the last date or last index and the extra(or future) 26 values are ignored.

这些方法是正确的,但它没有考虑到leading_spans 的未来日期。当我们将前导跨度移动 26 时,pandas 只会移动到最后一个日期或最后一个索引,并且忽略额外(或未来)26 个值。

Here's an implementation that accommodates for the future dates or future cloud formation

这是一个适应未来日期或未来云形成的实现

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)

Ichimoku Cloud

一目云

回答by Brijesh

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)

回答by TonyK

I wish the people who write the Ichimoku books were more explicit in their instructions in the calculations. Looking at the code above I'm assuming the following:

我希望编写 Ichimoku 书籍的人在计算中的说明更加明确。查看上面的代码,我假设如下:

  1. tenkan-sen: (9 period max high + 9 period min low)/2 Pick a date. Look the for maximum high price over the previous nine periods. Look for the minimum low price over the same nine periods. Add the two prices together and divide by two. Plot the result on the date's Y-axis.
  2. kiju-sen: (26 period max high + 26 period min low)/2 Use the same date as for the tenkan-sen. Look for the maximum high price over the previous twenty-six periods. Look for the minimum low price over the same twenty-six periods. Add the two prices and divide by two. Plot the result on the date's Y-axis.
  3. chikou span: Plot on the Y-axis the date's closing price twenty-six periods to the left of the chosen date.
  4. senkou span A: (tenkan-sen + kiju-sen)/2 shifted twenty-six periods to right. Start at the extreme left most date of the plot. Add the values of the tenkan-sen and kiju-sen. Divide the sum by 2. Plot the resulting value on the the date twenty-six periods to the right. Continue this until you get to today's date.
  5. senkou span B: (52 period maximum high price + 52 period minimum low price)/2 shifted 26 periods to the right. Again start at the extreme left most date of the plot. Find the maximum high price of the previous 52 periods. Find the minimum low price of the same 52 periods. Divide the sum by 2. Plot the resulting value on the the date twenty-six periods to the right. Continue this until you get to today's date.
  1. tenkan-sen:(9 期最高价 + 9 期最低价)/2 选择一个日期。寻找前九个时期的最高价。寻找相同九个时期内的最低价。将两个价格相加并除以二。在日期的 Y 轴上绘制结果。
  2. kiju-sen: (26 period max high + 26 period min low)/2 使用与tenkan-sen相同的日期。寻找过去 26 个时期的最高价。寻找相同 26 个时期内的最低价。将两个价格相加并除以二。在日期的 Y 轴上绘制结果。
  3. chikou span:在 Y 轴上绘制所选日期左侧 26 个周期的日期收盘价。
  4. senkou span A: (tenkan-sen + kiju-sen)/2 向右移动了 26 个周期。从情节最左边的日期开始。添加tenkan-sen 和kiju-sen 的值。将总和除以 2。将结果值绘制在右边 26 个周期的日期上。继续这个直到你到达今天的日期。
  5. 仙口跨度B:(52期最高价+52期最低价)/2右移26期。再次从情节最左边的日期开始。找出前 52 个周期的最高价。找出相同 52 个周期的最低价。将总和除以 2。将结果值绘制在右边 26 个周期的日期上。继续这个直到你到达今天的日期。

Plotting the first three from a chosen date to today's date results in three lines. The last two give a plot area ("cloud") along with two possible support/resistance lines defining the upper/lower "cloud" bounds. All this assumes the 'periods' are dates (they might be 15 minute periods for day traders as an example of other periods). Also, some books have senkou plan B shift 26 periods and some shift it 22 periods. I understand the original book by Goichi Hosoda had it twenty-six periods, so I used that value.

将选定日期的前三个绘制到今天的日期会生成三行。最后两个给出了一个绘图区域(“云”)以及定义上/下“云”边界的两条可能的支撑/阻力线。所有这些都假设“周期”是日期(对于日间交易者,它们可能是 15 分钟的周期,作为其他周期的示例)。另外,有些书有senkou plan B 26期,有些书22期。我知道 Goichi Hosoda 的原书有 26 个时期,所以我使用了这个值。

Thank you for writing the program. While I thought I understood what the authors of the books on this subject meant, I was never sure until I saw the code. Obviously the authors were not programmers or mathematicians doing proofs. I guess I'm just too linear!

感谢您编写程序。虽然我以为我理解了关于这个主题的书籍的作者的意思,但直到看到代码我才确定。显然,作者不是程序员或做证明的数学家。我想我只是太线性了!

回答by vibhu_singh

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')

enter image description here

在此处输入图片说明