모멘텀 브릭 전략

저자:차오장날짜: 2024-02-19 15:32:17
태그:

img

이 전략은 시뮬레이션 된 벽돌의 형성과 벽돌 방향에 따라 시장 동력의 변화를 판단합니다.

전략 논리

핵심 논리는 ATR 및 폐쇄 가격 관계를 계산하여 벽돌 형성을 시뮬레이션하는 것입니다. 구체적으로 두 변수 Brick1 및 Brick2가 정의됩니다.

Brick1은 다음과 같이 계산됩니다. 만약 종료값이 Brick1의 이전값 + ATR보다 높다면, Brick1 = Brick1의 이전값 + ATR; 만약 종료값이 Brick1의 이전값 - ATR보다 낮다면, Brick1은 Brick1의 이전값 - ATR입니다. 그렇지 않으면, Brick1은 Brick1의 이전값을 계승합니다.

Brick2는: Brick1이 Brick1의 이전 값과 같지 않으면 Brick2 = Brick1의 이전 값; 그렇지 않으면 Brick2의 이전 값을 상속합니다.

이것은 벽돌 형성을 시뮬레이션합니다. 벽돌 1이 ATR보다 더 높아지면 위로 올라가는 벽돌이 형성됩니다. 벽돌 1이 ATR보다 더 떨어지면 아래로 내려가는 벽돌이 형성됩니다. 벽돌 2은 이전 벽돌의 위치를 기록합니다.

벽돌 1과 벽돌 2가 가로로 올라가면 벽돌이 위로 팽창하고 길다고 판단됩니다. 벽돌 1과 벽돌 2가 가로로 내려가면 벽돌이 아래로 줄어들고 짧다고 판단됩니다.

장점

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


더 많은