오픈 하이스 크로스 오버 거래 전략

저자:차오장, 날짜: 2023-10-18 11:22:57
태그:

img

전반적인 설명

이 전략은 오픈 가격과 높은 가격 사이의 교차를 기반으로 거래 신호를 생성합니다. 오픈 가격이 높은 가격 이상으로 넘어가면 길고 오픈 가격이 높은 가격 이하로 넘어가면 짧습니다. 이동 평균은 가격 데이터를 매끄럽게하고 소란한 거래를 줄이기 위해 사용할 수 있습니다. 이동 평균의 다양한 유형과 매개 변수는 구성 가능합니다. 트레이링 스톱 손실은 또한 이익을 잠금 할 수 있습니다.

전략 논리

  1. 입력 매개 변수 useRes를 기반으로 대체 해상도를 사용할지 여부를 결정합니다. 활성화되면 해상도를 stratRes로 설정합니다.

  2. 입력 매개 변수를 기반으로 이동 평균 (useMA) 을 사용 여부를 결정합니다. 활성화 된 경우 baseType로 MA 유형을 선택하고 basisLen로 기간 길이를 설정합니다.

  3. 오픈 가격 (오픈) 및 폐쇄 가격 (클로즈) 시리즈 데이터를 얻으십시오. useMA가 활성화 된 경우 구성된 매개 변수와 함께 선택된 MA를 적용합니다.

  4. 현재 오픈 가격 x를 오픈 시리즈 openSeries와 비교합니다. x가 openSeries보다 크다면, 트렌드 스테이트를 롱으로 설정하고, 그렇지 않으면 단위로 설정합니다.

  5. 오픈 가격이 오픈 MA 시리즈를 넘을 때 긴 신호 longCond을 생성한다. 오픈 가격이 오픈 MA 시리즈를 넘을 때 짧은 신호 shortCond을 생성한다.

  6. 긴 신호와 짧은 신호에 따라 긴 또는 짧은 포지션을 입력합니다. 트레일링 스톱 손실이 활성화되어있는 경우 중지 손실 지점을 설정하고 오프셋합니다.

장점

  1. 두 가지 다른 가격 시리즈를 사용 합니다. 오픈과 높은 가격, 단일 시리즈의 제한을 피합니다.

  2. MA 기술은 단기적인 소음을 필터링하고 주요 트렌드에 집중합니다.

  3. 최적의 효과를 위해 유연한 MA 유형 및 매개 변수 구성

  4. 선택적인 트레일링 스톱 로스는 위험을 통제하고 수익을 확보합니다.

  5. 다양한 제품과 시장 환경에 대한 매개 변수를 조정하는 높은 최적화 공간.

위험성

  1. 단일 신호 소스는 희귀한 신호로 이어지고 잠재적으로 놓친 거래로 이어집니다.

  2. MA 지연은 단기 기회의 손실을 초래할 수 있습니다.

  3. 부적절한 스톱 손실 구성은 조기 종료 또는 과도한 손실로 이어질 수 있습니다.

  4. 패러미터 조정이 안되면 생방송 공연에 영향을 미치는 과도한 가상의 거래가 발생할 수 있습니다.

  5. 매개 변수 최적화는 다양한 제품과 환경에 도전입니다.

  6. 더 많은 지표 또는 ML 모델을 추가하여 신호 소스를 풍부하게하십시오. MA 유형과 매개 변수를 세밀하게 조정하십시오. 더 많은 이익을 얻기 위해 일부 버퍼로 손해를 조심스럽게 설정하십시오. 매개 변수를 철저히 백테스트하고 최적화하십시오.

최적화 방향

  1. 신호 소스를 확장하기 위해 볼링거 밴드, KD 등과 같은 추가 지표를 포함합니다.

  2. 신호 생성에 기계 학습 모델을 적용합니다.

  3. 가장 좋은 구성을 찾기 위해 MA 매개 변수를 최적화합니다.

  4. 리스크와 이윤 포착 사이의 스톱 로스 레벨을 균형 잡습니다.

  5. 자동으로 최적 설정을 찾기 위해 매개 변수 최적화 방법을 추가합니다.

  6. 다양한 제품에 대한 특화된 매개 변수 템플릿을 개발합니다.

  7. 빠른 전략 반복을 위해 양적 백테스팅 프레임워크를 구축합니다.

요약

이 전략은 오픈 하이 크로스오버를 기반으로 신호를 생성하고 소음을 필터하기 위해 MA를 사용합니다. 구성 가능한 매개 변수를 통해 유연성을 제공합니다. 이 전략은 장점이 있지만 희박한 신호 및 지연과 같은 몇 가지 문제도 있습니다. 더 많은 지표, 기계 학습 모델 등을 통해 추가 개선이 가능합니다. 다양한 제품과 시장 환경에서 최상의 성능을 위해 광범위한 매개 변수 조정 및 최적화가 필요합니다.


/*backtest
start: 2022-10-17 00:00:00
end: 2023-10-17 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=2

//strategy(title = "Open Close Cross Strategy", shorttitle = "OCC Strategy", overlay = true, pyramiding = 0, default_qty_type = strategy.percent_of_equity, default_qty_value = 10)

// Revision:        1
// Author:          @JayRogers
//
// Description:
//  - Strategy based around Open-Close Crossovers.
// Setup:
//  - I have generally found that setting the strategy resolution to 3-4x that of the chart you are viewing
//    tends to yield the best results, regardless of which MA option you may choose (if any)
//  - Don't aim for perfection. Just aim to get a reasonably snug fit with the O-C band, with good runs of
//    green and red.
//  - Option to either use basic open and close series data, or pick your poison with a wide array of MA types.
//  - Optional trailing stop for damage mitigation if desired (can be toggled on/off)
//  - Positions get taken automagically following a crossover - which is why it's better to set the resolution
//    of the script greater than that of your chart, so that the trades get taken sooner rather than later.
//  - If you make use of the trailing stops, be sure to take your time tweaking the values. Cutting it too fine
//    will cost you profits but keep you safer, while letting them loose could lead to more drawdown than you
//    can handle.

// === INPUTS ===
useRes      = input(defval = true, title = "Use Alternate Resolution? ( recommended )")
stratRes    = input(defval = "120", title = "Set Resolution ( should not be lower than chart )")
useMA       = input(defval = true, title = "Use MA? ( otherwise use simple Open/Close data )")
basisType   = input(defval = "DEMA", title = "MA Type: SMA, EMA, DEMA, TEMA, WMA, VWMA, SMMA, HullMA, LSMA, ALMA ( case sensitive )")
basisLen    = input(defval = 14, title = "MA Period", minval = 1)
offsetSigma = input(defval = 6, title = "Offset for LSMA / Sigma for ALMA", minval = 0)
offsetALMA  = input(defval = 0.85, title = "Offset for ALMA", minval = 0, step = 0.01)
useStop     = input(defval = true, title = "Use Trailing Stop?")
slPoints    = input(defval = 200, title = "Stop Loss Trail Points", minval = 1)
slOffset    = input(defval = 400, title = "Stop Loss Trail Offset", minval = 1)
// === /INPUTS ===

// === BASE FUNCTIONS ===
// Returns MA input selection variant, default to SMA if blank or typo.
variant(type, src, len, offSig, offALMA) =>
    v1 = sma(src, len)                                                  // Simple
    v2 = ema(src, len)                                                  // Exponential
    v3 = 2 * v2 - ema(v2, len)                                          // Double Exponential
    v4 = 3 * (v2 - ema(v2, len)) + ema(ema(v2, len), len)               // Triple Exponential
    v5 = wma(src, len)                                                  // Weighted
    v6 = vwma(src, len)                                                 // Volume Weighted
    v7 = na(v5[1]) ? sma(src, len) : (v5[1] * (len - 1) + src) / len    // Smoothed
    v8 = wma(2 * wma(src, len / 2) - wma(src, len), round(sqrt(len)))   // Hull
    v9 = linreg(src, len, offSig)                                       // Least Squares
    v10 = alma(src, len, offALMA, offSig)                               // Arnaud Legoux
    type=="EMA"?v2 : type=="DEMA"?v3 : type=="TEMA"?v4 : type=="WMA"?v5 : type=="VWMA"?v6 : type=="SMMA"?v7 : type=="HullMA"?v8 : type=="LSMA"?v9 : type=="ALMA"?v10 : v1
// security wrapper for repeat calls
reso(exp, use, res) => use ? request.security(syminfo.tickerid, res, exp) : exp
// === /BASE FUNCTIONS ===

// === SERIES SETUP ===
// open/close
//closeSeries = useMA ? reso(variant(basisType, close, basisLen, offsetSigma, offsetALMA), useRes, stratRes) : reso(close, useRes, stratRes)
openSeries  = useMA ? reso(variant(basisType, open, basisLen, offsetSigma, offsetALMA), useRes, stratRes) : reso(open, useRes, stratRes)
x = openSeries[1]
trendState  = x > openSeries ? true : x < openSeries ? false : trendState[1]
// === /SERIES ===

// === PLOTTING ===
barcolor(color = x > openSeries ? #006600 : #990000, title = "Bar Colours")
// channel outline
closePlot   = plot(x, title = "Close Line", color = #009900, linewidth = 2, style = line, transp = 90)
openPlot    = plot(openSeries, title = "Open Line", color = #CC0000, linewidth = 2, style = line, transp = 90)
// channel fill
closePlotU  = plot(trendState ? x : na, transp = 100, editable = false)
openPlotU   = plot(trendState ? openSeries : na, transp = 100, editable = false)
closePlotD  = plot(trendState ? na : x, transp = 100, editable = false)
openPlotD   = plot(trendState ? na : openSeries, transp = 100, editable = false)
fill(openPlotU, closePlotU, title = "Up Trend Fill", color = #009900, transp = 40)
fill(openPlotD, closePlotD, title = "Down Trend Fill", color = #CC0000, transp = 40)
// === /PLOTTING ===

// === STRATEGY ===
// conditions
longCond    = crossover(openSeries, x)
shortCond   = crossunder(openSeries, x)
// entries and base exit
strategy.entry("long", true, when = longCond)
strategy.entry("short", false, when = shortCond)
// if we're using the trailing stop
//if (useStop)
//    strategy.exit("XL", from_entry = "long", trail_points = slPoints, trail_offset = slOffset)
//    strategy.exit("XS", from_entry = "short", trail_points = slPoints, trail_offset = slOffset)
// not sure needed, but just incase..
//strategy.exit("XL", from_entry = "long", when = shortCond)
//strategy.exit("XS", from_entry = "short", when = longCond)
// === /STRATEGY ===

더 많은