Python Zig Zag 算法函数未返回预期结果 [英] Python Zig Zag algorithm function not returning expected results

查看:58
本文介绍了Python Zig Zag 算法函数未返回预期结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

概述

我正在尝试在财务数据上使用这个 Python 之字形烛台指标(利用高、低、收盘值),但下面的代码似乎有一个错误.

是否有其他可用的 Python 模块提供此功能?

什么是锯齿形指标

<块引用>

只要价格反转的百分比大于预先选择的变量,Zig Zag 指标就会在图表上绘制点.

在图表中显示问题的代码:

将 numpy 导入为 np导入 plotly.graph_objects as go将熊猫导入为 pd从日期时间导入日期时间df = pd.DataFrame(dict1)fig = go.Figure(data=[go.Candlestick(x=df['Date'],open=df['打开'],高=df['高'],低=df['低'],关闭=df['关闭'])])df_diff = df['枢轴价格'].dropna().diff().copy()fig.add_trace(go.Scatter(模式=线条+标记",x=df['日期'],y=df[枢轴价格"]))fig.update_layout(自动大小=假,宽度=1000,高度=800,)fig.add_trace(go.Scatter(x=df['Date'], y=df['Pivot Price'].interpolate(),模式 = '行',line = dict(color='black')))定义注释(值):如果 np.isnan(value):返回 '​​'别的:返回值j = 0对于 i, p in enumerate(df['Pivot Price']):如果不是 np.isnan(p):fig.add_annotation(dict(font=dict(color='rgba(0,0,200,0.8)',size=12),x=df['Date'].iloc[i],y=p,显示箭头=假,text=annot(round(abs(df_diff.iloc[j]),3)),文字角度=0,xanchor='右',外部参照 =x",yref=y"))j = j + 1fig.update_xaxes(type='category')图.show()

一般来说,该功能的工作原理如下图所示.

编辑.这是我用来创建 PivotsPivot Price 列的代码.根据@ands 的评论更新

df['Pivots'] = pivots df.loc[df['Pivots'] == 1, 'Pivot Price'] = df.High df.loc[df['Pivots'] == -1、'枢轴价格'] = df.Low

解决方案

dfPivot Price列有一个小问题,你的数据集for_so.csv 已经包含 Pivot Price 列,因此您需要删除 df['Pivot Price'] 中的值并根据 将其设置为新值支点.

我使用以下代码创建了正确的 'Pivots''Pivot Price' 列:

pivots = peak_valley_pivots_candlestick(df.Close, df.High, df.Low ,.01,-.01)df['枢轴'] = 枢轴df['Pivot Price'] = np.nan # 此行清除旧的枢轴价格df.loc[df['Pivots'] == 1, 'Pivot Price'] = df.Highdf.loc[df['Pivots'] == -1, 'Pivot Price'] = df.Low

主要问题在于锯齿形代码.函数 peak_valley_pivots_candlestick 有两个小错误.在 for 循环中,条件 if r >= up_thresh: 为真,则 last_pivot_x 设置为 x,但应设置为 high[t].

如果 r >= up_thresh:枢轴[last_pivot_t] = 趋势#趋势 = 1#last_pivot_x = xlast_pivot_x = 高[t]last_pivot_t = t

与条件 if r <= down_thresh: 中的代码相同,其中 last_pivot_x 应设置为 low[t]而不是 x.

如果 r <= down_thresh:枢轴[last_pivot_t] = 趋势趋势 = -1#last_pivot_x = xlast_pivot_x = 低[t]last_pivot_t = t

这里是完整的代码:

