golongshort로 돌아가기

Claude로 빌드

Claude로 주식 트레이딩 AI를 만드는 여정 — 지난 3개월

백테스트 12번, 리서치 30번. 지난 3개월간 Claude와 함께 체계적인 트레이딩 시스템을 만들고, 정직하게 두들겨 본 여정 — 그리고 지금도 계속 발전시키는 중이다.


본론 전에, 성적표부터. 지난 3개월간 나는 Claude와 함께 체계적인 트레이딩 기계를 하나 만들었고, 그다음엔 대부분의 시간을 그게 안 된다는 걸 증명하는 데 썼다. 정직한 측정에서 살아남은 건 이거다. 18년 백테스트에서 이 시스템은 S&P의 총수익은 못 이긴다. 대신 **더 높은 Sharpe(0.61 vs 0.53)에, 낙폭은 3분의 1(-20% vs -55%)**로 굴러왔다. 그리고 2008년 금융위기에 S&P가 37% 빠지는 동안, 시스템은 거의 꿈쩍도 안 했다.

시스템 vs S&P 500 — $10,000의 성장과 낙폭, 2008–2026

회색(S&P)이 더 높이 끝난다. 돈은 더 번다. 빨강(시스템)은 그 수익 일부를 포기하는 대신 훨씬 덜 흘린다. 낙폭은 3분의 1, 게다가 시장이 반토막 난 2008년에 생채기 하나 거의 안 났다. 비밀 엣지가 아니라 바로 이 맞바꿈이 설계의 전부다. (이건 분산 북의 18년 백테스트다. 실제로 굴리는 버전은 국채 대신 매니지드 퓨처스 ETF를 쓰는데, 그건 18년치 기록을 만들기엔 너무 어리다.)

내가 만든 것. 시장을 이기는 봇은 아니다. 정직하게 돌린 테스트는 하나같이 "솔로한테 그런 건 없다"고 말했으니까. 대신 만든 건 자기가 뭔지에 대해 정직한 분산 시스템이다. 그리고 예쁜 백테스트에 안 속게 도와주는 도구. 지금 이 순간에도 페이퍼로 돌고 있고, 클라우드에서 알아서 리밸런싱하고 있다.

나는 퀀트가 아니다. 펀드에서 돈을 굴려본 적도 없다. 다들 하나씩 가지고 있다고 주장하는 그 '시장을 이기는 기계'가 나도 갖고 싶었다. 그래서 Claude한테 같이 만들자고 했고, 그다음 — 여기가 진짜 중요한데 — 그걸 정직하게 검증하는 것까지 같이 하자고 했다. 이 글은 사실상 그 검증에 관한 이야기다.

📋 이 글은 그 자체로 완전한 빌드 키트다. 아래에 파일도 명령어도 전부 있다. 다섯 개 파일을 복사하고 명령어를 실행하면, 똑같은 시스템이 그대로 생긴다. 전략, 정직성 검사, 페이퍼 트레이딩 루프, 그리고 항상 켜져 있는 클라우드 배포까지. 아니면 이 글 전체를 Claude Code에 붙여넣고 "이거 만들어서 lavela에 배포해줘" 라고 해도 된다.

"나 시장 이겼다" 류 콘텐츠는 대개 스크린샷 한 장에 강의 결제 링크가 전부다. 이 글은 그 반대다. 왜 어려운가에 대한 영수증, 그리고 당신한테 거짓말하지 않는 시스템. 증명할 코드까지 붙여서.

목차


1. 무덤 — 뭘 테스트했고, 각각 왜 죽었나

처음부터 열두 번 말아먹으려던 건 아니었다. 정직하게 재보기 전까지는 하나같이 될 것처럼 보였다. 그 간극 — 될 것 같음 vs 실제로 정직함 — 이게 이 글의 교훈 전부다.

