이 전략은 다른 지표의 조합을 통해 가격 움직임의 잠재적 인 낮은 지점을 식별하고 위험을 줄이기 위해 피라미딩을 통해 점진적으로 포지션을 구축합니다. 이 전략은 또한 위험을 효과적으로 제어하기 위해 스톱 로스, 영업 취득 및 트레일 스톱 로스 등의 기능을 통합합니다.
이 전략은 먼저 RSI와 EMA RSI 사이의 차이를 사용하여 잠재적 인 가격 최저치를 식별합니다. 잘못된 신호를 필터링하기 위해 전략은 또한 이동 평균과 멀티 타임프레임 스토카스틱 지표를 결합하여 확인합니다. 낮은 포인트 신호가 확인되면, 긴 포지션은 피라미딩을 통해 그 지점에서 약간 낮은 가격으로 점차적으로 구축됩니다. 전략은 12 개의 추적 오더를 열 수 있으며, 각 오더의 크기가 순차적으로 증가하여 위험을 효과적으로 다양화 할 수 있습니다. 모든 오더는 출출을 위해 전체 스톱 손실을 따르며 각 오더에 대해 별도로 수익을 얻을 수 있습니다. 위험을 더 제어하기 위해 전략은 주식 비율을 기반으로 전체 스톱 손실을 설정합니다.
이 전략은 세 가지 주요 모듈으로 구성됩니다: 낮은 지점 식별, 피라미드 추적 및 위험 관리.
이낮은 지점 식별 모듈RSI와 EMA 사이의 차이를 사용하여 잠재적 인 가격 최저치를 식별합니다. 정확성을 향상시키기 위해 이동 평균 지표와 다중 시간 프레임 스토카스틱 지표가 신호 필터링에 도입됩니다. 가격이 이동 평균 이하이고 스토카스틱 K 라인이 30 이하일 때만 낮은 포인트 신호의 유효성이 확인됩니다.
이피라미드 추적 모듈이 전략의 핵심입니다. 낮은 지점 신호가 확인되면 전략은 그 낮은 지점의 0.1% 아래에서 첫 번째 포지션을 열 것입니다. 그 후, 가격이 계속 하락하고 평균 진입 가격의 특정 비율 이하인 한 더 많은 긴 주문이 추가됩니다. 새로운 주문의 크기는 순차적으로 증가합니다. 예를 들어 세 번째 주문은 첫 번째 주문 크기의 3 배입니다. 이 피라미드 추적 접근법은 위험을 평균화하는 데 도움이됩니다. 전략은 최대 12 개의 추적 명령을 허용합니다.
이위험 관리 모듈세 가지 측면을 포함합니다. 첫째는 최근 기간의 가장 높은 가격에 기반한 전체 스톱 손실입니다. 모든 주문은이 스톱 손실을 따릅니다. 둘째는 각 주문에 대한 독립적 인 수익 설정으로 입시 가격의 특정 비율에 따라 주문을 닫을 수 있습니다. 셋째는 가장 강력한 위험 제어 방법인 계정 자본의 비율에 기반한 전체 스톱 손실입니다.
위의 위험을 줄이기 위해 몇 가지 측면을 최적화 할 수 있습니다.
이 전략의 더 많은 최적화를 위한 여지가 있습니다.
이 전략은 피라미드 추적 접근을 통해 개별 주문의 위험을 효과적으로 줄이고, 전반적인 스톱 로스, 영리, 트레일링 스톱 기능도 리스크 제어의 매우 좋은 역할을 수행합니다. 그러나 여전히 낮은 포인트 식별 및 기타 측면을 개선 할 여지가 있습니다. 더 발전된 기술을 도입하면 매개 변수 동적 조정, 매개 변수 최적화와 결합하여 추가 할 수 있습니다. 이 전략의 위험 보상 비율은 크게 향상 될 수 있습니다.
/*backtest start: 2022-12-15 00:00:00 end: 2023-12-21 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © A3Sh //@version=5 // Strategy that finds potential lows in the price action and spreads the risk by entering multiple positions at these lows. // The low is detected based on the difference between MTF RSI and EMA based RSI, Moving Average and MTF Stochastic indicators. // The size of each next position that is entered is multiplied by the sequential number of the position. // Each separate position can exit when a specified take profit is triggered and re-open when detecting a new potential low. // All positions are closed when the price action crosses over the dynamic blue stop level line. // This strategy combines open-source code developed by fellow Tradingview community members: // The Lowfinder code is developed by RafaelZioni // https://www.tradingview.com/script/GzKq2RVl-Low-finder/ // Both the MTF RSI code and the MTF Stochastic code are adapted from the MTFindicators libary written by Peter_O // https://www.tradingview.com/script/UUVWSpXR-MTFindicators/ // The Stop Level calculation is inspired by the syminfo-mintick tutorial on Kodify.net // https://kodify.net/tradingview/info/syminfo-mintick/ strategy("LowFinder_PyraMider", overlay=true, pyramiding=99, precision=2, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=10, commission_type=strategy.commission.percent, commission_value=0.06, slippage=1 ) // Backtest Window start_time = input(defval=timestamp("01 April 2021 20:00"), group = "Backtest Window", title="Start Time") end_time = input(defval=timestamp("01 Aug 2030 20:00"), group = "Backtest Window", title="End Time") window() => true // Inputs portfolio_size = input.float (100, group = 'Risk - Portfolio', title = 'Portfolio %', step=1.0) / 100 leverage = input.int (1, group = 'Risk - Portfolio', title = 'Leverage', minval = 1) q_mode = input.string ('multiply', group = 'Risk - Order Size', title = 'Order Size Mode', options = ['base', 'multiply'], tooltip = 'Base mode: the base quantiy for each sequential order. Multiply mode: each quantity is multiplied by order number') q_mode_m = input.int (1, group = 'Risk - Order Size', title = 'Order Size Divider (Multiply Mode)', tooltip = 'Divide Multiply by this number to lower the sequential order sizes') fixed_q = input.bool (false, group = 'Risk - Order Size', title = 'Fixed Order Size', inline = '01', tooltip = 'Use with caution! Overrides all Risk calculations') amount_q = input.float (1, group = 'Risk - Order Size', title = '. . Base Currency:', inline = '01') sl_on = input.bool (false, group = 'Risk - Stop Loss', title = 'StopLoss of', inline = '03') stopLoss = input.float (1.5, group = 'Risk - Stop Loss', title = '', step=0.1, inline = '03') / 100 sl_mode = input.string ('equity', group = 'Risk - Stop Loss', title = '% of', options = ['avg_price', 'equity'], inline = '03') stop_len = input.int (100, group = 'Risk - Stop Level', title = 'Stop Level Length', tooltip = 'Lookback most recent highest high') stop_deviation = input.float (0.3, group = 'Risk - Stop Level', title = 'Deviatation % above Stop Level', step=0.1) / 100 cond2_toggle = input.bool (true , group = 'Risk - Take Profit', title = 'Take Profit/Trailing Stop', inline = '04') tp_all = input.float (1.0, group = 'Risk - Take Profit', title = '..........%', step=0.1, inline = '04') / 100 tp_on = input.bool (true, group = 'Risk - Take Profit', title = 'Exit Crossover Take Profit and .....', inline = '02') exit_mode = input.string ('stoplevel', group = 'Risk - Take Profit', title = '', options = ['close', 'stoplevel'], inline = '02') takeProfit = input.float (10.0, group = 'Risk - Take Profit', title = 'Take Profit % per Order', tooltip = 'Each separate order exits when hit', step=0.1) posCount = input.int (12, group = 'Pyramiding Settings', title = 'Max Number of Orders') next_entry = input.float (0.2, group = 'Pyramiding Settings', title = 'Next Order % below Avg. Price', step=0.1) oa_lookback = input.int (0, group = 'Pyramiding Settings', title = 'Next Order after X candles', tooltip = 'Prevents opening too much orders in a Row') len_rsi = input.int (5, group = 'MTF LowFinder Settings', title = 'Lookback of RSI') mtf_rsi = input.int (1, group = 'MTF LowFinder Settings', title = 'Higher TimeFrame Multiplier RSI', tooltip='Multiplies the current timeframe by specified value') ma_length = input.int (26, group = 'MTF LowFinder Settings', title = 'MA Length / Sensitivity') new_entry = input.float (0.1, group = 'MTF LowFinder Settings', title = 'First Order % below Low',step=0.1, tooltip = 'Open % lower then the found low')/100 ma_signal = input.int (100, group = 'Moving Average Filter', title = 'Moving Average Length') periodK = input.int (14, group = 'MTF Stochastic Filter', title = 'K', minval=1) periodD = input.int (3, group = 'MTF Stochastic Filter', title = 'D', minval=1) smoothK = input.int (3, group = 'MTF Stochastic Filter', title = 'Smooth', minval=1) lower = input.int (30, group = 'MTF Stochastic Filter', title = 'MTF Stoch Filter (above gets filtered)') mtf_stoch = input.int (10, group = 'MTF Stochastic Filter', title = 'Higher TimeFrame Multiplier', tooltip='Multiplies the current timeframe by specified value') avg_on = input.bool (true, group = 'Plots', title = 'Plot Average Price') plot_ma = input.bool (false, group = 'Plots', title = 'Plot Moving Average') plot_ts = input.bool (false, group = 'Plots', title = 'Plot Trailing Stop Level') // variables // var entry_price = 0.0 // The entry price of the first entry var previous_entry = 0.0 // Stores the price of the previous entry var iq = 0.0 // Inititial order quantity before risk calculation var nq = 0.0 // Updated new quantity after the loop var oq = 0.0 // Old quantity at the beginning or the loop var q = 0.0 // Final calculated quantity used as base order size var int order_after = 0 // Order size calaculations // // Order size based on max amount of pyramiding orders or fixed by user input /// // Order size calculation based on 'base' mode or ' multiply' mode // if fixed_q q := amount_q else if q_mode == 'multiply' iq := (math.abs(strategy.equity * portfolio_size / posCount) / open) * leverage oq := iq for i = 0 to posCount nq := oq + (iq * ( i/ q_mode_m + 1)) oq := nq q := (iq * posCount / oq) * iq else q := (math.abs(strategy.equity * portfolio_size / posCount) / open) * leverage // Function to calcaulate final order size based on order size modes and round the result with 1 decimal // quantity_mode(index,string q_mode) => q_mode == 'base' ? math.round(q,1) : q_mode == 'multiply' ? math.round(q * (index/q_mode_m + 1),1) : na // LowFinder Calculations // // MTF RSI by Peter_O // rsi_mtf(float source, simple int mtf,simple int len) => change_mtf=source-source[mtf] up_mtf = ta.rma(math.max(change_mtf, 0), len*mtf) down_mtf = ta.rma(-math.min(change_mtf, 0), len*mtf) rsi_mtf = down_mtf == 0 ? 100 : up_mtf == 0 ? 0 : 100 - (100 / (1 + up_mtf / down_mtf)) // Lowfinder by RafaelZioni // vrsi = rsi_mtf(close,mtf_rsi,len_rsi) pp=ta.ema(vrsi,ma_length) dd=(vrsi-pp)*5 cc=(vrsi+dd+pp)/2 lows=ta.crossover(cc,0) // MTF Stoch Calcualation // MTF Stoch adapted from Peter_O // stoch_mtfK(source, mtf, len) => k = ta.sma(ta.stoch(source, high, low, periodK * mtf), smoothK * mtf) stoch_mtfD(source, mtf, len) => k = ta.sma(ta.stoch(source, high, low, periodK * mtf), smoothK * mtf) d = ta.sma(k, periodD * mtf) mtfK = stoch_mtfK(close, mtf_stoch, periodK) mtfD = stoch_mtfD(close, mtf_stoch, periodK) // Open next position % below average position price // below_avg = close < (strategy.position_avg_price * (1 - (next_entry / 100))) // Moving Average Filter // moving_average_signal = ta.sma(close, ma_signal) plot (plot_ma ? moving_average_signal : na, title = 'Moving Average', color = color.rgb(154, 255, 72)) // Buy Signal // buy_signal = lows and close < moving_average_signal and mtfK < lower // First Entry % Below lows // if buy_signal entry_price := close * (1 - new_entry) // Plot Average Price of Position// plot (avg_on ? strategy.position_avg_price : na, title = 'Average Price', style = plot.style_linebr, color = color.new(color.white,0), linewidth = 1) // Take profit per Open Order // take_profit_price = close * takeProfit / 100 / syminfo.mintick // Calculate different Stop Level conditions to exit All // // Stop Level Caculation // stop_long1_level = ta.highest (high, stop_len)[1] * (1 + stop_deviation) stop_long2_level = ta.highest (high, stop_len)[2] * (1 + stop_deviation) stop_long3_level = ta.highest (high, stop_len)[3] * (1 + stop_deviation) stop_long4_level = ta.highest (high, stop_len)[1] * (1 - 0.008) // Stop triggers // stop_long1 = ta.crossover(close,stop_long1_level) stop_long2 = ta.crossover(close,stop_long2_level) stop_long4 = ta.crossunder(close,stop_long4_level) // Exit Conditions, cond 1 only Stop Level, cond2 Trailing Stop option // exit_condition_1 = close < strategy.position_avg_price ? stop_long1 : close > strategy.position_avg_price ? stop_long2 : na exit_condition_2 = close < strategy.position_avg_price * (1 + tp_all) ? stop_long2 : close > strategy.position_avg_price * (1 + tp_all) ? stop_long4 : close < strategy.position_avg_price ? stop_long1 : na // Switch between conditions // exit_conditions = cond2_toggle ? exit_condition_2 : exit_condition_1 // Exit when take profit // ex_m = exit_mode == 'close' ? close : stop_long2_level tp_exit = ta.crossover(ex_m, strategy.position_avg_price * (1 + tp_all)) and close > strategy.position_avg_price * 1.002 // Plot stoplevel, take profit level // plot_stop_level = strategy.position_size > 0 ? stop_long2_level : na plot_trailing_stop = cond2_toggle and plot_ts and strategy.position_size > 0 and close > strategy.position_avg_price * (1 + tp_all) ? stop_long4_level : na plot(plot_stop_level, title = 'Stop Level', style=plot.style_linebr, color = color.new(#41e3ff, 0), linewidth = 1) plot(plot_trailing_stop, title = 'Trailing Stop', style=plot.style_linebr, color = color.new(#4cfca4, 0), linewidth = 1) plot_tp_level = cond2_toggle and strategy.position_size > 0 ? strategy.position_avg_price * (1 + tp_all) : na plot(plot_tp_level, title = 'Take Profit Level', style=plot.style_linebr, color = color.new(#ff41df, 0), linewidth = 1) // Calculate Stop Loss based on equity and average price // loss_equity = ((strategy.position_size * strategy.position_avg_price) - (strategy.equity * stopLoss)) / strategy.position_size loss_avg_price = strategy.position_avg_price * (1 - stopLoss) stop_loss = sl_mode == 'avg_price' ? loss_avg_price : loss_equity plot(strategy.position_size > 0 and sl_on ? stop_loss : na, title = 'Stop Loss', color=color.new(color.red,0),style=plot.style_linebr, linewidth = 1) // Enter first position // if ta.crossunder(close,entry_price) and window() and strategy.position_size == 0 strategy.entry('L_1', strategy.long, qty = math.round(q,1), comment = '+' + str.tostring(math.round(q,1))) previous_entry := close // Enter next pyramiding positions // if buy_signal and window() and strategy.position_size > 0 and below_avg order_after := order_after + 1 for i = 1 to strategy.opentrades entry_comment = '+' + str.tostring((quantity_mode(i,q_mode))) // Comment with variable // if strategy.opentrades == i and i < posCount and order_after > oa_lookback entry_price := close entry_id = 'L_' + str.tostring(i + 1) strategy.entry(id = entry_id, direction=strategy.long, limit=entry_price, qty= quantity_mode(i,q_mode), comment = entry_comment) previous_entry := entry_price order_after := 0 // Exit per Position // if strategy.opentrades > 0 and window() for i = 0 to strategy.opentrades exit_comment = '-' + str.tostring(strategy.opentrades.size(i)) exit_from = 'L_' + str.tostring(i + 1) exit_id = 'Exit_' + str.tostring(i + 1) strategy.exit(id= exit_id, from_entry= exit_from, profit = take_profit_price, comment = exit_comment) // Exit All // if exit_conditions or (tp_exit and tp_on and cond2_toggle) and window() strategy.close_all('Exti All') entry_price := 0 if ta.crossunder(close,stop_loss) and sl_on and window() strategy.close_all('StopLoss') entry_price := 0