비트코인 · 자동매매 봇 · 슈퍼트렌드 · 실측 재현 페이지

슈퍼트렌드 봇,
신상으로 바꿀까 원조로 둘까

결론 — 굳이 신상으로 바꾸지 말고 원조 그대로, 두 규칙(50일선·비중)을 지키십시오. 8년 통째로는 신상이 조금 더 남겼지만 그 차이는 대부분 2020년 12월부터 석 달 사이에 났고, 2023년부터는 두 거래소 모두 원조가 더 빨리 불었습니다.

트레이딩뷰에 새로 올라온 'GARCH 슈퍼트렌드'(출렁임에 따라 선의 거리를 바꾸는 슈퍼트렌드)를 같은 생각으로 짜서, 원조 슈퍼트렌드와 맞붙였습니다. 두 봇에는 같은 두 규칙(일봉 50일선 위에서만 산다 · 최근 7일 출렁임이 크면 덜 산다)을 똑같이 달았습니다. 비트코인 4시간봉 실제 가격 · 2017년 12월 6일 ~ 2026년 10월 18일(UTC) · 1,000만원 · 사고팔 때마다 편도 0.1%. 영상의 숫자는 바이낸스 쪽입니다.

1억 1,742만원신상(길이 14 · 배수 2) + 두 규칙 — 가장 크게 줄었던 폭 -31.2%
1억 1,067만원원조(ATR 14 · 배수 2) + 두 규칙 — -28.8%
+46.5% 대 +18.6%최근 2년(2024-10-18~) 수익률 원조 대 신상 — 같은 두 규칙 · 바이낸스

설정 그대로

항목값
차트비트코인 4시간봉 · 현물
신상 슈퍼트렌드기준선 = 지연을 줄인 지수평균(ZLEMA) 길이 14 · 선의 거리 = 배수 2 × ATR 14 × 출렁임 배수(GARCH(1,1) α 0.10 · β 0.85, 0.5~2)
원조 슈퍼트렌드트레이딩뷰 기본 ta.supertrend(ATR 14 · 배수 2)
규칙 ① 50일선어제까지 끝난 일봉 종가가 일봉 50일선 위일 때만 산다 · 밑으로 끝나면 판다
규칙 ② 비중살 때 한 번 — 계좌의 0.5 ÷ 최근 7일(4시간봉 42개) 연율 변동성, 최대 100%. 팔 때까지 수량 그대로
체결봉 마감 판정 · 그 종가 체결 · 편도 0.1%

8년 통째로 앞선 신상 — 그 차이는 어디서 났나

바이낸스업비트
신상 ÷ 원조(끝 잔고) — 전체1.0611.479
2020-12-15 ~ 2021-03-15 석 달1.2111.382
그 석 달을 뺀 나머지0.8761.071
최근 2년(2024-10-18~) 수익률 원조 · 신상+46.5% · +18.6%+93.8% · +41.8%
2023-01-01 부터 끝까지 몇 배 — 원조 · 신상2.81배 · 2.03배3.90배 · 3.46배

1보다 크면 신상이 더 남긴 것. 바이낸스에서는 겨울 석 달을 빼면 원조가 더 남겼습니다.

사고팔 때마다 비용을 늘리면 — 원조 대 신상(길이 14 · 배수 2), 두 규칙 · 바이낸스

편도 비용원조신상
0.075%1억 2,215만원 (-28.2%)1억 3,289만원 (-30.6%)신상이
0.100%1억 1,067만원 (-28.8%)1억 1,742만원 (-31.2%)신상이
0.150%9,084만원 (-29.8%)9,166만원 (-32.4%)신상이
0.200%7,455만원 (-30.8%)7,154만원 (-34.5%)원조가
0.250%6,118만원 (-31.9%)5,583만원 (-38.1%)원조가

신상 봇이 더 자주 사고팝니다(바이낸스 548번 대 456번 — 길이 14 · 배수 2). 업비트는 편도 0.25%까지 신상이 더 남겼습니다.

신상 설정 9가지 — 바이낸스 1,000만원 →

원조 + 두 규칙 1억 1,067만원(-28.8%) · 원조 규칙 없이 6,912만원(-61.5%) · 그냥 보유 6,564만원(-83.9%)

