feat: 파일 이름 변경, 백테스트 샘플 추가, 디렉토리 패키지화
This commit is contained in:
parent
07e07dfbcd
commit
679eb4fe0b
@ -1,2 +1,9 @@
|
||||
# 실행
|
||||
streamlit run .\streamlit-quant\app.py --server.port 20000
|
||||
|
||||
# pre-
|
||||
Go to Build Tools for Visual Studio 2017
|
||||
Select free download under Visual Studio Community 2017. This will download the installer. Run the installer.
|
||||
Select what you need under workload tab:
|
||||
a. Under Windows, there are three choices. Only check Desktop development with C++.
|
||||
b. Under Web & Cloud, there are seven choices. Only check Python development (I believe this is optional, but I have done it).
|
||||
@ -69,6 +69,19 @@ class QuantCommon:
|
||||
|
||||
return price_list
|
||||
|
||||
def get_price_list_by_code(self, codes):
|
||||
engine = self.create_engine()
|
||||
|
||||
try:
|
||||
price_list = pd.read_sql(f"""
|
||||
select * from kor_price
|
||||
where 종목코드 in ({codes});
|
||||
""", con=engine)
|
||||
finally:
|
||||
engine.dispose()
|
||||
|
||||
return price_list
|
||||
|
||||
def get_fs_list(self):
|
||||
engine = self.create_engine()
|
||||
|
||||
|
||||
1
streamlit_quant/__init__.py
Normal file
1
streamlit_quant/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
__all__ = ['backtest', 'strategy']
|
||||
46
streamlit_quant/backtest/backtest-1.py
Normal file
46
streamlit_quant/backtest/backtest-1.py
Normal file
@ -0,0 +1,46 @@
|
||||
import bt
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
import pandas as pd
|
||||
|
||||
import quantcommon
|
||||
import streamlit_quant.strategy.multi_factor as multi_factor
|
||||
|
||||
|
||||
qc = quantcommon.QuantCommon()
|
||||
mf = multi_factor.get_multi_factor_top(qc, 20)
|
||||
|
||||
codes = ','.join(mf['종목코드'].array)
|
||||
price = qc.get_price_list_by_code(codes)
|
||||
|
||||
# price = price.set_index(['날짜'])
|
||||
# price.rename(columns={"날짜": "Date"})
|
||||
price["Date"] = pd.to_datetime(price["날짜"])
|
||||
|
||||
pivot_df = price.pivot(index="Date", columns="종목코드", values="종가")
|
||||
|
||||
# print(pivot_df.tail)
|
||||
|
||||
strategy = bt.Strategy("Asset_EW", [
|
||||
bt.algos.SelectAll(), # 모든 데이터 사용
|
||||
bt.algos.WeighEqually(), # 동일 비중 투자
|
||||
bt.algos.RunMonthly(), # 매 월말 리밸런싱
|
||||
bt.algos.Rebalance() # 계산된 비중에 따라 리밸런싱
|
||||
])
|
||||
|
||||
# 가격 데이터 중 시작 시점이 모두 다르므로, dropna() 함수를 통해 NA를 모두 제거하여 시작 시점을 맞춤
|
||||
pivot_df.dropna(inplace=True)
|
||||
|
||||
# 백테스트 생성
|
||||
backtest = bt.Backtest(strategy, pivot_df)
|
||||
|
||||
# 백테스트 실행
|
||||
result = bt.run(backtest)
|
||||
# prices: 누적 수익률이 데이터프레임 형태로 나타나며, 시작 시점을 100으로 환산하여 계산
|
||||
# to_returns: 수익률 계산
|
||||
# print(result.prices.to_returns())
|
||||
|
||||
result.plot(figsize=(10, 6), legend=False)
|
||||
plt.show()
|
||||
|
||||
result.display()
|
||||
1
streamlit_quant/strategy/__init__.py
Normal file
1
streamlit_quant/strategy/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
__all__ = ['multi_factor']
|
||||
@ -1,5 +1,4 @@
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import quantcommon
|
||||
|
||||
# DB 연결
|
||||
@ -4,14 +4,11 @@ import statsmodels.api as sm
|
||||
from scipy.stats import zscore
|
||||
import matplotlib.pyplot as plt
|
||||
import seaborn as sns
|
||||
import quantcommon
|
||||
|
||||
# 멀티 팩터 포트폴리오.
|
||||
# 퀄리티: 자기자본이익률(ROE), 매출총이익(GPA), 영업활동현금흐름(CFO)
|
||||
# 밸류: PER, PBR, PSR, PCR, DY
|
||||
# 모멘텀: 12개월 수익률, K-Ratio
|
||||
engine = quantcommon.QuantCommon().create_engine()
|
||||
|
||||
# 각 섹터별 아웃라이어를 제거한 후 순위와 z-score를 구하는 함수
|
||||
def col_clean(df, cutoff=0.01, asc=False):
|
||||
|
||||
@ -45,8 +42,7 @@ def plot_rank(df):
|
||||
plt.show()
|
||||
|
||||
|
||||
def get_multi_factor_top(count):
|
||||
qc = quantcommon.QuantCommon()
|
||||
def get_multi_factor_top(qc, count):
|
||||
ticker_list = qc.get_ticker_list()
|
||||
fs_list = qc.get_fs_list()
|
||||
value_list = qc.get_value_list()
|
||||
@ -220,7 +216,7 @@ def get_multi_factor_top(count):
|
||||
# 기본 테이블(data_bind)과 합침
|
||||
port_qvm = data_bind.merge(data_bind_final_sum, on='종목코드')
|
||||
# 최종 z-score의 합(qvm) 기준 순위가 20위 이내인 경우 투자 종목에 해당하니 Y로 표시, 나머진 N
|
||||
port_qvm['invest'] = np.where(port_qvm['qvm'].rank() <= 20, 'Y', 'N')
|
||||
port_qvm['invest'] = np.where(port_qvm['qvm'].rank() <= count, 'Y', 'N')
|
||||
|
||||
# round()는 DataFrame 객체 내의 요소를 반올림하는 메서드
|
||||
return port_qvm[port_qvm['invest'] == 'Y'].round(4)
|
||||
@ -252,11 +248,4 @@ def get_multi_factor_top(count):
|
||||
# hist_momentum['rank'] = hist_momentum.groupby('variable')['value'].rank(ascending = False)
|
||||
# plot_rank(hist_momentum)
|
||||
#
|
||||
# port_qvm[port_qvm['invest'] == 'Y']['종목코드'].to_excel('model.xlsx', index=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
top = get_multi_factor_top(20)
|
||||
# head() 상위 n개 반환. 기본값은 5
|
||||
print(top.head())
|
||||
top['종목코드'].to_excel('model.xlsx', index=False)
|
||||
# port_qvm[port_qvm['invest'] == 'Y']['종목코드'].to_excel('model.xlsx', index=False)
|
||||
Loading…
x
Reference in New Issue
Block a user