本策略是一个基于Jackson QFL(Quick finger Luc)思想的交易系统,主要通过识别市场恐慌性下跌时机进行建仓,并通过均线系统进行止盈止损管理。策略核心是捕捉短期剧烈波动带来的交易机会,通过多重技术指标确认入场时机,实现低位建仓的目标。
策略采用ATR(平均真实波幅)指标和自定义的基准线(Base Level)、反弹线(Rebound Level)作为主要交易信号。当价格出现恐慌性下跌并突破基准线时,触发做多信号。系统通过计算近期K线波动范围,结合ATR倍数来判定是否出现恐慌性下跌。止盈设置了三种模式:平均价格、首次入场价格和分批止盈,可根据不同市场环境灵活选择。系统还设置了冷却期,避免频繁交易。
QFL震荡条件止损均线策略是一个综合性的交易系统,通过多重技术指标捕捉市场恐慌性下跌机会。策略设计考虑了实战需求,包含完整的入场、止盈止损和风险控制机制。虽然存在一定局限性,但通过持续优化和完善,有望在实际交易中取得稳定收益。建议投资者在实盘应用前进行充分的历史数据回测,并根据具体市场特征调整参数设置。
/*backtest
start: 2024-02-19 00:00:00
end: 2025-02-17 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=6
strategy("Jackson Quickfingersluc (QFL) Strategy", overlay=true)
// Parameters
baseLevelMultiplier = input.float(1, title="Base Level Multiplier", minval=0.1, maxval=1.0, step=0.05)
reboundMultiplier = input.float(0.8, title="Rebound Level Multiplier", minval=0.0001, maxval=1.0, step=0.01) // Multiplier for range of past candles
lookBackPeriod = input.int(50, title="Look-back Period", minval=10)
atrPeriod = input.int(14, title="ATR Period", minval=1)
atrMultiplier = input.float(1.2, title="Panic Sell ATR Multiplier", minval=0.1, maxval=5.0, step=0.1) // Multiplier for ATR threshold
exitProfitThreshold = input.float(0.01, title="Exit Profit Threshold", minval=0.001, maxval=0.1, step=0.001) // Minimum profit threshold (e.g., 1%)
panicSellPercentage = input.float(0.005, title="Panic Sell Percentage Below Base Level", step=0.0001) // Percentage below base level for panic sell
showLabels = input.bool(true, title="Show Buy/Sell Labels") // Toggle for showing labels
takeProfitOption = input.string("avg_price", title="Take Profit Option", options=["avg_price", "first_entry", "each_position"]) // TP option selection
rangeBars = input.int(3, title="Number of Bars for Range Calculation", minval=1) // Input for number of bars for range calculation
cooldownBars = input.int(5, title="Cooldown Period (Bars)", minval=1) // Input for cooldown period after a buy
// Calculate Base Level
lowestClose = ta.lowest(close, lookBackPeriod)
baseLevel = lowestClose[1] * baseLevelMultiplier
// Calculate Rebound Level as a multiplier of the range of the last 'rangeBars' bars
rangeLastBars = ta.highest(high, rangeBars) - ta.lowest(low, rangeBars)
reboundLevel = reboundMultiplier * rangeLastBars + baseLevel
// Plotting base and rebound levels
plot(baseLevel, color=color.green, linewidth=2, title="Base Level")
plot(reboundLevel, color=color.red, linewidth=2, title="Rebound Level")
// Calculate ATR
atrValue = ta.atr(atrPeriod)
// Factorial average and panic sell movement calculation
var bool panicSellMovement = false
// Loop through each range and check for panic sell condition
for bar_i = 1 to rangeBars+1
currentBarRange = high[bar_i - 1] - low[bar_i - 1] // Current bar range
rangeOfLastXBars = ta.highest(high, bar_i) - ta.lowest(low, bar_i) // Range of the last `bar_i` bars
// Condition 1: Check if the average range of the last `bar_i` bars exceeds ATR multiplier
if (rangeOfLastXBars / bar_i) > atrMultiplier * atrValue
panicSellMovement := true
break // Exit the loop immediately
// Condition 2: Check if the current bar range exceeds ATR multiplier
if currentBarRange > atrMultiplier * atrValue
panicSellMovement := true
break // Exit the loop immediately
// Define the adjusted base level threshold for panic sell (base level - percentage)
panicSellThreshold = baseLevel[0] * (1 - panicSellPercentage)
// Define panic sell condition with base level check and the panic sell percentage threshold
isPanicSell = low < panicSellThreshold and panicSellMovement
// Define rebound condition
isRebound = close > reboundLevel
// Track the last entry bar index
var float lastEntryBar = na
// Store entry prices for each position in an array
var float[] entryPrices = na
var float[] entrySizes = na
bool exit_cond = false
if (na(entryPrices))
entryPrices := array.new_float(0)
if (na(entrySizes))
entrySizes := array.new_float(0)
// Strategy to simulate buys and sells (for backtesting purposes)
entry_cond = isPanicSell and (na(lastEntryBar) or (bar_index - lastEntryBar) > cooldownBars)
if entry_cond
strategy.entry("Buy", strategy.long)
lastEntryBar := bar_index // Set last entry bar to current bar index
// Store the entry price and size for this new position
array.push(entryPrices, close)
array.push(entrySizes, strategy.position_size)
// Trigger BUY alert
alert("BUY ALERT: Panic Sell condition triggered", alert.freq_once_per_bar)
isTakeProfitCondition(entryPrice) =>
profitPercentage = (close - entryPrice) / entryPrice
profitCondition = profitPercentage >= exitProfitThreshold
reboundCondition = isRebound
profitCondition and reboundCondition
// Check TP condition based on selected option
if takeProfitOption == "avg_price"
avgEntryPrice = strategy.position_avg_price
if isTakeProfitCondition(avgEntryPrice)
exit_cond := true
strategy.close("Buy")
else if takeProfitOption == "first_entry"
firstEntryPrice = strategy.opentrades.entry_price(0)
if isTakeProfitCondition(firstEntryPrice)
exit_cond := true
strategy.close("Buy")
else if takeProfitOption == "each_position"
// Ensure we only check when there is at least one entry
if array.size(entryPrices) > 0
// Loop until there are no more entries left
i = 0
while i < array.size(entryPrices)
entryPrice = array.get(entryPrices, i)
positionSize = array.get(entrySizes, i)
// Check profit condition for each position
if isTakeProfitCondition(entryPrice)
exit_cond := true
// Remove the entry price and size from the arrays once the position is closed
array.remove(entryPrices, i)
array.remove(entrySizes, i)
strategy.close("Buy", qty=positionSize) // Close only the position that reached the target
else
// Only increment the index if the current entry is not closed
i := i + 1
// Buy and Sell signals with labels and alerts
if showLabels and isPanicSell
label.new(bar_index, low, "BUY", style=label.style_label_up, color=color.green, textcolor=color.white, size=size.small)
if showLabels and exit_cond
label.new(bar_index, high, "SELL", style=label.style_label_down, color=color.rgb(213, 20, 20), textcolor=color.white, size=size.small)
// Trigger SELL alert
if exit_cond
alert("SELL ALERT: Exit condition met (take profit or rebound)", alert.freq_once_per_bar)