신상 설정두 규칙 달고규칙 없이
길이 14 · 배수 21억 1,742만원 (-31.2%)2억 2,698만원 (-54.0%)
길이 14 · 배수 31억 4,262만원 (-31.7%)2억 7,368만원 (-51.8%)
길이 14 · 배수 41억 5,383만원 (-34.4%)2억 3,806만원 (-45.2%)
길이 20 · 배수 21억 2,258만원 (-30.3%)2억 2,803만원 (-61.3%)
길이 20 · 배수 31억 2,871만원 (-28.6%)2억 1,266만원 (-54.1%)
길이 20 · 배수 41억 6,971만원 (-36.6%)2억 9,664만원 (-38.1%)
길이 50 · 배수 26,760만원 (-35.5%)9,074만원 (-59.0%)
길이 50 · 배수 31억 4,161만원 (-29.7%)1억 9,334만원 (-45.6%)
길이 50 · 배수 41억 3,752만원 (-36.1%)1억 4,314만원 (-44.1%)

같은 계산 — 업비트 원화 1,000만원 →

원조 + 두 규칙 2억 8,118만원(-27.7%) · 원조 규칙 없이 4억 4,282만원(-47.5%) · 그냥 보유 6,542만원(-87.0%)

신상 설정두 규칙 달고규칙 없이
길이 14 · 배수 24억 1,589만원 (-26.6%)9억 2,727만원 (-41.9%)
길이 14 · 배수 33억 3,147만원 (-34.7%)4억 1,681만원 (-53.5%)
길이 14 · 배수 43억 8,800만원 (-32.8%)8억 6,045만원 (-41.7%)
길이 20 · 배수 23억 6,935만원 (-25.6%)9억 250만원 (-45.8%)
길이 20 · 배수 33억 4,754만원 (-35.1%)5억 148만원 (-46.9%)
길이 20 · 배수 43억 6,992만원 (-33.5%)10억 20만원 (-41.7%)
길이 50 · 배수 23억 2,318만원 (-28.8%)5억 8,722만원 (-53.3%)
길이 50 · 배수 34억 2,124만원 (-32.8%)5억 5,009만원 (-41.1%)
길이 50 · 배수 43억 5,771만원 (-36.9%)5억 4,602만원 (-41.4%)

알고 쓰십시오

받아가기

돌리는 법: zip 을 풀고 python run_stnew.py

그대로 돌린 출력

AlgoLab 261102 — 비트코인 슈퍼트렌드 봇: 신상으로 바꿀까, 원조 그대로 둘까

