인플레이션에서 살아남기.

책 리뷰 2022. 10. 14. 09:46 Posted by UnHa Kim

 

FRB의 입장에 빙의해서 고민과 해결책을 고민해 보면서 향후 경제 흐름에 대한 안목을 넓혀주는 책.

 

1970년대 인플레이션 시대와 현재 상황에 대한 비교분석이 탁월하다.

 

나는 이 책을 읽고 나서 섣부른 경제 전망을 모두 내려놨다.

 

FRB의장조차도 인플레이션이 일시적이라는 예측이 틀려서 '겸손하고 재빠른' 모드로 태세 전환한 마당에 누가 향후 경제 흐름을 알 수 있단 말인가?

 

 

'책 리뷰' 카테고리의 다른 글

Successful Algorithm Trading  (0) 2022.12.19
가상화폐 투자마법 공식  (0) 2022.11.05
행운에 속지 마라.  (0) 2021.10.18
역발상 투자  (0) 2021.10.18
팩터 457개의 미국 증시에서 유효성 검증  (0) 2021.10.18

야후! 금융 재무 정보 얻기.

GHTS 2022. 10. 8. 13:46 Posted by UnHa Kim

다음 동영상에 '야후! 금융'에서 재무 정보를 추출하는 방법이 잘 설명되어 있다.

https://youtu.be/fw4gK-leExw

 

동영상 내용이 파이썬 기준이지만, 내용만 이해하면 Go언어에서도 구현은 쉽다.

chromedp(https://github.com/chromedp/chromedp) 모듈을 사용하면 자바스크립트를 이용해서 동적으로 생성되는 '야후! 금융' 웹페이지도 문제없이 불러들일 수 있다.

이렇게 읽어온 HTML에서 JSON 데이터 부분만 추출해서 map형태로 저장한 후 적절히 활용하면 된다.

애플의 재무 데이터를 읽어들이는 Go언어 예제 코드는 다음과 같다.

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/chromedp/chromedp"
	"log"
	"regexp"
	"testing"
	"time"
)

// 참고자료 : https://youtu.be/fw4gK-leExw
// 애플 재무 정보 수집 예제
func main() {
	const url템플릿 = `https://finance.yahoo.com/quote/%v/financials`
	종목코드 := "AAPL" // 애플

	// create chrome instance
	ctx, cancel := chromedp.NewContext(context.Background())
	defer cancel()

	// create a timeout
	ctx, cancel = context.WithTimeout(ctx, 30*time.Second)
	defer cancel()

	var html string
	url := fmt.Sprintf(url템플릿, 종목코드)

	if err := chromedp.Run(ctx,
		chromedp.Navigate(url),
		chromedp.InnerHTML("body", &html, chromedp.ByQuery),
	); err != nil {
		log.Fatal(err)
	}

	// HTML에서 JSON 데이터를 맵 형태로 추출
	html = regexp.MustCompile(`(?s)\s--\sData\s--\s.+?</script>`).FindString(html)
	html = regexp.MustCompile(`(?s)root.App.main.+</script>`).FindString(html)
	html = html[16 : len(html)-21]

	var 맵 map[string]interface{}

	json.Unmarshal([]byte(html), &맵)

	손익계산서_연도 := f2맵_모음(맵, []string{"context", "dispatcher", "stores", "QuoteSummaryStore", "incomeStatementHistory", "incomeStatementHistory"})
	f맵_모음_출력("손익계산서_연도", 손익계산서_연도)

	손익계산서_분기 := f2맵_모음(맵, []string{"context", "dispatcher", "stores", "QuoteSummaryStore", "incomeStatementHistoryQuarterly", "incomeStatementHistory"})
	f맵_모음_출력("손익계산서_분기", 손익계산서_분기)

	재무상태표_연도 := f2맵_모음(맵, []string{"context", "dispatcher", "stores", "QuoteSummaryStore", "balanceSheetHistory", "balanceSheetStatements"})
	f맵_모음_출력("재무상태표_연도", 재무상태표_연도)

	재무상태표_분기 := f2맵_모음(맵, []string{"context", "dispatcher", "stores", "QuoteSummaryStore", "balanceSheetHistoryQuarterly", "balanceSheetStatements"})
	f맵_모음_출력("재무상태표_분기", 재무상태표_분기)

	현금흐름표_연도 := f2맵_모음(맵, []string{"context", "dispatcher", "stores", "QuoteSummaryStore", "cashflowStatementHistory", "cashflowStatements"})
	f맵_모음_출력("현금흐름표_연도", 현금흐름표_연도)

	현금흐름표_분기 := f2맵_모음(맵, []string{"context", "dispatcher", "stores", "QuoteSummaryStore", "cashflowStatementHistoryQuarterly", "cashflowStatements"})
	f맵_모음_출력("현금흐름표_분기", 현금흐름표_분기)
}

