
Основная идея этой стратегии заключается в том, чтобы использовать диапазон разрыва для определения направления тренда в сочетании с фиксированными стоп-лоссами для управления риском. Стратегия сначала рассчитывает максимальную цену и минимальную цену в течение определенного периода, образуя диапазон разрыва.
Стратегия состоит из четырех основных частей: управление позициями, выявление прорывных полос, установка стоп-убытков и вычисление количества.
Во-первых, стратегия должна определить, есть ли в настоящее время позиции. Если уже есть позиции, то новый сигнал не создается.
Во-вторых, стратегия рассчитывает максимальные и минимальные цены в течение определенного периода, образуя полосы прорыва. Когда цена прорывается из внутренней полосы прорыва наружу, генерируется торговый сигнал. В частности, если цена прорывает полосу прорыва на траекторию, генерируется многозначный сигнал; если цена прорывает полосу прорыва на траекторию, генерируется пустой сигнал.
Кроме того, при появлении множественного сигнала стратегия устанавливает среднюю точку прорыва в качестве стоп-поста. При появлении сигнала дефолта также устанавливается стоп-пост. Для отслеживания стоп-поста стратегия также регулирует стоп-пост в режиме реального времени во время удержания позиции.
Наконец, стратегия позволяет установить фиксированную сумму стоп-лосса. Когда появляется сигнал, стратегия рассчитывает расстояние от точки стоп-лосса до текущей цены, а затем, в сочетании с другими факторами, такими как котировочная единица, обменный курс, вычисляет сумму, представленную изменениями цены между точками стоп-лосса.
Это основные принципы стратегии. Основная идея стратегии заключается в том, чтобы идентифицировать направление тенденции путем прорыва и контролировать риск с помощью фиксированных стоп-лосс.
Такая стратегия имеет следующие преимущества:
Стоп-стратегия более продвинута. Стратегия использует фиксированную сумму стоп-стратегии, а не фиксированную дистанцию стоп-стратегии. Это позволяет избежать проблемы нефиксированного риска, вызванного различными значениями точек между различными разновидностями.
Количественный расчет обоснован. Стратегия может разумно рассчитывать количество сделок на основе фиксированной суммы стоп-лосса, что позволяет контролировать каждый убыток и, таким образом, разумно контролировать риск.
Идентификация прорыва проста и эффективна. Идентификация прорывных полос проста и проста, и она позволяет эффективно идентифицировать направление тренда. По сравнению с прорывом только в определенном ценовом уровне, такая идентификация прорывных полос позволяет избежать большего количества ложных сигналов, которые отклоняются от направления тренда.
Отслеживание остановок увеличивает прибыль. Стратегия позволяет в режиме реального времени регулировать положение остановок, отслеживать остановки, помогая закрепить больше прибыли.
Широкий спектр применения. Стратегия может применяться для любой разновидности, при условии, что параметры настроены правильно, можно осуществлять риск-контроль с фиксированной суммой стоп-убытков, что позволяет иметь очень широкое применение.
Ясная структура кода. Ясная структура кода стратегии, хорошо разложенные функциональные модули, которые легко понять и последующие оптимизации.
Несмотря на вышеперечисленные преимущества, существуют определенные риски, о которых следует помнить:
Невозможно определить качество формы прорыва. Невозможно определить качество формы прорыва в стратегии, что может привести к появлению некачественных сигналов. Необходимо провести фильтрацию в сочетании с другими показателями.
Фиксированный стоп может быть слишком механическим. Рыночные цены часто характеризуются рыночными тенденциями, фиксированный стоп может быть слишком зависимым от правил и не может быть гибко скорректирован.
Невозможно ограничить частоту сделок. Стратегия не может ограничить частоту сделок, может быть слишком часто выступать. Необходимо ограничить частоту сделок в сочетании с другими правилами.
Фиксированный стоп зависит от параметров. Установка фиксированного стоп-пакета связана с общим контролем опционов, требует разумной настройки в зависимости от размера капитала, предпочтений риска и т. Д.
Прорывный путь может привести к ошибочному сигналу. Когда цена колеблется или отклоняется, может возникнуть ошибочный сигнал прорыва.
Отсутствие сдерживающих механизмов. Стратегия не имеет сдерживающих механизмов и не может активно определять прибыль. Это может привести к нежелательной прибыли.
Мы можем оптимизировать эти риски в следующих направлениях:
Добавление показателей для формографического суждения, фильтрации качества сигнала. Например, 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)