적립식 · 코스피200 ETF · 실측 재현 페이지

적립식이 마이너스면,
멈출까 계속 살까

코스피200 ETF(KODEX200)를 매달 첫 거래일에 50만원씩 10년 동안 사는 계좌 둘을 견줬습니다. 하나는 마이너스든 플러스든 매달 사고, 다른 하나는 전날 종가로 계좌가 원금 아래면 그달은 사지 않고 현금으로 모아 둡니다(연 3% 이자). 시작 달을 2002년 11월부터 1개월씩 옮겨 가며 168번 계산했습니다.

166번168번 중 10년 뒤 계속 산 계좌가 더 남은 경우 (멈춘 계좌가 더 남은 경우 2번)
7,700만원가운데쯤 되는 경우(2014-02 시작 · 원금 6,000만원) — 계속 산 계좌. 멈춘 계좌는 7,219만원
167번플러스로 돌아올 때 모아 둔 돈을 한꺼번에 넣어도 — 168번 중 계속 산 계좌가 더 남은 경우

오늘 드리는 것 — 적립 기준 한 줄

상황기준
적립식 계좌가 마이너스자동이체를 끊지 않는다 — 멈추면 가장 싼 달만 골라 건너뛴다
멈춘 달은 어떤 달이었나168/168 창 전부에서 멈춘 달의 평균 가격이 그 10년 납입일 평균 가격보다 쌌습니다(창별 값의 한가운데 -20.5%)
지키기 어렵다면매달 같은 날 매수를 자동으로 걸어 두기 — 빨간 숫자를 보고도 손대지 않게

올해 3월부터 산 계좌 (2026-10-08 종가)

3월부터 매달 50만원(원금 400만원) — 계속 산 계좌 402.7만원 · 마이너스인 달(4·8·9·10월)마다 멈춘 계좌 389.6만원. 한 계좌 장면일 뿐이고, 증거는 위의 168번입니다.

한계 — 먼저 읽어 주세요

받아가기

돌리는 법: zip 을 풀고 pip install numpy pandas 뒤 python run_dcastop.py (1분 안팎).

그대로 돌린 출력

[KODEX200 · 쉬는 돈 연 3% 이자] 자료 2002-10-14 ~ 2026-10-08 · 10년 창 168개 (시작 2002-11 ~ 2016-10) · 월 50만원 · 원금 6,000만원
  멈춤: 멈춘 적 있는 창 168번 중 계속이 더 남음 166번 · 멈춤이 더 남음 2번
    가운데쯤(끝 잔고 비율 순서 한가운데): 2014-02 시작 → 2024-01-31 · 계속 7,700만원 · 멈춤 7,219만원 · 차 481만원 · 멈춘 달 29번
    멈춤에 가장 불리: 2011-07 시작 · 계속 10,672만원 · 멈춤 7,505만원
    멈춤에 가장 유리: 2010-04 시작 · 계속 5,937만원 · 멈춤 6,139만원
    멈춘 달 평균 가격이 그 10년 납입일 평균 가격보다 쌌던 창: 168/168 · 얼마나 쌌나(창별 값의 한가운데) -20.5%
  멈춤·몰아넣기: 멈춘 적 있는 창 168번 중 계속이 더 남음 167번 · 멈춤·몰아넣기이 더 남음 1번
    가운데쯤(끝 잔고 비율 순서 한가운데): 2010-07 시작 → 2020-06-30 · 계속 6,982만원 · 멈춤·몰아넣기 6,881만원 · 차 101만원 · 멈춘 달 36번
    멈춤·몰아넣기에 가장 불리: 2007-11 시작 · 계속 9,087만원 · 멈춤·몰아넣기 8,395만원
    멈춤·몰아넣기에 가장 유리: 2011-03 시작 · 계속 10,134만원 · 멈춤·몰아넣기 10,171만원
    멈춘 달 평균 가격이 그 10년 납입일 평균 가격보다 쌌던 창: 168/168 · 얼마나 쌌나(창별 값의 한가운데) -24.9%