시작은 내가 만든 봇 하나였다. 레시피는 교과서적인 ML 퀀트였다. S&P 500을 가져와서, 종목마다 펀더멘털·기술 지표를 스무 개쯤 뽑는다. 밸류에이션(PER, PBR, EV/EBITDA), 수익성(ROE, 마진), 성장성, 퀄리티(피오트로스키 점수, 발생액), 모멘텀. 그다음 그래디언트 부스팅 모델(LightGBM)한테 각 종목의 63일 선행수익률을 예측하게 시킨다. 그리고 분기마다 점수 높은 종목을 롱으로 담되, 변동성에 반비례해 비중을 주고, 전체를 10% 변동성 타깃에 맞춘다.

python
# the first bot I built — the one that turned out to be wrong import lightgbm as lgb FEATURES = ["pe_trailing", "pb", "ev_ebitda", "roe", "net_margin", "revenue_growth", "piotroski_score", "sloan_accruals", "momentum_score", "beta", "vix", "yield_spread"] # ~20 in all def rank_stocks(panel): # panel: S&P 500, one row per stock model = lgb.LGBMRegressor(n_estimators=300, learning_rate=0.05, num_leaves=31) model.fit(panel[FEATURES], panel["fwd_ret_63d"]) # target: 63-day forward return panel["score"] = model.predict(panel[FEATURES]) return panel.nlargest(20, "score") # long the top 20, inverse-vol weighted

워크포워드로 학습시키고, 하이퍼파라미터 변형을 수십 개 훑었더니, 그중 제일 좋은 게 헤드라인 Sharpe 0.60으로 백테스트됐다. 신났다. 그래서 Claude한테 감사를 맡겼다. 적대적 검증 네 개를 동시에. 그러자 그 0.60이 세 군데에서 한꺼번에 무너졌다.

그다음엔 사람들이 철석같이 믿는 걸 하나씩 다 테스트했다. 실제 비용 넣고, 룩어헤드 없이, 공정한 벤치마크로.

테스트한 것 정직한 결과
대형주 팩터 스크리닝 (가치/퀄리티/모멘텀) SPY 못 이김
내부자 군집 매수 (SEC Form 4) 손실 — 소형주 지수보다도 나쁨
추세추종 (매니지드 퓨처스) 분산용은 되지만, 시장을 이기진 못함
소형주 퀄리티-밸류 (시점 정합 SEC 데이터) 서류상 SPY 이김 — 근데 팩터 덕이 아니라 생존편향 + 사이즈 베타 덕
변동성 프리미엄 (풋 매도) 프리미엄은 진짜, 그래도 SPY한테 짐
마켓 뉴트럴 롱/숏 터짐 (−14%/년) — 반등장마다 숏이 스퀴즈

마켓 뉴트럴은 진짜 승자들(르네상스의 메달리온)이 쓰는 바로 그 메커니즘이다. 그런데 리테일 규모에서는 그냥 터진다. 두들겨 맞은 소형주를 숏하면, 2020년·2023년 반등에서 그것들이 로켓처럼 튀어오르고, 당신의 "뉴트럴" 북은 더 이상 뉴트럴이 아니게 된다. 메달리온이 이걸 견디는 건 수천 종목을 싼 대차비용에 피코초 단위 체결로 숏하기 때문이다. 메커니즘은 공개돼 있다. 잠겨 있는 건 그걸 실제로 돌아가게 만드는 기계다.

제일 많이 배운 순간은 이거였다. 상관관계 낮은 전략 몇 개를 묶었더니 Sharpe 0.81이 나왔다. 드디어, 시장을 이기는 뭔가. 그래서 정직하게 스트레스 테스트를 걸었다. 매일 대신 매월 리밸런스, 실제 거래·대차 비용. 그러자 0.81은 0.56으로 증발했다. 지루하기 짝이 없는 60/40 밑으로. 알고 보니 매일 공짜로 리밸런싱한 데서 나온 허상이었다.

결국 게임의 본질은 이거다. "아이디어가 있느냐"가 아니라 — 아이디어는 누구나 있다 — **"그 아이디어가 정직한 측정에서 살아남느냐"**이고, 답은 거의 항상 '아니오'다.


2. 딱 하나 중요한 도구 — 나를 안 속이는 법

이 글에서 딱 하나만 챙긴다면, 이걸 챙겨라. 솔로가 만들 수 있는 것 중 가장 레버리지가 큰 건 신호가 아니다. 어떤 신호가 가짜라고 말해주는 통계다.

핵심은 이 사실이다(Bailey & López de Prado). 5년치 데이터로 전략 45개쯤 돌리면, 인샘플 Sharpe는 1.0인데 진짜 아웃오브샘플 Sharpe는 0인 전략을 거의 반드시 하나는 건지게 된다. 많이 시도할수록, "승자"가 넘어야 하는 기준선도 같이 높아진다. **Deflated Sharpe Ratio(디플레이티드 샤프)**는 그 기준선을 눈에 보이게 만들어준다. 봇의 가짜 0.60도, 내 가짜 0.81도 잡아낸 게 바로 이거다. 그리고 아래 키트에서 당신이 제일 먼저 만들 파일이기도 하다.


3. 통째로 만들기 — 파일 다섯 개, 복붙, 실행

시스템 전체가 여기 다 있다. 파일 다섯 개, 프레임워크 없음, 다 합쳐 200줄쯤. 파이썬 되는 아무 컴퓨터에서나 돈다.

셋업

bash
mkdir honest-trader && cd honest-trader python -m venv .venv && source .venv/bin/activate pip install yfinance pandas numpy scipy

파일 1 — strategy.py (전략 전체)

유동성 좋은 ETF 네 개 — 미국 주식, 금, 원자재, 매니지드 퓨처스(추세) 펀드 — 로 짜는 리스크 패리티. 각 자산을 자기 변동성에 반비례해서 담아, 넷이 대략 비슷한 리스크를 지게 만든다. ML도, 알파 신호도, 레버리지도 없다.

python
# strategy.py import numpy as np, pandas as pd ETFS = ["SPY", "GLD", "DBC", "DBMF"] # equity / gold / commodities / trend PPY, VOL_LOOKBACK = 252, 60 def get_prices(period="8mo") -> pd.DataFrame: import yfinance as yf px = yf.download(ETFS, period=period, auto_adjust=True, progress=False)["Close"] return px[ETFS].ffill().dropna() def target_weights(prices: pd.DataFrame) -> pd.Series: """Risk-parity: weight each asset inversely to its trailing 60-day volatility.""" vol = prices.pct_change().iloc[-VOL_LOOKBACK:].std() * np.sqrt(PPY) inv = 1.0 / vol return inv / inv.sum()

파일 2 — honesty.py (자기 속임을 막는 수학 — 제일 중요한 파일)

Deflated Sharpe Ratio, 그리고 다중 검정 헤어컷(감쇠). 어떤 백테스트 결과든 당신이 시도한 변형 개수와 같이 여기 통과시켜 보면, "굉장한" 전략들이 95% 기준선에서 우수수 떨어진다. 내 결과들을 넣어봤더니 대부분 떨어졌다. 그게 이 도구가 제대로 일하고 있다는 신호다.

python
# honesty.py import numpy as np from scipy.stats import norm _EULER = 0.5772156649015329 def expected_max_sharpe(sr_std, n_trials): """Expected best Sharpe of N skill-less strategies (False Strategy Theorem). The more you try, the higher a lucky-best Sharpe will be by pure chance.""" if n_trials < 2 or sr_std <= 0: return 0.0 g = _EULER return float(sr_std * ((1 - g) * norm.ppf(1 - 1/n_trials) + g * norm.ppf(1 - 1/(n_trials * np.e)))) def deflated_sharpe_ratio(sr, T, skew, kurt, trial_sharpes): """P(the selected strategy's Sharpe is real) given how many you tried. < 0.95not distinguishable from the luckiest of your N random trials. sr/skew/kurt are per-period (daily); kurt is full (normal = 3).""" trials = np.asarray(list(trial_sharpes), float) sr0 = expected_max_sharpe(trials.std(ddof=1), len(trials)) # the deflated bar denom = np.sqrt(1 - skew*sr + ((kurt - 1)/4)*sr**2) z = (sr - sr0) * np.sqrt(T - 1) / denom return float(norm.cdf(z)), sr0 def haircut_sharpe(sr_annual, T_days, n_trials, ppy=252): """Bonferroni multiple-testing haircut → the Sharpe implied after correcting for how many strategies you tried. Often collapses toward 0.""" years = T_days / ppy t = sr_annual * np.sqrt(years) p_single = 2 * (1 - norm.cdf(abs(t))) p_adj = min(p_single * n_trials, 1.0) # Bonferroni hsr = norm.ppf(1 - p_adj/2) / np.sqrt(years) return float(hsr)

파일 3 — backtest.py (증명하고, 리밸런스 규칙을 찾는다)

이 파일은 정직한 일 두 가지를 한다. 하나, 리스크 패리티 북을 실제 비용까지 넣어서 백테스트한다. 둘, 얼마나 자주 리밸런스할지를 달력 방식 vs 드리프트-임계값 방식으로 쭉 훑어서 답을 낸다. 이때 제일 좋은 것만 골라 보여주는 게 아니라 전부 보여준다. ASSETS를 장기 히스토리 세트로 바꾸면 18년치 강건성을 눈으로 볼 수 있다.

python
# backtest.py import numpy as np, pandas as pd from honesty import deflated_sharpe_ratio RF, PPY, COST_BPS = 0.02, 252, 5.0 ASSETS = ["SPY", "TLT", "GLD", "DBC"] # long-history set (2008→) for robustness def load(start="2007-01-01"): import yfinance as yf px = yf.download(ASSETS, start=start, auto_adjust=True, progress=False)["Close"].ffill().dropna() rets = px.pct_change().dropna() vol = rets.rolling(60).std().shift(1) * np.sqrt(PPY) return rets, vol def run(rets, vol, policy, param): """policy='calendar' (param=days) or 'threshold' (param=max weight drift).""" w, out, turn_sum, n_reb = None, [], 0.0, 0 for i, d in enumerate(rets.index): if vol.loc[d].isna().any(): out.append(0.0); continue target = (1/vol.loc[d]) / (1/vol.loc[d]).sum() do = (w is None) or ((i % param == 0) if policy == "calendar" else float((w - target).abs().max()) > param) cost = 0.0 if do: if w is not None: t = float((target - w).abs().sum()); turn_sum += t; cost = t*COST_BPS/1e4 w = target; n_reb += 1 out.append(float((w * rets.loc[d]).sum()) - cost) g = w * (1 + rets.loc[d]); w = g / g.sum() # drift between rebalances s = pd.Series(out, index=rets.index).loc[vol.notna().all(axis=1)] nav = (1 + s).cumprod(); r = s.to_numpy(); yrs = len(s)/PPY return dict(cagr=nav.iloc[-1]**(1/yrs)-1, sharpe=(r.mean()-RF/PPY)/r.std(ddof=1)*np.sqrt(PPY), maxdd=((nav/nav.cummax())-1).min(), reb_yr=n_reb/yrs) if __name__ == "__main__": rets, vol = load() print(f"{'policy':22s}{'CAGR':>7s}{'Sharpe':>8s}{'MaxDD':>8s}{'reb/yr':>8s}") for name, pol, par in [("calendar daily","calendar",1), ("calendar monthly","calendar",21), ("calendar quarterly","calendar",63), ("threshold 5%","threshold",0.05), ("threshold 10%","threshold",0.10)]: m = run(rets, vol, pol, par) print(f"{name:22s}{m['cagr']*100:>6.1f}%{m['sharpe']:>8.2f}{m['maxdd']*100:>7.1f}%{m['reb_yr']:>7.0f}")

실행:

bash
python backtest.py
text
policy CAGR Sharpe MaxDD reb/yr calendar daily 7.3% 0.59 -20.2% 252 calendar monthly 7.6% 0.62 -20.2% 12 calendar quarterly 7.5% 0.60 -19.7% 4 threshold 5% 7.5% 0.61 -19.9% 7 threshold 10% 7.8% 0.63 -18.9% 2

