繁体   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在这两个 function 中,rightbars 是什么意思? 请帮忙。

leftbars 和 rightbars 是pivot函数在搜索枢轴时查看的柱数。 例如: pivothigh(10,10)将搜索左侧 10 根柱线(过去数据)和右侧 10 根柱线(未来数据)期间未超过的最高价。 请注意,如果右侧的柱线少于 10 个,该函数将无法确定枢轴。

我试图在 pine 脚本中创建它的一个简单版本,它不使用 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

我也需要更好地了解pivothigh()pivotlow()函数如何在内部工作,所以我努力为自己编写 Pine Script 版本(使用 Pine Script 的第 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

这是我为 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);

在搜索了这种实现之后,我找到了这个线程。 这是我为那些一直在使用 Binance API 的人提供的实现。 (用java编写)

根据我自己的测试,它与 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);
    }
}

逻辑仍然适用。 享受

结果:

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

我不确定它是否正确,但您可以尝试:

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

我知道这是一篇旧文章,但我做了一个非常简单的 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(Looback left) 根蜡烛,向右看 n(lookback right) 根蜡烛,并且仍然是最低/最高,那么这就是枢轴

您可以使用 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()

对于“低点”。 它避免使用循环,是一个快速矢量化的 function。

这是我的 Python 实现。 ta.pivothighta.pivotlow 完全相同

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 低:

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