일본의 전설적 개인투자자 BNF의 매매법에 흥미가 생겼다.아르바이트로 모든 우리돈 1600만원으로 주식투자를 시작해 4000억원을 벌었다고 한다.
지금은 결혼해 하와이에 산다나.... 딸도 있다는거 같고...하와이에 간다면 꼭 한번 뵙고 싶다.
BNF는 주가가 엔벨로프 하단에 닿을 때마다 집중적으로 매수해 큰 성공을 거뒀다고 알려져 있다.
하지만 종목마다 최적의 편차(deviation)가 다르다 보니, 일일이 최적값을 찾는 게 여간 어려운 일이 아니다. BNF는 천재 트레이더라 최적의 편차를 찾아서 거래한거 같다. 그 최적의 편차는 업종마다 종목마다
다른데 BNF가 최적 편차가 얼마인지는 공개하지는 않았다. 일반인에게는 분명 넘사벽의 장벽이 있다.
BNF는 닛케이 주식을 매일 700~800 종목을 하나하나 살펴보고 그 종목들의 차트 움직임이 모두 머리속에 있다고 한다. 닛케이에는 코스피와는 비교할 수 없을 만큼 글로벌 시장을 이끄는 거대 대기업들이 대거 포진해 있다.
한국에서 똑같이 BNF처럼 700개 이상의 종목을 엔벨로프 방식으로 하다간 큰 코 다친다. 오만가지 개잡주가 다 걸리고 변동성에 세력들 장난질에, 아무리 BNF라도 한국에서 일본처럼 700개 이상 종목으로 하라고 했으면 안됐을듯.
한국 주식시장은 일본보다 전체 시가총액도 작고, 거래량이 적은 소형주와 개잡주가 많아 데이터 노이즈가 심하다.그래서 일단 코스피·코스닥 통합 시총 상위 1위부터 200위까지만 대상으로 삼아봤다.
거래량이 충분해 패턴이 좀 더 뚜렷하고 1위~200위라면 상당한 신뢰감을 확보한 회사들이라고 생각된다. 삼성전자, SK하이닉스, 네이버, 카카오, LG, 한화~~등등... 이런 회사들이면 해볼만 하다고 생각 했다.
아침에 눈을 뜨자마자 먼저 시가총액 1위부터 200위 종목 리스트를 웹에서 자동으로 스크래핑하는 코드를 돌려봤다. 번거롭게 일일이 종목을 골라 담지 않아도 되니 얼마나 좋은가.
오전 내내 이동평균선 기반으로 ±2%에서 ±10%까지 다양한 편차 값을 스캔하며 Envelope 밴드를 계산해 보는 작업을 이어갔다. 화면에 밴드가 차례차례 그려질 때마다, 제법 괜찮은거 같다.
점심을 먹고 나서는 지난 2년간 주가가 하단 밴드를 터치했던 횟수를 세고, 실제로 반등에 성공한 비율을 계산하는 로직을 점검했다. 지지선 역할을 하는 구간에서 주가가 어떻게 움직였는지 하나하나 들여다보니 시간 가는 줄을 몰랐다.
오후에는 터치 대비 반등 성공률을 쭉 정리한 뒤, 가장 높은 반등율을 기록한 편차 값을 자동으로 추천해 주는 기능을 테스트해 봤다. 각 종목마다 최적 편차를 한눈에 보여주고 있다.
저녁 시간에는 오늘 모은 모든 결과를 엑셀 파일로 저장해 봤다. 엑셀 파일을 열어서 데이터가 가지런히 정리된 모습을 보니, 실험이 상당한 진전을 보이고 있는듯하다.
이 실험은 모듈 로딩 시점에 datetime 객체로 정의된 EXPIRY_DATE와 현재 시점을 비교해, 만료 여부를 tkinter 숨김 윈도우와 messagebox 조합으로 알린 뒤 sys.exit를 통해 즉시 프로세스를 종료한다.
<BNF 엔벨로프 프로그램 구동화면. 종목명은 특정 회사를 홍보하는것 같아 노출시키지 않았다.>
warnings.simplefilter를 통해 FutureWarning 카테고리를 전역 억제함으로써, pandas·numpy 내부 버전 불일치로 인한 디프리케이션 노티스를 사전 차단한다.
calculate_envelope 함수는 pandas.DataFrame 복제본에 대해 rolling(window=ma_period).mean()으로 이동평균(MA)을 산출하고, deviation 파라미터 연산을 통해 상·하단 밴드(MA×(1±δ))를 벡터화 처리하여 NaN 제거 후 반환한다.
analyze_stock 루틴은 lookahead 윈도우 내에서 iloc 인덱싱으로 하단 밴드 접촉 시점을 집계(touches)하고, numpy any 연산으로 후방 N개 봉의 종가 반등 여부를 확인해 rebounds를 카운팅하며, 이를 통해 반등률(rate=rebounds/touches×100)을 산출한다.
get_top_200 유틸은 API로 코스피·코스닥 종목 메타데이터를 취합하고, dropna(axis=1, how='all')로 불필요 열을 제거한 뒤 Marcap 컬럼을 기준으로 내림차순 정렬하여 상위 200개 종목 코드·명칭 DataFrame을 생성한다.
run_analysis는 threading.Thread 기반 비동기 워커 함수를 spawn하여, datetime 연산으로 past date 기간을 산정하고 numpy.arange(0.02,0.11,0.01)로 편차 리스트를 생성한 뒤, fdr.DataReader로 시계열 OHLCV를 조회하여 analyze_stock을 반복 호출하며 최적 조건을 실시간으로 tkinter Treeview에 insert하고 status_label.config로 진행 상태를 갱신한다.
전역 변수 final_result에 수집된 dict 리스트를 pandas.DataFrame으로 변환해 저장하며, save_to_excel는 tkinter filedialog로 경로 입력을 받아 pandas.ExcelWriter 컨텍스트 매니저로 최종 xlsx를 덤프한다.
GUI 레이아웃은 tkinter root.geometry로 static으로 지정하고, ttk.Treeview 컬럼 헤더·너비를 수동 설정한 후 LabelFrame·Frame·Button 위젯을 조합해 단일 창 내에서 클릭 한두 번으로 일련의 분석 절차를 수행하도록 구성돼 있다.
이런 구조적 설계가 향후 유지보수를 쉽게 할수가 있다.
오늘은 데이터 전처리부터 잡음 제거에 이르는 파이프라인 구상을 시작했다. 먼저 Wavelet Transform을 적용해 시계열을 고·중·저·주파수 대역으로 분해하기로 했다.
단기적인 가격 변동에 휘둘리지 않으면서도 장기 추세를 놓치지 않으려면, 각 대역별 Envelope 밴드를 따로 계산해야겠다고 메모했다. 이상치 탐지에는 Isolation Forest를 써보고, 극단치는 로컬 회귀로 스무딩 처리하는 로직도 추가하려고 한다.
다변량 Envelope 모델 중 첫 번째 버전으로, 베이지안 업데이트 기반 ‘Dynamic Adaptive Envelope’을 설계했다. 실시간으로 터치-반등 데이터를 학습하면서 deviation 파라미터를 계속 보정하는 방식인데, 과거 데이터와 새로 수집된 데이터를 결합해 반영하는 흐름을 그려놨다.
Regime-Switching은 HMM으로 시장 상태(상승·하락·횡보)를 분류해서, 상태별로 밴드를 달리 적용하는 구조로 설계도 그려볼 생각이다.
이 모든 가설 수립과 수학적 검증, 그리고 코드 구현을 수행한 이유는 BNF 매매법에 흥미가 있기 때문이다.
BNF가 엔벨로프 밴드와 같은 간결한 원리로 시장의 복잡함을 해석해낸 방식은
나에게 영감을 주었고, 이 방정식과 최적화 과정을 설계하는 원동력이 되었다.
나는 BNF 매매법을 수학을 이용하며 해석해 봤는데 BNF는 수학보다는 천부적인 감각으로 했을꺼 같다.