func f2맵_모음(맵 map[string]interface{}, 키_모음 []string) (맵_모음 []map[string]interface{}) {
	for _, 키 := range 키_모음 {
		if 맵2, ok := 맵[키].(map[string]interface{}); ok {
			맵 = 맵2
			continue
		} else if 값_모음, ok := 맵[키].([]interface{}); ok {
			맵_모음 = make([]map[string]interface{}, len(값_모음))

			for i, 값 := range 값_모음 {
				맵_모음[i] = 값.(map[string]interface{})
			}

			return 맵_모음
		} else {
			panic(fmt.Errorf("예상하지 못한 자료형 %T\n", 맵[키]))
		}
	}

	return
}

func f맵_모음_출력(제목 string, 맵_모음 []map[string]interface{}) {
	for i, 맵 := range 맵_모음 {
		for 키, 값 := range 맵 {
			fmt.Printf("%v %v %v %v\n", 제목, i, 키, 값)
		}
	}
}

 

 

 

 

네이버에서 상당히 많은 국가의 주식 정보를 얻을 수 있다는 것을 알았으나,

좀 더 많은 국가의 정보를 수집하고 능력을 키우고 싶어서,

인베스팅닷컴에서 종목 정보를 수집을 시도해 봤다.

 

다음 URL에서 베트남 종목 목록 수집하는 것을 출발점으로 잡았다.