== 바이낸스 4시간봉 · 평가 2017-12-06 ~ 2026-10-18T16:00 · 1,000만원 · 편도 0.1%
  그냥 보유                         6,564만원 (가장 크게 줄었던 폭 -83.9%)
  원조 · 규칙 없이                    6,912만원 (연 24.4% · 가장 크게 줄었던 폭 -61.5%) · 사고판 횟수 746번
  원조 · 두 규칙                  1억 1,067만원 (연 31.2% · 가장 크게 줄었던 폭 -28.8%) · 사고판 횟수 456번
  신상 9가지(길이 n · 배수 m)          두 규칙                         규칙 없이
    n14  m2       1억 1,742만원 ( -31.2%)            2억 2,698만원 ( -54.0%)
    n14  m3       1억 4,262만원 ( -31.7%)            2억 7,368만원 ( -51.8%)
    n14  m4       1억 5,383만원 ( -34.4%)            2억 3,806만원 ( -45.2%)
    n20  m2       1억 2,258만원 ( -30.3%)            2억 2,803만원 ( -61.3%)
    n20  m3       1억 2,871만원 ( -28.6%)            2억 1,266만원 ( -54.1%)
    n20  m4       1억 6,971만원 ( -36.6%)            2억 9,664만원 ( -38.1%)
    n50  m2          6,760만원 ( -35.5%)               9,074만원 ( -59.0%)
    n50  m3       1억 4,161만원 ( -29.7%)            1억 9,334만원 ( -45.6%)
    n50  m4       1억 3,752만원 ( -36.1%)            1억 4,314만원 ( -44.1%)
  → 두 규칙을 달았을 때 신상이 원조보다 더 남긴 설정: 8/9 · 가장 크게 줄었던 폭이 35% 를 넘긴 신상 설정: 3/9
  → 사고판 횟수(두 규칙): 신상 길이 14·배수 2 548번 · 원조 456번
  → 평균하면 계좌의 몇 %를 비트코인으로 들고 있었나(두 규칙): 원조 27% · 신상 길이 14·배수 2 27%
  → 한 봉 늦게 체결하면(두 규칙): 원조 1억 318만원 (-34.6%) · 신상 길이 14·배수 2 1억 4,041만원 (-34.7%)
  → 출렁임 계산(GARCH)을 켠 판이 끈 판(기준선만 ZLEMA)보다 더 남긴 설정: 2/9
  수수료·밀림을 늘리면(사고팔 때마다 편도) — 원조 · 두 규칙 대 신상 길이 14 배수 2 · 두 규칙
    편도 0.075%  원조     1억 2,215만원 ( -28.2%)  신상     1억 3,289만원 ( -30.6%)  신상이 더 남김
    편도 0.100%  원조     1억 1,067만원 ( -28.8%)  신상     1억 1,742만원 ( -31.2%)  신상이 더 남김
    편도 0.150%  원조        9,084만원 ( -29.8%)  신상        9,166만원 ( -32.4%)  신상이 더 남김
    편도 0.200%  원조        7,455만원 ( -30.8%)  신상        7,154만원 ( -34.5%)  원조가 더 남김
    편도 0.250%  원조        6,118만원 ( -31.9%)  신상        5,583만원 ( -38.1%)  원조가 더 남김
  최근 2년(2024-10-18 ~ 끝, 두 규칙 · 그 날 계좌에서 다시 잼): 원조 +46.5% · 신상 +18.6%
  2022년 말부터(2023-01-01 ~ 끝, 두 규칙): 원조 2.81배 · 신상 2.03배
  신상 ÷ 원조(끝 잔고): 전체 1.061 · 2020-12-15~2021-03-15 석 달 1.211 · 그 석 달을 뺀 나머지 0.876

== 업비트 4시간봉 · 평가 2017-12-06 ~ 2026-10-18T16:00 · 1,000만원 · 편도 0.1%
  그냥 보유                         6,542만원 (가장 크게 줄었던 폭 -87.0%)
  원조 · 규칙 없이                 4억 4,282만원 (연 53.4% · 가장 크게 줄었던 폭 -47.5%) · 사고판 횟수 700번
  원조 · 두 규칙                  2억 8,118만원 (연 45.7% · 가장 크게 줄었던 폭 -27.7%) · 사고판 횟수 436번
  신상 9가지(길이 n · 배수 m)          두 규칙                         규칙 없이
    n14  m2       4억 1,589만원 ( -26.6%)            9억 2,727만원 ( -41.9%)
    n14  m3       3억 3,147만원 ( -34.7%)            4억 1,681만원 ( -53.5%)
    n14  m4       3억 8,800만원 ( -32.8%)            8억 6,045만원 ( -41.7%)
    n20  m2       3억 6,935만원 ( -25.6%)              9억 250만원 ( -45.8%)
    n20  m3       3억 4,754만원 ( -35.1%)              5억 148만원 ( -46.9%)
    n20  m4       3억 6,992만원 ( -33.5%)              10억 20만원 ( -41.7%)
    n50  m2       3억 2,318만원 ( -28.8%)            5억 8,722만원 ( -53.3%)
    n50  m3       4억 2,124만원 ( -32.8%)            5억 5,009만원 ( -41.1%)
    n50  m4       3억 5,771만원 ( -36.9%)            5억 4,602만원 ( -41.4%)
  → 두 규칙을 달았을 때 신상이 원조보다 더 남긴 설정: 9/9 · 가장 크게 줄었던 폭이 35% 를 넘긴 신상 설정: 2/9
  → 사고판 횟수(두 규칙): 신상 길이 14·배수 2 510번 · 원조 436번
  → 평균하면 계좌의 몇 %를 비트코인으로 들고 있었나(두 규칙): 원조 28% · 신상 길이 14·배수 2 27%
  → 한 봉 늦게 체결하면(두 규칙): 원조 3억 1,693만원 (-28.2%) · 신상 길이 14·배수 2 4억 5,590만원 (-31.6%)
  → 출렁임 계산(GARCH)을 켠 판이 끈 판(기준선만 ZLEMA)보다 더 남긴 설정: 7/9
  수수료·밀림을 늘리면(사고팔 때마다 편도) — 원조 · 두 규칙 대 신상 길이 14 배수 2 · 두 규칙
    편도 0.075%  원조     3억 1,013만원 ( -26.9%)  신상     4억 6,820만원 ( -26.2%)  신상이 더 남김
    편도 0.100%  원조     2억 8,118만원 ( -27.7%)  신상     4억 1,589만원 ( -26.6%)  신상이 더 남김
    편도 0.150%  원조     2억 3,112만원 ( -29.4%)  신상     3억 2,812만원 ( -28.3%)  신상이 더 남김
    편도 0.200%  원조     1억 8,996만원 ( -31.0%)  신상     2억 5,884만원 ( -29.9%)  신상이 더 남김
    편도 0.250%  원조     1억 5,611만원 ( -32.6%)  신상       2억 417만원 ( -31.5%)  신상이 더 남김
  최근 2년(2024-10-18 ~ 끝, 두 규칙 · 그 날 계좌에서 다시 잼): 원조 +93.8% · 신상 +41.8%
  2022년 말부터(2023-01-01 ~ 끝, 두 규칙): 원조 3.90배 · 신상 3.46배
  신상 ÷ 원조(끝 잔고): 전체 1.479 · 2020-12-15~2021-03-15 석 달 1.382 · 그 석 달을 뺀 나머지 1.071