[KODEX200 · 쉬는 돈 이자 0%] 자료 2002-10-14 ~ 2026-10-08 · 10년 창 168개 (시작 2002-11 ~ 2016-10) · 월 50만원 · 원금 6,000만원
  멈춤: 멈춘 적 있는 창 168번 중 계속이 더 남음 168번 · 멈춤이 더 남음 0번
    가운데쯤(끝 잔고 비율 순서 한가운데): 2012-11 시작 → 2022-10-31 · 계속 7,022만원 · 멈춤 6,357만원 · 차 665만원 · 멈춘 달 35번
    멈춤에 가장 불리: 2011-05 시작 · 계속 10,355만원 · 멈춤 6,470만원
    멈춤에 가장 유리: 2009-04 시작 · 계속 7,159만원 · 멈춤 7,144만원
    멈춘 달 평균 가격이 그 10년 납입일 평균 가격보다 쌌던 창: 168/168 · 얼마나 쌌나(창별 값의 한가운데) -20.5%
  멈춤·몰아넣기: 멈춘 적 있는 창 168번 중 계속이 더 남음 168번 · 멈춤·몰아넣기이 더 남음 0번
    가운데쯤(끝 잔고 비율 순서 한가운데): 2010-05 시작 → 2020-04-29 · 계속 6,461만원 · 멈춤·몰아넣기 6,335만원 · 차 126만원 · 멈춘 달 38번
    멈춤·몰아넣기에 가장 불리: 2011-05 시작 · 계속 10,355만원 · 멈춤·몰아넣기 9,370만원
    멈춤·몰아넣기에 가장 유리: 2009-03 시작 · 계속 7,392만원 · 멈춤·몰아넣기 7,389만원
    멈춘 달 평균 가격이 그 10년 납입일 평균 가격보다 쌌던 창: 168/168 · 얼마나 쌌나(창별 값의 한가운데) -24.6%

[S&P500 인덱스펀드 VFINX · 달러 · 쉬는 돈 미국 3개월 국채 이자] 자료 1980-01-02 ~ 2026-10-07 · 10년 창 441개 (시작 1980-02 ~ 2016-10) · 월 50만원 · 원금 6,000만원
  멈춤: 멈춘 적 있는 창 411번 중 계속이 더 남음 390번 · 멈춤이 더 남음 21번
    가운데쯤(끝 잔고 비율 순서 한가운데): 2014-12 시작 → 2024-11-29 · 계속 13,254만원 · 멈춤 12,427만원 · 차 827만원 · 멈춘 달 7번
    멈춤에 가장 불리: 2007-11 시작 · 계속 11,927만원 · 멈춤 7,489만원
    멈춤에 가장 유리: 1999-03 시작 · 계속 4,062만원 · 멈춤 5,495만원
    멈춘 달 평균 가격이 그 10년 납입일 평균 가격보다 쌌던 창: 411/411 · 얼마나 쌌나(창별 값의 한가운데) -43.9%
  멈춤·몰아넣기: 멈춘 적 있는 창 411번 중 계속이 더 남음 410번 · 멈춤·몰아넣기이 더 남음 1번
    가운데쯤(끝 잔고 비율 순서 한가운데): 1986-06 시작 → 1996-05-31 · 계속 13,069만원 · 멈춤·몰아넣기 12,955만원 · 차 114만원 · 멈춘 달 13번
    멈춤·몰아넣기에 가장 불리: 2007-11 시작 · 계속 11,927만원 · 멈춤·몰아넣기 10,285만원
    멈춤·몰아넣기에 가장 유리: 1982-09 시작 · 계속 11,666만원 · 멈춤·몰아넣기 11,667만원
    멈춘 달 평균 가격이 그 10년 납입일 평균 가격보다 쌌던 창: 411/411 · 얼마나 쌌나(창별 값의 한가운데) -44.2%