여기서 교훈이 두 개 나온다. 하나, 덜 거래할수록 이긴다. 매일 거래가 제일 나쁘다 — 아무것도 아닌 데 비용만 낸다. 오히려 가장 뜸하게 거래하는 정책들이 위로 올라온다. 둘, 전체가 강건하다. 모든 정책에서 Sharpe가 0.59~0.63 사이다. 운 좋은 주기 하나에 몰래 기대고 있는 게 아니라는 뜻이다. 스위트 스팟은 이거다. 매일 확인하되, 어떤 비중이 5% 넘게 벌어졌을 때만 거래한다. 거래 횟수는 절반(연 7번쯤)인데 월간 수준의 Sharpe가 나온다. "매일 지켜봐라"는 직관은 맞다. "매일 거래해라"는 직관은 틀렸다.

파일 4 — paper_sim.py (전방 검증 — 실제 가격, 가상 돈)

백테스트는 이제 바닥까지 짜냈다(게다가 두 번은 가짜였다). 지금부터 정직한 새 정보는 오직 앞으로 쌓이는(forward) 데이터뿐이다. 이 파일은 실제 가격으로 가상의 $100k를 추적하고, 5% 임계값으로 리밸런스하고, 돌 때마다 로그를 남긴다. 매일 돌려라. 대부분의 날은 그냥 지켜보기만 하고, 어쩌다 뭔가 5%를 넘겨 벌어진 날에만 리밸런싱한다.

python
# paper_sim.py import json, argparse from datetime import datetime, timezone from pathlib import Path from strategy import ETFS, get_prices, target_weights STATE, LOG = Path("paper_sim_state.json"), Path("paper_log.jsonl") INIT_CASH, DRIFT, COST_BPS = 100_000.0, 0.05, 5.0 def load_state(): if STATE.exists(): return json.loads(STATE.read_text()) return {"cash": INIT_CASH, "positions": {t: 0.0 for t in ETFS}, "inception_nav": INIT_CASH} def peak(nav): p = nav if LOG.exists(): for ln in LOG.read_text().splitlines(): try: p = max(p, json.loads(ln)["nav"]) except Exception: pass return p def main(): ap = argparse.ArgumentParser() ap.add_argument("--status", action="store_true"); ap.add_argument("--reset", action="store_true") a = ap.parse_args() if a.reset: STATE.write_text(json.dumps({"cash": INIT_CASH, "positions": {t: 0.0 for t in ETFS}, "inception_nav": INIT_CASH})); print("reset to $100k"); return prices, weights = get_prices().iloc[-1], target_weights(get_prices()) s = load_state(); pos, cash = {t: s["positions"].get(t, 0.0) for t in ETFS}, s["cash"] nav = cash + sum(pos[t] * prices[t] for t in ETFS) cur = {t: (pos[t]*prices[t]/nav if nav else 0) for t in ETFS} drift = max(abs(cur[t] - weights[t]) for t in ETFS) dd = nav / peak(nav) - 1 print(f"\n{datetime.now(timezone.utc):%Y-%m-%d} NAV ${nav:,.0f} since-start {nav/s['inception_nav']-1:+.1%} drawdown {dd:+.1%}") for t in ETFS: print(f" {t:5s} target {weights[t]*100:5.1f}% current {cur[t]*100:5.1f}% drift {(cur[t]-weights[t])*100:+5.1f}%") print(f" max drift {drift*100:.1f}% (threshold {DRIFT*100:.0f}%)") if a.status: return rebalanced = False if drift > DRIFT or all(v == 0 for v in pos.values()): new = {t: nav * weights[t] / prices[t] for t in ETFS} cost = sum(abs(new[t]-pos[t])*prices[t] for t in ETFS) * COST_BPS/1e4 cash, pos, nav, rebalanced = -cost, new, nav - cost, True print(f" ⟳ rebalanced (cost ${cost:,.0f}) → NAV ${nav:,.0f}") else: print(" ✅ within 5% → monitor only, no trades") s["cash"], s["positions"] = cash, pos STATE.write_text(json.dumps(s)) with open(LOG, "a") as f: f.write(json.dumps(dict(ts=datetime.now(timezone.utc).isoformat(), nav=nav, drift=round(drift, 4), rebalanced=rebalanced)) + "\n") if __name__ == "__main__": main()