끝.

재현 코드 전문

# -*- coding: utf-8 -*-
"""AlgoLab 261102 — 비트코인 슈퍼트렌드 봇: 신상(GARCH 슈퍼트렌드)으로 바꿀까, 원조 그대로 둘까.

같은 폴더의 data/ (바이낸스 BTCUSDT · 업비트 KRW-BTC 4시간봉, 2017-10-01 ~ 2026-10-18 16:00 UTC 얼림)만 읽는다.
필요한 것: Python 3.9+ · numpy.   돌리는 법:  python run_stnew.py

두 봇에 똑같이 다는 두 규칙
  ① 어제까지 끝난 일봉(UTC) 종가가 일봉 50일 이동평균보다 높을 때만 산다
  ② 살 때 한 번만 비중을 정한다: 0.5 ÷ 최근 4시간봉 42개 연율 변동성(최대 100%), 팔 때까지 수량 그대로
판정은 봉 마감, 체결은 그 봉 종가 · 편도 수수료 0.1% · 처음 400봉은 지표 준비(평가는 2017-12-06 부터)

원조 = 트레이딩뷰 ta.supertrend(ATR 14, 배수 2)
신상 = GARCH 슈퍼트렌드(같은 생각으로 저희가 짠 판 — 트레이딩뷰에 올라온 특정 스크립트 그대로가 아니다):
       기준선 = 지연을 줄인 지수평균(ZLEMA, 길이 n) · 선의 거리 = 배수 m × ATR 14 × 출렁임 배수
       출렁임 배수 = sqrt(GARCH(1,1) 조건부 분산 ÷ 장기 분산), α 0.10 · β 0.85, 0.5~2 로 자름
"""
import datetime
import os
import sys

import numpy as np

sys.stdout.reconfigure(encoding="utf-8", errors="replace")
HERE = os.path.dirname(os.path.abspath(__file__))
FILES = [("바이낸스", "바이낸스_BTCUSDT_4h.csv"), ("업비트", "업비트_KRW-BTC_4h.csv")]
WARM, FEE, W0 = 400, 0.001, 1000.0   # W0 = 1,000만원


def load(fn):
    d, rows = [], []
    with open(os.path.join(HERE, "data", fn), encoding="utf-8") as f:
        next(f)
        for line in f:
            p = line.rstrip("\n").split(",")
            d.append(p[0]); rows.append([float(x) for x in p[1:5]])
    a = np.asarray(rows)
    o, h, l, c = a[:, 0], a[:, 1], a[:, 2], a[:, 3]
    yrs = (datetime.date.fromisoformat(d[-1][:10]) - datetime.date.fromisoformat(d[0][:10])).days / 365.25
    ret = np.zeros(len(c)); ret[1:] = c[1:] / c[:-1] - 1
    return dict(d=d, o=o, h=h, l=l, c=c, ret=ret, ppy=len(c) / yrs)


