Tradingview Pinescript中的pivothigh()和pivotlow()函数是如何工作的?

10

我正在尝试将一个脚本重写为Python,但我无法理解pivothigh()和pivotlow()函数的作用,并且找不到源代码,我知道如何计算枢轴点,但是这两个函数中的leftbars和rightbars意味着什么?请帮忙。


你已经创建了这个函数吗?可以分享一下代码吗? - Krzysztof Maliszewski
你能否创建一个更通用的代码,可以分享给大家吗?谢谢! - Mayank Jain
有更新吗? - Frumda Grayforce
1
请避免在策略中使用Pivothigh()和pivotlow()。它们适用于指标。如果在策略中,您将基于pivothi或pivotlo做出某些决策,则要小心,因为它会“反弹”。例如,如果pivothi() / pivotlo()在上一个柱找到枢轴点,则不会在当前柱发出买入信号,而是在上一个柱发出。 - cyberspider789
11个回答

16

左边和右边的条数是 pivot 函数在寻找枢轴时查找的条数。 例如:pivothigh(10,10) 将搜索在左侧(过去数据)和右侧(未来数据)各10根K线中没有被超过的高价。请注意,如果右侧少于10根K线,则该函数将无法确定枢轴。


1
这是否意味着直到至少10个bar之后,图表上才会绘制出pivotHigh或Low?就像是超级滞后的指标一样? - Birrel
7
正确,滞后=右边栏+1,模式=左边栏+右边栏+1。 - e2e4

13

我也有一个需要更好地了解pivothigh()pivotlow()函数内部工作原理的需求,因此我努力编写了一个Pine脚本版本(使用Pine脚本的第5版),并将其与ta.pivotlow()ta.pivothigh()函数进行了并行测试,并且看起来它很有效。也许这也能帮到你。

my_pivothigh(float _series = high, int _leftBars, int _rightBars) =>
    float _pivotHigh = na
    int _pivotRange = ( _leftBars + _rightBars )
    float _leftEdgeValue = nz(_series[_pivotRange], na)
    if not na(_series) and _leftBars > 0 and _rightBars > 0 and not na(_leftEdgeValue)
        float _possiblePivotHigh = _series[_rightBars]
        float[] _arrayOfSeriesValues = array.new_float(0)
        for _barIndex = _pivotRange to 0
            array.push(_arrayOfSeriesValues, _series[_barIndex])
        //end for
        int _pivotHighRightBars = array.size(_arrayOfSeriesValues) - array.lastindexof(_arrayOfSeriesValues, array.max(_arrayOfSeriesValues)) - 1
        _pivotHigh := ( _pivotHighRightBars == _rightBars ) ? _possiblePivotHigh : na
    //end if
    _pivotHigh

my_pivotlow(float _series = low, int _leftBars, int _rightBars) =>
    float _pivotLow = na
    int _pivotRange = ( _leftBars + _rightBars )
    float _leftEdgeValue = nz(_series[_pivotRange], na)
    if not na(_series) and _leftBars > 0 and _rightBars > 0 and not na(_leftEdgeValue)
        float _possiblePivotLow = _series[_rightBars]
        float[] _arrayOfSeriesValues = array.new_float(0)
        for _barIndex = _pivotRange to 0
            array.push(_arrayOfSeriesValues, _series[_barIndex])
        //end for
        int _pivotLowRightBars = array.size(_arrayOfSeriesValues) - array.lastindexof(_arrayOfSeriesValues, array.min(_arrayOfSeriesValues)) - 1
        _pivotLow := ( _pivotLowRightBars == _rightBars ) ? _possiblePivotLow : na
    //end if
    _pivotLow

我需要你的Python代码中的my_pivotlow函数。谁能做到?! - MahdiAliz

8

我知道这是一篇旧帖子,但是我已经制作了一个非常简单的Python实现,任何人都可以在此基础上进行构建,它和Pine Scripts ta.pivot函数做的事情是一样的。

代码:

def pivots_high(data, LBR, LBL):
    pivots = []
    for i in range(len(data)-LBR):
        pivots.append(0)
        pivot = True
        if i > LBL:
            for j in range(LBL + 1):
                if data[i - j] > data[I]:  # do if data[i - j] < data[i] for pivot low
                    pivot = False
            for j in range(LBR + 1):
                if data[i + j] > data[I]:  # do if data[i + j] < data[i] for pivot low
                    pivot = False
        if pivot is True:
            pivots[len(pivots)-1] = data[i]
    for p in range(LBR):
        pivots.append(0)  # This is so the pivots length matches your data length
    return pivots  # The Pivots will be any value that is not 0 and it will be where the lowest/highest value is

回溯变量是指如果您选择一个价格点,向左看n个蜡烛(往前n根蜡烛),向右看n个蜡烛(往后n根蜡烛),且该价格点仍然是最低/最高点,则这就是支撑位/阻力位。

更新

我在处理大型数据集时遇到了一些问题,使用不同的数字组合会出现问题,因此我必须完全更改代码以始终与TradingView匹配。

新代码:

def checkhl(data_back, data_forward, hl):
    if hl == 'high' or hl == 'High':
        ref = data_back[len(data_back)-1]
        for i in range(len(data_back)-1):
            if ref < data_back[i]:
                return 0
        for i in range(len(data_forward)):
            if ref <= data_forward[i]:
                return 0
        return 1
    if hl == 'low' or hl == 'Low':
        ref = data_back[len(data_back)-1]
        for i in range(len(data_back)-1):
            if ref > data_back[i]:
                return 0
        for i in range(len(data_forward)):
            if ref >= data_forward[i]:
                return 0
        return 1


def pivot(osc, LBL, LBR, highlow)
    left = []
    right = []
    for i in range(len(osc)):
        pivots.append(0.0)
        if i < LBL + 1:
            left.append(osc[i])
        if i > LBL:
            right.append(osc[i])
        if i > LBL + LBR:
            left.append(right[0])
            left.pop(0)
            right.pop(0)
            if checkhl(left, right, highlow):
                pivots[i - LBR] = osc[i - LBR]
    return pivots

那么只需要执行以下操作:
pivots_low = pivot(data, lbl, lbr, 'low')
pivots_high = pivot(data, lbl, lbr, 'high')

输出的是实际位置的枢轴,否则为0.0。


5

你可以使用pandas的一行代码构建类似的东西:

pivots = high_column.shift(-len_right, fill_value=0).rolling(len_left).max()

针对'High'数据透视表(pd.Series)的'high_column'列:

pivots = low_column.shift(-len_right, fill_value=0).rolling(len_left).min()

对于“Lows”,它避免使用循环,是一个快速的矢量化函数。


3
这是我实现的javascript ta.pivotHigh函数,希望能对你有所帮助。
const pivotHigh = (series, period) => {
  
  let ph = 0;
  let phIndex = 0;

  // left + right bars + 1 pivot bar
  for ( let i = period + period + 1, len = series.length; i--; ) {

    const cur = series[len - i];
    
    // [!] > -1 logic. can also checks: NaN
    if ( cur > -1 ) {} else {
      break;
    }

    if ( cur > ph ) {
      ph = cur;
      phIndex = len - i;
    }
  }
  // found?
  return phIndex === period
    ? ph
    : 0;
};

使用方法:

const series = [0,1,2,3,4,5,4,3,2,1,0];
const period = 5;

const ph = pivotHigh(series, period);

3

这是我的谦虚方法

import numpy as np
from talib import MAX, MIN

def PIVOTHIGH(high: np.ndarray, left:int, right: int):
    pivots = np.roll(MAX(high, left + 1 + right), -right)
    pivots[pivots != high] = np.NaN
    return pivots

def PIVOTLOW(low: np.ndarray, left:int, right: int):
    pivots = np.roll(MIN(low, left + 1 + right), -right)
    pivots[pivots != low] = np.NaN
    return pivots

使用方法如下:

a = np.array([1, 1, 2., 2., 2., 3., 4., 5., 6., 7., 8., 9., 8., 7., 6., 7., 8., 9., 10, 9., 8., 9., 10])

PIVOTHIGH(a, 2, 2)

#output
array([nan, nan,  2., nan, nan, nan, nan, nan, nan, nan, nan,  9., nan,
       nan, nan, nan, nan, nan, 10., nan, nan, nan, nan])