将 numpy 导入为 np导入 plotly.graph_objects as go将熊猫导入为 pd峰值,谷值 = 1,-1def _identify_initial_pivot(X, up_thresh, down_thresh):"""快速识别 X[0] 为峰或谷."""x_0 = X[0]max_x = x_0max_t = 0min_x = x_0min_t = 0up_thresh += 1down_thresh += 1对于范围内的 t(1, len(X)):x_t = X[t]如果 x_t/min_x >= up_thresh:如果 min_t == 0 则返回 VALLEY 否则 PEAK如果 x_t/max_x <= down_thresh:如果 max_t == 0 则返回 PEAK 否则 VALLEY如果 x_t >最大_x:max_x = x_tmax_t = t如果 x_t 0:raise ValueError('down_thresh 必须是负数.')initial_pivot = _identify_initial_pivot(关闭,up_thresh,down_thresh)t_n = len(关闭)枢轴 = np.zeros(t_n, dtype='i1')枢轴[0] = initial_pivot# 在相对变化阈值上加一可以节省操作.反而# 计算每个点的相对变化为 x_j/x_i - 1,即# 计算为 x_j/x_1.然后,将该值与阈值 + 1 进行比较.# 这节省了 (t_n - 1) 次减法.up_thresh += 1down_thresh += 1趋势 = -initial_pivotlast_pivot_t = 0last_pivot_x = 关闭[0]对于范围内的 t(1, len(close)):如果趋势 == -1:x = 低 [t]r = x/last_pivot_x如果 r >= up_thresh:枢轴[last_pivot_t] = 趋势#趋势 = 1#last_pivot_x = xlast_pivot_x = 高[t]last_pivot_t = telif x last_pivot_x:last_pivot_x = xlast_pivot_t = t如果 last_pivot_t == t_n-1:枢轴[last_pivot_t] = 趋势elif 枢轴 [t_n-1] == 0:枢轴[t_n-1] = 趋势返回支点df = pd.read_csv('for_so.csv')枢轴 = peak_valley_pivots_candlestick(df.Close, df.High, df.Low ,.01,-.01)df['枢轴'] = 枢轴df['Pivot Price'] = np.nan # 此行清除旧的枢轴价格df.loc[df['Pivots'] == 1, 'Pivot Price'] = df.Highdf.loc[df['Pivots'] == -1, 'Pivot Price'] = df.Lowfig = go.Figure(data=[go.Candlestick(x=df['Date'],open=df['打开'],高=df['高'],低=df['低'],关闭=df['关闭'])])df_diff = df['枢轴价格'].dropna().diff().copy()fig.add_trace(go.Scatter(模式=线条+标记",x=df['日期'],y=df[枢轴价格"]))fig.update_layout(自动大小=假,宽度=1000,高度=800,)fig.add_trace(go.Scatter(x=df['Date'],y=df['枢轴价格'].interpolate(),模式 = '行',line = dict(color='black')))定义注释(值):如果 np.isnan(value):返回 '​​'别的:返回值j = 0对于 i, p in enumerate(df['Pivot Price']):如果不是 np.isnan(p):fig.add_annotation(dict(font=dict(color='rgba(0,0,200,0.8)',size=12),x=df['Date'].iloc[i],y=p,显示箭头=假,text=annot(round(abs(df_diff.iloc[j]),3)),文字角度=0,xanchor='右',外部参照 =x",yref=y"))j = j + 1fig.update_xaxes(type='category')图.show()

上面的代码生成了这个图表:

Overview

I am trying to use this Python Zig Zag candlestick indicator (utilises High,Low,Close values) on financial data but the code below appears to have a bug.

Is there another working Python module that provides this functionality?

What is a Zig Zag indicator

The Zig Zag indicator plots points on the chart whenever prices reverse by a percentage greater than a pre-chosen variable.

Source

What have I tried

While searching for a Python zigzag indicator for candlestick charts the only code I could find was from this pull request.

