본문 바로가기

코딩/퀀트 투자

[파이썬/ 웹 스크래핑] 벤저민 그레이엄의 투자 전략에 따른 종목 선정 - 공격 투자자(2)

 

 

https://kr.freepik.com/vectors/illustration

 

 

1. 목표

 

저번 포스팅에 이어서 벤저민 그레이엄의 공격 투자자를 위한 6가지 투자 전략 중 나머지 2가지 전략을 통해 종목 선정을 할 것이다.

 

4가지 전략에 대한 내용은 아래의 글을 참조하면 된다.

 

 

[파이썬/ 웹 스크래핑] 벤저민 그레이엄의 투자 전략에 따른 종목 선정 - 공격 투자자(1)

1. 목표 벤저민 그레이엄의 방어 투자자를 위한 투자 전략에 이어 공격 투자자를 위한 투자 전략을 사용해 종목 선정하는 것을 목표로 한다. 방어 투자자를 위한 투자 전략에 대한 정보가 궁금하

coding-gongbu.tistory.com

 

 

 

 

2. 공격 투자자를 위한 6가지 투자 전략 요약

 

(1) 적정 PER:

 

- PER이 9 이하인 종목

 

 

(2) 재무 상태:

 

- 유동자산이 유동부채의 150% 이상인 종목

("유동자산 / 유동부채 = 유동비율(current ratio) >= 1.5"인 종목)

- 부채(total debt)가 순 유동자산의 110% 이하인 종목

(순 유동자산 = 총 유동자산(total current assets) - 총 유동부채(total current liabilities))

 

 

(3) 이익의 안정성:

 

- 지난 5년 동안 적자를 기록한 적 없는 종목

(즉, 5년간 당기순이익(net income)이 마이너스가 없는 종목)

 

 

(4) 배당 실적:

 

- 당기에 조금이라도 배당을 지급한 종목

 

 

(5) 이익 증가:

 

- 작년 이익이 4년 전 이익보다 많은 종목

 

 

(6) 주가:

 

- 주가가 순유형자산의 120% 미만인 종목

(순유형자산(net tangible assets) = 총 자산(total assets) - 총 부채(total liabilities) - 무형자산(intangible assets) - 영업권(goodwill))

 

 

 

 

 

Photo by Arnold Francisca on Unsplash

 

 

네 번째, 주가가 순유형자산의 120% 미만인 종목 선정 (투자 전략 (6))

 

먼저 finviz.com에서 세 번째에서 추출한 ticker들의 주가(price), 총 자산(total assets), 총 부채(total liabilities), 무형자산(intangible assets)와 영업권(goodwill)을 웹 스크래핑으로 추출해 csv 파일에 저장한다.

 

 

FINVIZ.com - Stock Screener

× Ever heard of Finviz*Elite? Our premium service offers you real-time quotes, advanced visualizations, technical studies, and much more. Become Elite and make informed financial decisions. Find out more --> Upgrade your FINVIZ experience Join thousands o

finviz.com

 

코드는 다음과 같다.

 

from bs4 import BeautifulSoup
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time

tickers = pd.read_csv('tickers_result_3.csv')
tickers = tickers['Symbol'].tolist()

columns = ['Price', 'Total Assets', 'Intangibles, Net', 'Goodwill, Net', 'Total Liabilities']
df_filter = pd.DataFrame(index=tickers, columns=columns)

driver = webdriver.Chrome('C:/Program Files/chromedriver_win32/chromedriver.exe')
driver.implicitly_wait(3)

for ticker in tickers:
    driver.get(f'https://finviz.com/quote.ashx?t={ticker}')
    try:
        driver.find_element_by_link_text('balance sheet').send_keys(Keys.ENTER)
    except:
        continue
    time.sleep(5)
    html = driver.page_source
    soup = BeautifulSoup(html, 'lxml')

    df_filter.loc[ticker, 'Price'] = soup.find('td', text='Price').find_next('td').text

    for column in columns[1:]:
        r = soup.find(text=column).find_next(class_='snapshot-td2').find_next(class_='snapshot-td2').text
        try:
            df_filter.loc[ticker, column] = float(r.replace(',', ''))
        except:
            df_filter.loc[ticker, column] = None

df_filter.to_csv('df_filter_4.csv')

 

다음으로 위에서 추출한 정보로 주가가 순유형자산의 120% 미만인 종목을 필터링해 csv 파일로 저장한다.

 

이때 순유형자산은 총 자산(total assets) - 총 부채(total liabilities) - 무형자산(intangible assets) - 영업권(good will)로 계산된다.

 

코드는 다음과 같다.

 

import pandas as pd

df_filter = pd.read_csv('df_filter_4.csv', index_col=0)
df_filter = df_filter.dropna()

list = []

for i in range(len(df_filter)):
    net_tangible_assets = df_filter.iloc[i, 1] - df_filter.iloc[i, 2] - df_filter.iloc[i, 3] - df_filter.iloc[i, 4]
    if (net_tangible_assets * 1.2) > df_filter.iloc[i, 0]:
        list.append(df_filter.index[i])

df_result = pd.DataFrame({'Symbol' : list})
df_result.to_csv('tickers_result_4.csv')

 

 

 

 

다섯 번째, 당기에 조금이라도 배당을 지급한 종목 선정 (투자 전략 (4))

 

먼저 finviz.com에서 위에서 추출한 ticker들의 배당률(dividend %)를 추출해서 csv 파일에 저장한다.

 

 

FINVIZ.com - Stock Screener

× Ever heard of Finviz*Elite? Our premium service offers you real-time quotes, advanced visualizations, technical studies, and much more. Become Elite and make informed financial decisions. Find out more --> Upgrade your FINVIZ experience Join thousands o

finviz.com

 

코드는 다음과 같다.

 

from bs4 import BeautifulSoup
import pandas as pd
import requests as request

def get_html(url):
    _html = ""
    resp = request.get(url, headers={'User-agent' : 'Mozilla/5.0'})
    if resp.status_code == 200:
        _html = resp.text
    return _html

tickers = pd.read_csv('tickers_result_4.csv')
tickers = tickers['Symbol'].tolist()

df_filter = pd.DataFrame(index=tickers, columns=['Dividend %'])

for ticker in tickers:
    #dividend 크롤링
    url = f'https://finviz.com/quote.ashx?t={ticker}'
    html = get_html(url)
    soup = BeautifulSoup(html, 'lxml')
    df_filter.loc[ticker, 'Dividend %'] = soup.find('td', text='Dividend %').find_next('td').text

df_filter.to_csv('df_filter_5.csv')

 

다음으로 위에서 추출한 정보로 배당금을 지급하지 않은 종목들을 필터링해 dataframe의 형태로 csv 파일에 저장한다.

 

코드는 다음과 같다.

 

import pandas as pd

df_filter = pd.read_csv('df_filter_5.csv', index_col=0)

list = []

for i in range(len(df_filter)):
    if df_filter.iloc[i, 0] == '-':
        pass
    else:
        list.append(df_filter.index[i])

df_result = pd.DataFrame({'Symbol' : list})
df_result.to_csv('tickers_result_5.csv')

 

 

 

 

3. 결론

 

미국 주식에 벤저민 그레이엄의 공격 투자자를 위한 6가지 투자 전략을 모두 적용해본 결과 총 107가지의 종목이 선정되었다.