본문 바로가기
주식분석/Quant 분석(프로그래밍)

valuewhen 함수, 파이썬으로는 어떻게 작성할까?

by hustler78 2023. 3. 29.
728x90
반응형

 

 

요즘 HTS를 보면 사용자가 원하는 지표를 만들고, 원하는 신호를 띄우기 위해 수식관리자라는 프로그램으로 사용자 정의 수식을 만드는 기능이 있습니다.

파인 스크립트(pine script)라는 프로그램이 통상적으로 사용되는데요. 여러 함수 중 가장 파워풀하게 쓰이는 것 중 하나가 바로

 valuewhen

 

이라는 함수입니다. valuewhen 함수의 인풋 파라미터는 아래와 같습니다.

 

valuewhen(nth, condition, data)

 

data는 시계열 자료입니다. 위 valuewhen 함수의 함숫값은

오늘을 포함하여 condition이라는 조건을  nth 번째 만족하는 과거 시점의 data값
만일 condition 조건을 만족하는 시점이 없으면 data의 첫 번째 값 

입니다.  무슨뜻인지 감이 오시나요? 아래 실제 주가 데이터를 가지고 valuewhen 함수가 무엇인지 알아보겠습니다.

 

 

 

valuewhen 예제

 

삼성전자의 한 달 주식을 불러온 다음

 

당일의 종가가 전일의 종가보다 1% 이상 상승한 가장 최근일의 종가를 찾는 예제

 

를 생각해 봅시다.

 

def valuewhen_test():
    end_date = datetime.datetime.today()            # 조회 종료일 : 오늘
    start_date = end_date - relativedelta(months=1) # 조회 시작일 : 오늘부터 1달 전

    stk_code = '005930'                    # 삼성전자(005930)

    df = load_data(stk_code, start_date, end_date)
    df.to_excel('stock_series.xlsx')       # to_excel 함수를 이용하여 dataframe을 엑셀로 저장

 

1달치 삼성전자 시고저종 및 거래량 데이터

 

여기에 조건(condition) 열을 추가해 봅시다. 조건식은

 

당일의 종가 > 전일의 종가 × 1.01

 

입니다. 아래처럼 수식을 걸어 condition이라는 열을 작성합니다.

 

이제 가장 최근 조건만족일의 종가를 대입해 봅시다.

 

① 3/29일자 기준

3/29일 자의 condition 은 False이죠. 시간을 과거로 거슬로 올라갈 때, 가장 최근 True일자는 바로 위의 3/28일입니다.

따라서 이 때의 종가인 62900원(파란 셀)을 valuewhen column(회색 셀)의 3/29일 자에 기입해 주면 됩니다.

 

 

② 3/28일자 기준

 

3/28일 자 기준 가장 최근 True 일은 바로 자기 당일이죠? 따라서 당일 종가인 62900원이 valuewhen 함숫값이 됩니다.

 

이런 식으로 채워 나가면 됩니다. 우선 condition이 True인 날은 가장 최근일 중 조건을 만족하는 날이 자기 당일이므로

condition == True 인 날은 아래처럼 valuewhen 값을 채워 넣을 수 있고요. 이제 False 일 때는 어떻게 채워 넣을까요?

 

 

아래 그림 빨간 영역은 모두 condition이 False이고 이 시점들에서 가장 최근 True일은 바로 3월 6일이죠. 그리고 이때 삼성전자 종가는 61500원이므로 빨간 영역은 모두 61500이라는 숫자로 채워지게 됩니다. 

 

 

 

자, 그럼 valuewhen 칼럼의 수식은 이렇게 쓰면 될 것 같습니다.

condition이 True이면 종가,  condition이 False이면 바로 valuewhen칼럼 바로 위의 값

 

아래 그림처럼

=IF(condition, 종가, valuewhen바로 윗값)

 

을 해주고 초기값인 3월 2일의 valuewhen 가격은 그냥 종가 (E2)열로 세팅해 주면 모든 셀 값이 채워지게 되죠.

 

 

그럼 이것을  파이썬으로 구현해 볼까요?

 

 

 

Python Code : Valuewhen

 

import pandas as pd
import numpy as np
import mplfinance
import datetime
from dateutil.relativedelta import relativedelta
import FinanceDataReader as fdr

def load_data(stock_code, start_date, end_date):
    df = fdr.DataReader(stock_code, start_date, end_date)
    return df

def valuewhen_test():
    end_date = datetime.datetime.today()
    start_date = end_date - relativedelta(months=1)

    stk_code = '005930'

    df = load_data(stk_code, start_date, end_date)
    # df.to_excel('stock_series.xlsx')

    df['condition'] = df.Close > df.Close.shift(1) * (1 + 0.01)
    df['condition'].iloc[0]=True  # 시계열의 첫번째 자료에서 valuewhen함수값을 편하게 찾기위해
                                  # conition의 첫번째 값은 True로 함
    pd.set_option("display.max_rows", None)
                                  # dataframe의 모든 열을 다 display하도록

   df['res1'] = 0                 # 우선 res1이라는 column setting
    for i in reversed(range(len(df))):   # len(df) 즉, df의 끝 index부터 0까지 reverse로 내려오며
        j = i                            # j 에 i를 대입
        while df['condition'].iloc[j] == False:  # 만일 j번째 index의 condition이 False면
            if j == 0:                   # j=0 까지 내려가면 break
                break
            j -= 1                       # j를 하나씩 감소시켜 True가 나올때까지 찾음 이게 바로
                                         # valuewhen(nth =1 ,condition, data) 값임

        df['res1'].iloc[i] = df['Close'].iloc[j]
                                         # res1 는 valuewhen값으로 data = df.Close인 상황
                                         # 위에서 찾았던 j index의 값을 res1의 i번째에 넣어줌

    print(df[['Close','res1']])          # Close, res1 열을 출력해 본다.


if __name__ == '__main__':
    valuewhen_test()

 

자, 의식의 흐름대로 짠 코딩입니다. 결과를  보면,

 

            Close   res1
Date                    
2023-03-02  60800  60800
2023-03-03  60500  60800
2023-03-06  61500  61500
2023-03-07  60700  61500
2023-03-08  60300  61500
2023-03-09  60100  61500
2023-03-10  59500  61500
2023-03-13  60000  61500
2023-03-14  59000  61500
2023-03-15  59800  59800
2023-03-16  59900  59800
2023-03-17  61300  61300
2023-03-20  60200  61300
2023-03-21  60300  61300
2023-03-22  61100  61100
2023-03-23  62300  62300
2023-03-24  63000  63000
2023-03-27  62100  63000
2023-03-28  62900  62900
2023-03-29  62300  62900

이고 이 res1의 값은 위의 엑셀파일 그림의 valuewhen 칼럼의 값과 정확히 일치합니다.

 

 

어떻게 프로그래밍하든지 결과만 맞으면 장땡입니다만, 위 코딩은 조금 멋이 없습니다. 다음 글에서는 valuewhen 함수를 조금 멋있게 구현하는 방법에 대해 알아보겠습니다.

728x90
반응형

댓글