简体   繁体   English

pivothigh() 和 pivotlow() function 如何在 Tradingview Pinescript 上工作?

[英]How pivothigh() and pivotlow() function work on Tradingview Pinescript?

I'm trying to rewrite a script to Python, but I can't figure out how pivothigh() and pivotlow() function work, and I can't find source code, I know how to calculate Pivot Points, but what leftbars and rightbars means in this two function? I'm trying to rewrite a script to Python, but I can't figure out how pivothigh() and pivotlow() function work, and I can't find source code, I know how to calculate Pivot Points, but what leftbars and在这两个 function 中,rightbars 是什么意思? Please help.请帮忙。

Leftbars and rightbars are number of bars that the pivot functions looks when is searching for a pivot. leftbars 和 rightbars 是pivot函数在搜索枢轴时查看的柱数。 For example: pivothigh(10,10) will search for high price that was not exceeded during 10 bars to the left (past data) and 10 bars to the right (future data).例如: pivothigh(10,10)将搜索左侧 10 根柱线(过去数据)和右侧 10 根柱线(未来数据)期间未超过的最高价。 Note that the function won't be able to determine the pivot if there is less than 10 bars to the right.请注意,如果右侧的柱线少于 10 个,该函数将无法确定枢轴。

I've tried to create a simple version of it in pine script, which does not uses pivothigh/pivotlow - instead does the candlestick comparison.我试图在 pine 脚本中创建它的一个简单版本,它不使用 pivothigh/pivotlow - 而是进行烛台比较。

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

I was also able to convert this into Ruby code (Python code should be as easy)我还能够将其转换为 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

I too had a need to better understand how the pivothigh() and pivotlow() functions work internally so I made the effort to code a Pine Script version (using version 5 of Pine Script) for myself and tested it side-by-side with the ta.pivotlow() and ta.pivothigh() functions and it seems to work well.我也需要更好地了解pivothigh()pivotlow()函数如何在内部工作,所以我努力为自己编写 Pine Script 版本(使用 Pine Script 的第 5 版)并与它并排测试ta.pivotlow()ta.pivothigh()函数,它似乎运行良好。 Maybe this will help you as well.也许这也会对您有所帮助。

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

This is my implementation of ta.pivotHigh for javascript, hope this helps.这是我为 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;
};

usage:用法:

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

const ph = pivotHigh(series, period);

I had found this thread after I have searched for this kind of implementation.在搜索了这种实现之后,我找到了这个线程。 Here is my own implementation for those that have been utilizing the Binance API.这是我为那些一直在使用 Binance API 的人提供的实现。 (Written in java) (用java编写)

From my own testings, it has the same results as the pine script.根据我自己的测试,它与 pine 脚本的结果相同。

private boolean checkHighOrLow(Candlestick candlestick , int lengthForCheck, int currentCandleIndex, boolean checkForHigh) {
    double currentCandleStickClosePrice = Double.parseDouble(candlestick.getClose());
    for (int i = 0; i < lengthForCheck; i++) {
        double afterCandleStick  = Double.parseDouble(candlestickList.get(currentCandleIndex + i + 1).getClose());
        double beforeCandleStick = Double.parseDouble(candlestickList.get(currentCandleIndex - i - 1).getClose());
        if(checkForHigh) {
            if (afterCandleStick > currentCandleStickClosePrice)
                return false;
            if (beforeCandleStick > currentCandleStickClosePrice)
                return false;
        }else{
            if(afterCandleStick < currentCandleStickClosePrice)
                return false;
            if(beforeCandleStick < currentCandleStickClosePrice)
                return false;
        }
    }
    return true;
}

public void findHighsAndLows(){
    int lengthForCheck = 1;
    int numOfCandles   = candlestickList.size();
    for(int i = lengthForCheck; i < numOfCandles - lengthForCheck; i ++)
    {
         Candlestick currentCandle = candlestickList.get(i);
         if(checkHighOrLow(currentCandle,numOfCandles,lengthForCheck,i,true))
             highs.add(currentCandle);
         if(checkHighOrLow(currentCandle,numOfCandles,lengthForCheck,i,false))
             lows.add(currentCandle);
    }
}

Logic still applies.逻辑仍然适用。 Enjoy享受

Result:结果:

FOUND LOW | Wed Aug 25 04:20:00 IDT 2021
FOUND HIGH | Wed Aug 25 05:05:00 IDT 2021
FOUND LOW | Wed Aug 25 05:20:00 IDT 2021
FOUND HIGH | Wed Aug 25 05:30:00 IDT 2021
FOUND LOW | Wed Aug 25 05:35:00 IDT 2021
FOUND HIGH | Wed Aug 25 05:45:00 IDT 2021
FOUND LOW | Wed Aug 25 06:15:00 IDT 2021
FOUND HIGH | Wed Aug 25 06:25:00 IDT 2021
FOUND LOW | Wed Aug 25 06:35:00 IDT 2021
FOUND HIGH | Wed Aug 25 06:40:00 IDT 2021
FOUND LOW | Wed Aug 25 06:55:00 IDT 2021
FOUND HIGH | Wed Aug 25 07:05:00 IDT 2021
FOUND LOW | Wed Aug 25 07:25:00 IDT 2021
FOUND HIGH | Wed Aug 25 07:45:00 IDT 2021
FOUND LOW | Wed Aug 25 07:50:00 IDT 2021
FOUND HIGH | Wed Aug 25 08:20:00 IDT 2021
FOUND LOW | Wed Aug 25 08:25:00 IDT 2021
FOUND HIGH | Wed Aug 25 08:35:00 IDT 2021
FOUND LOW | Wed Aug 25 08:45:00 IDT 2021
FOUND HIGH | Wed Aug 25 08:50:00 IDT 2021
FOUND LOW | Wed Aug 25 09:15:00 IDT 2021
FOUND HIGH | Wed Aug 25 09:30:00 IDT 2021
FOUND LOW | Wed Aug 25 09:35:00 IDT 2021
FOUND HIGH | Wed Aug 25 09:40:00 IDT 2021
FOUND LOW | Wed Aug 25 09:55:00 IDT 2021
FOUND HIGH | Wed Aug 25 10:00:00 IDT 2021
FOUND LOW | Wed Aug 25 10:05:00 IDT 2021
FOUND HIGH | Wed Aug 25 10:15:00 IDT 2021
FOUND LOW | Wed Aug 25 10:45:00 IDT 2021
FOUND HIGH | Wed Aug 25 10:50:00 IDT 2021
FOUND LOW | Wed Aug 25 11:15:00 IDT 2021
FOUND HIGH | Wed Aug 25 11:20:00 IDT 2021
FOUND LOW | Wed Aug 25 11:35:00 IDT 2021
FOUND HIGH | Wed Aug 25 11:45:00 IDT 2021
FOUND LOW | Wed Aug 25 11:55:00 IDT 2021
FOUND HIGH | Wed Aug 25 12:15:00 IDT 2021

I am not sure if it is correct, but you can try:我不确定它是否正确,但您可以尝试:

def IsPivotHigh(array: ArrayData[T], leftPeriods: int, rightPeriods: int):
    """Return True if is Top Pivot Point, Note: It use future price"""

    isPivotPoint = HHVBars(array, leftPeriods) == 0

    barCount = len(isPivotPoint)

    for i in range(0, barCount):
        if isPivotPoint[i]:
            for j in range(i + 1, min(barCount, i + rightPeriods)):
                if j >= barCount:
                    continue
                if isPivotPoint[j]:
                    isPivotPoint[i] = False
                    break

    for i in range(max(0, barCount - rightPeriods), barCount):
        isPivotPoint[i] = False

    return isPivotPoint


def PivotHigh(array: ArrayData[T], leftPeriods: int, rightPeriods: int):
    return ValueWhen(IsPivotHigh(array, leftPeriods, rightPeriods), array)


def PivotHighBars(array: ArrayData[T], leftPeriods: int, rightPeriods: int):
    return BarsSince(IsPivotHigh(array, leftPeriods, rightPeriods))

I know this is an old post but I've made a very simple python implementation that anyone can build on, it does the same thing as Pine Scripts ta.pivot functions.我知道这是一篇旧文章,但我做了一个非常简单的 python 实现,任何人都可以在其上构建,它与 Pine Scripts ta.pivot 函数做同样的事情。

code:代码:

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

the lookback variables simply means that if you take one price point and look n(Looback left) candles left and n(lookback right) candles right, and still its the lowest/highest then that's the pivot回溯变量只是意味着,如果您取一个价格点,然后向左看 n(Looback left) 根蜡烛,向右看 n(lookback right) 根蜡烛,并且仍然是最低/最高,那么这就是枢轴

You could construct something similar with a one-liner with pandas:您可以使用 pandas 的单线构造类似的东西:

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

For 'High' pivots pd.Series 'high_column' and:对于 'High' 枢轴 pd.Series 'high_column' 和:

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

for the 'Lows'.对于“低点”。 It avoids using loops and is a fast vectorized function.它避免使用循环,是一个快速矢量化的 function。

Here's my Python implementation.这是我的 Python 实现。 Works exactly as ta.pivothigh and ta.pivotlow .ta.pivothighta.pivotlow 完全相同

Pivot high: Pivot 高:

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

Pivot low: Pivot 低:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM