Прорывная полоса фиксированная стратегия остановки потерь

Автор:Чао Чжан, Дата: 2023-11-03 14:31:21
Тэги:

img

Обзор

Основная идея этой стратегии заключается в использовании диапазона прорыва для определения направления тренда и объединения фиксированного стоп-лосса для управления рисками. Стратегия сначала рассчитывает самые высокие и самые низкие цены за определенный период, чтобы сформировать диапазон прорыва. Когда цена прорывается через диапазон прорыва, генерируется торговый сигнал. Кроме того, стратегия позволяет трейдерам установить фиксированную сумму стоп-лосса. Каждый раз, когда торговля размещается, система будет рассчитывать размер позиции на основе фиксированной суммы стоп-лосса, так что каждый убыток фиксируется.

Принцип стратегии

Стратегия состоит из четырех основных частей: управление позициями, определение диапазона прорыва, установка стоп-лосса и размещение позиций.

Во-первых, стратегия проверяет наличие открытой позиции.

Во-вторых, стратегия рассчитывает самые высокие и самые низкие цены за период, чтобы сформировать полосу прорыва. Когда цена выходит из полосы, генерируется торговый сигнал. В частности, если цена выходит за верхнюю полосу, генерируется длинный сигнал. Если цена выходит за нижнюю полосу, генерируется короткий сигнал.

Кроме того, когда генерируется длинный сигнал, стратегия устанавливает среднюю точку диапазона прорыва как стоп-лосс. То же самое относится и к коротким сигналам. Чтобы отслеживать стоп-лосс, стратегия также регулирует стоп-лосс в режиме реального времени при нахождении на позиции.

Наконец, стратегия позволяет установить фиксированную сумму стоп-лосса. Когда генерируется сигнал, стратегия рассчитывает количество пипсов от стоп-лосса до текущей цены и объединяет такие факторы, как размер тика и обменный курс, чтобы определить изменение цены между стоп-лосом и текущей ценой в денежном выражении.

Выше приведены основные принципы стратегии.Определить направление тренда с помощью диапазонов прорыва и контролировать риск с фиксированным стоп-лосом являются основными концепциями.

Преимущества

Эта стратегия фиксированного стоп-лосса имеет следующие преимущества:

  1. Развитая концепция стоп-лосса. Стратегия использует фиксированную сумму стоп-лосса вместо фиксированного расстояния стоп-лосса. Это позволяет избежать проблемы невозможности фиксировать риск между продуктами с различными значениями тика. С точки зрения управления рисками, фиксированная денежная стоп-лосс более продвинута.

  2. Разумный размер позиции: стратегия может разумно рассчитывать размер позиции на основе фиксированной суммы стоп-лосса, чтобы потеря на одну сделку контролировалась, тем самым разумно управляя риском.

  3. Простая и эффективная идентификация прорыва. Идентификация прорыва с помощью полос проста и прямая, и может эффективно идентифицировать направление тренда. По сравнению с прорывом одного уровня цены эта идентификация прорыва может избежать большего количества ложных сигналов от тренда.

  4. Способность стратегии регулировать стоп-лосс в режиме реального времени для стоп-лосса помогает зафиксировать большую прибыль.

  5. Широкая применимость. Стратегия применима к любым продуктам. Пока параметры установлены правильно, можно достичь контроля риска остановки потери фиксированной суммы, что делает стратегию очень универсальной.

  6. Структура кода ясна и модульная, что позволяет легко понять и оптимизировать.

Риски

Несмотря на преимущества, есть некоторые риски, которые следует отметить для стратегии:

  1. Качество шаблона прорыва не проверено. Стратегия не оценивает качество шаблона прорыва и может генерировать некоторые сигналы низкого качества. Для фильтрации сигналов необходимы другие индикаторы.

  2. Фиксированный стоп-лосс может быть слишком механическим. Рыночные цены часто разрывы. Фиксированный стоп-лосс может слишком полагаться на правила и не имеет гибкости в корректировке.

  3. Нет ограничения на частоту торговли. Стратегия не ограничивает частоту торговли и может торговать слишком часто. Для ограничения частоты необходимы другие правила.

  4. Установление фиксированной суммы стоп-лосса имеет решающее значение для общего контроля риска и должно учитывать размер капитала, желание рисковать и т.д.

  5. Направление прорыва может давать неправильные сигналы. Неправильные сигналы прорыва могут возникать во время колебаний цен или отступлений. Для оптимизации стратегии необходимо больше условий.

  6. Нет механизма получения прибыли. Стратегия в настоящее время не имеет возможности получения прибыли для активного блокирования прибыли. Это может привести к неудовлетворительной прибыли.

Для решения этих рисков некоторые способы оптимизации стратегии включают:

  1. Добавление индикаторов для фильтрации качества сигнала, например, MACD, KD и т.д.

  2. Включение показателей прочности прорыва для оценки качества. Например, оценка прочности на основе изменений объема.

  3. Добавление ограничений частоты открытых сделок, например, одна сделка в день.

  4. Оптимизация логики фиксированного стоп-лосса, например, стоп-лосса, основанного на процентах, выше определенного порога.

  5. Добавление других фильтров, например, волатильность, увеличение стоп-лосса и т.д.

  6. Включение стратегий получения прибыли, например, получение прибыли вблизи сопротивления.

Руководство по оптимизации

На основе анализа стратегия может быть оптимизирована в следующих аспектах:

  1. Добавление фильтров для улучшения качества сигнала с использованием нескольких технических индикаторов и оценки качества тренда.

  2. Оптимизация стоп-лосса для большей гибкости. Может переключаться на стоп-стоп на основе процентов после определенного ретрассемента. Также может оптимизироваться динамически на основе волатильности.

  3. Контроль частоты торговли, чтобы избежать чрезмерной торговли путем добавления фильтров по периодам времени или частоте.

  4. Включение индикаторов тенденции для улучшения сроков, например, ожидание подтверждения тенденции.

  5. Оптимизация стратегий получения прибыли для повышения прибыльности с помощью цели прибыли, остановки прибыли, остановки волатильности и т. Д.

  6. Оптимизация параметров риска на основе обратных тестов, таких как фиксированная сумма остановки, период выхода и т.д.

  7. Рефакторинг кода для лучшей расширяемости путем дальнейшего разъединения сигналов, фильтров, рисков, модулей прибыли.

  8. Тестирование большего количества продуктов для возможностей арбитража. Оценка преимуществ в различных комбинациях продуктов.

С помощью этих параметров оптимизации, стратегия остановки потерь может стать более надежной и прибыльной. Она также закладывает основу для расширения в больше комбинаций стратегий.

Заключение

В целом стратегия разумна в использовании прорывных диапазонов для выявления тенденций и фиксированной суммы остановок для контроля риска. Концепции прогрессивны для управления рисками. Логика размещения позиций также подходит для контроля потери на торговле. Но стратегия может быть улучшена с помощью различных оптимизаций для улучшения качества сигнала, гибкости в остановке потери, рентабельности и т. Д. Благодаря включению фильтров тренда, улучшению получения прибыли и строгому контролю за частотой торговли можно достичь значительного улучшения. В заключение стратегия обеспечивает основу для изучения методов управления рисками и размещения позиций, заложив основу для дальнейших исследований более сложных арбитражных и мультистратегийных систем.


/*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)


Больше