본문 바로가기
Algorithm Trading/Pine Script v5 기본

Pine Script v5 기본 개념 - 1 (Alerts)

by 컴돈AI 2023. 12. 26.

목차

    Alerts

    Introduction

    • Alerts는 실시간 차트에서 사용하는 알림입니다.
    • 정해놓은 신호가 발생할 경우 alert를 발생하도록 설정할 수 있습니다.

    alert()

    • alert() 형식
      • alert(message, freq)
        • message
          • 알림이 트리거 될 때 전송되는 메시지 텍스트
        • freq
          • 알림의 트리거 빈도를 지정합니다. 
          • 다음 값이 freq로 들어갈 수 있습니다.
            • alert.freq_once_per_bar : 각 실시간 막대당 첫 번째 호출만 알림을 트리거합니다.(기본값)
              • 한 막대에서 5개의 신호가 발생했다면 그 중 첫 번째 신호만 알림이 트리거 됩니다.
            • alert.freq_once_per_bar_close : 실시간 막대가 종료될 때 알림이 트리거 되며, 그 스크립트 반복 동안 alert() 호출이 실행되어야 합니다.
              • 한 막대에서 5개의 신호가 발생했더라도 그 막대가 종료될 때 딱 한 번만 알림이 트리거 됩니다.
            • alert.freq_all : 실시간 막대 동안의 모든 호출이 알림을 트리거합니다.
              • 한 막대에서 5개의 신호가 발생했다면, 그 신호가 발생할 때마다 알림이 트리거 됩니다.
    • alert() 함수는 지표(indicators)와 전략(strategies) 모두에 사용 가능합니다.
      • 기본적으로 전략(strategies)은 바가 닫힐 때 계산됩니다. 따라서 freq가 alert.freq_all이나 alert.freq_once_per_bar이더라도 바가 종료될 때 한 번만 알림이 발생합니다. 
      • 만약 지속적으로 설정해주고 싶다면 strategy 옵션에서 calc_on_every_tick을 true로 설정해주어야 합니다.
    • alert() 예시
      • 예시 1 
        • //@version=5
          indicator("All `alert()` calls")
          r = ta.rsi(close, 20)
          
          // Detect crosses.
          xUp = ta.crossover( r, 50)
          xDn = ta.crossunder(r, 50)
          // Trigger an alert on crosses.
          if xUp
              alert("Go long (RSI is " + str.tostring(r, "#.00)"))
          else if xDn
              alert("Go short (RSI is " + str.tostring(r, "#.00)"))
          
          plotchar(xUp, "Go Long",  "▲", location.bottom, color.lime, size = size.tiny)
          plotchar(xDn, "Go Short", "▼", location.top,    color.red,  size = size.tiny)
          hline(50)
          plot(r)
          • 삼항 연산자를 사용해서 다음과 같이 표현할 수 있습니다.
            • // Trigger an alert on crosses.
              if xUp or xDn
                  firstPart = (xUp ? "Go long" : "Go short") + " (RSI is "
                  alert(firstPart + str.tostring(r, "#.00)"))
      • 예시 2
        • 여러 조건을 묶어서 alert 시켜줄 수 있습니다. 
        • //@version=5
          indicator("Selective `alert()` calls")
          detectLongsInput  = input.bool(true,  "Detect Longs")
          detectShortsInput = input.bool(true,  "Detect Shorts")
          repaintInput      = input.bool(false, "Allow Repainting")
          
          r = ta.rsi(close, 20)
          // Detect crosses.
          xUp = ta.crossover( r, 50)
          xDn = ta.crossunder(r, 50)
          // Only generate entries when the trade's direction is allowed in inputs.
          enterLong  = detectLongsInput  and xUp and (repaintInput or barstate.isconfirmed)
          enterShort = detectShortsInput and xDn and (repaintInput or barstate.isconfirmed)
          // Trigger the alerts only when the compound condition is met.
          if enterLong
              alert("Go long (RSI is " + str.tostring(r, "#.00)"))
          else if enterShort
              alert("Go short (RSI is " + str.tostring(r, "#.00)"))
          
          plotchar(enterLong,  "Go Long",  "▲", location.bottom, color.lime, size = size.tiny)
          plotchar(enterShort, "Go Short", "▼", location.top,    color.red,  size = size.tiny)
          hline(50)
          plot(r)
      • 예시 3
        • //@version=5
          strategy("Strategy with selective `alert()` calls")
          r = ta.rsi(close, 20)
          
          // Detect crosses.
          xUp = ta.crossover( r, 50)
          xDn = ta.crossunder(r, 50)
          // Place orders on crosses.
          if xUp
              strategy.entry("Long", strategy.long)
          else if xDn
              strategy.entry("Short", strategy.short)
          
          // Trigger an alert when RSI diverges from our trade's direction.
          divInLongTrade  = strategy.position_size > 0 and ta.falling(r, 3)
          divInShortTrade = strategy.position_size < 0 and ta.rising( r, 3)
          if divInLongTrade
              alert("WARNING: Falling RSI", alert.freq_once_per_bar_close)
          if divInShortTrade
              alert("WARNING: Rising RSI", alert.freq_once_per_bar_close)
          
          plotchar(xUp, "Go Long",  "▲", location.bottom, color.lime, size = size.tiny)
          plotchar(xDn, "Go Short", "▼", location.top,    color.red,  size = size.tiny)
          plotchar(divInLongTrade,  "WARNING: Falling RSI", "•", location.top,    color.red,  size = size.tiny)
          plotchar(divInShortTrade, "WARNING: Rising RSI",  "•", location.bottom, color.lime, size = size.tiny)
          hline(50)
          plot(r)

    alert_message 이용

    • strategy 에는 주문을 생성할 수 있는 함수 strategy.close(), strategy.entry(), strategy.exit(), strategy.order()가 있습니다. 이 함수에는 alert_message라는 매개변수가 존재하는데 여기에 메시지를 적어서 알림 메시지를 생성하도록 만들 수 있습니다.
    • 예시
      • //@version=5
        strategy("Strategy using `alert_message`")
        r = ta.rsi(close, 20)
        
        // Detect crosses.
        xUp = ta.crossover( r, 50)
        xDn = ta.crossunder(r, 50)
        // Place order on crosses using a custom alert message for each.
        if xUp
            strategy.entry("Long", strategy.long, stop = high, alert_message = "Stop-buy executed (stop was " + str.tostring(high) + ")")
        else if xDn
            strategy.entry("Short", strategy.short, stop = low, alert_message = "Stop-sell executed (stop was " + str.tostring(low) + ")")
        
        plotchar(xUp, "Go Long",  "▲", location.bottom, color.lime, size = size.tiny)
        plotchar(xDn, "Go Short", "▼", location.top,    color.red,  size = size.tiny)
        hline(50)
        plot(r)

         

        상단 주석에//@strategy_alert_message {{strategy.order.alert_message}} 를 적어준다면 alert_message만 편하게 보낼 수 있습니다.
      • //@version=5
        //@strategy_alert_message {{strategy.order.alert_message}}
        
        strategy("Strategy using `alert_message`")
        r = ta.rsi(close, 20)
        
        // Detect crosses.
        xUp = ta.crossover( r, 50)
        xDn = ta.crossunder(r, 50)
        // Place order on crosses using a custom alert message for each.
        if xUp
            strategy.entry("Long", strategy.long, stop = high, alert_message = "Stop-buy executed (stop was " + str.tostring(high) + ")")
        else if xDn
            strategy.entry("Short", strategy.short, stop = low, alert_message = "Stop-sell executed (stop was " + str.tostring(low) + ")")
        
        plotchar(xUp, "Go Long",  "▲", location.bottom, color.lime, size = size.tiny)
        plotchar(xDn, "Go Short", "▼", location.top,    color.red,  size = size.tiny)
        hline(50)
        plot(r)
        • {{strategy.order.alert_message}}를 입력해서 넣어줘야지만 strategy에 작성한 alert_message 메시지가 발생됩니다.
        • //@strategy_alert_message {{strategy.order.alert_message}} 를 작성해 놓으면 메시지에 자동으로 {{strategy.order.alert_message}}가 채워져 있습니다.

    alert() vs strategy alert_message

    • alert()는 alert를 등록하면 alert 메시지와 상관없이 alert() 함수 안에 작성한 message가 발생하게 됩니다. 하지만 strategy의 alert_message를 이용하면 alert 등록을 할 때 위에서 말했듯이 {{strategy.order.alert_message}}를 입력해 주어야지 alert_message에 등록한 메시지가 alert를 통해 발생하게 됩니다.
    • alert()가 유용한 경우
      • 단순하게 신호에 따라 메시지만 발생시키고 싶다면 alert() 사용하면 됩니다.
      • ex) 전고점 돌파시 알림 메시지 발생
    • strategy의 alert_message가 유용한 경우
      • strategy의 alert_message를 이용하면 백테스팅과 동시에 실시간 매매에서도 그대로 그 코드를 사용할 수 있습니다.
      • strategy에서 진입과 탈출이 명확히 표시가 되어 있기 때문에 조금 더 가독성이 좋아집니다.
      • alert_message에 메시지만 넣어주고 그 메시지를 처리하는 프로그램만 만들어놓는다면 손쉽게 자동매매를 만들 수 있습니다. 

    Placeholders

    • Placeholders는 message와 함께 사용할 수 있는 변수입니다. message에 {{ }} 와 함께 작성하면 해당하는 값이 같이 메시지로 전송되게 됩니다.
    • 종류
      • {{ticker}}: 현재 차트의 티커 심볼을 나타냅니다.
        • ex. BTCUSDT.P , AAPL, BTCUSD, 005930
      • {{exchange}}: 현재 차트의 거래소 이름을 나타냅니다.
        • ex. BINANCE, KRX, NASDAQ
      • {{interval}}: 현재 차트의 시간 간격을 나타냅니다.
        • ex. S, 1D, 60(1시간)
      • {{open}}: 현재 막대의 시가를 나타냅니다.
      • {{high}}: 현재 막대의 고가를 나타냅니다.
      • {{low}}: 현재 막대의 저가를 나타냅니다.
      • {{close}}: 현재 막대의 종가를 나타냅니다.
      • {{volume}}: 현재 막대의 거래량을 나타냅니다.