PIVOTLOW(a, 2, 2)

#output
array([nan, nan, nan, nan,  2., nan, nan, nan, nan, nan, nan, nan, nan,
       nan,  6., nan, nan, nan, nan, nan,  8., nan, nan])

2不是枢轴,对吧?但它被返回为枢轴。 - Code_Worm
2不是枢轴,对吧?但它被返回为枢轴。 - undefined

1
这是我的Python实现。与ta.pivothighta.pivotlow完全相同。
枢轴高点:
def get_pivot_high(ohlcvs: List[OHLCV], left_bars: int, right_bars: int, key_name: str = 'high_price') -> Optional[float]:
    if len(ohlcvs) < left_bars + right_bars:
        return None
    highest_value = max(ohlcv.get(key_name) for ohlcv in ohlcvs[-(left_bars + right_bars + 1):])
    return highest_value if highest_value == ohlcvs[-right_bars].get(key_name) else None

枢轴低点:

def get_pivot_low(ohlcvs: List[OHLCV], left_bars: int, right_bars: int, key_name: str = 'low_price') -> Optional[float]:
    if len(ohlcvs) < left_bars + right_bars:
        return None
    lowest_value = min(ohlcv.get(key_name) for ohlcv in ohlcvs[-(left_bars + right_bars + 1):])
    return lowest_value if lowest_value == ohlcvs[-right_bars].get(key_name) else None

1

我试图用Pine Script创建一个简单版本,它不使用pivothigh/pivotlow,而是使用蜡烛图比较。

https://www.tradingview.com/script/BYHsrYPG-Broken-Fractal-Someone-s-broken-dream-is-your-profit

我还能将其转换为Ruby代码(Python代码也应该很容易)。
if (candles[i-1][:h] > candles[i-2][:h]) and (candles[i-1][:h] > candles[i][:h])
    puts "DownFractal"
end

if (candles[i-1][:l] < candles[i-2][:l]) and (candles[i-1][:l] < candles[i][:l])
    puts "UpFractal"
end

1

与TradingView Pivots HL相同的一行代码:

LEN = 50 #Lookback and Lookforward
OHLC['PivotHigh'] = OHLC['high'] == OHLC['high'].rolling(2 * LEN + 1, center=True).max()
OHLC['PivotLow'] = OHLC['low'] == OHLC['low'].rolling(2 * LEN + 1, center=True).min()

(左右长度将相同)


0
这个Python函数的设计目的是精确匹配Pine Script版本4中的pivotlow和pivothigh函数的逻辑。它已经在大型数据集上成功测试过。之前在这个帖子中的回答没有给我提供与Pine Script逻辑完全匹配的答案。
# This function is adapted to work with a pandas DataFrame.
# The function takes as input a DataFrame with OHLCV data, the index
# of the current candle - 1, and the window size for checking, prd.
# The function returns the pivot value if found, otherwise None.
# It is assumed that the DataFrame has columns "high" and "low"
# which contain the highs and lows of the candle, respectively.


def find_pivot_highs(df, index, prd):
    # Create a window of size (prd * 2 + 1) around the current index
    # Extract values from the "high" column of DataFrame df
    window = df["high"].iloc[index - prd * 2 : index + 1].values

    # Find the maximum value in the last prd elements of the window
    high_max = max(window[-prd:])

    # Find the maximum value in the entire window
    max_value = max(window)

    # Check if the current value is the maximum in the window
    # and if it's greater than the maximum value in the last prd elements
    if max_value == window[prd] and window[prd] > high_max:
        return window[prd]

    return None


def find_pivot_lows(df, index, prd):
    # Create a window of size (prd * 2 + 1) around the current index
    # Extract values from the "low" column of DataFrame df
    window = df["low"].iloc[index - prd * 2 : index + 1].values

    # Find the minimum value in the last prd elements of the window
    low_min = min(window[-prd:])

    # Find the minimum value in the entire window
    min_value = min(window)

    # Check if the current value is the minimum in the window
    # and if it's less than the minimum value in the last prd elements
    if min_value == window[prd] and window[prd] < low_min:
        return window[prd]

    return None

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接