Compare commits

...

2 Commits

Author SHA1 Message Date
f8c8b29531 Merge remote-tracking branch 'origin/master'
All checks were successful
CI Build / build (push) Successful in 5s
2025-03-29 19:18:10 +09:00
152de00783 chore: 패키지 구조 변경(실행 안 됨) 2025-03-29 19:17:49 +09:00
29 changed files with 100 additions and 73 deletions

View File

@ -1,5 +1,5 @@
# 실행 # 실행
streamlit run .\streamlit-quant\app.py --server.port 20000 streamlit run app.py --server.port=20000
# pre- # pre-
Go to Build Tools for Visual Studio 2017 Go to Build Tools for Visual Studio 2017

View File

@ -2,7 +2,7 @@
import numpy as np import numpy as np
import pandas as pd import pandas as pd
import quantcommon from streamlit_quant import quantcommon
# DB 연결 # DB 연결
common = quantcommon.QuantCommon() common = quantcommon.QuantCommon()

View File

@ -1,12 +1,10 @@
import re import re
import time
import pandas as pd import pandas as pd
import requests as rq import requests as rq
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from tqdm import tqdm
import quantcommon from streamlit_quant import quantcommon
# DB 연결 # DB 연결
common = quantcommon.QuantCommon() common = quantcommon.QuantCommon()

View File

@ -6,7 +6,7 @@ import requests as rq
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from tqdm import tqdm from tqdm import tqdm
import quantcommon from streamlit_quant import quantcommon
# src/current-financial-statement.py 로 개선 # src/current-financial-statement.py 로 개선
# DB 연결 # DB 연결

View File

@ -8,7 +8,7 @@ import requests as rq
from tqdm import tqdm from tqdm import tqdm
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from dotenv import load_dotenv from dotenv import load_dotenv
import quantcommon from streamlit_quant import quantcommon
# src/current-stock.py 로 개선 # src/current-stock.py 로 개선
load_dotenv() load_dotenv()

View File

@ -9,7 +9,7 @@ import requests as rq
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from tqdm import tqdm from tqdm import tqdm
import quantcommon from streamlit_quant import quantcommon
# src/current-price.py 로 개선 # src/current-price.py 로 개선

View File

@ -3,7 +3,7 @@ import matplotlib.pyplot as plt
import seaborn as sns import seaborn as sns
import statsmodels.api as sm import statsmodels.api as sm
import numpy as np import numpy as np
import quantcommon from streamlit_quant import quantcommon
# strategy/momentum에 구현 # strategy/momentum에 구현
# 모멘텀 포트폴리오. 최근 12개월 수익률이 높은 주식 # 모멘텀 포트폴리오. 최근 12개월 수익률이 높은 주식

View File

@ -1,6 +1,6 @@
import pandas as pd import pandas as pd
import numpy as np import numpy as np
import quantcommon from streamlit_quant import quantcommon
# strategy/value 에서 구현 # strategy/value 에서 구현

View File

@ -2,7 +2,7 @@ import pandas as pd
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import seaborn as sns import seaborn as sns
import quantcommon from streamlit_quant import quantcommon
# 마법 공식 포트폴리오. 밸류와 퀄리티의 조합. 조엘 그린블라트의 '마법공식 # 마법 공식 포트폴리오. 밸류와 퀄리티의 조합. 조엘 그린블라트의 '마법공식
engine = quantcommon.QuantCommon().create_engine() engine = quantcommon.QuantCommon().create_engine()

View File

@ -4,7 +4,7 @@ import statsmodels.api as sm
from scipy.stats import zscore from scipy.stats import zscore
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import seaborn as sns import seaborn as sns
import quantcommon from streamlit_quant import quantcommon
# strategy/multi-factor에서 구현 # strategy/multi-factor에서 구현

View File

@ -2,7 +2,7 @@ import pandas as pd
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import seaborn as sns import seaborn as sns
import quantcommon from streamlit_quant import quantcommon
# strategy/quality에서 구현 # strategy/quality에서 구현

View File

@ -1 +1 @@
__all__ = ['backtest', 'strategy'] __all__ = ['backtest', 'strategy', 'quantcommon']

View File

