국내 대형주 · 삼성전자 · 급락 매수 · 실측 재현 페이지
2007년 말 시가총액 상위 40개 종목의 2005년 이후 실제 가격(야후 수정종가)에서, 종가가 직전 20거래일 최고 종가보다 20% 넘게 낮아진 첫 날을 모두 모았습니다. 같은 돈으로 두 가지를 견줍니다. ① 바로 — 다음 거래일 종가에 산다 ② 반등 보고 — 그 뒤 가장 낮았던 종가에서 10% 오른 날의 다음 거래일 종가에 산다 둘 다 바로 산 날부터 250거래일(약 1년) 뒤 같은 날 종가로 평가합니다.
| 상황 | 할 일 |
|---|---|
| 사려던 대형주가 20거래일 최고 종가보다 20% 넘게 빠졌다 | 반등을 기다리지 말고 다음 날 산다 |
| 원래 살 생각이 없던 종목 | 이 페이지의 질문이 아닙니다 — 빠졌다는 이유만으로 사라는 뜻이 아닙니다 |
| 빠진 날 | 바로 산 날 | 바로 · 1년 뒤 | 반등 보고 산 날 | 반등 보고 · 1년 뒤 | 평가일 |
|---|---|---|---|---|---|
| 2008-07-10 | 2008-07-11 | 1,070만원 | 2008-07-25 | 1,055만원 | 2009-07-03 |
| 2008-10-24 | 2008-10-27 | 1,736만원 | 2008-10-29 | 1,600만원 | 2009-10-20 |
| 2011-08-19 | 2011-08-22 | 1,837만원 | 2011-09-02 | 1,650만원 | 2012-08-22 |
| 2020-03-16 | 2020-03-17 | 1,807만원 | 2020-03-25 | 1,757만원 | 2021-03-23 |
| 2024-09-19 | 2024-09-20 | 1,404만원 | 2024-11-19 | 1,562만원 | 2025-10-01 |
1,000만원 기준 · 수정주가. 2024년 9월은 바로 산 뒤에도 두 달 가까이 더 빠져 반등을 기다린 쪽이 더 싸게 샀습니다.
돌리는 법: zip 을 풀고 python run_bigdrop.py
대형주가 20일 최고 종가보다 20% 넘게 빠진 날 — 바로 살까, 반등(바닥 +10%)을 보고 살까 · 1년 뒤 같은 날 평가 == 국내 · 2007년 말 시가총액 상위 40종 (메인) 빠진 날 538번 · 1년 뒤 바로 산 쪽이 더 남은 것 371번 · 반등을 보고 산 쪽 167번 반등을 보고 산 값이 바로 산 값보다 비쌌던 것 371번(같은 날 평가라 위와 같은 수) 반등을 기다린 기간 가운데 값 11거래일 1,000만원 기준 1년 뒤 평균(기하): 바로 1,082만원 · 반등 보고 1,069만원 1,000만원 기준 1년 뒤 평균(단순): 바로 1,206만원 · 반등 보고 1,196만원 바로 산 쪽도 1년 뒤 산 값보다 아래였던 것 224번 종목별 평균으로 바로가 앞선 종목 28/40 · 달로 묶으면 100/141달 · 해로 묶으면 17/21해 반등을 본 쪽이 평균으로 앞선 해: 2014 · 2015 · 2018 · 2020 2020년 빠진 날 49번 · 반등을 보고 산 쪽이 더 남은 것 31번 20일선 위로 올라선 걸 보고 사기(평균 로그) +0.0525 — 바로 +0.0790 · 반등 보고 +0.0667 == 국내 · 대형주 36종 (개발 표본) 빠진 날 469번 · 1년 뒤 바로 산 쪽이 더 남은 것 340번 · 반등을 보고 산 쪽 129번 반등을 보고 산 값이 바로 산 값보다 비쌌던 것 340번(같은 날 평가라 위와 같은 수) 반등을 기다린 기간 가운데 값 11거래일 1,000만원 기준 1년 뒤 평균(기하): 바로 1,148만원 · 반등 보고 1,127만원 1,000만원 기준 1년 뒤 평균(단순): 바로 1,280만원 · 반등 보고 1,262만원 바로 산 쪽도 1년 뒤 산 값보다 아래였던 것 180번 종목별 평균으로 바로가 앞선 종목 28/36 · 달로 묶으면 97/130달 · 해로 묶으면 18/21해 반등을 본 쪽이 평균으로 앞선 해: 2014 · 2015 · 2020 2020년 빠진 날 42번 · 반등을 보고 산 쪽이 더 남은 것 27번 20일선 위로 올라선 걸 보고 사기(평균 로그) +0.1097 — 바로 +0.1382 · 반등 보고 +0.1195 == 미국 · 대형주 30종 빠진 날 187번 · 1년 뒤 바로 산 쪽이 더 남은 것 117번 · 반등을 보고 산 쪽 70번 반등을 보고 산 값이 바로 산 값보다 비쌌던 것 117번(같은 날 평가라 위와 같은 수) 반등을 기다린 기간 가운데 값 10거래일 1,000만원 기준 1년 뒤 평균(기하): 바로 1,104만원 · 반등 보고 1,117만원 1,000만원 기준 1년 뒤 평균(단순): 바로 1,229만원 · 반등 보고 1,240만원 바로 산 쪽도 1년 뒤 산 값보다 아래였던 것 37번 종목별 평균으로 바로가 앞선 종목 13/30 · 달로 묶으면 44/65달 · 해로 묶으면 12/19해 반등을 본 쪽이 평균으로 앞선 해: 2006 · 2007 · 2008 · 2016 · 2017 · 2018 · 2020 2020년 빠진 날 34번 · 반등을 보고 산 쪽이 더 남은 것 24번 20일선 위로 올라선 걸 보고 사기(평균 로그) +0.1002 — 바로 +0.0992 · 반등 보고 +0.1104 [기준선 — 빠진 날이 아니라 아무 달 첫 거래일에, 다음 날 산 것과 11거래일 늦게 산 것] 국내 2007 상위 40: 9,872번 중 5,058번 늦게 산 값이 더 비쌌다 국내 36: 8,955번 중 4,604번 늦게 산 값이 더 비쌌다 국내 2007 상위 40 · 2008년 이후 빠진 날만: 461번 중 302번 바로가 더 남음 국내 36 · 2008년 이후 빠진 날만: 402번 중 280번 바로가 더 남음 [삼성전자 005930 — 빠진 날 전부 · 1,000만원 기준 1년 뒤] 2008-07-10 → 바로 2008-07-11 매수 1,070만원 · 반등 보고 2008-07-25 매수 1,055만원 · 평가일 2009-07-03 2008-10-24 → 바로 2008-10-27 매수 1,736만원 · 반등 보고 2008-10-29 매수 1,600만원 · 평가일 2009-10-20 2011-08-19 → 바로 2011-08-22 매수 1,837만원 · 반등 보고 2011-09-02 매수 1,650만원 · 평가일 2012-08-22 2020-03-16 → 바로 2020-03-17 매수 1,807만원 · 반등 보고 2020-03-25 매수 1,757만원 · 평가일 2021-03-23 2024-09-19 → 바로 2024-09-20 매수 1,404만원 · 반등 보고 2024-11-19 매수 1,562만원 · 평가일 2025-10-01 [하락 × 반등 아홉 가지 조합 — 평균 로그로 바로가 앞선 조합 수] 국내 2007 상위 40: 9개 중 9개 (단순 평균으로는 9개 중 8개) 국내 36: 9개 중 9개 (단순 평균으로는 9개 중 8개) 미국 30: 9개 중 4개 (단순 평균으로는 9개 중 4개) 끝.
# -*- coding: utf-8 -*-
"""대형주가 크게 빠진 날 — 다음 날 바로 살까, 반등을 보고 살까 (AlgoLab · 2026-10-24)
돌리는 법: 이 파일 옆에 data_bigdrop/ 폴더를 두고 python run_bigdrop.py
표준 라이브러리만 씁니다. 가격 자료는 2026-10-23 까지 얼려 둔 야후 일봉 수정종가(날짜·종가)입니다.
빠진 날 : 종가가 직전 20거래일 최고 종가보다 20% 이상 낮아진 첫 날 t
(같은 종목은 60거래일이 지나고, 다시 20% 안쪽으로 회복했다가 빠질 때만 다시 센다)
바로 : t 다음 거래일 종가에 산다
반등 보고: t 이후 가장 낮았던 종가에서 10% 오른 종가가 나온 날의 다음 거래일 종가에 산다
(끝 날까지 안 나오면 현금으로 둔다)
평가 : 둘 다 '바로 산 날 + 250거래일'(약 1년) 종가로 같은 날 평가 · 사는 비용 편도 0.1% · 현금 이자 0
국내 종목은 하루 ±31% 넘는 등락을 액면분할 오류로 보고 0 으로 지운다.
"""
import csv
import math
import os
HERE = os.path.dirname(os.path.abspath(__file__))
D = os.path.join(HERE, "data_bigdrop")
H, GAP, COST, BUY0 = 250, 60, 0.001, "2005-01-01"
US = "XOM GE MSFT C BAC WMT JNJ PFE AIG MO PG JPM IBM INTC CVX WFC KO CSCO GOOG VZ AMGN PEP HD COP HPQ UPS T ORCL QCOM MRK".split()
def load(path, clean):
d, c = [], []
for r in csv.reader(open(path, encoding="utf-8")):
if r and r[0][:1].isdigit() and float(r[1]) > 0:
d.append(r[0]); c.append(float(r[1]))
if clean:
x = [c[0]]
for i in range(1, len(c)):
g = c[i] / c[i - 1] - 1
x.append(x[-1] * (1 + (0.0 if abs(g) > 0.31 else g)))
c = x
return d, c
def events(d, c, X):
out, armed, last = [], True, -10**9
for i in range(20, len(c)):
hi = max(c[i - 20:i])
if d[i] >= BUY0 and armed and i - last >= GAP and c[i] <= (1 - X) * hi:
out.append(i); last = i; armed = False
elif not armed and c[i] > (1 - X) * hi:
armed = True
return out
def knee(c, t, end, Y):
lo = c[t]
for s in range(t, end):
lo = min(lo, c[s])
if c[s] >= (1 + Y) * lo:
return s
return None
def ma_day(c, t, end):
for s in range(max(t, 20), end):
if c[s] > sum(c[s - 19:s + 1]) / 20:
return s
return None
def ret(c, buy, end):
if buy is None or buy >= end:
return 1.0
return c[end] / c[buy] * (1 - COST)
def run(sub, clean, names=None, X=0.20, Y=0.10):
names = names or sorted(f[:-4] for f in os.listdir(os.path.join(D, sub)) if f.endswith(".csv"))
ev = []
for nm in names:
d, c = load(os.path.join(D, sub, nm + ".csv"), clean)
for t in events(d, c, X):
end = t + 1 + H
if end < len(c):
s = knee(c, t, end, Y)
wb = None if s is None else s + 1
m = ma_day(c, t, end)
ev.append(dict(nm=nm, day=d[t], kd=d[t + 1], wd=None if wb is None or wb >= end else d[wb],
wait=None if s is None else s - t, end=d[end],
K=ret(c, t + 1, end), W=ret(c, wb, end), M=ret(c, None if m is None else m + 1, end)))
return ev
def won(ev):
return sum(e["K"] > e["W"] for e in ev)
def gmean(xs):
return math.exp(sum(math.log(x) for x in xs) / len(xs))
def median(xs):
xs = sorted(xs); n = len(xs)
return xs[n // 2] if n % 2 else (xs[n // 2 - 1] + xs[n // 2]) / 2
def report(title, ev):
n, k = len(ev), won(ev)
print(f"== {title}")
print(f" 빠진 날 {n}번 · 1년 뒤 바로 산 쪽이 더 남은 것 {k}번 · 반등을 보고 산 쪽 {n - k}번")
print(f" 반등을 보고 산 값이 바로 산 값보다 비쌌던 것 {k}번(같은 날 평가라 위와 같은 수)")
print(f" 반등을 기다린 기간 가운데 값 {median([e['wait'] for e in ev if e['wait'] is not None]):.0f}거래일")
print(f" 1,000만원 기준 1년 뒤 평균(기하): 바로 {1000 * gmean([e['K'] for e in ev]):,.0f}만원 · 반등 보고 {1000 * gmean([e['W'] for e in ev]):,.0f}만원")
print(f" 1,000만원 기준 1년 뒤 평균(단순): 바로 {1000 * sum(e['K'] for e in ev) / n:,.0f}만원 · 반등 보고 {1000 * sum(e['W'] for e in ev) / n:,.0f}만원")
print(f" 바로 산 쪽도 1년 뒤 산 값보다 아래였던 것 {sum(e['K'] < 1 for e in ev)}번")
per, mon, yr = {}, {}, {}
for e in ev:
g = math.log(e["K"]) - math.log(e["W"])
per.setdefault(e["nm"], []).append(g); mon.setdefault(e["day"][:7], []).append(g); yr.setdefault(e["day"][:4], []).append(g)
f = lambda m: sum(sum(v) > 0 for v in m.values())
print(f" 종목별 평균으로 바로가 앞선 종목 {f(per)}/{len(per)} · 달로 묶으면 {f(mon)}/{len(mon)}달 · 해로 묶으면 {f(yr)}/{len(yr)}해")
print(f" 반등을 본 쪽이 평균으로 앞선 해: {' · '.join(y for y, v in sorted(yr.items()) if sum(v) < 0)}")
e20 = [e for e in ev if e["day"][:4] == "2020"]
print(f" 2020년 빠진 날 {len(e20)}번 · 반등을 보고 산 쪽이 더 남은 것 {sum(e['W'] > e['K'] for e in e20)}번")
lk = sum(math.log(e['K']) for e in ev) / n; lw = sum(math.log(e['W']) for e in ev) / n; lm = sum(math.log(e['M']) for e in ev) / n
print(f" 20일선 위로 올라선 걸 보고 사기(평균 로그) {lm:+.4f} — 바로 {lk:+.4f} · 반등 보고 {lw:+.4f}")
if __name__ == "__main__":
print("대형주가 20일 최고 종가보다 20% 넘게 빠진 날 — 바로 살까, 반등(바닥 +10%)을 보고 살까 · 1년 뒤 같은 날 평가\n")
main = run("u2007", True)
report("국내 · 2007년 말 시가총액 상위 40종 (메인)", main)
dev = run("kr36", True)
report("국내 · 대형주 36종 (개발 표본)", dev)
us = run("us30", False, US)
report("미국 · 대형주 30종", us)
print("\n[기준선 — 빠진 날이 아니라 아무 달 첫 거래일에, 다음 날 산 것과 11거래일 늦게 산 것]")
for title, sub in (("국내 2007 상위 40", "u2007"), ("국내 36", "kr36")):
n = k = 0
for nm in sorted(f[:-4] for f in os.listdir(os.path.join(D, sub)) if f.endswith(".csv")):
d, c = load(os.path.join(D, sub, nm + ".csv"), True)
seen = set()
for t in range(20, len(c)):
if d[t] >= BUY0 and d[t][:7] not in seen:
seen.add(d[t][:7])
if t + 1 + H < len(c):
n += 1
k += c[t + 1] < c[t + 12]
print(f" {title}: {n:,}번 중 {k:,}번 늦게 산 값이 더 비쌌다")
for title, ev in (("국내 2007 상위 40", main), ("국내 36", dev)):
e8 = [e for e in ev if e["day"] >= "2008-01-01"]
print(f" {title} · 2008년 이후 빠진 날만: {len(e8)}번 중 {won(e8)}번 바로가 더 남음")
print("\n[삼성전자 005930 — 빠진 날 전부 · 1,000만원 기준 1년 뒤]")
for e in main:
if e["nm"] == "005930":
print(f" {e['day']} → 바로 {e['kd']} 매수 {1000 * e['K']:,.0f}만원 · 반등 보고 {e['wd']} 매수 {1000 * e['W']:,.0f}만원 · 평가일 {e['end']}")
print("\n[하락 × 반등 아홉 가지 조합 — 평균 로그로 바로가 앞선 조합 수]")
for title, sub, clean, nm in (("국내 2007 상위 40", "u2007", True, None), ("국내 36", "kr36", True, None), ("미국 30", "us30", False, US)):
w = wa = 0
for X in (0.15, 0.20, 0.30):
for Y in (0.05, 0.10, 0.20):
ev = run(sub, clean, nm, X, Y)
w += sum(math.log(e["K"]) for e in ev) > sum(math.log(e["W"]) for e in ev)
wa += sum(e["K"] for e in ev) > sum(e["W"] for e in ev)
print(f" {title}: 9개 중 {w}개 (단순 평균으로는 9개 중 {wa}개)")
print("\n끝.")
알고랩 Strategy Lab — 전략을 검증하고, 검증한 것만 자동매매로 옮깁니다. 크게 빠진 다음 날 정해 둔 대로 사는 일은 사람보다 규칙이 잘합니다. 알고랩 자동매매 살펴보기 · 전략 검증 전체 보기
과거 데이터를 돌려 본 결과이며 미래 수익을 보장하지 않습니다. 투자 판단과 책임은 본인에게 있습니다.