def peak_valley_pivots_candlestick(close, high, low, up_thresh, down_thresh):
    """
    Finds the peaks and valleys of a series of HLC (open is not necessary).
    TR: This is modified peak_valley_pivots function in order to find peaks and valleys for OHLC.
    Parameters
    ----------
    close : This is series with closes prices.
    high : This is series with highs  prices.
    low : This is series with lows prices.
    up_thresh : The minimum relative change necessary to define a peak.
    down_thesh : The minimum relative change necessary to define a valley.
    Returns
    -------
    an array with 0 indicating no pivot and -1 and 1 indicating valley and peak
    respectively
    Using Pandas
    ------------
    For the most part, close, high and low may be a pandas series. However, the index must
    either be [0,n) or a DateTimeIndex. Why? This function does X[t] to access
    each element where t is in [0,n).
    The First and Last Elements
    ---------------------------
    The first and last elements are guaranteed to be annotated as peak or
    valley even if the segments formed do not have the necessary relative
    changes. This is a tradeoff between technical correctness and the
    propensity to make mistakes in data analysis. The possible mistake is
    ignoring data outside the fully realized segments, which may bias analysis.
    """
    if down_thresh > 0:
        raise ValueError('The down_thresh must be negative.')

    initial_pivot = _identify_initial_pivot(close, up_thresh, down_thresh)

    t_n = len(close)
    pivots = np.zeros(t_n, dtype='i1')
    pivots[0] = initial_pivot

    # Adding one to the relative change thresholds saves operations. Instead
    # of computing relative change at each point as x_j / x_i - 1, it is
    # computed as x_j / x_1. Then, this value is compared to the threshold + 1.
    # This saves (t_n - 1) subtractions.
    up_thresh += 1
    down_thresh += 1

    trend = -initial_pivot
    last_pivot_t = 0
    last_pivot_x = close[0]
    for t in range(1, len(close)):

        if trend == -1:
            x = low[t]
            r = x / last_pivot_x
            if r >= up_thresh:
                pivots[last_pivot_t] = trend
                trend = 1
                last_pivot_x = x
                last_pivot_t = t
            elif x < last_pivot_x:
                last_pivot_x = x
                last_pivot_t = t
        else:
            x = high[t]
            r = x / last_pivot_x
            if r <= down_thresh:
                pivots[last_pivot_t] = trend
                trend = -1
                last_pivot_x = x
                last_pivot_t = t
            elif x > last_pivot_x:
                last_pivot_x = x
                last_pivot_t = t


    if last_pivot_t == t_n-1:
        pivots[last_pivot_t] = trend
    elif pivots[t_n-1] == 0:
        pivots[t_n-1] = trend

    return pivots 

It can be utilised as follows:

pivots = peak_valley_pivots_candlestick(df.Close, df.High, df.Low ,.01,-.01)

The peak_valley_pivots_candlestick function is almost working as expected but with the following data there appears to be a bug in how the Pivots are calculated.

Data

The data below is a slice from the complete data set.