[장면] KODEX200 · 2014-02 시작 · 12달마다 평가액(만원) — 계속 / 멈춤
  2014-02  0 / 0
  2015-02  595 / 593
  2016-02  1,128 / 1,167
  2017-02  1,988 / 1,900
  2018-02  3,177 / 2,822
  2019-02  3,378 / 3,215
  2020-02  4,064 / 3,900
  2021-02  6,764 / 5,840
  2022-02  6,617 / 5,991
  2023-02  6,601 / 6,225
  2024-01-31  7,700 / 7,219
  멈춘 달(29번): 2014-10 2014-11 2014-12 2015-01 2015-02 2015-03 2015-07 2015-08 2015-09 2015-10 2015-11 2015-12 2016-01 2016-02 2016-03 2016-04 2016-05 2016-06 2016-07 2016-08 2018-11 2018-12 2019-01 2019-06 2019-08 2019-09 2020-04 2020-05 2022-10
  월별경로 계속: 2014-02=0 2014-03=52 2014-04=102 2014-05=151 2014-06=205 2014-07=254 2014-08=316 2014-09=360 2014-10=396 2014-11=436 2014-12=492 2015-01=529 2015-02=595 2015-03=647 2015-04=711 2015-05=792 2015-06=823 2015-07=843 2015-08=862 2015-09=870 2015-10=939 2015-11=1049 2015-12=1073 2016-01=1116 2016-02=1128 2016-03=1198 2016-04=1300 2016-05=1348 2016-06=1390 2016-07=1446 2016-08=1540 2016-09=1619 2016-10=1674 2016-11=1715 2016-12=1757 2017-01=1872 2017-02=1988 2017-03=2048 2017-04=2187 2017-05=2290 2017-06=2490 2017-07=2601 2017-08=2671 2017-09=2664 2017-10=2793 2017-11=2995 2017-12=2967 2018-01=3040 2018-02=3177 2018-03=3034 2018-04=3111 2018-05=3241 2018-06=3169 2018-07=3109 2018-08=3142 2018-09=3209 2018-10=3277 2018-11=2923 2018-12=3060 2019-01=3043 2019-02=3378 2019-03=3402 2019-04=3377 2019-05=3522 2019-06=3305 2019-07=3540 2019-08=3449 2019-09=3395 2019-10=3652 2019-11=3742 2019-12=3797 2020-01=4136 2020-02=4064 2020-03=3876 2020-04=3477 2020-05=3847 2020-06=4042 2020-07=4289 2020-08=4635 2020-09=4813 2020-10=4916 2020-11=4822 2020-12=5606 2021-01=6441 2021-02=6764 2021-03=6909 2021-04=7039 2021-05=7218 2021-06=7348 2021-07=7594 2021-08=7409 2021-09=7371 2021-10=7104 2021-11=6926 2021-12=6725 2022-01=7216 2022-02=6617 2022-03=6731 2022-04=6870 2022-05=6723 2022-06=6760 2022-07=5933 2022-08=6276 2022-09=6296 2022-10=5568 2022-11=5991 2022-12=6465 2023-01=6011 2023-02=6601 2023-03=6599 2023-04=6812 2023-05=6943 2023-06=7280 2023-07=7328 2023-08=7492 2023-09=7345 2023-10=7240 2023-11=6822 2023-12=7610 2024-01=8160 2024-01-31=7700
  월별경로 멈춤: 2014-02=0 2014-03=52 2014-04=102 2014-05=151 2014-06=205 2014-07=254 2014-08=316 2014-09=360 2014-10=396 2014-11=436 2014-12=492 2015-01=532 2015-02=593 2015-03=645 2015-04=704 2015-05=773 2015-06=812 2015-07=844 2015-08=877 2015-09=903 2015-10=964 2015-11=1046 2015-12=1085 2016-01=1133 2016-02=1167 2016-03=1228 2016-04=1302 2016-05=1352 2016-06=1401 2016-07=1456 2016-08=1524 2016-09=1587 2016-10=1641 2016-11=1690 2016-12=1739 2017-01=1819 2017-02=1900 2017-03=1956 2017-04=2050 2017-05=2127 2017-06=2252 2017-07=2335 2017-08=2397 2017-09=2420 2017-10=2514 2017-11=2646 2017-12=2657 2018-01=2721 2018-02=2822 2018-03=2766 2018-04=2834 2018-05=2932 2018-06=2914 2018-07=2903 2018-08=2946 2018-09=3008 2018-10=3071 2018-11=2878 2018-12=2983 2019-01=2996 2019-02=3215 2019-03=3252 2019-04=3260 2019-05=3371 2019-06=3262 2019-07=3425 2019-08=3394 2019-09=3386 2019-10=3560 2019-11=3637 2019-12=3694 2020-01=3920 2020-02=3900 2020-03=3808 2020-04=3586 2020-05=3831 2020-06=3971 2020-07=4143 2020-08=4377 2020-09=4509 2020-10=4595 2020-11=4559 2020-12=5070 2021-01=5615 2021-02=5840 2021-03=5953 2021-04=6058 2021-05=6194 2021-06=6299 2021-07=6479 2021-08=6381 2021-09=6378 2021-10=6226 2021-11=6132 2021-12=6022 2022-01=6365 2022-02=5991 2022-03=6087 2022-04=6199 2022-05=6122 2022-06=6167 2022-07=5633 2022-08=5885 2022-09=5919 2022-10=5445 2022-11=5750 2022-12=6091 2023-01=5804 2023-02=6225 2023-03=6243 2023-04=6410 2023-05=6520 2023-06=6772 2023-07=6825 2023-08=6956 2023-09=6873 2023-10=6818 2023-11=6545 2023-12=7118 2024-01=7525 2024-01-31=7219