def sma(x, n):
    out = np.full(len(x), np.nan)
    if len(x) >= n:
        cs = np.cumsum(np.insert(x, 0, 0.0)); out[n - 1:] = (cs[n:] - cs[:-n]) / n
    return out


def ema(x, n):
    a = 2.0 / (n + 1); out = np.empty(len(x)); out[0] = x[0]
    for i in range(1, len(x)):
        out[i] = a * x[i] + (1 - a) * out[i - 1]
    return out


def atr(h, l, c, n):
    pc = np.r_[c[0], c[:-1]]
    tr = np.maximum(h - l, np.maximum(np.abs(h - pc), np.abs(l - pc)))
    a = np.full(len(tr), np.nan)
    if len(tr) >= n:
        a[n - 1] = tr[:n].mean()
        for i in range(n, len(tr)):
            a[i] = a[i - 1] + (tr[i] - a[i - 1]) / n
    return a


def supertrend_original(h, l, c, n=14, factor=2.0):
    """트레이딩뷰 ta.supertrend 그대로 — 1 = 상승(보유)."""
    at = atr(h, l, c, n); src = (h + l) / 2
    up = src + factor * at; lo = src - factor * at
    N = len(c); d = np.zeros(N); upper = np.ones(N, dtype=bool)
    for i in range(1, N):
        if np.isnan(at[i]):
            continue
        pl = lo[i - 1] if not np.isnan(lo[i - 1]) else 0.0
        pu = up[i - 1] if not np.isnan(up[i - 1]) else 0.0
        lo[i] = lo[i] if (lo[i] > pl or c[i - 1] < pl) else pl
        up[i] = up[i] if (up[i] < pu or c[i - 1] > pu) else pu
        if np.isnan(at[i - 1]):
            dirn = 1
        elif upper[i - 1]:
            dirn = -1 if c[i] > up[i] else 1
        else:
            dirn = 1 if c[i] < lo[i] else -1
        upper[i] = dirn == 1
        d[i] = 1.0 if dirn == -1 else 0.0
    return d


def supertrend_new(h, l, c, n=14, m=2.0, garch=True, a=0.10, b=0.85):
    """신상 GARCH 슈퍼트렌드 — garch=False 면 출렁임 계산을 끈 판(기준선만 ZLEMA)."""
    lag = (n - 1) // 2
    src = c + (c - np.r_[np.full(lag, c[0]), c[:-lag]]) if lag > 0 else c
    base = ema(src, n); at = atr(h, l, c, 14); N = len(c)
    reg = np.ones(N)
    if garch:
        r = np.zeros(N); r[1:] = np.log(c[1:] / c[:-1]); cum = np.cumsum(r * r)
        s2 = np.empty(N); s2[0] = r[1] ** 2
        for t in range(1, N):
            lr = cum[t - 1] / t
            s2[t] = (1 - a - b) * lr + a * r[t - 1] ** 2 + b * s2[t - 1]
            reg[t] = np.sqrt(s2[t] / lr) if lr > 0 else 1.0
        reg = np.clip(reg, 0.5, 2.0)
    upb = base - m * at * reg; dnb = base + m * at * reg
    d = np.ones(N)
    for i in range(1, N):
        if np.isnan(at[i]) or np.isnan(at[i - 1]):
            continue
        if c[i - 1] > upb[i - 1]:
            upb[i] = max(upb[i], upb[i - 1])
        if c[i - 1] < dnb[i - 1]:
            dnb[i] = min(dnb[i], dnb[i - 1])
        d[i] = 1 if c[i] > dnb[i - 1] else (-1 if c[i] < upb[i - 1] else d[i - 1])
    return (d > 0).astype(float)


def rule_50d(dates, c, n=50):
    """규칙 ①: 어제까지 끝난 일봉(UTC) 종가 > 일봉 50일선."""
    days = np.array([x[:10] for x in dates])
    uniq, first = np.unique(days, return_index=True)
    order = np.argsort(first); uniq = uniq[order]
    last_idx = np.r_[np.sort(first)[1:] - 1, len(c) - 1]
    dc = c[last_idx]; s = sma(dc, n)
    up = np.zeros(len(uniq)); mm = ~np.isnan(s); up[mm] = dc[mm] > s[mm]
    pos = {u: k for k, u in enumerate(uniq)}
    out = np.zeros(len(c))
    for i, dd in enumerate(days):
        k = pos[dd] - 1
        if k >= 0:
            out[i] = up[k]
    return out


