모멘텀 브릭 전략


생성 날짜: 2024-02-19 15:32:17 마지막으로 수정됨: 2024-02-19 15:32:17
복사: 1 클릭수: 577
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

모멘텀 브릭 전략

이 전략은 을 시뮬레이션하여 시장 동력의 변화를 판단하고, 의 방향에 따라 더 많은 공백을 한다.

전략 원칙

이 전략의 핵심 원칙은 ATR과 종결 가격의 관계를 계산하여 벽의 형성을 모방하는 것이다. 구체적으로, 두 개의 변수 Brick1과 Brick2을 정의한다.

Brick1의 계산 방법은: Brick1의 폐가치가 Brick1의 어제값+ATR의 값을 초과하면 Brick1은 Brick1의 어제값+ATR이 된다. 폐가치가 Brick1의 어제값-ATR의 값을 초과하면 Brick1은 Brick1의 어제값-ATR이 된다. 그렇지 않으면 Brick1은 Brick1의 어제값을 계승한다.

Brick2의 계산 방법은: Brick1값과 Brick1 어제값이 같지 않다면, Brick2는 Brick1 어제값이다; 그렇지 않으면 Brick2 어제값을 계승한다.

이렇게 하면 이 형성되는 것을 모방한다. Brick1이 올라갈 때 ATR이 넘으면 위쪽 이 형성되고, Brick1이 내려갈 때 ATR이 넘으면 아래쪽 이 형성된다. Brick2는 의 위치를 기록한다.

Brick1과 Brick2가 상향으로 교차할 때, 이 상향으로 확장되어 다목적으로 판단되는 것을 나타냅니다. Brick1과 Brick2가 하향으로 교차할 때, 이 하향으로 수축되어 공허로 판단되는 것을 나타냅니다.

전략적 이점

  1. ATR을 사용하여 의 형성을 판단하고, 고정된 크기의 을 사용하지 않고, 시장의 변동에 동적으로 적응할 수 있습니다.
  2. 의 교차를 통해 다공방향을 판단하고 동력 변화를 식별한다.
  3. 다른 ATR 주기를 통해 시장 동력에 대한 판단에 대한 민감성을 조정할 수 있습니다.
  4. 시각화 된 형성 및 교차 상황, 직관적으로 시장 움직임을 판단

전략적 위험

  1. ATR 크기의 선택은 전략 수익률에 영향을 미칩니다. ATR 크기가 너무 작다면, 생성되는 이 너무 많아서 더 많은 무효 신호를 생성합니다. ATR 크기가 너무 크다면, 이 너무 적어서 기회를 놓치게됩니다.
  2. 실제 동향은 의 형태를 따르지 않을 수도 있고, 의 교차 신호는 시장의 역전으로 거부될 수도 있다.
  3. 거래비용에 매우 민감해야 합니다. 그렇지 않으면, 자주 거래하는 경우, 순이익이 크게 줄어들 것입니다.

매개 변수를 최적화하여 최적의 ATR 주기를 찾을 수 있습니다. 유효하지 않은 신호에 의한 손실을 줄이기 위해 스톱 스톱 전략을 조정할 수 있습니다. 비용과 수익의 영향을 줄이기 위해 거래 품종을 적절히 확대할 수 있습니다.

전략 최적화

  1. 다른 지표와 결합하여 신호를 필터링 할 수 있습니다. 예를 들어 양 에너지 지표, 진동 지표 등, 무효 신호를 피합니다.
  2. 트렌드 필터를 추가하여 트렌드 방향으로만 신호를 발산하여 역전 손실을 방지합니다.
  3. 테스트 기간 동안 전체 샘플 변수를 최적화하는 방법을 사용하여 자동으로 최적의 변수를 찾습니다.

요약하다

이 전략은 동적 모의 의 교차를 통해 시장의 단기 경향과 동력을 판단하고, 시각화 형태를 직관적으로 보여준다. 전략 최적화 공간은 넓고, 매개 변수 최적화 및 신호 필터링은 안정성을 더욱 높일 수 있다.

