WLD DeepCoin 단계별 구조 재편 및 설정·문서 통합
로고스/루트 레거시를 제거하고 deepcoin 패키지·scripts 01~05 CLI·docs/reference로 데이터·GT·분석·매칭·운영 단계를 정리했다. config와 .env 기반 설정, trade_anaysis.html 동기화 포함. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
92
deepcoin/analysis/general_analysis_volume.py
Normal file
92
deepcoin/analysis/general_analysis_volume.py
Normal file
@@ -0,0 +1,92 @@
|
||||
"""
|
||||
general_analysis Volume Profile (POC, VAH, VAL).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
from config import GA_VP_BINS, GA_VP_VALUE_AREA_PCT
|
||||
from deepcoin.analysis.general_analysis_core import ga_col
|
||||
|
||||
|
||||
def general_analysis_volume_profile(
|
||||
win: pd.DataFrame,
|
||||
bins: int | None = None,
|
||||
value_area_pct: float | None = None,
|
||||
) -> dict[str, float | int]:
|
||||
"""
|
||||
lookback 구간 가격-거래량 분포에서 POC·VAH·VAL 계산.
|
||||
|
||||
Args:
|
||||
win: OHLCV.
|
||||
bins: 가격 구간 수.
|
||||
value_area_pct: value area 누적 비율 (기본 70%).
|
||||
|
||||
Returns:
|
||||
ga_vp_* 키 dict (접두사 없음).
|
||||
"""
|
||||
res: dict[str, float | int] = {
|
||||
"vp_poc": 0.0,
|
||||
"vp_vah": 0.0,
|
||||
"vp_val": 0.0,
|
||||
"vp_close_vs_poc_pct": 0.0,
|
||||
"vp_in_value_area": 0,
|
||||
}
|
||||
if bins is None:
|
||||
bins = GA_VP_BINS
|
||||
if value_area_pct is None:
|
||||
value_area_pct = GA_VP_VALUE_AREA_PCT
|
||||
|
||||
if win is None or len(win) < 10 or "Volume" not in win.columns:
|
||||
return res
|
||||
|
||||
h = win["High"].astype(float).values
|
||||
l = win["Low"].astype(float).values
|
||||
c = win["Close"].astype(float).values
|
||||
v = win["Volume"].astype(float).values
|
||||
tp = (h + l + c) / 3.0
|
||||
|
||||
lo, hi = float(l.min()), float(h.max())
|
||||
if hi <= lo:
|
||||
return res
|
||||
|
||||
edges = np.linspace(lo, hi, bins + 1)
|
||||
hist = np.zeros(bins, dtype=float)
|
||||
for i in range(len(tp)):
|
||||
idx = int(np.clip(np.digitize(tp[i], edges) - 1, 0, bins - 1))
|
||||
hist[idx] += v[i]
|
||||
|
||||
if hist.sum() <= 0:
|
||||
return res
|
||||
|
||||
poc_idx = int(np.argmax(hist))
|
||||
poc = float((edges[poc_idx] + edges[poc_idx + 1]) / 2)
|
||||
res["vp_poc"] = poc
|
||||
|
||||
order = np.argsort(hist)[::-1]
|
||||
cum = 0.0
|
||||
selected: list[int] = []
|
||||
total = hist.sum()
|
||||
for idx in order:
|
||||
selected.append(int(idx))
|
||||
cum += hist[idx]
|
||||
if cum >= total * value_area_pct:
|
||||
break
|
||||
sel_min, sel_max = min(selected), max(selected)
|
||||
res["vp_val"] = float(edges[sel_min])
|
||||
res["vp_vah"] = float(edges[sel_max + 1])
|
||||
res["vp_close_vs_poc_pct"] = float((c[-1] / poc - 1) * 100) if poc else 0.0
|
||||
res["vp_in_value_area"] = int(res["vp_val"] <= c[-1] <= res["vp_vah"])
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def general_analysis_volume_columns() -> list[str]:
|
||||
return ["vp_poc", "vp_vah", "vp_val", "vp_close_vs_poc_pct", "vp_in_value_area"]
|
||||
|
||||
|
||||
def general_analysis_volume_snapshot(win: pd.DataFrame) -> dict[str, object]:
|
||||
"""Volume profile → ga_vp_*."""
|
||||
return {ga_col(k): v for k, v in general_analysis_volume_profile(win).items()}
|
||||
Reference in New Issue
Block a user