Python으로 Chandelier Exit 지표 구현

Chandelier Exit는 트레이딩뷰 오픈 소스로 ‘everget‘라는 유저가 공개하였습니다.

💡 유저 설명 번역
이 버전의 Chandelier Exit 지표는 기존 지표의 불필요한 상태 전환을 제거하고, 두 개의 라인이 시작되는 지점을 강조하도록 개선되었습니다. Chandelier Exit은 Charles Le Beau가 개발했으며, Dr. Alexander Elder가 그의 저서 “Come Into My Trading Room: A Complete Guide to Trading” (2002) 에서 널리 알린 지표입니다. 간단히 말해, 이 지표는 평균 진폭 범위(ATR, Average True Range) 를 기반으로 한 트레일링 스탑(추적 손절매) 시스템입니다.

트레이딩뷰: https://kr.tradingview.com/script/AqXxNS7j-Chandelier-Exit/

지표의 Buy, Sell 시그널을 체크하겠습니다.

import pandas as pd
import ccxt
import pinetopy as pp
import numpy as np

# Binance Futures, BTCUSDT, 1h
bnb = ccxt.binance({'options': { 'defaultType': 'future' }}) 
ohlcv = bnb.fetch_ohlcv(symbol="BTC/USDT", timeframe="1h", limit=500)
df = pd.DataFrame(ohlcv, columns=['time', 'open', 'high', 'low', 'close', 'volume'])
df['time'] = pp.kst(df['time'])

# TradingView Default Settings
def main(df, length=22, mult=3.0):
    atr = mult * pp.atr(df, length)
    highest_close, lowest_close = df['close'].rolling(length).max(), df['close'].rolling(length).min()
    long_stop, short_stop = highest_close - atr, lowest_close + atr
    
    long_stop_prev, short_stop_prev = long_stop.copy(), short_stop.copy()
    dir_indicator = np.ones(len(df))
    dir_indicator[0] = 1
    
    for i in range(1, len(df)):
        long_stop_prev.iloc[i] = max(long_stop.iloc[i], long_stop_prev.iloc[i-1]) if df['close'].iloc[i-1] > long_stop_prev.iloc[i-1] else long_stop.iloc[i]
        short_stop_prev.iloc[i] = min(short_stop.iloc[i], short_stop_prev.iloc[i-1]) if df['close'].iloc[i-1] < short_stop_prev.iloc[i-1] else short_stop.iloc[i]
        dir_indicator[i] = np.where(df['close'].iloc[i] > short_stop_prev.iloc[i], 1,
                                    np.where(df['close'].iloc[i] < long_stop_prev.iloc[i], -1, dir_indicator[i-1]))
        
    df['ce_signal'] = np.where((dir_indicator == 1) & (np.roll(dir_indicator, 1) == -1), 'Buy',
            np.where((dir_indicator == -1) & (np.roll(dir_indicator, 1) == 1), 'Sell', ''))
    
    signal = df[df['ce_signal'] != '']
    return signal[['time', 'close', 'ce_signal']]

print(main(df))

트레이딩뷰 차트와 비교