(https://www.investing.com/equities/vietnam)

 

해당 페이지는 기본적으로 'HNX 30'에 포함된 종목만을 보여준다.

모든 종목의 목록을 얻고 싶다면, 선택 상자에서 'Vietnam all stocks' 항목을 선택해야 하는 데, 이것을 프로그래밍적으로 자동으로 수행하도록 구현하는 방법을 찾느라 한참 헤맸다.

 

시행착오를 거듭한 결과, Go언어 기준으로 chromedp(https://github.com/chromedp/chromedp) 라는 모듈을 이용해서 다음과 같이 하면 모든 종목의 식별 데이터가 포함된 HTML을 추출할 수 있다.

// create chrome instance
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()

// create a timeout
ctx, cancel = context.WithTimeout(ctx, lib.P1분)
defer cancel()

const url = `https://www.investing.com/equities/vietnam`

var html string

if 에러 := chromedp.Run(ctx,
   chromedp.Navigate(url),
   chromedp.SetAttributeValue(`#all`, "value", "ALL"),
   chromedp.SetValue(`//select[@id="stocksFilter"]`, "ALL", chromedp.BySearch),      
   chromedp.WaitVisible("cross_rate_markets_stocks_1", chromedp.ByID),
   chromedp.InnerHTML("marketInnerContent", &html, chromedp.ByID),
); 에러 != nil {
   log.Fatal(에러)
}

이렇게 추출해 낸 HTML을 GoQuery(https://github.com/PuerkitoBio/goquery)등의 모듈을 이용해서 내용을 분석하면, pare_id(인베스팅닷컴 독자적인 일종의 종목 구분 코드), 종목 이름, 추가 정보 URL등의 정보를 추출할 수 있다.

 

문서 := lib.F확인2(goquery.NewDocumentFromReader(strings.NewReader(html)))
문서.Find("tbody tr").Each(func(i int, s *goquery.Selection) {
    pair_id, _ := s.Attr("id")
    href, _ := s.Find("a").Attr("href")

    <... 중략 ...>    
})

 

여기서부터 문제가 시작되는 데, 인베스팅닷컴에서 사용하는 종목 구분 코드인 Pair ID는 인베스팅닷컴 사이트 내에서만 의미가 있고, 다른 곳에서는 통하지 않는다.

Pair ID와 연결된 범용적인 '종목 코드(ticker, symbol)'을 알아내려면 모든 종목에 대해서 추가 정보 URL을 일일이 질의해야 한다.

즉, 인베스팅닷컴은 전세계 주식 종목에 대한 정보를 가장 광범위하게 제공하지만, 대신에 인베스팅닷컴 고유의 독자적인분류 코드로만 제공해서 범용성이 떨어지고, 일반적으로 사용되는 종목 코드로 변환하려면, 상당히 많은 추가 웹 질의를 해야한다.

 

이러한 범용성 문제가 없는 '야후! 금융'의 경우 제공하는 종목의 범위가 훨씬 좁은 문제가 있다.

광범위한 정보를 쉽게 수집하는 방법은 아직 못 찾았고, 편리성과 광범위함은 트레이드오프 선택 관계에 있는 것 같다.

 

주식 투자도 해외 분산이 필요한 것 같아서 이리저리 조사하던 중,

한국투자증권에서 Open API에서 지원되는 국가 중 '베트남'이 왠지 만만해 보여서,

베트남 주식 시장 데이터 수집을 시도하고 있다.

 

한국 증시가 '코스피', '코스닥'으로 나누어지는 것처럼,

베트남 증시는 '호치민(HOCHIMINH)', '하노이(HANOI)'으로 나누어져 있다.

 

'야후! 금융'의 경우 호치민 증시 종목 정보만 제공하는 듯 하고,

'인베스팅닷컴'의 경우 (종목코드 대신) 자체적인 pair_id 위주로 정보가 제공되어서 애를 먹다가,

'네이버 금융'을 이용하면 간편하게 베트남 주식 정보를 구할 수 있다는 것을 알게 되었다.

 

다음 페이지의 3번 항목을 참고해서 상장된 주식 종목 리스트를 구했다.

(R을 이용한 해외 주식용 데이터 수집 (hyunyulhenry.github.io))

 

간단히 요약하면 다음 URL에 대해서 <페이지 번호> 자리에 1,2,3,4..를 바꾸어 넣어가면서,

HTTP GET 질의를 하면 JSON 형태로 예쁘게 응답이 온다.

(1번째 URL은 호치민, 2번째 URL은 하노이)

https://api.stock.naver.com/stock/exchange/HOCHIMINH/marketValue?pageSize=60&page=<페이지_번호>
https://api.stock.naver.com/stock/exchange/HANOI/marketValue?pageSize=60&page=<페이지_번호>

현재 2022년 10월 기준 총 748개의 종목이 상장되어 있다.

투자 성과의 불균일성.

투자 이야기 2022. 9. 23. 11:43 Posted by UnHa Kim

https://youtu.be/Lv9cqvoNhdU

 

중장기 퀀트 전략의 백테스트 결과에 나오는 수익율을 실현하려면 강세장이 필요하다.

 

'주식 시장을 이기는 작은 책'에 나오는 그린 블란트의 말을 인용하자면,

 

하락장에서는 지수 평균의 95%에 해당하는 성적을 올린 반면, 

상승장에서는 지수 평균의 140%에 해당하는 성적을 올렸다.

 

즉, 하락장에서는 지수보다 더 깨지고, 상승장에서 더 벌면서 전체적으로 지수 평균을 능가한다.

 

그런데, 지수조차도 10년마다 대폭락을 하고, 2년마다 20% 이상의 중급 하락한다.

 

중장기 퀀트 전략 투자 성과는 이보다 더 심한 등락을 보인다는 것이다.

 

이러한 성과의 불균일성을 이해하지 못하면, 기나긴 하락장을 견뎌낼 수 없으며,

 

부진한 투자 성과에 실망해서 중도 포기하게 되고,

 

결과적으로 백테스트에 나온 수익율을 현실화 시킬 수 없다.

 

'투자 이야기' 카테고리의 다른 글

데이비드 라이언  (0) 2023.01.06
팩터 모델의 경쟁력.  (2) 2022.11.02
손절매 혹은 추세 지표의 심리적 장애.  (2) 2022.09.23
모멘텀 가속 지표  (0) 2022.06.10
5월에 도망가기 전략  (0) 2022.05.26

https://youtu.be/5WS1dLQwbT8

 

추세 지표를 이용해서 손절매를 하면 MDD(최대손실폭)을 낮출 수 있고, 샤프지수도 높일 수 있다.

 

역사상 가장 높은 수익율을 기록한 터틀 실험 창시자 '데니스 리치'도 추세 지표를 이용한 전략을 썼다.

 

추세 지표는 얼핏 쉬워보이지만, 장기간 지속하려면 심리적으로 큰 어려움이 따른다.

 

모든 추세 지표는 승률이 낮고 기댓값이 크다.

 

손절매 했더니 반등할 확률이 70%가 넘는다.

 

큰 손실은 피하게 해주지만,  작지만 잦은 손실을 입게 된다.

 

장기적 생존 가능성은 높여주지만, 단기적으로 수익율을 갉아먹고, 투자 기간 내내 심리적으로 힘들다.

 

이것은 손절매에만 해당되지 않고 추세 추종 매매에도 해당된다.

 

추세 추종 원자재 매매 전략으로 유명한 터틀 전략의 경우에도 추세 시그널에 따라서 매수하면

도로 하락할 (손절매하게 될) 확률이 70%가 넘는다.

 

수없이 많은 손절매 끝에 어쩌다가 큰 추세가 형성되면

그 극소수의 거래에서 엄청난 수익을 내면서

그동안의 자잘한 누적 손실을 커버하고 전체적으로 수익을 내는 형태이다.

 

이것이 승률이 낮고, 기댓값이 높다는 말의 현실 세계에서의 의미이다.

 

낮은 MDD와 높은 수익율은 그 댓가로 심리적 고통을 요구한다.

 

 

'투자 이야기' 카테고리의 다른 글

팩터 모델의 경쟁력.  (2) 2022.11.02
투자 성과의 불균일성.  (0) 2022.09.23
모멘텀 가속 지표  (0) 2022.06.10
5월에 도망가기 전략  (0) 2022.05.26
2022년 1월 20%대 중급 하락장을 경험한 후 소감.  (0) 2022.02.10

IntelliJ GoLand 2021.2 이후 버전에서는 테스트 케이스 함수명이 한글로 되어 있는 경우 제대로 인식하지 못하고,

테스트 실행 시 문제가 발생한다.

 

IntellJ에 기술 지원 문의를 했더니 다음과 같은 해결책을 알려주었다.

  • Help | Find Action. (한글 언어팩을 설치한 경우에는 '도움말(H) | 액션 찾기(F)'
  • 'Registry...' 를 타이핑 (한글 언어팩을 설치한 경우에는 '레지스트리...'. 따옴표는 제외하고 입력.)
  • 'go.run.processes.with.pty'를 찾아서 비활성화.

오랜 시간 묵었던 문제가 해결되었다.

'프로그래밍' 카테고리의 다른 글

RStudio에서 대입 기호(<-) 간편하게 입력하기  (0) 2023.09.23
Go언어 내장형 SQL 데이터베이스  (0) 2022.12.19
한국투자증권 REST API  (2) 2022.07.07
Go언어 에러처리  (0) 2016.11.02
Go언어 소개  (0) 2014.11.04

Julia 전용 Pluto 노트북 설치

데이터 분석 2022. 7. 21. 20:59 Posted by UnHa Kim

Jupyter 노트북은 Python을 필요로 하는 반면,

 

Pluto 노트북은 Julia 언어로 작성되어서 설치 용량도 작고 경량임.

 

Julia REPL 창에서 다음을 실행한다.

 

----------------------------------------------

import Pkg

Pkg.add("Pluto")

using Pluto

# Starts local Pluto notebook server
Pluto.run()

----------------------------------------------

'데이터 분석' 카테고리의 다른 글

무료 R언어 강의 영상  (0) 2023.06.26
윈저화 평균 (winsorized mean)  (0) 2023.04.28
Go언어로 작성된 백테스트 프레임워크  (0) 2021.12.18
Julia용 JupyterLab 설치  (0) 2021.12.06
과거 기업 재무정보  (0) 2019.08.28

한국투자증권 REST API

프로그래밍 2022. 7. 7. 12:41 Posted by UnHa Kim

그동안 증권사 API는 MS-윈도우에 특화된 DLL, OLE, OCX등의 형태로 제공되는 경우가 대부분이어서, 시스템 독립적인 프로그래밍 언어로는 (특히, 사용자가 많은 Java는 심각할 정도로) 매매 시스템을 작성하기 힘든 면이 많았다.

 

이 블로그도 Go언어로 증권사 API를 호출하기 위해서 복잡다단한 단계를 거치다가 만들게 되었다.

그런데, 이제 프로그래밍 언어에 독립적인 REST로 형태로 제공되는 API가 생겨서 그런 제약 사항이 사라졌다.

 

https://apiportal.koreainvestment.com

 

KIS Developers

잠시만 기다려 주세요

apiportal.koreainvestment.com

 

모멘텀 가속 지표

투자 이야기 2022. 6. 10. 01:37 Posted by UnHa Kim

한국 증시는 전세계에서 보기 드물게 모멘텀 팩터가 잘 안 먹히는 특이한 시장이다.

그런데, 대신증권 김지윤 연구원의 보고서에 따르면 2015년에 발표된  '모멘텀 가속화' 지표는 한국 증시에서도 유효하다고 한다.

드디어 한국에서도 먹히는 개선된 모멘텀 지표가 나온 것인가?


'모멘텀 가속화' 지표 강의 동영상 링크 : https://youtu.be/wujiLjjhsRM

 

두근거리는 마음으로 강의 동영상에 나온 링크를 타고 들어가서 논문을 읽어보니, 가속화된 모멘텀은 지속될 수 없다는(즉 급등은 급락을 부른다는) 논리는 충분히 납득이 되고, 백테스트 결과도 일관되고 다 좋다.

그런데 논문의 내용을 가져다 실제로 적용하려니 뭔가 설명이 부족한 느낌이다.

 

'모멘텀 가속화' 지표를 계산하려면, 과거 월별 수익율에 '지수 곡선'으로 표현되는 비중을 적용한다고 나와있지만, 정작 그 '지수 곡선'의 공식이 안 나와 있다.

논문에 나온 그래프를 캡쳐해서 윈도우 그림판에 불러들인 후, <Ctrl+R>, <Ctrl+G>키를 눌러서, '눈금자'와 '격자'를 활성화하면, 그래프에 나온 지수 곡선의 각 교차점을 상당히 정확하게 '측정'할 수 있다.

윈도우 그림판의 '눈금자'와 '격자'를 활성화 시킨 후 측정.

계수 측정치 : [1.00, 0.46, 0.06, -0.24, -0.41, -0.61, -0.73, -0.81, -0.88, -0.94, -0.96, -1.00]

그렇게 구한 계수를 최근 한달부터 과거 12개월까지 각 '월 수익율'에 곱한 후 합산하면 가속화 지표를 구할 수 있다.

 

'절대 모멘텀' 팩터과 '모멘텀 가속화' 팩터를 동일 비중으로 적용해서, 소액으로 운용해 볼 계획이다.

(데이터 분석 능력이 취약하여 백테스트는 생략... ㅠ.ㅠ)

한국 증시에서도 유효한 개량형 모멘텀 팩터를 찾은 것일까?

만약 유효하다면 두고두고 써먹을 수 있는 좋은 도구가 생긴 것이고, 혹여나, 잘 안 되더라도 시도는 해 봤으니 후회는 없을 것 같다.

 

<추가>

'모멘텀 가속화' 지표를 사용하는 목적은 '상승'하고 있는 종목 중에서 '과도한 급등 종목'을 걸러내기 위함이지 하락하고 있는 종목을 찾으려는 게 아니다.

그런데, 단기 절대 모멘텀이 낮아질수록 '가속화 지표'가 낮아지면서, 단기 절대 모멘텀이 하락 중(-)임에도 전체적인 추세 점수가 높은 경우가 발생하는 왜곡 현상이 발생한다.

그래서, 12개월 절대 모멘텀과 혼합해서 절대 모멘텀이 낮은 경우에는 가속화 지표가 낮아도 전체적인 추세 점수는 높아지지 않도록 보정해서 사용 중이다.

즉, '보정된_가속화_지표_등급 = (12개월_절대_모멘텀_등급 + 순수_가속화_지표_등급) / 2'으로 보정을 해야 왜곡 현상이 줄어든다.

논문에서는 우선 절대 모멘텀이 높은 상위 20%(5분위 1등급)을 선별한 후 그 중에서 가속화 지표가 낮은 종목을 다시 선별하는 식으로 2번에 걸쳐서 선별을 하면서 이런 문제를 피했는 데, 이 경우 코딩하기 복잡해 지니까 이런 식으로 보정했다.

 

 

대신증권 보고서 링크 : [대신증권 김지윤] 가속화 모멘텀 전략 (daishin.co.kr)

 

[대신증권 김지윤] 가속화 모멘텀 전략

 

money2.daishin.co.kr

 

원래 논문 : (PDF) Momentum, Acceleration, and Reversal (researchgate.net)

 

(PDF) Momentum, Acceleration, and Reversal

PDF | This paper studies the impact of accelerated stock price increases on future performance. Accelerated stock price increases are a strong... | Find, read and cite all the research you need on ResearchGate

www.researchgate.net