@ -1,8 +1,8 @@
import streamlit as st import streamlit as st
crawling_page = st.Page("pages/crawling.py", title="크롤링") crawling_page = st.Page("crawling.py", title="크롤링")
super_quality_page = st.Page("pages/super_quality.py", title="슈퍼 퀄리티 전략") super_quality_page = st.Page("super_quality.py", title="슈퍼 퀄리티 전략")
super_value_momentum_page = st.Page("pages/super_value_momentum.py", title="슈퍼 밸류 모멘텀 전략") super_value_momentum_page = st.Page("super_value_momentum.py", title="슈퍼 밸류 모멘텀 전략")
pg = st.navigation({ pg = st.navigation({
'크롤링': [crawling_page], '크롤링': [crawling_page],

View File

@ -3,7 +3,7 @@ import matplotlib.pyplot as plt
import pandas as pd import pandas as pd
import quantcommon from streamlit_quant import quantcommon
import streamlit_quant.strategy.multi_factor as multi_factor import streamlit_quant.strategy.multi_factor as multi_factor
import streamlit_quant.strategy.magic_formula as magic_formula import streamlit_quant.strategy.magic_formula as magic_formula

View File

@ -1,41 +0,0 @@
import streamlit as st
st.write("""
'신F-스코어 3점 + 고GP/A 전략' '강환국 슈퍼 퀄리티 전략'이라 명명한다.
전략은 신F-스코어가 3점인 종목을 매수하되, GP/A로 순위를 매겨서 순위가 높은 종목만 매수하는 것이다.
경우 한국에서 수익이 어땠을지 분석해보자.
연도별로 신F-스코어 3점을 충족하는 종목은 600-700개였다.\n
신F-스코어 3 기업 내에서도 GP/A가 높은 종목이 3 종목 평균보다 CAGR 기준으로 3-4% 높았다.
반대로 GP/A가 낮은 종목의 수익률은 상대적으로 저조했다.\n\n
---
투자 전략: 강환국 슈퍼 퀄리티 전략 1.0\n
레벨: , 중급\n
스타일: 퀄리티\n
기대 CAGR: 20%\n
매수 전략:
- 신F-스코어 3 종목만 매수\n
- 여기에 GP/A 순위를 부여, 순위 높은 20-30종목을 매수\n
매도 전략: 1 리밸런싱\n\n\n
---
지금까지 소개한 거의 모든 전략에서 소형주 전략이 전체 주식 수익률보다 높았다.
시가총액 하위 20% 종목의 CAGR을 분석해보았다.\n\n
---
투자 전략: 강환국 슈퍼 퀄리티 전략 2.0\n
레벨: , 중급\n
스타일: 퀄리티\n
기대 CAGR: 20% 이상\n
매수 전략:
아래 조건을 만족하는 20-30종목 매수\n
- 신F-스코어 3 종목만 매수\n
- 여기에 GP/A 순위를 부여, 순위 높은 종목만 매수\n
- , 소형주(시가총액 최저 20%) 매수\n
매도 전략: 1 리밸런싱\n
---
소형주 신F-스코어가 3점인 종목을 찾아보니 2004-2016 구간에 80-100 종목이 남았다.
주식들을 통째로 매수해도 CAGR 34.55% 벌수 있었다!
정말 상당한 수익이다.
종목들을 샀으면 1,159 종목 14개가 파산했다.(1.2%)
1년간 마이너스 수익을 기록한 종목이 29.7%였다.\n
신F-스코어가 3점인 종목 GP/A가 높은 종목 위주로 매수했으면 (1) CAGR도 조금 개선되고 (2) 최상 30 종목을 매수했을 경우 선택받은 종목 360 파산한 기업은 1개였다.
F-스코어와 GP/A는 엄청난 잠재력을 지닌 콤비네이션임이 분명하다.
""")

View File

@ -6,7 +6,8 @@ import requests as rq
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from tqdm import tqdm from tqdm import tqdm
import quantcommon from streamlit_quant import quantcommon
# 재무제표 크롤링 # 재무제표 크롤링

View File

@ -6,10 +6,10 @@ from io import BytesIO
import pandas as pd import pandas as pd
import requests as rq import requests as rq
from dateutil.relativedelta import relativedelta
from tqdm import tqdm from tqdm import tqdm
import quantcommon from streamlit_quant import quantcommon
# 주가 크롤링 # 주가 크롤링

View File

@ -8,7 +8,7 @@ import requests as rq
from tqdm import tqdm from tqdm import tqdm
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from dotenv import load_dotenv from dotenv import load_dotenv
import quantcommon from streamlit_quant import quantcommon
load_dotenv() load_dotenv()

View File

@ -1 +1 @@
__all__ = ['multi_factor'] __all__ = ['multi_factor', 'f_score']

View File

@ -1,7 +1,8 @@
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
import seaborn as sns import seaborn as sns
import quantcommon from streamlit_quant import quantcommon
#가치주 포트폴리오. PER, PBR, PCR, PSR, DY #가치주 포트폴리오. PER, PBR, PCR, PSR, DY
def get_all_value_top(count): def get_all_value_top(count):

View File

@ -1,6 +1,7 @@
from datetime import datetime from datetime import datetime
import pandas as pd import pandas as pd
import quantcommon from streamlit_quant import quantcommon
# 흑자 기업이면 1점(당기순이익) # 흑자 기업이면 1점(당기순이익)
def calc_net_income(qc, base_date): def calc_net_income(qc, base_date):

View File

@ -1,8 +1,6 @@
import pandas as pd
import numpy as np import numpy as np
import matplotlib.pyplot as plt from streamlit_quant import quantcommon
import seaborn as sns
import quantcommon
# 마법 공식 포트폴리오. 밸류와 퀄리티의 조합. 조엘 그린블라트의 '마법공식' # 마법 공식 포트폴리오. 밸류와 퀄리티의 조합. 조엘 그린블라트의 '마법공식'
def get_magic_formula_top(count): def get_magic_formula_top(count):

View File

@ -3,7 +3,7 @@ import matplotlib.pyplot as plt
import seaborn as sns import seaborn as sns
import statsmodels.api as sm import statsmodels.api as sm
import numpy as np import numpy as np
import quantcommon from streamlit_quant import quantcommon
def print_graph(values): def print_graph(values):

View File

@ -1,7 +1,8 @@
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import seaborn as sns import seaborn as sns
import quantcommon from streamlit_quant import quantcommon
# 퀄리티(우량주) 포트폴리오. 영업수익성이 높은 주식 # 퀄리티(우량주) 포트폴리오. 영업수익성이 높은 주식
def get_quality_top(count): def get_quality_top(count):

View File

@ -1,6 +1,7 @@
import numpy as np import numpy as np
import quantcommon from streamlit_quant import quantcommon
#가치주 포트폴리오. PER, PBR이 낮은 회사 20개 #가치주 포트폴리오. PER, PBR이 낮은 회사 20개
def get_value_top(count): def get_value_top(count):

View File

@ -0,0 +1,67 @@
from datetime import datetime
import streamlit as st
from strategy import f_score
import quantcommon
# st.write("""
# '신F-스코어 3점 + 고GP/A 전략'을 '강환국 슈퍼 퀄리티 전략'이라 명명한다.
# 이 전략은 신F-스코어가 3점인 종목을 매수하되, GP/A로 순위를 매겨서 순위가 높은 종목만 매수하는 것이다.
# 이 경우 한국에서 수익이 어땠을지 분석해보자.
# 연도별로 신F-스코어 3점을 충족하는 종목은 600-700개였다.\n
# 신F-스코어 3점 기업 내에서도 GP/A가 높은 종목이 3점 종목 평균보다 CAGR 기준으로 3-4% 더 높았다.
# 반대로 GP/A가 낮은 종목의 수익률은 상대적으로 저조했다.\n\n
# ---
# 투자 전략: 강환국 슈퍼 퀄리티 전략 1.0\n
# 레벨: 초, 중급\n
# 스타일: 퀄리티\n
# 기대 CAGR: 약 20%\n
# 매수 전략:
# - 신F-스코어 3점 종목만 매수\n
# - 여기에 GP/A 순위를 부여, 순위 높은 20-30종목을 매수\n
# 매도 전략: 연 1회 리밸런싱\n\n\n
# ---
# 지금까지 소개한 거의 모든 전략에서 소형주 전략이 전체 주식 수익률보다 높았다.
# 시가총액 하위 20% 종목의 CAGR을 분석해보았다.\n\n
# ---
# 투자 전략: 강환국 슈퍼 퀄리티 전략 2.0\n
# 레벨: 초, 중급\n
# 스타일: 퀄리티\n
# 기대 CAGR: 20% 이상\n
# 매수 전략:
# 아래 조건을 만족하는 20-30종목 매수\n
# - 신F-스코어 3점 종목만 매수\n
# - 여기에 GP/A 순위를 부여, 순위 높은 종목만 매수\n
# - 단, 소형주(시가총액 최저 20%)만 매수\n
# 매도 전략: 연 1회 리밸런싱\n
# ---
# 소형주 중 신F-스코어가 3점인 종목을 찾아보니 2004-2016년 구간에 80-100개 종목이 남았다.
# 그 주식들을 통째로 매수해도 CAGR 34.55%를 벌수 있었다!
# 정말 상당한 수익이다.
# 이 종목들을 다 샀으면 총 1,159개 종목 중 14개가 파산했다.(1.2%)
# 또 1년간 마이너스 수익을 기록한 종목이 29.7%였다.\n
# 신F-스코어가 3점인 종목 중 GP/A가 높은 종목 위주로 매수했으면 (1) CAGR도 조금 개선되고 (2) 최상 30개 종목을 매수했을 경우 선택받은 종목 360개 중 파산한 기업은 단 1개였다.
# F-스코어와 GP/A는 엄청난 잠재력을 지닌 콤비네이션임이 분명하다.
# """)
def get_last_year_end():
# 현재 날짜 가져오기 (2025년 3월 16일 기준)
today = datetime.now()
# 작년 연도 계산
last_year = today.year - 1
# 작년 12월 31일 생성
last_year_end = datetime(last_year, 12, 31)
return last_year_end.date()
st.write("투자 전략: 강환국 슈퍼 퀄리티 전략 2.0")
date = get_last_year_end()
data = f_score.get_f_score(quantcommon.QuantCommon(), date)
config = {}
st.dataframe(data, column_config=config, use_container_width=True)