파이썬/바이낸스 선물 API+WS

[선물 API+WS] 데이터 프레임에 보조지표 추가하기

Eluv 2024. 11. 23. 09:58

[선물 API+WS] 차트 실시간 갱신하기

해당 글에서 연장되는 내용입니다.

 

이전 글에 올린 코드에서 update_chart 함수입니다.

# 차트를 업데이트 하는 함수
def update_chart(df, data):
    last_time = df.index[-1]
    new_time = pd.to_datetime(data['k']['t'], unit='ms') + timedelta(hours=9)
    new_candle = {}
    for x in data['k']:
        if x in df.columns:
            if x in ['q', 'Q']:
                new_candle[x] = round(float(data['k'][x]))
            elif x in ['t', 'n']:
                new_candle[x] = int(data['k'][x])
            elif x in 'T':
                pass
            else:
                new_candle[x] = float(data['k'][x])
    new_candle['t'] = new_time

    # 새로운 행 추가 및 오래된 행 제거
    if new_time != last_time:
        new_row = pd.DataFrame([new_candle]).set_index('t')
        df = pd.concat([df, new_row])
        df = df.iloc[1:]
    else:  # 현재 캔들 업데이트
        df.iloc[-1] = pd.Series(new_candle).reindex(df.columns)

    df['MA20'] = df['c'].rolling(window=20).mean()

    print(df.tail())
    return df

코드 내에서 아래의 코드로 20분 이동평균을 구현합니다.

df['MA20'] = df['c'].rolling(window=20).mean()

여기에서 window = 20 이 캔들의 길이입니다.

 

7분, 100분 등의 이동평균을 구하고 싶다면

아래와 같이 만드시면 됩니다.

df['MA7'] = df['c'].rolling(window=7).mean()
df['MA100'] = df['c'].rolling(window=100).mean()

 

간단한 보조지표는 위의 문법과 비슷하게 작성할 수 있습니다.

 

 

다음은 20분 평균 거래량입니다.

# 20분 평균 거래량
df['VOL20'] = round(df['v'].rolling(window=20).mean())

 

 

다음은 볼린저 밴드입니다.

# 볼린저 밴드
df['STD20'] = df['c'].rolling(window=20).std(ddof=0)
df['bb_Upper'] = df['MA20'] + df['STD20'] * 2
df['bb_Lower'] = df['MA20'] - df['STD20'] * 2

df [ 'MA20' ] 아래에 복붙해서 넣으시면 됩니다.

 

 

다음은 MACD 입니다.

# MACD
df['EMA12'] = df['c'].ewm(span=12, adjust=False).mean()
df['EMA26'] = df['c'].ewm(span=26, adjust=False).mean()
df['MACD'] = df['EMA12'] - df['EMA26']
df['Signal'] = df['MACD'].ewm(span=9, adjust=False).mean()

 

 

다음은 RSI 입니다.

# RSI
delta = df['c'].diff()
gain = delta.where(delta > 0, 0)
loss = -delta.where(delta < 0, 0)
avg_gain = gain.ewm(alpha=1/14, min_periods=14, adjust=False).mean()
avg_loss = loss.ewm(alpha=1/14, min_periods=14, adjust=False).mean()
rs = avg_gain / avg_loss
df['RSI'] = 100 - (100 / (1 + rs))

 

다음은 CCI 입니다.

df['TP'] = (df['h'] + df['l'] + df['c']) / 3
df['TP_MA'] = df['TP'].rolling(window=20, min_periods=20).mean()
df['MAD'] = df['TP'].rolling(window=20, min_periods=20).apply(lambda x: abs(x - x.mean()).mean(), raw=True)
df['CCI'] = (df['TP'] - df['TP_MA']) / (0.015 * df['MAD'])

 

 

 

전부 복붙해서 넣으면 대충 다음과 같은 모습입니다.

def update_chart(df, data):
    last_time = df.index[-1]
    new_time = pd.to_datetime(data['k']['t'], unit='ms') + timedelta(hours=9)
    new_candle = {}
    for x in data['k']:
        if x in df.columns:
            if x in ['q', 'Q']:
                new_candle[x] = round(float(data['k'][x]))
            elif x in ['t', 'n']:
                new_candle[x] = int(data['k'][x])
            elif x in 'T':
                pass
            else:
                new_candle[x] = float(data['k'][x])
    new_candle['t'] = new_time

    # 새로운 행 추가 및 오래된 행 제거
    if new_time != last_time:
        new_row = pd.DataFrame([new_candle]).set_index('t')
        df = pd.concat([df, new_row])
        df = df.iloc[1:]
    else:  # 현재 캔들 업데이트
        df.iloc[-1] = pd.Series(new_candle).reindex(df.columns)
        
    # 이동평균
    df['MA20'] = df['c'].rolling(window=20).mean()
    df['MA7'] = df['c'].rolling(window=7).mean()
    df['MA100'] = df['c'].rolling(window=100).mean()

    # 20분 평균 거래량
    df['VOL20'] = round(df['v'].rolling(window=20).mean())

    # 볼린저 밴드
    df['STD20'] = df['c'].rolling(window=20).std(ddof=0)
    df['bb_Upper'] = df['MA20'] + df['STD20'] * 2
    df['bb_Lower'] = df['MA20'] - df['STD20'] * 2

    # MACD
    df['EMA12'] = df['c'].ewm(span=12, adjust=False).mean()
    df['EMA26'] = df['c'].ewm(span=26, adjust=False).mean()
    df['MACD'] = df['EMA12'] - df['EMA26']
    df['Signal'] = df['MACD'].ewm(span=9, adjust=False).mean()

    # RSI
    delta = df['c'].diff()
    gain = delta.where(delta > 0, 0)
    loss = -delta.where(delta < 0, 0)
    avg_gain = gain.ewm(alpha=1/14, min_periods=14, adjust=False).mean()
    avg_loss = loss.ewm(alpha=1/14, min_periods=14, adjust=False).mean()
    rs = avg_gain / avg_loss
    df['RSI'] = 100 - (100 / (1 + rs))

    # CCI
	df['TP'] = (df['h'] + df['l'] + df['c']) / 3
	df['TP_MA'] = df['TP'].rolling(window=20, min_periods=20).mean()
	df['MAD'] = df['TP'].rolling(window=20, min_periods=20).apply(lambda x: abs(x - x.mean()).mean(), raw=True)
	df['CCI'] = (df['TP'] - df['TP_MA']) / (0.015 * df['MAD'])
    
    print(df.tail())
    return df