[올해 3월부터] KODEX200 매달 50만원 · 납입 8번(2026-03-03 ~ 2026-10-01) · 2026-10-08 종가 평가
  계속: 원금 400만원 · 평가 402.7만원 · +0.68% · 멈춘 달 []
  멈춤: 원금 400만원 · 평가 389.6만원 · -2.61% · 멈춘 달 ['2026-04', '2026-08', '2026-09', '2026-10']

끝.

코드 전문

# -*- coding: utf-8 -*-
"""알고랩 재현 코드 — 적립식 계좌가 마이너스면 멈출까, 계속 살까 (2026-10-09 영상)

같은 폴더의 data_dcastop/ 에 얼린 가격 자료만 쓴다(인터넷 접속 없음). 기준일 ASOF 고정.
  python run_dcastop.py        (numpy·pandas 필요)

규칙
- 계속: 매달 첫 거래일 종가에 50만원어치 산다.
- 멈춤: 그달 첫 거래일의 '전날 종가'로 계좌 주식 평가액이 주식에 넣은 원금보다 낮으면(마이너스) 그달은 사지 않고
        50만원을 현금으로 쌓는다(이자 붙음). 다음 달 플러스면 다시 산다. 쌓인 현금은 끝까지 현금으로 둔다.
- 멈춤·몰아넣기: 멈춤과 같되, 다시 사는 날 쌓인 현금을 그날 종가에 전부 넣는다.
- 10년(120번 납입) 창을 시작 달 한 달씩 옮겨 가며 비교. 평가 = 121번째 달 첫 거래일 전날 종가. 평가액 = 주식 + 현금.
- 한 번도 멈추지 않은 창은 두 계좌가 똑같아서 승·패에서 뺀다.
- 수수료·세금·호가 없음 · 공매도·빚 없음.
자료
- 069500_splice_1d.csv : KODEX200. 2009-04-17 이후 야후 수정가(분배금 재투자), 그 전은 네이버 종가(분배금 미반영)를 이어 붙였다
                         (야후 069500 은 2007-02 ~ 2009-04 가 통째로 비어 있다).
- VFINX_1d.csv         : 뱅가드 S&P500 인덱스펀드(배당 재투자 · 달러).
- _IRX_1d.csv          : 미국 3개월 국채 금리(연 %) — S&P500 쪽 쉬는 현금의 이자.
"""
import os
import numpy as np
import pandas as pd

HERE = os.path.dirname(os.path.abspath(__file__))
D = os.path.join(HERE, "data_dcastop")
ASOF = "2026-10-08"
MONTHLY = 50          # 만원
H = 120


def load(fn):
    df = pd.read_csv(os.path.join(D, fn), parse_dates=["date"])
    s = df.set_index("date")["close"].astype(float).dropna()
    s = s[(s > 0) & (s.index <= ASOF)]
    return s[~s.index.duplicated()]


IRX = load("_IRX_1d.csv")


def cash_index(idx, mode):
    if mode == "irx":
        r = IRX.reindex(idx, method="ffill").bfill().values / 100.0
        daily = (1 + r) ** (1 / 252.0)
    else:
        daily = np.full(len(idx), (1 + mode) ** (1 / 252.0))
    daily[0] = 1.0
    return np.cumprod(daily)


