이 전략은 MACD 지표가 높은 주기 (예: 일선) 에서 트렌드를 형성하고, 낮은 주기 (예: 5 분) 에서 특정 거래를 실행하기 위해 사용된다. 이러한 초주기 운영은 MACD 지표 거래 전략의 신뢰성을 높이기 위해 고안되었다.
전략적 원칙:
높은 주기에서 MACD 지표를 계산하여 큰 트렌드 방향을 판단한다.
낮은 주기에서 진입점을 찾으며, MACD 위쪽 신호선을 통과할 때 더하고, 아래쪽 신호선을 통과할 때 공백을 다.
MFI 지표의 과매매 신호와 결합하여 거래 시점을 추가로 확인합니다.
스톱 라인 스톱 라인을 설정하고, 리스크 관리를 한다.
매개 변수를 최적화하고, 지표와 전략의 안정성을 향상시킵니다.
이 전략의 장점:
“자동화 시장의 소음”에 방해받지 않도록 주기간의 판단을 한다.
MFI 지표 검증, 가짜 신호를 필터링, 정확도를 향상한다.
단편 거래의 위험을 조절하는 데 도움이 되는 Stop Loss Stop mechanism.
이 전략의 위험은:
초주기 연동에 지연 문제가 있어 최적의 시점을 놓칠 수 있다.
MACD와 MFI 모두 가짜 신호가 많이 나타날 수 있으므로 신중하게 검증해야 한다.
거래의 위험을 감수하기 위해 엄격한 자금 관리가 필요합니다.
요약하자면, 이 전략은 크로스 사이클 MACD를 사용하여 큰 추세를 판단하고 MFI 지표를 사용하여 필터링을 통해 낮은 사이클에서 거래를 할 수 있으며 안정성을 향상시킬 수 있습니다. 그러나 크로스 사이클 지연 문제는 여전히 존재하며 투자자는 여전히 신중하게 작동해야합니다.
/*backtest
start: 2022-09-11 00:00:00
end: 2023-01-18 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//(c) Wunderbit Trading
//Modified by Mauricio Zuniga - Trade at your own risk
//This script was originally shared on Wunderbit website as a free open source script for the community. (https://www.tradingview.com/u/Wunderbit/)
//
//WHAT THIS SCRIPT DOES:
// This is a scalping script originally intended to be used on altorightmic bot trading.
// This strategy is based on the trend-following momentum indicator. It includes the Money Flow index as an additional point for entry.
//HOW IT DOES IT:
// It uses a combination of MACD and MFI indicators to create entry signals. Parameters for each indicator have been surfaced for user configurability.
// Take profits are fixed, but stop loss uses ATR configuration to minimize losses and close profitably.
//HOW IS MY VERSION ORIGINAL:
// I started trying to deploy this script myself in my algorithmic tradingg but ran into some issues which I have tried to address in this version.
// Delayed Signals : The script has been refactored to use a time frame drop down. The higher time frame can be run on a faster chart (recommended on one minute chart for fastest signal confirmation and relay to algotrading platform.
// Repainting Issues : All indicators have been recoded to use the security function that checks to see if the current calculation is in realtime, if it is, then it uses the previous bar for calculation.
// If you are still experiencing repainting issues based on intended (or non intended use), please provide a report with screenshot and explanation so I can try to address.
// Filtering : I have added to additional filters an ABOVE EMA Filter and a BELOW RSI Filter (both can be turned on and off)
// Customizable Long and Clos Messages : This allows someone to use the script for algorithmic trading without having to alter code. It also means you can use one indicator for all of your different alterts required for your bots.
//HOW TO USE IT:
// Find a pair with high volatility - I have found it works particularly well with 3L and 3S tokens for crypto. although it the limitation is that confrigurations I have found to work typically have low R/R ratio, but very high win rate and profit factor.
// Ieally set one minute chart for bots, but you can use other charts for manual trading. The signal will be delayed by one bar but I have found configurations that still test well.
// Select a time frame in configuration for your indicator calculations.
// I like ot use 5 and 15 minutes for scalping scenarios, but I am interested in hearing back from other community memebers.
// Optimize your indicator without filters (trendFilter and RSI Filter)
// Use the TrendFilter and RSI Filter to further refine your signals for entry.
//@version=4
strategy("Customizable HTF MACD Strategy v1.5", overlay=false, pyramiding=0, commission_type=strategy.commission.percent, commission_value=0.08, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, currency = currency.USD, calc_on_every_tick=true)
openlongcomment = "Comment In Here"
closelongcomment = ""
openshortcomment = ""
closeshortcommment = ""
//RES
res = input(title="Resolution", type=input.resolution, defval="5", group="Strategy", inline="1")
ribbon_period = input(19, "Period", step=1, group="Strategy", inline="1")
olc = input(title="Open Long Comment", type=input.string, defval="",group="Strategy", inline="2")
clc = input(title="Close Long Comment", type=input.string, defval="",group="Strategy", inline="2")
if not(olc == "")
openlongcomment := olc
if not(clc == "")
closelongcomment := clc
// FUNCTIONS
Ema(src,p) =>
ema = 0.
sf = 2/(p+1)
ema := nz(ema[1] + sf*(src - ema[1]),src)
Sma(src,p) => a = cum(src), (a - a[max(p,0)])/max(p,0)
Atr(p, res) =>
atr = 0.
highHTF = security(syminfo.tickerid, res, high[barstate.isrealtime ? 1 : 0])
lowHTF = security(syminfo.tickerid, res, low[barstate.isrealtime ? 1 : 0])
closeHTF = security(syminfo.tickerid, res, close[barstate.isrealtime ? 1 : 0])
Tr = max(highHTF - lowHTF, max(abs(highHTF - closeHTF[1]), abs(lowHTF - closeHTF[1])))
atr := nz(atr[1] + (Tr - atr[1])/p,Tr)
htfClose = security(syminfo.tickerid, res, close[barstate.isrealtime ? 1 : 0])
leadLine1 = ema(htfClose, ribbon_period)
leadLine2 = sma(htfClose, ribbon_period)
// p3 = plot(leadLine1, color= #53b987, title="EMA", transp = 50, linewidth = 1)
// p4 = plot(leadLine2, color= #eb4d5c, title="SMA", transp = 50, linewidth = 1)
// fill(p3, p4, transp = 60, color = leadLine1 > leadLine2 ? #53b987 : #eb4d5c)
//Upward Trend
UT=leadLine2 < leadLine1
DT=leadLine2>leadLine1
// MACD
fast_length = input(title="Fast Length", type=input.integer, defval=7, group="MACD", inline='1')
slow_length = input(title="Slow Length", type=input.integer, defval=23, group="MACD", inline='1')
signal_length = input(title="Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 10, group="MACD", inline='2')
src = input(title="Source", type=input.source, defval=close, group="MACD", group="MACD", inline='2')
sma_source = input(title="Simple MA(Oscillator)", type=input.bool, defval=false, group="MACD", inline='3')
sma_signal = input(title="Simple MA(Signal Line)", type=input.bool, defval=false, group="MACD", inline='3')
// Plot colors
col_grow_above = #26A69A
col_grow_below = #FFCDD2
col_fall_above = #B2DFDB
col_fall_below = #EF5350
col_macd = #0094ff
col_signal = #ff6a00
srcHTF = security(syminfo.tickerid, res, src[barstate.isrealtime ? 1 : 0])
// Calculating
fast_ma = sma_source ? Sma(srcHTF, fast_length) : Ema(srcHTF, fast_length)
slow_ma = sma_source ? Sma(srcHTF, slow_length) : Ema(srcHTF, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal ? Sma(macd, signal_length) : Ema(macd, signal_length)
hist = macd - signal
//plot(hist, title="Histogram", style=plot.style_columns, color=(hist>=0 ? (hist[1] < hist ? col_grow_above : col_fall_above) : (hist[1] < hist ? col_grow_below : col_fall_below) ), transp=0 )
plot(macd, title="MACD", color=col_macd, transp=0)
plot(signal, title="Signal", color=col_signal, transp=0)
/// MFI
MFIsource = hlc3
MFTsourceHTF = security(syminfo.tickerid, res, MFIsource[barstate.isrealtime ? 1 : 0])
length = input(15, minval=1, group="MFI", inline='1' )
lower = input(12, minval=0, maxval=50, group="MFI", inline='1')
upper = input(80, minval=50, maxval=100, group="MFI", inline='1')
// DrawMFI_f=input(true, title="Draw MFI?", type=bool)
HighlightBreaches=input(true, title="Highlight Oversold/Overbought?")
volumeHTF = security(syminfo.tickerid, res, volume[barstate.isrealtime ? 1 : 0])
// MFI
upper_s = sum(volumeHTF * (change(MFTsourceHTF) <= 0 ? 0 : MFTsourceHTF), length)
lower_s = sum(volumeHTF * (change(MFTsourceHTF) >= 0 ? 0 : MFTsourceHTF), length)
mf = rsi(upper_s, lower_s)
mfp = plot(mf, color=color.new(color.gray,0), linewidth=1)
top = hline(upper, color=color.new(color.gray, 100), linewidth=1, editable=false)
bottom = hline(lower, color=color.new(color.gray,100), linewidth=1, editable=false)
hline(0, color=color.new(color.black,100), editable=false)
hline(100, color=color.new(color.black,100), editable=false)
// Breaches
b_color = (mf > upper) ? color.new(color.red,70) : (mf < lower) ? color.new(color.green,60) : na
bgcolor(HighlightBreaches ? b_color : na)
fill(top, bottom, color=color.gray, transp=75)
//DEPRACATED
// TAKE PROFIT AND STOP LOSS
//useTP1 = input(false, title="Use TPI", group="TP/SL", inline='1', type=input.bool)
//long_tp1_inp = input(1, title='Long TP 1 %', step=0.1, group="TP/SL", inline='1')/100
//long_tp1_qty = input(20, title="Long TP 1 Qty", step=1, group="TP/SL", inline='1')
//traling profit after goal
useTP1 = false //these are defined because of depracation above
long_tp1_inp = 6 //these are defined because of depracation above
long_tp1_qty = 100 //these are defined because of depracation above
enableTrailing = input(defval = true, title = 'Enable Trailing', type=input.bool, tooltip = 'Enable or disable the trailing for take profit.', group = 'Trailing Profit',inline='1')
longTakeProfitPerc = input(title="Long TP (%)", type=input.float, minval=0.0, step=0.1, defval=4, group = 'Trailing Profit', inline='1') * 0.01
trailingTakeProfitDeviationPerc = input(defval = 0.5, title = 'TTP Dev %%', type=input.float, minval = 0.01, maxval = 100, step = 0.1, tooltip = 'The step to follow the price when the take profit limit is reached.', group = 'Trailing Profit', inline='1') / 100
//DEPRACATED
long_trailing =1.3 // input(1.3, title='Trailing Stop', step=0.1, group="TP/SL", inline='1', tooltip="") / 100
long_take_level_1 = strategy.position_avg_price * (1 + long_tp1_inp)
longTPPrice = strategy.position_avg_price * (1 + longTakeProfitPerc)
longLossPerc = input(8, title="Fixed SL (%)", type=input.float, minval=0.0, step=0.1, defval=1, tooltip="Use 100 to turn off - Stop loss % even if ATR did not catch it") * 0.01
longStopPrice = strategy.position_avg_price * (1 - longLossPerc)
//DEPRACATED
// Stop Loss DEPRACATD
multiplier = 2 //input(2, "SL Mult", minval=1, step=0.1, group="TP/SL", inline='2')
ATR_period= 40 //input(40,"ATR Pd", minval=1, step=1, group="TP/SL", inline='2')
//DEPRACATED
//FILTER LOGIC
//Display numbers
showData = input(false, title="Show Data", group="Filters", inline='3', type=input.bool, tooltip="Use this to help see numbers and help set filters")
//Only trade above this MA
aboveTrend = input(false, title="Use Trend", group="Filters", inline='1', type=input.bool)
TrendLength = input(3, minval=1, title="Trend EMA", group="Filters", inline='1', type=input.integer)
aboveTrendFilter = ema(htfClose,TrendLength)
useRSI = input(false, title="Use RSI", group="Filters", inline='2', type=input.bool)
RSILength = input(34, minval=1, title="RSI Length", group="Filters", inline='2') // used to calculate RSI
belowRSIFilter = input(50, minval=1, title="Buy Below RSI Filter", group="Filters", inline='2') // only buy if its below this RSI - doesn't seem to work as expected
rsi = rsi(htfClose,RSILength)
//Filter via min ATR so you can make sure that there is enough volatility to make a profitable trade
minATR = input(0, title="Min ATR", type=input.float, minval=0.0, step=0.001, defval=1, tooltip="Use 0 to turn off - can remove periods of low volatility where less likely profitable")
if not(useRSI)
belowRSIFilter := 100
if not(aboveTrend)
aboveTrendFilter := 0 //should never have 0 moving average so should always be above
atr = Atr(ATR_period,res)
//show actual numbers
if bar_index % 25 == 0 and showData
label.new(bar_index, na, "RSI = " + tostring(rsi, format.mintick) + "\nATR = "+ tostring(atr, format.mintick), yloc = yloc.abovebar, style = label.style_none, textcolor = color.white, size = size.normal)
// Strategy
entry_long=(crossover(macd,signal) or (crossover(mf,lower) and leadLine2 < leadLine1)) and rsi < belowRSIFilter and close > aboveTrendFilter and atr > minATR
entry_price_long=valuewhen(entry_long,high,0)
//SL_floating_long = entry_price_long -( (entry_price_long)*multiplier/100)//*Atr(ATR_period,res)
//SL_floating_long = entry_price_long - multiplier*Atr(ATR_period,res)
SL_floating_long = entry_price_long - multiplier*atr
exit_long= close < SL_floating_long or close < longStopPrice
bool longIsActive = entry_long or strategy.position_size > 0
// LOGIC for Trailing Profit ============================================================================================================
float longTakeProfitPrice = na
longTakeProfitPrice := if longIsActive
if entry_long and not (strategy.position_size > 0)
close * (1 + longTakeProfitPerc)
else
nz(longTakeProfitPrice[1], close * (1 + longTakeProfitPerc))
else
na
longTrailingTakeProfitStepTicks = longTakeProfitPrice * trailingTakeProfitDeviationPerc / syminfo.mintick
var takeProfitColor = color.new(#419388, 0)
plot(series = longTakeProfitPrice, title = 'Long Take Profit', color = takeProfitColor, linewidth = 1, style = plot.style_linebr, offset = 1)
///// BACKTEST PERIOD ///////
testStartYear = input(2018, "Fr Year", group="Backtest", inline="1")
testStartMonth = input(1, "Fr Month", group="Backtest", inline="1")
testStartDay = input(1, "Fr Day", group="Backtest", inline="1")
testPeriodStart = timestamp(testStartYear, testStartMonth, testStartDay, 0, 0)
testStopYear = input(9999, "To Year", group="Backtest", inline="2")
testStopMonth = input(12, "To Month", group="Backtest", inline="2")
testStopDay = input(31, "To Day", group="Backtest", inline="2")
testPeriodStop = timestamp(testStopYear, testStopMonth, testStopDay, 0, 0)
testPeriod() =>
time >= testPeriodStart and time <= testPeriodStop ? true : false
if testPeriod()
if UT
strategy.entry("long", strategy.long, when=entry_long == true, comment=openlongcomment)
if (useTP1)
strategy.exit("TP1","long", qty_percent=long_tp1_qty, limit=long_take_level_1)
//if (strategy.position_size > 0)
if (strategy.position_size > 0) and close > longTPPrice
//strategy.exit(id="long", profit = longTPPrice, comment=closelongcomment)
// submit exit orders for trailing take profit price
strategy.exit(id = 'Long Trailing Profit', from_entry = 'long', comment=closelongcomment, limit = enableTrailing ? na : longTakeProfitPrice, trail_price = enableTrailing ? longTakeProfitPrice : na, trail_offset = enableTrailing ? longTrailingTakeProfitStepTicks : na, when = longIsActive, alert_message = 'Long(' + syminfo.ticker + '): Take Profit activated')
strategy.exit("ATR Trail stop","long", comment=closelongcomment, trail_points=entry_price_long * long_trailing / syminfo.mintick, trail_offset=entry_price_long * long_trailing / syminfo.mintick)
strategy.close("long", exit_long == true, comment=closelongcomment )