dict1 = {'Date': {77: '2018-12-19',
  78: '2018-12-20',
  79: '2018-12-21',
  80: '2018-12-24',
  81: '2018-12-25',
  82: '2018-12-26',
  83: '2018-12-27',
  84: '2018-12-28',
  85: '2018-12-31',
  86: '2019-01-01',
  87: '2019-01-02',
  88: '2019-01-03',
  89: '2019-01-04',
  90: '2019-01-07',
  91: '2019-01-08',
  92: '2019-01-09',
  93: '2019-01-10',
  94: '2019-01-11',
  95: '2019-01-14',
  96: '2019-01-15',
  97: '2019-01-16',
  98: '2019-01-17',
  99: '2019-01-18',
  100: '2019-01-21',
  101: '2019-01-22',
  102: '2019-01-23',
  103: '2019-01-24',
  104: '2019-01-25',
  105: '2019-01-28',
  106: '2019-01-29',
  107: '2019-01-30',
  108: '2019-01-31',
  109: '2019-02-01',
  110: '2019-02-04',
  111: '2019-02-05'},
 'Open': {77: 1.2654544115066528,
  78: 1.2625147104263306,
  79: 1.266993522644043,
  80: 1.2650061845779421,
  81: 1.2712942361831665,
  82: 1.2689388990402222,
  83: 1.2648460865020752,
  84: 1.264606237411499,
  85: 1.2689228057861328,
  86: 1.275022268295288,
  87: 1.2752337455749512,
  88: 1.2518777847290041,
  89: 1.2628973722457886,
  90: 1.2732852697372437,
  91: 1.2786905765533447,
  92: 1.2738852500915527,
  93: 1.2799508571624756,
  94: 1.275835633277893,
  95: 1.2849836349487305,
  96: 1.2876144647598269,
  97: 1.287282943725586,
  98: 1.2884771823883057,
  99: 1.298296570777893,
  100: 1.2853471040725708,
  101: 1.2892745733261108,
  102: 1.2956725358963013,
  103: 1.308318257331848,
  104: 1.3112174272537231,
  105: 1.3207770586013794,
  106: 1.3159972429275513,
  107: 1.308061599731445,
  108: 1.311681866645813,
  109: 1.3109252452850342,
  110: 1.3078563213348389,
  111: 1.3030844926834106},
 'High': {77: 1.267909288406372,
  78: 1.2705351114273071,
  79: 1.269728422164917,
  80: 1.273658275604248,
  81: 1.277791976928711,
  82: 1.2719732522964478,
  83: 1.2671220302581787,
  84: 1.2700024843215942,
  85: 1.2813942432403564,
  86: 1.2756729125976562,
  87: 1.2773349285125732,
  88: 1.2638230323791504,
  89: 1.2739664316177368,
  90: 1.2787723541259766,
  91: 1.2792304754257202,
  92: 1.2802950143814087,
  93: 1.2801146507263184,
  94: 1.2837464809417725,
  95: 1.292774677276611,
  96: 1.2916558980941772,
  97: 1.2895737886428833,
  98: 1.2939958572387695,
  99: 1.299376368522644,
  100: 1.2910722494125366,
  101: 1.296714186668396,
  102: 1.3080273866653442,
  103: 1.3095861673355105,
  104: 1.3176618814468384,
  105: 1.3210039138793943,
  106: 1.3196616172790527,
  107: 1.311991572380066,
  108: 1.3160665035247805,
  109: 1.311475396156311,
  110: 1.3098777532577517,
  111: 1.3051422834396362},
 'Low': {77: 1.2608431577682495,
  78: 1.2615113258361816,
  79: 1.2633600234985352,
  80: 1.2636953592300415,
  81: 1.266784906387329,
  82: 1.266512155532837,
  83: 1.261877417564392,
  84: 1.2636473178863523,
  85: 1.268182635307312,
  86: 1.2714558839797974,
  87: 1.2584631443023682,
  88: 1.2518777847290041,
  89: 1.261781930923462,
  90: 1.2724264860153198,
  91: 1.2714881896972656,
  92: 1.271779179573059,
  93: 1.273058295249939,
  94: 1.2716660499572754,
  95: 1.2821005582809448,
  96: 1.2756240367889404,
  97: 1.2827255725860596,
  98: 1.2836146354675293,
  99: 1.2892080545425415,
  100: 1.2831699848175049,
  101: 1.2855949401855469,
  102: 1.2945822477340698,
  103: 1.301371693611145,
  104: 1.3063528537750244,
  105: 1.313870549201965,
  106: 1.313145875930786,
  107: 1.3058068752288818,
  108: 1.3101180791854858,
  109: 1.3045804500579834,
  110: 1.3042230606079102,
  111: 1.2929919958114624},
 'Close': {77: 1.2655024528503418,
  78: 1.262785792350769,
  79: 1.2669775485992432,
  80: 1.2648941278457642,
  81: 1.2710840702056885,
  82: 1.2688745260238647,
  83: 1.2648781538009644,
  84: 1.2646220922470093,
  85: 1.269357681274414,
  86: 1.2738043069839478,
  87: 1.2754288911819458,
  88: 1.2521913051605225,
  89: 1.2628813982009888,
  90: 1.2734960317611694,
  91: 1.278608798980713,
  92: 1.2737879753112793,
  93: 1.279967188835144,
  94: 1.2753963470458984,
  95: 1.2849836349487305,
  96: 1.2874983549118042,
  97: 1.2872166633605957,
  98: 1.28857684135437,
  99: 1.2983977794647217,
  100: 1.2853471040725708,
  101: 1.2891747951507568,
  102: 1.295773148536682,
  103: 1.308215618133545,
  104: 1.3121638298034668,
  105: 1.3208470344543457,
  106: 1.3160146474838257,
  107: 1.30804443359375,
  108: 1.3117163181304932,
  109: 1.3109424114227295,
  110: 1.3077365159988403,
  111: 1.3031013011932373},
 'Pivots': {77: 0,
  78: 0,
  79: 0,
  80: 0,
  81: 0,
  82: 0,
  83: 0,
  84: 0,
  85: 1,
  86: 0,
  87: 0,
  88: 0,
  89: -1,
  90: 0,
  91: 0,
  92: 0,
  93: 0,
  94: 0,
  95: 0,
  96: 0,
  97: 0,
  98: 0,
  99: 0,
  100: 0,
  101: 0,
  102: 0,
  103: 0,
  104: 0,
  105: 1,
  106: 0,
  107: 0,
  108: 0,
  109: 0,
  110: 0,
  111: 0},
 'Pivot Price': {77: nan,
  78: nan,
  79: nan,
  80: nan,
  81: nan,
  82: nan,
  83: nan,
  84: nan,
  85: 1.2813942432403564,
  86: nan,
  87: nan,
  88: nan,
  89: 1.261781930923462,
  90: nan,
  91: nan,
  92: nan,
  93: nan,
  94: nan,
  95: nan,
  96: nan,
  97: nan,
  98: nan,
  99: nan,
  100: nan,
  101: nan,
  102: nan,
  103: nan,
  104: nan,
  105: 1.3210039138793943,
  106: nan,
  107: nan,
  108: nan,
  109: nan,
  110: nan,
  111: nan}}

