
동적 필터 양 거래 전략 (Dynamic Filter Quant Trading Strategy) 은 주로 범위 필터 지표와 여러 가지 기술 지표를 결합하여 암호화폐 BTCUSDT의 자동화 된 트렌드 추적 거래를 구현합니다. 전략은 고주파량 거래에 적용되며, 스톱 로스를 동적으로 조정하여 수익을 잠금하고, 회수율을 낮추습니다.
이 전략의 핵심 지표는 범위 필터 (Range Filter) 이며, 이는 통계 가격 변화 범위를 기반으로 중선을 생성한다. 가격이 중선을 뚫을 때 거래 신호를 생성한다. 또한, 전략은 RSI 지표가 과매매 과매매를 판단하고, 평균 선이 트렌드를 판단하고, MACD가 동력을 판단하는 등의 지표와 결합하여 더 신뢰할 수있는 거래 신호를 형성한다.
구체적으로, 범위 필터 중선은 가격 변화 범위의 지수 이동 평균에 의해 얻어지며, 방향 판단은 그 중선을 뚫는 강도와 속도에 의해 결정된다. 가격이 연속적으로 몇 개의 K 선이 중선을 뚫을 때 강력한 뚫는 신호가 생성된다.
RSI 지표는 오버 바이 오버 셀 상태를 판단하여 필터 신호를 확인한다. 평행선이 올라가는 것은 트렌드 상향으로 판단하고, 내려가는 것은 트렌드 하향으로 판단한다. MACD 지표는 시장 운동이 트렌드를 형성하기에 충분하다는 것을 판단한다.
이러한 지표들을 종합하여 판단하면, 포지션을 구축할 수 있는 시점으로 비교적 신뢰할 수 있는 트렌드 브레이크 포인트를 식별할 수 있다.
이 전략의 가장 큰 장점은 단일 기술 지표에 의존하지 않고 여러 지표를 결합하여 의사 결정을 내리는 것으로, 잘못된 거래의 가능성을 효과적으로 줄이고 거래 신호를 더 신뢰할 수 있도록합니다. 또한, 동적 조정 매개 변수는 전략이 시장 변화에 적응 할 수 있도록합니다.
또 다른 장점은 높은 주파수 거래가 가능하다는 것입니다. 범위 필터 지표는 소주기 가격 변화에 민감합니다. 이는 전략이 짧은 시간 내에 평화적인 포지션을 열 수 있다는 것을 의미하며, 따라서 높은 주파수와 큰 변동의 암호화폐 시장에서 이익을 얻을 수 있습니다.
이 전략에는 여전히 약간의 위험이 있습니다. 첫째, 기술적 인 형식의 판단이 실패 할 위험이 있습니다. 지표는 가격 움직임을 100% 보장 할 수 없기 때문입니다. 가격이 반전되면 정지 손실이 발생할 수 있습니다.
또 다른 주요 위험은 범위 필터 중선이 가격 변동을 완전히 필터링 할 수 없다는 것입니다. 중간 범위보다 큰 가격 변동이 발생하면 중선은 무효화되어 잘못된 신호가 발생할 위험이 있습니다. 이 경우 중선 범위를 확장하는 적절한 용이성을 부여 할 수 있습니다.
마지막으로, 고주파 거래 자체에도 위험이 있습니다. 거래 주파수가 너무 높을 때 거래 비용이 더 많이 발생하여 수익의 일부를 상쇄 할 수 있습니다. 이러한 경우 거래 주파수 및 포지션 시간을 적절하게 줄일 수 있습니다.
이 전략에는 더 많은 최적화 할 여지가 있습니다. 예를 들어, 트렌드를 확인하는 변동률 지표와 같은 더 많은 지표를 결합하거나 거래 신호를 더 정확하게 확인하기 위해 더 엄격한 필터링 조건을 구현하거나 다른 암호화폐와 주식의 가격 행동 법칙을 연구하여 가장 적합한 지표 파라미터를 설정하는 것을 고려할 수 있습니다.
거래 논리적으로, 동적 스톱로스 및 스톱레이드 폭을 설정할 수도 있다. 즉, 지분량이 커지면 스톱로스 범위를 확장하여 더 많은 이익을 잠금할 수 있다. 또는 수익이 커지면 스톱레이드 속도를 가속화할 수 있다. 이것은 어느 정도 회수량을 줄일 수 있다.
마지막으로, 필터 변수를 최적화하여 중선 범위를 효율적으로 흔들림을 필터링 할 수 있도록 한 변수 모음을 찾을 수 있습니다. 이러한 경우 많은 양의 재측정 데이터를 사용하여 융복합 분석이 필요합니다.
이 전략은 여러 지표들을 합쳐서 성공적으로 판단하여, 높은 신뢰성의 거래 전략을 형성하고, 고주파수 수량 거래에 적용하기에 적합하다. 지속적인 최적화와 개선에 의해, 안정적인 수익을 얻을 수 있다고 믿으며, 더 발전할 가치가 있다.
/*backtest
start: 2022-12-18 00:00:00
end: 2023-12-24 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy(title='5cel Scalp Strategy BTCUSDT Long & Short 30 Min', shorttitle='BTCUSDT Long & Short Scalp 30m', precision=1, overlay=true)
//Swing Call - Based on RSI Overbought & Oversold
//#### Starts Here #####
ema_value = input(5)
sma_value = input(50)
ema1 = ta.ema(close, ema_value)
sma2 = ta.sma(close, sma_value)
rs = ta.rsi(close, 14)
iff_1 = high < sma2 ? color.red : color.yellow
iff_2 = low > sma2 ? color.lime : iff_1
mycolor = rs >= 85 or rs <= 15 ? color.yellow : iff_2
//For Main Strategy
bool swingCallGreen = false
bool swingCallRed = false
bool swingCallYellow = false
if rs >= 85 or rs <= 15
//color.yellow
swingCallGreen := false
swingCallRed := false
swingCallYellow := true
swingCallYellow
else
if low > sma2
//color.lime
swingCallGreen := true
swingCallRed := false
swingCallYellow := false
swingCallYellow
//color.red
else if high < sma2
swingCallGreen := false
swingCallRed := true
swingCallYellow := false
swingCallYellow
else
//color.yellow
swingCallGreen := false
swingCallRed := false
swingCallYellow := true
swingCallYellow
hlong = input.int(80, title='Overbought limit of RSI', step=1)
ll = input.int(20, title='Oversold limit of RSI', step=1)
buyexit = ta.crossunder(rs, hlong)
sellexit = ta.crossover(rs, ll)
sellcall = ta.crossover(sma2, ema1) and open > close
buycall = ta.crossunder(sma2, ema1) and high > sma2
//#### Ends Here #####
//Parabolic SAR - Trend Circles
//#### Starts Here #####
start = input.int(2, minval=0, maxval=10, title='Start - Default = 2 - Multiplied by .01')
increment = input.int(2, minval=0, maxval=10, title='Step Setting (Sensitivity) - Default = 2 - Multiplied by .01')
maximum = input.int(2, minval=1, maxval=10, title='Maximum Step (Sensitivity) - Default = 2 - Multiplied by .10')
sus = input(true, 'Show Up Trending Parabolic Sar')
sds = input(true, 'Show Down Trending Parabolic Sar')
disc = input(false, title='Start and Step settings are *.01 so 2 = .02 etc, Maximum Step is *.10 so 2 = .2')
startCalc = start * .01
incrementCalc = increment * .01
maximumCalc = maximum * .10
sarUp = ta.sar(startCalc, incrementCalc, maximumCalc)
sarDown = ta.sar(startCalc, incrementCalc, maximumCalc)
colUp = close >= sarDown ? color.lime : na
colDown = close <= sarUp ? color.red : na
parabolicSARGreen = ta.sar(startCalc, incrementCalc, maximumCalc)
parabolicSARRed = ta.sar(startCalc, incrementCalc, maximumCalc)
//#### Ends Here #####
//EMA Line
//#### Starts Here #####
ema100 = ta.ema(close, 100)
//#### Ends Here #####
// Ichimoku Cloud
//#### Starts Here #####
sCloud = input(false, 'Show Ichimoku lines')
// Colors
colorGreen = #00ff00
colorRed = #ff0000
colorTenkanViolet = #9400D3
colorKijun = #fdd8a0
colorLime = #006400
colorMaroon = #8b0000
//Periods are set to standard
tenkanPeriods = input.int(9, minval=1, title='Tenkan')
kijunPeriods = input.int(26, minval=1, title='Kijun')
chikouPeriods = input.int(52, minval=1, title='Chikou')
displacement = input.int(26, minval=1, title='Offset')
donchian(len) =>
math.avg(ta.lowest(len), ta.highest(len))
tenkan = donchian(tenkanPeriods)
kijun = donchian(kijunPeriods)
senkouA = math.avg(tenkan, kijun)
senkouB = donchian(chikouPeriods)
displacedSenkouA = senkouA[displacement]
displacedSenkouB = senkouB[displacement]
bullishSignal = ta.crossover(tenkan, kijun)
bearishSignal = ta.crossunder(tenkan, kijun)
bullishSignalValues = bullishSignal ? tenkan : na
bearishSignalValues = bearishSignal ? tenkan : na
strongBullishSignal = bullishSignalValues > displacedSenkouA and bullishSignalValues > displacedSenkouB
neutralBullishSignal = bullishSignalValues > displacedSenkouA and bullishSignalValues < displacedSenkouB or bullishSignalValues < displacedSenkouA and bullishSignalValues > displacedSenkouB
weakBullishSignal = bullishSignalValues < displacedSenkouA and bullishSignalValues < displacedSenkouB
strongBearishSignal = bearishSignalValues < displacedSenkouA and bearishSignalValues < displacedSenkouB
neutralBearishSignal = bearishSignalValues > displacedSenkouA and bearishSignalValues < displacedSenkouB or bearishSignalValues < displacedSenkouA and bearishSignalValues > displacedSenkouB
weakBearishSignal = bearishSignalValues > displacedSenkouA and bearishSignalValues > displacedSenkouB
//#### Ends Here #####
//Higher High Lower Low Strategy
//#### Starts Here #####
lb = input.int(5, title='Left Bars', minval=1)
rb = input.int(5, title='Right Bars', minval=1)
showsupres = input.bool(true, title='Support/Resistance', inline='srcol')
supcol = input.color(color.lime, title='', inline='srcol')
rescol = input.color(color.red, title='', inline='srcol')
// srlinestyle = input.string(line.style_dotted, title='Line Style/Width', options=[line.style_solid, line.style_dashed, line.style_dotted], inline='style')
srlinewidth = input.int(3, title='', minval=1, maxval=5, inline='style')
changebarcol = input.bool(true, title='Change Bar Color', inline='bcol')
bcolup = input.color(color.blue, title='', inline='bcol')
bcoldn = input.color(color.black, title='', inline='bcol')
ph = ta.pivothigh(lb, rb)
pl = ta.pivotlow(lb, rb)
iff_3 = pl ? -1 : na // Trend direction
hl = ph ? 1 : iff_3
iff_4 = pl ? pl : na // similar to zigzag but may have multiple highs/lows
zz = ph ? ph : iff_4
valuewhen_1 = ta.valuewhen(hl, hl, 1)
valuewhen_2 = ta.valuewhen(zz, zz, 1)
zz := pl and hl == -1 and valuewhen_1 == -1 and pl > valuewhen_2 ? na : zz
valuewhen_3 = ta.valuewhen(hl, hl, 1)
valuewhen_4 = ta.valuewhen(zz, zz, 1)
zz := ph and hl == 1 and valuewhen_3 == 1 and ph < valuewhen_4 ? na : zz
valuewhen_5 = ta.valuewhen(hl, hl, 1)
valuewhen_6 = ta.valuewhen(zz, zz, 1)
hl := hl == -1 and valuewhen_5 == 1 and zz > valuewhen_6 ? na : hl
valuewhen_7 = ta.valuewhen(hl, hl, 1)
valuewhen_8 = ta.valuewhen(zz, zz, 1)
hl := hl == 1 and valuewhen_7 == -1 and zz < valuewhen_8 ? na : hl
zz := na(hl) ? na : zz
findprevious() => // finds previous three points (b, c, d, e)
ehl = hl == 1 ? -1 : 1
loc1 = 0.0
loc2 = 0.0
loc3 = 0.0
loc4 = 0.0
xx = 0
for x = 1 to 1000 by 1
if hl[x] == ehl and not na(zz[x])
loc1 := zz[x]
xx := x + 1
break
ehl := hl
for x = xx to 1000 by 1
if hl[x] == ehl and not na(zz[x])
loc2 := zz[x]
xx := x + 1
break
ehl := hl == 1 ? -1 : 1
for x = xx to 1000 by 1
if hl[x] == ehl and not na(zz[x])
loc3 := zz[x]
xx := x + 1
break
ehl := hl
for x = xx to 1000 by 1
if hl[x] == ehl and not na(zz[x])
loc4 := zz[x]
break
[loc1, loc2, loc3, loc4]
float a = na
float b = na
float c = na
float d = na
float e = na
if not na(hl)
[loc1, loc2, loc3, loc4] = findprevious()
a := zz
b := loc1
c := loc2
d := loc3
e := loc4
_hh = zz and a > b and a > c and c > b and c > d
_ll = zz and a < b and a < c and c < b and c < d
_hl = zz and (a >= c and b > c and b > d and d > c and d > e or a < b and a > c and b < d)
_lh = zz and (a <= c and b < c and b < d and d < c and d < e or a > b and a < c and b > d)
plotshape(_hl, text='HL', title='Higher Low', style=shape.labelup, color=color.new(color.lime, 0), textcolor=color.new(color.black, 0), location=location.belowbar, offset=-rb)
plotshape(_hh, text='HH', title='Higher High', style=shape.labeldown, color=color.new(color.lime, 0), textcolor=color.new(color.black, 0), location=location.abovebar, offset=-rb)
plotshape(_ll, text='LL', title='Lower Low', style=shape.labelup, color=color.new(color.red, 0), textcolor=color.new(color.white, 0), location=location.belowbar, offset=-rb)
plotshape(_lh, text='LH', title='Lower High', style=shape.labeldown, color=color.new(color.red, 0), textcolor=color.new(color.white, 0), location=location.abovebar, offset=-rb)
float res = na
float sup = na
res := _lh ? zz : res[1]
sup := _hl ? zz : sup[1]
int trend = na
iff_5 = close < sup ? -1 : nz(trend[1])
trend := close > res ? 1 : iff_5
res := trend == 1 and _hh or trend == -1 and _lh ? zz : res
sup := trend == 1 and _hl or trend == -1 and _ll ? zz : sup
rechange = res != res[1]
suchange = sup != sup[1]
var line resline = na
var line supline = na
//#### Ends Here #####
//Range Filter 5Min
//#### Starts Here #####
src = input(defval=close, title='Source')
per = input.int(defval=100, minval=1, title='Sampling Period')
// Range Multiplier
mult = input.float(defval=3.0, minval=0.1, title='Range Multiplier')
// Smooth Average Range
smoothrng(x, t, m) =>
wper = t * 2 - 1
avrng = ta.ema(math.abs(x - x[1]), t)
smoothrng = ta.ema(avrng, wper) * m
smoothrng
smrng = smoothrng(src, per, mult)
// Range Filter
rngfilt(x, r) =>
rngfilt = x
rngfilt := x > nz(rngfilt[1]) ? x - r < nz(rngfilt[1]) ? nz(rngfilt[1]) : x - r : x + r > nz(rngfilt[1]) ? nz(rngfilt[1]) : x + r
rngfilt
filt = rngfilt(src, smrng)
// Filter Direction
upward = 0.0
upward := filt > filt[1] ? nz(upward[1]) + 1 : filt < filt[1] ? 0 : nz(upward[1])
downward = 0.0
downward := filt < filt[1] ? nz(downward[1]) + 1 : filt > filt[1] ? 0 : nz(downward[1])
// Target Bands
hband = filt + smrng
lband = filt - smrng
// Colors
filtcolor = upward > 0 ? color.lime : downward > 0 ? color.red : color.orange
barcolor = src > filt and src > src[1] and upward > 0 ? color.lime : src > filt and src < src[1] and upward > 0 ? color.green : src < filt and src < src[1] and downward > 0 ? color.red : src < filt and src > src[1] and downward > 0 ? color.maroon : color.orange
// Break Outs
longCond = bool(na)
shortCond = bool(na)
longCond := src > filt and src > src[1] and upward > 0 or src > filt and src < src[1] and upward > 0
shortCond := src < filt and src < src[1] and downward > 0 or src < filt and src > src[1] and downward > 0
CondIni = 0
CondIni := longCond ? 1 : shortCond ? -1 : CondIni[1]
longCondition = longCond and CondIni[1] == -1
shortCondition = shortCond and CondIni[1] == 1
//#### Ends Here #####
//#### Starts Here #####
source = close
useCurrentRes = input(true, title='Use Current Chart Resolution?')
resCustom = input.timeframe(title='Use Different Timeframe? Uncheck Box Above', defval='60')
smd = input(true, title='Show MacD & Signal Line? Also Turn Off Dots Below')
sd = input(true, title='Show Dots When MacD Crosses Signal Line?')
sh = input(true, title='Show Histogram?')
macd_colorChange = input(true, title='Change MacD Line Color-Signal Line Cross?')
hist_colorChange = input(true, title='MacD Histogram 4 Colors?')
res1 = useCurrentRes ? timeframe.period : resCustom
fastLength = input.int(12, minval=1)
slowLength = input.int(26, minval=1)
signalLength = input.int(9, minval=1)
fastMA = ta.ema(source, fastLength)
slowMA = ta.ema(source, slowLength)
macd = fastMA - slowMA
signal = ta.sma(macd, signalLength)
hist = macd - signal
outMacD = request.security(syminfo.tickerid, res1, macd)
outSignal = request.security(syminfo.tickerid, res1, signal)
outHist = request.security(syminfo.tickerid, res1, hist)
histA_IsUp = outHist > outHist[1] and outHist > 0
histA_IsDown = outHist < outHist[1] and outHist > 0
histB_IsDown = outHist < outHist[1] and outHist <= 0
histB_IsUp = outHist > outHist[1] and outHist <= 0
//MacD Color Definitions
macd_IsAbove = outMacD >= outSignal
macd_IsBelow = outMacD < outSignal
plot_color = hist_colorChange ? histA_IsUp ? color.aqua : histA_IsDown ? color.blue : histB_IsDown ? color.red : histB_IsUp ? color.maroon : color.yellow : color.gray
macd_color = macd_colorChange ? macd_IsAbove ? color.lime : color.red : color.red
signal_color = macd_colorChange ? macd_IsAbove ? color.yellow : color.yellow : color.lime
circleYPosition = outSignal
//#### Ends Here #####
//////////////////
// Main Strategy
/////////////////
//#### Starts Here #####
var bottomText = 'Something is not ok'
bool rangeBuy = false
if longCondition
rangeBuy := true
else
rangeBuy := false
bool rangeSell = false
if shortCondition
rangeSell := true
else
rangeSell := false
bool ema100Bullish = false
bool ema100Bearish = false
bool ichimokuBearish = false
bool ichimokuBullish = false
string statusChance = 'Who knows what will happen'
string futureIchimokuTrend = 'Anything can happen'
if close > ema100
ema100Bullish := true
ema100Bearish := false
else
ema100Bullish := false
ema100Bearish := true
if displacedSenkouA > displacedSenkouB
ichimokuBearish := false
futureIchimokuTrend := 'Green - chance to go up'
ichimokuBullish := true
else
ichimokuBearish := true
futureIchimokuTrend := 'Red - chance to go down'
ichimokuBullish := false
ichimokuBullish
if ema100Bullish and parabolicSARGreen
if ichimokuBullish
statusChance := '100%'
else
statusChance := '95%'
else
if ema100Bullish and parabolicSARRed
statusChance := '75%'
else if ema100Bearish and parabolicSARGreen
statusChance := '65%'
else
statusChance := '55%'
bool longTradePosition = false
bool shortTradePosition = false
string longTradeText = 'Now cannot say anything'
if (swingCallGreen or swingCallYellow) and ichimokuBullish and longCondition and ema100Bullish and parabolicSARGreen
longTradePosition := true
longTradeText := 'Bullish'
bottomText := longTradeText + ' Chance: ' + statusChance + '\n Future Trend: ' + futureIchimokuTrend
// Bottom Text
var tLog = table.new(position=position.bottom_right, rows=1, columns=2, bgcolor=color.blue, border_width=1)
table.cell(tLog, row=0, column=0, text=bottomText, text_color=color.white)
table.cell_set_text(tLog, row=0, column=0, text=bottomText)
//#### Ends Here #####
bool entryLongPosition = false
bool exitLongPosition = false
bool entryShortPosition = false
bool exitShortPosition = false
bool longPositionCount = false
bool shortPositionCount = false
if (strategy.position_size > 0)
longPositionCount := true
if (strategy.position_size < 0)
shortPositionCount := true
// Entry LONG
if (longCondition) and (not longPositionCount)
entryLongPosition := true
// Exit LONG
if (shortCondition) and (longPositionCount)
exitLongPosition := true
// Entry SHORT
if (shortCondition) and (not shortPositionCount)
entryShortPosition := true
// Exit SHORT
if (longCondition) and (shortPositionCount)
exitShortPosition := true
// LONG Entry & Exit
plotshape(entryLongPosition, style=shape.labeldown, location=location.abovebar, color=color.new(color.green, 0), size=size.tiny, title='buy label', text='5cel\nLONG Entry', textcolor=color.new(color.white, 0))
plotshape(exitLongPosition, style=shape.labelup, location=location.belowbar, color=color.new(color.blue, 0), size=size.tiny, title='sell label', text='5cel\nExit LONG', textcolor=color.new(color.white, 0))
//SHORT Entry & Exit
plotshape(entryShortPosition, style=shape.labeldown, location=location.abovebar, color=color.new(color.red, 0), size=size.tiny, title='buy label', text='5cel\nSHORT Entry', textcolor=color.new(color.white, 0))
plotshape(exitShortPosition, style=shape.labelup, location=location.belowbar, color=color.new(color.blue, 0), size=size.tiny, title='sell label', text='5cel\nExit SHORT', textcolor=color.new(color.white, 0))
//Get the Current Value
heikinashi_close = request.security(ticker.heikinashi(syminfo.tickerid), timeframe.period, close)
if entryLongPosition
longLabel = label.new(bar_index, high, text=str.tostring(heikinashi_close, '0.00'), color=color.orange, style=label.style_label_down, yloc=yloc.abovebar)
if entryShortPosition
shortLabel = label.new(bar_index, high, text=str.tostring(heikinashi_close, '0.00'), color=color.orange, style=label.style_label_down, yloc=yloc.abovebar)
/// SHORT Exit
strategy.close("short", when=exitShortPosition, comment="close_short_position")
/// LONG Exit
strategy.close("long", when=exitLongPosition, comment = "close_long_position")
/// LONG Enter
strategy.entry("long", strategy.long, when=entryLongPosition, comment="open_long_position")
/// SHORT Enter
strategy.entry("short", strategy.short, when = entryShortPosition, comment="open_short_position")