mql5/Experts/pineScript.pine
1Morty 50a3adba89
2025-09-08 21:00:32 +08:00

67 lines
No EOL
2.9 KiB
Text

//@version=5
strategy("Pinbar Basic Strategy (1:1 RR)", overlay=true, initial_capital=10000, calc_on_every_tick=false, pyramiding=0)
// ===== 参数 =====
pinbarBodyRatio = input.float(0.30, "PinbarBodyRatio", minval=0, maxval=1.0)
pinbarShadowRatio = input.float(0.60, "PinbarShadowRatio", minval=0, maxval=1.0)
minPinbarLengthPts = input.int(10, "MinPinbarLength(Points)", minval=0)
qty = input.float(1.0, "Order Qty", minval=0.0, step=0.1)
minVolume = input.float(500, "Min Volume to Trade", minval=0)
// ===== 识别上一根K线 Pinbar =====
o1 = open[1]
h1 = high[1]
l1 = low[1]
c1 = close[1]
totalLen = h1 - l1
bodySize = math.abs(c1 - o1)
isBearish = o1 > c1
upperShadow = isBearish ? (h1 - o1) : (h1 - c1)
lowerShadow = isBearish ? (c1 - l1) : (o1 - l1)
// 最小长度:点数 * 最小跳动
minLen = minPinbarLengthPts * syminfo.mintick
validLen = totalLen > 0 and totalLen >= minLen
bodyOk = validLen and (bodySize / totalLen) <= pinbarBodyRatio
shadowOk = validLen and (math.max(upperShadow, lowerShadow) / totalLen) >= pinbarShadowRatio
isBullPinbar1 = shadowOk and bodyOk and (lowerShadow > upperShadow)
isBearPinbar1 = shadowOk and bodyOk and (upperShadow > lowerShadow)
isPinbar1 = validLen and bodyOk and shadowOk and (lowerShadow != upperShadow)
// ===== 标注(偏移到上一根K线位置) =====
plotshape(isBullPinbar1, title="Bull Pinbar", style=shape.triangleup, color=color.new(color.lime, 0), size=size.tiny, location=location.belowbar, offset=1, text="BP")
plotshape(isBearPinbar1, title="Bear Pinbar", style=shape.triangledown, color=color.new(color.red, 0), size=size.tiny, location=location.abovebar, offset=1, text="SP")
// ===== 只在新出现的上一根 Pinbar 时触发一次(兼容历史与实时) =====
var int lastPinbarTime = na
newSignal = isPinbar1 and (na(lastPinbarTime) or lastPinbarTime != time[1])
volOk = volume > minVolume
longSignal = newSignal and isBullPinbar1 and volOk
shortSignal = newSignal and isBearPinbar1 and volOk
// ===== 1:1 RR 止损/止盈 =====
// 入场使用当前K线的开盘/市价(由策略托管),SL 基于上一根 Pinbar 极点,TP 与入场到 SL 的距离相等
if longSignal
// 多:SL = pinbar低点
longSL = l1
// 预估入场价:用当前bar开盘价(更接近实际回测表现)
entryPriceLong = open
riskLong = math.max(entryPriceLong - longSL, syminfo.mintick)
longTP = entryPriceLong + riskLong
strategy.entry("Long", strategy.long, qty=qty)
strategy.exit("Long-Exit", "Long", stop=longSL, limit=longTP)
lastPinbarTime := time[1]
if shortSignal
// 空:SL = pinbar高点
shortSL = h1
entryPriceShort = open
riskShort = math.max(shortSL - entryPriceShort, syminfo.mintick)
shortTP = entryPriceShort - riskShort
strategy.entry("Short", strategy.short, qty=qty)
strategy.exit("Short-Exit", "Short", stop=shortSL, limit=shortTP)
lastPinbarTime := time[1]