돌리는 법(첫 실행 때 $100k를 배분하고, 그다음부터는 추적만 한다):

bash
python paper_sim.py # daily: monitor, rebalance only if drifted >5% python paper_sim.py --status # NAV, drawdown, drift — no changes
text
2026-07-02 NAV $100,000 since-start +0.0% drawdown +0.0% SPY target 27.7% current 0.0% drift -27.7% ... max drift 37.9% (threshold 5%) ⟳ rebalanced (cost $50) → NAV $99,950

이제 정직한 부분을 대놓고 말하겠다. 자기를 과대포장하는 시스템은 그 자체로 거짓말이니까. 이건 강세장에서 S&P를 못 이긴다. 일부러 뒤처지게 만들어졌다. 대신 주식이 안 될 때 이긴다. 금리 쇼크, 인플레이션, 위기 같은 때. 18년 백테스트에서 2008년 금융위기 때 S&P가 37% 빠지는 동안 이건 거의 그대로였고, 낙폭도 꾸준히 시장의 3분의 1쯤이다. 이건 국면 베팅이고 더 부드러운 승차감이지, 공짜 알파가 아니다.


4. 자동화 — plist 하나면 알아서 돈다

Mac이라면 launchd 에이전트가 평일 장 마감 후마다 시뮬을 알아서 돌려준다. 당신이 손댈 건 없다. 아래를 ~/Library/LaunchAgents/com.honesttrader.papersim.plist로 저장하고(경로 두 개만 고치고), launchctl load 하면 끝이다.

xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"><dict> <key>Label</key><string>com.honesttrader.papersim</string> <key>ProgramArguments</key> <array> <string>/ABSOLUTE/PATH/honest-trader/.venv/bin/python</string> <string>/ABSOLUTE/PATH/honest-trader/paper_sim.py</string> </array> <key>WorkingDirectory</key><string>/ABSOLUTE/PATH/honest-trader</string> <key>StartCalendarInterval</key> <array> <dict><key>Weekday</key><integer>1</integer><key>Hour</key><integer>18</integer></dict> <dict><key>Weekday</key><integer>2</integer><key>Hour</key><integer>18</integer></dict> <dict><key>Weekday</key><integer>3</integer><key>Hour</key><integer>18</integer></dict> <dict><key>Weekday</key><integer>4</integer><key>Hour</key><integer>18</integer></dict> <dict><key>Weekday</key><integer>5</integer><key>Hour</key><integer>18</integer></dict> </array> <key>StandardOutPath</key><string>/ABSOLUTE/PATH/honest-trader/sim.log</string> <key>StandardErrorPath</key><string>/ABSOLUTE/PATH/honest-trader/sim.log</string> </dict></plist>
bash
launchctl load ~/Library/LaunchAgents/com.honesttrader.papersim.plist launchctl start com.honesttrader.papersim # test it now tail sim.log

이제 알아서 돈다. 노트북이 늘 켜져 있는 건 아니라는 사실을 떠올리기 전까지는. 머신이 잠든 날을 건너뛴 트레이딩 로그는 차라리 없느니만 못하다. 마지막 파트가 푸는 게 바로 그 문제다.


5. lavela에 올리기 — 내 노트북 없이도 굴러가게

솔직히 이 파트가 제일 겁났고, 그래서 제일 안 건드렸다. 나는 서버를 안 굴린다. 클라우드 크론이니 TLS니 시크릿이니 배포 파이프라인이니, 배우고 싶지 않았다. 나는 그냥 이 매일 도는 잡이 어딘가 항상 켜져 있는 곳에서, 몇 달러에, 계속 돌기만 하면 됐다.

🗣️ 내가 부탁한 것

