尝试用 barssince 替换手动计数器

Trying to replace a manual counter with barssince

我有两个问题:

  1. 我想用 barssince 替换 redCandlesCounter,因为它看起来更好。问题是当我这样做时:if (barssince(not isCandleGreen and close > middleBand and open < upperBand) > 2 and isLong) 通过在下一根蜡烛上卖出有点打破了逻辑,这不是我想要的。顺便说一下,测试是在 GTO/USDT (Binance) 30m 间隔上进行的,图片是在 21 年 3 月 30 日 18:30.

预计不会:

预计:

  1. 一种更性感的方式来取代 isCandleGreen = close > open?

代码

//@version=4
strategy(title="MACD+BB Strategy", overlay=true, max_labels_count=500, initial_capital=300, currency=currency.USD, pyramiding=0, default_qty_type=strategy.percent_of_equity, default_qty_value=100, precision=2, commission_type=strategy.commission.percent, commission_value=0.1000)

// MACD Inputs
fast_length = input(title="Fast Length", type=input.integer, defval=12)
slow_length = input(title="Slow Length", type=input.integer, defval=26)
src = input(title="Source", type=input.source, defval=close)
signal_length = input(title="Signal Smoothing", type=input.integer, minval=1, maxval=50, defval=9)
sma_source = input(title="Simple MA (Oscillator)", type=input.bool, defval=false)
sma_signal = input(title="Simple MA (Signal Line)", type=input.bool, defval=false)

// MACD Calculations
fast_ma = sma_source ? sma(src, fast_length) : ema(src, fast_length)
slow_ma = sma_source ? sma(src, slow_length) : ema(src, slow_length)
macd = fast_ma - slow_ma
//=========================================================================================

// Bollinger Bands
length = input(20, minval=1)
srcBB = input(close, title="Source")
mult = input(2.0, minval=0.001, maxval=50, title="StdDev")
middleBand = sma(srcBB, length)
dev = mult * stdev(srcBB, length)
upperBand = middleBand + dev
lowerBand = middleBand - dev
offset = input(0, "Offset", type = input.integer, minval = -500, maxval = 500)
plot(middleBand, "Basis", color=#198787, offset=offset)
p1 = plot(upperBand, "Upper", color=#198787, offset=offset)
p2 = plot(lowerBand, "Lower", color=#198787, offset=offset)
fill(p1, p2, title = "Background", color=#198787, transp=95)
//=========================================================================================

// Testing Start dates
testStartYear = input(2020, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0)

// Stop date if you want to use a specific range of dates
testStopYear = input(2030, "Backtest Stop Year")
testStopMonth = input(1, "Backtest Stop Month")
testStopDay = input(1)
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,0,0)

testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false
//=========================================================================================

// Initialization
isLong  = (strategy.position_size > 0)
isShort = (strategy.position_size < 0)

var redCandlesCounter = 0
var wasBelowMiddleBandOnce = false
buySignal = false    
sellSignal = false

// Determine whether the candle is green
isCandleGreen = close > open

if (open < middleBand and close < middleBand)
    wasBelowMiddleBandOnce := true

if (macd > 0 and wasBelowMiddleBandOnce and isCandleGreen and open > middleBand and close < upperBand)
    buySignal := true
    redCandlesCounter := 0

if (not isCandleGreen and close > middleBand and open < upperBand)
    redCandlesCounter := redCandlesCounter + 1

if (redCandlesCounter == 2 and isLong)
    sellSignal := true
    redCandlesCounter := 0
    wasBelowMiddleBandOnce := false

// DEBUGGING MACHINE
plotchar(wasBelowMiddleBandOnce, "Bar index", "", location.top)

if (buySignal and testPeriod())
    strategy.entry("Buy", strategy.long, comment="Buy")

if (sellSignal and testPeriod())
    strategy.close("Buy", comment="Activated sell condition")

//plotchar(buySignal, "Buy", color=#32CD32, size=size.tiny, location=location.belowbar, char="▲")
//plotchar(sellSignal, "Sell", color=#DC143C, size=size.tiny, location=location.abovebar, char="▼")

我想,你可以尝试像这样使用 barssince:

***
some_fun() => 
    barssince(not isCandleGreen and close > middleBand and open < upperBand)
// this means that previous 2 bars is red, their close > middleBand and open < upperBand
plot(some_fun() == 0 and some_fun()[1] == 0 ? 1 : 0)
***

用户手册告诉我们,当表达式为真时,barssince 应该 return 从位置计算柱数。

更新:另一个正确但不是最优的解决方案 valuewhen

n = valuewhen(macd > 0 and wasBelowMiddleBandOnce and isCandleGreen and open > middleBand and close < upperBand, bar_index, 0)
v1 = valuewhen(not isCandleGreen and close > middleBand and open < upperBand, bar_index, 0)
v2 = valuewhen(not isCandleGreen and close > middleBand and open < upperBand, bar_index, 1)
cond = v1 > n and v2 > n
plot(cond and isLong ? 1 : 0)