전략 소스 코드
/*backtest
start: 2023-02-12 00:00:00
end: 2024-02-18 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4


///Component Code Start
testStartYear = input(2017, "Backtest Start Year")
testStartMonth = input(01, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear, testStartMonth, testStartDay, 0, 0)

testStopYear = input(2025, "Backtest Stop Year")
testStopMonth = input(1, "Backtest Stop Month")
testStopDay = input(1, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear, testStopMonth, testStopDay, 0, 0)



/// A switch to control background coloring of the test period
testPeriodBackground = input(title="Color Background?", type=input.bool, defval=false)
testPeriodBackgroundColor = testPeriodBackground and time >= testPeriodStart and time <= testPeriodStop ? 
   #00FF00 : na
bgcolor(testPeriodBackgroundColor, transp=97)

testPeriod() => true
/// Component Code Stop


//Zack_the_Lego (original AUTHOR) made into strategy by mkonsap
strategy("Flex Renko Emulator", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100)
margin = input(true, title="Margin?")
Margin = margin ? margin : false
res = input(type=input.resolution, defval="D", title="Resolution of ATR")
xATR = atr(14)
//TF = x78tf ? "78" : "39"
BrickSize = security(syminfo.tickerid, res, xATR)

//Brick1 =  close >  nz(Brick1[1]) + BrickSize ? nz(Brick1[1]) + BrickSize : close <
                    //nz(Brick1[1]) - BrickSize ?
                        //nz(Brick1[1]) - BrickSize
                            //: nz(Brick1[1]))


Brick1() =>
    s1 = 0.0
    s1 := close > nz(s1[1]) + BrickSize ? nz(s1[1]) + BrickSize : 
       close < nz(s1[1]) - BrickSize ? nz(s1[1]) - BrickSize : nz(s1[1])
    s1


Brick2() =>
    s2 = 0.0
    Brick1_1 = Brick1()
    s2 := Brick1() != Brick1()[1] ? Brick1_1[1] : nz(s2[1])
    s2

colorer = Brick1() > Brick2() ? color.green : color.red
p1 = plot(Brick1(), color=colorer, linewidth=4, title="Renko")
p2 = plot(Brick2(), color=colorer, linewidth=4, title="Renko")
fill(p1, p2, color=color.purple, transp=50)




mylong = crossover(Brick1(), Brick2())
myshort = crossunder(Brick1(), Brick2())

last_long = float(na)
last_short = float(na)
last_long := mylong ? time : nz(last_long[1])
last_short := myshort ? time : nz(last_short[1])

in_long = last_long > last_short ? 2 : 0
in_short = last_short > last_long ? 2 : 0

mylong2 = crossover(Brick1(), Brick2())
myshort2 = crossunder(Brick1(), Brick2())

last_long2 = float(na)
last_short2 = float(na)
last_long2 := mylong2 ? time : nz(last_long2[1])
last_short2 := myshort2 ? time : nz(last_short2[1])

in_long2 = last_long2 > last_short2 ? 0 : 0
in_short2 = last_short2 > last_long2 ? 0 : 0


condlongx = in_long + in_long2
condlong = crossover(condlongx, 1.9)
condlongclose = crossunder(condlongx, 1.9)

condshortx = in_short + in_short2
condshort = crossover(condshortx, 1.9)
condshortclose = crossunder(condshortx, 1.9)


// === STRATEGY - LONG POSITION EXECUTION WITH CLOSE ORDERS ===
//enterLong() => crossover(condlongx, 1.9) and testPeriod() and strategy.position_size <= 0
//exitLong()  => crossunder(condlongx, 1.9) and testPeriod() and strategy.position_size > 0
//strategy.entry(id = "Long", long = true, when = enterLong())
//strategy.close(id = "Long", when = exitLong())
// === STRATEGY - SHORT POSITION EXECUTION WITH CLOSE ORDER===
//enterShort() => crossover(condshortx, 1.9) and testPeriod() and strategy.position_size >= 0 and Margin
//exitShort() => crossunder(condshortx, 1.9)  and testPeriod() and strategy.position_size < 0
//strategy.entry(id = "Short", long = false, when = enterShort())
//strategy.close(id = "Short", when = exitShort())   
//END


///STRATEGY ONLY LONG AND SHORT/////
if crossover(condlongx, 1.9) and testPeriod() and strategy.position_size <= 0
    strategy.entry("Long", strategy.long, comment="Long")

if crossover(condshortx, 1.9) and testPeriod() and strategy.position_size >= 0
    strategy.close("Long", when=not Margin)

if crossover(condshortx, 1.9) and testPeriod() and strategy.position_size >= 0
    strategy.entry("Short", strategy.short, comment="Short", when=Margin)

/////// END ////