Chart showing the issue

2019-01-03 should be the low pivot not 2019-01-04

Code to show the issue in a chart:

import numpy as np
import plotly.graph_objects as go
import pandas as pd
from datetime import datetime

df = pd.DataFrame(dict1)

fig = go.Figure(data=[go.Candlestick(x=df['Date'],

                open=df['Open'],
                high=df['High'],
                low=df['Low'],
                close=df['Close'])])


df_diff = df['Pivot Price'].dropna().diff().copy()


fig.add_trace(
    go.Scatter(mode = "lines+markers",
        x=df['Date'],
        y=df["Pivot Price"]
    ))

fig.update_layout(
    autosize=False,
    width=1000,
    height=800,)

fig.add_trace(go.Scatter(x=df['Date'], y=df['Pivot Price'].interpolate(),
                         mode = 'lines',
                         line = dict(color='black')))


def annot(value):
    if np.isnan(value):
        return ''
    else:
        return value
    

j = 0
for i, p in enumerate(df['Pivot Price']):
    if not np.isnan(p):

        
        fig.add_annotation(dict(font=dict(color='rgba(0,0,200,0.8)',size=12),
                                        x=df['Date'].iloc[i],
                                        y=p,
                                        showarrow=False,
                                        text=annot(round(abs(df_diff.iloc[j]),3)),
                                        textangle=0,
                                        xanchor='right',
                                        xref="x",
                                        yref="y"))
        j = j + 1
fig.update_xaxes(type='category')
fig.show()

Generally the function works as can be seen in this chart.

Edit. This is the code I used to create the Pivots and Pivot Price cols. Updating as per comment from @ands

df['Pivots'] = pivots df.loc[df['Pivots'] == 1, 'Pivot Price'] = df.High df.loc[df['Pivots'] == -1, 'Pivot Price'] = df.Low

解决方案

There is a small problem with Pivot Price column of df, your data set for_so.csv already contains column Pivot Price so you need to delete values in df['Pivot Price'] and set it to new values based on pivots.

I have used the following code to create the correct 'Pivots' and 'Pivot Price' columns:

pivots = peak_valley_pivots_candlestick(df.Close, df.High, df.Low ,.01,-.01)
df['Pivots'] = pivots
df['Pivot Price'] = np.nan  # This line clears old pivot prices
df.loc[df['Pivots'] == 1, 'Pivot Price'] = df.High
df.loc[df['Pivots'] == -1, 'Pivot Price'] = df.Low

The main problem is with the zigzag code. Function peak_valley_pivots_candlestick has two small error. In for loop when condition if r >= up_thresh: is true then last_pivot_x is set to x, but it should be set to high[t].

if r >= up_thresh:
    pivots[last_pivot_t] = trend#
    trend = 1
    #last_pivot_x = x
    last_pivot_x = high[t]
    last_pivot_t = t

It is the same with code in condition if r <= down_thresh: where last_pivot_x should be is set to low[t] instead of x.

if r <= down_thresh:
    pivots[last_pivot_t] = trend
    trend = -1
    #last_pivot_x = x
    last_pivot_x = low[t]
    last_pivot_t = t

And here is complete code:

import numpy as np
import plotly.graph_objects as go
import pandas as pd


PEAK, VALLEY = 1, -1

def _identify_initial_pivot(X, up_thresh, down_thresh):
    """Quickly identify the X[0] as a peak or valley."""
    x_0 = X[0]
    max_x = x_0
    max_t = 0
    min_x = x_0
    min_t = 0
    up_thresh += 1
    down_thresh += 1

    for t in range(1, len(X)):
        x_t = X[t]

        if x_t / min_x >= up_thresh:
            return VALLEY if min_t == 0 else PEAK

        if x_t / max_x <= down_thresh:
            return PEAK if max_t == 0 else VALLEY

        if x_t > max_x:
            max_x = x_t
            max_t = t

        if x_t < min_x:
            min_x = x_t
            min_t = t

    t_n = len(X)-1
    return VALLEY if x_0 < X[t_n] else PEAK