"이거 클라우드에서 돌게 해줘. 내 노트북이 깨어 있든 말든 상관없게. 그리고 쉽게."

그게 부탁의 전부였다. 거기서 Claude가 lavela를 추천했다. 발상은 *"DevOps를 통째로 대체한다"*이다. lavela를 Claude Code에 MCP 서버로 붙여두면, 그때부터는 Claude가 컴퓨트, 스케줄링, 시크릿을 툴 콜로 직접 프로비저닝한다. 당신은 DevOps를 만질 일이 없다.

그래서 내가 한 일은 딱 두 개였다. 콘솔에서 가입하고(https://console.lavela.dev), 한 줄 실행한 것.

bash
npx @lavela/cli connect

브라우저가 열리고 → 로그인 → Authorize & connect. CLI가 토큰을 당신의 Claude Code 설정에 바로 써넣는다. URL에도, 셸 히스토리에도, 대화창에도 절대 안 뜬다. Claude Code를 새로 켜면(또는 /mcp → Reconnect) mcp__lavela__* 툴이 살아 있다. 그다음은 "매일 도는 페이퍼 시뮬 잡을 lavela에 배포해줘" 한마디면 끝이다.

🤖 Claude가 한 것

그리고 이건 소리 내서 말할 만하다. 언젠가 이 위에 유료 제품을 얹더라도, lavela는 당신이 번 돈의 0%를 가져간다. 매출은 전액 당신한테 정산되고, lavela는 당신 매출이 아니라 자기가 돌리는 컴퓨트에서 돈을 번다. 개인 트레이딩 로그야 팔 게 없지만 — 내 취미를 배포한 그 한 줄이, 진짜 제품을 배포할 바로 그 한 줄이다.

정리하면 이렇다. "내 Mac이 깨어 있을 때만 도는 스크립트"에서 "클라우드에서 24시간, 계속, 몇 달러에 알아서 도는 잡"으로 넘어갔다. 그러는 데 내가 한 건 명령어 하나 실행하고 승인 한 번 누른 게 전부다. 어려운 인프라는 내가 하나도 모르는 부분이고, 동시에 내가 안 해도 됐던 부분이다.


3개월 차 — 여정은 아직 진행 중

나는 시장을 이기는 기계를 원했다. 3개월이 지난 지금, 아직 그런 건 없다 — 대신 당신한테 그걸 팔겠다는 사람들도 왜 못 가졌는지 정확히 알게 됐다. 나는 환상을 쫓는 걸 그만두고, 실제로 믿을 수 있는 걸 만들기 시작했다. 그리고 지금도 매주 조금씩 다듬고 있다.

대신 내 손에 남은 건 그 환상보다 낫다. 자기가 뭔지에 대해 정직한, 단순한 분산 시스템. 내가 나한테 거짓말하는 걸 잡아내는 통계. 그리고 나 없이도 그걸 계속 돌려주는 클라우드 잡. 이건 나를 부자로 만들어주진 않는다. 대신 있지도 않은 엣지를 쫓다가 나를 터뜨리지도 않는다. 액티브 트레이더의 약 93%가 결국 나가떨어진다는 걸 생각하면, 그게 진짜 이기는 거다.

이 글에서 딱 하나만 만든다면, 검증을 만들어라. honesty.py, 생존편향 없는 데이터, 정직한 비용. 전략이야 초보자도 복사할 수 있는 ETF 네 개다. 진짜 희귀한 건 나를 안 속이는 규율이고, 그게 프로가 실제로 가진 것 중 당신도 똑같이 가질 수 있는 유일한 거다.

📋 파일 다섯 개, 명령어 네 줄, 배포 한 번. 아니면 이 글 전체를 Claude Code에 붙여넣고 "이거 만들어서 lavela에 배포해줘" 라고 해라. 똑같은 시스템, 똑같은 정직성 검사, 똑같이 항상 켜진 클라우드 잡이 생긴다. 그리고 운이 좋으면, 똑같은 겸손함까지.

이 글 좋아요

댓글

계정 불필요. 댓글은 공개되니 예의를 지켜주세요.