전 봉 BB·일목 조합 분석 및 simulation 단일 실행으로 통합

9개 간격(1~1440분) BB·일목 위치 특징을 3분 타임라인에 맞춰 분석하고,
discover로 매수·매도 규칙을 찾은 뒤 HTML 차트에 해당 체결만 표시한다.
simulation_1h.py를 simulation.py로 변경했으며, 파라미터 없이 실행하면
analyze→discover→차트가 한 번에 수행된다.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dsyoon
2026-05-29 01:20:36 +09:00
parent 7d53090034
commit e218a8ea32
15 changed files with 1510 additions and 803 deletions

58
indicators.py Normal file
View File

@@ -0,0 +1,58 @@
"""
볼린저 밴드·일목균형표 계산 (모든 봉 간격 공용).
"""
from __future__ import annotations
import numpy as np
import pandas as pd
from config import BB_PERIOD, BB_STD
def add_bollinger(
df: pd.DataFrame,
period: int = BB_PERIOD,
std_mult: float = BB_STD,
) -> pd.DataFrame:
"""MA, Upper, Lower, BB_Width, bb_pos 컬럼 추가."""
out = df.copy()
if "MA" not in out.columns:
out["MA"] = out["Close"].rolling(period).mean()
if "Upper" not in out.columns or "Lower" not in out.columns:
std = out["Close"].rolling(period).std()
out["STD"] = std
out["Upper"] = out["MA"] + std_mult * std
out["Lower"] = out["MA"] - std_mult * std
ma = out["MA"].replace(0, np.nan)
band = (out["Upper"] - out["Lower"]).replace(0, np.nan)
out["bb_pos"] = ((out["Close"] - out["Lower"]) / band).clip(0, 1)
out["BB_Width"] = band / ma * 100
return out
def add_ichimoku(
df: pd.DataFrame,
tenkan: int = 9,
kijun: int = 26,
senkou_b_period: int = 52,
) -> pd.DataFrame:
"""
일목균형표 라인·구름 위치 컬럼 추가 (해당 봉 시점, 미래 데이터 미사용).
Returns:
ichi_tenkan, ichi_kijun, ichi_span_a, ichi_span_b,
ichi_cloud_top, ichi_cloud_bottom
"""
out = df.copy()
h = out["High"].astype(float)
l = out["Low"].astype(float)
c = out["Close"].astype(float)
out["ichi_tenkan"] = (h.rolling(tenkan).max() + l.rolling(tenkan).min()) / 2
out["ichi_kijun"] = (h.rolling(kijun).max() + l.rolling(kijun).min()) / 2
out["ichi_span_a"] = (out["ichi_tenkan"] + out["ichi_kijun"]) / 2
out["ichi_span_b"] = (h.rolling(senkou_b_period).max() + l.rolling(senkou_b_period).min()) / 2
out["ichi_cloud_top"] = np.maximum(out["ichi_span_a"], out["ichi_span_b"])
out["ichi_cloud_bottom"] = np.minimum(out["ichi_span_a"], out["ichi_span_b"])
return out