본문 바로가기

데이터분석/금융

python 활용 투자 포트폴리오 [2화: 백테스팅 시뮬레이션]

정해진 예산 범위에서 특정 방법으로 자산을 배분했을 때, 어느 정도의 수익률을 얻을 수 있는지 총 과정을 시뮬레이션하기 위한 코드를 짜보기로 했다. 전체 과정을 쉽게 풀어쓰면 (pseudo-code) 아래와 같을 것이다.

 

 

지난 글(링크)에서는 단순히 총 자산에 맞춰 종목을 구매한 뒤 최종 일자까지 보유함으로써 얻는 수익률을 AI ETF와 비교하는 것에 그쳤지만, 위 알고리즘에 해당하는 파트들을 명령어로 묶어두는 것이 다양한 백테스트를 실행하는 데 도움이 될 것이다.

 

python 활용 투자 포트폴리오 [1화: AI ETF와 비교한 수익률 백테스팅]

데이터 분석을 어디에 쓰면 좋을까, 고민하다가 게임을 시작했고 (핑계에 가깝지만) 결과는 신통치 않다. 딱히 데이터 분석을 하고 있는지도 잘 모르겠는 것이다. 그러던 와중에 재테크 책인 강

mech-literacy.tistory.com

 

## 종목별 비율 확인

print(len(portfolio))
closing_asset = np.zeros([3, 1])
for i in range(num_item):
    closing_asset[i] = portfolio[i][['Close']].iloc[-1]
    
# 총 자산 재확인
total_asset = remain + sum(closing_asset)
print("total asset : ", total_asset[0])
print("remain : ", remain)
print("closing asset")
print(closing_asset)
ratio = closing_asset / total_asset
print(ratio)

print("buying vol")
print(buying_vol)

# 종목별 거래가격 확인
trading_price = np.zeros([3, 1])
for i in range(num_item):
    trading_price[i] = np.mean(portfolio[i][['Close', 'Open']].iloc[-1]/ buying_vol[i])
print("trading_price")
print(trading_price)

## Remain Strategy: 
# remain_input: 잔액 부족할 경우 채워넣기
# remain_hold: 잔액 부족할 경우 가능한 만큼만 구매하기
remain_strategy = "remain_hold"
# Rebalancing
holding_vol = buying_vol.copy()
for i in range(num_item):
    if ratio[i] > portion[i]: # 비율 초과일 경우
        sell_more = closing_asset[i] - total_asset*portion[i] # 비율 맞추기 위해 팔아야 하는 금액
        print("Sell ", sell_more)
        sell_vol = np.floor(sell_more / trading_price[i])
        sell_output = trading_price[i] * sell_vol
        sell_output = sell_output - commission * sell_output
        remain = remain + sell_output
        holding_vol[i] = holding_vol[i] - sell_vol
        
    else: # 비율 이하일 경우
        buy_more = total_asset*portion[i] - closing_asset[i] # 비율 맞추기 위해 사야 하는 금액
        print("Buy ", buy_more)
        buy_vol = np.floor(buy_more / trading_price[i])
        buy_input = trading_price[i] * buy_vol
        buy_input = buy_input + commission * buy_input
        
        if remain > buy_input:
            remain = remain - buy_input
            holding_vol[i] = holding_vol[i] + buy_vol
            
        else:
            if remain_strategy == "remain_hold":
                buy_vol = np.floor(remain / trading_price[i])
                buy_input = trading_price[i] * buy_vol
                buy_input = buy_input + commission * buy_input
                remain = remain - buy_input
                holding_vol[i] = holding_vol[i] + buy_vol
                
portfolio_RB2 = [None] * num_item
for i in range(num_item):
    portfolio_RB2[i] = total_items[i] * holding_vol[i][0]
    if i == 0:
        revenue_RB2 = portfolio[0]
    else:
        revenue_RB2 = portfolio_sum + portfolio_RB2[i].values
result = np.array(portfolio_sum2)[-1,3]
print("remain", remain)
print("rebalanced asset 0", portfolio_RB2[0][['Close']].iloc[-1])
print("rebalanced asset 1", portfolio_RB2[1][['Close']].iloc[-1])
print("rebalanced asset 2", portfolio_RB2[2][['Close']].iloc[-1])
print("holding vol", holding_vol)

위 코드는 리밸런싱을 수행하기까지의 과정을 담은 코드이다. 이제 리밸런싱을 수행할 일자를 선정하고, 그에 맞춰 수익 그래프를 뽑아낼 수 있으면 끝이다.