def month_starts(idx):
    s = pd.Series(np.arange(len(idx)), index=idx)
    return s.groupby([idx.year, idx.month]).first().values


def sim(price, C, cs, E, arm, path=None):
    """arm: A=계속 · B1=멈춤 · B2=멈춤·몰아넣기. 반환 (평가액(납입 1 단위), 멈춘 달 위치, 산 달 위치).
    path 에 리스트를 주면 매 납입일 직전(전날 종가) 평가액을 담는다."""
    sh = 0.0; cash = 0.0; cash_cost = 0.0; inv = 0.0
    paused = False; stopped, bought = [], []
    for c in cs:
        if path is not None:
            path.append(sh * price[c - 1] + cash * C[c - 1])
        inv += 1.0
        if arm == "A":
            sh += 1.0 / price[c]; bought.append(c); continue
        stock_cost = inv - 1.0 - cash_cost
        neg = sh > 0 and sh * price[c - 1] < stock_cost - 1e-12
        if neg:
            cash += 1.0 / C[c]; cash_cost += 1.0; stopped.append(c); paused = True
        else:
            sh += 1.0 / price[c]; bought.append(c)
            if paused and arm == "B2" and cash > 0:
                sh += cash * C[c] / price[c]; cash = 0.0; cash_cost = 0.0
            paused = False
    if path is not None:
        path.append(sh * price[E] + cash * C[E])
    return sh * price[E] + cash * C[E], stopped, bought


def 만(x):
    return f"{x:,.0f}만원"


