Compare commits
6
Commits
chanmacro
...
7f393b93ed
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f393b93ed | ||
|
|
5c10e35b76 | ||
|
|
8c165f11cd | ||
|
|
97e77847d0 | ||
|
|
90499533fb | ||
|
|
8ee11317d3 |
+8
-28
@@ -1,42 +1,22 @@
|
||||
# MacOS
|
||||
.DS_Store
|
||||
|
||||
# Python编译文件和缓存
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.pyc
|
||||
*.pyo
|
||||
.pytest_cache/
|
||||
|
||||
# 策略文件的缓存
|
||||
strategies/__pycache__/
|
||||
|
||||
# Machine Learning / AI model files
|
||||
*_model*_xgb_model.json
|
||||
*modelchan*.json
|
||||
*.libsvm
|
||||
feature_meta
|
||||
*_model_feature_data.csv
|
||||
*.pem
|
||||
|
||||
# Log files
|
||||
# Logs & databases
|
||||
*.log
|
||||
|
||||
# Database files
|
||||
*.sqlite
|
||||
*.sqlite-shm
|
||||
*.sqlite-wal
|
||||
.DS_Store
|
||||
交易记录/~$交易规则.docx
|
||||
/datasvc/data
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
/data_provider/data
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
data_provider/._config.json
|
||||
|
||||
# Local data
|
||||
data/
|
||||
|
||||
# Local tooling
|
||||
.gstack/
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# chan — Agent Entry
|
||||
|
||||
本仓受 ESS 约束。不要一上来扫全库或加载全部 governance。
|
||||
|
||||
## Boot
|
||||
|
||||
1. `docs/PROJECT_PROFILE.md`
|
||||
2. `docs/PROJECT_RULES.md`
|
||||
3. `docs/STATE/CURRENT.md` + `docs/AGENT_MEMORY.md`
|
||||
4. 有进行中任务再读 `docs/TASKS/` / 对应 ECR / HANDOFF
|
||||
5. 角色文件:ESS 根目录 `agents/{ARCHITECT|ENGINEER|REVIEWER|RELEASE_MANAGER}.md`
|
||||
|
||||
## Roles(选一)
|
||||
|
||||
| 意图 | 角色 |
|
||||
|------|------|
|
||||
| 规格 / 架构 / ECR | ARCHITECT |
|
||||
| 实现 / 修 bug | ENGINEER |
|
||||
| 审阅 | REVIEWER |
|
||||
| 发版 / tag | RELEASE_MANAGER |
|
||||
|
||||
## Never
|
||||
|
||||
- 无 ECR 改 `config/` / `strategies/` 交易逻辑
|
||||
- 无 ADR 改缠论算法语义
|
||||
- 无 ECR 删减 `/api/analyze` 字段
|
||||
- 把聊天记录当成完成;阶段结束须落盘 `docs/`
|
||||
|
||||
## Pointers
|
||||
|
||||
- TRACEABILITY: `docs/TRACEABILITY.md`
|
||||
- CHANGELOG: `docs/CHANGELOG/CHANGELOG.md`
|
||||
- 人类向导:`CLAUDE.md`
|
||||
@@ -1,116 +0,0 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
缠论 (Chan Theory) technical analysis system for Freqtrade. Implements Chan Zhong Shui Chan's theory for crypto/stock trading, including fractal (分型), stroke (笔), segment (线段), pivot/center (中枢), and buy/sell point (买卖点) detection.
|
||||
|
||||
## Governance
|
||||
|
||||
- Agent 入口:`AGENTS.md`(boot 顺序)· `docs/PROJECT_PROFILE.md` · `docs/AGENT_MEMORY.md` · `docs/STATE/CURRENT.md`
|
||||
- ESS 文档:`docs/ECR/`、`docs/ENGINEERING_SPEC/`、`docs/TRACEABILITY.md`、`docs/CHANGELOG/`
|
||||
- **正式引擎包**:`chanlun/`;strategies / web 已用 `from chanlun import ...`
|
||||
- 根目录 `Chan*.py` / `TF_DF.py` 仍为 **兼容 shim**(旧脚本可用)
|
||||
- 变更分级:无 ECR 不改 strategies/config;无 ADR 不改缠论算法语义
|
||||
|
||||
## Core Architecture
|
||||
|
||||
### Chan Theory Engine (`chanlun/`)
|
||||
|
||||
```text
|
||||
chanlun/
|
||||
core/ # KLU KLC BI SBI SEG ZS BIZS BSP Enum CTime
|
||||
pipeline/ # orchestrator(ChanLun) + timeframe(TF_DF) + builders/
|
||||
indicators/ # ChanMACD*
|
||||
analysis/ # Zone Classifier Pivot Heng PY Find_Trend ...
|
||||
```
|
||||
|
||||
Data processing pipeline (each step feeds the next):
|
||||
|
||||
1. **`chanlun.core.ChanKLU`** — Raw K-line unit with TA indicators and pattern recognition
|
||||
2. **`chanlun.core.ChanKLC`** — Combined K-line: inclusion + fractal; `.next`/`.pre` linked list
|
||||
3. **`chanlun.core.ChanBI`** — Stroke (笔)
|
||||
4. **`chanlun.core.ChanSBI`** — Special stroke → SEG
|
||||
5. **`chanlun.core.ChanSEG`** — Segment (线段)
|
||||
6. **`chanlun.core.ChanZS`** / **`ChanBIZS`** — Centers (中枢)
|
||||
7. **`chanlun.core.ChanBSP`** — Buy/Sell points
|
||||
8. **`chanlun.pipeline.orchestrator.ChanLun`** — Orchestrator
|
||||
9. **`chanlun.pipeline.timeframe.TF_DF`** — Timeframe facade;实现拆在 `pipeline/builders/`
|
||||
|
||||
### Services
|
||||
|
||||
- **外部 DATA_SERVICE** — 行情服务(env: `DATA_SERVICE_URL`);本仓库可不含 data_provider 源码
|
||||
- **`web/`** — Flask UI:`create_app()` + `api/` blueprints + `services/`;前端 `static/js/app/`。默认端口见 `web/config.py`(`FLASK_PORT`,常见 8128)
|
||||
- **`strategies/`** — Freqtrade strategies(本 ECR 不改)
|
||||
- **`config/`** — Freqtrade configs(本 ECR 不改)
|
||||
|
||||
### Data Flow
|
||||
|
||||
```
|
||||
Exchange / DATA_SERVICE → Freqtrade Strategy / web → ChanLun → TF_DF
|
||||
→ KLU → KLC → BI → SBI → SEG → ZS → BSP
|
||||
```
|
||||
|
||||
## Common Commands
|
||||
|
||||
### Freqtrade Trading
|
||||
|
||||
```bash
|
||||
# Live trade
|
||||
freqtrade trade -c ./user_data/Chan/config/<config>.json --strategy <StrategyName> --strategy-path ./user_data/Chan/strategies
|
||||
|
||||
# Backtest
|
||||
freqtrade backtesting -c ./user_data/Chan/config/<config>.json --strategy <StrategyName> --strategy-path ./user_data/Chan/strategies --timerange=20251008-
|
||||
|
||||
# Download data
|
||||
freqtrade download-data -c ./user_data/Chan/config/<config>.json -t 1m 1h 1d --pairs BTC/USDT:USDT --timerange=20240101-
|
||||
|
||||
# Hyperopt
|
||||
freqtrade hyperopt --hyperopt-loss SharpeHyperOptLossDaily --spaces roi --strategy <StrategyName> --strategy-path ./user_data/Chan/strategies -c ./user_data/Chan/config/<config>.json -e 200 --timerange=20250201-20250901
|
||||
|
||||
# Plot
|
||||
freqtrade plot-dataframe --strategy <StrategyName> --datadir user_data/data/binance -c ./user_data/Chan/config/<config>.json --timerange=20250721-
|
||||
```
|
||||
|
||||
### Data Provider
|
||||
|
||||
```bash
|
||||
# Docker
|
||||
cd data_provider && docker compose up -d
|
||||
|
||||
# Direct
|
||||
cd data_provider && python main.py
|
||||
|
||||
# With custom config
|
||||
CONFIG_PATH=./config.json python main.py
|
||||
```
|
||||
|
||||
### Web UI
|
||||
|
||||
```bash
|
||||
cd web && python app.py
|
||||
# or via gunicorn:
|
||||
gunicorn -w 4 -b 0.0.0.0:8123 app:app
|
||||
|
||||
# Deploy scripts:
|
||||
cd web && ./deploy.sh # standard
|
||||
cd web && ./deploy_venv.sh # Ubuntu 22.04+ (venv)
|
||||
```
|
||||
|
||||
### Docker (Freqtrade)
|
||||
|
||||
```bash
|
||||
sudo docker compose run --rm chanlun_btc backtesting -c ./user_data/Chan/config/<config>.json --strategy <StrategyName> --strategy-path ./user_data/Chan/strategies --timerange=20250721-
|
||||
```
|
||||
|
||||
## Key Conventions
|
||||
|
||||
- All Chan theory classes are prefixed with `Chan` (e.g., `ChanBI`, `ChanZS`)
|
||||
- Strategies import `ChanLun` and add `sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))` to import from parent
|
||||
- MACD params: `MACD(26, 52, 9)` by default (slow period 52 instead of standard 26)
|
||||
- Enums in `ChanEnum.py` use `auto()` values
|
||||
- `ChanKLC` is a linked-list style data structure with `.next`/`.pre` pointers
|
||||
- The `TF_DF` class is the primary data container per timeframe
|
||||
- K-line direction uses `Chan_KLINE_DIR` (UP/DOWN/COMBINE/INCLUDED)
|
||||
- All text comments/commits are in Chinese
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.core.ChanBI import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.core.ChanBIZS import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.core.ChanBSP import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.core.ChanCTime import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.core.ChanEnum import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.analysis.ChanHeng import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.core.ChanKLC import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.core.ChanKLU import * # noqa: F403
|
||||
@@ -1,3 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.pipeline.orchestrator import ChanLun # noqa: F401
|
||||
from chanlun.pipeline.timeframe import TF_DF # noqa: F401
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.analysis.ChanLun_Classifier import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.indicators.ChanMACD import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.indicators.ChanMACDHistSet import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.indicators.ChanMACDSeg import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.indicators.ChanMACDUnitTF import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.analysis.ChanPY import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.analysis.ChanPivotClassifier import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.analysis.ChanPivotMonitor import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.core.ChanSBI import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.core.ChanSEG import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.core.ChanZS import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.analysis.ChanZone import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.core.Chan_FX_Box import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.analysis.Find_Trend import * # noqa: F403
|
||||
@@ -1,2 +0,0 @@
|
||||
"""兼容 shim — 请优先 from chanlun import ..."""
|
||||
from chanlun.pipeline.timeframe import TF_DF # noqa: F401
|
||||
@@ -1,6 +0,0 @@
|
||||
"""威科夫分析(启发式):交易区间 / 阶段 / 事件 / Volume Profile。"""
|
||||
from __future__ import annotations
|
||||
|
||||
from .engine import analyze_wyckoff
|
||||
|
||||
__all__ = ["analyze_wyckoff"]
|
||||
@@ -1,80 +0,0 @@
|
||||
"""威科夫分析入口。"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
import pandas as pd
|
||||
|
||||
from .events import build_phases, detect_bias_and_events
|
||||
from .range import detect_trading_range
|
||||
from .volume_profile import compute_volume_profile
|
||||
|
||||
|
||||
def _fmt_time(v) -> Optional[str]:
|
||||
if v is None:
|
||||
return None
|
||||
if hasattr(v, "isoformat"):
|
||||
try:
|
||||
return v.isoformat()
|
||||
except Exception:
|
||||
pass
|
||||
return str(v)
|
||||
|
||||
|
||||
def analyze_wyckoff(df: pd.DataFrame, lookback: int = 120, vp_bins: int = 50) -> Dict[str, Any]:
|
||||
"""
|
||||
对主周期 OHLCV DataFrame 做威科夫启发式分析。
|
||||
需要列: open, high, low, close, volume;建议有 date 或 timestamp。
|
||||
"""
|
||||
empty = {
|
||||
"trading_range": None,
|
||||
"bias": "unknown",
|
||||
"phases": [],
|
||||
"events": [],
|
||||
"volume_profile": {"bins": [], "poc": None, "vah": None, "val": None, "bin_count": vp_bins},
|
||||
"volume_confirm": {"avg_volume": 0.0, "event_checks": {}},
|
||||
}
|
||||
if df is None or len(df) < 30:
|
||||
return empty
|
||||
if not all(c in df.columns for c in ("open", "high", "low", "close")):
|
||||
return empty
|
||||
work = df.copy()
|
||||
if "volume" not in work.columns:
|
||||
work["volume"] = 1.0
|
||||
|
||||
tr = detect_trading_range(work, lookback=lookback)
|
||||
if tr is None:
|
||||
return empty
|
||||
|
||||
bias, events, volume_confirm = detect_bias_and_events(work, tr)
|
||||
phases = build_phases(work, tr, bias, events)
|
||||
vp = compute_volume_profile(
|
||||
work,
|
||||
int(tr["abs_start_idx"]),
|
||||
int(tr["abs_end_idx"]),
|
||||
bin_count=vp_bins,
|
||||
)
|
||||
|
||||
trading_range = {
|
||||
"start_time": _fmt_time(tr.get("start_time")),
|
||||
"end_time": _fmt_time(tr.get("end_time")),
|
||||
"high": float(tr["high"]),
|
||||
"low": float(tr["low"]),
|
||||
"mid": float(tr["mid"]),
|
||||
"active": bool(tr.get("active", True)),
|
||||
"bars": int(tr.get("bars", 0)),
|
||||
}
|
||||
for ev in events:
|
||||
ev["time"] = _fmt_time(ev.get("time"))
|
||||
for ph in phases:
|
||||
ph["start_time"] = _fmt_time(ph.get("start_time"))
|
||||
ph["end_time"] = _fmt_time(ph.get("end_time"))
|
||||
|
||||
return {
|
||||
"trading_range": trading_range,
|
||||
"bias": bias,
|
||||
"phases": phases,
|
||||
"events": events,
|
||||
"volume_profile": vp,
|
||||
"volume_confirm": volume_confirm,
|
||||
}
|
||||
@@ -1,247 +0,0 @@
|
||||
"""威科夫阶段与事件(启发式)。"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Dict, List, Tuple
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def _bar_time(df: pd.DataFrame, i: int):
|
||||
row = df.iloc[i]
|
||||
if "date" in df.columns and pd.notna(row["date"]):
|
||||
return row["date"]
|
||||
if "timestamp" in df.columns:
|
||||
return row["timestamp"]
|
||||
return i
|
||||
|
||||
|
||||
def _avg_vol(df: pd.DataFrame, i: int, win: int = 20) -> float:
|
||||
a = max(0, i - win + 1)
|
||||
v = df["volume"].astype(float).iloc[a : i + 1]
|
||||
m = float(v.mean()) if len(v) else 0.0
|
||||
return m if m > 0 else 1.0
|
||||
|
||||
|
||||
def detect_bias_and_events(
|
||||
df: pd.DataFrame,
|
||||
tr: Dict[str, Any],
|
||||
) -> Tuple[str, List[Dict[str, Any]], Dict[str, Any]]:
|
||||
"""
|
||||
返回 bias、events、volume_confirm。
|
||||
"""
|
||||
hi = float(tr["high"])
|
||||
lo = float(tr["low"])
|
||||
mid = float(tr["mid"])
|
||||
tol = float(tr.get("tol") or (hi - lo) * 0.05)
|
||||
s = int(tr["abs_start_idx"])
|
||||
e = int(tr["abs_end_idx"])
|
||||
events: List[Dict[str, Any]] = []
|
||||
|
||||
# 扫描区间内及之后(含 tail_reserve)
|
||||
scan_end = int(tr.get("abs_scan_end_idx", min(len(df) - 1, e + 15)))
|
||||
scan_end = min(len(df) - 1, max(scan_end, e))
|
||||
spring = None
|
||||
utad = None
|
||||
sos = None
|
||||
sod = None # sign of weakness / distribution breakdown
|
||||
lps = None
|
||||
lpsy = None
|
||||
|
||||
for i in range(s + 2, scan_end + 1):
|
||||
row = df.iloc[i]
|
||||
low = float(row["low"])
|
||||
high = float(row["high"])
|
||||
close = float(row["close"])
|
||||
vol = float(row["volume"]) if "volume" in df.columns else 0.0
|
||||
avg_v = _avg_vol(df, i)
|
||||
ratio = vol / avg_v if avg_v else 0.0
|
||||
|
||||
# Spring: pierce below low then close back above low
|
||||
if spring is None and low < lo - tol * 0.5 and close >= lo - tol * 0.2:
|
||||
vol_ok = ratio <= 1.35 or (i + 1 <= scan_end and float(df.iloc[min(i + 1, scan_end)]["volume"]) / avg_v < 1.2)
|
||||
spring = {
|
||||
"type": "Spring",
|
||||
"time": _bar_time(df, i),
|
||||
"price": low,
|
||||
"note": "假破下沿后收回",
|
||||
"volume_ratio": round(ratio, 3),
|
||||
"volume_ok": bool(vol_ok),
|
||||
"idx": i,
|
||||
}
|
||||
|
||||
# UTAD: pierce above high then close back below
|
||||
if utad is None and high > hi + tol * 0.5 and close <= hi + tol * 0.2:
|
||||
vol_ok = ratio >= 0.8
|
||||
utad = {
|
||||
"type": "UTAD",
|
||||
"time": _bar_time(df, i),
|
||||
"price": high,
|
||||
"note": "假破上沿后跌回",
|
||||
"volume_ratio": round(ratio, 3),
|
||||
"volume_ok": bool(vol_ok),
|
||||
"idx": i,
|
||||
}
|
||||
|
||||
# SOS: close above high with volume
|
||||
if sos is None and close > hi + tol * 0.15:
|
||||
vol_ok = ratio >= 1.15
|
||||
sos = {
|
||||
"type": "SOS",
|
||||
"time": _bar_time(df, i),
|
||||
"price": close,
|
||||
"note": "放量上破交易区间",
|
||||
"volume_ratio": round(ratio, 3),
|
||||
"volume_ok": bool(vol_ok),
|
||||
"idx": i,
|
||||
}
|
||||
|
||||
# SOW / breakdown
|
||||
if sod is None and close < lo - tol * 0.15:
|
||||
vol_ok = ratio >= 1.15
|
||||
sod = {
|
||||
"type": "SOW",
|
||||
"time": _bar_time(df, i),
|
||||
"price": close,
|
||||
"note": "放量下破交易区间",
|
||||
"volume_ratio": round(ratio, 3),
|
||||
"volume_ok": bool(vol_ok),
|
||||
"idx": i,
|
||||
}
|
||||
|
||||
# LPS after SOS: pullback that holds above mid/high-band with lighter volume
|
||||
if sos is not None:
|
||||
si = int(sos["idx"])
|
||||
for i in range(si + 1, min(len(df), si + 25)):
|
||||
row = df.iloc[i]
|
||||
low = float(row["low"])
|
||||
close = float(row["close"])
|
||||
vol = float(row["volume"]) if "volume" in df.columns else 0.0
|
||||
avg_v = _avg_vol(df, i)
|
||||
ratio = vol / avg_v if avg_v else 0.0
|
||||
if low >= mid - tol and close >= hi - tol * 2:
|
||||
vol_ok = ratio <= 1.05
|
||||
lps = {
|
||||
"type": "LPS",
|
||||
"time": _bar_time(df, i),
|
||||
"price": low,
|
||||
"note": "突破后缩量回踩不破",
|
||||
"volume_ratio": round(ratio, 3),
|
||||
"volume_ok": bool(vol_ok),
|
||||
"idx": i,
|
||||
}
|
||||
break
|
||||
|
||||
if sod is not None:
|
||||
si = int(sod["idx"])
|
||||
for i in range(si + 1, min(len(df), si + 25)):
|
||||
row = df.iloc[i]
|
||||
high = float(row["high"])
|
||||
close = float(row["close"])
|
||||
vol = float(row["volume"]) if "volume" in df.columns else 0.0
|
||||
avg_v = _avg_vol(df, i)
|
||||
ratio = vol / avg_v if avg_v else 0.0
|
||||
if high <= mid + tol and close <= lo + tol * 2:
|
||||
vol_ok = ratio <= 1.05
|
||||
lpsy = {
|
||||
"type": "LPSY",
|
||||
"time": _bar_time(df, i),
|
||||
"price": high,
|
||||
"note": "下跌突破后缩量反抽不过",
|
||||
"volume_ratio": round(ratio, 3),
|
||||
"volume_ok": bool(vol_ok),
|
||||
"idx": i,
|
||||
}
|
||||
break
|
||||
|
||||
for ev in (spring, sos, lps, utad, sod, lpsy):
|
||||
if ev:
|
||||
events.append({k: v for k, v in ev.items() if k != "idx"})
|
||||
|
||||
# bias
|
||||
last_c = float(df["close"].iloc[-1])
|
||||
bias = "unknown"
|
||||
if sos and (not sod or int(sos.get("idx", 0)) >= int(sod.get("idx", 0))):
|
||||
bias = "accumulation"
|
||||
elif sod and (not sos or int(sod.get("idx", 0)) > int(sos.get("idx", 0))):
|
||||
bias = "distribution"
|
||||
elif spring and not utad:
|
||||
bias = "accumulation"
|
||||
elif utad and not spring:
|
||||
bias = "distribution"
|
||||
elif last_c >= mid:
|
||||
bias = "accumulation"
|
||||
else:
|
||||
bias = "distribution"
|
||||
|
||||
avg_volume = float(df["volume"].astype(float).iloc[max(0, e - 20) : e + 1].mean()) if "volume" in df.columns else 0.0
|
||||
volume_confirm = {
|
||||
"avg_volume": avg_volume,
|
||||
"event_checks": {ev["type"]: {"volume_ok": ev.get("volume_ok"), "volume_ratio": ev.get("volume_ratio")} for ev in events},
|
||||
}
|
||||
return bias, events, volume_confirm
|
||||
|
||||
|
||||
def build_phases(
|
||||
df: pd.DataFrame,
|
||||
tr: Dict[str, Any],
|
||||
bias: str,
|
||||
events: List[Dict[str, Any]],
|
||||
min_bars: int = 3,
|
||||
) -> List[Dict[str, Any]]:
|
||||
"""按时间切分 A–E 粗阶段;保证非重叠且每段至少 min_bars 根(空间不足则截断尾部阶段)。"""
|
||||
s = int(tr["abs_start_idx"])
|
||||
e = int(tr["abs_end_idx"])
|
||||
n_last = len(df) - 1
|
||||
min_span = max(2, min_bars - 1)
|
||||
|
||||
event_idx = {}
|
||||
for ev in events:
|
||||
t = ev.get("time")
|
||||
for i in range(s, min(len(df), e + 20)):
|
||||
if _bar_time(df, i) == t:
|
||||
event_idx[ev["type"]] = i
|
||||
break
|
||||
|
||||
a_end = s + max(min_bars, (e - s) // 5)
|
||||
c_anchor = event_idx.get("Spring") or event_idx.get("UTAD") or (s + (e - s) // 2)
|
||||
d_anchor = event_idx.get("SOS") or event_idx.get("SOW") or e
|
||||
|
||||
def _lab(phase: str) -> str:
|
||||
if bias == "distribution":
|
||||
m = {"A": "A停止上涨", "B": "B筑顶", "C": "C测试", "D": "D派发", "E": "E下跌"}
|
||||
else:
|
||||
m = {"A": "A停止下跌", "B": "B筑底", "C": "C测试", "D": "D拉升", "E": "E离开"}
|
||||
return m.get(phase, phase)
|
||||
|
||||
# 理想切点(随后再强制非重叠 + 最小跨度)
|
||||
raw = [
|
||||
("A", s, a_end),
|
||||
("B", a_end, c_anchor),
|
||||
("C", c_anchor, d_anchor),
|
||||
("D", d_anchor, min(n_last, d_anchor + max(min_bars, (e - s) // 6))),
|
||||
("E", min(n_last, d_anchor + max(min_bars, (e - s) // 6)), min(n_last, max(e, d_anchor + max(min_bars * 2, 8)))),
|
||||
]
|
||||
phases: List[Dict[str, Any]] = []
|
||||
cursor = s
|
||||
for phase, _a, _b in raw:
|
||||
if cursor >= n_last:
|
||||
break
|
||||
a = max(int(_a), cursor)
|
||||
b = int(max(_b, a + min_span))
|
||||
b = int(np.clip(b, a, n_last))
|
||||
if b - a < min_span:
|
||||
# 尾部空间不足:并入上一段终点并停止新增
|
||||
if phases:
|
||||
phases[-1]["end_time"] = _bar_time(df, n_last)
|
||||
break
|
||||
phases.append(
|
||||
{
|
||||
"phase": phase,
|
||||
"label": _lab(phase),
|
||||
"start_time": _bar_time(df, a),
|
||||
"end_time": _bar_time(df, b),
|
||||
}
|
||||
)
|
||||
cursor = b
|
||||
return phases
|
||||
@@ -1,128 +0,0 @@
|
||||
"""交易区间检测:ATR 容差下按评分选取近期震荡箱。"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def _atr(df: pd.DataFrame, period: int = 14) -> pd.Series:
|
||||
high = df["high"].astype(float)
|
||||
low = df["low"].astype(float)
|
||||
close = df["close"].astype(float)
|
||||
prev_close = close.shift(1)
|
||||
tr = pd.concat(
|
||||
[
|
||||
(high - low).abs(),
|
||||
(high - prev_close).abs(),
|
||||
(low - prev_close).abs(),
|
||||
],
|
||||
axis=1,
|
||||
).max(axis=1)
|
||||
return tr.rolling(period, min_periods=max(3, period // 2)).mean()
|
||||
|
||||
|
||||
def _score_segment(
|
||||
length: int,
|
||||
near_hi: int,
|
||||
near_lo: int,
|
||||
inside: float,
|
||||
width: float,
|
||||
atr: float,
|
||||
) -> float:
|
||||
"""触边密度 + 箱内比例 − 相对宽度;弱奖励长度以免只追最长。"""
|
||||
touch_density = (near_hi + near_lo) / float(max(length, 1))
|
||||
width_pen = (width / atr) if atr > 0 else width
|
||||
return touch_density * 50.0 + float(inside) * 30.0 - width_pen * 3.0 + min(length / 40.0, 2.0)
|
||||
|
||||
|
||||
def detect_trading_range(
|
||||
df: pd.DataFrame,
|
||||
lookback: int = 120,
|
||||
min_bars: int = 24,
|
||||
atr_mult: float = 1.2,
|
||||
tail_reserve: int = 12,
|
||||
) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
在最近 lookback 根内寻找高低点波动受控的连续段作为交易区间。
|
||||
尾部预留 tail_reserve 根用于事件(Spring/SOS),不参与箱体边界计算。
|
||||
在硬门槛之上按评分取最优段(非仅最长窗口)。
|
||||
"""
|
||||
if df is None or len(df) < min_bars + 5:
|
||||
return None
|
||||
work = df.tail(lookback).reset_index(drop=True)
|
||||
n = len(work)
|
||||
reserve = min(tail_reserve, max(0, n - min_bars - 2))
|
||||
core_end = n - reserve if reserve > 0 else n
|
||||
core = work.iloc[:core_end]
|
||||
if len(core) < min_bars:
|
||||
core = work
|
||||
core_end = n
|
||||
reserve = 0
|
||||
|
||||
atr = _atr(work)
|
||||
last_atr = float(atr.iloc[core_end - 1]) if atr.notna().iloc[:core_end].any() else float(
|
||||
(core["high"] - core["low"]).mean()
|
||||
)
|
||||
if not np.isfinite(last_atr) or last_atr <= 0:
|
||||
last_atr = float(core["close"].iloc[-1]) * 0.01
|
||||
|
||||
best = None
|
||||
best_score = float("-inf")
|
||||
cn = len(core)
|
||||
for length in range(min(cn, lookback), min_bars - 1, -4):
|
||||
seg = core.iloc[-length:]
|
||||
hi = float(seg["high"].max())
|
||||
lo = float(seg["low"].min())
|
||||
width = hi - lo
|
||||
if width <= 0 or width > last_atr * atr_mult * 3.5:
|
||||
continue
|
||||
tol = last_atr * atr_mult * 0.35
|
||||
near_hi = int((seg["high"] >= hi - tol).sum())
|
||||
near_lo = int((seg["low"] <= lo + tol).sum())
|
||||
if near_hi < 2 or near_lo < 2:
|
||||
continue
|
||||
inside = float(((seg["close"] >= lo - tol) & (seg["close"] <= hi + tol)).mean())
|
||||
if inside < 0.75:
|
||||
continue
|
||||
score = _score_segment(length, near_hi, near_lo, inside, width, last_atr)
|
||||
if score <= best_score:
|
||||
continue
|
||||
start_i = cn - length
|
||||
end_i = cn - 1
|
||||
mid = (hi + lo) / 2.0
|
||||
last_c = float(work["close"].iloc[-1])
|
||||
active = (lo - tol * 1.5) <= last_c <= (hi + tol * 1.5)
|
||||
best_score = score
|
||||
best = {
|
||||
"start_idx": int(start_i),
|
||||
"end_idx": int(end_i),
|
||||
"high": hi,
|
||||
"low": lo,
|
||||
"mid": mid,
|
||||
"active": bool(active),
|
||||
"atr": last_atr,
|
||||
"tol": tol,
|
||||
"bars": int(length),
|
||||
"score": float(score),
|
||||
}
|
||||
|
||||
if best is None:
|
||||
return None
|
||||
|
||||
def _ts(row) -> Any:
|
||||
if "date" in work.columns and pd.notna(row["date"]):
|
||||
return row["date"]
|
||||
if "timestamp" in work.columns:
|
||||
return row["timestamp"]
|
||||
return None
|
||||
|
||||
best["start_time"] = _ts(work.iloc[best["start_idx"]])
|
||||
# 区间时间结束取 core 末,事件可落在其后
|
||||
best["end_time"] = _ts(work.iloc[best["end_idx"]])
|
||||
offset = len(df) - len(work)
|
||||
best["abs_start_idx"] = offset + best["start_idx"]
|
||||
best["abs_end_idx"] = offset + best["end_idx"]
|
||||
best["abs_scan_end_idx"] = offset + n - 1
|
||||
return best
|
||||
@@ -1,72 +0,0 @@
|
||||
"""区间内 Volume Profile。"""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Dict, List
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def compute_volume_profile(
|
||||
df: pd.DataFrame,
|
||||
start_idx: int,
|
||||
end_idx: int,
|
||||
bin_count: int = 50,
|
||||
value_area_pct: float = 0.70,
|
||||
) -> Dict[str, Any]:
|
||||
seg = df.iloc[start_idx : end_idx + 1]
|
||||
if seg.empty:
|
||||
return {"bins": [], "poc": None, "vah": None, "val": None, "bin_count": bin_count}
|
||||
|
||||
typical = (seg["high"].astype(float) + seg["low"].astype(float) + seg["close"].astype(float)) / 3.0
|
||||
vol = seg["volume"].astype(float).fillna(0.0)
|
||||
lo = float(seg["low"].min())
|
||||
hi = float(seg["high"].max())
|
||||
if not np.isfinite(lo) or not np.isfinite(hi) or hi <= lo:
|
||||
mid = float(seg["close"].iloc[-1])
|
||||
return {
|
||||
"bins": [{"price": mid, "volume": float(vol.sum())}],
|
||||
"poc": mid,
|
||||
"vah": mid,
|
||||
"val": mid,
|
||||
"bin_count": 1,
|
||||
}
|
||||
|
||||
edges = np.linspace(lo, hi, bin_count + 1)
|
||||
# 右开最后一桶闭合
|
||||
idx = np.clip(np.digitize(typical.values, edges) - 1, 0, bin_count - 1)
|
||||
vols = np.zeros(bin_count, dtype=float)
|
||||
for i, v in zip(idx, vol.values):
|
||||
vols[i] += float(v)
|
||||
|
||||
centers = (edges[:-1] + edges[1:]) / 2.0
|
||||
poc_i = int(np.argmax(vols)) if vols.sum() > 0 else bin_count // 2
|
||||
poc = float(centers[poc_i])
|
||||
|
||||
# Value Area:从 POC 向两侧扩展直到累计 >= value_area_pct
|
||||
total = float(vols.sum()) or 1.0
|
||||
target = total * value_area_pct
|
||||
left = right = poc_i
|
||||
acc = float(vols[poc_i])
|
||||
while acc < target and (left > 0 or right < bin_count - 1):
|
||||
left_v = vols[left - 1] if left > 0 else -1.0
|
||||
right_v = vols[right + 1] if right < bin_count - 1 else -1.0
|
||||
if right_v >= left_v and right < bin_count - 1:
|
||||
right += 1
|
||||
acc += float(vols[right])
|
||||
elif left > 0:
|
||||
left -= 1
|
||||
acc += float(vols[left])
|
||||
else:
|
||||
break
|
||||
|
||||
bins: List[Dict[str, float]] = [
|
||||
{"price": float(centers[i]), "volume": float(vols[i])} for i in range(bin_count)
|
||||
]
|
||||
return {
|
||||
"bins": bins,
|
||||
"poc": poc,
|
||||
"vah": float(centers[right]),
|
||||
"val": float(centers[left]),
|
||||
"bin_count": bin_count,
|
||||
}
|
||||
@@ -467,7 +467,7 @@ class BiBuilderMixin:
|
||||
pre_last_bi = bi_list[-2]
|
||||
last_bi = bi_list[-1]
|
||||
if pre_last_bi.is_sure and not last_bi.is_sure and pre_last_bi.dir == Chan_BI_DIR.UP and False:
|
||||
pre_last_bi.update_bi(klc)
|
||||
#pre_last_bi.update_bi(klc)
|
||||
bi_list.remove(last_bi)
|
||||
pre_last_bi.set_next(None)
|
||||
#last_top.set_fx(Chan_FX_TYPE.PTOP)
|
||||
@@ -585,7 +585,7 @@ class BiBuilderMixin:
|
||||
pre_last_bi = bi_list[-2]
|
||||
last_bi = bi_list[-1]
|
||||
if pre_last_bi.is_sure and not last_bi.is_sure and pre_last_bi.dir == Chan_BI_DIR.DOWN and False:
|
||||
pre_last_bi.update_bi(klc)
|
||||
#pre_last_bi.update_bi(klc)
|
||||
bi_list.remove(last_bi)
|
||||
pre_last_bi.set_next(None)
|
||||
last_bottom = klc
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
"""增量更新:新K只追加 KLU/KLC,笔与笔中枢在当前列表上重算。
|
||||
|
||||
不改 init_TF_DF 的整段语义。笔必须整表重扫:最后一笔 is_sure 允许收回
|
||||
(OWN_CHAN_ZS_001 上 60 天出现 7 次)。笔中枢用 cal_bi_zs_list_pure。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
import pandas as pd
|
||||
from pandas import DataFrame
|
||||
from technical.util import resample_to_interval
|
||||
|
||||
from chanlun.core.ChanEnum import Chan_FX_TYPE, Chan_KLC_FX, Chan_KLC_STATE
|
||||
from chanlun.core.ChanKLU import ChanKLU
|
||||
|
||||
|
||||
class IncrementalBuilderMixin:
|
||||
def init_stream(self, df, interval=1, timeframe=None):
|
||||
"""用历史K线初始化流式状态,之后用 append_bar / replace_last_bar。"""
|
||||
if df is None or df.empty:
|
||||
raise ValueError("DataFrame for stream is empty.")
|
||||
if "date" not in df.columns:
|
||||
raise ValueError(f"DataFrame missing 'date' column. Columns: {df.columns.tolist()}")
|
||||
self.timeframe = timeframe
|
||||
self.interval = interval
|
||||
if interval == 1:
|
||||
self.dataframe = df.copy()
|
||||
else:
|
||||
self.dataframe = resample_to_interval(df, interval)
|
||||
self.dataframe = self.add_indicators(self.dataframe)
|
||||
self.klu_list = []
|
||||
self.klc_list = []
|
||||
self.bi_list = []
|
||||
self.bi_zs_list = []
|
||||
self.seg_list = []
|
||||
self.zs_list = []
|
||||
self.bsp_list = []
|
||||
self.klc_fx_list = []
|
||||
self.big_zs_list = []
|
||||
self._klc_feed_last_klu = None
|
||||
for i in range(len(self.dataframe)):
|
||||
self._append_row_at(i, rebuild=False)
|
||||
self.rebuild_bi_zs()
|
||||
return self
|
||||
|
||||
def append_bar(self, row):
|
||||
"""追加一根已收盘K线。同一时间戳则改为替换最后一根。"""
|
||||
self._ensure_stream_state()
|
||||
item = self._normalize_row(row)
|
||||
if self.klu_list and self.klu_list[-1].time == self._row_time_str(item):
|
||||
return self.replace_last_bar(item)
|
||||
self._append_item_to_dataframe(item)
|
||||
self.dataframe = self.add_indicators(self.dataframe)
|
||||
self._append_row_at(len(self.dataframe) - 1, rebuild=True)
|
||||
return self
|
||||
|
||||
def replace_last_bar(self, row):
|
||||
"""更新最后一根K(未完成K线走新OHLC)。包含关系从 KLU 列表重放。"""
|
||||
self._ensure_stream_state()
|
||||
if not self.klu_list:
|
||||
return self.append_bar(row)
|
||||
item = self._normalize_row(row)
|
||||
idx = self.dataframe.index[-1]
|
||||
for key, val in item.items():
|
||||
self.dataframe.at[idx, key] = val
|
||||
self.dataframe = self.add_indicators(self.dataframe)
|
||||
self._apply_item_to_klu(self.klu_list[-1], self.dataframe.iloc[-1])
|
||||
self._rebuild_klc_from_klu()
|
||||
self.rebuild_bi_zs()
|
||||
return self
|
||||
|
||||
def rebuild_bi_zs(self):
|
||||
"""在当前 KLC 上重算笔 + cal_bi_zs_list_pure。会先清分型标记。"""
|
||||
self._reset_klc_bi_marks(self.klc_list)
|
||||
self.bi_list = self.cal_bi_list(self.klc_list) if self.klc_list else []
|
||||
self.bi_zs_list = self.cal_bi_zs_list_pure(self.bi_list) if self.bi_list else []
|
||||
return self.bi_zs_list
|
||||
|
||||
def _ensure_stream_state(self):
|
||||
if not hasattr(self, "klu_list") or self.klu_list is None:
|
||||
self.klu_list = []
|
||||
if not hasattr(self, "klc_list") or self.klc_list is None:
|
||||
self.klc_list = []
|
||||
if not hasattr(self, "dataframe") or self.dataframe is None:
|
||||
self.dataframe = DataFrame(
|
||||
columns=["date", "open", "high", "low", "close", "volume"]
|
||||
)
|
||||
if not hasattr(self, "_klc_feed_last_klu"):
|
||||
self._klc_feed_last_klu = self.klu_list[-1] if self.klu_list else None
|
||||
if not hasattr(self, "bi_zs_list"):
|
||||
self.bi_zs_list = []
|
||||
|
||||
def _rebuild_klc_from_klu(self):
|
||||
self.klc_list = []
|
||||
last_klu = None
|
||||
for klu in self.klu_list:
|
||||
self._push_klu_into_klc_list(self.klc_list, klu, last_klu)
|
||||
last_klu = klu
|
||||
self._klc_feed_last_klu = last_klu
|
||||
|
||||
def _append_row_at(self, idx, rebuild=True):
|
||||
item = self.dataframe.iloc[idx]
|
||||
klu = self._klu_from_item(item, idx)
|
||||
if self.klu_list:
|
||||
self.klu_list[-1].set_next(klu)
|
||||
klu.set_pre(self.klu_list[-1])
|
||||
self._push_klu_into_klc_list(self.klc_list, klu, self._klc_feed_last_klu)
|
||||
self._klc_feed_last_klu = klu
|
||||
self.klu_list.append(klu)
|
||||
if rebuild:
|
||||
self.rebuild_bi_zs()
|
||||
|
||||
def _klu_from_item(self, item, idx):
|
||||
klu = ChanKLU(
|
||||
self._item_time_str(item),
|
||||
item["open"],
|
||||
item["high"],
|
||||
item["low"],
|
||||
item["close"],
|
||||
item["volume"],
|
||||
)
|
||||
klu.set_idx(idx)
|
||||
if not hasattr(klu, "ema13"):
|
||||
klu.ema13 = 0
|
||||
if "macd" in item:
|
||||
klu.set_indicators(item)
|
||||
return klu
|
||||
|
||||
def _apply_item_to_klu(self, klu, item):
|
||||
klu.time = self._item_time_str(item)
|
||||
klu.open = item["open"]
|
||||
klu.high = item["high"]
|
||||
klu.low = item["low"]
|
||||
klu.close = item["close"]
|
||||
klu.volume = item["volume"]
|
||||
klu.range = klu.high - klu.low
|
||||
klu.body = abs(klu.close - klu.open)
|
||||
if "macd" in item:
|
||||
klu.set_indicators(item)
|
||||
|
||||
def _reset_klc_bi_marks(self, klc_list):
|
||||
for klc in klc_list:
|
||||
klc.fx = Chan_FX_TYPE.UNKNOWN
|
||||
klc.klc_fx_type = Chan_KLC_FX.UNKNOWN
|
||||
klc.klc_state = Chan_KLC_STATE.UNKNOWN
|
||||
klc.bi = None
|
||||
klc.fx_confirmed = False
|
||||
|
||||
def _item_time_str(self, item):
|
||||
date = item["date"]
|
||||
if hasattr(date, "to_pydatetime"):
|
||||
date = date.to_pydatetime()
|
||||
if isinstance(date, datetime):
|
||||
return date.strftime("%Y-%m-%d %H:%M:%S")
|
||||
return str(date)
|
||||
|
||||
def _row_time_str(self, item):
|
||||
return self._item_time_str(item)
|
||||
|
||||
def _normalize_row(self, row):
|
||||
if isinstance(row, pd.Series):
|
||||
return row
|
||||
return pd.Series(row)
|
||||
|
||||
def _append_item_to_dataframe(self, item):
|
||||
row_df = DataFrame([item])
|
||||
if self.dataframe is None or self.dataframe.empty:
|
||||
self.dataframe = row_df
|
||||
else:
|
||||
self.dataframe = pd.concat([self.dataframe, row_df], ignore_index=True)
|
||||
@@ -86,7 +86,8 @@ class KlineBuilderMixin:
|
||||
return Chan_FX_TYPE.UNKNOWN
|
||||
|
||||
def check_fx(self, klc):
|
||||
if klc.pre and klc.next:
|
||||
# 右K未完成(仍在包含合并)时不分型:否则确认笔会随 next 扩区间被 check_*_fx 收回
|
||||
if klc.pre and klc.next and klc.next.end_klu is not None:
|
||||
if klc.high > klc.pre.high and klc.high > klc.next.high and klc.low > klc.pre.low and klc.low > klc.next.low:
|
||||
#if (klc.close > klc.ema52 or klc.next.close > klc.next.ema52) and klc.macd > 0:
|
||||
klc.set_fx(Chan_FX_TYPE.TOP)
|
||||
@@ -99,6 +100,21 @@ class KlineBuilderMixin:
|
||||
return Chan_FX_TYPE.BOTTOM
|
||||
return Chan_FX_TYPE.UNKNOWN
|
||||
|
||||
def check_fx3(self, klc):
|
||||
# 右K未完成(仍在包含合并)时不分型:否则确认笔会随 next 扩区间被 check_*_fx 收回
|
||||
if klc.pre and klc.next and klc.next.end_klu is not None:
|
||||
next_klu = klc.next.end_klu.next
|
||||
if klc.high > klc.pre.high and klc.high > klc.next.high and klc.low > klc.pre.low and klc.low > klc.next.low and klc.high > next_klu.high:
|
||||
#if (klc.close > klc.ema52 or klc.next.close > klc.next.ema52) and klc.macd > 0:
|
||||
klc.set_fx(Chan_FX_TYPE.TOP)
|
||||
#print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time, klc.macd, klc.state, klc.fx, "TOP")
|
||||
return Chan_FX_TYPE.TOP
|
||||
elif klc.low < klc.pre.low and klc.low < klc.next.low and klc.high < klc.pre.high and klc.high < klc.next.high and klc.low < next_klu.low:
|
||||
#if (klc.close < klc.ema52 or klc.next.close < klc.next.ema52) and klc.macd < 0:
|
||||
klc.set_fx(Chan_FX_TYPE.BOTTOM)
|
||||
#print(klc.start_time, klc.end_time,klc.next.start_time, klc.next.end_time, klc.macd, klc.state, klc.fx, "BOTTOM")
|
||||
return Chan_FX_TYPE.BOTTOM
|
||||
return Chan_FX_TYPE.UNKNOWN
|
||||
def check_fx2(self, klc):
|
||||
if klc.pre and klc.next:
|
||||
if klc.high > klc.pre.close and klc.close > klc.next.close and klc.close > klc.pre.close and klc.close > klc.next.close:
|
||||
@@ -171,6 +187,43 @@ class KlineBuilderMixin:
|
||||
def get_kl_data(self, dataframe:DataFrame):
|
||||
return self.cal_kl_data(dataframe)
|
||||
|
||||
def _push_klu_into_klc_list(self, klc_list, klu, last_klu):
|
||||
"""把一根 KLU 并入包含K线列表。与 get_klc_list 的几何规则相同。"""
|
||||
if len(klc_list) > 0:
|
||||
last_klc = klc_list[-1]
|
||||
if klu.exception:
|
||||
ddir = Chan_KLINE_DIR.DOWN
|
||||
if last_klc.high < klu.high:
|
||||
ddir = Chan_KLINE_DIR.UP
|
||||
klc = ChanKLC(klu, index=len(klc_list), ddir=ddir)
|
||||
klc.high = klu.close if klu.close > klu.open else klu.open
|
||||
klc.low = klu.open if klu.close > klu.open else klu.close
|
||||
klc_list.append(klc)
|
||||
last_klc.set_next(klc)
|
||||
klc.set_pre(last_klc)
|
||||
last_klc.set_end_klu(last_klu)
|
||||
klc.set_pre_fx()
|
||||
else:
|
||||
included = last_klc.check_klu_included(klu)
|
||||
if not included:
|
||||
ddir = Chan_KLINE_DIR.DOWN
|
||||
if last_klc.high < klu.high:
|
||||
ddir = Chan_KLINE_DIR.UP
|
||||
klc = ChanKLC(klu, index=len(klc_list), ddir=ddir)
|
||||
klc_list.append(klc)
|
||||
last_klc.set_next(klc)
|
||||
klc.set_pre(last_klc)
|
||||
last_klc.set_end_klu(last_klu)
|
||||
klc.set_pre_fx()
|
||||
else:
|
||||
last_klc.add_klu(klu)
|
||||
else:
|
||||
ddir = Chan_KLINE_DIR.UP
|
||||
if klu.open > klu.close:
|
||||
ddir = Chan_KLINE_DIR.DOWN
|
||||
klc = ChanKLC(klu, 0, ddir)
|
||||
klc_list.append(klc)
|
||||
|
||||
def get_klc_list(self, klu_list):
|
||||
klc_list = []
|
||||
last_klu = None
|
||||
@@ -198,41 +251,7 @@ class KlineBuilderMixin:
|
||||
ema_down_list.append(ema_down_count)
|
||||
#print(last_klu.time, ema_down_count, "DOWN END")
|
||||
ema_down_count = 0
|
||||
if len(klc_list) > 0:
|
||||
last_klc = klc_list[-1]
|
||||
if klu.exception:
|
||||
ddir = Chan_KLINE_DIR.DOWN
|
||||
if last_klc.high < klu.high:
|
||||
ddir = Chan_KLINE_DIR.UP
|
||||
klc = ChanKLC(klu, index=len(klc_list), ddir=ddir)
|
||||
klc.high = klu.close if klu.close > klu.open else klu.open
|
||||
klc.low = klu.open if klu.close > klu.open else klu.close
|
||||
klc_list.append(klc)
|
||||
last_klc.set_next(klc)
|
||||
klc.set_pre(last_klc)
|
||||
last_klc.set_end_klu(last_klu)
|
||||
klc.set_pre_fx()
|
||||
#print(klu.time, klu.high, klu.low, klu.close, klu.open, klu.exception)
|
||||
else:
|
||||
included = last_klc.check_klu_included(klu)
|
||||
if not included:
|
||||
ddir = Chan_KLINE_DIR.DOWN
|
||||
if last_klc.high < klu.high:
|
||||
ddir = Chan_KLINE_DIR.UP
|
||||
klc = ChanKLC(klu, index=len(klc_list), ddir=ddir)
|
||||
klc_list.append(klc)
|
||||
last_klc.set_next(klc)
|
||||
klc.set_pre(last_klc)
|
||||
last_klc.set_end_klu(last_klu)
|
||||
klc.set_pre_fx()
|
||||
else:
|
||||
last_klc.add_klu(klu)
|
||||
else:
|
||||
ddir = Chan_KLINE_DIR.UP
|
||||
if klu.open > klu.close:
|
||||
ddir = Chan_KLINE_DIR.DOWN
|
||||
klc = ChanKLC(klu, 0, ddir)
|
||||
klc_list.append(klc)
|
||||
self._push_klu_into_klc_list(klc_list, klu, last_klu)
|
||||
last_klu = klu
|
||||
klc_list = self.cal_trend(klc_list)
|
||||
#print(ema52_up_list, ema52_down_list)
|
||||
|
||||
@@ -355,9 +355,12 @@ class ZsBuilderMixin:
|
||||
return bi_zs_list
|
||||
|
||||
def get_zs_range(bis):
|
||||
zg = min(bi.high for bi in bis)
|
||||
zd = max(bi.low for bi in bis)
|
||||
return zg, zd
|
||||
bis_list = bis[0:3]
|
||||
zg = min(bi.high for bi in bis_list)
|
||||
zd = max(bi.low for bi in bis_list)
|
||||
dd = min(bi.low for bi in bis_list)
|
||||
gg = max(bi.high for bi in bis_list)
|
||||
return zg, zd, dd, gg
|
||||
|
||||
def is_bi_overlap_range(bi, zg, zd):
|
||||
return bi.high >= zd and bi.low <= zg
|
||||
@@ -375,8 +378,8 @@ class ZsBuilderMixin:
|
||||
zs.bi_list = list(bis)
|
||||
for bi in zs.bi_list:
|
||||
bi.set_bi_zs(zs)
|
||||
zs.set_gg(max(bi.high for bi in zs.bi_list))
|
||||
zs.set_dd(min(bi.low for bi in zs.bi_list))
|
||||
#zs.set_gg(max(bi.high for bi in zs.bi_list))
|
||||
#zs.set_dd(min(bi.low for bi in zs.bi_list))
|
||||
zs.classify_zs()
|
||||
|
||||
last_zs = None
|
||||
@@ -394,7 +397,7 @@ class ZsBuilderMixin:
|
||||
start_idx += 1
|
||||
continue
|
||||
|
||||
zg, zd = get_zs_range([bi1, bi2, bi3])
|
||||
zg, zd, dd, gg = get_zs_range([bi1, bi2, bi3])
|
||||
if zg <= zd:
|
||||
start_idx += 1
|
||||
continue
|
||||
@@ -420,6 +423,8 @@ class ZsBuilderMixin:
|
||||
zs = ChanBIZS(bi1, len(bi_zs_list), zs_dir)
|
||||
zs.set_zg(zg)
|
||||
zs.set_zd(zd)
|
||||
zs.set_dd(dd)
|
||||
zs.set_gg(gg)
|
||||
|
||||
set_zs_bi_list(zs, bis_for_zs)
|
||||
zs.set_end_bi(bis_for_zs[-1], bis_for_zs[-1].sure_time)
|
||||
|
||||
@@ -178,6 +178,15 @@ class ChanLun():
|
||||
def cal_bi_zs_list(self, bi_list):
|
||||
#return self.tf_df.cal_bi_zs(bi_list)
|
||||
return self.tf_df.cal_bi_zs_list(bi_list)
|
||||
def cal_bi_zs_list_pure(self, bi_list):
|
||||
return self.tf_df.cal_bi_zs_list_pure(bi_list)
|
||||
def init_stream(self, dataframe, interval=1, timeframe=None):
|
||||
self.tf_df.init_stream(dataframe, interval, timeframe)
|
||||
return self.tf_df
|
||||
def append_bar(self, row):
|
||||
return self.tf_df.append_bar(row)
|
||||
def replace_last_bar(self, row):
|
||||
return self.tf_df.replace_last_bar(row)
|
||||
def get_bi_zs_list(self, bi_list):
|
||||
return self.tf_df.get_bi_zs_list(bi_list)
|
||||
def get_decimal(self, value):
|
||||
|
||||
@@ -31,12 +31,13 @@ from chanlun.core.ChanZS import ChanZS, ChanZS_Big
|
||||
from chanlun.indicators.ChanMACD import ChanMACD
|
||||
from chanlun.pipeline.builders.bi import BiBuilderMixin
|
||||
from chanlun.pipeline.builders.bsp import BspBuilderMixin
|
||||
from chanlun.pipeline.builders.incremental import IncrementalBuilderMixin
|
||||
from chanlun.pipeline.builders.indicators import IndicatorsBuilderMixin
|
||||
from chanlun.pipeline.builders.kline import KlineBuilderMixin
|
||||
from chanlun.pipeline.builders.seg import SegBuilderMixin
|
||||
from chanlun.pipeline.builders.zs import ZsBuilderMixin
|
||||
|
||||
class TF_DF(IndicatorsBuilderMixin, KlineBuilderMixin, BiBuilderMixin, SegBuilderMixin, ZsBuilderMixin, BspBuilderMixin):
|
||||
class TF_DF(IndicatorsBuilderMixin, KlineBuilderMixin, BiBuilderMixin, SegBuilderMixin, ZsBuilderMixin, BspBuilderMixin, IncrementalBuilderMixin):
|
||||
def __init__(self, df=None, interval=0, timeframe=None):
|
||||
if df is not None:
|
||||
self.init_TF_DF(df, interval, timeframe)
|
||||
@@ -59,12 +60,14 @@ class TF_DF(IndicatorsBuilderMixin, KlineBuilderMixin, BiBuilderMixin, SegBuilde
|
||||
self.klc_list = []
|
||||
self.bi_list = []
|
||||
self.zs_list = []
|
||||
self.bi_zs_list = []
|
||||
self.bsp_list = []
|
||||
self.seg_list = []
|
||||
self.klc_fx_list = []
|
||||
self.klu_list = self.cal_kl_data(self.dataframe)
|
||||
self.klc_list = self.get_klc_list(self.klu_list)
|
||||
self.bi_list = self.cal_bi_list(self.klc_list)
|
||||
self.bi_zs_list = self.cal_bi_zs_list_pure(self.bi_list)
|
||||
self.seg_list = self.get_seg_list(self.bi_list)
|
||||
self.zs_list = self.get_zs_list(self.bi_list, self.seg_list)
|
||||
self.big_zs_list = self.get_big_zs_list(self.zs_list)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from __future__ import annotations
|
||||
@@ -0,0 +1,141 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
import pandas as pd
|
||||
|
||||
_CHAN = Path(__file__).resolve().parents[2]
|
||||
if str(_CHAN) not in sys.path:
|
||||
sys.path.insert(0, str(_CHAN))
|
||||
|
||||
from chanlun.pipeline.timeframe import TF_DF # noqa: E402
|
||||
|
||||
|
||||
def _zigzag_df(n=160, step=8):
|
||||
dates = pd.date_range("2024-01-01", periods=n, freq="5min")
|
||||
rows = []
|
||||
price = 100.0
|
||||
for i, date in enumerate(dates):
|
||||
up = (i // step) % 2 == 0
|
||||
if up:
|
||||
o = price
|
||||
c = price + 1.5
|
||||
h = c + 0.3
|
||||
l = o - 0.2
|
||||
else:
|
||||
o = price
|
||||
c = price - 1.5
|
||||
h = o + 0.2
|
||||
l = c - 0.3
|
||||
price = c
|
||||
rows.append(
|
||||
{
|
||||
"date": date,
|
||||
"open": o,
|
||||
"high": h,
|
||||
"low": l,
|
||||
"close": c,
|
||||
"volume": 1.0,
|
||||
}
|
||||
)
|
||||
return pd.DataFrame(rows)
|
||||
|
||||
|
||||
def _sure_bi_key(bi):
|
||||
return (str(bi.start_time), bi.dir.name, round(float(bi.high), 6), round(float(bi.low), 6))
|
||||
|
||||
|
||||
def _zs_key(zs):
|
||||
return (
|
||||
str(zs.start_time),
|
||||
round(float(zs.zg), 6),
|
||||
round(float(zs.zd), 6),
|
||||
len(zs.bi_list),
|
||||
)
|
||||
|
||||
|
||||
class TestIncremental(unittest.TestCase):
|
||||
def test_init_stream_matches_batch_push(self):
|
||||
df = _zigzag_df()
|
||||
stream = TF_DF()
|
||||
stream.init_stream(df, 1, "5m")
|
||||
|
||||
batch = TF_DF()
|
||||
indexed = batch.add_indicators(df.copy())
|
||||
klu = batch.cal_kl_data(indexed)
|
||||
klc = []
|
||||
last = None
|
||||
for k in klu:
|
||||
batch._push_klu_into_klc_list(klc, k, last)
|
||||
last = k
|
||||
batch.klc_list = klc
|
||||
batch.rebuild_bi_zs()
|
||||
|
||||
self.assertEqual(len(stream.klu_list), len(klu))
|
||||
self.assertEqual(len(stream.klc_list), len(klc))
|
||||
self.assertEqual(
|
||||
[_sure_bi_key(b) for b in stream.bi_list if b.is_sure],
|
||||
[_sure_bi_key(b) for b in batch.bi_list if b.is_sure],
|
||||
)
|
||||
self.assertEqual(
|
||||
[_zs_key(z) for z in stream.bi_zs_list],
|
||||
[_zs_key(z) for z in batch.bi_zs_list],
|
||||
)
|
||||
|
||||
def test_append_bar_matches_init_stream(self):
|
||||
df = _zigzag_df()
|
||||
stream = TF_DF()
|
||||
stream.init_stream(df, 1, "5m")
|
||||
|
||||
inc = TF_DF()
|
||||
for _, row in df.iterrows():
|
||||
inc.append_bar(row)
|
||||
|
||||
self.assertEqual(len(inc.klu_list), len(stream.klu_list))
|
||||
self.assertEqual(len(inc.klc_list), len(stream.klc_list))
|
||||
self.assertEqual(
|
||||
[_sure_bi_key(b) for b in inc.bi_list if b.is_sure],
|
||||
[_sure_bi_key(b) for b in stream.bi_list if b.is_sure],
|
||||
)
|
||||
self.assertEqual(
|
||||
[_zs_key(z) for z in inc.bi_zs_list],
|
||||
[_zs_key(z) for z in stream.bi_zs_list],
|
||||
)
|
||||
|
||||
def test_replace_last_bar_keeps_count(self):
|
||||
df = _zigzag_df(n=80)
|
||||
tf = TF_DF()
|
||||
tf.init_stream(df, 1, "5m")
|
||||
n_klu = len(tf.klu_list)
|
||||
last = df.iloc[-1].copy()
|
||||
last["close"] = float(last["close"]) + 0.01
|
||||
last["high"] = max(float(last["high"]), float(last["close"]))
|
||||
tf.replace_last_bar(last)
|
||||
self.assertEqual(len(tf.klu_list), n_klu)
|
||||
self.assertGreater(len(tf.klc_list), 0)
|
||||
|
||||
def test_check_fx_skips_forming_right_wing(self):
|
||||
from types import SimpleNamespace
|
||||
|
||||
from chanlun.core.ChanEnum import Chan_FX_TYPE
|
||||
|
||||
tf = TF_DF()
|
||||
pre = SimpleNamespace(high=10, low=8)
|
||||
nxt_open = SimpleNamespace(high=11, low=7, end_klu=None)
|
||||
nxt_done = SimpleNamespace(high=11, low=7, end_klu=object())
|
||||
center = SimpleNamespace(
|
||||
pre=pre,
|
||||
next=nxt_open,
|
||||
high=12,
|
||||
low=9,
|
||||
set_fx=lambda *_a, **_k: None,
|
||||
)
|
||||
self.assertEqual(tf.check_fx(center), Chan_FX_TYPE.UNKNOWN)
|
||||
center.next = nxt_done
|
||||
self.assertEqual(tf.check_fx(center), Chan_FX_TYPE.TOP)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -1,84 +0,0 @@
|
||||
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.btc_chan.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"SOL/USDT:USDT",
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800,
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8882,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.btc_perpetual.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short": true,
|
||||
"timeframe": "1m",
|
||||
"process_only_new_candles": false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "YOUR_BINANCE_API_KEY",
|
||||
"secret": "YOUR_BINANCE_API_SECRET",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"token": "YOUR_TELEGRAM_BOT_TOKEN",
|
||||
"chat_id": "YOUR_TELEGRAM_CHAT_ID"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "0.0.0.0",
|
||||
"listen_port": 8820,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "change_me_to_a_random_secret_key",
|
||||
"ws_token": "change_me_to_a_random_ws_token",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "BTC_Perpetual_Bot",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chan.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT",
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800,
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8800,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_btc_15.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8811,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_btc_1m.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"order_types": {
|
||||
"entry": "limit",
|
||||
"exit": "limit",
|
||||
"stoploss": "limit",
|
||||
"stoploss_on_exchange": false
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true
|
||||
},
|
||||
"exit_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {
|
||||
"proxies": {
|
||||
"http": "http://127.0.0.1:7897",
|
||||
"https": "http://127.0.0.1:7897"
|
||||
}
|
||||
},
|
||||
"ccxt_async_config": {
|
||||
"aiohttp_proxy": "http://127.0.0.1:7897"
|
||||
},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"token": "8197349375:AAH208JghCq8raFYF-IpnobYknCr6iGDH_0",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "0.0.0.0",
|
||||
"listen_port": 8814,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 1
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_btc_15.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "0.0.0.0",
|
||||
"listen_port": 8813,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
{
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_btc_5m.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "5m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 5,
|
||||
"exit": 5,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"order_types": {
|
||||
"entry": "limit",
|
||||
"exit": "limit",
|
||||
"stoploss": "limit",
|
||||
"stoploss_on_exchange": false
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true
|
||||
},
|
||||
"exit_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {
|
||||
"proxies": {
|
||||
"http": "http://127.0.0.1:7897",
|
||||
"https": "http://127.0.0.1:7897"
|
||||
}
|
||||
},
|
||||
"ccxt_async_config": {
|
||||
"aiohttp_proxy": "http://127.0.0.1:7897"
|
||||
},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"internals": {
|
||||
"process_throttle_secs": 5
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_btc_60.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "0.0.0.0",
|
||||
"listen_port": 8814,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_btc_k.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8815,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_btc_k.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short": true,
|
||||
"timeframe": "1m",
|
||||
"process_only_new_candles": false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8815,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_btc_15.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "0.0.0.0",
|
||||
"listen_port": 8820,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_btc_15.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "0.0.0.0",
|
||||
"listen_port": 8820,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_eth_60.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"ETH/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8813,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_btc_15.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "5m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "other",
|
||||
"use_order_book": false,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "other",
|
||||
"use_order_book": false,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8813,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_sol.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8811,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 2,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.95,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_sol_optimized.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short": true,
|
||||
"timeframe": "5m",
|
||||
"process_only_new_candles": false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 2,
|
||||
"exit": 2,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "other",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "",
|
||||
"secret": "",
|
||||
"ccxt_config": {
|
||||
"options": {"defaultType": "swap"}
|
||||
},
|
||||
"ccxt_async_config": {
|
||||
"enableRateLimit": true,
|
||||
"rateLimit": 1000,
|
||||
"timeout": 30000
|
||||
},
|
||||
"pair_whitelist": [
|
||||
"SOL/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": []
|
||||
},
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "",
|
||||
"chat_id": ""
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": false,
|
||||
"listen_ip_address": "0.0.0.0",
|
||||
"listen_port": 8080,
|
||||
"verbosity": "error",
|
||||
"jwt_secret_key": "",
|
||||
"username": "",
|
||||
"password": ""
|
||||
},
|
||||
"discord": {
|
||||
"enabled": false,
|
||||
"webhook": "",
|
||||
"webhook_avatar": "",
|
||||
"poll_delay_seconds": 10
|
||||
},
|
||||
"notification_settings": {
|
||||
"status": "on",
|
||||
"status_inactive_after": 7,
|
||||
"timeframe_condition_change": "on",
|
||||
"telegram": { },
|
||||
"discord": { },
|
||||
"notify_all": true
|
||||
},
|
||||
"bot_name": "SOL_Chan_Optimized",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 5
|
||||
},
|
||||
"edge": {
|
||||
"enabled": false,
|
||||
"process_throttle_secs": 3600,
|
||||
"calculate_since_number_of_days": 7,
|
||||
"allowed_risk": 0.01,
|
||||
"stoploss_range_min": -0.01,
|
||||
"stoploss_range_max": -0.007,
|
||||
"stoploss_range_step": 0.001,
|
||||
"minimum_winrate": 0.60,
|
||||
"minimum_expectancy": 0.20,
|
||||
"min_trade_number": 10,
|
||||
"max_trade_duration_minute": 1440,
|
||||
"remove_pumps": false
|
||||
},
|
||||
"order_types": {
|
||||
"entry": "limit",
|
||||
"exit": "market",
|
||||
"emergency_exit": "market",
|
||||
"force_exit": "market",
|
||||
"force_entry": "market",
|
||||
"stoploss": "market",
|
||||
"stoploss_on_exchange": false,
|
||||
"stoploss_on_exchange_interval": 60
|
||||
},
|
||||
"order_time_in_force": {
|
||||
"entry": "GTC",
|
||||
"exit": "GTC"
|
||||
},
|
||||
"strategy_path": "./user_data/Chan/strategies/",
|
||||
"strategy": "ChanLun_SOL_Optimized",
|
||||
"minimal_roi": {
|
||||
"0": 0.012,
|
||||
"120": 0.010,
|
||||
"240": 0.007,
|
||||
"360": 0.005
|
||||
},
|
||||
"stoploss": -0.007,
|
||||
"trailing_stop": true,
|
||||
"trailing_stop_positive": 0.003,
|
||||
"trailing_stop_positive_offset": 0.005,
|
||||
"trailing_only_offset_is_reached": true,
|
||||
"use_custom_stoploss": true,
|
||||
"max_open_trades_per_pair": 1,
|
||||
"dry_run_wallet_refresh_time": 5,
|
||||
"caches": {
|
||||
"dataframe": {
|
||||
"enabled": true,
|
||||
"refresh_period": 60
|
||||
},
|
||||
"strategy": {
|
||||
"enabled": true,
|
||||
"refresh_period": 300
|
||||
}
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"config": {
|
||||
"pairs": ["SOL/USDT:USDT"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_sol.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : true,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"SOL/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"freqai": {
|
||||
"enabled": true,
|
||||
"purge_old_models": true,
|
||||
"train_period_days": 30,
|
||||
"backtest_period_days": 7,
|
||||
"identifier": "chanLun1",
|
||||
"live_retrain_hours": 1,
|
||||
"expiration_hours": 48,
|
||||
"fit_live_predictions_candles": 0,
|
||||
"data_kitchen_thread_count": 4,
|
||||
"save_backtest_models": true,
|
||||
"save_metadata": true,
|
||||
"feature_parameters": {
|
||||
"include_timeframes": [
|
||||
"1m",
|
||||
"5m",
|
||||
"15m"
|
||||
],
|
||||
"include_corr_pairlist": [
|
||||
"BTC/USDT:USDT",
|
||||
"ETH/USDT:USDT"
|
||||
],
|
||||
"label_period_candles": 24,
|
||||
"include_shifted_candles": 2,
|
||||
"indicator_periods_candles": [10, 20, 30],
|
||||
"allow_duplicate_train": true
|
||||
},
|
||||
"data_split_parameters": {
|
||||
"test_size": 0.25
|
||||
},
|
||||
"model_training_parameters": {
|
||||
"n_estimators": 100,
|
||||
"learning_rate": 0.1,
|
||||
"max_depth": 5,
|
||||
"subsample": 0.8,
|
||||
"colsample_bytree": 0.8,
|
||||
"use_label_for_weight": true,
|
||||
"booster": "gbtree",
|
||||
"num_class": 2
|
||||
}
|
||||
},
|
||||
"freqaimodel": "XGBoostClassifier",
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8811,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 3,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.btc_chan.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "30m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "ocQUqAPSD9PDhIL2lTMlMan0wMFwvvu5Fv8eYF3wUM8yPytm2jBgz51cgiHXw7J6",
|
||||
"secret": "yHIc6FOnSoOI2FvygpRKKku4FKaZGI5DSwC83Ip4wRfUcxszennF6hy2vhbVuLYJ",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT",
|
||||
"ETH/USDT:USDT",
|
||||
"SOL/USDT:USDT",
|
||||
"WIF/USDT:USDT",
|
||||
"1000PEPE/USDT:USDT",
|
||||
"DOGS/USDT:USDT",
|
||||
"ORDI/USDT:USDT",
|
||||
"AAVE/USDT:USDT",
|
||||
"REEF/USDT:USDT",
|
||||
"1000SATS/USDT:USDT",
|
||||
"SUI/USDT:USDT",
|
||||
"1INCH/USDT:USDT",
|
||||
"DOGE/USDT:USDT",
|
||||
"TON/USDT:USDT",
|
||||
"UNI/USDT:USDT",
|
||||
"XRP/USDT:USDT",
|
||||
"SUN/USDT:USDT",
|
||||
"NOT/USDT:USDT",
|
||||
"RARE/USDT:USDT",
|
||||
"RDNT/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "VolumePairList",
|
||||
"number_assets": 10,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8088,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "5m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT",
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "5985766683:AAEx2Nm_4y2IC0Tj4Hhz7djVRJRso0JKaj0",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8088,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.btc_chan.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"SOL/USDT:USDT",
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800,
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": false,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8888,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"strategy": "ChanStrategy",
|
||||
"db_url": "sqlite:///tradesv3.btc_chan.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"SOL/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": false,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8818,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chan.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"SOL/USDT:USDT",
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800,
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8815,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDC",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chan.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "hyperliquid",
|
||||
"walletAddress": "0xA834b6d3Fa1D8A55ea8e502685ef5cbD2b2D3343",
|
||||
"privateKey": "0xa399cea4c01be67c16b88e1d2121ed6e72bab6b4e8d81684ed03ce78f8b4f827",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"PURR/USDC:USDC",
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800,
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8815,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chan_sol_30.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"SOL/USDT:USDT",
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800,
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8818,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chan.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT",
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800,
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8801,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 3,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"db_url": "sqlite:///tradesv3.deepseek_trader.sqlite",
|
||||
"dry_run": true,
|
||||
"dry_run_wallet": 10000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 0,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT",
|
||||
"ETH/USDT:USDT",
|
||||
"SOL/USDT:USDT",
|
||||
"WIF/USDT:USDT",
|
||||
"1000PEPE/USDT:USDT",
|
||||
"DOGS/USDT:USDT",
|
||||
"ORDI/USDT:USDT",
|
||||
"AAVE/USDT:USDT",
|
||||
"REEF/USDT:USDT",
|
||||
"1000SATS/USDT:USDT",
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 10,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"token": "5985766683:AAEx2Nm_4y2IC0Tj4Hhz7djVRJRso0JKaj0",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8001,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": true,
|
||||
"internals": {
|
||||
"process_throttle_secs": 15
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.ema26_ema52_cross.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"SOL/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "0.0.0.0",
|
||||
"listen_port": 8820,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.ema_pattern.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1h",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "0.0.0.0",
|
||||
"listen_port": 8888,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 2,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.elliottwave_btc.sqlite",
|
||||
"dry_run_wallet": 10000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"unfilledtimeout": {
|
||||
"entry": 5,
|
||||
"exit": 5,
|
||||
"exit_timeout_count": 3,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "",
|
||||
"secret": "",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "",
|
||||
"chat_id": ""
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": false,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8080,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "freqtrade_secret",
|
||||
"ws_token": "freqtrade_ws",
|
||||
"username": "freqtrade",
|
||||
"password": "freqtrade"
|
||||
},
|
||||
"bot_name": "ElliottWaveBTC"
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.freqai_sol.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short": true,
|
||||
"timeframe": "5m",
|
||||
"process_only_new_candles": true,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "",
|
||||
"secret": "",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"SOL/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList"
|
||||
}
|
||||
],
|
||||
"freqai": {
|
||||
"enabled": true,
|
||||
"purge_old_models": 2,
|
||||
"train_period_days": 10,
|
||||
"backtest_period_days": 7,
|
||||
"live_retrain_hours": 1,
|
||||
"identifier": "sol_futures_lgbm_v1",
|
||||
"feature_parameters": {
|
||||
"include_timeframes": [
|
||||
"5m",
|
||||
"15m"
|
||||
],
|
||||
"include_corr_pairlist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"label_period_candles": 12,
|
||||
"include_shifted_candles": 1,
|
||||
"DI_threshold": 0.9,
|
||||
"weight_factor": 0.9,
|
||||
"principal_component_analysis": false,
|
||||
"use_SVM_to_remove_outliers": true,
|
||||
"indicator_periods_candles": [
|
||||
14
|
||||
],
|
||||
"plot_feature_importances": 0
|
||||
},
|
||||
"data_split_parameters": {
|
||||
"test_size": 0.15,
|
||||
"random_state": 42
|
||||
},
|
||||
"model_training_parameters": {
|
||||
"n_estimators": 300,
|
||||
"learning_rate": 0.05,
|
||||
"max_depth": 5,
|
||||
"num_leaves": 31,
|
||||
"min_child_samples": 20,
|
||||
"subsample": 0.8,
|
||||
"colsample_bytree": 0.8,
|
||||
"reg_alpha": 0.1,
|
||||
"reg_lambda": 0.1,
|
||||
"n_jobs": 1,
|
||||
"verbosity": -1
|
||||
}
|
||||
},
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "",
|
||||
"chat_id": ""
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "0.0.0.0",
|
||||
"listen_port": 8822,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqai_sol",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 5
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.heikinashi_btc.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "1m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": true,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "0.0.0.0",
|
||||
"listen_port": 8814,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.ema26_ema52_cross.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"timeframe": "1m",
|
||||
"can_short" : true,
|
||||
"process_only_new_candles" : true,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "other",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "other",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"BTC/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "0.0.0.0",
|
||||
"listen_port": 8821,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.sol5m.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short": true,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "other",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing": {
|
||||
"price_side": "other",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"SOL/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "0.0.0.0",
|
||||
"listen_port": 8822,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "SOL5m",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 5
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
{
|
||||
"$schema": "https://schema.freqtrade.io/schema.json",
|
||||
"max_open_trades": 1,
|
||||
"stake_currency": "USDT",
|
||||
"stake_amount": "unlimited",
|
||||
"tradable_balance_ratio": 0.99,
|
||||
"fiat_display_currency": "USD",
|
||||
"dry_run": true,
|
||||
"db_url": "sqlite:///tradesv3.chanlun_btc_15.sqlite",
|
||||
"dry_run_wallet": 1000,
|
||||
"cancel_open_orders_on_exit": true,
|
||||
"trading_mode": "futures",
|
||||
"margin_mode": "isolated",
|
||||
"can_short" : true,
|
||||
"timeframe" : "15m",
|
||||
"process_only_new_candles" : false,
|
||||
"unfilledtimeout": {
|
||||
"entry": 1,
|
||||
"exit": 1,
|
||||
"exit_timeout_count": 5,
|
||||
"unit": "minutes"
|
||||
},
|
||||
"entry_pricing": {
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1,
|
||||
"price_last_balance": 0.0,
|
||||
"check_depth_of_market": {
|
||||
"enabled": false,
|
||||
"bids_to_ask_delta": 1
|
||||
}
|
||||
},
|
||||
"exit_pricing":{
|
||||
"price_side": "same",
|
||||
"use_order_book": true,
|
||||
"order_book_top": 1
|
||||
},
|
||||
"exchange": {
|
||||
"name": "binance",
|
||||
"key": "hvoXanRExQvcN4tyGFvEnsSF4gqxXp6ZJnBu5lnhvlVuHaDbj2PhLBQGCLkkyeI8",
|
||||
"secret": "3UKA2oyDj7OoXrausmnaLwLlNfXmlNf2imBdmQqqKHArcJfk6X9xjaUF19wzu82l",
|
||||
"ccxt_config": {},
|
||||
"ccxt_async_config": {},
|
||||
"pair_whitelist": [
|
||||
"WIF/USDT:USDT"
|
||||
],
|
||||
"pair_blacklist": [
|
||||
"BNB/.*"
|
||||
]
|
||||
},
|
||||
"pairlists": [
|
||||
{
|
||||
"method": "StaticPairList",
|
||||
"number_assets": 1,
|
||||
"sort_key": "quoteVolume",
|
||||
"min_value": 0,
|
||||
"refresh_period": 1800
|
||||
}
|
||||
],
|
||||
"telegram": {
|
||||
"enabled": false,
|
||||
"token": "7677670958:AAFL_jgZvNUTPR3R3vWieREX_tDVi9w2C1Y",
|
||||
"chat_id": "580807463"
|
||||
},
|
||||
"api_server": {
|
||||
"enabled": true,
|
||||
"listen_ip_address": "127.0.0.1",
|
||||
"listen_port": 8811,
|
||||
"verbosity": "error",
|
||||
"enable_openapi": false,
|
||||
"jwt_secret_key": "14d3510740e2c39a973a8895f1aa2704d98d08b86170260085709fa5ea48251d",
|
||||
"ws_token": "dtKKDnafBrX4icq_ZCw7acJTahTK4h_yvg",
|
||||
"CORS_origins": [],
|
||||
"username": "freqtrader",
|
||||
"password": "FreqTrade007"
|
||||
},
|
||||
"bot_name": "freqtrade",
|
||||
"initial_state": "running",
|
||||
"force_entry_enable": false,
|
||||
"internals": {
|
||||
"process_throttle_secs": 2
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -1,82 +0,0 @@
|
||||
#!/bin/bash
|
||||
# 缠论分析系统生产环境部署脚本
|
||||
|
||||
# 显示执行的命令
|
||||
set -x
|
||||
|
||||
# 确保脚本在错误时停止
|
||||
set -e
|
||||
|
||||
# 项目根目录
|
||||
PROJECT_DIR=$(pwd)
|
||||
echo "项目将部署在: $PROJECT_DIR"
|
||||
|
||||
# 创建虚拟环境
|
||||
echo "创建Python虚拟环境..."
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# 安装依赖
|
||||
echo "安装依赖包..."
|
||||
pip install --upgrade pip
|
||||
pip install flask pandas matplotlib ccxt pytz talib-binary gunicorn
|
||||
|
||||
# 安装任何额外的系统依赖
|
||||
# sudo apt-get update
|
||||
# sudo apt-get install -y python3-dev
|
||||
|
||||
# 检查目录结构
|
||||
echo "检查目录结构..."
|
||||
mkdir -p web/templates
|
||||
|
||||
# 创建日志目录
|
||||
mkdir -p logs
|
||||
|
||||
# 创建启动脚本
|
||||
echo "创建启动脚本..."
|
||||
cat > start_service.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# 缠论分析系统启动脚本
|
||||
|
||||
# 项目根目录
|
||||
PROJECT_DIR=$(pwd)
|
||||
cd $PROJECT_DIR
|
||||
|
||||
# 激活虚拟环境
|
||||
source venv/bin/activate
|
||||
|
||||
# 启动服务
|
||||
cd web
|
||||
echo "启动缠论分析系统服务..."
|
||||
gunicorn app:app --bind=0.0.0.0:8123 --workers=4 --timeout=120 --log-level=info --log-file=logs/chanlun.log --daemon
|
||||
|
||||
echo "服务已启动,端口8123"
|
||||
echo "日志文件位置: $PROJECT_DIR/web/logs/chanlun.log"
|
||||
EOF
|
||||
|
||||
# 创建停止脚本
|
||||
echo "创建停止脚本..."
|
||||
cat > stop_service.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
# 停止缠论分析系统服务
|
||||
|
||||
echo "停止缠论分析系统服务..."
|
||||
pkill -f "gunicorn app:app"
|
||||
echo "服务已停止"
|
||||
EOF
|
||||
|
||||
# 添加执行权限
|
||||
chmod +x start_service.sh
|
||||
chmod +x stop_service.sh
|
||||
|
||||
# 修改app.py中的调试模式(生产环境应关闭调试模式)
|
||||
if [ -f web/app.py ]; then
|
||||
echo "配置app.py为生产环境模式..."
|
||||
sed -i 's/app.run(debug=True, host='\''0.0.0.0'\'', port=8123)/# 在生产环境中,使用gunicorn启动服务\n# app.run(debug=False, host='\''0.0.0.0'\'', port=8124)/' user_data/Chan/web/app.py
|
||||
else
|
||||
echo "警告: 未找到app.py文件"
|
||||
fi
|
||||
|
||||
echo "部署完成!"
|
||||
echo "使用 ./start_service.sh 启动服务"
|
||||
echo "使用 ./stop_service.sh 停止服务"
|
||||
@@ -1,22 +0,0 @@
|
||||
# ADR-001: 包布局与兼容 shim
|
||||
|
||||
**Status:** Accepted
|
||||
**Date:** 2026-08-05
|
||||
**ECR:** ECR-001
|
||||
|
||||
## Context
|
||||
|
||||
根目录扁平模块被 strategies 与 web 通过模块名直接 import;完全改名会破坏 Freqtrade 策略。需要正式包边界,同时零改 `strategies/`。
|
||||
|
||||
## Decision
|
||||
|
||||
1. 正式包名:`chanlun`(`core` / `pipeline` / `indicators` / `analysis`)。
|
||||
2. 根目录保留同名 shim 文件,再导出公共符号。
|
||||
3. Web 使用 Flask blueprints + services;前端 JS 模块化,不引入 TS 构建。
|
||||
4. `TF_DF` 保留门面类名与公开方法,内部委托 builders。
|
||||
|
||||
## Consequences
|
||||
|
||||
- 策略无需修改。
|
||||
- 长期可逐步引导新代码 `from chanlun import ...`。
|
||||
- shim 需保持至策略侧显式迁移(另立 ECR)。
|
||||
@@ -1,39 +0,0 @@
|
||||
# AGENT_MEMORY — chan
|
||||
|
||||
> Agent 短记忆。先读 `PROJECT_PROFILE.md`,再读本文件。不要把猜测写进这里。
|
||||
|
||||
## 双前端
|
||||
|
||||
| 入口 | 引擎 | 实时 |
|
||||
|------|------|------|
|
||||
| `/` | Lightweight Charts | HTTP 定时自动刷新(增量 + 每 6 次全量) |
|
||||
| `/chan_tv` | Charting Library 全版 | datafeed `subscribeBars` → WS |
|
||||
|
||||
勿把主站 `live_feed` 方案与 chan_tv datafeed 混为一谈;主站 WS 实时已回退。
|
||||
|
||||
## 版本
|
||||
|
||||
- `system_version`:`v1.0.0`(ECR-001)
|
||||
- `strategy_version`:与 system 解耦;默认不改 `config/` / `strategies/`
|
||||
|
||||
## 近期变更
|
||||
|
||||
- IDEA-002 / `9f1e736`:主站内存泄漏 dispose、首屏单次 analyze、ChanMACD 复用、chan_tv 体验
|
||||
- ECR-002 Reviewed:拆 `web/services/runtime/`、加深 analyze 契约
|
||||
- ECR-003 Reviewed:主站威科夫叠层(`chanlun/analysis/wyckoff/` + `include_wyckoff`)→ `081a57a`
|
||||
- ECR-004 Reviewed:TR 评分硬化 + VP 少系列 + 阶段/门闩/单测(无币种参数)
|
||||
|
||||
## 硬约束提醒
|
||||
|
||||
- `/api/analyze` 字段可增不可删
|
||||
- 无 ADR 不改笔/段/中枢/买卖点语义
|
||||
- 威科夫为独立叠层(ECR-003);勿借机改缠论算法
|
||||
- 交易 L2+ → RISK_REVIEW + EXP;Live 须 Human
|
||||
|
||||
## 已知债务
|
||||
|
||||
- `chart_tv.js` 单体巨大 → 后续可选 ECR
|
||||
- analyze 契约已加深(mock HTTP + wyckoff opt-in);可再加固定 JSON 快照文件
|
||||
- 内存泄漏尚无自动化 heap/监听断言
|
||||
- `macd_config` POST 写本地 global 的历史 quirks(未改)
|
||||
- 威科夫启发式参数未做 UI 调参
|
||||
@@ -1,73 +0,0 @@
|
||||
# CHANGELOG
|
||||
|
||||
## Unreleased — 2026-08-06
|
||||
|
||||
### ECR-004(L2,Reviewed)
|
||||
|
||||
- 威科夫 TR 评分选段(防吞前置趋势);阶段非重叠最小跨度
|
||||
- 主站 VP Top-8 + bins≤24;填充线减负
|
||||
- `elements_only` 时不跑威科夫;收紧单测(无币种独立参数)
|
||||
|
||||
### ECR-003(L2,Reviewed)
|
||||
|
||||
- 新增 `chanlun/analysis/wyckoff/`:交易区间、阶段 A–E、Spring/SOS/LPS/UTAD 等事件、区间 VP(POC/VAH/VAL)、量能确认
|
||||
- `/api/analyze` 按需 `include_wyckoff=1` 返回顶层 `wyckoff`
|
||||
- 主站「威科夫」开关与 Lightweight 叠层(区间/阶段/事件/VP)
|
||||
- 单测与 analyze 契约 opt-in 断言
|
||||
|
||||
### ECR-002(L3,Reviewed)
|
||||
|
||||
- 拆分 `web/services/runtime.py` 为包 `web/services/runtime/`(state / timeframes / market_data / indicators / analyze / serialize)
|
||||
- 加深 analyze 契约测试(mock HTTP + analyze_chan 键集 + serialize JSON)
|
||||
- 新增 TF_DF 全量 init 冒烟与 runtime 门面测试
|
||||
|
||||
### IDEA-002(L1 补档)
|
||||
|
||||
对应 commit `9f1e736`。无新 system tag(仍为 `v1.0.0`)。
|
||||
|
||||
#### Fixed
|
||||
|
||||
- 主站自动刷新内存泄漏:`disposeTradingViewCharts`、去掉重复 sync 监听、默认增量刷新(每 6 次全量重建笔/段/中枢)
|
||||
- 加密货币首屏重复调用 `/api/analyze`
|
||||
- ChanMACD 同周期重复全量分析(复用 `get_klc_list` 结果)
|
||||
|
||||
#### Changed
|
||||
|
||||
- `/chan_tv`:WS/REST 可分离配置、指标布局 localStorage、未完成中枢与 datafeed 实时 tick 行为完善
|
||||
- `PROJECT_PROFILE` Realtime 条目与 chan_tv WS 对齐(文档)
|
||||
|
||||
#### Docs
|
||||
|
||||
- ESS:IDEA-002、AGENT_MEMORY、AGENTS;ECR-002 实现与报告
|
||||
|
||||
---
|
||||
|
||||
## v1.0.0 — 2026-08-05(首个正式 Release)
|
||||
|
||||
对应 ECR-001 / tag `v1.0.0`。详见 `docs/RELEASE/ECR-001-v1.0.0.md`。
|
||||
|
||||
### Added
|
||||
|
||||
- 正式包 `chanlun/`(core / pipeline / builders / indicators / analysis)
|
||||
- ESS 文档树 `docs/`(PROFILE / ECR / SPEC / ADR / HANDOFF / CODE_REVIEW / RELEASE)
|
||||
- Web `config.py`、`services/`、`api/` blueprints
|
||||
- 前端 `web/static/js/app/` 模块
|
||||
- Golden 回归 `tests/generate_golden.py` + fixtures
|
||||
|
||||
### Changed
|
||||
|
||||
- 根目录 `Chan*.py` / `TF_DF.py` 改为兼容 shim
|
||||
- `TF_DF` 实现拆至 builders,门面签名保持
|
||||
- `web/app.py` 瘦身为 `create_app()`
|
||||
- `index.html` 去掉巨型 inline 业务 JS
|
||||
- HTTP 代理改为环境变量配置
|
||||
- strategies / web / tests / examples → `from chanlun...` 导入
|
||||
|
||||
### Fixed
|
||||
|
||||
- 恢复缺失的 `TF_DF.get_zs_list`(委托 `get_seg_zs_list`)
|
||||
|
||||
### Moved
|
||||
|
||||
- 示例 → `examples/`;笔记 → `docs/notes/`
|
||||
- 未接线 TSX/TS → `static/js/_unused/`
|
||||
@@ -1,75 +0,0 @@
|
||||
# CODE_REVIEW — ECR-001
|
||||
|
||||
**Role:** REVIEWER
|
||||
**Date:** 2026-08-05
|
||||
**Commit:** `74dec4e` (`refactor: 缠论引擎包化与 Web 分层(ECR-001)`)
|
||||
**Decision:** Approve
|
||||
|
||||
## Evidence loaded
|
||||
|
||||
- `docs/ECR/ECR-001-chan-web-restructure.md`
|
||||
- `docs/ENGINEERING_SPEC/ECR-001-restructure.md`
|
||||
- `docs/IMPLEMENTATION_REPORT/ECR-001.md`
|
||||
- `docs/TEST_REPORT/ECR-001.md`
|
||||
- `docs/HANDOFF/ECR-001-engineer-to-reviewer.md`
|
||||
- Diff `e2e45bc..74dec4e`;本地复跑测试
|
||||
|
||||
## Acceptance ↔ Evidence
|
||||
|
||||
| Acceptance | Verdict | Evidence |
|
||||
|------------|---------|----------|
|
||||
| `from ChanLun import ChanLun` / `ChanEnum` 仍可用 | PASS | 复跑 shim+package 同一对象;`test_compat_shim_still_works` |
|
||||
| Golden bi/seg/zs/bsp 与基线一致 | PASS | `python tests/generate_golden.py --check` → GOLDEN OK;pytest 含 golden |
|
||||
| `/api/analyze` 关键字段兼容 | PASS | `analyze_contract_keys.json` + 路由注册冒烟(未做实盘拉行情 E2E,见 Findings) |
|
||||
| `web/app.py` 瘦身 factory | PASS | `web/app.py` 32 行;`create_app` + blueprints |
|
||||
| `index.html` 无大体量 inline 业务 JS | PASS | ~1482 行;业务在 `static/js/app/*` |
|
||||
| ESS docs / TEST / IMPL / CHANGELOG | PASS | `docs/` 齐全 |
|
||||
| `config/` 无内容变更 | PASS | `git diff e2e45bc..HEAD -- config` 空 |
|
||||
| `strategies/` 无内容变更 | **AMENDED** | 见下「范围修订」 |
|
||||
|
||||
## 范围修订(Human 后续指示)
|
||||
|
||||
原 ECR Forbidden 写「不改 strategies/」。实现后期 Human 要求「一次性做完」导入迁移:strategies 仅改 import / `sys.path`(26 files, +75/−75),**无策略交易逻辑变更**。
|
||||
审阅结论:视为 **L3 结构收尾的允许增补**,不构成交易语义 L2;建议 ECR Acceptance 改为「strategies 仅允许 import/path 迁移,禁止改买卖逻辑」。
|
||||
**不据此 Request changes。**
|
||||
|
||||
## 复跑结果(Reviewer)
|
||||
|
||||
```text
|
||||
shim+package OK
|
||||
GOLDEN OK {klu:400, klc:208, bi:14, seg:2, zs:0, bsp:3}
|
||||
pytest tests/test_golden_pipeline.py web/tests/test_analyze_contract.py → 6 passed
|
||||
```
|
||||
|
||||
## Findings
|
||||
|
||||
### Non-blocking(记入债务,需新 ECR 再动)
|
||||
|
||||
1. **`web/services/runtime.py` ~1176 行** — 已从 app 抽出但仍是大模块;facade 再导出符合计划 → **已起草 `docs/ECR/ECR-002-runtime-split.md`(Draft)**。
|
||||
2. **`web/static/js/app/chart_tv.js` ~4664 行** — `initTradingView` 单体;行为冻结下可接受;ECR-002 可选范围。
|
||||
3. **`/api/analyze` 契约测试偏浅** — 仅关键字段清单 + 路由存在;无固定 fixture 的端到端 JSON 快照(需 mock 行情)→ ECR-002。
|
||||
4. **TEST_REPORT 写「5 passed」** — 现为 6(含 shim 兼容测);Release 前可改正文(L0 docs)。
|
||||
5. **L1:`TF_DF.get_zs_list` 恢复** — 合理兼容修复;golden 走 analyze 路径未覆盖 `TF_DF(df,...)` 全量 `__init__` → ECR-002 Acceptance。
|
||||
|
||||
### No blockers
|
||||
|
||||
未发现违反「算法语义冻结 / API 可增不可删 / 无 Vite-React / config 未改」的证据。
|
||||
|
||||
## Decision
|
||||
|
||||
**Approve**
|
||||
|
||||
- ECR-001 可进入 Release(本变更无交易 EXP 门禁)。
|
||||
- 非阻断项进入 backlog / 未来 ECR,不阻塞 tag。
|
||||
|
||||
## Next owner
|
||||
|
||||
`release_manager` — 写 RELEASE_REPORT、打 tag(需 Human 确认发布动作)。
|
||||
|
||||
## Traceability
|
||||
|
||||
| Item | Updated |
|
||||
|------|---------|
|
||||
| Acceptance mapping | 本文件 |
|
||||
| STATE.owner | → release_manager |
|
||||
| ECR Status | → Done (Reviewed) |
|
||||
@@ -1,74 +0,0 @@
|
||||
# CODE_REVIEW — ECR-002
|
||||
|
||||
**Role:** REVIEWER
|
||||
**Date:** 2026-08-06
|
||||
**Scope:** 工作区未提交实现(相对 `HEAD`/`9f1e736`);包 `web/services/runtime/` + 测试 + ESS 文档
|
||||
**Decision:** Approve
|
||||
|
||||
## Evidence loaded
|
||||
|
||||
- `docs/ECR/ECR-002-runtime-split.md`
|
||||
- `docs/ENGINEERING_SPEC/ECR-002-runtime-split.md`
|
||||
- `docs/IMPLEMENTATION_REPORT/ECR-002.md`
|
||||
- `docs/TEST_REPORT/ECR-002.md`
|
||||
- `docs/HANDOFF/ECR-002-engineer-to-reviewer.md`
|
||||
- 包源码:`web/services/runtime/{__init__,state,timeframes,market_data,indicators,analyze,serialize}.py`
|
||||
- Diff:删除 `web/services/runtime.py`;新增包与测试
|
||||
|
||||
## Acceptance ↔ Evidence
|
||||
|
||||
| Acceptance | Verdict | Evidence |
|
||||
|------------|---------|----------|
|
||||
| runtime 门面公开符号兼容(含历史 `import *` 漏出) | PASS | 手工核对 api 所需符号;`timezone`/`OrderedDict`/`np`/`StructureZone*`/`ThreadPoolExecutor` 等在门面;`test_runtime_facade` |
|
||||
| Golden 通过 | PASS | 复跑 `tests/test_golden_pipeline.py` |
|
||||
| Analyze 契约加深 | PASS | `test_analyze_contract`:键清单 + analyze_chan 键集 + serialize JSON + mock HTTP |
|
||||
| TF_DF 全量 init 冒烟 | PASS | `tests/test_tf_df_init.py`(`interval=1`) |
|
||||
| config/strategies 无交易逻辑 diff | PASS | 工作区无 `config/`/`strategies/` 变更 |
|
||||
| IMPL / TEST / CHANGELOG / TRACEABILITY | PASS | docs 已落盘 |
|
||||
| CODE_REVIEW Approve | PASS | 本文件 |
|
||||
|
||||
## 复跑结果(Reviewer)
|
||||
|
||||
```text
|
||||
PYTHONPATH=.:web python -m pytest \
|
||||
tests/test_golden_pipeline.py \
|
||||
tests/test_tf_df_init.py \
|
||||
web/tests/test_runtime_facade.py \
|
||||
web/tests/test_analyze_contract.py -q
|
||||
→ 13 passed
|
||||
```
|
||||
|
||||
算法冻结抽查:`analyze.py` 仍为 `cal_bi_zs(seg_list)` + `_last_chan_macd` 复用;未改笔段中枢语义。
|
||||
|
||||
## Findings
|
||||
|
||||
### Non-blocking(不挡 Approve)
|
||||
|
||||
1. **门面标量同步只做一次** — `__init__` 在首次 `refresh` 后把 `DATA_SERVICE_AVAILABLE` / `macd_*` 写入模块 dict;之后 `refresh_data_service_metadata` 只改 `state.*`。通过 `R.DATA_SERVICE_AVAILABLE` 读取可能与 state 短期不一致;`from services.runtime import *` 的 bool 拷贝问题在 monolith 时代已存在。建议后续 L1:在 `refresh` 末尾同步写回门面模块,或让标量只经 `state`/`__getattr__` 暴露。
|
||||
2. **`__getattr__` 对已绑定名无效** — 与上条相关;属清理项。
|
||||
3. **`chart_tv.js` 拆分未做** — ECR 明确可选;继续记入 backlog。
|
||||
4. **契约测试仍无「固定 JSON 快照文件」** — 已有 mock HTTP + 键集,比 ECR-001 深;完整响应快照可另开 L1/ECR。
|
||||
5. **`web/tests/test_cn_stock_data_fetch.py` 仍因旧 `user_data.Chan...` 路径无法收集** — 既有问题,非本 ECR 引入。
|
||||
|
||||
### No blockers
|
||||
|
||||
未发现违反「算法语义冻结 / API 可增不可删 / 无 Vite-React / 未动 strategies·config / 未引主站 WS」的证据。
|
||||
|
||||
## Decision
|
||||
|
||||
**Approve**
|
||||
|
||||
- ECR-002 可标 Done(Reviewed);不强制新 system tag(仍为 `v1.0.0` Unreleased 文档变更)。
|
||||
- 非阻断项进 backlog;不阻塞合并本实现。
|
||||
|
||||
## Next owner
|
||||
|
||||
`engineer` / Human — 提交合并;若要发版再交 `release_manager`(本 ECR 未要求 bump tag)。
|
||||
|
||||
## Traceability
|
||||
|
||||
| Item | Updated |
|
||||
|------|---------|
|
||||
| Acceptance mapping | 本文件 |
|
||||
| STATE.owner | → idle / merge |
|
||||
| ECR Status | → Done (Reviewed) |
|
||||
@@ -1,77 +0,0 @@
|
||||
# CODE_REVIEW — ECR-003
|
||||
|
||||
**Role:** REVIEWER
|
||||
**Date:** 2026-08-06
|
||||
**Scope:** 工作区未提交 ECR-003(相对 `origin/dev` @ `df27b4d`)
|
||||
**Decision:** Approve(带非阻断 Findings;建议合并前勿提交 `.DS_Store`)
|
||||
|
||||
## Evidence loaded
|
||||
|
||||
- `chanlun/analysis/wyckoff/{engine,range,events,volume_profile}.py`
|
||||
- `web/api/analyze.py`(`include_wyckoff`)
|
||||
- `web/templates/index.html`、`chart_view.js`、`macd_ui.js`、`chart_tv.js` 威科夫块
|
||||
- `tests/test_wyckoff.py`、`web/tests/test_analyze_contract.py`
|
||||
- ESS:ECR/PRODUCT/ENG/IMPL/TEST/HANDOFF
|
||||
|
||||
## Acceptance ↔ Evidence
|
||||
|
||||
| Acceptance | Verdict | Evidence |
|
||||
|------------|---------|----------|
|
||||
| `include_wyckoff=1` 返回约定键;默认不强制 | PASS | 契约测试;默认无 `wyckoff` 键 |
|
||||
| 合成 TR + 事件;VP POC | PASS | `test_wyckoff.py`(12 相关套件全绿) |
|
||||
| 主站可开关绘制 | PASS | 主开关按需拉取;子项本地重绘 |
|
||||
| golden 不变 | PASS | `test_golden_pipeline` |
|
||||
| 未改缠论算法 / strategies / chan_tv | PASS | diff 范围核对 |
|
||||
| ESS 闭环 | PASS | IMPL/TEST/TRACE/CHANGELOG/本文件 |
|
||||
|
||||
## 复跑
|
||||
|
||||
```text
|
||||
PYTHONPATH=.:web python -m pytest \
|
||||
tests/test_wyckoff.py tests/test_golden_pipeline.py \
|
||||
web/tests/test_analyze_contract.py -q
|
||||
→ 12 passed
|
||||
```
|
||||
|
||||
## Findings
|
||||
|
||||
### Important(不挡 Approve,建议跟进)
|
||||
|
||||
1. **交易区间易吞并前置趋势**
|
||||
`detect_trading_range` 从最长窗口向下搜,合成夹具下 `abs_start_idx=0`,箱体前下跌段被算进 TR。单测只断言「有区间 + 有事件」,未锁定高低/起点。
|
||||
*建议:* 用「宽度/触边密度」评分取最优段,或要求近端触边;测试断言 `high≈60/low≈40` 与起点靠近箱体。
|
||||
|
||||
2. **VP 叠层系列数偏多,可能加压自动刷新内存**
|
||||
开启 VP 时约每个 bin 一条 `addLineSeries`(默认 ~50),再加区间填充/阶段。与 IDEA-002 内存修复同路径全量重建时放大。
|
||||
*建议:* 只画非零 bin 或合并为少量 series / histogram;或限制 `vp_bins` 上限到 24。
|
||||
|
||||
### Medium
|
||||
|
||||
3. **阶段 C–E 在事件扎堆时常退化重叠**
|
||||
夹具输出中 D/E 起止几乎相同;状态机按事件锚点硬切,缺少最小阶段长度。展示可用,语义偏弱。
|
||||
|
||||
4. **`elements_only=true` 仍可能跑威科夫**
|
||||
威科夫挂在路由末尾,不依赖 `not elements_only`。主站当前不这么发,但契约上奇怪;建议与主周期分析同门闩。
|
||||
|
||||
5. **单测断言偏松**
|
||||
`Spring in types or SOS`、`abs(poc-50)<2` 对回归保护不足。
|
||||
|
||||
### Low
|
||||
|
||||
6. 失败时 `wyckoff.error` 回传异常字符串(与结构区 print 风格一致,信息暴露轻微)。
|
||||
7. 事件 marker 一律 `arrowUp`(跌破类也可 `arrowDown`)。
|
||||
8. 工作区 `.DS_Store` 脏文件——**勿纳入 commit**。
|
||||
|
||||
### No blockers
|
||||
|
||||
未发现:契约删键、缠论语义改动、策略/config 改动、未鉴权危险写操作、主站误引 WS。
|
||||
|
||||
## Decision
|
||||
|
||||
**Approve**
|
||||
|
||||
可合并提交(排除 `.DS_Store`)。Important #1/#2 可开后续 L1/L2,不阻塞本 ECR 着陆。
|
||||
|
||||
## Next owner
|
||||
|
||||
`engineer` / Human — commit(勿含 `.DS_Store`);可选跟进 TR 评分与 VP 绘图优化。
|
||||
@@ -1,53 +0,0 @@
|
||||
# CODE_REVIEW — ECR-004
|
||||
|
||||
**Role:** REVIEWER
|
||||
**Date:** 2026-08-06
|
||||
**Scope:** `d3188ca`(相对 ECR-003)威科夫硬化
|
||||
**Decision:** Approve
|
||||
|
||||
## Evidence loaded
|
||||
|
||||
- Diff `d3188ca`:`range.py` / `events.py` / `analyze.py` / `chart_tv.js` / tests / ESS
|
||||
- 复跑:`tests/test_wyckoff.py` + golden + analyze contract → **14 passed**
|
||||
- 合成夹具抽查:`abs_start_idx=20`,low/high≈40.1/59.9(相对 003 的 bar0 已修好)
|
||||
|
||||
## Acceptance ↔ Evidence
|
||||
|
||||
| Acceptance | Verdict | Evidence |
|
||||
|------------|---------|----------|
|
||||
| TR 不吞明显前置趋势;边界近箱体 | PASS | 评分选段;单测 low/high 带 + `abs_start≥12` + start 时间容差 |
|
||||
| VP series 减负 | PASS | Top-8 + 填充 3 + POC/VAH/VAL;API bins≤24 |
|
||||
| 阶段最小跨度 / 不重合 | PASS | 链式 cursor;unique (start,end) 断言 |
|
||||
| elements_only 门闩 | PASS | `include_wyckoff and not elements_only` + 契约测试 |
|
||||
| golden 不变 / 无策略改动 / 无币种表 | PASS | golden 绿;diff 无 config/strategies |
|
||||
|
||||
## Findings
|
||||
|
||||
### Medium(不挡 Approve)
|
||||
|
||||
1. **同分 tie-break 偏向更长窗口**
|
||||
循环从长到短,`score <= best_score` 时保留已有(更长)。多数情况分数拉开;若实盘出现「长窗与短窗同分」,仍可能略偏长。可选:同分取更短,或加 `1/length` 微项。
|
||||
|
||||
2. **阶段常截断为 A–C**
|
||||
Spring/SOS 落在尾部时 D/E 因 `min_span` 被吃掉——与 ENG「空间不足截断」一致,但 UI 勾选「阶段」时用户可能期望总见 D/E。属产品预期,非缺陷;可在 UI/文档标明「尾部不足则省略」。
|
||||
|
||||
### Low
|
||||
|
||||
3. **`abs_start_idx >= 12` 弱于「箱体起点」** —— 主测已用时间容差;该断言可再收紧到 `>= 16` 一类。
|
||||
4. **VP Top-N 无自动化 series 计数** —— 靠代码审查 + ENG 约定。
|
||||
5. 事件 marker 仍一律 `arrowUp`(003 遗留)。
|
||||
6. 失败路径仍回传 `wyckoff.error` 字符串。
|
||||
|
||||
### No blockers
|
||||
|
||||
未发现契约删键、缠论语义改动、策略改动、或回归红灯。
|
||||
|
||||
## Decision
|
||||
|
||||
**Approve**
|
||||
|
||||
ECR-004 可维持 Done (Reviewed)。Medium 项进 backlog,不必立刻新 ECR,除非实盘 TR 仍偏长。
|
||||
|
||||
## Next owner
|
||||
|
||||
Human — 主站 BTC 勾选威科夫目测;无发版要求则保持 `v1.0.0` Unreleased 累计。
|
||||
@@ -1,70 +0,0 @@
|
||||
# ECR-001
|
||||
|
||||
**Title:** 缠论引擎包化 + Web 分层重构(行为冻结)
|
||||
**Status:** Approved
|
||||
**Date:** 2026-08-05
|
||||
**Change Level:** L3
|
||||
|
||||
## Change
|
||||
|
||||
将根目录扁平 `Chan*.py` / `TF_DF.py` 包化为 `chanlun/`,拆分 `web/app.py` 与巨型 `index.html` inline JS;算法与 `/api/analyze` 契约冻结;`config/` / `strategies/` 不动。
|
||||
|
||||
## Motivation
|
||||
|
||||
根目录与 Web 单体过大、职责混杂,难以维护与测试;需在不影响 Freqtrade 策略导入的前提下重整结构。
|
||||
|
||||
## Scope
|
||||
|
||||
### Allowed
|
||||
|
||||
- 创建 `chanlun/`(core / pipeline / indicators / analysis)与根目录兼容 shim
|
||||
- 拆分 `TF_DF` 为 builders + 门面(公开方法签名不变)
|
||||
- Web:`config` + `services` + `api` blueprints;配置外置(proxy / DATA_SERVICE)
|
||||
- 前端:`index.html` 业务 JS 外置到 `static/js/app/`;隔离未接线 TS/TSX
|
||||
- 示例与笔记迁入 `examples/` / `docs/notes/`
|
||||
- Golden / 契约回归测试
|
||||
|
||||
### Forbidden
|
||||
|
||||
- 修改笔 / 线段 / 中枢 / 买卖点算法语义
|
||||
- 破坏 `/api/analyze` JSON 字段(可增不可删)
|
||||
- 修改 `config/`;修改 `strategies/` 交易逻辑或参数(import/`sys.path` 迁移除外,见 CODE_REVIEW)
|
||||
- 引入 Vite/React/TS 构建
|
||||
- 重做 UI 视觉或更换 TradingView
|
||||
|
||||
## Risk
|
||||
|
||||
| Risk | Mitigation |
|
||||
|------|------------|
|
||||
| 策略 import 断裂 | 根 shim + 冒烟导入 |
|
||||
| 拆文件改算法 | 仅搬移;golden fixture |
|
||||
| 前端事件遗漏 | 按块抽取 + 手工/冒烟 |
|
||||
| API 字段漂移 | analyze 契约测试 |
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] `from ChanLun import ChanLun` / `from ChanEnum import ...` 仍可用
|
||||
- [x] Golden:同一 fixture 下 bi/seg/zs/bsp 序列化结果与基线一致
|
||||
- [x] `/api/analyze` 关键字段集合兼容(契约冒烟)
|
||||
- [x] `web/app.py` 瘦身为 factory;业务在 services/api
|
||||
- [x] `index.html` 不再含大体量业务 inline JS
|
||||
- [x] ESS docs 齐全;TEST_REPORT / IMPLEMENTATION_REPORT / CHANGELOG
|
||||
- [x] `config/` 无内容变更;`strategies/` 仅允许 import/`sys.path` 迁移(Human 增补,无交易逻辑变更)
|
||||
|
||||
**Status:** Done (Released as `v1.0.0`)
|
||||
|
||||
## Rollback
|
||||
|
||||
单分支 / 单 PR 回滚;shim 期可整体 `git revert`。
|
||||
|
||||
## Risk Review
|
||||
|
||||
- Path: `docs/RISK_REVIEW/ECR-001.md` — N/A(不改交易语义)
|
||||
|
||||
## Linked
|
||||
|
||||
- PRD / PRODUCT_SPEC: `docs/PRODUCT_SPEC/ECR-001-restructure.md`
|
||||
- ENGINEERING_SPEC: `docs/ENGINEERING_SPEC/ECR-001-restructure.md`
|
||||
- ADR: `docs/ADR/ADR-001-package-layout.md`
|
||||
- EXPERIMENT: N/A
|
||||
- TRACEABILITY: Yes
|
||||
@@ -1,74 +0,0 @@
|
||||
# ECR-002
|
||||
|
||||
**Title:** 拆分 `web/services/runtime.py` + 加深 `/api/analyze` 契约测试
|
||||
**Status:** Done (Reviewed)
|
||||
**Date:** 2026-08-06
|
||||
**Change Level:** L3(行为冻结;若 golden 漂移则升 L2)
|
||||
|
||||
## Change
|
||||
|
||||
将仍偏大的 `web/services/runtime.py` 按职责拆为可维护子模块;加深 analyze API 契约/快照测试;可选拆分主站巨型 `chart_tv.js`(本轮未做)。
|
||||
|
||||
## Motivation
|
||||
|
||||
ECR-001 CODE_REVIEW 非阻断债务:runtime 过大、契约测试偏浅、chart_tv 单体。不处理会继续抬高 Web 改动风险。
|
||||
|
||||
## Scope
|
||||
|
||||
### Allowed
|
||||
|
||||
- 物理拆分 `web/services/runtime.py` → 包 `web/services/runtime/`(state / timeframes / market_data / indicators / analyze / serialize + 门面)
|
||||
- 加深 `web/tests/`:固定 fixture / mock 行情下的关键字段快照与契约
|
||||
- 补 `TF_DF(..., interval=1)` 全量 `__init__` 冒烟
|
||||
- 更新 TECH_STACK / TRACEABILITY / CHANGELOG
|
||||
|
||||
### Forbidden
|
||||
|
||||
- 修改笔 / 线段 / 中枢 / 买卖点算法语义
|
||||
- 破坏 `/api/analyze` JSON 字段(可增不可删)
|
||||
- 修改 `config/`、`strategies/` 交易逻辑或参数
|
||||
- 引入 Vite/React/TS 构建
|
||||
- 为主站重新引入 WebSocket 实时(须另 ECR)
|
||||
- 无 Approve 即大规模改前端视觉
|
||||
|
||||
## Risk
|
||||
|
||||
| Risk | Mitigation |
|
||||
|------|------------|
|
||||
| 拆文件隐式改行为 | 仅搬移;golden + analyze 契约/快照 |
|
||||
| 门面漏导出 | 保留 `runtime` re-export + 历史 import * 兼容符号 |
|
||||
| 测试依赖真实行情 | mock / fixture;不绑生产 WS |
|
||||
| chart_tv 拆分漏事件 | 本轮不做 |
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] `runtime` 门面公开符号与拆分前兼容(含 `timezone`/`OrderedDict`/`np`/StructureZone 等历史漏出)
|
||||
- [x] Golden:`pytest tests/test_golden_pipeline.py` 通过
|
||||
- [x] Analyze 契约/快照测试通过且覆盖关键字段清单以上
|
||||
- [x] TF_DF 全量 init 冒烟通过
|
||||
- [x] `config/` / `strategies/` 无交易逻辑 diff
|
||||
- [x] IMPLEMENTATION_REPORT / TEST_REPORT / CHANGELOG / TRACEABILITY 更新
|
||||
- [x] CODE_REVIEW Approve
|
||||
|
||||
## Rollback
|
||||
|
||||
`git revert` 本 ECR 提交;门面保留期可整包回滚。
|
||||
|
||||
## Risk Review
|
||||
|
||||
- Path: `docs/RISK_REVIEW/ECR-002.md` — N/A(不改交易决策语义)
|
||||
|
||||
## Linked
|
||||
|
||||
- IDEA: `docs/IDEA/IDEA-003-runtime-split.md`
|
||||
- PRODUCT_SPEC: `docs/PRODUCT_SPEC/ECR-002-runtime-split.md`
|
||||
- ENGINEERING_SPEC: `docs/ENGINEERING_SPEC/ECR-002-runtime-split.md`
|
||||
- ADR: 引用 ADR-001(包内再拆,无新顶层布局 ADR)
|
||||
- EXPERIMENT: N/A
|
||||
- TRACEABILITY: Yes
|
||||
- IMPLEMENTATION_REPORT: `docs/IMPLEMENTATION_REPORT/ECR-002.md`
|
||||
- TEST_REPORT: `docs/TEST_REPORT/ECR-002.md`
|
||||
|
||||
## Origin
|
||||
|
||||
- `docs/CODE_REVIEW/ECR-001.md` Findings 1–3、5
|
||||
@@ -1,62 +0,0 @@
|
||||
# ECR-003
|
||||
|
||||
**Title:** 主站威科夫分析与图表展示
|
||||
**Status:** Done (Reviewed)
|
||||
**Date:** 2026-08-06
|
||||
**Change Level:** L2
|
||||
|
||||
## Change
|
||||
|
||||
在主站 `/` 增加威科夫交易区间、阶段(A–E)、关键事件(Spring/SOS/LPS/UTAD 等)、区间内简易 VP(POC/VAH/VAL)与量能确认;按需接入 `/api/analyze`。
|
||||
|
||||
## Motivation
|
||||
|
||||
用户需要在缠论图上叠加威科夫结构解读;与现有结构区语义分离。
|
||||
|
||||
## Scope
|
||||
|
||||
### Allowed
|
||||
|
||||
- 新建 `chanlun/analysis/wyckoff/`
|
||||
- `/api/analyze` 增加可选 `include_wyckoff` 与响应字段 `wyckoff`(可增不可删既有字段)
|
||||
- 主站 UI 开关与 Lightweight 绘图
|
||||
- 单测 + ESS 文档
|
||||
|
||||
### Forbidden
|
||||
|
||||
- 修改笔/段/中枢/买卖点算法语义
|
||||
- 改 `config/` / `strategies/`
|
||||
- `/chan_tv` Study
|
||||
- Vite/React、主站 WebSocket 实时(另 ECR)
|
||||
|
||||
## Risk
|
||||
|
||||
| Risk | Mitigation |
|
||||
|------|------------|
|
||||
| 启发式误标 | 规格写明启发式;UI 可关;单测合成形态 |
|
||||
| 负载 | 默认关闭,勾选才计算 |
|
||||
| 与结构区混淆 | 独立开关与字段名 |
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] `include_wyckoff=1` 返回约定 `wyckoff` 键;默认不强制计算
|
||||
- [x] 合成 fixture:能检出 TR + 至少一类事件;VP POC 可测
|
||||
- [x] 主站可开关绘制区间/阶段/事件/VP
|
||||
- [x] golden 缠论基线不变
|
||||
- [x] TEST/IMPL/CHANGELOG/TRACEABILITY + CODE_REVIEW
|
||||
|
||||
## Rollback
|
||||
|
||||
`git revert`;关闭 UI 开关即可无图面影响。
|
||||
|
||||
## Risk Review
|
||||
|
||||
- `docs/RISK_REVIEW/ECR-003.md` — N/A(展示分析,非 Live 策略)
|
||||
|
||||
## Linked
|
||||
|
||||
- IDEA: `docs/IDEA/IDEA-004-wyckoff-main.md`
|
||||
- PRODUCT_SPEC / ENGINEERING_SPEC: 同目录 ECR-003-*
|
||||
- EXPERIMENT: N/A
|
||||
- TRACEABILITY: Yes
|
||||
- CODE_REVIEW: `docs/CODE_REVIEW/ECR-003.md` — Approve
|
||||
@@ -1,69 +0,0 @@
|
||||
# ECR-004
|
||||
|
||||
**Title:** 威科夫区间评分硬化与主站 VP 绘图减负
|
||||
**Status:** Done (Reviewed)
|
||||
**Date:** 2026-08-06
|
||||
**Change Level:** L2
|
||||
|
||||
## Change
|
||||
|
||||
跟进 ECR-003 CODE_REVIEW Findings:改进交易区间选取启发式、阶段最小长度、收紧单测;主站 VP/叠层降低 Lightweight series 数量;`include_wyckoff` 与主周期分析同门闩。
|
||||
|
||||
## Motivation
|
||||
|
||||
003 已 Approve 合入;质量与内存项不得回塞已审变更,须独立可审闭环。
|
||||
|
||||
## Scope
|
||||
|
||||
### Allowed
|
||||
|
||||
- `chanlun/analysis/wyckoff/range.py` / `events.py`(阶段)启发式与单测
|
||||
- `web/static/js/app/chart_tv.js` 威科夫 VP/填充绘制路径
|
||||
- `web/api/analyze.py`:`elements_only` 时不跑威科夫;默认 `vp_bins` 上限 24
|
||||
- ESS 文档与契约测试补充断言(不删既有 `wyckoff` 键)
|
||||
|
||||
### Forbidden
|
||||
|
||||
- 改笔/段/中枢/买卖点语义
|
||||
- `config/` / `strategies/`
|
||||
- `/chan_tv`
|
||||
- 新数据源 / 订单流
|
||||
- **按币种独立参数表**(全局 ATR 相对即可;当前以 BTC 场景验证)
|
||||
|
||||
## Decisions(Approve 时锁定)
|
||||
|
||||
- VP:**A+C**(前端 Top-N 有量 bin + 服务端 bins 上限 24)
|
||||
- 不做 per-symbol 参数
|
||||
|
||||
## Risk
|
||||
|
||||
| Risk | Mitigation |
|
||||
|------|------------|
|
||||
| TR 结果相对 003 漂移 | 合成夹具锁定高低与起点;文档标明启发式迭代 |
|
||||
| 前端 VP 观感变化 | 保留 POC/VAH/VAL;密度用 Top-N |
|
||||
| 回归 | 扩展 `tests/test_wyckoff.py` + 既有契约套件 |
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] 合成箱体夹具:`trading_range` 高低接近箱体边界,起点不落入明显前置趋势段
|
||||
- [x] 开启 VP 时主图新增 series 数显著低于「每 bin 一条」(目标:填充+VP ≤ ~15 或等价合并策略)
|
||||
- [x] 阶段输出满足最小跨度或合并退化段;文档说明规则
|
||||
- [x] `elements_only=true` 即使 `include_wyckoff=1` 也不返回 `wyckoff`
|
||||
- [x] golden 缠论基线不变;相关 pytest 绿
|
||||
- [x] TEST/IMPL/CHANGELOG/TRACEABILITY + CODE_REVIEW
|
||||
|
||||
## Rollback
|
||||
|
||||
`git revert`;UI 关威科夫即可无图面影响。
|
||||
|
||||
## Risk Review
|
||||
|
||||
- `docs/RISK_REVIEW/ECR-004.md` — N/A(展示/启发式,非 Live 策略)
|
||||
|
||||
## Linked
|
||||
|
||||
- IDEA: `docs/IDEA/IDEA-005-wyckoff-harden.md`
|
||||
- 上游: `docs/CODE_REVIEW/ECR-003.md` Findings 1–5
|
||||
- PRODUCT_SPEC / ENGINEERING_SPEC: 同目录 ECR-004-*
|
||||
- TRACEABILITY: Yes
|
||||
- CODE_REVIEW: `docs/CODE_REVIEW/ECR-004.md` — Approve
|
||||
@@ -1,105 +0,0 @@
|
||||
# Engineering Spec: ECR-001 引擎 + Web 重构
|
||||
|
||||
## Related
|
||||
|
||||
| Doc | Link |
|
||||
|-----|------|
|
||||
| ECR | `docs/ECR/ECR-001-chan-web-restructure.md` |
|
||||
| PRODUCT_SPEC | `docs/PRODUCT_SPEC/ECR-001-restructure.md` |
|
||||
| ADR | `docs/ADR/ADR-001-package-layout.md` |
|
||||
|
||||
## Module Design
|
||||
|
||||
### `chanlun/core/*`
|
||||
|
||||
| 项 | 值 |
|
||||
|----|-----|
|
||||
| Responsibility | K 线单元、合并 K、笔/段/中枢/买卖点数据结构与枚举 |
|
||||
| Can | 表达缠论基础对象 |
|
||||
| Cannot | 拉行情、写 Flask 路由 |
|
||||
| Layer | domain |
|
||||
|
||||
### `chanlun/pipeline/*`
|
||||
|
||||
| 项 | 值 |
|
||||
|----|-----|
|
||||
| Responsibility | `ChanLun` 编排、`TF_DF` 门面、builders |
|
||||
| Can | 从 DataFrame 构建结构 |
|
||||
| Cannot | 改公开方法语义 |
|
||||
| Layer | application |
|
||||
|
||||
### `chanlun/indicators/*` / `chanlun/analysis/*`
|
||||
|
||||
| 项 | 值 |
|
||||
|----|-----|
|
||||
| Responsibility | MACD 状态、Zone/Classifier/Trend 等分析 |
|
||||
| Layer | domain / application |
|
||||
|
||||
### Root shims (`ChanLun.py`, `ChanEnum.py`, …)
|
||||
|
||||
| 项 | 值 |
|
||||
|----|-----|
|
||||
| Responsibility | 转发到 `chanlun.*`,兼容 strategies |
|
||||
| Cannot | 含业务逻辑 |
|
||||
|
||||
### `web/config.py` + `web/services/*` + `web/api/*`
|
||||
|
||||
| 项 | 值 |
|
||||
|----|-----|
|
||||
| Responsibility | 配置、行情、分析、序列化、HTTP |
|
||||
| Cannot | 修改缠论算法 |
|
||||
|
||||
### `web/static/js/app/*`
|
||||
|
||||
| 项 | 值 |
|
||||
|----|-----|
|
||||
| Responsibility | 图表、overlay、UI、API 客户端 |
|
||||
| Cannot | 本轮引入 React 构建 |
|
||||
|
||||
## Interfaces
|
||||
|
||||
```python
|
||||
class TF_DF:
|
||||
# 公开方法签名保持与重构前一致
|
||||
def get_kl_data(self, dataframe): ...
|
||||
def get_bi_list(self, dataframe): ...
|
||||
# ... 门面委托 builders
|
||||
|
||||
class ChanLun:
|
||||
def init_dataframes(...): ...
|
||||
```
|
||||
|
||||
`/api/analyze`:查询参数与 JSON 顶层字段兼容。
|
||||
|
||||
## Algorithm Sketch
|
||||
|
||||
1. 物理迁移模块到 `chanlun/`,修正 import
|
||||
2. 根 shim 再导出
|
||||
3. `TF_DF` 方法体迁移到 builders,门面调用
|
||||
4. Web 按职责拆文件,路由注册不变
|
||||
5. HTML 抽 JS;未接线 TS 入 `_unused`
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Case | Behavior |
|
||||
|------|----------|
|
||||
| 行情失败 | 保持现有 JSON error |
|
||||
| 分析异常 | 保持现有日志与错误返回 |
|
||||
|
||||
## Config / Constants
|
||||
|
||||
| Name | Source |
|
||||
|------|--------|
|
||||
| DATA_SERVICE_URL | env / config |
|
||||
| HTTP(S)_PROXY | env / config(替代硬编码 7897) |
|
||||
| MACD periods | config |
|
||||
|
||||
## Test Plan Pointer
|
||||
|
||||
- `tests/test_golden_pipeline.py` + `tests/fixtures/golden_*`
|
||||
- `web/tests/` analyze 契约冒烟
|
||||
- `python -c "from ChanLun import ChanLun"`
|
||||
|
||||
## Migration / API Impact
|
||||
|
||||
无破坏性 API 变更;仅内部路径变化。
|
||||
@@ -1,23 +0,0 @@
|
||||
# ENGINEERING_SPEC — ECR-002
|
||||
|
||||
**Status:** Implemented
|
||||
**Date:** 2026-08-06
|
||||
|
||||
## Design
|
||||
|
||||
1. **包目录** `web/services/runtime/`(不用平铺 `runtime_*.py`)
|
||||
2. **边界**
|
||||
- `state`:可变全局与客户端
|
||||
- `timeframes`:周期工具
|
||||
- `market_data`:行情
|
||||
- `indicators`:技术指标列
|
||||
- `analyze`:缠论编排 + 趋势分类
|
||||
- `serialize`:JSON 整形
|
||||
- `__init__`:门面 + 历史 `import *` 兼容再导出
|
||||
3. **测试**:facade / analyze_chan 键 / serialize / HTTP mock 契约 / TF_DF init / golden
|
||||
4. **chart_tv 拆分**:本轮不做(仍可选后续 ECR)
|
||||
|
||||
## Open questions(已决)
|
||||
|
||||
- [x] 采用包目录 `services/runtime/`
|
||||
- [x] chart_tv 拆分不纳入本 PR
|
||||
@@ -1,46 +0,0 @@
|
||||
# ENGINEERING_SPEC — ECR-003
|
||||
|
||||
**Status:** Approved
|
||||
**Date:** 2026-08-06
|
||||
|
||||
## Package
|
||||
|
||||
`chanlun/analysis/wyckoff/`:
|
||||
|
||||
- `engine.py` — `analyze_wyckoff(df) -> dict`
|
||||
- `range.py` — 交易区间检测(ATR 容差震荡箱)
|
||||
- `phases.py` — A–E 状态机
|
||||
- `events.py` — Spring/SOS/LPS/UTAD(及 distribution 对称)
|
||||
- `volume_profile.py` — 区间内分桶 VP
|
||||
- `__init__.py` — 导出 `analyze_wyckoff`
|
||||
|
||||
## API
|
||||
|
||||
`GET /api/analyze?include_wyckoff=1` → `result["wyckoff"]`:
|
||||
|
||||
```json
|
||||
{
|
||||
"trading_range": {"start_time","end_time","high","low","mid","active"},
|
||||
"bias": "accumulation|distribution|unknown",
|
||||
"phases": [{"phase","label","start_time","end_time"}],
|
||||
"events": [{"type","time","price","note","volume_ratio","volume_ok"}],
|
||||
"volume_profile": {"bins":[{"price","volume"}],"poc","vah","val","bin_count"},
|
||||
"volume_confirm": {"avg_volume","event_checks":{}}
|
||||
}
|
||||
```
|
||||
|
||||
默认 `include_wyckoff` 假:可不返回或返回 `null`(实现选:不返回键以减负)。
|
||||
|
||||
## Detection heuristics
|
||||
|
||||
1. ATR(14) 容差;扫描最近窗口找高低点接近的连续段作为 TR。
|
||||
2. 阶段:价格在 TR 内相对位置 + 假破/真破时间序。
|
||||
3. Spring:下破 TR.low 后收回且收盘回到区间内;量能相对均量判断。
|
||||
4. SOS:收盘站上 TR.high 且放量。
|
||||
5. LPS:SOS 后回踩不破 mid/high 带且缩量。
|
||||
6. UTAD:上破后跌回区间内(派发)。
|
||||
7. VP:typical=(H+L+C)/3,volume 加权分桶,VA≈70% 围绕 POC。
|
||||
|
||||
## Frontend
|
||||
|
||||
主站 checkbox + `chart_view` 传参;`chart_tv.js` 绘制。
|
||||
@@ -1,43 +0,0 @@
|
||||
# ENGINEERING_SPEC — ECR-004
|
||||
|
||||
**Status:** Approved(实现锁定:评分选段;VP=A+C;无币种参数)
|
||||
**Date:** 2026-08-06
|
||||
|
||||
## Range scoring
|
||||
|
||||
替换「仅取最长合格窗口」:
|
||||
|
||||
1. 仍在 `lookback` + `tail_reserve` 框架内扫描候选段(步长 -4)。
|
||||
2. 硬门槛不变:near_hi/lo≥2、inside≥0.75、宽度上限等。
|
||||
3. 分数:`touch_density*50 + inside*30 - (width/ATR)*3 + min(length/40, 2)`,取最高。
|
||||
4. 单测:`low∈[38,42]`、`high∈[58,62]`,起点不早于箱体(容差 8 根);`abs_start_idx >= 12`。
|
||||
|
||||
## Phases
|
||||
|
||||
- 非重叠链式切分;每段至少 `min_bars=3`。
|
||||
- 尾部空间不足则延长上一段并停止新增(避免 D/E 完全重合双画)。
|
||||
|
||||
## API gate
|
||||
|
||||
```text
|
||||
if include_wyckoff and not elements_only:
|
||||
result["wyckoff"] = analyze_wyckoff(..., vp_bins∈[10,24])
|
||||
```
|
||||
|
||||
默认 `wyckoff_vp_bins=24`,上限 24。
|
||||
|
||||
## Frontend VP(A+C)
|
||||
|
||||
- 填充线 6→3
|
||||
- 有量 bin 按 volume Top-8 绘制 + POC/VAH/VAL
|
||||
- 目标:区间填充+边框+VP ≈ ≤15 series 量级
|
||||
|
||||
## Tests
|
||||
|
||||
- `tests/test_wyckoff.py` 收紧
|
||||
- `elements_only=true&include_wyckoff=1` 无 `wyckoff`
|
||||
- 不改 golden 缠论 JSON
|
||||
|
||||
## Non-goals
|
||||
|
||||
- 按币种独立参数(全局 ATR 相对;以 BTC 场景验证)
|
||||
@@ -1,38 +0,0 @@
|
||||
# Handoff
|
||||
|
||||
**From:** ARCHITECT
|
||||
**To:** ENGINEER
|
||||
**ECR:** ECR-001
|
||||
**State:** design → coding
|
||||
**Date:** 2026-08-05
|
||||
|
||||
## Artifacts
|
||||
|
||||
- [x] ECR (Approved)
|
||||
- [x] PRODUCT_SPEC
|
||||
- [x] ENGINEERING_SPEC
|
||||
- [x] RISK_REVIEW (N/A)
|
||||
- [x] ADR-001
|
||||
- [x] TRACEABILITY
|
||||
- [ ] TEST_REPORT / CODE_REVIEW / EXP (engineer / reviewer)
|
||||
|
||||
## Restrictions — Do not modify
|
||||
|
||||
- `config/`、`strategies/` 内容
|
||||
- 缠论算法语义、`/api/analyze` 破坏性变更
|
||||
- 计划文件本身
|
||||
|
||||
## Goal for receiver
|
||||
|
||||
按 ENGINEERING_SPEC 完成包化、TF_DF 拆分、Web 分层、前端模块化、golden 测试与文档收尾。
|
||||
|
||||
## Done for this hop
|
||||
|
||||
- [x] ESS docs 落盘
|
||||
- [x] ECR Approved(计划实施授权)
|
||||
|
||||
## References
|
||||
|
||||
- `docs/ECR/ECR-001-chan-web-restructure.md`
|
||||
- `docs/ENGINEERING_SPEC/ECR-001-restructure.md`
|
||||
- Plan: ESS Chan Refactor(1B+2B)
|
||||
@@ -1,29 +0,0 @@
|
||||
# Handoff
|
||||
|
||||
**From:** ENGINEER
|
||||
**To:** REVIEWER
|
||||
**ECR:** ECR-001
|
||||
**State:** coding → review
|
||||
**Date:** 2026-08-05
|
||||
|
||||
## Artifacts
|
||||
|
||||
- [x] ECR (Approved / Done pending review)
|
||||
- [x] PRODUCT_SPEC / ENGINEERING_SPEC / ADR / RISK N/A
|
||||
- [x] IMPLEMENTATION_REPORT
|
||||
- [x] TEST_REPORT
|
||||
- [x] CODE_REVIEW → Approve(`docs/CODE_REVIEW/ECR-001.md`)
|
||||
|
||||
## Goal for receiver
|
||||
|
||||
对照 ECR-001 Acceptance 做代码审阅;确认 strategies/config 无 diff;golden 与路由契约通过。
|
||||
|
||||
## Reviewer outcome
|
||||
|
||||
**Approve**(strategies 仅 import 迁移,记为范围修订)。Next → release_manager。
|
||||
|
||||
## References
|
||||
|
||||
- `docs/IMPLEMENTATION_REPORT/ECR-001.md`
|
||||
- `docs/TEST_REPORT/ECR-001.md`
|
||||
- `docs/CHANGELOG/CHANGELOG.md`
|
||||
@@ -1,30 +0,0 @@
|
||||
# HANDOFF — ECR-002 engineer → reviewer
|
||||
|
||||
**From:** ENGINEER
|
||||
**To:** REVIEWER
|
||||
**Date:** 2026-08-06
|
||||
**ECR:** ECR-002
|
||||
|
||||
## Ask
|
||||
|
||||
对照 ECR-002 Acceptance 做代码审阅;确认 strategies/config 无 diff;golden + 新契约测试通过。
|
||||
|
||||
## Artifacts
|
||||
|
||||
- `docs/ECR/ECR-002-runtime-split.md`
|
||||
- `docs/IMPLEMENTATION_REPORT/ECR-002.md`
|
||||
- `docs/TEST_REPORT/ECR-002.md`
|
||||
- `docs/ENGINEERING_SPEC/ECR-002-runtime-split.md`
|
||||
|
||||
## Diff focus
|
||||
|
||||
- `web/services/runtime/`(新包)
|
||||
- 删除原 `web/services/runtime.py`
|
||||
- `web/tests/test_*.py`、`tests/test_tf_df_init.py`
|
||||
- ESS docs 更新
|
||||
|
||||
## Out of scope this round
|
||||
|
||||
- `chart_tv.js` 拆分
|
||||
- 主站 WebSocket
|
||||
- strategies/config
|
||||
@@ -1,27 +0,0 @@
|
||||
# HANDOFF — ECR-003 engineer → reviewer
|
||||
|
||||
**Date:** 2026-08-06
|
||||
**From:** engineer
|
||||
**To:** reviewer
|
||||
|
||||
## Summary
|
||||
|
||||
主站威科夫 L2:独立分析包 + 按需 API + Lightweight 叠层。
|
||||
|
||||
## Artifacts
|
||||
|
||||
- IMPL: `docs/IMPLEMENTATION_REPORT/ECR-003.md`
|
||||
- TEST: `docs/TEST_REPORT/ECR-003.md`
|
||||
- SPEC: PRODUCT / ENG `docs/*/ECR-003-wyckoff-main.md`
|
||||
- RISK: N/A(展示分析)
|
||||
|
||||
## How to verify
|
||||
|
||||
```bash
|
||||
PYTHONPATH=.:web python -m pytest \
|
||||
tests/test_wyckoff.py \
|
||||
tests/test_golden_pipeline.py \
|
||||
web/tests/test_analyze_contract.py -q
|
||||
```
|
||||
|
||||
主站勾选「威科夫」→ 区间/阶段/事件/VP 可见。
|
||||
@@ -1,5 +0,0 @@
|
||||
# HANDOFF — ECR-004 engineer → reviewer
|
||||
|
||||
**Date:** 2026-08-06
|
||||
|
||||
已实现并自测 14 passed。请对照 `docs/CODE_REVIEW/ECR-004.md`。
|
||||
@@ -1,3 +0,0 @@
|
||||
# IDEA: 引擎与 Web 结构重整
|
||||
|
||||
根目录与 `web/app.py` / `index.html` 过于臃肿,需在行为冻结前提下包化与分层。见 ECR-001。
|
||||
@@ -1,35 +0,0 @@
|
||||
# Idea: 主站自动刷新内存泄漏 + chan_tv 体验修补
|
||||
|
||||
## Problem
|
||||
|
||||
主站(Lightweight Charts)勾选自动刷新后,浏览器内存持续上涨;首屏偶发重复打 `/api/analyze`。全版 TradingView(`/chan_tv`)指标/布局/未完成中枢体验不完整。
|
||||
|
||||
## Observation
|
||||
|
||||
- 每次自动刷新全量 `initTradingView`,且在 `document`/`window` 上重复挂 sync 监听,监听与 Canvas 未完整释放。
|
||||
- `ui.js` 加密货币首屏对 `updateChart()` 调度了两次。
|
||||
- `get_klc_list` 与 `TF_DF` / `analyze_chan` 可能重复跑 ChanMACD。
|
||||
- `chan_tv` 需 WS 与 REST 可分离、指标本地恢复、未完成中枢绘制修正。
|
||||
|
||||
## Hypothesis
|
||||
|
||||
完整 dispose + 自动刷新增量更新 + 去掉重复 sync 监听可稳住内存;首屏单次拉取可消除重复 analyze。chan_tv 问题为前端/datafeed 修补,不改缠论算法语义。
|
||||
|
||||
## Expected Impact
|
||||
|
||||
自动刷新可长期开启;首屏请求减半;chan_tv 更接近可用交易终端体验。
|
||||
|
||||
## Change Level Guess
|
||||
|
||||
**L1**(Bug Fix / 体验修补;不改笔段中枢算法语义,不改 strategies/config)
|
||||
|
||||
## Implementation
|
||||
|
||||
- Commit: `9f1e736`
|
||||
- Date: 2026-08-06
|
||||
|
||||
## Next
|
||||
|
||||
- [x] 仅 Bugfix(L1)— 代码已合入 `9f1e736`
|
||||
- [x] CHANGELOG / STATE / TRACEABILITY / TEST_REPORT 补档
|
||||
- [ ] 可选:自动化回归(内存/监听数量断言)— 暂人工验证
|
||||
@@ -1,27 +0,0 @@
|
||||
# Idea: 继续拆分 Web runtime 与加深契约测试
|
||||
|
||||
## Problem
|
||||
|
||||
ECR-001 Review 非阻断债务:`web/services/runtime.py` 仍过大;`/api/analyze` 契约测试偏浅;`chart_tv.js` 单体巨大。
|
||||
|
||||
## Observation
|
||||
|
||||
CODE_REVIEW ECR-001 Findings 1–3、5 明确记入 backlog,要求新 ECR 再动。
|
||||
|
||||
## Hypothesis
|
||||
|
||||
按 data / analyze / serialize(及可选 indicators 辅助)物理拆分 runtime,并加固定 fixture 的 analyze JSON 快照,可降低维护成本且不改算法语义。
|
||||
|
||||
## Expected Impact
|
||||
|
||||
可测性与可审阅性提升;为后续 Web 功能迭代减负。
|
||||
|
||||
## Change Level Guess
|
||||
|
||||
**L3**(结构重构;行为冻结)— 若触及识别结果则升 L2 + RISK/EXP。
|
||||
|
||||
## Next
|
||||
|
||||
- [x] ECR-002 Draft
|
||||
- [ ] Human Approve 后再实现
|
||||
- [ ] ENGINEERING_SPEC / ADR(若布局再变)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user