def peak_valley_pivots_candlestick(close, high, low, up_thresh, down_thresh):
    """
    Finds the peaks and valleys of a series of HLC (open is not necessary).
    TR: This is modified peak_valley_pivots function in order to find peaks and valleys for OHLC.
    Parameters
    ----------
    close : This is series with closes prices.
    high : This is series with highs  prices.
    low : This is series with lows prices.
    up_thresh : The minimum relative change necessary to define a peak.
    down_thesh : The minimum relative change necessary to define a valley.
    Returns
    -------
    an array with 0 indicating no pivot and -1 and 1 indicating valley and peak
    respectively
    Using Pandas
    ------------
    For the most part, close, high and low may be a pandas series. However, the index must
    either be [0,n) or a DateTimeIndex. Why? This function does X[t] to access
    each element where t is in [0,n).
    The First and Last Elements
    ---------------------------
    The first and last elements are guaranteed to be annotated as peak or
    valley even if the segments formed do not have the necessary relative
    changes. This is a tradeoff between technical correctness and the
    propensity to make mistakes in data analysis. The possible mistake is
    ignoring data outside the fully realized segments, which may bias analysis.
    """
    if down_thresh > 0:
        raise ValueError('The down_thresh must be negative.')

    initial_pivot = _identify_initial_pivot(close, up_thresh, down_thresh)

    t_n = len(close)
    pivots = np.zeros(t_n, dtype='i1')
    pivots[0] = initial_pivot

    # Adding one to the relative change thresholds saves operations. Instead
    # of computing relative change at each point as x_j / x_i - 1, it is
    # computed as x_j / x_1. Then, this value is compared to the threshold + 1.
    # This saves (t_n - 1) subtractions.
    up_thresh += 1
    down_thresh += 1

    trend = -initial_pivot
    last_pivot_t = 0
    last_pivot_x = close[0]
    for t in range(1, len(close)):

        if trend == -1:
            x = low[t]
            r = x / last_pivot_x
            if r >= up_thresh:
                pivots[last_pivot_t] = trend#
                trend = 1
                #last_pivot_x = x
                last_pivot_x = high[t]
                last_pivot_t = t
            elif x < last_pivot_x:
                last_pivot_x = x
                last_pivot_t = t
        else:
            x = high[t]
            r = x / last_pivot_x
            if r <= down_thresh:
                pivots[last_pivot_t] = trend
                trend = -1
                #last_pivot_x = x
                last_pivot_x = low[t]
                last_pivot_t = t
            elif x > last_pivot_x:
                last_pivot_x = x
                last_pivot_t = t


    if last_pivot_t == t_n-1:
        pivots[last_pivot_t] = trend
    elif pivots[t_n-1] == 0:
        pivots[t_n-1] = trend

    return pivots


df = pd.read_csv('for_so.csv')



pivots = peak_valley_pivots_candlestick(df.Close, df.High, df.Low ,.01,-.01)
df['Pivots'] = pivots
df['Pivot Price'] = np.nan  # This line clears old pivot prices
df.loc[df['Pivots'] == 1, 'Pivot Price'] = df.High
df.loc[df['Pivots'] == -1, 'Pivot Price'] = df.Low



fig = go.Figure(data=[go.Candlestick(x=df['Date'],

                open=df['Open'],
                high=df['High'],
                low=df['Low'],
                close=df['Close'])])


df_diff = df['Pivot Price'].dropna().diff().copy()


fig.add_trace(
    go.Scatter(mode = "lines+markers",
        x=df['Date'],
        y=df["Pivot Price"]
    ))

fig.update_layout(
    autosize=False,
    width=1000,
    height=800,)

fig.add_trace(go.Scatter(x=df['Date'],
                         y=df['Pivot Price'].interpolate(),
                         mode = 'lines',
                         line = dict(color='black')))


def annot(value):
    if np.isnan(value):
        return ''
    else:
        return value
    

j = 0
for i, p in enumerate(df['Pivot Price']):
    if not np.isnan(p):

        
        fig.add_annotation(dict(font=dict(color='rgba(0,0,200,0.8)',size=12),
                                        x=df['Date'].iloc[i],
                                        y=p,
                                        showarrow=False,
                                        text=annot(round(abs(df_diff.iloc[j]),3)),
                                        textangle=0,
                                        xanchor='right',
                                        xref="x",
                                        yref="y"))
        j = j + 1

        
fig.update_xaxes(type='category')
fig.show()

The code above produces this chart:

这篇关于Python Zig Zag 算法函数未返回预期结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