def run(label, fn, cash_mode):
    p = load(fn)
    idx = p.index; price = p.values
    C = cash_index(idx, cash_mode)
    ms = month_starts(idx)
    ms = ms[ms >= 1]
    nwin = len(ms) - H
    print(f"\n[{label}] 자료 {idx[0].date()} ~ {idx[-1].date()} · 10년 창 {nwin}개 "
          f"(시작 {str(idx[ms[0]].date())[:7]} ~ {str(idx[ms[nwin - 1]].date())[:7]}) · 월 {MONTHLY}만원 · 원금 {만(MONTHLY * H)}")
    res = {}
    for arm, name in (("B1", "멈춤"), ("B2", "멈춤·몰아넣기")):
        rows = []
        for w in range(nwin):
            cs = ms[w:w + H]; E = ms[w + H] - 1
            wa, _, _ = sim(price, C, cs, E, "A")
            wb, st, _ = sim(price, C, cs, E, arm)
            if not st:
                continue
            cheap = float(np.mean(price[st]) / np.mean(price[cs]) - 1)
            rows.append(dict(w=w, 시작=str(idx[cs[0]].date())[:7], 끝=str(idx[E].date()), A=wa * MONTHLY, B=wb * MONTHLY,
                             r=wb / wa, 멈춘달=len(st), 싼정도=cheap))
        r = np.array([x["r"] for x in rows])
        mid = rows[int(np.argsort(r)[len(r) // 2])]
        wi = rows[int(np.argmin(r))]; bi = rows[int(np.argmax(r))]
        cheaper = sum(1 for x in rows if x["싼정도"] < 0)
        print(f"  {name}: 멈춘 적 있는 창 {len(rows)}번 중 계속이 더 남음 {int((r < 1).sum())}번 · {name}이 더 남음 {int((r > 1).sum())}번")
        print(f"    가운데쯤(끝 잔고 비율 순서 한가운데): {mid['시작']} 시작 → {mid['끝']} · 계속 {만(mid['A'])} · {name} {만(mid['B'])} · 차 {만(round(mid['A']) - round(mid['B']))} · 멈춘 달 {mid['멈춘달']}번")
        print(f"    {name}에 가장 불리: {wi['시작']} 시작 · 계속 {만(wi['A'])} · {name} {만(wi['B'])}")
        print(f"    {name}에 가장 유리: {bi['시작']} 시작 · 계속 {만(bi['A'])} · {name} {만(bi['B'])}")
        print(f"    멈춘 달 평균 가격이 그 10년 납입일 평균 가격보다 쌌던 창: {cheaper}/{len(rows)} · "
              f"얼마나 쌌나(창별 값의 한가운데) {np.median([x['싼정도'] for x in rows]) * 100:+.1f}%")
        res[arm] = dict(rows=rows, mid=mid)
    return res, (idx, price, C, ms)


def path_of(fn, cash_mode, start):
    p = load(fn); idx = p.index; price = p.values; C = cash_index(idx, cash_mode)
    ms = month_starts(idx); ms = ms[ms >= 1]
    w = [i for i, c in enumerate(ms) if str(idx[c].date())[:7] == start][0]
    cs = ms[w:w + H]; E = ms[w + H] - 1
    out = {}
    for arm in ("A", "B1"):
        pa = []
        _, st, _ = sim(price, C, cs, E, arm, path=pa)
        out[arm] = pa; out[arm + "_멈춤"] = [str(idx[c].date())[:7] for c in st]
    labels = [str(idx[c].date())[:7] for c in cs] + [str(idx[E].date())]
    return labels, out


if __name__ == "__main__":
    k3, _ = run("KODEX200 · 쉬는 돈 연 3% 이자", "069500_splice_1d.csv", 0.03)
    k0, _ = run("KODEX200 · 쉬는 돈 이자 0%", "069500_splice_1d.csv", 0.0)
    sp, _ = run("S&P500 인덱스펀드 VFINX · 달러 · 쉬는 돈 미국 3개월 국채 이자", "VFINX_1d.csv", "irx")

    # 가운데쯤 장면(KODEX200 · 3%) — 12달마다 계좌 평가액(전날 종가 · 만원)
    s0 = k3["B1"]["mid"]["시작"]
    labels, pth = path_of("069500_splice_1d.csv", 0.03, s0)
    print(f"\n[장면] KODEX200 · {s0} 시작 · 12달마다 평가액(만원) — 계속 / 멈춤")
    for i in list(range(0, len(labels), 12)) + ([len(labels) - 1] if (len(labels) - 1) % 12 else []):
        print(f"  {labels[i]}  {pth['A'][i] * MONTHLY:,.0f} / {pth['B1'][i] * MONTHLY:,.0f}")
    print(f"  멈춘 달({len(pth['B1_멈춤'])}번): {' '.join(pth['B1_멈춤'])}")
    print("  월별경로 계속: " + " ".join(f"{labels[i]}={pth['A'][i] * MONTHLY:.0f}" for i in range(len(labels))))
    print("  월별경로 멈춤: " + " ".join(f"{labels[i]}={pth['B1'][i] * MONTHLY:.0f}" for i in range(len(labels))))

    # 올해 3월부터 KODEX200 매달 50만원 — ASOF 종가 평가
    p = load("069500_splice_1d.csv"); idx = p.index; price = p.values; C = cash_index(idx, 0.03)
    ms = month_starts(idx); ms = ms[ms >= 1]
    cs = [c for c in ms if str(idx[c].date()) >= "2026-03-01"]
    print(f"\n[올해 3월부터] KODEX200 매달 {MONTHLY}만원 · 납입 {len(cs)}번({str(idx[cs[0]].date())} ~ {str(idx[cs[-1]].date())}) · {ASOF} 종가 평가")
    for arm, name in (("A", "계속"), ("B1", "멈춤")):
        v, st, _ = sim(price, C, cs, len(price) - 1, arm)
        print(f"  {name}: 원금 {만(len(cs) * MONTHLY)} · 평가 {v * MONTHLY:,.1f}만원 · {(v / len(cs) - 1) * 100:+.2f}% · 멈춘 달 {[str(idx[c].date())[:7] for c in st]}")
    print("\n끝.")

알고랩 Strategy Lab — 전략을 검증하고, 검증한 것만 자동매매로 옮깁니다. "이번 달만 쉬어 갈까" 싶을 때 정한 규칙을 지키는 일은 사람보다 봇이 잘합니다. 알고랩 자동매매 살펴보기 · 전략 검증 전체 보기

과거 데이터를 돌려 본 결과이며 미래 수익을 보장하지 않습니다. 투자 판단과 책임은 본인에게 있습니다.