막힌 설정을 고친 기록과, 통념을 직접 재본 결과입니다
맥미니 한 대로 한국 주식시장의 공시와 뉴스를 모아 가설을 세우고 재봅니다. 본문의 수치는 발행 전에 데이터베이스와 자동 대조합니다. 자세한 규칙은소개에 있습니다.
막혔던 것을 고친 기록14편
에러 메시지와 증상에서 시작해 원인과 해결을 먼저 적었습니다.
최근 launchctl bootstrap으로 LaunchAgent 등록하기 — KeepAlive가 크래시를 75초 만에 살린 plist
재보고 답한 것9편
RSI 과매수, 볼린저 밴드 압축처럼 널리 쓰이는 통념을 우리 데이터로 재본 결과입니다.
연구 기록1편
글에 쓴 숫자를 원본 데이터베이스와 대조하는 장치를 어떻게 만들었는지 적었습니다.
막혔던 것을 고친 기록
에러 메시지와 증상에서 시작해 원인과 해결을 먼저 적었습니다. launchd·MLX·n8n·Cloudflare·DART·PostgreSQL 에서 직접 막힌 자리이고, 공식 문서 첫 페이지에 답이 있는 것은 쓰지 않았습니다.
launchctl bootstrap으로 LaunchAgent 등록하기 — KeepAlive가 크래시를 75초 만에 살린 plist
launchctl load 대신 bootstrap으로 LaunchAgent를 등록하는 세 줄과, KeepAlive가 Metal 메모리 부족 크래시를 75초 만에 다시 띄운 실측. plist 안에서 ~는 안 풀리고, 파이썬 서버 로그는 stderr 쪽에 다 쌓입니다.
launchctl kickstart로 재시작했는데 설정이 그대로일 때 — plist는 bootout 뒤 bootstrap
launchctl kickstart -k로 재시작해도 고친 plist는 반영되지 않습니다. kickstart는 plist를 다시 읽지 않고, 반영하려면 bootout 뒤 bootstrap입니다. ps -o command=으로 인자를 확인하는 법과 32B 모델 재시작 한 번의 값 5분 57초.
맥미니 로컬 LLM 상시 운영 설정 — mlx_lm.server를 launchd로 149일 굴린 plist
mlx_lm.server를 launchd로 149일 돌리며 README에 없던 다섯 가지 — bootstrap과 KeepAlive, plist에는 셸 환경이 없다, kickstart는 plist를 다시 읽지 않는다, KV 캐시 상한 두 줄, 메모리는 ps가 아니라 footprint(23MB 대 23GB).
LLM 분류가 틀리면 모델 탓일까 — 범인은 LLM 후처리의 정규식 188건
실적이 43% 줄었다는 공시가 어닝 서프라이즈로 분류돼 있었습니다. LLM 출력을 먼저 의심했지만 태그도 방향도 정확했습니다. 범인은 그 뒤에서 도는 정규식 정규화 계층의 first-match-wins였고, 188건이 같은 경로로 뒤집혀 있었습니다.
wrangler Missing entry-point 오류 — Pages와 Workers 동명
GitHub PR의 Cloudflare Workers Builds 체크가 wrangler Missing entry-point로 실패하는데 Pages 배포는 성공한다면, 같은 레포에 Workers와 Pages가 같은 이름으로 둘 연결된 상태입니다. 원인, 해제 방법, 그리고 4일 동안 틀렸던 판단.
DART 공시 시간이 전부 09시일 때 — rcept_dt에는 시각이 없다
OpenDART의 rcept_dt에는 시각이 없습니다. 변환 단계가 09:00을 기본값으로 채워 공시 8만여 건의 발행 시각이 100% 오전 9시가 됐습니다. DART 공시 시간을 확인하는 법과, 이 '그럴듯한 값'이 결측보다 위험한 이유. 룩어헤드 편향은 발견되지 않습니다.
PostgreSQL array_length가 빈 배열에서 0이 아니라 NULL인 이유 — cardinality와의 차이
PostgreSQL에서 array_length(빈 배열)은 0이 아니라 NULL이라 WHERE 조건에서 조용히 빠집니다. 데이터만 백필하고 코드를 안 고쳐 나흘 만에 같은 상태로 돌아온 버그와, 석 달간 보이지 않았던 이유.
Cloudflare Tunnel과 Access Service Token으로 Vercel에 집 서버 붙이기
Vercel의 Next.js에서 Cloudflare Access 뒤 API를 fetch하면 401이 아니라 302와 로그인 HTML이 오고, 에러는 Unexpected token '<' JSON 파싱 실패로 위장합니다. Cloudflare Tunnel과 Access Service Token으로 포트 개방 없이 집 서버를 붙인 설정.
launchd cron이 command not found로 죽을 때 — PATH가 없다
launchd 잡이 exit 127, node: command not found로 8일간 실패했는데 로그 파일은 매번 생겼습니다. launchd는 ~/.zshrc를 읽지 않아 nvm의 PATH가 없습니다. plist에 PATH를 주는 법과, 버전 경로를 박는 해법이 다음 실패를 예약하는 이유.
Cloudflare Analytics CLS 점수가 나쁨일 때 — Cumulative Layout Shift 검산법
Cloudflare Web Analytics가 CLS를 '나쁨'으로 표시할 때 P50부터 P99까지 전부 1인 이유는 비콘이 Math.ceil로 값을 올림하기 때문이었습니다. 대시보드 CLS 점수를 믿기 전에 확인할 것과 실제 CLS를 재는 법.
Astro data-store.json — 삭제한 글이 빌드에 계속 남는 이유
Astro에서 삭제한 글이 빌드 결과와 sitemap에 계속 남는다면 원인은 node_modules/.astro/data-store.json입니다. .astro/와 dist/를 지워도 안 사라지는 이유를 재현하고, 해결책 세 가지와 내 프로젝트가 이 상태인지 확인하는 법을 정리했습니다.
거래일 계산을 달력으로 하면 — 금요일 신호가 사라진다
이전 거래일을 '어제'로 계산한 코드 한 줄이 넉 달 동안 신호 57건 중 13건(22.8%)을 버렸습니다. 금요일 10건, 연휴 직전 3건, 오류 로그 0줄. 달력일과 거래일을 혼동한 거래일 계산 버그를 찾고, 재고, 고친 기록.
mlx_lm server 메모리가 계속 늘 때 — MLX KV cache 상한 설정
mlx_lm 서버가 64GB 맥미니 메모리를 고갈시켰는데 ps의 RSS는 0.31GB였습니다. 원인은 상한 없는 KV 캐시. RSS와 실제 점유가 다른 이유, mlx kv cache 제한 설정, 그리고 '느린 게 정상'이라는 결론까지.
n8n import workflow 뒤 실행이 안 될 때 — n8n CLI의 active 컬럼 하나
n8n import:workflow로 배포하면 워크플로가 비활성화됩니다. CLI에 활성화 옵션이 없고, active 컬럼 하나가 하루 409회 스케줄 전체를 끕니다. n8n import 뒤 실행이 안 될 때 확인할 스위치 두 개.
재보고 답한 것
RSI 과매수, 볼린저 밴드 압축, 벤치마크 선택처럼 널리 쓰이는 통념을 우리 데이터로 재본 결과입니다. 기각한 가설과 번복한 판단도 지우지 않습니다.
포트폴리오 벤치마크를 바꾸면 알파 부호가 뒤집힌다 — 벤치마크 수익률 계산법
같은 포트폴리오의 초과수익이 벤치마크를 코스피200에서 보유 비중 혼합 지수로 바꾸자 −31.9%p에서 +7.6%p로 뒤집혔습니다. 벤치마크 수익률 선택이 백테스트 알파의 부호를 바꾸는 과정과, 새 자도 안심할 수 없는 이유.
LLM API 비용 줄이기 — 10만 건 분류에 $125 쓴 3단 라우팅
공시·뉴스 104,659건 분류에 API 비용 $125.66. 규칙→로컬 LLM(MLX)→상용 API 3단 라우팅으로, 전부 API였을 때의 $786 대비 약 16%입니다. LLM API 비용을 줄인 구조, 규칙이 59.3%를 거르는 이유, 넉 달 뒤 찾은 빠진 규칙 하나.
퀀트 백테스트 사전 등록이 막지 못하는 것 — 3/3 통과 뒤 기각
사전 등록한 합격 기준 3개를 모두 통과한 결과를 채택하지 않았습니다. 강건성 검사에서 걸렸고, 발견 연도의 데이터는 아웃오브샘플이 아니었습니다. 퀀트 백테스트에서 사전 등록만으로 해석 오류를 못 막는 이유와 고친 등록 양식.
RAG 없이 돌리면 답변 품질이 떨어질까 — 4주 A/B 결과
RAG(임베딩 검색)를 끄고 4주 A/B로 비교했습니다. 결론은 유지인데 근거는 '좋아졌다'가 아니라 '불리한 조건에서도 근거검증 통과율이 내려가지 않았다'는 관측입니다. 비열등성 검정이 아닌 이유, 선택 편향이 만드는 논증, 남은 한계 세 가지.
백테스트를 스스로 오염시키는 5가지 실수
측정하려고 만든 장치가 측정 대상과 연결되는 자기 오염의 다섯 형태입니다. 벤치마크 ETF를 종목으로 매수, 자기 판단을 근거로 쓰기, 가설을 낳은 데이터로 검증하기. 백테스트에서 오염을 찾는 세 가지 질문.
투자 유니버스와 관측 유니버스를 분리해야 하는 이유
수익률을 못 재는 종목 263개를 종목 마스터에 넣으면 관측 대상이 투자 대상이 됩니다. 모멘텀 스크리너가 자기 벤치마크 ETF를 매수한 사고로 배운, 투자 유니버스와 관측 유니버스를 분리해야 하는 이유.
코스닥 벤치마크를 코스피200으로 잡으면 생기는 일 — 코스피 지수와 코스닥 지수 차이
코스닥 종목의 초과수익을 코스피200 지수로 계산하면 두 지수가 79.9%p 벌어진 기간에 측정값 전체가 왜곡됩니다. 코스피 지수와 코스닥 지수의 차이를 벤치마크에 반영해 전건 재계산한 교정 기록과, 교정 뒤에도 남은 문제.
볼린저 밴드 스퀴즈는 정말 신호일까 — 4주 사전 등록 백테스트
볼린저 밴드 스퀴즈(밴드폭 압축) 뒤 이벤트 수익이 더 크다는 가설을 판정 기준을 미리 고정하고 4주 뒤 기각했습니다. 볼린저밴드 스퀴즈 전략을 백테스트할 때 사전 등록이 무엇을 바꾸는지에 대한 기록.
RSI 과매수 70이면 정말 내릴까 — RSI 지표와 과매수 과매도 오해 3가지
RSI 70 이상이면 과매수라 곧 내린다는 통념을 실제 종목 수치로 확인합니다. RSI 지표(14일 단순평균)가 측정하는 것, 같은 RSI가 종목마다 다른 뜻인 이유, RSI 과매수·과매도만으로 부족한 이유 세 가지.
연구 기록
글에 쓴 숫자를 원본 데이터베이스와 대조하고 비공개 값이 새어나가지 않게 막는 장치를 어떻게 만들었는지에 대한 기록입니다.
블로그 원고의 숫자를 DB와 자동 대조하고 유출을 막는 CI
블로그 원고의 숫자를 PostgreSQL과 자동 대조하고, 맞아서 문제인 값(비공개 파라미터)은 정규식 스캐너로 막는 발행 파이프라인입니다. 검증→제거→스캔→쓰기 순서가 왜 그래야 하는지, 내가 만든 가드가 가드가 아니었던 이유.