목돈 · S&P500 · 실측 재현 페이지
퇴직금·적금 만기처럼 한 번에 생긴 1억을 S&P500 인덱스펀드에 넣을 때, 첫날 다 넣는 것과 12달에 나눠 넣는 것을 견줬습니다. 1985년 1월부터 2021년 10월까지 매달 첫 거래일을 시작일로 바꿔 가며 442번, 넣고 5년 뒤 평가액을 비교했습니다. 아직 안 넣은 돈은 미국 3개월 국채 이자를 받습니다.
| 상황 | 기준 |
|---|---|
| S&P500 에 넣을 목돈 | 12달 나누지 말고 한 번에 — 나누면 덜 무섭지만 대부분 덜 남았습니다 |
| 그래도 나눠 넣기로 했다면 | 매달 첫 거래일 같은 금액 — 12번의 매수를 자동으로 걸어 두기 |
| 한 번에 넣었다면 | 할 일은 떨어질 때 팔지 않는 것 |
1억을 5년 뒤 — 한 번에 vs 12달 나눠 (S&P500) 시작 442번 중 한 번에가 더 남음 335번 · 12달이 더 남음 107번 평균 한 번에 17,488만원 · 12달 16,840만원 · 차 648만원 5년 뒤 1억 아래로 끝남 — 한 번에 53번 · 12달 60번
한 번에 넣은 쪽이 가장 깊이 빠진 건 2007-10-01에 넣었을 때입니다. 2년 안에 잔고가 4,527만원까지 내려갔고(같은 날 12달 나눠 넣은 쪽은 5,071만원), 원금으로 돌아온 날은 2012-03-19입니다. 5년 뒤에는 한 번에 10,379만원 · 12달 11,625만원로 이 시작에서는 나눠 넣은 쪽이 더 남았습니다. 12달 나눠 넣은 쪽이 가장 깊이 빠진 시작은 2007-04-02 · 4,875만원 였습니다. 폭락 직전에 넣으면 나눠 넣는 쪽이 낫지만, 그런 날을 미리 알 수는 없습니다.
돌리는 법: zip 을 풀고 pip install numpy 뒤 python run_lumpsum.py (1분 안팎).
가격 S&P500 인덱스펀드(VFINX) 1985-01-02 ~ 2026-10-06 · 시작 1985-01-02 ~ 2021-10-01 · 수수료 살 때마다 0.05% ① 1억을 5년 뒤 — 한 번에 vs 12달 나눠 (S&P500) 시작 442번 중 한 번에가 더 남음 335번 · 12달이 더 남음 107번 평균 한 번에 17,488만원 · 12달 16,840만원 · 차 648만원 5년 뒤 1억 아래로 끝남 — 한 번에 53번 · 12달 60번 ② 넣은 뒤 2년 안에 가장 깊이 빠진 때 (S&P500) 한 번에 가장 깊이: 2007-10-01 넣음 → 바닥 4,527만원 · 같은 날 12달 바닥 5,071만원 5년 뒤 그 시작: 한 번에 10,379만원 · 12달 11,625만원 12달이 가장 깊이: 2007-04-02 넣음 → 바닥 4,875만원 2년 안 잔고가 7,000만원 아래로 내려간 시작 — 한 번에 53번 · 12달 33번 2007-10-01 한 번에 1억: 바닥 2009-03-09 · 원금 회복 2012-03-19 ③ 몇 달로 나누든 — 5년 뒤 평균 (S&P500 · 1억) 1달 17,488만원 · 2년 안 가장 깊이 4,527만원 2달 17,426만원 · 2년 안 가장 깊이 4,590만원 3달 17,365만원 · 2년 안 가장 깊이 4,638만원 4달 17,306만원 · 2년 안 가장 깊이 4,675만원 6달 17,187만원 · 2년 안 가장 깊이 4,691만원 12달 16,840만원 · 2년 안 가장 깊이 4,875만원 24달 16,199만원 · 2년 안 가장 깊이 5,798만원 ④ S&P500 달마다 — 오른 달 / 내린 달 오른 달 327 · 내린(같은) 달 173 ⑤ 다른 시장 — 한 번에 vs 12달 코스피 대표 ETF(KODEX200) · 기다리는 돈 연 0% · 시작 178번 중 한 번에가 더 남음 103번 · 평균 차 318만원 코스피 대표 ETF(KODEX200) · 기다리는 돈 연 3% · 시작 178번 중 한 번에가 더 남음 90번 · 평균 차 128만원 일본 닛케이(가격 지수) · 기다리는 돈 연 0% · 시작 442번 중 한 번에가 더 남음 239번 · 평균 차 216만원 일본 닛케이(가격 지수) · 기다리는 돈 연 3% · 시작 442번 중 한 번에가 더 남음 223번 · 평균 차 53만원 ⑥ 2007년 10월 시작 경로(달 첫 거래일 평가액 · 만원) 1달: 2007-10=9,995 2007-11=9,758 2007-12=9,544 2008-01=9,398 2008-02=9,070 2008-03=8,673 2008-04=8,940 2008-05=9,207 2008-06=9,070 2008-07=8,426 2008-08=8,275 2008-09=8,407 2008-10=7,657 2008-11=6,384 2008-12=5,411 2009-01=6,196 2009-02=5,495 2009-03=4,685 2009-04=5,434 2009-05=5,887 2009-06=6,343 2009-07=6,225 2009-08=6,770 2009-09=6,754 2009-10=6,980 2009-11=7,076 2009-12=7,542 2010-01=7,718 2010-02=7,427 2010-03=7,625 2010-04=8,063 2010-05=8,236 2010-06=7,351 2010-07=7,064 2010-08=7,750 2010-09=7,453 2010-10=7,919 2010-11=8,191 2010-12=8,361 2011-01=8,828 2011-02=9,084 2011-03=9,094 2011-04=9,289 2011-05=9,498 2011-06=9,193 2011-07=9,382 2011-08=9,021 2011-09=8,465 2011-10=7,735 2011-11=8,584 2011-12=8,794 2012-01=9,037 2012-02=9,382 2012-03=9,758 2012-04=10,091 2012-05=10,008 2012-06=9,123 2012-07=9,761 2012-08=9,844 2012-09=10,080 2012-10=10,379 12달: 2007-10=10,000 2007-11=10,010 2007-12=9,997 2008-01=9,977 2008-02=9,878 2008-03=9,714 2008-04=9,862 2008-05=10,034 2008-06=9,940 2008-07=9,417 2008-08=9,281 2008-09=9,417 2008-10=8,577 2008-11=7,150 2008-12=6,061 2009-01=6,940 2009-02=6,155 2009-03=5,247 2009-04=6,086 2009-05=6,594 2009-06=7,105 2009-07=6,973 2009-08=7,582 2009-09=7,565 2009-10=7,818 2009-11=7,926 2009-12=8,447 2010-01=8,645 2010-02=8,319 2010-03=8,541 2010-04=9,031 2010-05=9,224 2010-06=8,233 2010-07=7,913 2010-08=8,680 2010-09=8,348 2010-10=8,870 2010-11=9,174 2010-12=9,365 2011-01=9,888 2011-02=10,175 2011-03=10,186 2011-04=10,404 2011-05=10,639 2011-06=10,297 2011-07=10,509 2011-08=10,105 2011-09=9,481 2011-10=8,664 2011-11=9,615 2011-12=9,849 2012-01=10,122 2012-02=10,508 2012-03=10,930 2012-04=11,303 2012-05=11,210 2012-06=10,218 2012-07=10,934 2012-08=11,026 2012-09=11,291 2012-10=11,625 끝.
# -*- coding: utf-8 -*-
"""알고랩 · 목돈, 한 번에 넣을까 12달 나눠 넣을까 (재현 코드)
영상: 「목돈 생기면 한 번에 넣을까, 12달 나눠 넣을까」 편 (2026-10-08)
필요: python 3.9+ · numpy 실행: python run_lumpsum.py
무엇을 하나
원금 1(= 1억 원으로 환산해 말함)을 매달 첫 거래일에 시작해
① 한 번에: 첫날 전부 산다
② N달 나눠: 시작일부터 매달 첫 거래일에 남은 돈을 같은 몫으로 나눠 산다(N=12 가 본편)
아직 안 산 돈은 이자를 받는다 — S&P500 은 미국 3개월 국채(^IRX 연율, 달력일 일할), 국내·일본은 연 0% / 3% 두 판.
살 때마다 0.05% 수수료. 종가에 산다. 공매도·빚 없음. 세금·환율·호가 차이 제외.
5년 뒤 = 시작 후 60번째 달 첫 거래일 평가액. '무서운 순간' = 시작 후 24개월 동안 계좌(주식+기다리는 돈) 최저 평가액.
가격: data_lumpsum/*.csv 의 close = 야후 수정주가(배당 재투자). 닛케이(^N225)는 가격 지수(배당 없음).
코스피 대표 ETF(KODEX200): 야후 자료가 2007-02-07 ~ 2009-04-17 통째로 비어 있어, 그 앞은 네이버 종가(분배금 미반영)를
2009-04-17 에서 이어 붙인 069500_splice_1d.csv 를 쓴다(2007-01-29 부터). 분배금이 빠진 구간은 오래 들고 있는 '한 번에'에 불리하다.
2026-10-07 에서 얼렸다. 시작 달은 1개월씩 옮기므로 이웃한 결과끼리 5년이 거의 다 겹친다(따로 된 실험이 아니다).
"""
import csv, datetime as dt, os
import numpy as np
HERE = os.path.dirname(os.path.abspath(__file__))
DATA = os.path.join(HERE, "data_lumpsum")
ASOF = "2026-10-07"
COST = 0.0005
H5, SCARY = 60, 24
NS = [1, 2, 3, 4, 6, 12, 24]
def load(fn, start=""):
d, c = [], []
for r in csv.DictReader(open(os.path.join(DATA, fn), encoding="utf-8")):
if r["date"] < start or r["date"] > ASOF or not r["close"]:
continue
d.append(r["date"][:10]); c.append(float(r["close"]))
return np.array(d), np.array(c)
irx_d, irx_c = load("_IRX_1d.csv"); IRX = dict(zip(irx_d, irx_c))
def rate(dates, mode, kr):
out, last = np.zeros(len(dates)), 0.0
for i, x in enumerate(dates):
if mode == "irx":
last = IRX[x] / 100 if x in IRX else last
out[i] = last
else:
out[i] = kr
return out
def month_starts(dates):
idx, prev = [], None
for i, x in enumerate(dates):
if x[:7] != prev:
idx.append(i); prev = x[:7]
return np.array(idx)
def run(dates, px, r, ns=NS, keep_path=None):
ms = month_starts(dates)
od = np.array([dt.date.fromisoformat(x).toordinal() for x in dates])
grow = np.cumprod(1 + r * np.diff(od, prepend=od[0]) / 365.0)
res = {N: {"끝": [], "바닥": [], "시작": []} for N in ns}
paths = {}
for k in range(len(ms)):
if k + H5 >= len(ms):
break
s, e = ms[k], ms[k + H5]
se = ms[min(k + SCARY, len(ms) - 1)]
for N in ns:
buys = list(ms[k:k + N]); remain, sh, bi = 1.0, 0.0, 0
path = np.empty(e + 1 - s)
for t in range(s, e + 1):
if bi < N and t == buys[bi]:
take = remain / (N - bi)
sh += take * grow[t] / grow[s] * (1 - COST) / px[t]
remain -= take; bi += 1
path[t - s] = sh * px[t] + remain * grow[t] / grow[s]
res[N]["끝"].append(path[-1]); res[N]["바닥"].append(path[: se - s + 1].min()); res[N]["시작"].append(dates[s])
if keep_path and dates[s].startswith(keep_path):
paths[N] = (dates[s:e + 1], path)
for N in ns:
for key in ("끝", "바닥"):
res[N][key] = np.array(res[N][key])
return res, paths
def 만원(x):
return f"{x * 1e4:,.0f}만원"
d, c = load("VFINX_1d.csv")
res, paths = run(d, c, rate(d, "irx", 0), keep_path="2007-10")
L, S = res[1], res[12]
n = len(L["끝"]); win = int((L["끝"] > S["끝"]).sum())
print(f"가격 S&P500 인덱스펀드(VFINX) {d[0]} ~ {d[-1]} · 시작 {L['시작'][0]} ~ {L['시작'][-1]} · 수수료 살 때마다 {COST*100:.2f}%")
print("\n① 1억을 5년 뒤 — 한 번에 vs 12달 나눠 (S&P500)")
print(f" 시작 {n}번 중 한 번에가 더 남음 {win}번 · 12달이 더 남음 {n - win}번")
print(f" 평균 한 번에 {만원(L['끝'].mean())} · 12달 {만원(S['끝'].mean())} · 차 {(L['끝'].mean() - S['끝'].mean()) * 1e4:,.0f}만원")
print(f" 5년 뒤 1억 아래로 끝남 — 한 번에 {int((L['끝'] < 1).sum())}번 · 12달 {int((S['끝'] < 1).sum())}번")
print("\n② 넣은 뒤 2년 안에 가장 깊이 빠진 때 (S&P500)")
i = int(L["바닥"].argmin()); j = int(S["바닥"].argmin())
print(f" 한 번에 가장 깊이: {L['시작'][i]} 넣음 → 바닥 {만원(L['바닥'][i])} · 같은 날 12달 바닥 {만원(S['바닥'][i])}")
print(f" 5년 뒤 그 시작: 한 번에 {만원(L['끝'][i])} · 12달 {만원(S['끝'][i])}")
print(f" 12달이 가장 깊이: {S['시작'][j]} 넣음 → 바닥 {만원(S['바닥'][j])}")
print(f" 2년 안 잔고가 7,000만원 아래로 내려간 시작 — 한 번에 {int((L['바닥'] < 0.7).sum())}번 · 12달 {int((S['바닥'] < 0.7).sum())}번")
pd_, pp = paths[1]
k0 = int(np.argmin(pp)); rec = next(pd_[t] for t in range(k0, len(pp)) if pp[t] >= 1.0)
print(f" {L['시작'][i]} 한 번에 1억: 바닥 {pd_[k0]} · 원금 회복 {rec}")
print("\n③ 몇 달로 나누든 — 5년 뒤 평균 (S&P500 · 1억)")
for N in [1, 2, 3, 4, 6, 12, 24]:
print(f" {N:2d}달 {만원(res[N]['끝'].mean())} · 2년 안 가장 깊이 {만원(res[N]['바닥'].min())}")
print("\n④ S&P500 달마다 — 오른 달 / 내린 달")
ms = month_starts(d); me = list(ms[1:]) + [len(d)]
mret = [c[e - 1] / c[s - 1] - 1 for s, e in zip(ms[1:], me[1:])]
mret = [r for r, s in zip(mret, ms[1:]) if d[s] < "2026-10-01"]
print(f" 오른 달 {sum(1 for r in mret if r > 0)} · 내린(같은) 달 {sum(1 for r in mret if r <= 0)}")
print("\n⑤ 다른 시장 — 한 번에 vs 12달")
for name, fn, mode, st in [("코스피 대표 ETF(KODEX200)", "069500_splice_1d.csv", "kr", "2007-01-29"), ("일본 닛케이(가격 지수)", "_N225_1d.csv", "kr", "")]:
dd, cc = load(fn, st)
for kr in (0.0, 0.03):
rr, _ = run(dd, cc, rate(dd, mode, kr), ns=[1, 12])
a, b = rr[1]["끝"], rr[12]["끝"]
print(f" {name} · 기다리는 돈 연 {kr*100:.0f}% · 시작 {len(a)}번 중 한 번에가 더 남음 {int((a > b).sum())}번 · 평균 차 {(a.mean() - b.mean()) * 1e4:,.0f}만원")
print("\n⑥ 2007년 10월 시작 경로(달 첫 거래일 평가액 · 만원)")
for N in (1, 12):
dd, p = paths[N]
m = month_starts(dd)
print(f" {N:2d}달: " + " ".join(f"{dd[t][:7]}={p[t] * 1e4:,.0f}" for t in m))
print("\n끝.")
알고랩 Strategy Lab — 전략을 검증하고, 검증한 것만 자동매매로 옮깁니다. "지금이라도 팔아야 하나" 싶을 때 정한 규칙을 지키는 일은 사람보다 봇이 잘합니다. 알고랩 자동매매 살펴보기 · 전략 검증 전체 보기
과거 데이터를 돌려 본 결과이며 미래 수익을 보장하지 않습니다. 투자 판단과 책임은 본인에게 있습니다.