Эта стратегия использует обратную торговлю, основанную на бычьих/медвежьих факторах, с заранее установленными уровнями получения прибыли. Ядром факторов является расширенный шаблон
Определение бычьих/медвежьих факторов на основе
Использование моделей свечей для определения классических уровней S/R, фильтрованных по значительному объему
Общие S/R имеют лучший охват, чем классические модели
Разрыв обобщенных сигналов поддержки длинный фактор, разрыв обобщенных сигналов сопротивления короткий фактор
Реверсивная торговля
Возьмите обратное положение, когда фактор сигнал запускается
Если уже на месте, уменьшить или добавить обратное положение
Установление целевых уровней прибыли
Установка стоп-потери на основе ATR
Установите несколько уровней прибыли как 1R, 2R, 3R
Частичное получение прибыли при достижении различных целей
Зафиксировать благоприятные среднесрочные реверсии
Прорывы S/R представляют собой сильные сигналы реверсии с некоторой надежностью, способные улавливать среднесрочные реверсии.
Быстрая прибыль, небольшие вычеты
Установление стоп-лосс и множественные цели прибыли, может достичь быстрых прибылей и ограничить выводы
Подходит для акций с значительным институциональным капиталом и волатильностью
Стратегия опирается на объем, требующий значительного институционального участия; также требует волатильности для получения прибыли
Попасть в ловушку на рынке с ограниченным диапазоном
Частые выходы и повторные выходы в противоположном направлении могут привести к ударам.
Неисправность поддержки/сопротивления
Общие S / R не являются абсолютно надежными, некоторые сбои существуют
Односторонний риск хранения
Чистая логика переворота может упустить большие возможности тренда
Управление рисками:
Условия фактора расслабления, не обратный при каждом прорыве
Добавить другие фильтры, например, расхождение между ценой и объемом
Оптимизировать стратегию стоп-лосса для уменьшения ловушек
Оптимизация параметров S/R
Найти более надежные факторы путем настройки обобщенных настроек S / R
Оптимизировать получение прибыли
Добавьте больше уровней прибыли или используйте нефиксированные цели
Оптимизация стоп-лосса
Регулировать параметры ATR или использовать предотвращение потерь для уменьшения ненужных остановок
Включить тенденцию и другие факторы
Добавьте фильтры трендов, такие как скользящая средняя, чтобы избежать больших конфликтов трендов; также добавьте другие факторы, помогающие
Основой стратегии является захват приличных среднесрочных колебаний с помощью обратной торговли. Логика проста и прямая, и может быть практична с настройкой параметров. Но агрессивный характер обратных операций приводит к некоторому снижению и риску ловушки. Дальнейшие улучшения стоп-лосса, получения прибыли и выравнивания тренда помогут уменьшить ненужные потери.
/*backtest start: 2023-09-29 00:00:00 end: 2023-10-29 00:00:00 period: 1h basePeriod: 15m 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/ // © DojiEmoji //@version=5 strategy("Fractal Strat [KL] ", overlay=true, pyramiding=1, initial_capital=1000000000) var string ENUM_LONG = "Long" var string GROUP_ENTRY = "Entry" var string GROUP_TSL = "Stop loss" var string GROUP_TREND = "Trend prediction" var string GROUP_ORDER = "Order size and Profit taking" // backtest_timeframe_start = input.time(defval=timestamp("01 Apr 2000 13:30 +0000"), title="Backtest Start Time") within_timeframe = true // TSL: calculate the stop loss price. { _multiple = input(2.0, title="ATR Multiplier for trailing stop loss", group=GROUP_TSL) ATR_TSL = ta.atr(input(14, title="Length of ATR for trailing stop loss", group=GROUP_TSL, tooltip="Initial risk amount = atr(this length) x multiplier")) * _multiple TSL_source = low TSL_line_color = color.green TSL_transp = 100 var stop_loss_price = float(0) var float initial_entry_p = float(0) var float risk_amt = float(0) var float initial_order_size = float(0) if strategy.position_size == 0 or not within_timeframe TSL_line_color := color.black stop_loss_price := TSL_source - ATR_TSL else if strategy.position_size > 0 stop_loss_price := math.max(stop_loss_price, TSL_source - ATR_TSL) TSL_transp := 0 plot(stop_loss_price, color=color.new(TSL_line_color, TSL_transp)) // } end of "TSL" block // Order size and profit taking { pcnt_alloc = input.int(5, title="Allocation (%) of portfolio into this security", tooltip="Size of positions is based on this % of undrawn capital. This is fixed throughout the backtest period.", minval=0, maxval=100, group=GROUP_ORDER) / 100 // Taking profits at user defined target levels relative to risked amount (i.e 1R, 2R, 3R) var bool tp_mode = input(true, title="Take profit and different levels", group=GROUP_ORDER) var float FIRST_LVL_PROFIT = input.float(1, title="First level profit", tooltip="Relative to risk. Example: entry at $10 and inital stop loss at $9. Taking first level profit at 1R means taking profits at $11", group=GROUP_ORDER) var float SECOND_LVL_PROFIT = input.float(2, title="Second level profit", tooltip="Relative to risk. Example: entry at $10 and inital stop loss at $9. Taking second level profit at 2R means taking profits at $12", group=GROUP_ORDER) var float THIRD_LVL_PROFIT = input.float(3, title="Third level profit", tooltip="Relative to risk. Example: entry at $10 and inital stop loss at $9. Taking third level profit at 3R means taking profits at $13", group=GROUP_ORDER) // } // Fractals { // Modified from synapticEx's implementation: https://www.tradingview.com/script/cDCNneRP-Fractal-Support-Resistance-Fixed-Volume-2/ rel_vol_len = 6 // Relative volume is used; the middle candle has to have volume above the average (say sma over prior 6 bars) rel_vol = ta.sma(volume, rel_vol_len) _up = high[3]>high[4] and high[4]>high[5] and high[2]<high[3] and high[1]<high[2] and volume[3]>rel_vol[3] _down = low[3]<low[4] and low[4]<low[5] and low[2]>low[3] and low[1]>low[2] and volume[3]>rel_vol[3] fractal_resistance = high[3], fractal_support = low[3] // initialize fractal_resistance := _up ? high[3] : fractal_resistance[1] fractal_support := _down ? low[3] : fractal_support[1] plot(fractal_resistance, "fractal_resistance", color=color.new(color.red,50), linewidth=2, style=plot.style_cross, offset =-3, join=false) plot(fractal_support, "fractal_support", color=color.new(color.lime,50), linewidth=2, style=plot.style_cross, offset=-3, join=false) // } // ATR diversion test { // Hypothesis testing (2-tailed): // // Null hypothesis (H0) and Alternative hypothesis (Ha): // H0 : atr_fast equals atr_slow // Ha : atr_fast not equals to atr_slow; implies atr_fast is either too low or too high len_fast = input(5,title="Length of ATR (fast) for diversion test", group=GROUP_ENTRY) atr_fast = ta.atr(len_fast) atr_slow = ta.atr(input(50,title="Length of ATR (slow) for diversion test", group=GROUP_ENTRY, tooltip="This needs to be larger than Fast")) // Calculate test statistic (test_stat) std_error = ta.stdev(ta.tr, len_fast) / math.pow(len_fast, 0.5) test_stat = (atr_fast - atr_slow) / std_error // Compare test_stat against critical value defined by user in settings //critical_value = input.float(1.645,title="Critical value", tooltip="Strategy uses 2-tailed test to compare atr_fast vs atr_slow. Null hypothesis (H0) is that both should equal. Based on the computed test statistic value, if absolute value of it is +/- this critical value, then H0 will be rejected.", group=GROUP_ENTRY) conf_interval = input.string(title="Confidence Interval", defval="95%", options=["90%","95%","99%"], tooltip="Critical values of 1.645, 1.96, 2.58, for CI=90%/95%/99%, respectively; Under 2-tailed test to compare atr_fast vs atr_slow. Null hypothesis (H0) is that both should equal. Based on the computed test statistic value, if absolute value of it is +/- critical value, then H0 will be rejected.") critical_value = conf_interval == "90%" ? 1.645 : conf_interval == "95%" ? 1.96 : 2.58 reject_H0_lefttail = test_stat < -critical_value reject_H0_righttail = test_stat > critical_value // } end of "ATR diversion test" block // Entry Signals entry_signal_long = close >= fractal_support and reject_H0_lefttail // MAIN { // Update the stop limit if strategy holds a position. if strategy.position_size > 0 strategy.exit(ENUM_LONG, comment="SL", stop=stop_loss_price) // Entry if within_timeframe and entry_signal_long and strategy.position_size == 0 initial_entry_p := close risk_amt := ATR_TSL initial_order_size := math.floor(pcnt_alloc * strategy.equity / close) strategy.entry(ENUM_LONG, strategy.long, qty=initial_order_size) var int TP_taken_count = 0 if tp_mode and close > strategy.position_avg_price if close >= initial_entry_p + THIRD_LVL_PROFIT * risk_amt and TP_taken_count == 2 strategy.close(ENUM_LONG, comment="TP Lvl3", qty=math.floor(initial_order_size / 3)) TP_taken_count := TP_taken_count + 1 else if close >= initial_entry_p + SECOND_LVL_PROFIT * risk_amt and TP_taken_count == 1 strategy.close(ENUM_LONG, comment="TP Lvl2", qty=math.floor(initial_order_size / 3)) TP_taken_count := TP_taken_count + 1 else if close >= initial_entry_p + FIRST_LVL_PROFIT * risk_amt and TP_taken_count == 0 strategy.close(ENUM_LONG, comment="TP Lvl1", qty=math.floor(initial_order_size / 3)) TP_taken_count := TP_taken_count + 1 // Alerts _atr = ta.atr(14) alert_helper(msg) => prefix = "[" + syminfo.root + "] " suffix = "(P=" + str.tostring(close, "#.##") + "; atr=" + str.tostring(_atr, "#.##") + ")" alert(str.tostring(prefix) + str.tostring(msg) + str.tostring(suffix), alert.freq_once_per_bar) if strategy.position_size > 0 and ta.change(strategy.position_size) if strategy.position_size > strategy.position_size[1] alert_helper("BUY") else if strategy.position_size < strategy.position_size[1] alert_helper("SELL") // Clean up - set the variables back to default values once no longer in use if ta.change(strategy.position_size) and strategy.position_size == 0 TP_taken_count := 0 initial_entry_p := float(0) risk_amt := float(0) initial_order_size := float(0) stop_loss_price := float(0) // } end of MAIN block