def rule_weight(c, target=0.5, win=42, ppy=2190.0):
    """규칙 ②의 목표 비중: 0.5 ÷ 최근 42봉 연율 변동성(최대 1)."""
    N = len(c); r = np.zeros(N); r[1:] = c[1:] / c[:-1] - 1
    w = np.ones(N)
    for t in range(win, N):
        v = r[t - win + 1:t + 1].std() * np.sqrt(ppy)
        w[t] = min(1.0, target / v) if v > 1e-9 else 1.0
    return w


def account(c, tw, entry_only=True, fee=FEE):
    """코인 수량으로 드는 계좌. entry_only=True 면 살 때만 비중을 정하고 팔 때까지 수량 그대로."""
    N = len(c); E = np.ones(N); cash, units = 1.0, 0.0; k = 0; held = np.zeros(N)
    for i in range(N):
        eq = cash + units * c[i]
        cur = units * c[i] / eq if eq > 0 else 0.0
        t = tw[i]
        new = 0.0 if t <= 0 else (t if (not entry_only or cur == 0) else cur)
        if abs(new - cur) > 1e-12:
            eq -= fee * abs(new - cur) * eq
            units = new * eq / c[i]; cash = eq - units * c[i]; k += 1
        E[i] = eq; held[i] = new
    return E, held, k


def stats(S, E):
    e = E[WARM:] / E[WARM - 1]
    yrs = len(e) / S["ppy"]
    cagr = e[-1] ** (1 / yrs) - 1
    mdd = float((e / np.maximum.accumulate(e) - 1).min())
    return e[-1] * W0, cagr * 100, mdd * 100


def won(x):
    x = int(round(x))
    return f"{x // 10000}억 {x % 10000:,}만원" if x >= 10000 else f"{x:,}만원"


def show(tag, S, E, k=None):
    end, cg, md = stats(S, E)
    print(f"  {tag:<22} {won(end):>14} (연 {cg:.1f}% · 가장 크게 줄었던 폭 {md:.1f}%)" + (f" · 사고판 횟수 {k}번" if k else ""))
    return int(round(end)), round(md, 1)


