Основная идея этой стратегии заключается в использовании диапазона прорыва для определения направления тренда и объединения фиксированного стоп-лосса для управления рисками. Стратегия сначала рассчитывает самые высокие и самые низкие цены за определенный период, чтобы сформировать диапазон прорыва. Когда цена прорывается через диапазон прорыва, генерируется торговый сигнал. Кроме того, стратегия позволяет трейдерам установить фиксированную сумму стоп-лосса. Каждый раз, когда торговля размещается, система будет рассчитывать размер позиции на основе фиксированной суммы стоп-лосса, так что каждый убыток фиксируется.
Стратегия состоит из четырех основных частей: управление позициями, определение диапазона прорыва, установка стоп-лосса и размещение позиций.
Во-первых, стратегия проверяет наличие открытой позиции.
Во-вторых, стратегия рассчитывает самые высокие и самые низкие цены за период, чтобы сформировать полосу прорыва. Когда цена выходит из полосы, генерируется торговый сигнал. В частности, если цена выходит за верхнюю полосу, генерируется длинный сигнал. Если цена выходит за нижнюю полосу, генерируется короткий сигнал.
Кроме того, когда генерируется длинный сигнал, стратегия устанавливает среднюю точку диапазона прорыва как стоп-лосс. То же самое относится и к коротким сигналам. Чтобы отслеживать стоп-лосс, стратегия также регулирует стоп-лосс в режиме реального времени при нахождении на позиции.
Наконец, стратегия позволяет установить фиксированную сумму стоп-лосса. Когда генерируется сигнал, стратегия рассчитывает количество пипсов от стоп-лосса до текущей цены и объединяет такие факторы, как размер тика и обменный курс, чтобы определить изменение цены между стоп-лосом и текущей ценой в денежном выражении.
Выше приведены основные принципы стратегии.Определить направление тренда с помощью диапазонов прорыва и контролировать риск с фиксированным стоп-лосом являются основными концепциями.
Эта стратегия фиксированного стоп-лосса имеет следующие преимущества:
Развитая концепция стоп-лосса. Стратегия использует фиксированную сумму стоп-лосса вместо фиксированного расстояния стоп-лосса. Это позволяет избежать проблемы невозможности фиксировать риск между продуктами с различными значениями тика. С точки зрения управления рисками, фиксированная денежная стоп-лосс более продвинута.
Разумный размер позиции: стратегия может разумно рассчитывать размер позиции на основе фиксированной суммы стоп-лосса, чтобы потеря на одну сделку контролировалась, тем самым разумно управляя риском.
Простая и эффективная идентификация прорыва. Идентификация прорыва с помощью полос проста и прямая, и может эффективно идентифицировать направление тренда. По сравнению с прорывом одного уровня цены эта идентификация прорыва может избежать большего количества ложных сигналов от тренда.
Способность стратегии регулировать стоп-лосс в режиме реального времени для стоп-лосса помогает зафиксировать большую прибыль.
Широкая применимость. Стратегия применима к любым продуктам. Пока параметры установлены правильно, можно достичь контроля риска остановки потери фиксированной суммы, что делает стратегию очень универсальной.
Структура кода ясна и модульная, что позволяет легко понять и оптимизировать.
Несмотря на преимущества, есть некоторые риски, которые следует отметить для стратегии:
Качество шаблона прорыва не проверено. Стратегия не оценивает качество шаблона прорыва и может генерировать некоторые сигналы низкого качества. Для фильтрации сигналов необходимы другие индикаторы.
Фиксированный стоп-лосс может быть слишком механическим. Рыночные цены часто разрывы. Фиксированный стоп-лосс может слишком полагаться на правила и не имеет гибкости в корректировке.
Нет ограничения на частоту торговли. Стратегия не ограничивает частоту торговли и может торговать слишком часто. Для ограничения частоты необходимы другие правила.
Установление фиксированной суммы стоп-лосса имеет решающее значение для общего контроля риска и должно учитывать размер капитала, желание рисковать и т.д.
Направление прорыва может давать неправильные сигналы. Неправильные сигналы прорыва могут возникать во время колебаний цен или отступлений. Для оптимизации стратегии необходимо больше условий.
Нет механизма получения прибыли. Стратегия в настоящее время не имеет возможности получения прибыли для активного блокирования прибыли. Это может привести к неудовлетворительной прибыли.
Для решения этих рисков некоторые способы оптимизации стратегии включают:
Добавление индикаторов для фильтрации качества сигнала, например, MACD, KD и т.д.
Включение показателей прочности прорыва для оценки качества. Например, оценка прочности на основе изменений объема.
Добавление ограничений частоты открытых сделок, например, одна сделка в день.
Оптимизация логики фиксированного стоп-лосса, например, стоп-лосса, основанного на процентах, выше определенного порога.
Добавление других фильтров, например, волатильность, увеличение стоп-лосса и т.д.
Включение стратегий получения прибыли, например, получение прибыли вблизи сопротивления.
На основе анализа стратегия может быть оптимизирована в следующих аспектах:
Добавление фильтров для улучшения качества сигнала с использованием нескольких технических индикаторов и оценки качества тренда.
Оптимизация стоп-лосса для большей гибкости. Может переключаться на стоп-стоп на основе процентов после определенного ретрассемента. Также может оптимизироваться динамически на основе волатильности.
Контроль частоты торговли, чтобы избежать чрезмерной торговли путем добавления фильтров по периодам времени или частоте.
Включение индикаторов тенденции для улучшения сроков, например, ожидание подтверждения тенденции.
Оптимизация стратегий получения прибыли для повышения прибыльности с помощью цели прибыли, остановки прибыли, остановки волатильности и т. Д.
Оптимизация параметров риска на основе обратных тестов, таких как фиксированная сумма остановки, период выхода и т.д.
Рефакторинг кода для лучшей расширяемости путем дальнейшего разъединения сигналов, фильтров, рисков, модулей прибыли.
Тестирование большего количества продуктов для возможностей арбитража. Оценка преимуществ в различных комбинациях продуктов.
С помощью этих параметров оптимизации, стратегия остановки потерь может стать более надежной и прибыльной. Она также закладывает основу для расширения в больше комбинаций стратегий.
В целом стратегия разумна в использовании прорывных диапазонов для выявления тенденций и фиксированной суммы остановок для контроля риска. Концепции прогрессивны для управления рисками. Логика размещения позиций также подходит для контроля потери на торговле. Но стратегия может быть улучшена с помощью различных оптимизаций для улучшения качества сигнала, гибкости в остановке потери, рентабельности и т. Д. Благодаря включению фильтров тренда, улучшению получения прибыли и строгому контролю за частотой торговли можно достичь значительного улучшения. В заключение стратегия обеспечивает основу для изучения методов управления рисками и размещения позиций, заложив основу для дальнейших исследований более сложных арбитражных и мультистратегийных систем.
/*backtest start: 2023-10-26 00:00:00 end: 2023-10-28 03:00:00 period: 10m basePeriod: 1m 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/ //@version=4 //@author=Takazudo strategy("Fixed price SL", overlay=true, default_qty_type=strategy.fixed, initial_capital=0, currency=currency.USD) var COLOR_TRANSPARENT = color.new(#000000, 100) var COLOR_ENTRY_BAND = color.new(#43A6F5, 30) //============================================================================ // config //============================================================================ // Money management _g1 = 'Money management' var config_riskPrice = input(100, minval=1, title="Risk price for each entry", group=_g1) var config_depositCurrency = input(title="Deposit currency", type=input.string, defval="USD", options=["USD"], group=_g1) // Entry strategy _g2 = 'Entry strategy' var config_entryBandBars = input(defval = 100, title = "Entry band bar count", minval=1, group=_g2) // Backtesting range _g3 = 'Backtesting range' fromYear = input(defval = 2018, title = "From Year", minval = 1970, group=_g3) fromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12, group=_g3) fromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31, group=_g3) toYear = input(defval = 2020, title = "To Year", minval = 1970, group=_g3) toMonth = input(defval = 12, title = "To Month", minval = 1, maxval = 12, group=_g3) toDay = input(defval = 31, title = "To Day", minval = 1, maxval = 31, group=_g3) //============================================================================ // exchange caliculations //============================================================================ // mico pip size caliculation // ex1: AUDCAD -> 0.0001 // ex2: USDJPY -> 0.01 f_calcMicroPipSize() => _base = syminfo.basecurrency _quote = syminfo.currency _result = 0.0001 if _quote == 'JPY' _result := _result * 100 if _base == 'BTC' _result := _result * 100 _result // convert price to pips f_convertPriceToPips(_price) => _microPipSize = f_calcMicroPipSize() _price / _microPipSize // caliculate exchange rate between deposit and quote currency f_calcDepositExchangeSymbolId() => _result = '' _deposit = config_depositCurrency _quote = syminfo.currency if (_deposit == 'USD') and (_quote == 'USD') _result := na if (_deposit == 'USD') and (_quote == 'AUD') _result := 'OANDA:AUDUSD' if (_deposit == 'EUR') and (_quote == 'USD') _result := 'OANDA:EURUSD' if (_deposit == 'USD') and (_quote == 'GBP') _result := 'OANDA:GBPUSD' if (_deposit == 'USD') and (_quote == 'NZD') _result := 'OANDA:NZDUSD' if (_deposit == 'USD') and (_quote == 'CAD') _result := 'OANDA:USDCAD' if (_deposit == 'USD') and (_quote == 'CHF') _result := 'OANDA:USDCHF' if (_deposit == 'USD') and (_quote == 'JPY') _result := 'OANDA:USDJPY' _result // Let's say we need CAD to USD exchange // However there's only "OANDA:USDCAD" symbol. // Then we need to invert the exhchange rate. // this function tells us whether we should invert the rate or not f_calcShouldInvert() => _result = false _deposit = config_depositCurrency _quote = syminfo.currency if (_deposit == 'USD') and (_quote == 'CAD') _result := true if (_deposit == 'USD') and (_quote == 'CHF') _result := true if (_deposit == 'USD') and (_quote == 'JPY') _result := true _result // caliculate how much quantity should I buy or sell f_calcQuantitiesForEntry(_depositExchangeRate, _slPips) => _microPipSize = f_calcMicroPipSize() _priceForEachPipAsDeposit = _microPipSize * _depositExchangeRate _losePriceOnSl = _priceForEachPipAsDeposit * _slPips floor(config_riskPrice / _losePriceOnSl) //============================================================================ // Quantity caliculation //============================================================================ depositExchangeSymbolId = f_calcDepositExchangeSymbolId() // caliculate deposit exchange rate rate = security(depositExchangeSymbolId, timeframe.period, hl2) shouldInvert = f_calcShouldInvert() depositExchangeRate = if config_depositCurrency == syminfo.currency // if USDUSD, no exchange of course 1 else // else, USDCAD to CADUSD invert if we need shouldInvert ? (1 / rate) : rate //============================================================================ // Range Edge caliculation //============================================================================ f_calcEntryBand_high() => _highest = max(open[3], close[3]) for i = 4 to (config_entryBandBars - 1) _highest := max(_highest, open[i], close[i]) _highest f_calcEntryBand_low() => _lowest = min(open[3], close[3]) for i = 4 to (config_entryBandBars - 1) _lowest := min(_lowest, open[i], close[i]) _lowest entryBand_high = f_calcEntryBand_high() entryBand_low = f_calcEntryBand_low() entryBand_height = entryBand_high - entryBand_low plot(entryBand_high, color=COLOR_ENTRY_BAND, linewidth=1) plot(entryBand_low, color=COLOR_ENTRY_BAND, linewidth=1) rangeBreakDetected_long = entryBand_high < close rangeBreakDetected_short = entryBand_low > close shouldMakeEntryLong = (strategy.position_size == 0) and rangeBreakDetected_long shouldMakeEntryShort = (strategy.position_size == 0) and rangeBreakDetected_short //============================================================================ // SL & Quantity //============================================================================ var sl_long = hl2 var sl_short = hl2 entryQty = 0 slPips = 0.0 // just show info bubble f_showEntryInfo(_isLong) => _str = 'SL pips: ' + tostring(slPips) + '\n' + 'Qty: ' + tostring(entryQty) _bandHeight = entryBand_high - entryBand_low _y = _isLong ? (entryBand_low + _bandHeight * 1/4) : (entryBand_high - _bandHeight * 1/4) _style = _isLong ? label.style_label_up : label.style_label_down label.new(bar_index, _y, _str, size=size.large, style=_style) if shouldMakeEntryLong sl_long := (entryBand_high + entryBand_low) / 2 slPips := f_convertPriceToPips(close - sl_long) entryQty := f_calcQuantitiesForEntry(depositExchangeRate, slPips) if shouldMakeEntryShort sl_short := (entryBand_high + entryBand_low) / 2 slPips := f_convertPriceToPips(sl_short - close) entryQty := f_calcQuantitiesForEntry(depositExchangeRate, slPips) // trailing SL if strategy.position_size > 0 sl_long := max(sl_long, entryBand_low) if strategy.position_size < 0 sl_short := min(sl_short, entryBand_high) //============================================================================ // backtest duration //============================================================================ // Calculate start/end date and time condition startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00) finishDate = timestamp(toYear, toMonth, toDay, 00, 00) //============================================================================ // make entries //============================================================================ if (true) if shouldMakeEntryLong strategy.entry(id="Long", long=true, stop=close, qty=entryQty) f_showEntryInfo(true) if shouldMakeEntryShort strategy.entry(id="Short", long=false, stop=close, qty=entryQty) f_showEntryInfo(false) strategy.exit('Long-SL/TP', 'Long', stop=sl_long) strategy.exit('Short-SL/TP', 'Short', stop=sl_short) //============================================================================ // plot misc //============================================================================ sl = strategy.position_size > 0 ? sl_long : strategy.position_size < 0 ? sl_short : na plot(sl, color=color.red, style=plot.style_cross, linewidth=2, title="SL") value_bgcolor = rangeBreakDetected_long ? color.green : rangeBreakDetected_short ? color.red : COLOR_TRANSPARENT bgcolor(value_bgcolor, transp=95)