print("AlgoLab 261102 — 비트코인 슈퍼트렌드 봇: 신상으로 바꿀까, 원조 그대로 둘까")
for name, fn in FILES:
    S = load(fn); c, h, l = S["c"], S["h"], S["l"]
    f50 = rule_50d(S["d"], c); wv = rule_weight(c)
    print(f"\n== {name} 4시간봉 · 평가 {S['d'][WARM][:10]} ~ {S['d'][-1][:16]} · 1,000만원 · 편도 0.1%")
    hold = np.cumprod(1 + S["ret"]); hold = hold / hold[WARM - 1]
    print(f"  {'그냥 보유':<22} {won(hold[-1] * W0):>14} (가장 크게 줄었던 폭 {float((hold[WARM:] / np.maximum.accumulate(hold[WARM:]) - 1).min()) * 100:.1f}%)")
    so = supertrend_original(h, l, c)
    E, _, k = account(c, so, entry_only=False); o_raw = show("원조 · 규칙 없이", S, E, k)
    E, _, k = account(c, so * f50 * wv); o_dev = show("원조 · 두 규칙", S, E, k); o_dev_k = k
    more, deep35 = 0, 0
    print("  신상 9가지(길이 n · 배수 m)          두 규칙                         규칙 없이")
    for n in (14, 20, 50):
        for m in (2.0, 3.0, 4.0):
            sn = supertrend_new(h, l, c, n, m)
            Ed, _, kd = account(c, sn * f50 * wv); Er, _, kr = account(c, sn, entry_only=False)
            ed, cd, md = stats(S, Ed); er, cr, mr = stats(S, Er)
            more += int(round(ed)) > o_dev[0]; deep35 += md < -35
            print(f"    n{n:<3} m{m:g}   {won(ed):>14} ({md:6.1f}%)        {won(er):>14} ({mr:6.1f}%)")
    print(f"  → 두 규칙을 달았을 때 신상이 원조보다 더 남긴 설정: {more}/9 · 가장 크게 줄었던 폭이 35% 를 넘긴 신상 설정: {deep35}/9")
    _, held14, k14 = account(c, supertrend_new(h, l, c, 14, 2.0) * f50 * wv)
    _, heldo, _ = account(c, so * f50 * wv)
    print(f"  → 사고판 횟수(두 규칙): 신상 길이 14·배수 2 {k14}번 · 원조 {o_dev_k}번")
    print(f"  → 평균하면 계좌의 몇 %를 비트코인으로 들고 있었나(두 규칙): 원조 {heldo[WARM:].mean() * 100:.0f}% · 신상 길이 14·배수 2 {held14[WARM:].mean() * 100:.0f}%")
    lag = lambda x: np.r_[0.0, x[:-1]]
    Eo1, _, _ = account(c, lag(so * f50 * wv)); En1, _, _ = account(c, lag(supertrend_new(h, l, c, 14, 2.0) * f50 * wv))
    eo1, _, mo1 = stats(S, Eo1); en1, _, mn1 = stats(S, En1)
    print(f"  → 한 봉 늦게 체결하면(두 규칙): 원조 {won(eo1)} ({mo1:.1f}%) · 신상 길이 14·배수 2 {won(en1)} ({mn1:.1f}%)")
    zg = 0
    for n in (14, 20, 50):
        for m in (2.0, 3.0, 4.0):
            Eg, _, _ = account(c, supertrend_new(h, l, c, n, m, True) * f50 * wv)
            Ez, _, _ = account(c, supertrend_new(h, l, c, n, m, False) * f50 * wv)
            zg += Eg[-1] > Ez[-1]
    print(f"  → 출렁임 계산(GARCH)을 켠 판이 끈 판(기준선만 ZLEMA)보다 더 남긴 설정: {zg}/9")
    print("  수수료·밀림을 늘리면(사고팔 때마다 편도) — 원조 · 두 규칙 대 신상 길이 14 배수 2 · 두 규칙")
    sn = supertrend_new(h, l, c, 14, 2.0)
    for fee in (0.00075, 0.001, 0.0015, 0.002, 0.0025):
        Eo, _, _ = account(c, so * f50 * wv, fee=fee); En, _, _ = account(c, sn * f50 * wv, fee=fee)
        eo, _, mo = stats(S, Eo); en, _, mn = stats(S, En)
        print(f"    편도 {fee * 100:.3f}%  원조 {won(eo):>14} ({mo:6.1f}%)  신상 {won(en):>14} ({mn:6.1f}%)  {'신상이 더 남김' if en > eo else '원조가 더 남김'}")
    Eo, _, _ = account(c, so * f50 * wv); En, _, _ = account(c, sn * f50 * wv)
    i2 = next(k for k, x in enumerate(S["d"]) if x >= "2024-10-18")
    print(f"  최근 2년(2024-10-18 ~ 끝, 두 규칙 · 그 날 계좌에서 다시 잼): 원조 {(Eo[-1] / Eo[i2 - 1] - 1) * 100:+.1f}% · 신상 {(En[-1] / En[i2 - 1] - 1) * 100:+.1f}%")
    i3 = next(k for k, x in enumerate(S["d"]) if x >= "2023-01-01")
    print(f"  2022년 말부터(2023-01-01 ~ 끝, 두 규칙): 원조 {Eo[-1] / Eo[i3 - 1]:.2f}배 · 신상 {En[-1] / En[i3 - 1]:.2f}배")
    a = next(k for k, x in enumerate(S["d"]) if x >= "2020-12-15"); b = next(k for k, x in enumerate(S["d"]) if x >= "2021-03-15")
    tot = (En[-1] / En[WARM - 1]) / (Eo[-1] / Eo[WARM - 1]); seg = (En[b] / En[a]) / (Eo[b] / Eo[a])
    print(f"  신상 ÷ 원조(끝 잔고): 전체 {tot:.3f} · 2020-12-15~2021-03-15 석 달 {seg:.3f} · 그 석 달을 뺀 나머지 {tot / seg:.3f}")
print("\n끝.")

알고랩 Strategy Lab — 전략을 검증하고, 검증한 것만 자동매매로 옮깁니다. 4시간마다 봉이 끝날 때 판정하고 그 자리에서 주문하는 일은 사람보다 봇이 잘합니다. 알고랩 자동매매 살펴보기 · 전략 검증 전체 보기

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