Compare commits

...

64 Commits

Author SHA1 Message Date
ddrwode
2f28401e7f 日志展示优化 2026-02-06 16:45:26 +08:00
ddrwode
e4db999ad9 日志展示优化 2026-02-06 16:27:40 +08:00
ddrwode
3b4b5d3a58 日志展示优化 2026-02-06 16:22:10 +08:00
ddrwode
eae69f7c8a 优化日志展示 2026-02-06 16:07:02 +08:00
ddrwode
a54e7d1823 优化单根 k 线可以多次开仓 2026-02-06 15:54:35 +08:00
ddrwode
aaa3a655bb 优化回调平仓规则 2026-02-06 15:48:44 +08:00
ddrwode
b979f8ff42 优化阴线回调止盈 2026-02-06 15:40:47 +08:00
ddrwode
51458e2649 haha 2026-02-06 14:43:20 +08:00
ddrwode
c58f020e9e 优化前改动 2026-02-06 14:32:24 +08:00
ddrwode
e22048fe0d 优化前改动 2026-02-06 14:09:38 +08:00
ddrwode
649858761e 优化前改动 2026-02-06 14:07:19 +08:00
ddrwode
275b1319f8 优化前改动 2026-02-06 13:42:39 +08:00
ddrwode
cfcf8f3136 优化前改动 2026-02-06 11:37:51 +08:00
ddrwode
afb26ced5d 优化前改动 2026-02-06 11:32:40 +08:00
ddrwode
2f9d589b33 优化前改动 2026-02-06 11:12:43 +08:00
ddrwode
0a7f206ad2 优化前改动 2026-02-06 10:53:59 +08:00
ddrwode
c929b94031 优化前改动 2026-02-06 10:04:36 +08:00
27942
cda8612eb7 优化完美代码,优化计算盈亏 2026-02-06 02:35:31 +08:00
Administrator
a52d9270d9 haha 2026-02-06 02:17:50 +08:00
27942
bb6341763a 优化完美代码,优化计算盈亏 2026-02-06 00:21:11 +08:00
27942
c19ae00e84 优化完美代码,加入止盈条件 2026-02-06 00:13:21 +08:00
27942
82c71d2d90 优化完美代码的跳空高开和跳空低开情况 2026-02-05 20:13:37 +08:00
ddrwode
a9938ba354 优化了,完美代码,加入了如果我没有持仓,上一根的开盘价是 2000,收盘是 2300,如果我没有持仓,当前这根实时价格大于 2375 的时候,就需要开多了 2026-02-05 18:30:04 +08:00
ddrwode
938cb3eb96 haha 2026-02-05 18:18:17 +08:00
ddrwode
0b7ce2758b haha 2026-02-05 18:14:50 +08:00
ddrwode
ef6dbabedf 优化前改动 2026-02-05 18:08:43 +08:00
ddrwode
9f9ec214f8 优化前改动 2026-02-05 17:45:59 +08:00
ddrwode
3ba87c1648 优化逻辑 2026-02-05 16:10:53 +08:00
ddrwode
79e0c88bd3 优化前改动 2026-02-05 15:33:22 +08:00
ddrwode
df296fb66f 优化前改动 2026-02-05 14:53:12 +08:00
ddrwode
46e10dd62b 优化前改动 2026-02-05 14:41:49 +08:00
ddrwode
c81dbed42c 加入 weex 2026-02-05 14:05:18 +08:00
Administrator
57e1466d59 haha 2026-02-05 13:58:15 +08:00
ddrwode
b2e481bfa6 加入 weex 2026-02-05 11:27:52 +08:00
27942
6928521173 加入精准回测数据 2026-02-04 23:23:21 +08:00
27942
a04bc121c9 加入精准回测数据 2026-02-04 22:22:40 +08:00
ddrwode
f0d0614873 加入 weex 2026-02-04 14:33:49 +08:00
ddrwode
d4e55b4bff 加入 weex 2026-02-04 14:17:05 +08:00
Administrator
995ef6122b haha 2026-02-04 13:29:29 +08:00
27942
fdc43477d0 加入精准回测数据 2026-02-04 01:50:34 +08:00
Administrator
f0ad547aeb haha 2026-02-04 01:46:28 +08:00
27942
7eeef8fb20 加入精准回测数据 2026-02-04 01:02:07 +08:00
27942
a0ea166d2b 优化反手 2026-02-04 01:01:29 +08:00
Administrator
fd151f7a80 haha 2026-02-04 00:58:52 +08:00
27942
aef0e89631 优化反手 2026-02-04 00:35:42 +08:00
27942
9785c46fec 优化反手 2026-02-04 00:29:56 +08:00
27942
d1e0361dec 优化 2026-02-04 00:02:14 +08:00
27942
187e97b36b haha 2026-02-03 23:43:07 +08:00
27942
757b7033fe 优化bitmart交易 2026-02-03 23:27:14 +08:00
Administrator
fd63961e3c haha 2026-02-03 18:26:58 +08:00
ddrwode
dbfd56d002 加入 weex 2026-02-03 18:05:01 +08:00
Administrator
d07d3b6a1d haha 2026-02-03 17:57:13 +08:00
ddrwode
d7f64050b2 加入 weex 2026-02-03 17:52:21 +08:00
ddrwode
7c9ede446f 加入 weex 2026-02-03 17:51:44 +08:00
ddrwode
ee9e7c29a8 加入 weex 2026-02-03 17:49:34 +08:00
ddrwode
a7c6b4e1fc 加入 weex 2026-02-03 17:28:53 +08:00
ddrwode
fdcec74585 加入 weex 2026-02-03 17:07:40 +08:00
ddrwode
784a2a3af3 代码结构优化 2026-02-03 11:52:59 +08:00
ddrwode
6af2458241 代码结构优化 2026-02-03 11:46:15 +08:00
ddrwode
40683f4bab 代码结构优化 2026-02-03 10:28:54 +08:00
ddrwode
d81b9eced0 代码结构优化 2026-02-03 10:19:56 +08:00
ddrwode
488e8de86a 代码结构优化 2026-02-02 17:18:31 +08:00
ddrwode
71c025b627 代码结构优化 2026-02-02 17:03:49 +08:00
ddrwode
a938495d40 代码结构优化 2026-02-02 16:31:48 +08:00
83 changed files with 5174 additions and 115623 deletions

1315
1.json

File diff suppressed because it is too large Load Diff

30
1111
View File

@@ -14,10 +14,6 @@ api交易
yto0mg6r05kkyolwefqw
db2e87093c120766bca60d2282y72760688
api交易
yto0mg6r05kkyolwefqw
db2e87093c120766bca60d2282y72760688
yx20250715@gmail.com
Abc12345678
@@ -25,23 +21,27 @@ Abc12345678
248.23
2611
bitmart\框架.py 读取这个代码文件夹
基础开仓逻辑
基于前一根有效 K 线(实体 ≥ 0.1
做多触发价 = 当前 k 线开盘价 + 实体 / 5收盘价向上 1/5 实体)
做空触发价 = 当前 k 线开盘价 - 实体 / 5收盘价向下 1/5 实体)
若已有持仓,在 3 分钟 K 线的第一分钟可单独检测反手:
持空反手做多:价格涨到 开仓价 + 前一根实体 / 5
持多反手做空:价格跌到 开仓价 - 前一根实体 / 5
做多触发价 = 当前 k 线开盘价 + 上一根实体 / 4
做空触发价 = 当前 k 线开盘价 - 上一根实体 / 4
反手信号:
持空反手做多:价格涨到 当前k线开仓价 + 前一根实体 / 3
持多反手做空:价格跌到 当前k线开仓价 - 前一根实体 / 3
持多反手做空:价格跌到 k 线的上阴线涨幅大于 0.01%当前这个根跌倒了上一根的k线的实体边平仓做空
持空反手做多:价格涨到 k 线的下阴线跌幅大于 0.01%当前这个根涨到了上一根的k线的实体边平仓做多
上一根阴线 + 当前阳线(做多形态)→ 不按上三分之一做空。
上一根阳线 + 当前阴线(做空形态)→ 不按下三分之一做多。
反手做空,当前 k 线开盘价 - 上一根实体 / 3收盘价向下 1/3 实体)
反手做多,当前 k 线开盘价 + 上一根实体 / 3收盘价向上 1/3 实体)
2574

View File

@@ -1,79 +0,0 @@
# 自适应三分位趋势策略
优化版实盘策略:趋势过滤 + 动态阈值 + 信号确认 + 完整风险管理。
## 目录结构
- `config.py` - 策略参数(趋势模式、止损止盈、确认条件等)
- `indicators.py` - EMA、ATR 指标
- `data_fetcher.py` - **Bitmart 方式**拉取 5/15/60 分钟 K 线API 或 CSV
- `strategy_core.py` - 趋势判断、有效 K 线、动态触发价、信号确认
- `backtest.py` - 回测引擎(硬止损、止盈、移动止损、时间止损)
- `trade.py` - 实盘交易入口(拉数据 + 信号,开平仓需对接现有 Bitmart 下单逻辑)
- `data/` - 回测用 K 线 CSV可选无则 API 拉取)
## 回测(先出数据再回测)
在**项目根目录** `lm_code` 下执行:
```bash
# 使用 API 拉取数据并回测(会请求 Bitmart 接口)
python adaptive_third_strategy/backtest.py --start 2025-01-01 --end 2025-01-30 --capital 10000
# 仅用本地已有 CSV 回测(需先抓过数据)
python adaptive_third_strategy/backtest.py --start 2025-01-01 --end 2025-01-30 --no-api
```
数据会保存到 `adaptive_third_strategy/data/kline_5m.csv``kline_15m.csv``kline_60m.csv`
回测结果输出到控制台,交易明细保存到 `adaptive_third_strategy/backtest_trades.csv`
## 仅抓取数据Bitmart 方式)
`bitmart/回测.py``bitmart/抓取多周期K线.py` 相同的 API 调用方式:
```bash
cd adaptive_third_strategy && python -c "
from data_fetcher import fetch_multi_timeframe, save_klines_csv
import time, os
end_ts = int(time.time())
start_ts = end_ts - 30*24*3600
data = fetch_multi_timeframe(start_ts, end_ts, [5, 15, 60])
os.makedirs('data', exist_ok=True)
for step, klines in data.items():
save_klines_csv(klines, f'data/kline_{step}m.csv')
"
```
需在项目根目录 `lm_code` 下执行时,先 `import sys; sys.path.insert(0, '..')` 或使用:
```bash
python -c "
import sys, os
sys.path.insert(0, os.getcwd())
from adaptive_third_strategy.data_fetcher import fetch_multi_timeframe, save_klines_csv
import time
end_ts = int(time.time())
start_ts = end_ts - 30*24*3600
data = fetch_multi_timeframe(start_ts, end_ts, [5, 15, 60])
os.makedirs('adaptive_third_strategy/data', exist_ok=True)
for step, klines in data.items():
save_klines_csv(klines, f'adaptive_third_strategy/data/kline_{step}m.csv')
"
```
## 实盘
```bash
python adaptive_third_strategy/trade.py
```
当前 `trade.py` 只做:拉 5/15/60 数据、算信号、打日志/钉钉。实际开平仓需在 `run_loop` 里接入你现有的 Bitmart 下单方式(如 `交易/bitmart-三分之一策略交易.py` 的浏览器点击或 API 下单)。
## 策略要点
- **数据与周期**:主周期 5 分钟,趋势用 15 分钟 / 1 小时 EMA。
- **有效 K 线**:实体 ≥ max(ATR×0.1, 价格×0.05%)。
- **趋势过滤**:长期 1h EMA50/200中期 15m EMA20/50短期 5m 收盘 vs EMA9保守模式要求中期+短期一致。
- **动态触发**:波动率系数 clamp(实体/ATR, 0.3, 3.0),顺势方向更易触发。
- **信号确认**:收盘价、成交量、动量等至少满足 2 项。
- **风控**:硬止损 ATR×2、时间止损 3 根 K、移动止损盈利 1×ATR 后 0.5×ATR 跟踪)、止盈目标 1.5/3/5×ATR。

View File

@@ -1,2 +0,0 @@
# -*- coding: utf-8 -*-
"""自适应三分位趋势策略"""

View File

@@ -1,464 +0,0 @@
# -*- coding: utf-8 -*-
"""
自适应三分位趋势策略 - 回测引擎
使用 Bitmart 方式获取数据API 或 CSV含硬止损、分批止盈、移动止损、时间止损
"""
import os
import sys
import csv
import datetime
from typing import List, Dict, Optional, Tuple
# 使用 UTC 时区,避免 utcfromtimestamp 弃用警告
def _utc_dt(ts):
if hasattr(datetime, "timezone") and hasattr(datetime.timezone, "utc"):
return datetime.datetime.fromtimestamp(ts, tz=datetime.timezone.utc)
return datetime.datetime.utcfromtimestamp(ts)
try:
from loguru import logger
except ImportError:
import logging
logger = logging.getLogger(__name__)
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if ROOT_DIR not in sys.path:
sys.path.insert(0, ROOT_DIR)
from adaptive_third_strategy.config import (
STEP_5M,
STEP_15M,
STEP_60M,
ATR_PERIOD,
EMA_SHORT,
EMA_MID_FAST,
EMA_MID_SLOW,
EMA_LONG_FAST,
EMA_LONG_SLOW,
STOP_LOSS_ATR_MULT,
TIME_STOP_BARS,
TRAIL_START_ATR,
TRAIL_ATR_MULT,
TP1_ATR,
TP2_ATR,
TP3_ATR,
TP1_RATIO,
TP2_RATIO,
TP3_RATIO,
MIN_BARS_SINCE_ENTRY,
SAME_KLINE_NO_REVERSE,
REVERSE_BREAK_MULT,
REVERSE_LOSS_ATR,
MAX_POSITION_PERCENT,
BASE_POSITION_PERCENT,
CONTRACT_SIZE,
FEE_RATE,
FEE_FIXED,
FEE_FIXED_BACKTEST,
MIN_BARS_BETWEEN_TRADES,
SLIPPAGE_POINTS,
)
from adaptive_third_strategy.indicators import get_ema_atr_from_klines, align_higher_tf_ema
from adaptive_third_strategy.strategy_core import (
check_trigger,
get_body_size,
build_volume_ma,
)
from adaptive_third_strategy.data_fetcher import (
fetch_multi_timeframe,
load_klines_csv,
save_klines_csv,
)
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
def ensure_data(
start_time: int,
end_time: int,
data_dir: str,
use_api: bool = True,
api_key: str = "",
secret_key: str = "",
) -> Tuple[List[Dict], List[Dict], List[Dict]]:
"""
确保有 5/15/60 分钟数据。若 data_dir 下已有 CSV 则加载,否则用 API 拉取并保存。
use_api=False 时仅从 CSV 加载(需事先抓取)。
"""
data_dir = data_dir or os.path.join(SCRIPT_DIR, "data")
os.makedirs(data_dir, exist_ok=True)
paths = {
5: os.path.join(data_dir, "kline_5m.csv"),
15: os.path.join(data_dir, "kline_15m.csv"),
60: os.path.join(data_dir, "kline_60m.csv"),
}
k5 = load_klines_csv(paths[5])
k15 = load_klines_csv(paths[15])
k60 = load_klines_csv(paths[60])
need_fetch = not k5 or not k15 or not k60
if need_fetch and use_api:
from adaptive_third_strategy.data_fetcher import DEFAULT_API_KEY, DEFAULT_SECRET_KEY, DEFAULT_MEMO
key = api_key or DEFAULT_API_KEY
sec = secret_key or DEFAULT_SECRET_KEY
data = fetch_multi_timeframe(start_time, end_time, [5, 15, 60], key, sec, DEFAULT_MEMO)
k5, k15, k60 = data[5], data[15], data[60]
for step, kl in [(5, k5), (15, k15), (60, k60)]:
save_klines_csv(kl, paths[step])
# 按时间范围过滤end_time 若为次日 0 点则用 < 以只含 end 日及之前)
k5 = [x for x in k5 if start_time <= x["id"] < end_time]
k15 = [x for x in k15 if start_time <= x["id"] < end_time]
k60 = [x for x in k60 if start_time <= x["id"] < end_time]
k5.sort(key=lambda x: x["id"])
k15.sort(key=lambda x: x["id"])
k60.sort(key=lambda x: x["id"])
return k5, k15, k60
def run_backtest(
klines_5m: List[Dict],
klines_15m: List[Dict],
klines_60m: List[Dict],
initial_capital: float = 10000.0,
use_stop_loss: bool = True,
use_take_profit: bool = True,
use_trailing_stop: bool = True,
use_time_stop: bool = True,
fixed_margin_usdt: Optional[float] = None,
leverage: Optional[float] = None,
deduct_fee: bool = True,
) -> Tuple[List[Dict], Dict, List[Dict]]:
"""
回测主循环。
- 若指定 fixed_margin_usdt 与 leverage则每笔开仓名义价值 = fixed_margin_usdt * leverage如 50U 一百倍 = 5000U
- deduct_fee=False 时不扣手续费,总盈利 = 所有 money_pnl 之和。
"""
if len(klines_5m) < ATR_PERIOD + 50:
logger.warning("5分钟K线数量不足")
return [], {}, klines_5m
ema_5m, atr_5m = get_ema_atr_from_klines(klines_5m, EMA_SHORT, ATR_PERIOD)
ema_15m_align = align_higher_tf_ema(klines_5m, klines_15m, EMA_MID_FAST, EMA_MID_SLOW)
ema_60m_align = align_higher_tf_ema(klines_5m, klines_60m, EMA_LONG_FAST, EMA_LONG_SLOW)
volume_ma = build_volume_ma(klines_5m)
trades: List[Dict] = []
position: Optional[Dict] = None
last_trade_bar_idx: Optional[int] = None
last_close_bar_idx: Optional[int] = None
equity_curve: List[float] = [initial_capital]
capital = initial_capital
# 每笔固定名义价值USDT50U 一百倍 = 5000
fixed_notional = (fixed_margin_usdt * leverage) if (fixed_margin_usdt is not None and leverage is not None) else None
use_fee = deduct_fee
fee_fixed = 0 if not use_fee else (FEE_FIXED_BACKTEST if FEE_FIXED_BACKTEST is not None else FEE_FIXED)
def _size_usdt(cap: float) -> float:
if fixed_notional is not None:
return fixed_notional
return min(cap * MAX_POSITION_PERCENT, cap * BASE_POSITION_PERCENT)
def _fee(sz: float) -> float:
return 0 if not use_fee else (fee_fixed + sz * FEE_RATE * 2)
for idx in range(ATR_PERIOD, len(klines_5m)):
just_reversed = False
curr = klines_5m[idx]
bar_id = curr["id"]
high, low, close = float(curr["high"]), float(curr["low"]), float(curr["close"])
atr_val = atr_5m[idx]
if atr_val is None or atr_val <= 0:
equity_curve.append(capital)
continue
# ---------- 持仓管理:止损 / 止盈 / 移动止损 / 时间止损 ----------
if position is not None:
pos_dir = position["direction"]
entry_price = position["entry_price"]
entry_idx = position["entry_bar_idx"]
entry_atr = position["entry_atr"]
stop_price = position.get("stop_price")
trail_activated = position.get("trail_activated", False)
exit_reason = None
exit_price = close
if pos_dir == "long":
# 硬止损
if use_stop_loss and stop_price is not None and low <= stop_price:
exit_price = min(stop_price, high)
exit_reason = "stop_loss"
# 止盈(简化:首次触及任一目标即全平)
elif use_take_profit:
tp1 = entry_price + entry_atr * TP1_ATR
tp2 = entry_price + entry_atr * TP2_ATR
tp3 = entry_price + entry_atr * TP3_ATR
if high >= tp3:
exit_price = tp3
exit_reason = "tp3"
elif high >= tp2:
exit_price = tp2
exit_reason = "tp2"
elif high >= tp1:
exit_price = tp1
exit_reason = "tp1"
# 移动止损
if use_trailing_stop and not exit_reason:
if close >= entry_price + entry_atr * TRAIL_START_ATR:
trail_activated = True
position["trail_activated"] = True
trail_stop = close - entry_atr * TRAIL_ATR_MULT
if low <= trail_stop:
exit_price = trail_stop
exit_reason = "trail_stop"
# 时间止损
if use_time_stop and not exit_reason and (idx - entry_idx) >= TIME_STOP_BARS:
if close <= entry_price:
exit_price = close
exit_reason = "time_stop"
else:
if use_stop_loss and stop_price is not None and high >= stop_price:
exit_price = max(stop_price, low)
exit_reason = "stop_loss"
elif use_take_profit:
tp1 = entry_price - entry_atr * TP1_ATR
tp2 = entry_price - entry_atr * TP2_ATR
tp3 = entry_price - entry_atr * TP3_ATR
if low <= tp3:
exit_price = tp3
exit_reason = "tp3"
elif low <= tp2:
exit_price = tp2
exit_reason = "tp2"
elif low <= tp1:
exit_price = tp1
exit_reason = "tp1"
if use_trailing_stop and not exit_reason:
if close <= entry_price - entry_atr * TRAIL_START_ATR:
trail_activated = True
position["trail_activated"] = True
trail_stop = close + entry_atr * TRAIL_ATR_MULT
if high >= trail_stop:
exit_price = trail_stop
exit_reason = "trail_stop"
if use_time_stop and not exit_reason and (idx - entry_idx) >= TIME_STOP_BARS:
if close >= entry_price:
exit_price = close
exit_reason = "time_stop"
if exit_reason:
# 平仓
if pos_dir == "long":
point_pnl = exit_price - entry_price
else:
point_pnl = entry_price - exit_price
size_usdt = position.get("size_usdt", _size_usdt(capital))
contract_val = CONTRACT_SIZE / entry_price
money_pnl = point_pnl / entry_price * size_usdt
fee = _fee(size_usdt)
net = money_pnl - fee
capital += net
trades.append({
"direction": "做多" if pos_dir == "long" else "做空",
"entry_time": _utc_dt(position["entry_time"]),
"exit_time": _utc_dt(bar_id),
"entry_price": entry_price,
"exit_price": exit_price,
"point_pnl": point_pnl,
"money_pnl": money_pnl,
"fee": fee,
"net_profit": net,
"exit_reason": exit_reason,
"hold_bars": idx - entry_idx,
})
position = None
last_close_bar_idx = idx
equity_curve.append(capital)
continue
# ---------- 信号检测 ----------
direction, trigger_price, valid_prev_idx, valid_prev = check_trigger(
klines_5m, idx, atr_5m, ema_5m, ema_15m_align, ema_60m_align, volume_ma, use_confirm=True
)
if direction is None:
equity_curve.append(capital)
continue
if SAME_KLINE_NO_REVERSE and last_trade_bar_idx == idx:
equity_curve.append(capital)
continue
if position is not None:
if direction == position["direction"]:
equity_curve.append(capital)
continue
# 反手条件
bars_since = idx - position["entry_bar_idx"]
if bars_since < MIN_BARS_SINCE_ENTRY:
equity_curve.append(capital)
continue
entry_atr_pos = position.get("entry_atr") or atr_val
pos_loss_atr = (position["entry_price"] - close) / entry_atr_pos if position["direction"] == "long" else (close - position["entry_price"]) / entry_atr_pos
if pos_loss_atr < REVERSE_LOSS_ATR:
# 可选:反向突破幅度 > 实体/2 才反手
equity_curve.append(capital)
continue
# 先平仓再开仓(下面统一开仓)
# 简化:这里直接平仓记一笔,再开新仓
exit_price = close
if position["direction"] == "long":
point_pnl = exit_price - position["entry_price"]
else:
point_pnl = position["entry_price"] - exit_price
size_usdt = position.get("size_usdt", _size_usdt(capital))
money_pnl = point_pnl / position["entry_price"] * size_usdt
fee = _fee(size_usdt)
net = money_pnl - fee
capital += net
trades.append({
"direction": "做多" if position["direction"] == "long" else "做空",
"entry_time": _utc_dt(position["entry_time"]),
"exit_time": _utc_dt(bar_id),
"entry_price": position["entry_price"],
"exit_price": exit_price,
"point_pnl": point_pnl,
"money_pnl": money_pnl,
"fee": fee,
"net_profit": net,
"exit_reason": "reverse",
"hold_bars": idx - position["entry_bar_idx"],
})
position = None
last_close_bar_idx = idx
just_reversed = True
# ---------- 开仓 ----------
# 反手后本 K 线允许开仓;否则需间隔 MIN_BARS_BETWEEN_TRADES 根
if not just_reversed and last_close_bar_idx is not None and (idx - last_close_bar_idx) < MIN_BARS_BETWEEN_TRADES:
equity_curve.append(capital)
continue
just_reversed = False
size_usdt = _size_usdt(capital)
if size_usdt <= 0:
equity_curve.append(capital)
continue
stop_price = None
if direction == "long":
stop_price = trigger_price - atr_val * STOP_LOSS_ATR_MULT
else:
stop_price = trigger_price + atr_val * STOP_LOSS_ATR_MULT
position = {
"direction": direction,
"entry_price": trigger_price,
"entry_time": bar_id,
"entry_bar_idx": idx,
"entry_atr": atr_val,
"stop_price": stop_price,
"size_usdt": size_usdt,
"closed_ratio": 0,
"trail_activated": False,
}
last_trade_bar_idx = idx
equity_curve.append(capital)
# 尾仓
if position is not None:
last_bar = klines_5m[-1]
exit_price = float(last_bar["close"])
pos_dir = position["direction"]
entry_price = position["entry_price"]
if pos_dir == "long":
point_pnl = exit_price - entry_price
else:
point_pnl = entry_price - exit_price
size_usdt = position.get("size_usdt", _size_usdt(capital))
money_pnl = point_pnl / entry_price * size_usdt
fee = _fee(size_usdt)
net = money_pnl - fee
capital += net
trades.append({
"direction": "做多" if pos_dir == "long" else "做空",
"entry_time": _utc_dt(position["entry_time"]),
"exit_time": _utc_dt(last_bar["id"]),
"entry_price": entry_price,
"exit_price": exit_price,
"point_pnl": point_pnl,
"money_pnl": money_pnl,
"fee": fee,
"net_profit": net,
"exit_reason": "tail",
"hold_bars": len(klines_5m) - 1 - position["entry_bar_idx"],
})
# 统计
total_net = sum(t["net_profit"] for t in trades)
total_gross = sum(t["money_pnl"] for t in trades)
total_fee = sum(t["fee"] for t in trades)
win_count = len([t for t in trades if t["net_profit"] > 0])
stats = {
"total_trades": len(trades),
"win_count": win_count,
"win_rate": (win_count / len(trades) * 100) if trades else 0,
"total_gross_profit": total_gross,
"total_fee": total_fee,
"total_net_profit": total_net,
"final_capital": capital,
"max_drawdown": 0,
"max_drawdown_pct": 0,
}
peak = initial_capital
for eq in equity_curve:
peak = max(peak, eq)
dd = peak - eq
if peak > 0:
stats["max_drawdown"] = max(stats["max_drawdown"], dd)
stats["max_drawdown_pct"] = max(stats["max_drawdown_pct"], dd / peak * 100)
return trades, stats, klines_5m
def main():
import argparse
parser = argparse.ArgumentParser(description="自适应三分位趋势策略回测")
parser.add_argument("--start", default="2025-01-01", help="开始日期 YYYY-MM-DD")
parser.add_argument("--end", default="2025-12-31", help="结束日期,默认 2025-12-31")
parser.add_argument("--data-dir", default=None, help="数据目录,默认 adaptive_third_strategy/data")
parser.add_argument("--no-api", action="store_true", help="不从 API 拉取,仅用本地 CSV")
parser.add_argument("--capital", type=float, default=10000, help="初始资金(按比例开仓时用)")
parser.add_argument("--fixed-margin", type=float, default=None, help="每笔固定保证金 USDT如 50")
parser.add_argument("--leverage", type=float, default=None, help="杠杆倍数,如 100")
parser.add_argument("--no-fee", action="store_true", help="不扣手续费,只算总盈利")
args = parser.parse_args()
start_dt = datetime.datetime.strptime(args.start, "%Y-%m-%d")
if args.end:
end_dt = datetime.datetime.strptime(args.end, "%Y-%m-%d")
# 包含 end 日全天:取次日 0 点前一刻,这样 id < end_ts 的 K 线都含在内
end_ts = int((end_dt + datetime.timedelta(days=1)).timestamp())
else:
end_ts = int(datetime.datetime.utcnow().timestamp())
start_ts = int(start_dt.timestamp())
data_dir = args.data_dir or os.path.join(SCRIPT_DIR, "data")
k5, k15, k60 = ensure_data(start_ts, end_ts, data_dir, use_api=not args.no_api)
if not k5:
logger.error("无 5 分钟数据,请先抓取或开启 --api")
return
logger.info(f"5m={len(k5)} 15m={len(k15)} 60m={len(k60)}")
trades, stats, _ = run_backtest(
k5, k15, k60,
initial_capital=args.capital,
fixed_margin_usdt=args.fixed_margin,
leverage=args.leverage,
deduct_fee=not args.no_fee,
)
logger.info(f"交易笔数: {stats['total_trades']} 胜率: {stats['win_rate']:.2f}% "
f"总盈利(未扣费): {stats['total_gross_profit']:.2f} USDT "
f"总手续费: {stats['total_fee']:.2f} 总净利润: {stats['total_net_profit']:.2f} "
f"最大回撤: {stats['max_drawdown']:.2f} ({stats['max_drawdown_pct']:.2f}%)")
out_csv = os.path.join(SCRIPT_DIR, "backtest_trades.csv")
if trades:
with open(out_csv, "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=["direction", "entry_time", "exit_time", "entry_price", "exit_price", "point_pnl", "money_pnl", "fee", "net_profit", "exit_reason", "hold_bars"])
w.writeheader()
for t in trades:
w.writerow({k: str(v) if isinstance(v, datetime.datetime) else v for k, v in t.items()})
logger.info(f"交易记录已保存: {out_csv}")
if __name__ == "__main__":
main()

File diff suppressed because it is too large Load Diff

View File

@@ -1,97 +0,0 @@
# -*- coding: utf-8 -*-
"""
自适应三分位趋势策略 - 配置参数
"""
# ========== 数据与周期 ==========
CONTRACT_SYMBOL = "ETHUSDT"
STEP_5M = 5
STEP_15M = 15
STEP_60M = 60
# 有效K线标准实体 >= max(ATR(20)*0.1, 最小波动阈值)
MIN_BODY_ATR_RATIO = 0.1
MIN_VOLATILITY_PERCENT = 0.0005 # 当前价格 × 0.05%
# ========== 趋势判断EMA周期 ==========
# 长期1小时 EMA(50) vs EMA(200)
EMA_LONG_FAST = 50
EMA_LONG_SLOW = 200
# 中期15分钟 EMA(20) vs EMA(50)
EMA_MID_FAST = 20
EMA_MID_SLOW = 50
# 短期5分钟 EMA(9)
EMA_SHORT = 9
# 交易模式aggressive / conservative / strict
TREND_MODE = "conservative"
# ========== 动态触发 ==========
ATR_PERIOD = 20
VOLATILITY_COEF_CLAMP = (0.3, 3.0) # 波动率系数范围
BASE_COEF = 0.33
# 趋势方向系数(顺势更易触发)
TREND_FAVOR_COEF = 0.8
TREND_AGAINST_COEF = 1.2
# ========== 信号确认(至少满足几项) ==========
CONFIRM_REQUIRED = 2
VOLUME_MA_PERIOD = 20
VOLUME_RATIO_THRESHOLD = 0.8 # 成交量 > 前20根均量 × 0.8
# ========== 风险管理 ==========
MAX_POSITION_PERCENT = 0.10 # 单笔最大 10%
BASE_POSITION_PERCENT = 0.02 # 基础仓位 2%
STOP_LOSS_ATR_MULT = 2.0 # 硬止损 = ATR × 2.0
TIME_STOP_BARS = 3 # 3根K线未盈利平仓
TRAIL_START_ATR = 1.0 # 盈利 1×ATR 后启动移动止损
TRAIL_ATR_MULT = 0.5 # 移动止损距离 0.5×ATR
# 止盈目标ATR倍数与分批比例
TP1_ATR = 1.5
TP2_ATR = 3.0
TP3_ATR = 5.0
TP1_RATIO = 0.30
TP2_RATIO = 0.30
TP3_RATIO = 0.40
# ========== 反手条件 ==========
REVERSE_BREAK_MULT = 0.5 # 突破幅度 > 实体/2
REVERSE_LOSS_ATR = 0.5 # 当前持仓亏损 > 0.5×ATR 可反手
MIN_BARS_SINCE_ENTRY = 2 # 距离上次开仓至少2根K线
SAME_KLINE_NO_REVERSE = True # 同一K线不反手
# ========== 市场状态调整 ==========
# 强趋势 / 震荡 / 高波动 时的系数
STRONG_TREND_COEF = 0.25
STRONG_TREND_STOP_ATR = 3.0
RANGE_COEF = 0.4
RANGE_STOP_ATR = 1.5
HIGH_VOL_POSITION_COEF = 0.5
HIGH_VOL_EXTRA_CONFIRM = 1
# ========== 禁止交易时段UTC+8 小时:分) ==========
FORBIDDEN_PERIODS = [
(0, 0, 0, 30), # 00:00-00:30
(8, 0, 8, 30), # 08:00-08:30
(20, 0, 20, 30), # 20:00-20:30
]
# 高波动暂停ATR > 平均ATR × 2 暂停
ATR_PAUSE_MULT = 2.0
# ========== 自适应绩效 ==========
CONSECUTIVE_LOSS_PAUSE = 3 # 连续亏损3次仓位减半
WIN_RATE_LOOKBACK = 20
WIN_RATE_PAUSE_THRESHOLD = 0.40 # 胜率<40% 暂停
MAX_DRAWDOWN_PERCENT = 0.10 # 最大回撤10% 观察期
MAX_TRADES_PER_DAY = 20
MAX_HOLD_BARS = 4 * 12 # 4小时 ≈ 4*12 根5分钟
# ========== 回测/实盘通用 ==========
CONTRACT_SIZE = 10000
SLIPPAGE_POINTS = 3
FEE_RATE = 0.0005
FEE_FIXED = 5
# 回测专用:固定手续费(合约多为按比例,可设为 0 观察策略本身)
FEE_FIXED_BACKTEST = 0
# 两笔开仓之间至少间隔 N 根 5 分钟 K 线,减少过度交易
MIN_BARS_BETWEEN_TRADES = 4

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,697 +0,0 @@
id,open,high,low,close,volume
1735660800,3412.6,3416.0,3390.39,3408.23,102369440.0
1735664400,3408.23,3410.38,3329.45,3362.6,239948902.0
1735668000,3362.62,3372.14,3349.24,3360.3,87820990.0
1735671600,3360.3,3367.9,3342.85,3354.68,42695570.0
1735675200,3354.68,3364.47,3336.84,3346.12,54111736.0
1735678800,3345.76,3354.28,3331.51,3351.72,48624216.0
1735682400,3351.66,3351.66,3327.8,3338.94,44710804.0
1735686000,3338.94,3345.03,3327.22,3336.37,37042226.0
1735689600,3336.47,3364.49,3334.99,3362.89,57465298.0
1735693200,3362.89,3365.08,3341.6,3345.83,34711202.0
1735696800,3345.83,3368.02,3345.35,3361.81,34405766.0
1735700400,3361.81,3363.0,3350.22,3354.34,21508812.0
1735704000,3354.34,3355.78,3338.4,3340.12,45813072.0
1735707600,3340.04,3350.57,3339.13,3344.2,29504628.0
1735711200,3344.2,3347.33,3335.57,3345.65,26979022.0
1735714800,3345.65,3347.77,3338.32,3346.0,19122736.0
1735718400,3345.94,3348.0,3330.48,3335.57,39528308.0
1735722000,3335.57,3340.16,3313.08,3333.4,129899100.0
1735725600,3333.52,3337.99,3325.01,3325.99,32584622.0
1735729200,3325.99,3347.73,3322.8,3340.07,45465420.0
1735732800,3340.07,3351.21,3337.29,3346.01,39172620.0
1735736400,3346.01,3352.78,3331.45,3343.1,51120458.0
1735740000,3342.83,3358.89,3327.15,3345.0,82299724.0
1735743600,3345.06,3354.24,3332.01,3352.07,51286002.0
1735747200,3352.07,3356.14,3331.27,3337.72,49132440.0
1735750800,3337.72,3344.37,3322.56,3343.02,49046866.0
1735754400,3343.01,3351.47,3332.38,3347.81,36271786.0
1735758000,3347.81,3363.82,3338.02,3356.2,55282332.0
1735761600,3356.2,3361.76,3351.0,3359.39,38099614.0
1735765200,3359.28,3370.87,3352.49,3367.59,51552628.0
1735768800,3367.59,3373.97,3357.81,3360.65,43553722.0
1735772400,3360.65,3365.99,3352.07,3359.35,33197468.0
1735776000,3359.35,3399.41,3354.01,3389.27,123638482.0
1735779600,3389.27,3404.76,3377.72,3383.02,72528314.0
1735783200,3383.1,3397.9,3376.89,3397.89,35142436.0
1735786800,3397.89,3401.77,3386.57,3388.01,28707566.0
1735790400,3388.01,3427.38,3387.4,3417.81,124752266.0
1735794000,3417.82,3419.18,3404.4,3412.37,64463210.0
1735797600,3412.63,3415.73,3401.82,3410.19,37061074.0
1735801200,3410.19,3421.77,3408.6,3419.68,42976506.0
1735804800,3419.68,3442.8,3414.59,3437.98,81383320.0
1735808400,3437.13,3470.72,3433.94,3467.93,117165150.0
1735812000,3467.93,3476.09,3457.49,3468.61,95625752.0
1735815600,3468.61,3474.99,3457.1,3470.47,55981282.0
1735819200,3470.46,3480.37,3465.1,3479.77,71134738.0
1735822800,3479.89,3483.94,3459.45,3465.33,135921684.0
1735826400,3465.33,3509.87,3439.82,3494.61,298463722.0
1735830000,3494.61,3495.56,3455.45,3462.76,137324232.0
1735833600,3462.76,3488.75,3447.84,3468.71,102691858.0
1735837200,3468.7,3478.07,3429.2,3449.77,130762240.0
1735840800,3449.66,3464.67,3439.64,3464.16,96730060.0
1735844400,3464.16,3473.57,3458.11,3462.31,52010818.0
1735848000,3462.31,3474.61,3450.9,3452.17,41220990.0
1735851600,3452.29,3455.39,3442.18,3453.73,48633000.0
1735855200,3453.73,3453.75,3419.06,3440.0,62033228.0
1735858800,3439.91,3456.41,3437.0,3454.81,33740154.0
1735862400,3454.81,3466.23,3445.58,3448.8,49005198.0
1735866000,3448.8,3465.02,3442.11,3464.36,64836976.0
1735869600,3464.36,3476.32,3455.92,3456.74,51253786.0
1735873200,3456.64,3471.96,3455.04,3469.22,41861896.0
1735876800,3469.21,3470.11,3455.0,3457.65,33613294.0
1735880400,3457.85,3459.99,3443.71,3455.13,57285134.0
1735884000,3455.13,3460.9,3441.01,3441.9,36792172.0
1735887600,3441.9,3443.62,3431.19,3432.52,64944146.0
1735891200,3432.52,3441.96,3422.35,3429.01,71555590.0
1735894800,3429.01,3449.99,3428.0,3442.67,45692272.0
1735898400,3442.66,3451.63,3437.26,3444.82,34326568.0
1735902000,3444.82,3466.53,3444.82,3464.73,51124624.0
1735905600,3464.47,3475.49,3460.01,3462.58,57106556.0
1735909200,3462.53,3496.26,3462.05,3480.31,136074052.0
1735912800,3480.36,3535.47,3479.85,3525.73,252612796.0
1735916400,3527.99,3575.99,3518.91,3564.31,266749252.0
1735920000,3564.31,3598.54,3564.2,3583.68,236728242.0
1735923600,3583.76,3593.0,3572.94,3574.28,77062022.0
1735927200,3574.28,3616.82,3573.18,3604.62,145063892.0
1735930800,3604.53,3629.68,3601.44,3621.89,136264822.0
1735934400,3621.89,3622.32,3599.55,3600.11,82316038.0
1735938000,3600.2,3615.64,3594.35,3613.51,60389536.0
1735941600,3613.51,3623.2,3609.21,3615.11,41030186.0
1735945200,3615.11,3616.87,3603.44,3607.89,55205762.0
1735948800,3607.89,3619.9,3601.06,3601.96,52305142.0
1735952400,3601.96,3603.52,3581.77,3595.65,60263730.0
1735956000,3595.65,3599.45,3582.0,3595.42,35032408.0
1735959600,3595.42,3599.48,3590.01,3597.04,28343560.0
1735963200,3597.08,3597.18,3583.1,3590.9,31587898.0
1735966800,3590.9,3596.15,3585.87,3595.52,27817296.0
1735970400,3595.52,3606.6,3594.06,3599.16,34022310.0
1735974000,3599.16,3609.0,3591.89,3593.04,43060454.0
1735977600,3593.04,3603.11,3584.0,3584.17,82921978.0
1735981200,3584.06,3594.99,3582.48,3588.57,39073846.0
1735984800,3588.57,3591.98,3570.92,3587.1,48068340.0
1735988400,3587.1,3605.05,3583.83,3601.16,55657250.0
1735992000,3601.16,3644.09,3599.35,3634.42,152503238.0
1735995600,3634.42,3648.59,3626.28,3643.77,105667482.0
1735999200,3643.77,3646.0,3631.36,3636.4,63779260.0
1736002800,3636.4,3662.37,3592.27,3606.5,238821272.0
1736006400,3606.5,3627.64,3600.3,3620.72,76957118.0
1736010000,3620.89,3633.52,3618.89,3632.52,40292730.0
1736013600,3632.52,3643.7,3618.0,3625.99,47967500.0
1736017200,3625.99,3638.39,3623.02,3629.81,24410624.0
1736020800,3629.81,3667.58,3629.81,3659.31,70469288.0
1736024400,3659.31,3669.95,3653.82,3657.57,60929522.0
1736028000,3657.57,3662.13,3645.68,3658.81,34926154.0
1736031600,3658.81,3664.88,3649.92,3655.98,35246640.0
1736035200,3655.98,3674.56,3646.87,3648.66,55777438.0
1736038800,3648.66,3650.3,3630.11,3635.55,52527572.0
1736042400,3635.55,3644.01,3633.69,3640.11,24195566.0
1736046000,3640.11,3640.9,3628.03,3636.5,20439542.0
1736049600,3636.5,3648.0,3635.87,3642.88,29199868.0
1736053200,3642.88,3642.9,3629.28,3631.5,26183660.0
1736056800,3631.5,3640.66,3626.93,3637.54,20101968.0
1736060400,3637.54,3640.13,3628.97,3630.38,19147964.0
1736064000,3630.38,3632.11,3607.51,3618.97,102512590.0
1736067600,3618.97,3622.41,3604.01,3608.53,47549468.0
1736071200,3608.65,3617.6,3601.63,3614.68,40940760.0
1736074800,3614.68,3620.13,3608.33,3612.57,30546036.0
1736078400,3612.57,3621.77,3603.95,3612.88,43155640.0
1736082000,3613.04,3626.65,3611.35,3613.49,37524524.0
1736085600,3613.49,3627.36,3592.53,3621.73,135663724.0
1736089200,3621.65,3637.67,3618.01,3628.43,75103806.0
1736092800,3628.43,3640.01,3623.01,3627.1,60533890.0
1736096400,3627.1,3647.35,3621.0,3627.36,52375452.0
1736100000,3627.14,3632.37,3611.43,3629.47,43996958.0
1736103600,3629.47,3638.96,3625.0,3636.9,25938496.0
1736107200,3636.9,3657.0,3627.34,3634.52,61275846.0
1736110800,3634.52,3647.21,3632.96,3644.52,23260872.0
1736114400,3644.52,3648.89,3633.14,3644.18,23637400.0
1736118000,3644.15,3654.47,3631.56,3634.85,35985516.0
1736121600,3634.85,3654.52,3620.5,3620.5,61317924.0
1736125200,3620.67,3654.84,3608.95,3647.81,86153808.0
1736128800,3647.51,3684.08,3644.14,3657.59,182952938.0
1736132400,3657.5,3673.87,3652.98,3663.93,46604218.0
1736136000,3663.93,3678.2,3659.69,3671.82,46449432.0
1736139600,3671.82,3697.99,3666.17,3679.61,99035916.0
1736143200,3679.61,3684.04,3664.12,3664.87,52617428.0
1736146800,3664.87,3667.1,3641.26,3649.39,93646214.0
1736150400,3649.39,3659.4,3635.02,3639.98,82925846.0
1736154000,3639.98,3649.36,3639.06,3643.89,28971374.0
1736157600,3643.89,3645.87,3631.43,3637.07,42695740.0
1736161200,3637.07,3658.44,3635.1,3653.7,56217424.0
1736164800,3653.7,3661.82,3640.68,3641.68,59441302.0
1736168400,3641.68,3651.94,3623.81,3650.0,96201734.0
1736172000,3650.0,3702.32,3621.12,3684.3,289303830.0
1736175600,3684.26,3713.01,3670.27,3711.59,260080200.0
1736179200,3712.89,3743.7,3690.41,3709.39,272849142.0
1736182800,3709.39,3710.16,3654.92,3672.78,176868982.0
1736186400,3672.78,3691.03,3661.17,3681.2,68879960.0
1736190000,3681.31,3694.94,3674.38,3686.47,39532406.0
1736193600,3686.47,3702.68,3671.65,3682.33,59308086.0
1736197200,3682.07,3687.78,3665.39,3666.31,51081846.0
1736200800,3666.31,3682.56,3666.1,3677.43,38055272.0
1736204400,3677.43,3686.36,3667.4,3685.72,28287998.0
1736208000,3685.72,3693.4,3672.22,3674.01,48983234.0
1736211600,3674.01,3695.78,3661.96,3693.68,48454388.0
1736215200,3693.68,3699.99,3675.01,3676.88,41902274.0
1736218800,3676.87,3687.99,3672.81,3681.48,34679266.0
1736222400,3681.48,3685.53,3672.38,3672.4,22079898.0
1736226000,3672.4,3676.15,3657.64,3668.64,45811008.0
1736229600,3668.64,3674.79,3663.01,3671.53,29019498.0
1736233200,3671.53,3678.99,3661.35,3666.6,29153142.0
1736236800,3666.6,3678.49,3659.26,3673.4,41854680.0
1736240400,3673.4,3675.58,3652.21,3660.13,57671204.0
1736244000,3660.14,3665.0,3650.39,3657.01,42289288.0
1736247600,3657.01,3657.99,3625.07,3638.34,132520824.0
1736251200,3638.6,3642.32,3625.51,3632.68,67571326.0
1736254800,3632.68,3644.9,3630.15,3635.14,48976982.0
1736258400,3635.2,3641.18,3523.0,3567.07,333440168.0
1736262000,3567.07,3580.49,3410.38,3461.46,1085438710.0
1736265600,3461.33,3490.42,3447.53,3456.8,250533314.0
1736269200,3456.8,3469.33,3420.12,3441.09,227652302.0
1736272800,3440.99,3458.14,3411.8,3420.51,182306610.0
1736276400,3420.51,3436.46,3374.36,3384.93,267051616.0
1736280000,3384.59,3399.26,3362.16,3395.32,175652002.0
1736283600,3395.27,3412.8,3359.81,3361.96,139760754.0
1736287200,3362.09,3396.25,3355.13,3395.21,96223134.0
1736290800,3395.21,3395.21,3373.61,3379.37,51490032.0
1736294400,3379.37,3413.55,3376.91,3410.01,87357960.0
1736298000,3410.09,3410.12,3373.39,3389.82,70746830.0
1736301600,3389.82,3402.98,3381.2,3381.23,51129254.0
1736305200,3381.23,3386.39,3342.71,3359.34,186577674.0
1736308800,3359.34,3372.73,3342.07,3347.27,105866768.0
1736312400,3347.27,3371.89,3336.08,3350.48,104936154.0
1736316000,3350.48,3361.34,3306.03,3307.77,211327564.0
1736319600,3307.8,3358.07,3306.71,3353.19,146187366.0
1736323200,3353.19,3375.59,3349.83,3364.56,101254772.0
1736326800,3364.57,3372.85,3345.0,3345.89,75539896.0
1736330400,3345.89,3371.99,3345.16,3360.9,69829694.0
1736334000,3360.9,3366.39,3321.76,3348.44,164453210.0
1736337600,3348.44,3359.3,3337.6,3338.59,85930986.0
1736341200,3338.61,3365.29,3338.61,3357.39,89649230.0
1736344800,3357.21,3380.52,3346.3,3369.27,151342344.0
1736348400,3368.94,3384.66,3332.0,3345.99,206886030.0
1736352000,3345.99,3347.06,3310.44,3313.07,148369138.0
1736355600,3313.11,3318.93,3207.46,3262.23,658990620.0
1736359200,3262.21,3329.38,3257.5,3281.58,286190748.0
1736362800,3281.99,3308.69,3270.47,3279.62,140264688.0
1736366400,3279.57,3290.0,3265.01,3284.51,65621974.0
1736370000,3284.51,3303.67,3268.87,3297.9,74963226.0
1736373600,3297.85,3332.86,3297.28,3331.31,80470748.0
1736377200,3331.31,3333.47,3314.73,3325.46,41780554.0
1736380800,3325.46,3342.07,3316.67,3340.7,60166482.0
1736384400,3340.12,3356.49,3333.9,3344.64,63614256.0
1736388000,3344.64,3349.59,3305.94,3339.6,165240584.0
1736391600,3339.6,3341.35,3315.56,3324.06,63469448.0
1736395200,3323.71,3342.24,3311.0,3339.0,67512222.0
1736398800,3338.96,3341.19,3323.42,3327.38,39150924.0
1736402400,3327.38,3333.77,3313.68,3314.92,41707280.0
1736406000,3314.92,3323.33,3281.3,3288.19,154505570.0
1736409600,3288.19,3325.89,3263.38,3308.99,192210656.0
1736413200,3309.07,3326.72,3305.94,3316.68,65498146.0
1736416800,3316.68,3321.07,3283.42,3310.84,106064710.0
1736420400,3310.84,3325.5,3292.07,3300.36,76143062.0
1736424000,3300.36,3309.23,3279.89,3294.89,72951552.0
1736427600,3294.89,3297.76,3211.02,3219.8,310900906.0
1736431200,3219.6,3251.76,3209.02,3249.62,207212678.0
1736434800,3249.62,3335.0,3242.45,3318.81,240337982.0
1736438400,3318.81,3326.2,3286.7,3300.79,164041718.0
1736442000,3300.79,3302.94,3234.38,3249.49,184871012.0
1736445600,3249.49,3269.11,3244.47,3258.78,103697430.0
1736449200,3259.07,3267.62,3190.01,3193.56,229460404.0
1736452800,3193.54,3212.74,3155.96,3194.13,302442148.0
1736456400,3194.12,3224.91,3189.44,3206.78,90139568.0
1736460000,3205.89,3238.13,3186.39,3222.7,89771046.0
1736463600,3222.7,3231.72,3208.6,3217.86,49759112.0
1736467200,3218.13,3232.61,3212.86,3221.74,54670720.0
1736470800,3221.74,3238.89,3212.52,3235.53,61826016.0
1736474400,3235.53,3258.78,3229.27,3239.91,73960624.0
1736478000,3240.12,3254.85,3237.3,3253.05,39189052.0
1736481600,3253.05,3263.57,3245.37,3252.64,52641914.0
1736485200,3252.78,3280.15,3241.27,3262.78,81991616.0
1736488800,3262.6,3279.35,3258.56,3276.45,46459632.0
1736492400,3276.45,3312.38,3269.49,3294.65,142743074.0
1736496000,3294.65,3300.61,3286.36,3294.77,54960336.0
1736499600,3294.77,3309.3,3289.02,3301.2,55245834.0
1736503200,3301.2,3319.92,3296.47,3316.89,63228784.0
1736506800,3316.89,3318.66,3294.49,3309.74,69342416.0
1736510400,3309.74,3311.0,3291.98,3309.36,67812524.0
1736514000,3309.25,3315.95,3215.36,3242.94,442746528.0
1736517600,3242.94,3277.64,3235.03,3255.47,229753402.0
1736521200,3253.81,3274.86,3193.21,3243.69,363287258.0
1736524800,3243.54,3260.64,3231.0,3246.19,141134442.0
1736528400,3246.11,3320.22,3241.43,3313.36,173307620.0
1736532000,3313.27,3313.27,3280.14,3285.21,117654418.0
1736535600,3285.76,3297.7,3269.11,3293.79,84001780.0
1736539200,3293.79,3293.8,3256.27,3258.81,62458836.0
1736542800,3258.71,3273.33,3256.01,3264.13,32978326.0
1736546400,3264.13,3280.1,3258.48,3272.36,35630396.0
1736550000,3272.36,3274.17,3263.04,3265.52,22914060.0
1736553600,3265.52,3268.92,3256.51,3264.4,38075382.0
1736557200,3264.4,3266.68,3235.13,3244.52,61301216.0
1736560800,3244.52,3250.87,3236.17,3246.5,29747936.0
1736564400,3246.5,3247.11,3230.52,3235.88,28924308.0
1736568000,3235.88,3242.0,3228.51,3237.53,32303354.0
1736571600,3237.53,3244.92,3231.48,3244.35,33205960.0
1736575200,3244.35,3249.5,3236.31,3236.33,28510900.0
1736578800,3236.33,3243.13,3224.17,3234.72,38537850.0
1736582400,3234.72,3239.07,3215.12,3223.37,48376530.0
1736586000,3223.37,3243.45,3222.27,3243.01,49518806.0
1736589600,3243.01,3255.31,3242.22,3255.26,79756560.0
1736593200,3255.26,3279.23,3252.9,3272.68,95103116.0
1736596800,3272.68,3280.0,3266.71,3271.65,39652500.0
1736600400,3271.65,3274.82,3257.51,3266.4,49449588.0
1736604000,3266.4,3278.98,3257.26,3277.3,42866688.0
1736607600,3277.2,3281.01,3265.16,3270.07,31206676.0
1736611200,3270.07,3277.14,3261.0,3274.11,31282780.0
1736614800,3274.11,3274.9,3257.7,3270.89,40054362.0
1736618400,3270.89,3279.01,3266.11,3277.06,18851470.0
1736622000,3276.96,3282.49,3268.28,3277.47,31217294.0
1736625600,3277.47,3299.48,3274.61,3298.28,40594708.0
1736629200,3298.28,3319.01,3298.05,3305.69,62717802.0
1736632800,3305.69,3307.36,3284.5,3287.56,40714280.0
1736636400,3287.56,3293.32,3280.33,3281.85,29895820.0
1736640000,3281.85,3286.11,3277.98,3282.18,22834780.0
1736643600,3282.18,3288.32,3273.02,3287.87,25636570.0
1736647200,3287.87,3288.96,3278.26,3288.87,17973236.0
1736650800,3288.87,3289.88,3277.02,3285.27,19745114.0
1736654400,3285.27,3288.62,3279.52,3282.52,17536690.0
1736658000,3282.52,3284.4,3273.11,3278.51,18182922.0
1736661600,3278.51,3280.29,3266.38,3269.24,28730928.0
1736665200,3269.24,3272.82,3262.31,3265.63,38470516.0
1736668800,3265.62,3270.61,3233.02,3238.36,122652126.0
1736672400,3238.45,3243.5,3223.13,3236.97,107510624.0
1736676000,3236.97,3244.82,3232.45,3243.12,47696088.0
1736679600,3243.12,3257.11,3239.67,3251.63,50138698.0
1736683200,3251.86,3264.27,3246.51,3249.24,57619188.0
1736686800,3249.24,3270.58,3246.94,3266.0,68944450.0
1736690400,3266.0,3279.9,3265.0,3267.83,73240184.0
1736694000,3267.83,3294.5,3264.0,3284.65,79888684.0
1736697600,3284.65,3286.99,3267.61,3280.51,43169660.0
1736701200,3280.51,3291.46,3277.19,3287.9,46143554.0
1736704800,3287.81,3298.89,3279.33,3283.73,47041518.0
1736708400,3283.73,3287.97,3274.66,3279.11,25800656.0
1736712000,3279.11,3288.49,3272.07,3280.55,23003516.0
1736715600,3280.63,3281.94,3262.59,3265.11,44126248.0
1736719200,3265.12,3267.41,3232.85,3239.17,101407078.0
1736722800,3239.17,3267.36,3237.68,3265.69,44761358.0
1736726400,3265.69,3338.19,3263.9,3307.67,252955806.0
1736730000,3307.43,3311.66,3251.27,3260.13,196644388.0
1736733600,3260.13,3269.95,3236.0,3254.9,121374346.0
1736737200,3254.9,3265.89,3234.02,3241.24,90367330.0
1736740800,3241.24,3259.58,3236.46,3237.36,78938608.0
1736744400,3237.36,3237.8,3211.68,3224.18,119089336.0
1736748000,3224.49,3232.3,3180.01,3190.13,176832932.0
1736751600,3190.1,3208.74,3181.93,3200.53,86710800.0
1736755200,3200.53,3205.45,3159.9,3168.74,156073064.0
1736758800,3168.74,3176.15,3119.18,3155.01,234976700.0
1736762400,3155.01,3155.99,3106.07,3117.96,317611886.0
1736766000,3118.75,3123.04,3055.09,3056.7,378759676.0
1736769600,3056.4,3084.95,3039.54,3045.72,305548852.0
1736773200,3045.89,3090.3,3032.3,3059.44,249979524.0
1736776800,3059.44,3060.11,2909.6,3033.47,974243346.0
1736780400,3033.59,3076.35,3025.13,3047.42,366822882.0
1736784000,3047.42,3058.66,3004.86,3008.65,234479378.0
1736787600,3007.87,3035.84,3003.01,3019.36,152995168.0
1736791200,3019.36,3032.98,2985.02,3006.39,179997976.0
1736794800,3006.38,3036.47,2991.8,3023.97,125369102.0
1736798400,3023.97,3103.38,3010.35,3090.15,177752432.0
1736802000,3090.41,3118.78,3081.97,3112.72,165786786.0
1736805600,3112.72,3141.66,3110.97,3130.64,116974672.0
1736809200,3130.64,3139.43,3124.38,3136.15,47544220.0
1736812800,3136.15,3147.25,3124.06,3132.57,84185166.0
1736816400,3132.57,3157.97,3132.19,3138.01,94074596.0
1736820000,3137.9,3165.79,3130.36,3155.98,85221592.0
1736823600,3155.98,3174.3,3153.45,3157.58,54405210.0
1736827200,3157.58,3174.12,3157.58,3171.39,55857890.0
1736830800,3171.23,3181.33,3158.29,3160.65,79933988.0
1736834400,3160.65,3187.06,3156.26,3182.95,73104704.0
1736838000,3182.95,3189.0,3169.86,3170.4,56505048.0
1736841600,3170.4,3191.27,3168.36,3181.91,74257186.0
1736845200,3182.0,3255.21,3176.59,3242.42,259501370.0
1736848800,3242.42,3242.89,3219.7,3233.75,124964948.0
1736852400,3233.75,3234.23,3209.7,3216.28,67811012.0
1736856000,3216.12,3218.73,3179.51,3182.39,163014218.0
1736859600,3182.5,3231.74,3178.0,3207.21,199494486.0
1736863200,3207.22,3232.31,3186.1,3190.41,130742936.0
1736866800,3190.94,3214.98,3186.11,3197.86,137337984.0
1736870400,3197.86,3202.94,3171.03,3189.99,137636112.0
1736874000,3189.99,3211.7,3182.72,3211.33,80978048.0
1736877600,3211.1,3231.4,3205.89,3223.37,92417500.0
1736881200,3223.37,3234.31,3211.09,3212.9,62213378.0
1736884800,3212.9,3224.69,3193.52,3221.24,82723252.0
1736888400,3221.24,3232.5,3211.25,3214.72,50505536.0
1736892000,3214.72,3239.2,3212.11,3233.81,35697584.0
1736895600,3233.81,3236.6,3221.18,3223.99,28458870.0
1736899200,3223.99,3241.26,3216.09,3220.18,62474718.0
1736902800,3220.18,3244.58,3215.73,3228.96,71656158.0
1736906400,3228.96,3238.69,3205.0,3211.66,70425488.0
1736910000,3211.77,3240.66,3207.26,3239.89,54759212.0
1736913600,3239.88,3251.11,3220.79,3225.01,81473270.0
1736917200,3224.99,3234.39,3213.86,3228.57,46760866.0
1736920800,3228.57,3231.82,3215.17,3229.14,47369732.0
1736924400,3229.14,3249.69,3228.61,3231.31,72666604.0
1736928000,3231.31,3246.86,3228.52,3230.98,60786620.0
1736931600,3231.1,3236.52,3195.34,3199.21,97527064.0
1736935200,3199.21,3217.14,3196.79,3208.08,62126134.0
1736938800,3208.08,3208.96,3185.53,3198.3,77459828.0
1736942400,3198.3,3210.72,3185.4,3200.66,78921674.0
1736946000,3200.66,3297.25,3200.4,3297.01,361680060.0
1736949600,3297.01,3330.61,3274.57,3328.32,260514000.0
1736953200,3328.37,3353.09,3324.53,3333.17,216457060.0
1736956800,3333.07,3365.41,3332.56,3338.3,139245078.0
1736960400,3338.3,3357.46,3322.99,3324.68,90410118.0
1736964000,3324.68,3373.77,3324.68,3370.89,81676352.0
1736967600,3370.8,3442.18,3366.66,3433.76,263310966.0
1736971200,3433.76,3472.38,3431.66,3432.83,208944138.0
1736974800,3432.81,3445.86,3426.0,3431.39,62340338.0
1736978400,3431.39,3434.99,3417.53,3429.39,51207524.0
1736982000,3429.48,3451.12,3419.23,3449.82,66010384.0
1736985600,3449.82,3458.48,3385.69,3397.95,171382692.0
1736989200,3397.95,3412.55,3391.65,3402.58,46722624.0
1736992800,3402.58,3405.0,3380.39,3384.03,61431958.0
1736996400,3384.03,3386.8,3345.74,3362.11,132369822.0
1737000000,3362.11,3374.53,3360.45,3373.24,55905782.0
1737003600,3373.24,3376.07,3364.58,3366.9,27209092.0
1737007200,3366.9,3386.02,3361.78,3378.89,55504360.0
1737010800,3378.86,3389.29,3375.89,3382.41,42026166.0
1737014400,3382.41,3384.0,3301.88,3315.42,213550818.0
1737018000,3315.44,3335.0,3298.01,3334.8,173270654.0
1737021600,3334.8,3340.99,3328.0,3332.2,59671834.0
1737025200,3332.87,3354.87,3320.07,3349.64,111186100.0
1737028800,3349.65,3363.28,3340.11,3355.43,97407238.0
1737032400,3355.53,3357.3,3309.0,3327.07,167514778.0
1737036000,3327.1,3341.53,3264.28,3276.1,285205966.0
1737039600,3276.25,3332.09,3268.53,3331.98,228397622.0
1737043200,3331.98,3360.66,3329.4,3339.22,152861984.0
1737046800,3338.77,3364.41,3329.91,3342.69,93468544.0
1737050400,3342.69,3349.79,3308.93,3324.61,90234800.0
1737054000,3324.61,3344.94,3318.01,3343.35,43458370.0
1737057600,3343.35,3351.99,3324.68,3335.77,53289036.0
1737061200,3335.71,3336.78,3310.16,3319.09,54644580.0
1737064800,3319.09,3319.31,3267.03,3296.7,131717852.0
1737068400,3296.7,3311.39,3289.02,3306.93,68247846.0
1737072000,3306.93,3316.78,3306.59,3312.78,42675412.0
1737075600,3312.78,3393.76,3312.72,3384.73,214952370.0
1737079200,3384.73,3396.23,3354.05,3372.07,140006948.0
1737082800,3372.07,3376.06,3357.4,3359.98,47167210.0
1737086400,3359.98,3371.42,3346.44,3369.69,64118896.0
1737090000,3369.69,3374.77,3358.19,3365.51,44641394.0
1737093600,3365.51,3374.7,3363.39,3366.38,39763556.0
1737097200,3366.38,3393.91,3361.3,3371.36,70940042.0
1737100800,3371.36,3412.78,3371.0,3405.9,121892422.0
1737104400,3405.9,3413.03,3399.07,3402.51,70929662.0
1737108000,3402.51,3437.78,3401.1,3426.64,102788236.0
1737111600,3426.64,3429.5,3415.53,3422.1,55018198.0
1737115200,3422.1,3425.46,3399.89,3406.78,90512196.0
1737118800,3406.78,3422.93,3394.96,3400.81,77679768.0
1737122400,3400.76,3431.89,3400.75,3427.7,167275558.0
1737126000,3427.49,3449.69,3403.1,3420.33,195084666.0
1737129600,3420.32,3447.59,3410.53,3436.43,111256436.0
1737133200,3436.43,3441.9,3406.02,3413.26,100510326.0
1737136800,3413.38,3428.83,3409.07,3410.49,47213594.0
1737140400,3410.49,3443.03,3409.73,3430.79,91962986.0
1737144000,3431.02,3524.4,3424.26,3514.04,286751750.0
1737147600,3514.04,3524.53,3465.44,3472.64,136440486.0
1737151200,3472.64,3486.56,3466.01,3468.91,61781218.0
1737154800,3468.91,3483.87,3461.49,3472.39,47196678.0
1737158400,3472.39,3492.94,3467.34,3485.83,52615116.0
1737162000,3485.83,3485.83,3453.85,3464.95,63843980.0
1737165600,3464.95,3473.28,3446.9,3450.06,47257378.0
1737169200,3450.11,3455.0,3366.79,3382.77,229697520.0
1737172800,3382.77,3394.52,3350.01,3364.52,172058940.0
1737176400,3364.52,3369.99,3290.01,3292.89,274237194.0
1737180000,3292.89,3339.39,3291.66,3312.76,153000770.0
1737183600,3312.76,3314.37,3280.01,3286.46,147604794.0
1737187200,3286.47,3294.66,3251.0,3291.85,228254978.0
1737190800,3291.85,3299.87,3252.31,3269.83,127768426.0
1737194400,3269.89,3276.99,3225.14,3265.78,252550352.0
1737198000,3265.81,3323.48,3247.76,3310.18,227271112.0
1737201600,3310.29,3320.91,3273.3,3288.68,159370596.0
1737205200,3288.68,3322.36,3278.33,3321.84,137949644.0
1737208800,3321.84,3325.22,3287.76,3295.86,97189442.0
1737212400,3295.86,3346.2,3283.95,3305.77,219267024.0
1737216000,3305.89,3315.72,3252.51,3252.51,243473644.0
1737219600,3252.51,3284.8,3252.12,3257.2,97599068.0
1737223200,3256.5,3283.03,3249.0,3263.66,83528110.0
1737226800,3263.54,3292.49,3260.39,3289.08,56544316.0
1737230400,3289.08,3290.88,3256.74,3264.87,58021088.0
1737234000,3264.88,3285.06,3262.08,3273.72,37319280.0
1737237600,3273.72,3287.67,3270.02,3279.36,30291248.0
1737241200,3279.42,3320.34,3278.22,3306.69,83215168.0
1737244800,3306.69,3322.38,3297.72,3315.68,66796494.0
1737248400,3315.68,3365.18,3312.9,3352.57,155449194.0
1737252000,3352.57,3377.32,3346.9,3352.47,82240816.0
1737255600,3352.47,3365.32,3332.52,3334.97,97009222.0
1737259200,3334.97,3337.32,3276.02,3282.51,202282652.0
1737262800,3282.51,3299.78,3258.18,3298.57,105321972.0
1737266400,3298.57,3299.93,3280.91,3282.12,47257870.0
1737270000,3282.18,3292.37,3261.31,3275.02,88322326.0
1737273600,3275.02,3277.15,3215.0,3221.19,203332442.0
1737277200,3221.19,3233.18,3143.11,3226.34,411242284.0
1737280800,3225.66,3226.18,3173.02,3174.2,166786984.0
1737284400,3174.3,3188.53,3131.0,3149.56,209689408.0
1737288000,3150.33,3210.59,3144.26,3205.26,164299906.0
1737291600,3205.26,3277.31,3193.14,3273.7,251270350.0
1737295200,3275.24,3395.99,3258.42,3380.19,863763538.0
1737298800,3380.11,3424.81,3352.82,3383.79,333831610.0
1737302400,3383.77,3424.04,3377.57,3410.83,168812328.0
1737306000,3410.88,3448.14,3385.96,3442.35,194255198.0
1737309600,3442.35,3449.0,3406.9,3434.0,106325700.0
1737313200,3433.4,3434.0,3407.59,3419.94,57312166.0
1737316800,3419.94,3432.95,3351.04,3378.22,144020792.0
1737320400,3378.22,3379.4,3207.05,3235.01,501866746.0
1737324000,3232.5,3311.84,3156.18,3265.77,478996130.0
1737327600,3265.76,3265.76,3160.07,3213.52,466762210.0
1737331200,3214.05,3225.31,3142.73,3170.28,407986910.0
1737334800,3170.27,3219.48,3165.19,3200.27,229060286.0
1737338400,3199.96,3273.76,3196.01,3243.54,218587436.0
1737342000,3244.04,3279.99,3227.01,3271.39,119161842.0
1737345600,3271.35,3298.81,3249.6,3269.87,100450292.0
1737349200,3269.87,3318.14,3266.79,3290.91,124554022.0
1737352800,3290.91,3454.72,3285.41,3417.53,388228564.0
1737356400,3417.41,3441.9,3351.89,3383.02,374577926.0
1737360000,3382.95,3412.04,3380.02,3392.15,127096766.0
1737363600,3392.15,3411.93,3352.99,3364.15,186871672.0
1737367200,3364.15,3391.99,3341.78,3354.39,126612530.0
1737370800,3354.39,3388.33,3334.21,3375.69,172373108.0
1737374400,3375.69,3379.6,3256.4,3303.82,367009686.0
1737378000,3303.93,3354.87,3295.01,3342.28,210560350.0
1737381600,3342.23,3361.6,3329.61,3358.56,154930784.0
1737385200,3358.55,3378.98,3315.21,3335.57,241523322.0
1737388800,3335.93,3390.0,3276.81,3380.16,274158310.0
1737392400,3379.9,3384.07,3205.0,3292.24,795072372.0
1737396000,3292.24,3341.58,3283.72,3330.16,213855650.0
1737399600,3330.04,3364.11,3308.4,3342.92,128630890.0
1737403200,3342.92,3344.32,3313.98,3320.27,77237838.0
1737406800,3320.27,3337.16,3280.51,3284.42,82249858.0
1737410400,3284.36,3324.16,3255.28,3318.25,103096784.0
1737414000,3318.14,3320.28,3260.59,3283.21,98151492.0
1737417600,3283.21,3289.47,3220.47,3225.66,167574272.0
1737421200,3225.9,3260.77,3203.89,3250.4,181075574.0
1737424800,3250.4,3272.75,3227.81,3256.73,97124780.0
1737428400,3256.73,3269.67,3248.01,3262.23,63734320.0
1737432000,3262.23,3262.25,3212.81,3246.37,95284392.0
1737435600,3246.37,3253.9,3216.03,3224.39,73892594.0
1737439200,3224.65,3253.97,3212.82,3241.15,98098922.0
1737442800,3241.15,3266.0,3234.55,3254.01,67830494.0
1737446400,3254.0,3262.97,3233.55,3253.27,67584610.0
1737450000,3253.27,3276.4,3249.82,3275.74,77660896.0
1737453600,3275.74,3308.8,3270.41,3302.06,104765974.0
1737457200,3302.06,3313.19,3291.81,3304.39,91283102.0
1737460800,3304.39,3325.85,3293.07,3306.62,128372258.0
1737464400,3306.62,3314.49,3288.96,3308.85,80976134.0
1737468000,3308.71,3333.73,3279.0,3288.51,211256600.0
1737471600,3288.51,3300.99,3261.77,3294.1,128559286.0
1737475200,3294.1,3349.14,3289.36,3313.34,197211854.0
1737478800,3313.15,3356.04,3307.09,3350.37,90531198.0
1737482400,3350.37,3367.88,3329.87,3345.17,100399176.0
1737486000,3345.18,3346.29,3317.24,3331.74,80784936.0
1737489600,3331.74,3339.63,3303.34,3313.41,70082146.0
1737493200,3313.43,3335.71,3301.87,3331.61,54339844.0
1737496800,3331.58,3346.58,3326.0,3333.06,38895058.0
1737500400,3333.91,3334.32,3307.27,3326.74,73269766.0
1737504000,3326.74,3365.96,3322.53,3361.54,73640766.0
1737507600,3361.54,3361.83,3321.61,3328.53,68953758.0
1737511200,3328.34,3346.78,3322.0,3343.32,51151860.0
1737514800,3343.32,3347.85,3327.2,3330.54,33271698.0
1737518400,3330.54,3332.93,3315.84,3331.15,33810516.0
1737522000,3331.15,3339.33,3317.01,3317.66,29934040.0
1737525600,3317.66,3323.48,3301.61,3308.82,50870486.0
1737529200,3308.82,3310.36,3286.18,3287.05,76036546.0
1737532800,3286.97,3300.02,3273.0,3298.39,92349262.0
1737536400,3298.39,3303.49,3289.1,3297.4,35948534.0
1737540000,3297.4,3307.4,3287.82,3306.99,40550278.0
1737543600,3306.99,3328.83,3303.3,3325.53,53272540.0
1737547200,3325.53,3331.45,3310.14,3315.9,52994384.0
1737550800,3315.85,3318.31,3279.25,3283.32,100473366.0
1737554400,3283.39,3310.99,3266.7,3292.02,165657884.0
1737558000,3292.72,3304.69,3268.95,3277.5,108866836.0
1737561600,3277.5,3282.91,3261.0,3277.1,97706330.0
1737565200,3277.15,3287.01,3271.02,3284.6,48476310.0
1737568800,3284.6,3290.85,3239.08,3248.93,96991712.0
1737572400,3249.38,3279.0,3247.52,3261.51,73598538.0
1737576000,3261.51,3276.21,3253.01,3255.86,46359000.0
1737579600,3255.82,3264.32,3240.0,3258.42,64803018.0
1737583200,3258.42,3265.69,3231.89,3237.63,52779412.0
1737586800,3237.63,3245.99,3221.53,3241.77,78166668.0
1737590400,3241.77,3260.81,3237.04,3252.92,56714310.0
1737594000,3252.92,3257.59,3220.0,3234.28,65753656.0
1737597600,3234.34,3236.57,3203.23,3222.26,94598842.0
1737601200,3222.48,3242.35,3214.38,3225.64,57395280.0
1737604800,3225.71,3230.89,3182.66,3196.01,114327136.0
1737608400,3196.01,3220.5,3195.34,3213.89,55114374.0
1737612000,3213.89,3223.98,3203.26,3207.1,39191160.0
1737615600,3207.1,3232.44,3197.39,3231.96,53561668.0
1737619200,3231.96,3232.44,3207.44,3209.22,45550378.0
1737622800,3209.26,3221.14,3191.13,3195.94,60758744.0
1737626400,3195.94,3212.68,3187.34,3203.3,65237070.0
1737630000,3203.3,3216.15,3194.82,3212.78,49857888.0
1737633600,3212.78,3217.94,3188.52,3202.62,78595334.0
1737637200,3202.62,3242.4,3201.12,3233.01,108985424.0
1737640800,3232.89,3285.36,3221.81,3274.6,249651856.0
1737644400,3274.6,3280.91,3225.01,3258.51,281277612.0
1737648000,3258.51,3296.73,3252.0,3253.65,190993782.0
1737651600,3253.64,3270.76,3230.02,3264.89,108032146.0
1737655200,3264.92,3269.43,3234.0,3239.9,70643910.0
1737658800,3239.9,3245.0,3193.09,3203.76,157291960.0
1737662400,3203.71,3294.1,3195.86,3246.15,442292904.0
1737666000,3246.11,3255.52,3212.77,3247.4,120420326.0
1737669600,3247.85,3322.98,3245.19,3321.94,160218202.0
1737673200,3321.66,3347.53,3311.27,3337.88,118336168.0
1737676800,3337.88,3348.99,3284.11,3284.72,117342552.0
1737680400,3284.69,3325.37,3283.51,3297.47,90561650.0
1737684000,3297.49,3313.1,3278.58,3284.64,67232158.0
1737687600,3285.21,3311.93,3275.0,3301.41,91279686.0
1737691200,3301.35,3339.92,3291.13,3332.72,87852684.0
1737694800,3332.45,3409.47,3328.55,3409.22,199536164.0
1737698400,3409.28,3420.61,3378.01,3385.27,167874148.0
1737702000,3385.32,3400.36,3371.39,3380.59,82619272.0
1737705600,3380.59,3415.57,3374.6,3400.57,104233816.0
1737709200,3400.58,3412.03,3391.01,3400.87,62308630.0
1737712800,3400.73,3414.21,3390.53,3412.88,57566642.0
1737716400,3412.88,3413.9,3391.8,3398.69,44487372.0
1737720000,3398.69,3404.63,3385.41,3403.48,58305470.0
1737723600,3403.48,3429.0,3390.25,3394.44,113839350.0
1737727200,3394.44,3421.99,3378.04,3398.31,143869564.0
1737730800,3398.34,3408.99,3355.0,3382.62,182652482.0
1737734400,3382.62,3397.06,3375.88,3379.29,76641652.0
1737738000,3379.35,3405.0,3371.76,3396.65,80638944.0
1737741600,3396.6,3408.37,3373.79,3380.06,61571938.0
1737745200,3380.0,3393.91,3363.16,3367.16,95047310.0
1737748800,3367.19,3377.48,3325.47,3327.04,158225220.0
1737752400,3327.75,3345.6,3322.22,3328.33,70830146.0
1737756000,3328.59,3335.82,3321.01,3324.47,47898010.0
1737759600,3324.47,3324.72,3302.5,3309.02,79667410.0
1737763200,3309.02,3312.97,3268.32,3272.36,114215218.0
1737766800,3272.27,3304.88,3267.35,3292.74,75981114.0
1737770400,3292.74,3303.18,3287.86,3293.48,31908786.0
1737774000,3293.48,3322.77,3290.52,3318.01,62089274.0
1737777600,3318.01,3318.57,3296.69,3298.78,41619704.0
1737781200,3298.78,3301.7,3286.6,3295.01,41837638.0
1737784800,3295.01,3302.39,3282.57,3290.84,42042506.0
1737788400,3290.78,3294.18,3281.83,3289.78,31177086.0
1737792000,3289.78,3299.99,3281.43,3289.6,41350052.0
1737795600,3289.6,3291.48,3280.0,3282.3,25686474.0
1737799200,3282.25,3296.12,3270.4,3294.2,64393426.0
1737802800,3294.24,3310.53,3289.62,3305.5,56540872.0
1737806400,3305.5,3306.2,3293.02,3304.78,37528022.0
1737810000,3304.78,3309.07,3299.01,3306.3,28691106.0
1737813600,3306.3,3318.59,3297.0,3314.36,36664870.0
1737817200,3314.41,3343.6,3308.42,3333.02,126783138.0
1737820800,3332.94,3347.91,3328.7,3341.0,60067516.0
1737824400,3341.08,3344.93,3329.09,3343.34,50834736.0
1737828000,3343.34,3347.11,3334.0,3340.79,28862350.0
1737831600,3340.79,3342.99,3333.01,3338.71,18958684.0
1737835200,3338.71,3349.46,3334.15,3335.62,26919424.0
1737838800,3335.66,3341.62,3330.89,3338.49,22254066.0
1737842400,3338.49,3344.78,3330.72,3332.85,16937198.0
1737846000,3332.85,3336.13,3313.36,3317.9,53735534.0
1737849600,3317.9,3326.9,3312.38,3319.74,34181402.0
1737853200,3319.74,3336.98,3317.18,3330.23,29997596.0
1737856800,3330.16,3330.16,3316.39,3327.22,26861986.0
1737860400,3327.22,3349.05,3324.99,3337.47,39360420.0
1737864000,3337.47,3364.99,3335.0,3350.99,60812656.0
1737867600,3350.99,3352.29,3336.82,3341.07,29644874.0
1737871200,3341.07,3346.39,3337.0,3340.36,20394300.0
1737874800,3340.36,3344.23,3328.67,3337.56,24837804.0
1737878400,3337.56,3342.4,3322.11,3330.52,40964058.0
1737882000,3330.52,3331.44,3291.46,3297.06,116578472.0
1737885600,3297.06,3305.58,3294.6,3304.27,37585964.0
1737889200,3304.27,3314.83,3301.35,3310.45,41215532.0
1737892800,3310.45,3310.46,3298.41,3306.64,30648776.0
1737896400,3306.47,3308.32,3299.05,3306.62,41653970.0
1737900000,3306.62,3311.91,3295.61,3309.48,35483260.0
1737903600,3309.48,3319.49,3307.06,3313.61,37547550.0
1737907200,3313.61,3318.63,3306.37,3314.39,35922004.0
1737910800,3314.39,3343.45,3313.81,3336.32,70866966.0
1737914400,3336.32,3341.72,3332.34,3335.83,51959942.0
1737918000,3335.83,3340.69,3328.77,3337.51,32405448.0
1737921600,3337.51,3341.35,3325.55,3328.26,20768510.0
1737925200,3328.3,3328.66,3290.68,3295.01,77584126.0
1737928800,3294.88,3308.55,3280.01,3286.36,69877756.0
1737932400,3286.31,3286.31,3227.47,3230.78,274026736.0
1737936000,3230.65,3252.53,3208.01,3212.62,180964884.0
1737939600,3212.63,3223.16,3186.86,3194.14,165658226.0
1737943200,3193.87,3194.0,3162.32,3169.45,191214386.0
1737946800,3169.45,3197.46,3160.24,3182.11,92065924.0
1737950400,3182.11,3182.11,3152.65,3155.73,87218334.0
1737954000,3155.73,3163.38,3113.02,3139.75,203842944.0
1737957600,3139.8,3148.9,3077.81,3082.76,298234274.0
1737961200,3082.76,3090.27,3020.93,3069.26,415672338.0
1737964800,3069.11,3071.81,3037.23,3064.19,162267474.0
1737968400,3064.24,3088.9,3056.92,3079.48,119649952.0
1737972000,3079.48,3080.18,3032.7,3037.11,115805844.0
1737975600,3037.05,3074.22,3036.34,3057.48,90659514.0
1737979200,3057.48,3121.61,3052.14,3101.53,187794412.0
1737982800,3101.47,3133.28,3087.85,3097.86,231867426.0
1737986400,3097.86,3144.83,3081.86,3136.15,203057890.0
1737990000,3135.72,3150.8,3110.7,3131.09,147629814.0
1737993600,3131.97,3132.04,3074.43,3083.0,203328436.0
1737997200,3082.95,3098.11,3065.24,3071.53,114566258.0
1738000800,3071.57,3087.79,3045.3,3053.88,103725792.0
1738004400,3053.91,3080.93,3053.91,3074.89,83541122.0
1738008000,3074.89,3147.82,3071.83,3145.22,143522924.0
1738011600,3143.97,3237.99,3141.23,3158.16,299739690.0
1738015200,3158.16,3180.06,3145.0,3169.25,79707278.0
1738018800,3169.25,3181.44,3158.71,3180.75,56318916.0
1738022400,3180.79,3202.51,3163.01,3166.22,77481438.0
1738026000,3166.27,3175.57,3150.31,3165.28,59624336.0
1738029600,3164.96,3198.41,3164.14,3191.6,59293696.0
1738033200,3191.56,3216.86,3174.1,3201.47,109284848.0
1738036800,3201.47,3221.53,3196.11,3210.64,83876044.0
1738040400,3210.67,3220.69,3207.19,3211.69,44259070.0
1738044000,3211.69,3214.02,3190.44,3193.55,48991426.0
1738047600,3193.43,3214.7,3187.51,3194.62,50038618.0
1738051200,3194.62,3204.1,3182.01,3197.47,81225676.0
1738054800,3197.42,3200.58,3183.0,3195.72,38138356.0
1738058400,3195.72,3206.32,3187.84,3192.87,39941280.0
1738062000,3192.87,3199.56,3175.47,3185.2,39874048.0
1738065600,3185.2,3194.62,3165.52,3173.72,60379984.0
1738069200,3173.64,3188.0,3169.01,3174.14,39825956.0
1738072800,3174.14,3179.53,3156.0,3171.09,125274148.0
1738076400,3171.34,3213.44,3169.55,3180.15,145496580.0
1738080000,3180.15,3181.81,3130.72,3149.59,141098534.0
1738083600,3149.46,3181.56,3149.05,3166.11,107192478.0
1738087200,3166.07,3176.76,3139.18,3142.6,67871000.0
1738090800,3142.6,3149.32,3118.98,3146.4,100694056.0
1738094400,3146.48,3153.45,3092.03,3094.31,134835852.0
1738098000,3093.42,3113.6,3051.32,3052.43,169849482.0
1738101600,3052.32,3089.94,3038.2,3082.86,165296122.0
1738105200,3082.93,3095.01,3052.51,3075.96,82801056.0
1738108800,3075.96,3116.55,3075.12,3108.9,1274170.0
1738112400,3108.85,3119.0,3097.82,3109.31,1144288.0
1738116000,3109.31,3128.3,3108.69,3112.81,4755046.0
1738119600,3112.74,3131.26,3106.65,3129.02,44437084.0
1738123200,3129.04,3138.89,3121.51,3122.94,51333698.0
1738126800,3122.87,3133.32,3115.46,3129.66,45341342.0
1738130400,3129.66,3148.96,3127.16,3145.88,60770492.0
1738134000,3145.88,3158.0,3137.4,3155.64,54759780.0
1738137600,3155.64,3162.68,3143.0,3146.4,48938372.0
1738141200,3146.4,3147.23,3121.93,3129.27,68754366.0
1738144800,3129.27,3142.05,3119.65,3136.48,46871668.0
1738148400,3136.48,3142.08,3130.31,3133.64,37915812.0
1738152000,3133.64,3138.84,3112.15,3117.69,73520948.0
1738155600,3117.69,3120.73,3087.77,3100.83,123395826.0
1738159200,3100.81,3115.17,3079.41,3095.1,130122046.0
1738162800,3095.81,3117.95,3092.7,3099.65,80143028.0
1 id open high low close volume
2 1735660800 3412.6 3416.0 3390.39 3408.23 102369440.0
3 1735664400 3408.23 3410.38 3329.45 3362.6 239948902.0
4 1735668000 3362.62 3372.14 3349.24 3360.3 87820990.0
5 1735671600 3360.3 3367.9 3342.85 3354.68 42695570.0
6 1735675200 3354.68 3364.47 3336.84 3346.12 54111736.0
7 1735678800 3345.76 3354.28 3331.51 3351.72 48624216.0
8 1735682400 3351.66 3351.66 3327.8 3338.94 44710804.0
9 1735686000 3338.94 3345.03 3327.22 3336.37 37042226.0
10 1735689600 3336.47 3364.49 3334.99 3362.89 57465298.0
11 1735693200 3362.89 3365.08 3341.6 3345.83 34711202.0
12 1735696800 3345.83 3368.02 3345.35 3361.81 34405766.0
13 1735700400 3361.81 3363.0 3350.22 3354.34 21508812.0
14 1735704000 3354.34 3355.78 3338.4 3340.12 45813072.0
15 1735707600 3340.04 3350.57 3339.13 3344.2 29504628.0
16 1735711200 3344.2 3347.33 3335.57 3345.65 26979022.0
17 1735714800 3345.65 3347.77 3338.32 3346.0 19122736.0
18 1735718400 3345.94 3348.0 3330.48 3335.57 39528308.0
19 1735722000 3335.57 3340.16 3313.08 3333.4 129899100.0
20 1735725600 3333.52 3337.99 3325.01 3325.99 32584622.0
21 1735729200 3325.99 3347.73 3322.8 3340.07 45465420.0
22 1735732800 3340.07 3351.21 3337.29 3346.01 39172620.0
23 1735736400 3346.01 3352.78 3331.45 3343.1 51120458.0
24 1735740000 3342.83 3358.89 3327.15 3345.0 82299724.0
25 1735743600 3345.06 3354.24 3332.01 3352.07 51286002.0
26 1735747200 3352.07 3356.14 3331.27 3337.72 49132440.0
27 1735750800 3337.72 3344.37 3322.56 3343.02 49046866.0
28 1735754400 3343.01 3351.47 3332.38 3347.81 36271786.0
29 1735758000 3347.81 3363.82 3338.02 3356.2 55282332.0
30 1735761600 3356.2 3361.76 3351.0 3359.39 38099614.0
31 1735765200 3359.28 3370.87 3352.49 3367.59 51552628.0
32 1735768800 3367.59 3373.97 3357.81 3360.65 43553722.0
33 1735772400 3360.65 3365.99 3352.07 3359.35 33197468.0
34 1735776000 3359.35 3399.41 3354.01 3389.27 123638482.0
35 1735779600 3389.27 3404.76 3377.72 3383.02 72528314.0
36 1735783200 3383.1 3397.9 3376.89 3397.89 35142436.0
37 1735786800 3397.89 3401.77 3386.57 3388.01 28707566.0
38 1735790400 3388.01 3427.38 3387.4 3417.81 124752266.0
39 1735794000 3417.82 3419.18 3404.4 3412.37 64463210.0
40 1735797600 3412.63 3415.73 3401.82 3410.19 37061074.0
41 1735801200 3410.19 3421.77 3408.6 3419.68 42976506.0
42 1735804800 3419.68 3442.8 3414.59 3437.98 81383320.0
43 1735808400 3437.13 3470.72 3433.94 3467.93 117165150.0
44 1735812000 3467.93 3476.09 3457.49 3468.61 95625752.0
45 1735815600 3468.61 3474.99 3457.1 3470.47 55981282.0
46 1735819200 3470.46 3480.37 3465.1 3479.77 71134738.0
47 1735822800 3479.89 3483.94 3459.45 3465.33 135921684.0
48 1735826400 3465.33 3509.87 3439.82 3494.61 298463722.0
49 1735830000 3494.61 3495.56 3455.45 3462.76 137324232.0
50 1735833600 3462.76 3488.75 3447.84 3468.71 102691858.0
51 1735837200 3468.7 3478.07 3429.2 3449.77 130762240.0
52 1735840800 3449.66 3464.67 3439.64 3464.16 96730060.0
53 1735844400 3464.16 3473.57 3458.11 3462.31 52010818.0
54 1735848000 3462.31 3474.61 3450.9 3452.17 41220990.0
55 1735851600 3452.29 3455.39 3442.18 3453.73 48633000.0
56 1735855200 3453.73 3453.75 3419.06 3440.0 62033228.0
57 1735858800 3439.91 3456.41 3437.0 3454.81 33740154.0
58 1735862400 3454.81 3466.23 3445.58 3448.8 49005198.0
59 1735866000 3448.8 3465.02 3442.11 3464.36 64836976.0
60 1735869600 3464.36 3476.32 3455.92 3456.74 51253786.0
61 1735873200 3456.64 3471.96 3455.04 3469.22 41861896.0
62 1735876800 3469.21 3470.11 3455.0 3457.65 33613294.0
63 1735880400 3457.85 3459.99 3443.71 3455.13 57285134.0
64 1735884000 3455.13 3460.9 3441.01 3441.9 36792172.0
65 1735887600 3441.9 3443.62 3431.19 3432.52 64944146.0
66 1735891200 3432.52 3441.96 3422.35 3429.01 71555590.0
67 1735894800 3429.01 3449.99 3428.0 3442.67 45692272.0
68 1735898400 3442.66 3451.63 3437.26 3444.82 34326568.0
69 1735902000 3444.82 3466.53 3444.82 3464.73 51124624.0
70 1735905600 3464.47 3475.49 3460.01 3462.58 57106556.0
71 1735909200 3462.53 3496.26 3462.05 3480.31 136074052.0
72 1735912800 3480.36 3535.47 3479.85 3525.73 252612796.0
73 1735916400 3527.99 3575.99 3518.91 3564.31 266749252.0
74 1735920000 3564.31 3598.54 3564.2 3583.68 236728242.0
75 1735923600 3583.76 3593.0 3572.94 3574.28 77062022.0
76 1735927200 3574.28 3616.82 3573.18 3604.62 145063892.0
77 1735930800 3604.53 3629.68 3601.44 3621.89 136264822.0
78 1735934400 3621.89 3622.32 3599.55 3600.11 82316038.0
79 1735938000 3600.2 3615.64 3594.35 3613.51 60389536.0
80 1735941600 3613.51 3623.2 3609.21 3615.11 41030186.0
81 1735945200 3615.11 3616.87 3603.44 3607.89 55205762.0
82 1735948800 3607.89 3619.9 3601.06 3601.96 52305142.0
83 1735952400 3601.96 3603.52 3581.77 3595.65 60263730.0
84 1735956000 3595.65 3599.45 3582.0 3595.42 35032408.0
85 1735959600 3595.42 3599.48 3590.01 3597.04 28343560.0
86 1735963200 3597.08 3597.18 3583.1 3590.9 31587898.0
87 1735966800 3590.9 3596.15 3585.87 3595.52 27817296.0
88 1735970400 3595.52 3606.6 3594.06 3599.16 34022310.0
89 1735974000 3599.16 3609.0 3591.89 3593.04 43060454.0
90 1735977600 3593.04 3603.11 3584.0 3584.17 82921978.0
91 1735981200 3584.06 3594.99 3582.48 3588.57 39073846.0
92 1735984800 3588.57 3591.98 3570.92 3587.1 48068340.0
93 1735988400 3587.1 3605.05 3583.83 3601.16 55657250.0
94 1735992000 3601.16 3644.09 3599.35 3634.42 152503238.0
95 1735995600 3634.42 3648.59 3626.28 3643.77 105667482.0
96 1735999200 3643.77 3646.0 3631.36 3636.4 63779260.0
97 1736002800 3636.4 3662.37 3592.27 3606.5 238821272.0
98 1736006400 3606.5 3627.64 3600.3 3620.72 76957118.0
99 1736010000 3620.89 3633.52 3618.89 3632.52 40292730.0
100 1736013600 3632.52 3643.7 3618.0 3625.99 47967500.0
101 1736017200 3625.99 3638.39 3623.02 3629.81 24410624.0
102 1736020800 3629.81 3667.58 3629.81 3659.31 70469288.0
103 1736024400 3659.31 3669.95 3653.82 3657.57 60929522.0
104 1736028000 3657.57 3662.13 3645.68 3658.81 34926154.0
105 1736031600 3658.81 3664.88 3649.92 3655.98 35246640.0
106 1736035200 3655.98 3674.56 3646.87 3648.66 55777438.0
107 1736038800 3648.66 3650.3 3630.11 3635.55 52527572.0
108 1736042400 3635.55 3644.01 3633.69 3640.11 24195566.0
109 1736046000 3640.11 3640.9 3628.03 3636.5 20439542.0
110 1736049600 3636.5 3648.0 3635.87 3642.88 29199868.0
111 1736053200 3642.88 3642.9 3629.28 3631.5 26183660.0
112 1736056800 3631.5 3640.66 3626.93 3637.54 20101968.0
113 1736060400 3637.54 3640.13 3628.97 3630.38 19147964.0
114 1736064000 3630.38 3632.11 3607.51 3618.97 102512590.0
115 1736067600 3618.97 3622.41 3604.01 3608.53 47549468.0
116 1736071200 3608.65 3617.6 3601.63 3614.68 40940760.0
117 1736074800 3614.68 3620.13 3608.33 3612.57 30546036.0
118 1736078400 3612.57 3621.77 3603.95 3612.88 43155640.0
119 1736082000 3613.04 3626.65 3611.35 3613.49 37524524.0
120 1736085600 3613.49 3627.36 3592.53 3621.73 135663724.0
121 1736089200 3621.65 3637.67 3618.01 3628.43 75103806.0
122 1736092800 3628.43 3640.01 3623.01 3627.1 60533890.0
123 1736096400 3627.1 3647.35 3621.0 3627.36 52375452.0
124 1736100000 3627.14 3632.37 3611.43 3629.47 43996958.0
125 1736103600 3629.47 3638.96 3625.0 3636.9 25938496.0
126 1736107200 3636.9 3657.0 3627.34 3634.52 61275846.0
127 1736110800 3634.52 3647.21 3632.96 3644.52 23260872.0
128 1736114400 3644.52 3648.89 3633.14 3644.18 23637400.0
129 1736118000 3644.15 3654.47 3631.56 3634.85 35985516.0
130 1736121600 3634.85 3654.52 3620.5 3620.5 61317924.0
131 1736125200 3620.67 3654.84 3608.95 3647.81 86153808.0
132 1736128800 3647.51 3684.08 3644.14 3657.59 182952938.0
133 1736132400 3657.5 3673.87 3652.98 3663.93 46604218.0
134 1736136000 3663.93 3678.2 3659.69 3671.82 46449432.0
135 1736139600 3671.82 3697.99 3666.17 3679.61 99035916.0
136 1736143200 3679.61 3684.04 3664.12 3664.87 52617428.0
137 1736146800 3664.87 3667.1 3641.26 3649.39 93646214.0
138 1736150400 3649.39 3659.4 3635.02 3639.98 82925846.0
139 1736154000 3639.98 3649.36 3639.06 3643.89 28971374.0
140 1736157600 3643.89 3645.87 3631.43 3637.07 42695740.0
141 1736161200 3637.07 3658.44 3635.1 3653.7 56217424.0
142 1736164800 3653.7 3661.82 3640.68 3641.68 59441302.0
143 1736168400 3641.68 3651.94 3623.81 3650.0 96201734.0
144 1736172000 3650.0 3702.32 3621.12 3684.3 289303830.0
145 1736175600 3684.26 3713.01 3670.27 3711.59 260080200.0
146 1736179200 3712.89 3743.7 3690.41 3709.39 272849142.0
147 1736182800 3709.39 3710.16 3654.92 3672.78 176868982.0
148 1736186400 3672.78 3691.03 3661.17 3681.2 68879960.0
149 1736190000 3681.31 3694.94 3674.38 3686.47 39532406.0
150 1736193600 3686.47 3702.68 3671.65 3682.33 59308086.0
151 1736197200 3682.07 3687.78 3665.39 3666.31 51081846.0
152 1736200800 3666.31 3682.56 3666.1 3677.43 38055272.0
153 1736204400 3677.43 3686.36 3667.4 3685.72 28287998.0
154 1736208000 3685.72 3693.4 3672.22 3674.01 48983234.0
155 1736211600 3674.01 3695.78 3661.96 3693.68 48454388.0
156 1736215200 3693.68 3699.99 3675.01 3676.88 41902274.0
157 1736218800 3676.87 3687.99 3672.81 3681.48 34679266.0
158 1736222400 3681.48 3685.53 3672.38 3672.4 22079898.0
159 1736226000 3672.4 3676.15 3657.64 3668.64 45811008.0
160 1736229600 3668.64 3674.79 3663.01 3671.53 29019498.0
161 1736233200 3671.53 3678.99 3661.35 3666.6 29153142.0
162 1736236800 3666.6 3678.49 3659.26 3673.4 41854680.0
163 1736240400 3673.4 3675.58 3652.21 3660.13 57671204.0
164 1736244000 3660.14 3665.0 3650.39 3657.01 42289288.0
165 1736247600 3657.01 3657.99 3625.07 3638.34 132520824.0
166 1736251200 3638.6 3642.32 3625.51 3632.68 67571326.0
167 1736254800 3632.68 3644.9 3630.15 3635.14 48976982.0
168 1736258400 3635.2 3641.18 3523.0 3567.07 333440168.0
169 1736262000 3567.07 3580.49 3410.38 3461.46 1085438710.0
170 1736265600 3461.33 3490.42 3447.53 3456.8 250533314.0
171 1736269200 3456.8 3469.33 3420.12 3441.09 227652302.0
172 1736272800 3440.99 3458.14 3411.8 3420.51 182306610.0
173 1736276400 3420.51 3436.46 3374.36 3384.93 267051616.0
174 1736280000 3384.59 3399.26 3362.16 3395.32 175652002.0
175 1736283600 3395.27 3412.8 3359.81 3361.96 139760754.0
176 1736287200 3362.09 3396.25 3355.13 3395.21 96223134.0
177 1736290800 3395.21 3395.21 3373.61 3379.37 51490032.0
178 1736294400 3379.37 3413.55 3376.91 3410.01 87357960.0
179 1736298000 3410.09 3410.12 3373.39 3389.82 70746830.0
180 1736301600 3389.82 3402.98 3381.2 3381.23 51129254.0
181 1736305200 3381.23 3386.39 3342.71 3359.34 186577674.0
182 1736308800 3359.34 3372.73 3342.07 3347.27 105866768.0
183 1736312400 3347.27 3371.89 3336.08 3350.48 104936154.0
184 1736316000 3350.48 3361.34 3306.03 3307.77 211327564.0
185 1736319600 3307.8 3358.07 3306.71 3353.19 146187366.0
186 1736323200 3353.19 3375.59 3349.83 3364.56 101254772.0
187 1736326800 3364.57 3372.85 3345.0 3345.89 75539896.0
188 1736330400 3345.89 3371.99 3345.16 3360.9 69829694.0
189 1736334000 3360.9 3366.39 3321.76 3348.44 164453210.0
190 1736337600 3348.44 3359.3 3337.6 3338.59 85930986.0
191 1736341200 3338.61 3365.29 3338.61 3357.39 89649230.0
192 1736344800 3357.21 3380.52 3346.3 3369.27 151342344.0
193 1736348400 3368.94 3384.66 3332.0 3345.99 206886030.0
194 1736352000 3345.99 3347.06 3310.44 3313.07 148369138.0
195 1736355600 3313.11 3318.93 3207.46 3262.23 658990620.0
196 1736359200 3262.21 3329.38 3257.5 3281.58 286190748.0
197 1736362800 3281.99 3308.69 3270.47 3279.62 140264688.0
198 1736366400 3279.57 3290.0 3265.01 3284.51 65621974.0
199 1736370000 3284.51 3303.67 3268.87 3297.9 74963226.0
200 1736373600 3297.85 3332.86 3297.28 3331.31 80470748.0
201 1736377200 3331.31 3333.47 3314.73 3325.46 41780554.0
202 1736380800 3325.46 3342.07 3316.67 3340.7 60166482.0
203 1736384400 3340.12 3356.49 3333.9 3344.64 63614256.0
204 1736388000 3344.64 3349.59 3305.94 3339.6 165240584.0
205 1736391600 3339.6 3341.35 3315.56 3324.06 63469448.0
206 1736395200 3323.71 3342.24 3311.0 3339.0 67512222.0
207 1736398800 3338.96 3341.19 3323.42 3327.38 39150924.0
208 1736402400 3327.38 3333.77 3313.68 3314.92 41707280.0
209 1736406000 3314.92 3323.33 3281.3 3288.19 154505570.0
210 1736409600 3288.19 3325.89 3263.38 3308.99 192210656.0
211 1736413200 3309.07 3326.72 3305.94 3316.68 65498146.0
212 1736416800 3316.68 3321.07 3283.42 3310.84 106064710.0
213 1736420400 3310.84 3325.5 3292.07 3300.36 76143062.0
214 1736424000 3300.36 3309.23 3279.89 3294.89 72951552.0
215 1736427600 3294.89 3297.76 3211.02 3219.8 310900906.0
216 1736431200 3219.6 3251.76 3209.02 3249.62 207212678.0
217 1736434800 3249.62 3335.0 3242.45 3318.81 240337982.0
218 1736438400 3318.81 3326.2 3286.7 3300.79 164041718.0
219 1736442000 3300.79 3302.94 3234.38 3249.49 184871012.0
220 1736445600 3249.49 3269.11 3244.47 3258.78 103697430.0
221 1736449200 3259.07 3267.62 3190.01 3193.56 229460404.0
222 1736452800 3193.54 3212.74 3155.96 3194.13 302442148.0
223 1736456400 3194.12 3224.91 3189.44 3206.78 90139568.0
224 1736460000 3205.89 3238.13 3186.39 3222.7 89771046.0
225 1736463600 3222.7 3231.72 3208.6 3217.86 49759112.0
226 1736467200 3218.13 3232.61 3212.86 3221.74 54670720.0
227 1736470800 3221.74 3238.89 3212.52 3235.53 61826016.0
228 1736474400 3235.53 3258.78 3229.27 3239.91 73960624.0
229 1736478000 3240.12 3254.85 3237.3 3253.05 39189052.0
230 1736481600 3253.05 3263.57 3245.37 3252.64 52641914.0
231 1736485200 3252.78 3280.15 3241.27 3262.78 81991616.0
232 1736488800 3262.6 3279.35 3258.56 3276.45 46459632.0
233 1736492400 3276.45 3312.38 3269.49 3294.65 142743074.0
234 1736496000 3294.65 3300.61 3286.36 3294.77 54960336.0
235 1736499600 3294.77 3309.3 3289.02 3301.2 55245834.0
236 1736503200 3301.2 3319.92 3296.47 3316.89 63228784.0
237 1736506800 3316.89 3318.66 3294.49 3309.74 69342416.0
238 1736510400 3309.74 3311.0 3291.98 3309.36 67812524.0
239 1736514000 3309.25 3315.95 3215.36 3242.94 442746528.0
240 1736517600 3242.94 3277.64 3235.03 3255.47 229753402.0
241 1736521200 3253.81 3274.86 3193.21 3243.69 363287258.0
242 1736524800 3243.54 3260.64 3231.0 3246.19 141134442.0
243 1736528400 3246.11 3320.22 3241.43 3313.36 173307620.0
244 1736532000 3313.27 3313.27 3280.14 3285.21 117654418.0
245 1736535600 3285.76 3297.7 3269.11 3293.79 84001780.0
246 1736539200 3293.79 3293.8 3256.27 3258.81 62458836.0
247 1736542800 3258.71 3273.33 3256.01 3264.13 32978326.0
248 1736546400 3264.13 3280.1 3258.48 3272.36 35630396.0
249 1736550000 3272.36 3274.17 3263.04 3265.52 22914060.0
250 1736553600 3265.52 3268.92 3256.51 3264.4 38075382.0
251 1736557200 3264.4 3266.68 3235.13 3244.52 61301216.0
252 1736560800 3244.52 3250.87 3236.17 3246.5 29747936.0
253 1736564400 3246.5 3247.11 3230.52 3235.88 28924308.0
254 1736568000 3235.88 3242.0 3228.51 3237.53 32303354.0
255 1736571600 3237.53 3244.92 3231.48 3244.35 33205960.0
256 1736575200 3244.35 3249.5 3236.31 3236.33 28510900.0
257 1736578800 3236.33 3243.13 3224.17 3234.72 38537850.0
258 1736582400 3234.72 3239.07 3215.12 3223.37 48376530.0
259 1736586000 3223.37 3243.45 3222.27 3243.01 49518806.0
260 1736589600 3243.01 3255.31 3242.22 3255.26 79756560.0
261 1736593200 3255.26 3279.23 3252.9 3272.68 95103116.0
262 1736596800 3272.68 3280.0 3266.71 3271.65 39652500.0
263 1736600400 3271.65 3274.82 3257.51 3266.4 49449588.0
264 1736604000 3266.4 3278.98 3257.26 3277.3 42866688.0
265 1736607600 3277.2 3281.01 3265.16 3270.07 31206676.0
266 1736611200 3270.07 3277.14 3261.0 3274.11 31282780.0
267 1736614800 3274.11 3274.9 3257.7 3270.89 40054362.0
268 1736618400 3270.89 3279.01 3266.11 3277.06 18851470.0
269 1736622000 3276.96 3282.49 3268.28 3277.47 31217294.0
270 1736625600 3277.47 3299.48 3274.61 3298.28 40594708.0
271 1736629200 3298.28 3319.01 3298.05 3305.69 62717802.0
272 1736632800 3305.69 3307.36 3284.5 3287.56 40714280.0
273 1736636400 3287.56 3293.32 3280.33 3281.85 29895820.0
274 1736640000 3281.85 3286.11 3277.98 3282.18 22834780.0
275 1736643600 3282.18 3288.32 3273.02 3287.87 25636570.0
276 1736647200 3287.87 3288.96 3278.26 3288.87 17973236.0
277 1736650800 3288.87 3289.88 3277.02 3285.27 19745114.0
278 1736654400 3285.27 3288.62 3279.52 3282.52 17536690.0
279 1736658000 3282.52 3284.4 3273.11 3278.51 18182922.0
280 1736661600 3278.51 3280.29 3266.38 3269.24 28730928.0
281 1736665200 3269.24 3272.82 3262.31 3265.63 38470516.0
282 1736668800 3265.62 3270.61 3233.02 3238.36 122652126.0
283 1736672400 3238.45 3243.5 3223.13 3236.97 107510624.0
284 1736676000 3236.97 3244.82 3232.45 3243.12 47696088.0
285 1736679600 3243.12 3257.11 3239.67 3251.63 50138698.0
286 1736683200 3251.86 3264.27 3246.51 3249.24 57619188.0
287 1736686800 3249.24 3270.58 3246.94 3266.0 68944450.0
288 1736690400 3266.0 3279.9 3265.0 3267.83 73240184.0
289 1736694000 3267.83 3294.5 3264.0 3284.65 79888684.0
290 1736697600 3284.65 3286.99 3267.61 3280.51 43169660.0
291 1736701200 3280.51 3291.46 3277.19 3287.9 46143554.0
292 1736704800 3287.81 3298.89 3279.33 3283.73 47041518.0
293 1736708400 3283.73 3287.97 3274.66 3279.11 25800656.0
294 1736712000 3279.11 3288.49 3272.07 3280.55 23003516.0
295 1736715600 3280.63 3281.94 3262.59 3265.11 44126248.0
296 1736719200 3265.12 3267.41 3232.85 3239.17 101407078.0
297 1736722800 3239.17 3267.36 3237.68 3265.69 44761358.0
298 1736726400 3265.69 3338.19 3263.9 3307.67 252955806.0
299 1736730000 3307.43 3311.66 3251.27 3260.13 196644388.0
300 1736733600 3260.13 3269.95 3236.0 3254.9 121374346.0
301 1736737200 3254.9 3265.89 3234.02 3241.24 90367330.0
302 1736740800 3241.24 3259.58 3236.46 3237.36 78938608.0
303 1736744400 3237.36 3237.8 3211.68 3224.18 119089336.0
304 1736748000 3224.49 3232.3 3180.01 3190.13 176832932.0
305 1736751600 3190.1 3208.74 3181.93 3200.53 86710800.0
306 1736755200 3200.53 3205.45 3159.9 3168.74 156073064.0
307 1736758800 3168.74 3176.15 3119.18 3155.01 234976700.0
308 1736762400 3155.01 3155.99 3106.07 3117.96 317611886.0
309 1736766000 3118.75 3123.04 3055.09 3056.7 378759676.0
310 1736769600 3056.4 3084.95 3039.54 3045.72 305548852.0
311 1736773200 3045.89 3090.3 3032.3 3059.44 249979524.0
312 1736776800 3059.44 3060.11 2909.6 3033.47 974243346.0
313 1736780400 3033.59 3076.35 3025.13 3047.42 366822882.0
314 1736784000 3047.42 3058.66 3004.86 3008.65 234479378.0
315 1736787600 3007.87 3035.84 3003.01 3019.36 152995168.0
316 1736791200 3019.36 3032.98 2985.02 3006.39 179997976.0
317 1736794800 3006.38 3036.47 2991.8 3023.97 125369102.0
318 1736798400 3023.97 3103.38 3010.35 3090.15 177752432.0
319 1736802000 3090.41 3118.78 3081.97 3112.72 165786786.0
320 1736805600 3112.72 3141.66 3110.97 3130.64 116974672.0
321 1736809200 3130.64 3139.43 3124.38 3136.15 47544220.0
322 1736812800 3136.15 3147.25 3124.06 3132.57 84185166.0
323 1736816400 3132.57 3157.97 3132.19 3138.01 94074596.0
324 1736820000 3137.9 3165.79 3130.36 3155.98 85221592.0
325 1736823600 3155.98 3174.3 3153.45 3157.58 54405210.0
326 1736827200 3157.58 3174.12 3157.58 3171.39 55857890.0
327 1736830800 3171.23 3181.33 3158.29 3160.65 79933988.0
328 1736834400 3160.65 3187.06 3156.26 3182.95 73104704.0
329 1736838000 3182.95 3189.0 3169.86 3170.4 56505048.0
330 1736841600 3170.4 3191.27 3168.36 3181.91 74257186.0
331 1736845200 3182.0 3255.21 3176.59 3242.42 259501370.0
332 1736848800 3242.42 3242.89 3219.7 3233.75 124964948.0
333 1736852400 3233.75 3234.23 3209.7 3216.28 67811012.0
334 1736856000 3216.12 3218.73 3179.51 3182.39 163014218.0
335 1736859600 3182.5 3231.74 3178.0 3207.21 199494486.0
336 1736863200 3207.22 3232.31 3186.1 3190.41 130742936.0
337 1736866800 3190.94 3214.98 3186.11 3197.86 137337984.0
338 1736870400 3197.86 3202.94 3171.03 3189.99 137636112.0
339 1736874000 3189.99 3211.7 3182.72 3211.33 80978048.0
340 1736877600 3211.1 3231.4 3205.89 3223.37 92417500.0
341 1736881200 3223.37 3234.31 3211.09 3212.9 62213378.0
342 1736884800 3212.9 3224.69 3193.52 3221.24 82723252.0
343 1736888400 3221.24 3232.5 3211.25 3214.72 50505536.0
344 1736892000 3214.72 3239.2 3212.11 3233.81 35697584.0
345 1736895600 3233.81 3236.6 3221.18 3223.99 28458870.0
346 1736899200 3223.99 3241.26 3216.09 3220.18 62474718.0
347 1736902800 3220.18 3244.58 3215.73 3228.96 71656158.0
348 1736906400 3228.96 3238.69 3205.0 3211.66 70425488.0
349 1736910000 3211.77 3240.66 3207.26 3239.89 54759212.0
350 1736913600 3239.88 3251.11 3220.79 3225.01 81473270.0
351 1736917200 3224.99 3234.39 3213.86 3228.57 46760866.0
352 1736920800 3228.57 3231.82 3215.17 3229.14 47369732.0
353 1736924400 3229.14 3249.69 3228.61 3231.31 72666604.0
354 1736928000 3231.31 3246.86 3228.52 3230.98 60786620.0
355 1736931600 3231.1 3236.52 3195.34 3199.21 97527064.0
356 1736935200 3199.21 3217.14 3196.79 3208.08 62126134.0
357 1736938800 3208.08 3208.96 3185.53 3198.3 77459828.0
358 1736942400 3198.3 3210.72 3185.4 3200.66 78921674.0
359 1736946000 3200.66 3297.25 3200.4 3297.01 361680060.0
360 1736949600 3297.01 3330.61 3274.57 3328.32 260514000.0
361 1736953200 3328.37 3353.09 3324.53 3333.17 216457060.0
362 1736956800 3333.07 3365.41 3332.56 3338.3 139245078.0
363 1736960400 3338.3 3357.46 3322.99 3324.68 90410118.0
364 1736964000 3324.68 3373.77 3324.68 3370.89 81676352.0
365 1736967600 3370.8 3442.18 3366.66 3433.76 263310966.0
366 1736971200 3433.76 3472.38 3431.66 3432.83 208944138.0
367 1736974800 3432.81 3445.86 3426.0 3431.39 62340338.0
368 1736978400 3431.39 3434.99 3417.53 3429.39 51207524.0
369 1736982000 3429.48 3451.12 3419.23 3449.82 66010384.0
370 1736985600 3449.82 3458.48 3385.69 3397.95 171382692.0
371 1736989200 3397.95 3412.55 3391.65 3402.58 46722624.0
372 1736992800 3402.58 3405.0 3380.39 3384.03 61431958.0
373 1736996400 3384.03 3386.8 3345.74 3362.11 132369822.0
374 1737000000 3362.11 3374.53 3360.45 3373.24 55905782.0
375 1737003600 3373.24 3376.07 3364.58 3366.9 27209092.0
376 1737007200 3366.9 3386.02 3361.78 3378.89 55504360.0
377 1737010800 3378.86 3389.29 3375.89 3382.41 42026166.0
378 1737014400 3382.41 3384.0 3301.88 3315.42 213550818.0
379 1737018000 3315.44 3335.0 3298.01 3334.8 173270654.0
380 1737021600 3334.8 3340.99 3328.0 3332.2 59671834.0
381 1737025200 3332.87 3354.87 3320.07 3349.64 111186100.0
382 1737028800 3349.65 3363.28 3340.11 3355.43 97407238.0
383 1737032400 3355.53 3357.3 3309.0 3327.07 167514778.0
384 1737036000 3327.1 3341.53 3264.28 3276.1 285205966.0
385 1737039600 3276.25 3332.09 3268.53 3331.98 228397622.0
386 1737043200 3331.98 3360.66 3329.4 3339.22 152861984.0
387 1737046800 3338.77 3364.41 3329.91 3342.69 93468544.0
388 1737050400 3342.69 3349.79 3308.93 3324.61 90234800.0
389 1737054000 3324.61 3344.94 3318.01 3343.35 43458370.0
390 1737057600 3343.35 3351.99 3324.68 3335.77 53289036.0
391 1737061200 3335.71 3336.78 3310.16 3319.09 54644580.0
392 1737064800 3319.09 3319.31 3267.03 3296.7 131717852.0
393 1737068400 3296.7 3311.39 3289.02 3306.93 68247846.0
394 1737072000 3306.93 3316.78 3306.59 3312.78 42675412.0
395 1737075600 3312.78 3393.76 3312.72 3384.73 214952370.0
396 1737079200 3384.73 3396.23 3354.05 3372.07 140006948.0
397 1737082800 3372.07 3376.06 3357.4 3359.98 47167210.0
398 1737086400 3359.98 3371.42 3346.44 3369.69 64118896.0
399 1737090000 3369.69 3374.77 3358.19 3365.51 44641394.0
400 1737093600 3365.51 3374.7 3363.39 3366.38 39763556.0
401 1737097200 3366.38 3393.91 3361.3 3371.36 70940042.0
402 1737100800 3371.36 3412.78 3371.0 3405.9 121892422.0
403 1737104400 3405.9 3413.03 3399.07 3402.51 70929662.0
404 1737108000 3402.51 3437.78 3401.1 3426.64 102788236.0
405 1737111600 3426.64 3429.5 3415.53 3422.1 55018198.0
406 1737115200 3422.1 3425.46 3399.89 3406.78 90512196.0
407 1737118800 3406.78 3422.93 3394.96 3400.81 77679768.0
408 1737122400 3400.76 3431.89 3400.75 3427.7 167275558.0
409 1737126000 3427.49 3449.69 3403.1 3420.33 195084666.0
410 1737129600 3420.32 3447.59 3410.53 3436.43 111256436.0
411 1737133200 3436.43 3441.9 3406.02 3413.26 100510326.0
412 1737136800 3413.38 3428.83 3409.07 3410.49 47213594.0
413 1737140400 3410.49 3443.03 3409.73 3430.79 91962986.0
414 1737144000 3431.02 3524.4 3424.26 3514.04 286751750.0
415 1737147600 3514.04 3524.53 3465.44 3472.64 136440486.0
416 1737151200 3472.64 3486.56 3466.01 3468.91 61781218.0
417 1737154800 3468.91 3483.87 3461.49 3472.39 47196678.0
418 1737158400 3472.39 3492.94 3467.34 3485.83 52615116.0
419 1737162000 3485.83 3485.83 3453.85 3464.95 63843980.0
420 1737165600 3464.95 3473.28 3446.9 3450.06 47257378.0
421 1737169200 3450.11 3455.0 3366.79 3382.77 229697520.0
422 1737172800 3382.77 3394.52 3350.01 3364.52 172058940.0
423 1737176400 3364.52 3369.99 3290.01 3292.89 274237194.0
424 1737180000 3292.89 3339.39 3291.66 3312.76 153000770.0
425 1737183600 3312.76 3314.37 3280.01 3286.46 147604794.0
426 1737187200 3286.47 3294.66 3251.0 3291.85 228254978.0
427 1737190800 3291.85 3299.87 3252.31 3269.83 127768426.0
428 1737194400 3269.89 3276.99 3225.14 3265.78 252550352.0
429 1737198000 3265.81 3323.48 3247.76 3310.18 227271112.0
430 1737201600 3310.29 3320.91 3273.3 3288.68 159370596.0
431 1737205200 3288.68 3322.36 3278.33 3321.84 137949644.0
432 1737208800 3321.84 3325.22 3287.76 3295.86 97189442.0
433 1737212400 3295.86 3346.2 3283.95 3305.77 219267024.0
434 1737216000 3305.89 3315.72 3252.51 3252.51 243473644.0
435 1737219600 3252.51 3284.8 3252.12 3257.2 97599068.0
436 1737223200 3256.5 3283.03 3249.0 3263.66 83528110.0
437 1737226800 3263.54 3292.49 3260.39 3289.08 56544316.0
438 1737230400 3289.08 3290.88 3256.74 3264.87 58021088.0
439 1737234000 3264.88 3285.06 3262.08 3273.72 37319280.0
440 1737237600 3273.72 3287.67 3270.02 3279.36 30291248.0
441 1737241200 3279.42 3320.34 3278.22 3306.69 83215168.0
442 1737244800 3306.69 3322.38 3297.72 3315.68 66796494.0
443 1737248400 3315.68 3365.18 3312.9 3352.57 155449194.0
444 1737252000 3352.57 3377.32 3346.9 3352.47 82240816.0
445 1737255600 3352.47 3365.32 3332.52 3334.97 97009222.0
446 1737259200 3334.97 3337.32 3276.02 3282.51 202282652.0
447 1737262800 3282.51 3299.78 3258.18 3298.57 105321972.0
448 1737266400 3298.57 3299.93 3280.91 3282.12 47257870.0
449 1737270000 3282.18 3292.37 3261.31 3275.02 88322326.0
450 1737273600 3275.02 3277.15 3215.0 3221.19 203332442.0
451 1737277200 3221.19 3233.18 3143.11 3226.34 411242284.0
452 1737280800 3225.66 3226.18 3173.02 3174.2 166786984.0
453 1737284400 3174.3 3188.53 3131.0 3149.56 209689408.0
454 1737288000 3150.33 3210.59 3144.26 3205.26 164299906.0
455 1737291600 3205.26 3277.31 3193.14 3273.7 251270350.0
456 1737295200 3275.24 3395.99 3258.42 3380.19 863763538.0
457 1737298800 3380.11 3424.81 3352.82 3383.79 333831610.0
458 1737302400 3383.77 3424.04 3377.57 3410.83 168812328.0
459 1737306000 3410.88 3448.14 3385.96 3442.35 194255198.0
460 1737309600 3442.35 3449.0 3406.9 3434.0 106325700.0
461 1737313200 3433.4 3434.0 3407.59 3419.94 57312166.0
462 1737316800 3419.94 3432.95 3351.04 3378.22 144020792.0
463 1737320400 3378.22 3379.4 3207.05 3235.01 501866746.0
464 1737324000 3232.5 3311.84 3156.18 3265.77 478996130.0
465 1737327600 3265.76 3265.76 3160.07 3213.52 466762210.0
466 1737331200 3214.05 3225.31 3142.73 3170.28 407986910.0
467 1737334800 3170.27 3219.48 3165.19 3200.27 229060286.0
468 1737338400 3199.96 3273.76 3196.01 3243.54 218587436.0
469 1737342000 3244.04 3279.99 3227.01 3271.39 119161842.0
470 1737345600 3271.35 3298.81 3249.6 3269.87 100450292.0
471 1737349200 3269.87 3318.14 3266.79 3290.91 124554022.0
472 1737352800 3290.91 3454.72 3285.41 3417.53 388228564.0
473 1737356400 3417.41 3441.9 3351.89 3383.02 374577926.0
474 1737360000 3382.95 3412.04 3380.02 3392.15 127096766.0
475 1737363600 3392.15 3411.93 3352.99 3364.15 186871672.0
476 1737367200 3364.15 3391.99 3341.78 3354.39 126612530.0
477 1737370800 3354.39 3388.33 3334.21 3375.69 172373108.0
478 1737374400 3375.69 3379.6 3256.4 3303.82 367009686.0
479 1737378000 3303.93 3354.87 3295.01 3342.28 210560350.0
480 1737381600 3342.23 3361.6 3329.61 3358.56 154930784.0
481 1737385200 3358.55 3378.98 3315.21 3335.57 241523322.0
482 1737388800 3335.93 3390.0 3276.81 3380.16 274158310.0
483 1737392400 3379.9 3384.07 3205.0 3292.24 795072372.0
484 1737396000 3292.24 3341.58 3283.72 3330.16 213855650.0
485 1737399600 3330.04 3364.11 3308.4 3342.92 128630890.0
486 1737403200 3342.92 3344.32 3313.98 3320.27 77237838.0
487 1737406800 3320.27 3337.16 3280.51 3284.42 82249858.0
488 1737410400 3284.36 3324.16 3255.28 3318.25 103096784.0
489 1737414000 3318.14 3320.28 3260.59 3283.21 98151492.0
490 1737417600 3283.21 3289.47 3220.47 3225.66 167574272.0
491 1737421200 3225.9 3260.77 3203.89 3250.4 181075574.0
492 1737424800 3250.4 3272.75 3227.81 3256.73 97124780.0
493 1737428400 3256.73 3269.67 3248.01 3262.23 63734320.0
494 1737432000 3262.23 3262.25 3212.81 3246.37 95284392.0
495 1737435600 3246.37 3253.9 3216.03 3224.39 73892594.0
496 1737439200 3224.65 3253.97 3212.82 3241.15 98098922.0
497 1737442800 3241.15 3266.0 3234.55 3254.01 67830494.0
498 1737446400 3254.0 3262.97 3233.55 3253.27 67584610.0
499 1737450000 3253.27 3276.4 3249.82 3275.74 77660896.0
500 1737453600 3275.74 3308.8 3270.41 3302.06 104765974.0
501 1737457200 3302.06 3313.19 3291.81 3304.39 91283102.0
502 1737460800 3304.39 3325.85 3293.07 3306.62 128372258.0
503 1737464400 3306.62 3314.49 3288.96 3308.85 80976134.0
504 1737468000 3308.71 3333.73 3279.0 3288.51 211256600.0
505 1737471600 3288.51 3300.99 3261.77 3294.1 128559286.0
506 1737475200 3294.1 3349.14 3289.36 3313.34 197211854.0
507 1737478800 3313.15 3356.04 3307.09 3350.37 90531198.0
508 1737482400 3350.37 3367.88 3329.87 3345.17 100399176.0
509 1737486000 3345.18 3346.29 3317.24 3331.74 80784936.0
510 1737489600 3331.74 3339.63 3303.34 3313.41 70082146.0
511 1737493200 3313.43 3335.71 3301.87 3331.61 54339844.0
512 1737496800 3331.58 3346.58 3326.0 3333.06 38895058.0
513 1737500400 3333.91 3334.32 3307.27 3326.74 73269766.0
514 1737504000 3326.74 3365.96 3322.53 3361.54 73640766.0
515 1737507600 3361.54 3361.83 3321.61 3328.53 68953758.0
516 1737511200 3328.34 3346.78 3322.0 3343.32 51151860.0
517 1737514800 3343.32 3347.85 3327.2 3330.54 33271698.0
518 1737518400 3330.54 3332.93 3315.84 3331.15 33810516.0
519 1737522000 3331.15 3339.33 3317.01 3317.66 29934040.0
520 1737525600 3317.66 3323.48 3301.61 3308.82 50870486.0
521 1737529200 3308.82 3310.36 3286.18 3287.05 76036546.0
522 1737532800 3286.97 3300.02 3273.0 3298.39 92349262.0
523 1737536400 3298.39 3303.49 3289.1 3297.4 35948534.0
524 1737540000 3297.4 3307.4 3287.82 3306.99 40550278.0
525 1737543600 3306.99 3328.83 3303.3 3325.53 53272540.0
526 1737547200 3325.53 3331.45 3310.14 3315.9 52994384.0
527 1737550800 3315.85 3318.31 3279.25 3283.32 100473366.0
528 1737554400 3283.39 3310.99 3266.7 3292.02 165657884.0
529 1737558000 3292.72 3304.69 3268.95 3277.5 108866836.0
530 1737561600 3277.5 3282.91 3261.0 3277.1 97706330.0
531 1737565200 3277.15 3287.01 3271.02 3284.6 48476310.0
532 1737568800 3284.6 3290.85 3239.08 3248.93 96991712.0
533 1737572400 3249.38 3279.0 3247.52 3261.51 73598538.0
534 1737576000 3261.51 3276.21 3253.01 3255.86 46359000.0
535 1737579600 3255.82 3264.32 3240.0 3258.42 64803018.0
536 1737583200 3258.42 3265.69 3231.89 3237.63 52779412.0
537 1737586800 3237.63 3245.99 3221.53 3241.77 78166668.0
538 1737590400 3241.77 3260.81 3237.04 3252.92 56714310.0
539 1737594000 3252.92 3257.59 3220.0 3234.28 65753656.0
540 1737597600 3234.34 3236.57 3203.23 3222.26 94598842.0
541 1737601200 3222.48 3242.35 3214.38 3225.64 57395280.0
542 1737604800 3225.71 3230.89 3182.66 3196.01 114327136.0
543 1737608400 3196.01 3220.5 3195.34 3213.89 55114374.0
544 1737612000 3213.89 3223.98 3203.26 3207.1 39191160.0
545 1737615600 3207.1 3232.44 3197.39 3231.96 53561668.0
546 1737619200 3231.96 3232.44 3207.44 3209.22 45550378.0
547 1737622800 3209.26 3221.14 3191.13 3195.94 60758744.0
548 1737626400 3195.94 3212.68 3187.34 3203.3 65237070.0
549 1737630000 3203.3 3216.15 3194.82 3212.78 49857888.0
550 1737633600 3212.78 3217.94 3188.52 3202.62 78595334.0
551 1737637200 3202.62 3242.4 3201.12 3233.01 108985424.0
552 1737640800 3232.89 3285.36 3221.81 3274.6 249651856.0
553 1737644400 3274.6 3280.91 3225.01 3258.51 281277612.0
554 1737648000 3258.51 3296.73 3252.0 3253.65 190993782.0
555 1737651600 3253.64 3270.76 3230.02 3264.89 108032146.0
556 1737655200 3264.92 3269.43 3234.0 3239.9 70643910.0
557 1737658800 3239.9 3245.0 3193.09 3203.76 157291960.0
558 1737662400 3203.71 3294.1 3195.86 3246.15 442292904.0
559 1737666000 3246.11 3255.52 3212.77 3247.4 120420326.0
560 1737669600 3247.85 3322.98 3245.19 3321.94 160218202.0
561 1737673200 3321.66 3347.53 3311.27 3337.88 118336168.0
562 1737676800 3337.88 3348.99 3284.11 3284.72 117342552.0
563 1737680400 3284.69 3325.37 3283.51 3297.47 90561650.0
564 1737684000 3297.49 3313.1 3278.58 3284.64 67232158.0
565 1737687600 3285.21 3311.93 3275.0 3301.41 91279686.0
566 1737691200 3301.35 3339.92 3291.13 3332.72 87852684.0
567 1737694800 3332.45 3409.47 3328.55 3409.22 199536164.0
568 1737698400 3409.28 3420.61 3378.01 3385.27 167874148.0
569 1737702000 3385.32 3400.36 3371.39 3380.59 82619272.0
570 1737705600 3380.59 3415.57 3374.6 3400.57 104233816.0
571 1737709200 3400.58 3412.03 3391.01 3400.87 62308630.0
572 1737712800 3400.73 3414.21 3390.53 3412.88 57566642.0
573 1737716400 3412.88 3413.9 3391.8 3398.69 44487372.0
574 1737720000 3398.69 3404.63 3385.41 3403.48 58305470.0
575 1737723600 3403.48 3429.0 3390.25 3394.44 113839350.0
576 1737727200 3394.44 3421.99 3378.04 3398.31 143869564.0
577 1737730800 3398.34 3408.99 3355.0 3382.62 182652482.0
578 1737734400 3382.62 3397.06 3375.88 3379.29 76641652.0
579 1737738000 3379.35 3405.0 3371.76 3396.65 80638944.0
580 1737741600 3396.6 3408.37 3373.79 3380.06 61571938.0
581 1737745200 3380.0 3393.91 3363.16 3367.16 95047310.0
582 1737748800 3367.19 3377.48 3325.47 3327.04 158225220.0
583 1737752400 3327.75 3345.6 3322.22 3328.33 70830146.0
584 1737756000 3328.59 3335.82 3321.01 3324.47 47898010.0
585 1737759600 3324.47 3324.72 3302.5 3309.02 79667410.0
586 1737763200 3309.02 3312.97 3268.32 3272.36 114215218.0
587 1737766800 3272.27 3304.88 3267.35 3292.74 75981114.0
588 1737770400 3292.74 3303.18 3287.86 3293.48 31908786.0
589 1737774000 3293.48 3322.77 3290.52 3318.01 62089274.0
590 1737777600 3318.01 3318.57 3296.69 3298.78 41619704.0
591 1737781200 3298.78 3301.7 3286.6 3295.01 41837638.0
592 1737784800 3295.01 3302.39 3282.57 3290.84 42042506.0
593 1737788400 3290.78 3294.18 3281.83 3289.78 31177086.0
594 1737792000 3289.78 3299.99 3281.43 3289.6 41350052.0
595 1737795600 3289.6 3291.48 3280.0 3282.3 25686474.0
596 1737799200 3282.25 3296.12 3270.4 3294.2 64393426.0
597 1737802800 3294.24 3310.53 3289.62 3305.5 56540872.0
598 1737806400 3305.5 3306.2 3293.02 3304.78 37528022.0
599 1737810000 3304.78 3309.07 3299.01 3306.3 28691106.0
600 1737813600 3306.3 3318.59 3297.0 3314.36 36664870.0
601 1737817200 3314.41 3343.6 3308.42 3333.02 126783138.0
602 1737820800 3332.94 3347.91 3328.7 3341.0 60067516.0
603 1737824400 3341.08 3344.93 3329.09 3343.34 50834736.0
604 1737828000 3343.34 3347.11 3334.0 3340.79 28862350.0
605 1737831600 3340.79 3342.99 3333.01 3338.71 18958684.0
606 1737835200 3338.71 3349.46 3334.15 3335.62 26919424.0
607 1737838800 3335.66 3341.62 3330.89 3338.49 22254066.0
608 1737842400 3338.49 3344.78 3330.72 3332.85 16937198.0
609 1737846000 3332.85 3336.13 3313.36 3317.9 53735534.0
610 1737849600 3317.9 3326.9 3312.38 3319.74 34181402.0
611 1737853200 3319.74 3336.98 3317.18 3330.23 29997596.0
612 1737856800 3330.16 3330.16 3316.39 3327.22 26861986.0
613 1737860400 3327.22 3349.05 3324.99 3337.47 39360420.0
614 1737864000 3337.47 3364.99 3335.0 3350.99 60812656.0
615 1737867600 3350.99 3352.29 3336.82 3341.07 29644874.0
616 1737871200 3341.07 3346.39 3337.0 3340.36 20394300.0
617 1737874800 3340.36 3344.23 3328.67 3337.56 24837804.0
618 1737878400 3337.56 3342.4 3322.11 3330.52 40964058.0
619 1737882000 3330.52 3331.44 3291.46 3297.06 116578472.0
620 1737885600 3297.06 3305.58 3294.6 3304.27 37585964.0
621 1737889200 3304.27 3314.83 3301.35 3310.45 41215532.0
622 1737892800 3310.45 3310.46 3298.41 3306.64 30648776.0
623 1737896400 3306.47 3308.32 3299.05 3306.62 41653970.0
624 1737900000 3306.62 3311.91 3295.61 3309.48 35483260.0
625 1737903600 3309.48 3319.49 3307.06 3313.61 37547550.0
626 1737907200 3313.61 3318.63 3306.37 3314.39 35922004.0
627 1737910800 3314.39 3343.45 3313.81 3336.32 70866966.0
628 1737914400 3336.32 3341.72 3332.34 3335.83 51959942.0
629 1737918000 3335.83 3340.69 3328.77 3337.51 32405448.0
630 1737921600 3337.51 3341.35 3325.55 3328.26 20768510.0
631 1737925200 3328.3 3328.66 3290.68 3295.01 77584126.0
632 1737928800 3294.88 3308.55 3280.01 3286.36 69877756.0
633 1737932400 3286.31 3286.31 3227.47 3230.78 274026736.0
634 1737936000 3230.65 3252.53 3208.01 3212.62 180964884.0
635 1737939600 3212.63 3223.16 3186.86 3194.14 165658226.0
636 1737943200 3193.87 3194.0 3162.32 3169.45 191214386.0
637 1737946800 3169.45 3197.46 3160.24 3182.11 92065924.0
638 1737950400 3182.11 3182.11 3152.65 3155.73 87218334.0
639 1737954000 3155.73 3163.38 3113.02 3139.75 203842944.0
640 1737957600 3139.8 3148.9 3077.81 3082.76 298234274.0
641 1737961200 3082.76 3090.27 3020.93 3069.26 415672338.0
642 1737964800 3069.11 3071.81 3037.23 3064.19 162267474.0
643 1737968400 3064.24 3088.9 3056.92 3079.48 119649952.0
644 1737972000 3079.48 3080.18 3032.7 3037.11 115805844.0
645 1737975600 3037.05 3074.22 3036.34 3057.48 90659514.0
646 1737979200 3057.48 3121.61 3052.14 3101.53 187794412.0
647 1737982800 3101.47 3133.28 3087.85 3097.86 231867426.0
648 1737986400 3097.86 3144.83 3081.86 3136.15 203057890.0
649 1737990000 3135.72 3150.8 3110.7 3131.09 147629814.0
650 1737993600 3131.97 3132.04 3074.43 3083.0 203328436.0
651 1737997200 3082.95 3098.11 3065.24 3071.53 114566258.0
652 1738000800 3071.57 3087.79 3045.3 3053.88 103725792.0
653 1738004400 3053.91 3080.93 3053.91 3074.89 83541122.0
654 1738008000 3074.89 3147.82 3071.83 3145.22 143522924.0
655 1738011600 3143.97 3237.99 3141.23 3158.16 299739690.0
656 1738015200 3158.16 3180.06 3145.0 3169.25 79707278.0
657 1738018800 3169.25 3181.44 3158.71 3180.75 56318916.0
658 1738022400 3180.79 3202.51 3163.01 3166.22 77481438.0
659 1738026000 3166.27 3175.57 3150.31 3165.28 59624336.0
660 1738029600 3164.96 3198.41 3164.14 3191.6 59293696.0
661 1738033200 3191.56 3216.86 3174.1 3201.47 109284848.0
662 1738036800 3201.47 3221.53 3196.11 3210.64 83876044.0
663 1738040400 3210.67 3220.69 3207.19 3211.69 44259070.0
664 1738044000 3211.69 3214.02 3190.44 3193.55 48991426.0
665 1738047600 3193.43 3214.7 3187.51 3194.62 50038618.0
666 1738051200 3194.62 3204.1 3182.01 3197.47 81225676.0
667 1738054800 3197.42 3200.58 3183.0 3195.72 38138356.0
668 1738058400 3195.72 3206.32 3187.84 3192.87 39941280.0
669 1738062000 3192.87 3199.56 3175.47 3185.2 39874048.0
670 1738065600 3185.2 3194.62 3165.52 3173.72 60379984.0
671 1738069200 3173.64 3188.0 3169.01 3174.14 39825956.0
672 1738072800 3174.14 3179.53 3156.0 3171.09 125274148.0
673 1738076400 3171.34 3213.44 3169.55 3180.15 145496580.0
674 1738080000 3180.15 3181.81 3130.72 3149.59 141098534.0
675 1738083600 3149.46 3181.56 3149.05 3166.11 107192478.0
676 1738087200 3166.07 3176.76 3139.18 3142.6 67871000.0
677 1738090800 3142.6 3149.32 3118.98 3146.4 100694056.0
678 1738094400 3146.48 3153.45 3092.03 3094.31 134835852.0
679 1738098000 3093.42 3113.6 3051.32 3052.43 169849482.0
680 1738101600 3052.32 3089.94 3038.2 3082.86 165296122.0
681 1738105200 3082.93 3095.01 3052.51 3075.96 82801056.0
682 1738108800 3075.96 3116.55 3075.12 3108.9 1274170.0
683 1738112400 3108.85 3119.0 3097.82 3109.31 1144288.0
684 1738116000 3109.31 3128.3 3108.69 3112.81 4755046.0
685 1738119600 3112.74 3131.26 3106.65 3129.02 44437084.0
686 1738123200 3129.04 3138.89 3121.51 3122.94 51333698.0
687 1738126800 3122.87 3133.32 3115.46 3129.66 45341342.0
688 1738130400 3129.66 3148.96 3127.16 3145.88 60770492.0
689 1738134000 3145.88 3158.0 3137.4 3155.64 54759780.0
690 1738137600 3155.64 3162.68 3143.0 3146.4 48938372.0
691 1738141200 3146.4 3147.23 3121.93 3129.27 68754366.0
692 1738144800 3129.27 3142.05 3119.65 3136.48 46871668.0
693 1738148400 3136.48 3142.08 3130.31 3133.64 37915812.0
694 1738152000 3133.64 3138.84 3112.15 3117.69 73520948.0
695 1738155600 3117.69 3120.73 3087.77 3100.83 123395826.0
696 1738159200 3100.81 3115.17 3079.41 3095.1 130122046.0
697 1738162800 3095.81 3117.95 3092.7 3099.65 80143028.0

View File

@@ -1,172 +0,0 @@
# -*- coding: utf-8 -*-
"""
Bitmart 多周期K线数据抓取 - 供回测与实盘使用
与 bitmart/回测.py、bitmart/抓取多周期K线.py 相同的 API 调用方式
"""
import time
import csv
import os
from typing import List, Dict, Optional
try:
from loguru import logger
except ImportError:
import logging
logger = logging.getLogger(__name__)
# 项目根目录为 lm_codebitmart 包在根目录
import sys
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_DIR = os.path.dirname(SCRIPT_DIR)
if ROOT_DIR not in sys.path:
sys.path.insert(0, ROOT_DIR)
# 默认 API与 bitmart/回测.py 一致,回测仅拉数据可不填有效 key
# APIContract 在 fetch_klines / fetch_multi_timeframe 内按需导入,以便 --no-api 回测不依赖 bitmart
DEFAULT_API_KEY = "a0fb7b98464fd9bcce67e7c519d58ec10d0c38a8"
DEFAULT_SECRET_KEY = "4eaeba78e77aeaab1c2027f846a276d164f264a44c2c1bb1c5f3be50c8de1ca5"
DEFAULT_MEMO = "合约交易"
CONTRACT_SYMBOL = "ETHUSDT"
def _format_bar(k: dict) -> dict:
"""API 单根K线 -> 统一格式id 为秒时间戳"""
return {
"id": int(k["timestamp"]),
"open": float(k["open_price"]),
"high": float(k["high_price"]),
"low": float(k["low_price"]),
"close": float(k["close_price"]),
"volume": float(k.get("volume", 0)),
}
def fetch_klines(
contract_api: "APIContract",
step: int,
start_time: int,
end_time: int,
symbol: str = CONTRACT_SYMBOL,
) -> List[Dict]:
"""
拉取指定周期的K线与 bitmart 回测抓取方式一致)。
:param contract_api: bitmart.api_contract.APIContract 实例
:param step: K线周期分钟如 5/15/60
:param start_time: 开始时间戳(秒)
:param end_time: 结束时间戳(秒)
:param symbol: 合约符号
:return: [{"id", "open", "high", "low", "close", "volume"}, ...],按 id 升序
"""
all_data: List[Dict] = []
existing_ids = set()
request_interval = step * 60 * 500 # 每次最多约 500 根
current_start = start_time
while current_start < end_time:
current_end = min(current_start + request_interval, end_time)
try:
response = contract_api.get_kline(
contract_symbol=symbol,
step=step,
start_time=current_start,
end_time=current_end,
)[0]
if response.get("code") != 1000:
logger.warning(f"get_kline code={response.get('code')}, msg={response.get('msg')}")
time.sleep(1)
current_start = current_end
continue
data = response.get("data", [])
except Exception as e:
logger.warning(f"get_kline 异常 step={step} {e}60秒后重试")
time.sleep(60)
continue
for k in data:
k_id = int(k["timestamp"])
if k_id in existing_ids:
continue
existing_ids.add(k_id)
all_data.append(_format_bar(k))
if len(data) < 500:
current_start = current_end
else:
all_data.sort(key=lambda x: x["id"])
current_start = all_data[-1]["id"] + 1
time.sleep(0.25)
all_data.sort(key=lambda x: x["id"])
return all_data
def fetch_multi_timeframe(
start_time: int,
end_time: int,
steps: List[int] = None,
api_key: str = DEFAULT_API_KEY,
secret_key: str = DEFAULT_SECRET_KEY,
memo: str = DEFAULT_MEMO,
symbol: str = CONTRACT_SYMBOL,
) -> Dict[int, List[Dict]]:
"""
拉取多周期K线5/15/60供回测使用。
:return: { step: [kline_list] }
"""
steps = steps or [5, 15, 60]
from bitmart.api_contract import APIContract
api = APIContract(api_key, secret_key, memo, timeout=(5, 15))
result = {}
for step in steps:
logger.info(f"抓取 {step} 分钟 K 线: {start_time} ~ {end_time}")
result[step] = fetch_klines(api, step, start_time, end_time, symbol)
logger.info(f" -> {len(result[step])}")
return result
def save_klines_csv(klines: List[Dict], path: str) -> None:
"""将K线保存为 CSVid, open, high, low, close, volume"""
if not klines:
return
cols = ["id", "open", "high", "low", "close", "volume"]
with open(path, "w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=cols)
w.writeheader()
for row in klines:
w.writerow({k: row.get(k) for k in cols})
logger.info(f"已保存 {len(klines)} 条到 {path}")
def load_klines_csv(path: str) -> List[Dict]:
"""从 CSV 加载K线"""
if not os.path.isfile(path):
return []
with open(path, "r", encoding="utf-8") as f:
r = csv.DictReader(f)
rows = list(r)
out = []
for row in rows:
out.append({
"id": int(row["id"]),
"open": float(row["open"]),
"high": float(row["high"]),
"low": float(row["low"]),
"close": float(row["close"]),
"volume": float(row.get("volume", 0)),
})
out.sort(key=lambda x: x["id"])
return out
if __name__ == "__main__":
import datetime
# 示例:拉取最近约 30 天 5/15/60 分钟数据并保存
end_ts = int(time.time())
start_ts = end_ts - 30 * 24 * 3600
data_dir = os.path.join(SCRIPT_DIR, "data")
os.makedirs(data_dir, exist_ok=True)
data = fetch_multi_timeframe(start_ts, end_ts, steps=[5, 15, 60])
for step, klines in data.items():
path = os.path.join(data_dir, f"kline_{step}m.csv")
save_klines_csv(klines, path)

View File

@@ -1,86 +0,0 @@
# -*- coding: utf-8 -*-
"""
技术指标EMA、ATR
"""
from typing import List, Dict, Optional
def ema(series: List[float], period: int) -> List[Optional[float]]:
"""EMA(period),前 period-1 个为 None"""
if not series or period < 1:
return []
k = 2.0 / (period + 1)
out: List[Optional[float]] = [None] * (period - 1)
s = sum(series[:period])
out.append(s / period)
for i in range(period, len(series)):
val = series[i] * k + out[-1] * (1 - k) # type: ignore
out.append(val)
return out
def atr(high: List[float], low: List[float], close: List[float], period: int) -> List[Optional[float]]:
"""ATR(period),前 period 个为 None"""
n = len(close)
if n < period + 1 or len(high) != n or len(low) != n:
return [None] * n
tr_list: List[float] = []
for i in range(n):
if i == 0:
tr_list.append(high[0] - low[0])
else:
tr = max(
high[i] - low[i],
abs(high[i] - close[i - 1]),
abs(low[i] - close[i - 1])
)
tr_list.append(tr)
return ema(tr_list, period)
def get_ema_atr_from_klines(klines: List[Dict], ema_period: int, atr_period: int
) -> tuple:
"""
从K线列表计算收盘价 EMA 和 ATR。
返回 (ema_list, atr_list),长度与 klines 一致。
"""
close = [float(k["close"]) for k in klines]
high = [float(k["high"]) for k in klines]
low = [float(k["low"]) for k in klines]
ema_list = ema(close, ema_period)
atr_list = atr(high, low, close, atr_period)
return ema_list, atr_list
def align_higher_tf_ema(
klines_5m: List[Dict],
klines_higher: List[Dict],
ema_fast: int,
ema_slow: int
) -> List[Dict]:
"""
根据更高周期K线计算 EMA并按 5 分钟时间对齐。
返回列表长度与 klines_5m 一致,每项为 {"ema_fast": float, "ema_slow": float} 或 None。
"""
if not klines_higher or len(klines_higher) < ema_slow:
return [{}] * len(klines_5m)
close_hi = [float(k["close"]) for k in klines_higher]
ema_f = ema(close_hi, ema_fast)
ema_s = ema(close_hi, ema_slow)
id_hi = [k["id"] for k in klines_higher]
result = []
for k5 in klines_5m:
t = k5["id"]
# 当前 5m 时刻所属的更高周期:取 <= t 的最后一根
idx = -1
for i, tid in enumerate(id_hi):
if tid <= t:
idx = i
else:
break
if idx >= ema_slow - 1 and ema_f[idx] is not None and ema_s[idx] is not None:
result.append({"ema_fast": ema_f[idx], "ema_slow": ema_s[idx]})
else:
result.append({})
return result

View File

@@ -1,305 +0,0 @@
# -*- coding: utf-8 -*-
"""
自适应三分位趋势策略 - 核心逻辑
趋势过滤、动态阈值、信号确认、市场状态
"""
from typing import List, Dict, Optional, Tuple
import sys
import os
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if ROOT_DIR not in sys.path:
sys.path.insert(0, ROOT_DIR)
from adaptive_third_strategy.config import (
MIN_BODY_ATR_RATIO,
MIN_VOLATILITY_PERCENT,
EMA_SHORT,
EMA_LONG_FAST,
EMA_LONG_SLOW,
EMA_MID_FAST,
EMA_MID_SLOW,
ATR_PERIOD,
VOLATILITY_COEF_CLAMP,
BASE_COEF,
TREND_FAVOR_COEF,
TREND_AGAINST_COEF,
TREND_MODE,
CONFIRM_REQUIRED,
VOLUME_MA_PERIOD,
VOLUME_RATIO_THRESHOLD,
REVERSE_BREAK_MULT,
MIN_BARS_SINCE_ENTRY,
FORBIDDEN_PERIODS,
ATR_PAUSE_MULT,
STRONG_TREND_COEF,
RANGE_COEF,
HIGH_VOL_EXTRA_CONFIRM,
)
from adaptive_third_strategy.indicators import (
get_ema_atr_from_klines,
align_higher_tf_ema,
ema,
)
def get_body_size(candle: Dict) -> float:
return abs(float(candle["open"]) - float(candle["close"]))
def is_bullish(candle: Dict) -> bool:
return float(candle["close"]) > float(candle["open"])
def get_min_body_threshold(price: float, atr_value: Optional[float]) -> float:
"""有效K线最小实体 = max(ATR*0.1, 价格*0.05%)"""
min_vol = price * MIN_VOLATILITY_PERCENT
if atr_value is not None and atr_value > 0:
min_vol = max(min_vol, atr_value * MIN_BODY_ATR_RATIO)
return min_vol
def find_valid_prev_bar(
all_data: List[Dict],
current_idx: int,
atr_series: List[Optional[float]],
min_body_override: Optional[float] = None,
) -> Tuple[Optional[int], Optional[Dict]]:
"""从当前索引往前找实体>=阈值的K线。阈值 = max(ATR*0.1, 价格*0.05%)"""
if current_idx <= 0:
return None, None
for i in range(current_idx - 1, -1, -1):
prev = all_data[i]
body = get_body_size(prev)
price = float(prev["close"])
atr_val = atr_series[i] if i < len(atr_series) else None
th = min_body_override if min_body_override is not None else get_min_body_threshold(price, atr_val)
if body >= th:
return i, prev
return None, None
def get_trend(
klines_5m: List[Dict],
idx_5m: int,
ema_5m: List[Optional[float]],
ema_15m_align: List[Dict],
ema_60m_align: List[Dict],
) -> str:
"""
多时间框架趋势。返回 "long" / "short" / "neutral"
长期1h EMA50 vs EMA200中期15m EMA20 vs EMA50短期5m close vs EMA9。
ema_*_align: 与 5m 对齐的列表,每项 {"ema_fast", "ema_slow"}。
"""
if idx_5m >= len(klines_5m):
return "neutral"
curr = klines_5m[idx_5m]
close_5 = float(curr["close"])
# 短期
ema9 = ema_5m[idx_5m] if idx_5m < len(ema_5m) else None
short_bull = (ema9 is not None and close_5 > ema9)
# 中期
mid = ema_15m_align[idx_5m] if idx_5m < len(ema_15m_align) else {}
mid_bull = (mid.get("ema_fast") is not None and mid.get("ema_slow") is not None
and mid["ema_fast"] > mid["ema_slow"])
# 长期
long_d = ema_60m_align[idx_5m] if idx_5m < len(ema_60m_align) else {}
long_bull = (long_d.get("ema_fast") is not None and long_d.get("ema_slow") is not None
and long_d["ema_fast"] > long_d["ema_slow"])
if TREND_MODE == "aggressive":
return "long" if short_bull else "short"
if TREND_MODE == "conservative":
if mid_bull and short_bull:
return "long"
if not mid_bull and not short_bull:
return "short"
return "neutral"
# strict
if long_bull and mid_bull and short_bull:
return "long"
if not long_bull and not mid_bull and not short_bull:
return "short"
return "neutral"
def get_dynamic_trigger_levels(
prev: Dict,
atr_value: float,
trend: str,
market_state: str = "normal",
) -> Tuple[Optional[float], Optional[float]]:
"""
动态三分位触发价。
波动率系数 = clamp(实体/ATR, 0.3, 3.0),调整系数 = 0.33 * 波动率系数。
顺势方向 ×0.8,逆势 ×1.2。
"""
body = get_body_size(prev)
if body < 1e-6 or atr_value <= 0:
return None, None
vol_coef = body / atr_value
vol_coef = max(VOLATILITY_COEF_CLAMP[0], min(VOLATILITY_COEF_CLAMP[1], vol_coef))
adj = BASE_COEF * vol_coef
if market_state == "strong_trend":
adj = STRONG_TREND_COEF
elif market_state == "range":
adj = RANGE_COEF
p_close = float(prev["close"])
if trend == "long":
long_adj = adj * TREND_FAVOR_COEF
short_adj = adj * TREND_AGAINST_COEF
elif trend == "short":
long_adj = adj * TREND_AGAINST_COEF
short_adj = adj * TREND_FAVOR_COEF
else:
long_adj = short_adj = adj
long_trigger = p_close + body * long_adj
short_trigger = p_close - body * short_adj
return long_trigger, short_trigger
def check_signal_confirm(
curr: Dict,
direction: str,
trigger_price: float,
all_data: List[Dict],
current_idx: int,
volume_ma: Optional[float],
required: int = CONFIRM_REQUIRED,
) -> int:
"""
确认条件计数:收盘价确认、成交量确认、动量确认。
返回满足的个数。
"""
count = 0
c_close = float(curr["close"])
c_volume = float(curr.get("volume", 0))
# 1. 收盘价确认
if direction == "long" and c_close >= trigger_price:
count += 1
elif direction == "short" and c_close <= trigger_price:
count += 1
# 2. 成交量确认
if volume_ma is not None and volume_ma > 0 and c_volume >= volume_ma * VOLUME_RATIO_THRESHOLD:
count += 1
# 3. 动量确认当前K线实体方向与信号一致
if direction == "long" and is_bullish(curr):
count += 1
elif direction == "short" and not is_bullish(curr):
count += 1
return count
def in_forbidden_period(ts_sec: int) -> bool:
"""是否在禁止交易时段(按 UTC+8 小时:分)"""
from datetime import datetime, timezone
try:
dt = datetime.fromtimestamp(ts_sec, tz=timezone.utc)
except Exception:
dt = datetime.utcfromtimestamp(ts_sec)
# 转 UTC+8
hour = (dt.hour + 8) % 24
minute = dt.minute
for h1, m1, h2, m2 in FORBIDDEN_PERIODS:
t1 = h1 * 60 + m1
t2 = h2 * 60 + m2
t = hour * 60 + minute
if t1 <= t < t2:
return True
return False
def get_market_state(
atr_value: float,
atr_avg: Optional[float],
trend: str,
) -> str:
"""normal / strong_trend / range / high_vol"""
if atr_avg is not None and atr_avg > 0 and atr_value >= atr_avg * ATR_PAUSE_MULT:
return "high_vol"
if trend in ("long", "short") and atr_avg is not None and atr_value > atr_avg * 1.2:
return "strong_trend"
if trend == "neutral":
return "range"
return "normal"
def check_trigger(
all_data: List[Dict],
current_idx: int,
atr_series: List[Optional[float]],
ema_5m: List[Optional[float]],
ema_15m_align: List[Dict],
ema_60m_align: List[Dict],
volume_ma_list: Optional[List[Optional[float]]] = None,
use_confirm: bool = True,
) -> Tuple[Optional[str], Optional[float], Optional[int], Optional[Dict]]:
"""
检查当前K线是否产生有效信号含趋势过滤与确认
返回 (方向, 触发价, 有效前一根索引, 有效前一根K线) 或 (None, None, None, None)。
"""
if current_idx <= 0 or current_idx >= len(all_data):
return None, None, None, None
curr = all_data[current_idx]
valid_prev_idx, prev = find_valid_prev_bar(all_data, current_idx, atr_series)
if prev is None:
return None, None, None, None
atr_val = atr_series[current_idx] if current_idx < len(atr_series) else None
if atr_val is None or atr_val <= 0:
return None, None, None, None
trend = get_trend(
all_data, current_idx, ema_5m, ema_15m_align, ema_60m_align,
)
atr_avg = None
if atr_series:
valid_atr = [x for x in atr_series[: current_idx + 1] if x is not None and x > 0]
if len(valid_atr) >= ATR_PERIOD:
atr_avg = sum(valid_atr) / len(valid_atr)
market_state = get_market_state(atr_val, atr_avg, trend)
if market_state == "high_vol":
return None, None, None, None
long_trigger, short_trigger = get_dynamic_trigger_levels(prev, atr_val, trend, market_state)
if long_trigger is None:
return None, None, None, None
c_high = float(curr["high"])
c_low = float(curr["low"])
long_triggered = c_high >= long_trigger
short_triggered = c_low <= short_trigger
direction = None
trigger_price = None
if long_triggered and short_triggered:
c_open = float(curr["open"])
if abs(c_open - short_trigger) <= abs(c_open - long_trigger):
direction, trigger_price = "short", short_trigger
else:
direction, trigger_price = "long", long_trigger
elif short_triggered:
direction, trigger_price = "short", short_trigger
elif long_triggered:
direction, trigger_price = "long", long_trigger
if direction is None:
return None, None, None, None
# 趋势过滤:逆势不交易(可选,这里做过滤)
if trend == "long" and direction == "short":
return None, None, None, None
if trend == "short" and direction == "long":
return None, None, None, None
# 禁止时段
if in_forbidden_period(curr["id"]):
return None, None, None, None
# 信号确认
if use_confirm and CONFIRM_REQUIRED > 0:
vol_ma = volume_ma_list[current_idx] if volume_ma_list and current_idx < len(volume_ma_list) else None
n = check_signal_confirm(curr, direction, trigger_price, all_data, current_idx, vol_ma, CONFIRM_REQUIRED)
if n < CONFIRM_REQUIRED:
return None, None, None, None
return direction, trigger_price, valid_prev_idx, prev
def build_volume_ma(klines: List[Dict], period: int = VOLUME_MA_PERIOD) -> List[Optional[float]]:
"""前 period-1 为 None之后为 volume 的 SMA"""
vol = [float(k.get("volume", 0)) for k in klines]
out: List[Optional[float]] = [None] * (period - 1)
for i in range(period - 1, len(vol)):
out.append(sum(vol[i - period + 1 : i + 1]) / period)
return out

View File

@@ -1,187 +0,0 @@
# -*- coding: utf-8 -*-
"""
自适应三分位趋势策略 - 实盘交易
拉取 Bitmart 5/15/60 分钟数据,计算信号,执行开平仓(沿用 交易/bitmart-三分之一策略交易 的浏览器/API 逻辑)
"""
import os
import sys
import time
import datetime
from typing import List, Dict, Optional, Tuple
try:
from loguru import logger
except ImportError:
import logging
logger = logging.getLogger(__name__)
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if ROOT_DIR not in sys.path:
sys.path.insert(0, ROOT_DIR)
from bitmart.api_contract import APIContract
from adaptive_third_strategy.config import (
STEP_5M,
STEP_15M,
STEP_60M,
ATR_PERIOD,
EMA_SHORT,
EMA_MID_FAST,
EMA_MID_SLOW,
EMA_LONG_FAST,
EMA_LONG_SLOW,
BASE_POSITION_PERCENT,
MAX_POSITION_PERCENT,
CONTRACT_SYMBOL,
)
from adaptive_third_strategy.indicators import get_ema_atr_from_klines, align_higher_tf_ema
from adaptive_third_strategy.strategy_core import check_trigger, build_volume_ma
from adaptive_third_strategy.data_fetcher import fetch_klines, _format_bar
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
class AdaptiveThirdStrategyTrader:
"""实盘获取多周期K线 -> 策略信号 -> 开平仓(可接浏览器或纯 API"""
def __init__(
self,
api_key: str,
secret_key: str,
memo: str = "合约交易",
symbol: str = CONTRACT_SYMBOL,
bit_id: Optional[str] = None,
):
self.api_key = api_key
self.secret_key = secret_key
self.memo = memo
self.symbol = symbol
self.bit_id = bit_id
self.contractAPI = APIContract(api_key, secret_key, memo, timeout=(5, 15))
self.check_interval = 3
self.last_trigger_kline_id: Optional[int] = None
self.last_trigger_direction: Optional[str] = None
self.last_trade_kline_id: Optional[int] = None
self.position_direction: int = 0 # 1 多 -1 空 0 无
def get_klines_multi(self) -> Tuple[List[Dict], List[Dict], List[Dict]]:
"""拉取当前 5/15/60 分钟 K 线(最近约 3 小时足够算 EMA/ATR"""
end_ts = int(time.time())
start_ts = end_ts - 3600 * 3
k5 = fetch_klines(self.contractAPI, STEP_5M, start_ts, end_ts, self.symbol)
k15 = fetch_klines(self.contractAPI, STEP_15M, start_ts, end_ts, self.symbol)
k60 = fetch_klines(self.contractAPI, STEP_60M, start_ts, end_ts, self.symbol)
return k5, k15, k60
def get_position_status(self) -> bool:
"""查询当前持仓,更新 self.position_direction"""
try:
response = self.contractAPI.get_position(contract_symbol=self.symbol)[0]
if response.get("code") != 1000:
return False
positions = response.get("data", [])
if not positions:
self.position_direction = 0
return True
self.position_direction = 1 if positions[0].get("position_type") == 1 else -1
return True
except Exception as e:
logger.error(f"持仓查询异常: {e}")
return False
def check_realtime_signal(
self,
klines_5m: List[Dict],
klines_15m: List[Dict],
klines_60m: List[Dict],
) -> Tuple[Optional[str], Optional[float], Optional[Dict]]:
"""
基于当前 K 线(最后一根未收盘)检测实时信号。
返回 (方向, 触发价, 当前K线) 或 (None, None, None)。
"""
if len(klines_5m) < ATR_PERIOD + 2:
return None, None, None
from adaptive_third_strategy.indicators import get_ema_atr_from_klines
from adaptive_third_strategy.strategy_core import check_trigger
ema_5m, atr_5m = get_ema_atr_from_klines(klines_5m, EMA_SHORT, ATR_PERIOD)
ema_15m_align = align_higher_tf_ema(klines_5m, klines_15m, EMA_MID_FAST, EMA_MID_SLOW)
ema_60m_align = align_higher_tf_ema(klines_5m, klines_60m, EMA_LONG_FAST, EMA_LONG_SLOW)
volume_ma = build_volume_ma(klines_5m)
curr_idx = len(klines_5m) - 1
direction, trigger_price, _, _ = check_trigger(
klines_5m, curr_idx, atr_5m, ema_5m, ema_15m_align, ema_60m_align, volume_ma, use_confirm=True
)
curr = klines_5m[curr_idx]
curr_id = curr["id"]
if direction is None:
return None, None, None
if self.last_trigger_kline_id == curr_id and self.last_trigger_direction == direction:
return None, None, None
if self.last_trade_kline_id == curr_id:
return None, None, None
if (direction == "long" and self.position_direction == 1) or (direction == "short" and self.position_direction == -1):
return None, None, None
return direction, trigger_price, curr
def run_loop(self, ding_callback=None):
"""
主循环:拉数据 -> 检测信号 -> 若需交易则调用开平仓(需外部实现或注入)。
ding_callback(msg, error=False) 可选,用于钉钉通知。
"""
def ding(msg: str, error: bool = False):
if ding_callback:
ding_callback(msg, error)
else:
if error:
logger.error(msg)
else:
logger.info(msg)
logger.info("自适应三分位趋势策略实盘启动,按 Bitmart 方式拉取 5/15/60 分钟数据")
while True:
try:
k5, k15, k60 = self.get_klines_multi()
if len(k5) < ATR_PERIOD + 2:
time.sleep(self.check_interval)
continue
if not self.get_position_status():
time.sleep(self.check_interval)
continue
direction, trigger_price, curr = self.check_realtime_signal(k5, k15, k60)
if direction and trigger_price is not None and curr is not None:
curr_id = curr["id"]
ding(f"信号: {direction} @ {trigger_price:.2f} 当前K线 id={curr_id}")
# 这里接入你的开平仓实现:平仓 + 开单(可调用 交易/bitmart-三分之一策略交易 的 平仓/开单 或 API 下单)
# 示例:仅记录,不实际下单
self.last_trigger_kline_id = curr_id
self.last_trigger_direction = direction
self.last_trade_kline_id = curr_id
time.sleep(self.check_interval)
except Exception as e:
logger.exception(e)
time.sleep(60)
def main():
import argparse
parser = argparse.ArgumentParser(description="自适应三分位趋势策略实盘")
parser.add_argument("--api-key", default="", help="Bitmart API Key")
parser.add_argument("--secret-key", default="", help="Bitmart Secret Key")
parser.add_argument("--bit-id", default="", help="比特浏览器 ID若用浏览器下单")
args = parser.parse_args()
api_key = args.api_key or os.environ.get("BITMART_API_KEY", "a0fb7b98464fd9bcce67e7c519d58ec10d0c38a8")
secret_key = args.secret_key or os.environ.get("BITMART_SECRET_KEY", "4eaeba78e77aeaab1c2027f846a276d164f264a44c2c1bb1c5f3be50c8de1ca5")
trader = AdaptiveThirdStrategyTrader(api_key, secret_key, bit_id=args.bit_id or None)
try:
from 交易.tools import send_dingtalk_message
def ding(msg, error=False):
prefix = "❌自适应三分位:" if error else "🔔自适应三分位:"
send_dingtalk_message(f"{prefix}{msg}")
except Exception:
def ding(msg, error=False):
logger.info(msg)
trader.run_loop(ding_callback=ding)
if __name__ == "__main__":
main()

View File

@@ -1,139 +0,0 @@
import requests
import datetime
cookies = {
'bitget_lang': 'zh-CN',
'_dx_kvani5r': '24e0dceb12f85d9a1279183ca29c09f772f8c61124e4eca228d8dd909c9b24b0019c2b9a',
'OptanonAlertBoxClosed': 'Wed%20Sep%2024%202025%2017:12:32%20GMT+0800%20(%E4%B8%AD%E5%9B%BD%E6%A0%87%E5%87%86%E6%97%B6%E9%97%B4)',
'OptanonConsent': 'isMarketing=1&isStatistic=1',
'_cfuvid': 'IHXjOVVjx5iewfwL1nrgeHsZ6whu9s4iYYYvNvJvOQM-1758867462928-0.0.1.1-604800000',
'dy_token': '68d630093VQFDNL1nUkv46lfDdhjHGYpoz9dddX1',
'g_state': '{"i_l":0}',
'theme': 'white',
'BITGET_LOCAL_COOKIE': '{%22bitget_lang%22:%22zh-CN%22%2C%22bitget_unit%22:%22CNY%22%2C%22bitget_showasset%22:true%2C%22bitget_theme%22:%22white%22%2C%22bitget_layout%22:%22right%22%2C%22bitget_valuationunit%22:0%2C%22bitget_valuationunit_new%22:1%2C%22bitget_valuationunitandfiat%22:1%2C%22bitgt_login%22:false%2C%22theme%22:%22black%22%2C%22brand_simulation_trade%22:false%2C%22bitget_currency%22:%22%22}',
'bt_rtoken': 'upex:session:id:1d00ce6487e37f4d7230a5aafe3ffc82e799156a86e9778bacb2310c7cf39b98',
'bt_uid': '619BB9EC4D4A3F9FC1AC092D38818A00',
'bt_sessonid': '0bf4ef42-798c-4f8d-8fe5-c07364d3b6b5',
'bt_newsessionid': 'eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ZjJmNDBjYS0zNTkyLTRiNmItOTdiMy01OWQ5MTU5Y2E2YmQ0NzQ5ODIwMTAiLCJ1aWQiOiIxV00rVjRqcTJYSVRQemdJVWhUMnNRPT0iLCJzdWIiOiJsenoqKipvbSIsImlwIjoiM3dNK05yTkxjQXVQTG95dWZkWkI1QT09IiwiZGlkIjoiSjBZZjQ1NkV5RUxaSGhaa2tWYnNQZTVlSFVYYUNKZS9CM21wTHJ5SHJWMTEyUklzWlFLTTVIQmtTNHlUUmhuVyIsInN0cyI6MCwiaWF0IjoxNzU4ODY3NTgxLCJleHAiOjE3NTkyOTk1ODEsInB1c2hpZCI6ImRka1NMR1VDak9Sd1pFdU1rMFlaMWc9PSIsImlzcyI6InVwZXgifQ.Buwhs7UF7dOnOAso8l-RIyc_A47UdWSeVMiwIonOdiY',
'USD': 'CNY',
'__cf_bm': '3AMy5P3a.qp5uEqe9d_DonCDcL621CKULNKaUpfn2rE-1758868368-1.0.1.1-JzjFQidqwDxVV3gJH8ls0NeCGe.nsK.SFYP0hPXUcupuLTBpscmBYQRMfAjeOlnaZRBsQROFL2fETfXatDwQwDHU7aHOT4IMwECKB3sTIN4',
}
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh,zh-CN;q=0.9,zh-HK;q=0.8,en;q=0.7',
'baggage': 'sentry-environment=online,sentry-release=905e3a416e2b0ad3c98a82ab9b94dd87f1a5c1fd,sentry-public_key=8aeef93d782e4ef5ae75634bfee9b590,sentry-trace_id=e7afec8af26a4480893c8b58257af49b',
'cache-control': 'no-cache',
'custom-token': '765eb29bf89843258756f8851ed5a48f',
'deviceid': '7c88d47fdc39e5c422eff197b10d3485',
'dy-token': '68d630093VQFDNL1nUkv46lfDdhjHGYpoz9dddX1',
'language': 'zh_CN',
'locale': 'zh_CN',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://www.bitget.com/zh-CN/futures/usdt/ETHUSDT',
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'sentry-trace': 'e7afec8af26a4480893c8b58257af49b-8aacec1747b38bd7-0',
'terminalcode': 'cc98a9dd01af7e2d50d9b9858723b25e',
'terminaltype': '1',
'tm': '1758868503025',
'uhti': 'w17588685039139806ab12716',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36',
'website': 'mix',
# 'cookie': 'bitget_lang=zh-CN; _dx_kvani5r=24e0dceb12f85d9a1279183ca29c09f772f8c61124e4eca228d8dd909c9b24b0019c2b9a; OptanonAlertBoxClosed=Wed%20Sep%2024%202025%2017:12:32%20GMT+0800%20(%E4%B8%AD%E5%9B%BD%E6%A0%87%E5%87%86%E6%97%B6%E9%97%B4); OptanonConsent=isMarketing=1&isStatistic=1; _cfuvid=IHXjOVVjx5iewfwL1nrgeHsZ6whu9s4iYYYvNvJvOQM-1758867462928-0.0.1.1-604800000; dy_token=68d630093VQFDNL1nUkv46lfDdhjHGYpoz9dddX1; g_state={"i_l":0}; theme=white; BITGET_LOCAL_COOKIE={%22bitget_lang%22:%22zh-CN%22%2C%22bitget_unit%22:%22CNY%22%2C%22bitget_showasset%22:true%2C%22bitget_theme%22:%22white%22%2C%22bitget_layout%22:%22right%22%2C%22bitget_valuationunit%22:0%2C%22bitget_valuationunit_new%22:1%2C%22bitget_valuationunitandfiat%22:1%2C%22bitgt_login%22:false%2C%22theme%22:%22black%22%2C%22brand_simulation_trade%22:false%2C%22bitget_currency%22:%22%22}; bt_rtoken=upex:session:id:1d00ce6487e37f4d7230a5aafe3ffc82e799156a86e9778bacb2310c7cf39b98; bt_uid=619BB9EC4D4A3F9FC1AC092D38818A00; bt_sessonid=0bf4ef42-798c-4f8d-8fe5-c07364d3b6b5; bt_newsessionid=eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ZjJmNDBjYS0zNTkyLTRiNmItOTdiMy01OWQ5MTU5Y2E2YmQ0NzQ5ODIwMTAiLCJ1aWQiOiIxV00rVjRqcTJYSVRQemdJVWhUMnNRPT0iLCJzdWIiOiJsenoqKipvbSIsImlwIjoiM3dNK05yTkxjQXVQTG95dWZkWkI1QT09IiwiZGlkIjoiSjBZZjQ1NkV5RUxaSGhaa2tWYnNQZTVlSFVYYUNKZS9CM21wTHJ5SHJWMTEyUklzWlFLTTVIQmtTNHlUUmhuVyIsInN0cyI6MCwiaWF0IjoxNzU4ODY3NTgxLCJleHAiOjE3NTkyOTk1ODEsInB1c2hpZCI6ImRka1NMR1VDak9Sd1pFdU1rMFlaMWc9PSIsImlzcyI6InVwZXgifQ.Buwhs7UF7dOnOAso8l-RIyc_A47UdWSeVMiwIonOdiY; USD=CNY; __cf_bm=3AMy5P3a.qp5uEqe9d_DonCDcL621CKULNKaUpfn2rE-1758868368-1.0.1.1-JzjFQidqwDxVV3gJH8ls0NeCGe.nsK.SFYP0hPXUcupuLTBpscmBYQRMfAjeOlnaZRBsQROFL2fETfXatDwQwDHU7aHOT4IMwECKB3sTIN4',
}
if __name__ == '__main__':
params = {
'symbolId': 'ETHUSDT_UMCBL',
'kLineStep': '1m',
'kLineType': '1',
'endTime': '1758864600000',
}
response = requests.get(
'https://www.bitget.com/v1/kline/getMoreKlineDataV2',
params=params, cookies=cookies, headers=headers
)
raw_data = response.json()["data"]
print(raw_data)
# 转换成字典格式,方便后续处理
data = []
for i in raw_data:
data.append({
'id': int(i[0]) // 1000, # 秒级时间戳
'open': float(i[1]),
'high': float(i[2]),
'low': float(i[3]),
'close': float(i[4]),
})
print(i)
print(data)
# 按时间排序
sorted_data = sorted(data, key=lambda x: x['id'])
print(sorted_data)
signals = 0
wins = 0
lig_price = 0
low_price = 0
for idx in range(1, len(sorted_data) - 2): # 至少留两根 K 线验证
prev = sorted_data[idx - 1]
curr = sorted_data[idx]
future = sorted_data[idx + 2]
prev_open, prev_close = prev['open'], prev['close']
curr_open, curr_close = curr['open'], curr['close']
future_close = future['close']
# 当前为涨
if curr_close > curr_open:
# 前一笔涨 + 包裹
if prev_close > prev_open and curr_open < prev_open and curr_close > prev_close:
signals += 1
lig_price += (future_close - curr_close)
if future_close > curr_close:
wins += 1
# 前一笔跌 + 反包
elif prev_close < prev_open and curr_open < prev_close and curr_close > prev_open:
signals += 1
lig_price += (future_close - curr_close)
if future_close > curr_close:
wins += 1
# 当前为跌
elif curr_close < curr_open:
# 前一笔跌 + 包裹
if prev_close < prev_open and curr_open > prev_open and curr_close < prev_close:
signals += 1
low_price += (curr_close - future_close)
if future_close < curr_close:
wins += 1
# 前一笔涨 + 反包
elif prev_close > prev_open and curr_open > prev_close and curr_close < prev_open:
signals += 1
low_price += (curr_close - future_close)
if future_close < curr_close:
wins += 1
if signals > 0:
win_rate = wins / signals * 100
print(f"信号数={signals}, 胜率={win_rate:.2f}%")
else:
print("没有找到符合条件的形态")
print("上涨盈亏合计:", lig_price)
print("下跌盈亏合计:", low_price)

View File

@@ -1,81 +0,0 @@
import requests
cookies = {
'bitget_lang': 'zh-CN',
'_dx_kvani5r': '24e0dceb12f85d9a1279183ca29c09f772f8c61124e4eca228d8dd909c9b24b0019c2b9a',
'OptanonAlertBoxClosed': 'Wed%20Sep%2024%202025%2017:12:32%20GMT+0800%20(%E4%B8%AD%E5%9B%BD%E6%A0%87%E5%87%86%E6%97%B6%E9%97%B4)',
'OptanonConsent': 'isMarketing=1&isStatistic=1',
'g_state': '{"i_l":0}',
'theme': 'white',
'BITGET_LOCAL_COOKIE': '{%22bitget_lang%22:%22zh-CN%22%2C%22bitget_unit%22:%22CNY%22%2C%22bitget_showasset%22:true%2C%22bitget_theme%22:%22white%22%2C%22bitget_layout%22:%22right%22%2C%22bitget_valuationunit%22:0%2C%22bitget_valuationunit_new%22:1%2C%22bitget_valuationunitandfiat%22:1%2C%22bitgt_login%22:false%2C%22theme%22:%22black%22%2C%22brand_simulation_trade%22:false%2C%22bitget_currency%22:%22%22}',
'USD': 'CNY',
'_gcl_au': '1.1.737358653.1759055313',
'_ga': 'GA1.1.942322417.1759055313',
'afUserId': '58c62981-8c6f-4601-adee-77489e65d72b-p',
'AF_SYNC': '1759974778836',
'bt_rtoken': 'upex:session:id:d250cc2b001c88f9e9c60a3686fd7dcf5773a666402d41b35c7a6fa3f853392d',
'bt_uid': '619BB9EC4D4A3F9FC1AC092D38818A00',
'bt_sessonid': '6ad2dd3f-35f3-4ef8-accb-3292ceb8b5d7',
'bt_newsessionid': 'eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI1NTk2ZjA1MC0zOGFhLTQxMjktOTcyZS0wMWUyZDI1MWI0N2M1NzQxNTgyOTIiLCJ1aWQiOiIxV00rVjRqcTJYSVRQemdJVWhUMnNRPT0iLCJzdWIiOiJsenoqKipvbSIsImlwIjoiWGRhSGJmdHZQVGVpeFlnMmxlVmdUZz09IiwiZGlkIjoiSjBZZjQ1NkV5RUxaSGhaa2tWYnNQZTVlSFVYYUNKZS9CM21wTHJ5SHJWMTEyUklzWlFLTTVIQmtTNHlUUmhuVyIsInN0cyI6MCwiaWF0IjoxNzU5OTc0NzkwLCJleHAiOjE3NjA0MDY3OTAsInB1c2hpZCI6ImRka1NMR1VDak9Sd1pFdU1rMFlaMWc9PSIsImlzcyI6InVwZXgifQ.0SygmCSR3f5tfA0xQpdzS241nFDbsVultPm0LmleYgY',
'_ga_Z8Q93KHR0F': 'GS2.1.s1759974680$o4$g1$t1759974795$j19$l0$h0',
'dy_token': '68e74d44zBITZniRPCwXG8rs7bnFrrlGIHyxtKx1',
'_cfuvid': '7C9e7Tl9zudw90jhhHGEM4H7SJnpWoi39xepaHJpJuM-1759995357475-0.0.1.1-604800000',
'__cf_bm': 'y7VR5vFWhYBo1IWnsrX2txdXsSeztAnTxMOQjyhyuf0-1760001832-1.0.1.1-kj32unDiaucuNb8pjHeq89WUlOf.zwJW6gyN53JjOsQ8FhB1R23kpDJtzc4878CdMKYfk7xFyYUnUBEiESvziCBFUbhm3F.R0qaPyZ.dw8g',
}
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9,zh-HK;q=0.8,en;q=0.7',
'baggage': 'sentry-environment=online,sentry-release=776c8c2125078b22570121601aabb051a52c0936,sentry-public_key=8aeef93d782e4ef5ae75634bfee9b590,sentry-trace_id=cb93656935cd47f289b30e55dd96f6c0',
'cache-control': 'no-cache',
'content-type': 'application/json;charset=UTF-8',
'custom-token': '2facaf72193a42ab84dd879b94b57c7e',
'deviceid': '7c88d47fdc39e5c422eff197b10d3485',
'dy-token': '68e74d44zBITZniRPCwXG8rs7bnFrrlGIHyxtKx1',
'language': 'zh_CN',
'locale': 'zh_CN',
'origin': 'https://www.bitget.com',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://www.bitget.com/zh-CN/futures/usdt/ETHUSDT',
'sec-ch-ua': '"Google Chrome";v="141", "Not?A_Brand";v="8", "Chromium";v="141"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-origin',
'sentry-trace': 'cb93656935cd47f289b30e55dd96f6c0-b7272e524943c558-0',
'terminalcode': 'cc98a9dd01af7e2d50d9b9858723b25e',
'terminaltype': '1',
'tm': '1760002404225',
'uhti': 'w1760002409197066bf83bff8',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36',
'website': 'mix',
# 'cookie': 'bitget_lang=zh-CN; _dx_kvani5r=24e0dceb12f85d9a1279183ca29c09f772f8c61124e4eca228d8dd909c9b24b0019c2b9a; OptanonAlertBoxClosed=Wed%20Sep%2024%202025%2017:12:32%20GMT+0800%20(%E4%B8%AD%E5%9B%BD%E6%A0%87%E5%87%86%E6%97%B6%E9%97%B4); OptanonConsent=isMarketing=1&isStatistic=1; g_state={"i_l":0}; theme=white; BITGET_LOCAL_COOKIE={%22bitget_lang%22:%22zh-CN%22%2C%22bitget_unit%22:%22CNY%22%2C%22bitget_showasset%22:true%2C%22bitget_theme%22:%22white%22%2C%22bitget_layout%22:%22right%22%2C%22bitget_valuationunit%22:0%2C%22bitget_valuationunit_new%22:1%2C%22bitget_valuationunitandfiat%22:1%2C%22bitgt_login%22:false%2C%22theme%22:%22black%22%2C%22brand_simulation_trade%22:false%2C%22bitget_currency%22:%22%22}; USD=CNY; _gcl_au=1.1.737358653.1759055313; _ga=GA1.1.942322417.1759055313; afUserId=58c62981-8c6f-4601-adee-77489e65d72b-p; AF_SYNC=1759974778836; bt_rtoken=upex:session:id:d250cc2b001c88f9e9c60a3686fd7dcf5773a666402d41b35c7a6fa3f853392d; bt_uid=619BB9EC4D4A3F9FC1AC092D38818A00; bt_sessonid=6ad2dd3f-35f3-4ef8-accb-3292ceb8b5d7; bt_newsessionid=eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI1NTk2ZjA1MC0zOGFhLTQxMjktOTcyZS0wMWUyZDI1MWI0N2M1NzQxNTgyOTIiLCJ1aWQiOiIxV00rVjRqcTJYSVRQemdJVWhUMnNRPT0iLCJzdWIiOiJsenoqKipvbSIsImlwIjoiWGRhSGJmdHZQVGVpeFlnMmxlVmdUZz09IiwiZGlkIjoiSjBZZjQ1NkV5RUxaSGhaa2tWYnNQZTVlSFVYYUNKZS9CM21wTHJ5SHJWMTEyUklzWlFLTTVIQmtTNHlUUmhuVyIsInN0cyI6MCwiaWF0IjoxNzU5OTc0NzkwLCJleHAiOjE3NjA0MDY3OTAsInB1c2hpZCI6ImRka1NMR1VDak9Sd1pFdU1rMFlaMWc9PSIsImlzcyI6InVwZXgifQ.0SygmCSR3f5tfA0xQpdzS241nFDbsVultPm0LmleYgY; _ga_Z8Q93KHR0F=GS2.1.s1759974680$o4$g1$t1759974795$j19$l0$h0; dy_token=68e74d44zBITZniRPCwXG8rs7bnFrrlGIHyxtKx1; _cfuvid=7C9e7Tl9zudw90jhhHGEM4H7SJnpWoi39xepaHJpJuM-1759995357475-0.0.1.1-604800000; __cf_bm=y7VR5vFWhYBo1IWnsrX2txdXsSeztAnTxMOQjyhyuf0-1760001832-1.0.1.1-kj32unDiaucuNb8pjHeq89WUlOf.zwJW6gyN53JjOsQ8FhB1R23kpDJtzc4878CdMKYfk7xFyYUnUBEiESvziCBFUbhm3F.R0qaPyZ.dw8g',
}
json_data = {
'startTime': 1759912500000,
'endTime': 1760002409196,
'symbolCode': 'ETHUSDT',
'languageType': 1,
}
response = requests.post(
'https://www.bitget.com/v1/trigger/strategy/tradingview/queryHistorySignals',
cookies=cookies,
headers=headers,
json=json_data,
)
print(response.json())
# Note: json_data will not be serialized by requests
# exactly as it was in the original request.
# data = '{"startTime":1759912500000,"endTime":1760002409196,"symbolCode":"ETHUSDT","languageType":1}'
# response = requests.post(
# 'https://www.bitget.com/v1/trigger/strategy/tradingview/queryHistorySignals',
# cookies=cookies,
# headers=headers,
# data=data,
# )

File diff suppressed because it is too large Load Diff

View File

@@ -1,418 +0,0 @@
import re
import json
import hmac
import time
import base64
import hashlib
import datetime
import requests
from tqdm import *
from loguru import *
from DrissionPage import *
from bs4 import BeautifulSoup
def is_bullish(c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(c): # 阴线
return float(c['close']) < float(c['open'])
class WeexTransaction:
def __init__(self, tge_id):
self.tge_port = None # tge浏览器使用端口
self.tge_id = tge_id # tge id
self.tge_url = "http://127.0.0.1:50326" # tge本地服务url
self.tge_headers = {
"Authorization": f"Bearer asp_174003986c9b0799677c5b2c1adb76e402735d753bc91a91",
"Content-Type": "application/json"
}
# 替换为你自己的钉钉机器人 Webhook 地址
self.webhook_url = "https://oapi.dingtalk.com/robot/send?access_token=e2fafb3f46866d50fe52cbb29650ba9ef1cbc97915dde238192f04c906fe4125"
# 替换为你自己的钉钉机器人秘钥
self.secret = "SEC5f320e72d7a4eaca540c66c3d09edff2f74936517390dee99ece6dd1b3611998"
self.page = None # 浏览器对象
self.start = 0 # 持仓状态 -1:做空0维持仓1做多
self.kline_1 = None # 01
self.kline_2 = None # 01
self.direction = None # 信号类型
self.pbar = None # 进度条对象
def get_signature(self, timestamp):
# 将时间戳和密钥拼接
string_to_sign = f'{timestamp}\n{self.secret}'
string_to_sign = string_to_sign.encode('utf-8')
# 使用 HMAC-SHA256 算法进行签名
hmac_code = hmac.new(self.secret.encode('utf-8'), string_to_sign, digestmod=hashlib.sha256).digest()
# 对签名结果进行 Base64 编码
sign = base64.b64encode(hmac_code).decode('utf-8')
return sign
# def send_dingtalk_message(self, message_content):
# # 获取当前时间戳(毫秒)
# timestamp = str(round(time.time() * 1000))
# # 生成签名
# sign = self.get_signature(timestamp, )
# # 拼接带有签名信息的完整 Webhook URL
# full_url = f"{self.webhook_url}&timestamp={timestamp}&sign={sign}"
#
# # 定义消息内容
# message = {
# "msgtype": "text",
# "text": {
# "content": message_content
# }
# }
#
# # 设置请求头
# headers = {
# "Content-Type": "application/json"
# }
#
# try:
# # 发送 POST 请求
# response = requests.post(full_url, headers=headers, data=json.dumps(message))
#
# except requests.RequestException as e:
# print(f"请求发生错误: {e}")
def send_dingtalk_message(self, message_content):
pass
# url = "http://8.137.99.82:9005/api/send_click?token=fegergauiernguie&phone=8613661496481"
#
# res = requests.post(
# url=url,
# json={
# "phone": "8613661496481",
# "bot_name": "ergggreef",
# "datas": [
# {"send_message": [message_content], "click_button": [""], },
# ]
#
# }
# )
#
# print(res.json())
def openBrowser(self, ): # 直接指定ID打开窗口也可以使用 createBrowser 方法返回的ID
try:
response = requests.post(
f"{self.tge_url}/api/browser/start",
json={"envId": self.tge_id},
headers=self.tge_headers
)
self.tge_port = response.json()["data"]["port"]
return True
except:
return False
def take_over_browser(self):
try:
co = ChromiumOptions()
co.set_local_port(self.tge_port)
self.page = ChromiumPage(addr_or_opts=co)
self.page.set.window.max()
return True
except:
return False
def is_bullish(self, c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(self, c): # 阴线
return float(c['close']) < float(c['open'])
def check_signal(self, prev, curr):
"""
包住形态信号判定仅15分钟K线
- 前跌后涨包住 -> 做多
- 前涨后跌包住 -> 做空
"""
p_open, p_close = float(prev['open']), float(prev['close'])
c_open, c_close = float(curr['open']), float(curr['close'])
# 前跌后涨包住 -> 做多
if is_bullish(curr) and is_bearish(prev) and int(c_open) <= int(p_close) and int(c_close) >= int(p_open):
return "long", "bear_bull_engulf"
# 前涨后跌包住 -> 做空
if is_bearish(curr) and is_bullish(prev) and int(c_open) >= int(p_close) and int(c_close) <= int(p_open):
return "short", "bull_bear_engulf"
return None, None
def get_price(self):
for i in range(3):
try:
logger.info(f"获取最新数据:{i + 1}次。。。")
self.mn_tab.get(url="https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
res = self.mn_tab.listen.wait(timeout=25) # 等待并获取一个数据包
datas = []
if res:
for data in res.response.body["data"]:
insert_data = {
'id': int(data["timestamp"]) - 1,
'open': float(data["open"]),
'high': float(data["high"]),
'low': float(data["low"]),
'close': float(data["close"])
}
datas.append(insert_data)
return datas
except:
pass
return False
def remove_tags_and_spaces(self, html):
# 创建 BeautifulSoup 对象
soup = BeautifulSoup(html, 'html.parser')
# 获取去除标签后的文本
text = soup.get_text()
# 去除所有空格
text = text.replace(" ", "")
return text
def to_do_page(self):
# self.page.get("https://www.weeaxs.site/zh-CN/futures/demo-trading/ETH-SUSDT")
self.mn_tab.ele('x:(//button[normalize-space(text()) = "市价"])').click()
time.sleep(1)
self.mn_tab.ele('x://*[@id="size_0"]').input(float(self.get_num()) / 100)
time.sleep(1)
if self.direction == "long" and not self.start:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开多")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开多")
self.mn_tab.ele('x://span[normalize-space(text()) = "买入/做多"]').click()
self.start = 1
elif self.direction == "short" and not self.start:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开空")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开空")
self.mn_tab.ele('x://span[normalize-space(text()) = "卖出/做空"]').click()
self.start = -1
elif self.direction == "long" and self.start == -1:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平空做多")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平空做多")
self.mn_tab.ele('x:(//span[normalize-space(text()) = "市价"])').scroll.to_see(center=True)
self.mn_tab.ele('x:(//span[normalize-space(text()) = "市价"])').click()
time.sleep(3)
self.mn_tab.ele('x:(//span[normalize-space(text()) = "买入/做多"])').click()
self.start = 1
elif self.direction == "short" and self.start == 1:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平多做空")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平多做空")
self.mn_tab.ele('x:(//span[normalize-space(text()) = "市价"])').scroll.to_see(center=True)
self.mn_tab.ele('x:(//span[normalize-space(text()) = "市价"])').click()
time.sleep(3)
self.mn_tab.ele('x://span[normalize-space(text()) = "卖出/做空"]').click()
self.start = -1
def get_text(self, target_text):
# 去除目标文本中的空白字符
cleaned_target_text = re.sub(r'\s', '', target_text)
# 创建 BeautifulSoup 对象
soup = BeautifulSoup(self.mn_tab.html, 'html.parser')
# 遍历所有标签的文本内容
for tag in soup.find_all():
tag_text = tag.get_text()
# 去除标签文本中的空白字符
cleaned_tag_text = re.sub(r'\s', '', tag_text)
if cleaned_target_text in cleaned_tag_text:
return True
else:
return False
def get_now_time(self):
# 获取当前时间戳
current_timestamp = time.time()
# 将当前时间戳转换为 datetime 对象
current_datetime = datetime.datetime.fromtimestamp(current_timestamp)
# 计算距离当前时间最近的整点或 30 分时刻
if current_datetime.minute < 30:
target_datetime = current_datetime.replace(minute=0, second=0, microsecond=0)
else:
target_datetime = current_datetime.replace(minute=30, second=0, microsecond=0)
# 将目标 datetime 对象转换为时间戳
target_timestamp = target_datetime.timestamp()
return int(target_timestamp)
def close_extra_tabs_in_browser(self):
try:
for _, i in enumerate(self.page.get_tabs()):
if _ == 0:
continue
i.close()
return True
except:
pass
return False
def get_num(self):
num_tab = self.page.new_tab()
num_tab.listen.start("derivatives.bitmart.com/gw-api/contract-tiger/forward/v1/ifcontract/accounts")
for i in range(3):
try:
logger.info(f"获取最新数据:{i + 1}次。。。")
num_tab.get(url="https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
res = num_tab.listen.wait(timeout=15) # 等待并获取一个数据包
if res:
num_tab.close()
return res.response.body["data"]["accounts"][0]["available_balance"]
except:
pass
num_tab.close()
return False
def action(self):
# 获取比特端口
if self.openBrowser():
logger.info("获取打开比特成功,成功获取端口!!!")
else:
logger.error("打开比特失败!!!")
return
# 接管浏览器
if self.take_over_browser():
logger.info("接管比特浏览器成功!!!")
else:
logger.error("接管浏览器失败!!!")
return
if self.close_extra_tabs_in_browser():
logger.info('关闭多余标签页成功!!!')
else:
logger.info('关闭多余标签页失败!!!')
self.mn_tab = self.page.new_tab()
self.mn_tab.listen.start("contract-v2.bitmart.com/v1/ifcontract/quote/kline")
logger.success("浏览器开启抓包模式。。。")
self.mn_tab.get(url="https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT") # 打开网页
self.pbar = tqdm(total=30, desc="等待时间中", ncols=80) # desc进度条说明ncols长度
while True:
# 获取当前时间
current_time = time.localtime()
current_minute = current_time.tm_min
if current_minute < 30:
self.pbar.n = current_minute
self.pbar.refresh()
else:
self.pbar.n = current_minute - 30
self.pbar.refresh()
if current_minute not in [0, 1, 2, 3, 4, 5, 30, 31, 32, 33, 34, ]: # 判断是否是 新的30分钟了
# if current_minute not in range(60): # 判断是否是 新的30分钟了
time.sleep(10)
continue
new_price_datas = self.get_price()
if new_price_datas:
logger.success("获取最新交易价格成功!!!")
else:
logger.info("获取最新价格有问题!!!")
continue
new_price_datas1 = sorted(new_price_datas, key=lambda x: x["id"])
self.kline_1, self.kline_2, self.kline_3 = new_price_datas1[-3:]
# 判断抓取的数据是否正确
if self.get_now_time() != self.kline_3["id"]:
continue
time.sleep(15)
if self.get_text(target_text="全仓做多100X永续持仓"):
self.start = 1
elif self.get_text(target_text="全仓做空100X永续持仓"):
self.start = -1
else:
self.start = 0
if self.start == 1:
if is_bearish(self.kline_1) and is_bearish(self.kline_2):
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平多")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平多")
self.mn_tab.ele('x:(//span[normalize-space(text()) = "市价"])').scroll.to_see(center=True)
self.mn_tab.ele('x:(//span[normalize-space(text()) = "市价"])').click()
self.start = 0
elif self.start == -1:
if is_bullish(self.kline_1) and is_bullish(self.kline_2):
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平空")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平空")
self.mn_tab.ele('x:(//span[normalize-space(text()) = "市价"])').scroll.to_see(center=True)
self.mn_tab.ele('x:(//span[normalize-space(text()) = "市价"])').click()
self.start = 0
self.direction, signal_key = self.check_signal(prev=self.kline_1, curr=self.kline_2) # 判断信号
if self.direction:
try:
self.to_do_page()
except Exception as e:
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()}{e}")
self.pbar.reset() # 重置进度条
self.send_dingtalk_message(
message_content=
f"{datetime.datetime.now()}"
f"目前有持仓:{"" if self.start == 0 else ("" if self.start == 1 else "")}"
f"当前信号:{"" if not self.direction else ("" if self.direction == "long" else "")}"
)
if __name__ == '__main__':
WeexTransaction(
tge_id=196495,
).action()
# //*[contains(text(), '特定文本')]

View File

@@ -1,29 +0,0 @@
"""测试 BitMart API K线获取"""
import time
from bitmart.api_contract import APIContract
api_key = "a0fb7b98464fd9bcce67e7c519d58ec10d0c38a8"
secret_key = "4eaeba78e77aeaab1c2027f846a276d164f264a44c2c1bb1c5f3be50c8de1ca5"
memo = "数据抓取"
contractAPI = APIContract(api_key, secret_key, memo, timeout=(5, 15))
# 测试获取最近1小时的15分钟K线
end_time = int(time.time())
start_time = end_time - 3600 # 1小时前
print(f"当前时间戳: {end_time}")
print(f"开始时间戳: {start_time}")
print(f"当前时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(end_time))}")
print(f"开始时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(start_time))}")
try:
response = contractAPI.get_kline(
contract_symbol="ETHUSDT",
step=15,
start_time=start_time,
end_time=end_time
)
print(f"\n响应: {response}")
except Exception as e:
print(f"\n错误: {e}")

View File

@@ -0,0 +1,567 @@
"""
BitMart 三分之一策略 — 5分钟K线交易
策略规则:
1. 触发价格基于前一根有效K线实体>=0.1使用当前K线开盘价
- 做多触发价 = 当前K线开盘价 + 实体/3
- 做空触发价 = 当前K线开盘价 - 实体/3
2. 信号触发(无持仓时):
- 当前5分钟K线最高价 >= 做多触发价 → 做多信号
- 当前5分钟K线最低价 <= 做空触发价 → 做空信号
3. 执行逻辑:
- 做多时遇到做空信号 -> 平多并反手开空
- 做空时遇到做多信号 -> 平空并反手开多
- 同一根5分钟K线内只交易一次
4. 同根K线多空都触及时用开盘价与触发价距离判断先后。
5. 反手信号(有持仓时检测):
- 反手做空当前持多上一根K线上阴线涨幅 > 0.01%当前K线跌到上一根K线的实体下边 -> 平多反手开空
- 反手做多当前持空上一根K线下阴线跌幅 > 0.01%当前K线涨到上一根K线的实体上边 -> 平空反手开多
(上阴线 = high - max(open,close),上阴线涨幅 = (上阴线/开盘价)*100下阴线同理
(实体上边 = max(open,close),实体下边 = min(open,close)
"""
import random
import time
import datetime
from concurrent.futures import ThreadPoolExecutor
from tqdm import tqdm
from loguru import logger
from bit_tools import openBrowser
from DrissionPage import ChromiumPage
from DrissionPage import ChromiumOptions
from bitmart.api_contract import APIContract
try:
from 交易.tools import send_dingtalk_message
except ImportError:
send_dingtalk_message = None
ding_executor = ThreadPoolExecutor(max_workers=2, thread_name_prefix="dingtalk")
class BitmartOneThirdStrategy:
"""三分之一策略:触发价 = 当前K线开盘价 ± 实体/35分钟K线"""
def __init__(self, bit_id):
self.page: ChromiumPage | None = None
self.api_key = "a0fb7b98464fd9bcce67e7c519d58ec10d0c38a8"
self.secret_key = "4eaeba78e77aeaab1c2027f846a276d164f264a44c2c1bb1c5f3be50c8de1ca5"
self.memo = "合约交易"
self.contract_symbol = "ETHUSDT"
self.contractAPI = APIContract(self.api_key, self.secret_key, self.memo, timeout=(5, 15))
self.start = 0 # 持仓: -1 空, 0 无, 1 多
self.direction = None
self.pbar = tqdm(total=5, desc="等待K线", ncols=80)
self.last_kline_time = None
self.leverage = "100"
self.open_type = "cross"
self.risk_percent = 0.01
self.open_avg_price = None
self.current_amount = None
self.position_cross = None
self.bit_id = bit_id
self.min_body_size = 0.1 # 前一根有效K线实体下限
self.kline_step = 5 # 5分钟K线
self.check_interval = 3
self.last_trigger_kline_id = None
self.last_trigger_direction = None
self.min_shadow_pct = 0.01 # 反手信号:上/下影线幅度需 > 0.01%
# ========================= 三分之一策略核心 =========================
def is_bullish(self, c):
return float(c['close']) > float(c['open'])
def get_body_size(self, candle):
return abs(float(candle['open']) - float(candle['close']))
def find_valid_prev_bar(self, all_data, current_idx):
"""找到当前K线之前最近一根实体>=min_body_size的K线"""
if current_idx <= 0:
return None, None
for i in range(current_idx - 1, -1, -1):
prev = all_data[i]
if self.get_body_size(prev) >= self.min_body_size:
return i, prev
return None, None
def get_one_third_levels(self, prev, curr):
"""
做多触发价 = 当前K线开盘价 + 实体/3
做空触发价 = 当前K线开盘价 - 实体/3
实体来自前一根有效K线
"""
p_open = float(prev['open'])
p_close = float(prev['close'])
curr_open = float(curr['open'])
body = abs(p_open - p_close)
if body < 0.001:
return None, None
long_trigger = curr_open + body / 3
short_trigger = curr_open - body / 3
return long_trigger, short_trigger
def get_upper_shadow(self, candle):
"""上影线 = high - max(open, close)"""
o, c, h = float(candle['open']), float(candle['close']), float(candle['high'])
return h - max(o, c)
def get_lower_shadow(self, candle):
"""下影线 = min(open, close) - low"""
o, c, l = float(candle['open']), float(candle['close']), float(candle['low'])
return min(o, c) - l
def upper_shadow_pct(self, candle):
"""上影线涨幅 = (上影线/开盘价)*100"""
o = float(candle['open'])
if o <= 0:
return 0.0
return self.get_upper_shadow(candle) / o * 100
def lower_shadow_pct(self, candle):
"""下影线跌幅 = (下影线/开盘价)*100"""
o = float(candle['open'])
if o <= 0:
return 0.0
return self.get_lower_shadow(candle) / o * 100
def get_body_upper_edge(self, candle):
"""实体上边 = max(open, close)"""
return max(float(candle['open']), float(candle['close']))
def get_body_lower_edge(self, candle):
"""实体下边 = min(open, close)"""
return min(float(candle['open']), float(candle['close']))
def check_reverse_signal(self, kline_data):
"""
反手信号(有持仓时检测):
- 反手做空当前持多上一根K线上阴线涨幅 > 0.01%当前K线跌到上一根K线的实体下边
- 反手做多当前持空上一根K线下阴线跌幅 > 0.01%当前K线涨到上一根K线的实体上边
使用紧邻的上一根K线kline_data[-2])。
返回:(方向 'long'|'short', 上一根K线) 或 (None, None)
"""
if len(kline_data) < 2:
return None, None
curr = kline_data[-1]
prev = kline_data[-2]
curr_high = float(curr['high'])
curr_low = float(curr['low'])
prev_body_upper = self.get_body_upper_edge(prev) # 实体上边
prev_body_lower = self.get_body_lower_edge(prev) # 实体下边
# 持多反手做空:上一根上阴线涨幅>0.01%,当前跌到上一根实体下边
if self.start == 1:
if self.upper_shadow_pct(prev) > self.min_shadow_pct and curr_low <= prev_body_lower:
return 'short', prev
# 持空反手做多:上一根下阴线跌幅>0.01%,当前涨到上一根实体上边
if self.start == -1:
if self.lower_shadow_pct(prev) > self.min_shadow_pct and curr_high >= prev_body_upper:
return 'long', prev
return None, None
def check_realtime_trigger(self, kline_data):
"""
检查当前5分钟K线是否触发信号。
做多触发价 = 当前K线开盘价 + 实体/3做空 = 当前K线开盘价 - 实体/3。
同根多空都触发时用开盘价与触发价距离判断先后。
返回:(方向, 触发价格, 有效前一根K线, 当前K线) 或 (None, None, None, None)
"""
if len(kline_data) < 2:
return None, None, None, None
curr = kline_data[-1]
curr_kline_id = curr['id']
curr_high = float(curr['high'])
curr_low = float(curr['low'])
curr_open = float(curr['open'])
valid_prev_idx, prev = self.find_valid_prev_bar(kline_data, len(kline_data) - 1)
if prev is None:
return None, None, None, None
long_trigger, short_trigger = self.get_one_third_levels(prev, curr)
if long_trigger is None:
return None, None, None, None
long_triggered = curr_high >= long_trigger
short_triggered = curr_low <= short_trigger
both_triggered = long_triggered and short_triggered
direction = None
trigger_price = None
if both_triggered:
dist_to_long = abs(long_trigger - curr_open)
dist_to_short = abs(short_trigger - curr_open)
if dist_to_short <= dist_to_long:
direction = 'short'
trigger_price = short_trigger
else:
direction = 'long'
trigger_price = long_trigger
elif short_triggered:
direction = 'short'
trigger_price = short_trigger
elif long_triggered:
direction = 'long'
trigger_price = long_trigger
if direction is None:
return None, None, None, None
if self.last_trigger_kline_id == curr_kline_id and self.last_trigger_direction == direction:
return None, None, None, None
return direction, trigger_price, prev, curr
# ========================= API =========================
def get_klines(self):
"""获取最近5分钟K线"""
try:
end_time = int(time.time())
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=self.kline_step,
start_time=end_time - 3600 * 3,
end_time=end_time
)[0]["data"]
formatted = []
for k in response:
formatted.append({
'id': int(k["timestamp"]),
'open': float(k["open_price"]),
'high': float(k["high_price"]),
'low': float(k["low_price"]),
'close': float(k["close_price"])
})
formatted.sort(key=lambda x: x['id'])
return formatted
except Exception as e:
if "429" in str(e) or "too many requests" in str(e).lower():
logger.warning(f"API限流等待60秒: {e}")
time.sleep(60)
else:
logger.error(f"获取K线异常: {e}")
self.ding("获取K线异常", error=True)
return None
def get_current_price(self):
try:
end_time = int(time.time())
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=1,
start_time=end_time - 3600 * 3,
end_time=end_time
)[0]
if response.get('code') == 1000:
return float(response['data'][-1]["close_price"])
return None
except Exception as e:
logger.error(f"获取价格异常: {e}")
return None
def get_available_balance(self):
try:
response = self.contractAPI.get_assets_detail()[0]
if response.get('code') == 1000:
data = response.get('data')
if isinstance(data, dict):
return float(data.get('available_balance', 0))
if isinstance(data, list):
for asset in data:
if asset.get('currency') == 'USDT':
return float(asset.get('available_balance', 0))
return None
except Exception as e:
logger.error(f"余额查询异常: {e}")
return None
def get_position_status(self):
try:
response = self.contractAPI.get_position(contract_symbol=self.contract_symbol)[0]
if response.get('code') == 1000:
positions = response.get('data') or []
if not positions:
self.start = 0
self.open_avg_price = None
self.current_amount = None
self.position_cross = None
return True
self.start = 1 if positions[0].get('position_type') == 1 else -1
self.open_avg_price = positions[0].get('open_avg_price')
self.current_amount = positions[0].get('current_amount')
self.position_cross = positions[0].get("position_cross")
return True
return False
except Exception as e:
logger.error(f"持仓查询异常: {e}")
return False
def set_leverage(self):
try:
response = self.contractAPI.post_submit_leverage(
contract_symbol=self.contract_symbol,
leverage=self.leverage,
open_type=self.open_type
)[0]
if response.get('code') == 1000:
logger.success(f"全仓 {self.leverage}x 杠杆设置成功")
return True
logger.error(f"杠杆设置失败: {response}")
return False
except Exception as e:
logger.error(f"设置杠杆异常: {e}")
return False
# ========================= 浏览器 =========================
def open_browser(self):
try:
bit_port = openBrowser(id=self.bit_id)
co = ChromiumOptions()
co.set_local_port(port=bit_port)
self.page = ChromiumPage(addr_or_opts=co)
return True
except Exception:
return False
def close_extra_tabs(self):
try:
for idx, tab in enumerate(self.page.get_tabs()):
if idx > 0:
tab.close()
return True
except Exception:
return False
def click_safe(self, xpath, sleep=0.5):
try:
ele = self.page.ele(xpath)
if not ele:
return False
ele.scroll.to_see(center=True)
time.sleep(sleep)
ele.click(by_js=True)
return True
except Exception:
return False
def 平仓(self):
logger.info("执行平仓...")
self.click_safe('x://span[normalize-space(text()) ="市价"]')
time.sleep(0.5)
self.ding("执行平仓")
def 开单(self, marketPriceLongOrder=0, size=None):
if size is None or size <= 0:
logger.warning("开单金额无效")
return False
direction_str = "做多" if marketPriceLongOrder == 1 else "做空"
logger.info(f"执行{direction_str},金额: {size}")
try:
if marketPriceLongOrder == -1:
self.click_safe('x://button[normalize-space(text()) ="市价"]')
self.page.ele('x://*[@id="size_0"]').input(size)
self.click_safe('x://span[normalize-space(text()) ="卖出/做空"]')
elif marketPriceLongOrder == 1:
self.click_safe('x://button[normalize-space(text()) ="市价"]')
self.page.ele('x://*[@id="size_0"]').input(size)
self.click_safe('x://span[normalize-space(text()) ="买入/做多"]')
self.ding(f"执行{direction_str},金额: {size}")
return True
except Exception as e:
logger.error(f"开单异常: {e}")
return False
def ding(self, msg, error=False):
prefix = "❌三分之一策略:" if error else "🔔三分之一策略:"
full_msg = f"{prefix}{msg}"
if error:
logger.error(msg)
for _ in range(3):
ding_executor.submit(self._send_ding_safe, full_msg)
else:
logger.info(msg)
ding_executor.submit(self._send_ding_safe, full_msg)
def _send_ding_safe(self, msg):
try:
if send_dingtalk_message:
send_dingtalk_message(msg)
except Exception as e:
logger.warning(f"钉钉发送失败: {e}")
# ========================= 主循环 =========================
def action(self):
if not self.set_leverage():
logger.error("杠杆设置失败,程序继续运行但可能下单失败")
if not self.open_browser():
self.ding("打开浏览器失败!", error=True)
return
logger.info("浏览器打开成功")
self.close_extra_tabs()
self.page.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
time.sleep(2)
self.click_safe('x://button[normalize-space(text()) ="市价"]')
logger.info("三分之一策略5分钟K线开始监测")
last_report_time = 0
report_interval = 300
while True:
for _ in range(5):
if self.open_browser():
break
time.sleep(5)
else:
self.ding("打开浏览器失败!", error=True)
return
self.close_extra_tabs()
self.page.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
time.sleep(2)
self.click_safe('x://button[normalize-space(text()) ="市价"]')
try:
kline_data = self.get_klines()
if not kline_data or len(kline_data) < 2:
logger.warning("K线数据不足等待重试...")
time.sleep(self.check_interval)
continue
curr = kline_data[-1]
prev = kline_data[-2]
curr_time_str = datetime.datetime.fromtimestamp(curr['id']).strftime('%H:%M:%S')
if not self.get_position_status():
logger.warning("获取仓位失败,使用缓存")
curr_kline_id = curr['id']
# 有持仓时优先检测反手信号
if self.start != 0:
rev_dir, rev_prev = self.check_reverse_signal(kline_data)
if rev_dir:
balance = self.get_available_balance()
trade_size = (balance or 0) * self.risk_percent
if rev_prev is not None:
up_pct = self.upper_shadow_pct(rev_prev)
low_pct = self.lower_shadow_pct(rev_prev)
prev_body_upper = self.get_body_upper_edge(rev_prev)
prev_body_lower = self.get_body_lower_edge(rev_prev)
logger.info(f"{'='*50}")
if rev_dir == 'long':
logger.info(f"🔄 反手信号({rev_dir})当前K线涨到上一根实体上边={prev_body_upper:.2f}")
else:
logger.info(f"🔄 反手信号({rev_dir})当前K线跌到上一根实体下边={prev_body_lower:.2f}")
logger.info(f" 上一根 上阴线涨幅={up_pct:.3f}% 下阴线跌幅={low_pct:.3f}%")
logger.info(f"{'='*50}")
if rev_dir == 'long':
logger.info("📈 平空反手开多")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=1, size=trade_size)
else:
logger.info("📉 平多反手开空")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=-1, size=trade_size)
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = rev_dir
self.get_position_status()
time.sleep(self.check_interval)
continue
direction, trigger_price, valid_prev, curr_kline = self.check_realtime_trigger(kline_data)
if direction:
curr_kline_id = curr_kline['id']
# 信号与持仓同向则不操作
if (direction == "long" and self.start == 1) or (direction == "short" and self.start == -1):
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
time.sleep(self.check_interval)
continue
prev_time = datetime.datetime.fromtimestamp(valid_prev['id']).strftime('%H:%M')
prev_type = "阳线" if self.is_bullish(valid_prev) else "阴线"
prev_body = self.get_body_size(valid_prev)
logger.info(f"{'='*50}")
logger.info(f"🚨 检测到{direction}信号 触发价={trigger_price:.2f}")
logger.info(f" 有效前一根[{prev_time}] {prev_type} 实体={prev_body:.2f}")
logger.info(f" 当前5分钟K线 O={curr_kline['open']:.2f} H={curr_kline['high']:.2f} L={curr_kline['low']:.2f} C={curr_kline['close']:.2f}")
logger.info(f" 当前持仓: {self.start} (1=多 -1=空 0=无)")
balance = self.get_available_balance()
trade_size = (balance or 0) * self.risk_percent
executed = False
if direction == "long":
if self.start == -1:
logger.info("📈 平空反手开多")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=1, size=trade_size)
executed = True
elif self.start == 0:
logger.info("📈 无仓位开多")
self.开单(marketPriceLongOrder=1, size=trade_size)
executed = True
elif direction == "short":
if self.start == 1:
logger.info("📉 平多反手开空")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=-1, size=trade_size)
executed = True
elif self.start == 0:
logger.info("📉 无仓位开空")
self.开单(marketPriceLongOrder=-1, size=trade_size)
executed = True
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
if executed:
self.get_position_status()
logger.info(f"{'='*50}")
else:
logger.debug(f"[{curr_time_str}] O={curr['open']:.2f} H={curr['high']:.2f} L={curr['low']:.2f}")
if time.time() - last_report_time >= report_interval:
last_report_time = time.time()
time.sleep(self.check_interval)
except Exception as e:
logger.error(f"主循环异常: {e}")
time.sleep(self.check_interval)
time.sleep(3)
if random.randint(1, 10) > 7:
self.page.close()
time.sleep(15)
if __name__ == '__main__':
try:
BitmartOneThirdStrategy(bit_id="f2320f57e24c45529a009e1541e25961").action()
except KeyboardInterrupt:
logger.info("程序被用户中断")
finally:
ding_executor.shutdown(wait=True)

View File

@@ -0,0 +1,516 @@
"""
BitMart 五分之一策略(开盘价版)— 3分钟K线交易
策略规则(与 1111 一致):
基于前一根有效 K 线(实体 ≥ 0.1
做多触发价 = 当前K线开盘价 + 实体/5收盘价向上 1/5 实体)
做空触发价 = 当前K线开盘价 - 实体/5收盘价向下 1/5 实体)
反手(若已有持仓):
持空反手做多:价格涨到 开仓价 + 前一根实体/5
持多反手做空:价格跌到 开仓价 - 前一根实体/5
同根K线内多空都触及时用开盘价与触发价距离判断先后。
"""
import random
import time
import datetime
from concurrent.futures import ThreadPoolExecutor
from tqdm import tqdm
from loguru import logger
from bit_tools import openBrowser
from DrissionPage import ChromiumPage
from DrissionPage import ChromiumOptions
from bitmart.api_contract import APIContract
try:
from 交易.tools import send_dingtalk_message
except ImportError:
send_dingtalk_message = None
ding_executor = ThreadPoolExecutor(max_workers=2, thread_name_prefix="dingtalk")
class BitmartOneFifthOpenStrategy:
"""五分之一策略(开盘价版):触发价 = 当前K线开盘价 ± 实体/53分钟K线"""
def __init__(self, bit_id):
self.page: ChromiumPage | None = None
self.api_key = "a0fb7b98464fd9bcce67e7c519d58ec10d0c38a8"
self.secret_key = "4eaeba78e77aeaab1c2027f846a276d164f264a44c2c1bb1c5f3be50c8de1ca5"
self.memo = "合约交易"
self.contract_symbol = "ETHUSDT"
self.contractAPI = APIContract(self.api_key, self.secret_key, self.memo, timeout=(5, 15))
self.start = 0 # 持仓: -1 空, 0 无, 1 多
self.direction = None
self.pbar = tqdm(total=3, desc="等待K线", ncols=80)
self.last_kline_time = None
self.leverage = "100"
self.open_type = "cross"
self.risk_percent = 0.01
self.open_avg_price = None
self.current_amount = None
self.bit_id = bit_id
self.min_body_size = 0.1 # 前一根有效K线实体下限
self.kline_step = 3 # 3分钟K线
self.check_interval = 3
self.last_trigger_kline_id = None
self.last_trigger_direction = None
self.last_trade_kline_id = None
# ========================= 策略核心(开盘价版)=========================
def get_body_size(self, candle):
return abs(float(candle['open']) - float(candle['close']))
def find_valid_prev_bar(self, all_data, current_idx):
"""找到当前K线之前最近一根实体≥min_body_size的K线"""
if current_idx <= 0:
return None, None
for i in range(current_idx - 1, -1, -1):
prev = all_data[i]
if self.get_body_size(prev) >= self.min_body_size:
return i, prev
return None, None
def get_trigger_levels_by_open(self, curr_open, prev_bar):
"""
做多触发价 = 当前K线开盘价 + 实体/5
做空触发价 = 当前K线开盘价 - 实体/5
实体来自前一根有效K线。
"""
body = self.get_body_size(prev_bar)
if body < 0.001:
return None, None
curr_open_f = float(curr_open)
long_trigger = curr_open_f + body / 5
short_trigger = curr_open_f - body / 5
return long_trigger, short_trigger
def check_realtime_trigger(self, kline_data):
"""
检查当前3分钟K线是否触发信号开盘价版
做多触发价 = 当前K线开盘价 + 前一根实体/5
做空触发价 = 当前K线开盘价 - 前一根实体/5
若同根多空都触发,用开盘价与触发价距离判断先后。
返回:(方向, 触发价格, 有效前一根K线, 当前K线) 或 (None, None, None, None)
"""
if len(kline_data) < 2:
return None, None, None, None
curr = kline_data[-1]
curr_kline_id = curr['id']
curr_open = float(curr['open'])
curr_high = float(curr['high'])
curr_low = float(curr['low'])
valid_prev_idx, prev = self.find_valid_prev_bar(kline_data, len(kline_data) - 1)
if prev is None:
return None, None, None, None
long_trigger, short_trigger = self.get_trigger_levels_by_open(curr_open, prev)
if long_trigger is None:
return None, None, None, None
long_triggered = curr_high >= long_trigger
short_triggered = curr_low <= short_trigger
both_triggered = long_triggered and short_triggered
direction = None
trigger_price = None
if both_triggered:
dist_to_long = abs(long_trigger - curr_open)
dist_to_short = abs(short_trigger - curr_open)
if dist_to_short <= dist_to_long:
direction = 'short'
trigger_price = short_trigger
else:
direction = 'long'
trigger_price = long_trigger
elif short_triggered:
direction = 'short'
trigger_price = short_trigger
elif long_triggered:
direction = 'long'
trigger_price = long_trigger
if direction is None:
return None, None, None, None
if self.last_trigger_kline_id == curr_kline_id and self.last_trigger_direction == direction:
return None, None, None, None
return direction, trigger_price, prev, curr
def check_reverse_trigger(self, kline_data):
"""
反手检测:持空反手做多 = 现价 >= 开仓价+前一根实体/5
持多反手做空 = 现价 <= 开仓价-前一根实体/5
使用当前价最新K线收盘或 get_current_price与 开仓价±实体/5 比较。
"""
if self.start == 0 or self.open_avg_price is None:
return None, None
if len(kline_data) < 2:
return None, None
valid_prev_idx, prev = self.find_valid_prev_bar(kline_data, len(kline_data) - 1)
if prev is None:
return None, None
body = self.get_body_size(prev)
if body < 0.001:
return None, None
open_price_f = float(self.open_avg_price)
reverse_long_price = open_price_f + body / 5 # 持空反手做多线
reverse_short_price = open_price_f - body / 5 # 持多反手做空线
curr = kline_data[-1]
curr_high = float(curr['high'])
curr_low = float(curr['low'])
if self.start == -1 and curr_high >= reverse_long_price:
return 'long', reverse_long_price
if self.start == 1 and curr_low <= reverse_short_price:
return 'short', reverse_short_price
return None, None
def is_bullish(self, c):
return float(c['close']) > float(c['open'])
# ========================= API =========================
def get_klines(self):
"""获取最近3分钟K线"""
try:
end_time = int(time.time())
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=self.kline_step,
start_time=end_time - 3600 * 3,
end_time=end_time
)[0]["data"]
formatted = []
for k in response:
formatted.append({
'id': int(k["timestamp"]),
'open': float(k["open_price"]),
'high': float(k["high_price"]),
'low': float(k["low_price"]),
'close': float(k["close_price"])
})
formatted.sort(key=lambda x: x['id'])
return formatted
except Exception as e:
if "429" in str(e) or "too many requests" in str(e).lower():
logger.warning(f"API限流等待60秒: {e}")
time.sleep(60)
else:
logger.error(f"获取K线异常: {e}")
self.ding("获取K线异常", error=True)
return None
def get_current_price(self):
try:
end_time = int(time.time())
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=1,
start_time=end_time - 3600 * 3,
end_time=end_time
)[0]
if response.get('code') == 1000:
return float(response['data'][-1]["close_price"])
return None
except Exception as e:
logger.error(f"获取价格异常: {e}")
return None
def get_available_balance(self):
try:
response = self.contractAPI.get_assets_detail()[0]
if response.get('code') == 1000:
data = response.get('data')
if isinstance(data, dict):
return float(data.get('available_balance', 0))
if isinstance(data, list):
for asset in data:
if asset.get('currency') == 'USDT':
return float(asset.get('available_balance', 0))
return None
except Exception as e:
logger.error(f"余额查询异常: {e}")
return None
def get_position_status(self):
try:
response = self.contractAPI.get_position(contract_symbol=self.contract_symbol)[0]
if response.get('code') == 1000:
positions = response.get('data') or []
if not positions:
self.start = 0
self.open_avg_price = None
self.current_amount = None
self.position_cross = None
return True
self.start = 1 if positions[0].get('position_type') == 1 else -1
self.open_avg_price = positions[0].get('open_avg_price')
self.current_amount = positions[0].get('current_amount')
self.position_cross = positions[0].get("position_cross")
return True
return False
except Exception as e:
logger.error(f"持仓查询异常: {e}")
return False
def set_leverage(self):
try:
response = self.contractAPI.post_submit_leverage(
contract_symbol=self.contract_symbol,
leverage=self.leverage,
open_type=self.open_type
)[0]
if response.get('code') == 1000:
logger.success(f"全仓 {self.leverage}x 杠杆设置成功")
return True
logger.error(f"杠杆设置失败: {response}")
return False
except Exception as e:
logger.error(f"设置杠杆异常: {e}")
return False
# ========================= 浏览器 =========================
def open_browser(self):
try:
bit_port = openBrowser(id=self.bit_id)
co = ChromiumOptions()
co.set_local_port(port=bit_port)
self.page = ChromiumPage(addr_or_opts=co)
return True
except Exception:
return False
def close_extra_tabs(self):
try:
for idx, tab in enumerate(self.page.get_tabs()):
if idx > 0:
tab.close()
return True
except Exception:
return False
def click_safe(self, xpath, sleep=0.5):
try:
ele = self.page.ele(xpath)
if not ele:
return False
ele.scroll.to_see(center=True)
time.sleep(sleep)
ele.click(by_js=True)
return True
except Exception:
return False
def 平仓(self):
logger.info("执行平仓...")
self.click_safe('x://span[normalize-space(text()) ="市价"]')
time.sleep(0.5)
self.ding("执行平仓")
def 开单(self, marketPriceLongOrder=0, size=None):
if size is None or size <= 0:
logger.warning("开单金额无效")
return False
direction_str = "做多" if marketPriceLongOrder == 1 else "做空"
logger.info(f"执行{direction_str},金额: {size}")
try:
if marketPriceLongOrder == -1:
self.click_safe('x://button[normalize-space(text()) ="市价"]')
self.page.ele('x://*[@id="size_0"]').input(size)
self.click_safe('x://span[normalize-space(text()) ="卖出/做空"]')
elif marketPriceLongOrder == 1:
self.click_safe('x://button[normalize-space(text()) ="市价"]')
self.page.ele('x://*[@id="size_0"]').input(size)
self.click_safe('x://span[normalize-space(text()) ="买入/做多"]')
self.ding(f"执行{direction_str},金额: {size}")
return True
except Exception as e:
logger.error(f"开单异常: {e}")
return False
def ding(self, msg, error=False):
prefix = "❌五分之一开盘价版:" if error else "🔔五分之一开盘价版:"
full_msg = f"{prefix}{msg}"
if error:
logger.error(msg)
for _ in range(3):
ding_executor.submit(self._send_ding_safe, full_msg)
else:
logger.info(msg)
ding_executor.submit(self._send_ding_safe, full_msg)
def _send_ding_safe(self, msg):
try:
if send_dingtalk_message:
send_dingtalk_message(msg)
except Exception as e:
logger.warning(f"钉钉发送失败: {e}")
# ========================= 主循环 =========================
def action(self):
if not self.set_leverage():
logger.error("杠杆设置失败,程序继续运行但可能下单失败")
if not self.open_browser():
self.ding("打开浏览器失败!", error=True)
return
logger.info("浏览器打开成功")
self.close_extra_tabs()
self.page.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
time.sleep(2)
self.click_safe('x://button[normalize-space(text()) ="市价"]')
logger.info("五分之一策略开盘价版3分钟K线开始监测")
last_report_time = 0
report_interval = 300
while True:
for _ in range(5):
if self.open_browser():
break
time.sleep(5)
else:
self.ding("打开浏览器失败!", error=True)
return
self.close_extra_tabs()
self.page.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
time.sleep(2)
self.click_safe('x://button[normalize-space(text()) ="市价"]')
try:
kline_data = self.get_klines()
if not kline_data or len(kline_data) < 3:
logger.warning("K线数据不足等待重试...")
time.sleep(self.check_interval)
continue
curr = kline_data[-1]
curr_time_str = datetime.datetime.fromtimestamp(curr['id']).strftime('%H:%M:%S')
if not self.get_position_status():
logger.warning("获取仓位失败,使用缓存")
# 1) 反手检测:有持仓时先看是否触发反手
rev_dir, rev_price = self.check_reverse_trigger(kline_data)
if rev_dir:
curr_kline_id = curr['id']
if self.last_trade_kline_id != curr_kline_id:
prev_idx, prev_bar = self.find_valid_prev_bar(kline_data, len(kline_data) - 1)
if prev_bar is not None:
balance = self.get_available_balance()
trade_size = (balance or 0) * self.risk_percent
logger.info(f"反手信号: {rev_dir} 触发价={rev_price:.2f}")
if rev_dir == 'long':
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=1, size=trade_size)
else:
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=-1, size=trade_size)
self.last_trade_kline_id = curr_kline_id
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = rev_dir
self.get_position_status()
time.sleep(self.check_interval)
continue
# 2) 常规开仓/反手:基于 当前K线开盘价 ± 实体/5
direction, trigger_price, valid_prev, curr_kline = self.check_realtime_trigger(kline_data)
if direction:
curr_kline_id = curr_kline['id']
if self.last_trade_kline_id == curr_kline_id:
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
time.sleep(self.check_interval)
continue
prev_time = datetime.datetime.fromtimestamp(valid_prev['id']).strftime('%H:%M')
prev_type = "阳线" if self.is_bullish(valid_prev) else "阴线"
prev_body = self.get_body_size(valid_prev)
logger.info(f"{'='*50}")
logger.info(f"🚨 检测到{direction}信号 触发价={trigger_price:.2f}")
logger.info(f" 有效前一根[{prev_time}] {prev_type} 实体={prev_body:.2f}")
logger.info(f" 当前3分钟K线 O={curr_kline['open']:.2f} H={curr_kline['high']:.2f} L={curr_kline['low']:.2f}")
logger.info(f" 当前持仓: {self.start} (1=多 -1=空 0=无)")
balance = self.get_available_balance()
trade_size = (balance or 0) * self.risk_percent
executed = False
if direction == "long":
if self.start == -1:
logger.info("📈 平空反手开多")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=1, size=trade_size)
executed = True
elif self.start == 0:
logger.info("📈 无仓位开多")
self.开单(marketPriceLongOrder=1, size=trade_size)
executed = True
elif direction == "short":
if self.start == 1:
logger.info("📉 平多反手开空")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=-1, size=trade_size)
executed = True
elif self.start == 0:
logger.info("📉 无仓位开空")
self.开单(marketPriceLongOrder=-1, size=trade_size)
executed = True
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
if executed:
self.last_trade_kline_id = curr_kline_id
self.get_position_status()
logger.info(f"{'='*50}")
else:
logger.debug(f"[{curr_time_str}] O={curr['open']:.2f} H={curr['high']:.2f} L={curr['low']:.2f}")
if time.time() - last_report_time >= report_interval:
last_report_time = time.time()
time.sleep(self.check_interval)
except Exception as e:
logger.error(f"主循环异常: {e}")
time.sleep(self.check_interval)
time.sleep(3)
if random.randint(1, 10) > 7:
self.page.close()
time.sleep(15)
if __name__ == '__main__':
try:
BitmartOneFifthOpenStrategy(bit_id="f2320f57e24c45529a009e1541e25961").action()
except KeyboardInterrupt:
logger.info("程序被用户中断")
finally:
ding_executor.shutdown(wait=True)

View File

@@ -0,0 +1,686 @@
import time
from tqdm import tqdm
from loguru import logger
from bit_tools import openBrowser
from DrissionPage import ChromiumPage
from DrissionPage import ChromiumOptions
from bitmart.api_contract import APIContract
class BitmartFuturesTransaction:
def __init__(self, bit_id):
self.page: ChromiumPage | None = None
self.api_key = "a0fb7b98464fd9bcce67e7c519d58ec10d0c38a8"
self.secret_key = "4eaeba78e77aeaab1c2027f846a276d164f264a44c2c1bb1c5f3be50c8de1ca5"
self.memo = "合约交易"
self.contract_symbol = "ETHUSDT"
self.contractAPI = APIContract(self.api_key, self.secret_key, self.memo, timeout=(5, 15))
self.start = 0 # 持仓状态: -1 空, 0 无, 1 多
self.pbar = tqdm(total=30, desc="等待K线", ncols=80) # 可选:用于长时间等待时展示进度
self.last_kline_time = None # 上一次处理的K线时间戳用于判断是否是新K线
# 反手频率控制
self.reverse_cooldown_seconds = 1.5 * 60 # 反手冷却时间(秒)
self.reverse_min_move_pct = 0.05 # 反手最小价差过滤(百分比)
self.last_reverse_time = None # 上次反手时间
# 开仓频率控制
self.open_cooldown_seconds = 60 # 开仓冷却时间(秒),两次开仓至少间隔此时长
self.last_open_time = None # 上次开仓时间
self.last_open_kline_id = None # 上次开仓所在 K 线 id同一根 K 线只允许开仓一次
self.leverage = "100" # 高杠杆(全仓模式下可开更大仓位)
self.open_type = "cross" # 全仓模式
self.risk_percent = 0 # 未使用;若启用则可为每次开仓占可用余额的百分比
self.take_profit_usd = 5 # 仓位盈利达到此金额(美元)时平仓止盈
self.stop_loss_usd = -3 # 固定止损:亏损达到 3 美元平仓
self.trailing_activation_usd = 2 # 盈利达到此金额后启动移动止损
self.trailing_distance_usd = 1.5 # 从最高盈利回撤此金额则平仓
self.max_unrealized_pnl_seen = None # 持仓期间见过的最大盈利(用于移动止损)
self.open_avg_price = None # 开仓价格
self.current_amount = None # 持仓量
self.bit_id = bit_id
self.default_order_size = 25 # 开仓/反手张数,统一在此修改
# 策略相关变量
self.prev_kline = None # 上一根K线
self.current_kline = None # 当前K线
self.prev_entity = None # 上一根K线实体大小
self.current_open = None # 当前K线开盘价
def get_klines(self):
"""获取最近2根K线当前K线和上一根K线"""
try:
end_time = int(time.time())
# 获取足够多的条目确保有最新的K线
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=5, # 5分钟
start_time=end_time - 3600 * 3, # 取最近3小时
end_time=end_time
)[0]["data"]
# 每根: [timestamp, open, high, low, close, volume]
formatted = []
for k in response:
formatted.append({
'id': int(k["timestamp"]),
'open': float(k["open_price"]),
'high': float(k["high_price"]),
'low': float(k["low_price"]),
'close': float(k["close_price"])
})
formatted.sort(key=lambda x: x['id'])
# 返回最近2根K线倒数第二根上一根和最后一根当前
if len(formatted) >= 2:
return formatted[-2], formatted[-1]
return None, None
except Exception as e:
logger.error(f"获取K线异常: {e}")
self.ding(text="获取K线异常", error=True)
return None, None
def get_current_price(self):
"""获取当前最新价格"""
try:
end_time = int(time.time())
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=1, # 1分钟
start_time=end_time - 3600 * 1, # 取最近1小时
end_time=end_time
)[0]
if response['code'] == 1000:
return float(response['data'][-1]["close_price"])
return None
except Exception as e:
logger.error(f"获取价格异常: {e}")
return None
def get_available_balance(self):
"""获取合约账户可用USDT余额"""
try:
response = self.contractAPI.get_assets_detail()[0]
if response['code'] == 1000:
data = response['data']
if isinstance(data, dict):
return float(data.get('available_balance', 0))
elif isinstance(data, list):
for asset in data:
if asset.get('currency') == 'USDT':
return float(asset.get('available_balance', 0))
return None
except Exception as e:
logger.error(f"余额查询异常: {e}")
return None
def get_position_status(self):
"""获取当前持仓方向"""
try:
response = self.contractAPI.get_position(contract_symbol=self.contract_symbol)[0]
if response['code'] == 1000:
positions = response['data']
if not positions:
self.start = 0
self.open_avg_price = None
self.current_amount = None
self.unrealized_pnl = None
return True
pos = positions[0]
self.start = 1 if pos['position_type'] == 1 else -1
self.open_avg_price = float(pos['open_avg_price'])
self.current_amount = float(pos['current_amount'])
self.position_cross = pos["position_cross"]
# 直接从API获取未实现盈亏Bitmart返回的是 unrealized_value 字段)
self.unrealized_pnl = float(pos.get('unrealized_value', 0))
logger.debug(f"持仓详情: 方向={self.start}, 开仓均价={self.open_avg_price}, "
f"持仓量={self.current_amount}, 未实现盈亏={self.unrealized_pnl:.2f}")
return True
else:
return False
except Exception as e:
logger.error(f"持仓查询异常: {e}")
return False
def get_unrealized_pnl_usd(self):
"""
获取当前持仓未实现盈亏美元直接使用API返回值
"""
if self.start == 0 or self.unrealized_pnl is None:
return None
return self.unrealized_pnl
def set_leverage(self):
"""程序启动时设置全仓 + 高杠杆"""
try:
response = self.contractAPI.post_submit_leverage(
contract_symbol=self.contract_symbol,
leverage=self.leverage,
open_type=self.open_type
)[0]
if response['code'] == 1000:
logger.success(f"全仓模式 + {self.leverage}x 杠杆设置成功")
return True
else:
logger.error(f"杠杆设置失败: {response}")
return False
except Exception as e:
logger.error(f"设置杠杆异常: {e}")
return False
def openBrowser(self):
"""打开 TGE 对应浏览器实例"""
try:
bit_port = openBrowser(id=self.bit_id)
co = ChromiumOptions()
co.set_local_port(port=bit_port)
self.page = ChromiumPage(addr_or_opts=co)
return True
except:
return False
def click_safe(self, xpath, sleep=0.5):
"""安全点击"""
try:
ele = self.page.ele(xpath)
if not ele:
return False
# ele.scroll.to_see(center=True)
# time.sleep(sleep)
ele.click(by_js=True)
return True
except:
return False
def 平仓(self):
"""平仓操作"""
self.click_safe('x://span[normalize-space(text()) ="市价"]')
def 开单(self, marketPriceLongOrder=0, limitPriceShortOrder=0, size=None, price=None):
"""
marketPriceLongOrder 市价做多或者做空1是做多-1是做空
limitPriceShortOrder 限价做多或者做空
"""
if marketPriceLongOrder == -1:
# self.click_safe('x://button[normalize-space(text()) ="市价"]')
# self.page.ele('x://*[@id="size_0"]').input(vals=size, clear=True)
self.click_safe('x://span[normalize-space(text()) ="卖出/做空"]')
elif marketPriceLongOrder == 1:
# self.click_safe('x://button[normalize-space(text()) ="市价"]')
# self.page.ele('x://*[@id="size_0"]').input(vals=size, clear=True)
self.click_safe('x://span[normalize-space(text()) ="买入/做多"]')
if limitPriceShortOrder == -1:
self.click_safe('x://button[normalize-space(text()) ="限价"]')
self.page.ele('x://*[@id="price_0"]').input(vals=price, clear=True)
time.sleep(1)
self.page.ele('x://*[@id="size_0"]').input(1)
self.click_safe('x://span[normalize-space(text()) ="卖出/做空"]')
elif limitPriceShortOrder == 1:
self.click_safe('x://button[normalize-space(text()) ="限价"]')
self.page.ele('x://*[@id="price_0"]').input(vals=price, clear=True)
time.sleep(1)
self.page.ele('x://*[@id="size_0"]').input(1)
self.click_safe('x://span[normalize-space(text()) ="买入/做多"]')
def ding(self, text, error=False):
"""日志通知"""
if error:
logger.error(text)
else:
logger.info(text)
def calculate_entity(self, kline):
"""计算K线实体大小绝对值"""
return abs(kline['close'] - kline['open'])
def calculate_upper_shadow(self, kline):
"""计算上阴线(上影线)涨幅百分比"""
# 上阴线 = (最高价 - max(开盘价, 收盘价)) / max(开盘价, 收盘价)
body_top = max(kline['open'], kline['close'])
if body_top == 0:
return 0
return (kline['high'] - body_top) / body_top * 100
def calculate_lower_shadow(self, kline):
"""计算下阴线(下影线)跌幅百分比"""
# 下阴线 = (min(开盘价, 收盘价) - 最低价) / min(开盘价, 收盘价)
body_bottom = min(kline['open'], kline['close'])
if body_bottom == 0:
return 0
return (body_bottom - kline['low']) / body_bottom * 100
def get_entity_edge(self, kline):
"""获取K线实体边收盘价或开盘价取决于是阳线还是阴线"""
# 阳线(收盘>开盘):实体上边=收盘价,实体下边=开盘价
# 阴线(收盘<开盘):实体上边=开盘价,实体下边=收盘价
return {
'upper': max(kline['open'], kline['close']), # 实体上边
'lower': min(kline['open'], kline['close']) # 实体下边
}
def check_signal(self, current_price, prev_kline, current_kline):
"""
检查交易信号
返回: ('long', trigger_price) / ('short', trigger_price) / None
"""
# 计算上一根K线实体
prev_entity = self.calculate_entity(prev_kline)
# 实体过小不交易(实体 < 0.1
if prev_entity < 0.1:
logger.info(f"上一根K线实体过小: {prev_entity:.4f},跳过信号检测")
return None
# 获取上一根K线的实体上下边
prev_entity_edge = self.get_entity_edge(prev_kline)
prev_entity_upper = prev_entity_edge['upper'] # 实体上边
prev_entity_lower = prev_entity_edge['lower'] # 实体下边
# 优化:以下两种情况以当前这根的开盘价作为计算基准
# 1) 上一根阳线 且 当前开盘价 > 上一根收盘价(跳空高开)
# 2) 上一根阴线 且 当前开盘价 < 上一根收盘价(跳空低开)
prev_is_bullish_for_calc = prev_kline['close'] > prev_kline['open']
prev_is_bearish_for_calc = prev_kline['close'] < prev_kline['open']
current_open_above_prev_close = current_kline['open'] > prev_kline['close']
current_open_below_prev_close = current_kline['open'] < prev_kline['close']
use_current_open_as_base = (prev_is_bullish_for_calc and current_open_above_prev_close) or (prev_is_bearish_for_calc and current_open_below_prev_close)
if use_current_open_as_base:
# 以当前K线开盘价为基准计算跳空时用当前开盘价参与计算
calc_lower = current_kline['open']
calc_upper = current_kline['open'] # 同一基准,上下四分之一对称
long_trigger = calc_lower + prev_entity / 4
short_trigger = calc_upper - prev_entity / 4
long_breakout = calc_upper + prev_entity / 4
short_breakout = calc_lower - prev_entity / 4
else:
# 原有计算方式
long_trigger = prev_entity_lower + prev_entity / 4 # 做多触发价 = 实体下边 + 实体/4下四分之一处
short_trigger = prev_entity_upper - prev_entity / 4 # 做空触发价 = 实体上边 - 实体/4上四分之一处
long_breakout = prev_entity_upper + prev_entity / 4 # 做多突破价 = 实体上边 + 实体/4
short_breakout = prev_entity_lower - prev_entity / 4 # 做空突破价 = 实体下边 - 实体/4
# 上一根阴线 + 当前阳线做多形态不按上一根K线上三分之一做空
prev_is_bearish = prev_kline['close'] < prev_kline['open']
current_is_bullish = current_kline['close'] > current_kline['open']
skip_short_by_upper_third = prev_is_bearish and current_is_bullish
# 上一根阳线 + 当前阴线做空形态不按上一根K线下三分之一做多
prev_is_bullish = prev_kline['close'] > prev_kline['open']
current_is_bearish = current_kline['close'] < current_kline['open']
skip_long_by_lower_third = prev_is_bullish and current_is_bearish
if use_current_open_as_base:
if prev_is_bullish_for_calc and current_open_above_prev_close:
logger.info(f"上一根阳线且当前开盘价({current_kline['open']:.2f})>上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
else:
logger.info(f"上一根阴线且当前开盘价({current_kline['open']:.2f})<上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
logger.info(f"当前价格: {current_price:.2f}, 上一根实体: {prev_entity:.4f}")
logger.info(f"上一根实体上边: {prev_entity_upper:.2f}, 下边: {prev_entity_lower:.2f}")
logger.info(f"做多触发价(下1/4): {long_trigger:.2f}, 做空触发价(上1/4): {short_trigger:.2f}")
logger.info(f"突破做多价(上1/4外): {long_breakout:.2f}, 突破做空价(下1/4外): {short_breakout:.2f}")
if skip_short_by_upper_third:
logger.info("上一根阴线+当前阳线(做多形态),不按上四分之一做空")
if skip_long_by_lower_third:
logger.info("上一根阳线+当前阴线(做空形态),不按下四分之一做多")
# 无持仓时检查开仓信号
if self.start == 0:
if current_price >= long_breakout and not skip_long_by_lower_third:
logger.info(f"触发做多信号!价格 {current_price:.2f} >= 突破价(上1/4外) {long_breakout:.2f}")
return ('long', long_breakout)
elif current_price <= short_breakout and not skip_short_by_upper_third:
logger.info(f"触发做空信号!价格 {current_price:.2f} <= 突破价(下1/4外) {short_breakout:.2f}")
return ('short', short_breakout)
# 持仓时检查反手信号
elif self.start == 1: # 持多仓
# 反手条件1: 价格跌到上一根K线的上三分之一处做空触发价上一根阴线+当前阳线做多时跳过
if current_price <= short_trigger and not skip_short_by_upper_third:
logger.info(f"持多反手做空!价格 {current_price:.2f} <= 触发价(上1/4) {short_trigger:.2f}")
return ('reverse_short', short_trigger)
# 反手条件2: 上一根K线上阴线涨幅>0.01%,当前跌到上一根实体下边
upper_shadow_pct = self.calculate_upper_shadow(prev_kline)
if upper_shadow_pct > 0.01 and current_price <= prev_entity_lower:
logger.info(f"持多反手做空!上阴线涨幅 {upper_shadow_pct:.4f}% > 0.01%"
f"价格 {current_price:.2f} <= 实体下边 {prev_entity_lower:.2f}")
return ('reverse_short', prev_entity_lower)
elif self.start == -1: # 持空仓
# 反手条件1: 价格涨到上一根K线的下三分之一处做多触发价上一根阳线+当前阴线做空时跳过
if current_price >= long_trigger and not skip_long_by_lower_third:
logger.info(f"持空反手做多!价格 {current_price:.2f} >= 触发价(下1/4) {long_trigger:.2f}")
return ('reverse_long', long_trigger)
# 反手条件2: 上一根K线下阴线跌幅>0.01%,当前涨到上一根实体上边
lower_shadow_pct = self.calculate_lower_shadow(prev_kline)
if lower_shadow_pct > 0.01 and current_price >= prev_entity_upper:
logger.info(f"持空反手做多!下阴线跌幅 {lower_shadow_pct:.4f}% > 0.01%"
f"价格 {current_price:.2f} >= 实体上边 {prev_entity_upper:.2f}")
return ('reverse_long', prev_entity_upper)
return None
def can_open(self, current_kline_id):
"""开仓前过滤:同一根 K 线只开一次 + 开仓冷却时间。仅用于 long/short 新开仓。"""
now = time.time()
if self.last_open_kline_id is not None and self.last_open_kline_id == current_kline_id:
logger.info(f"开仓频率控制:本 K 线({current_kline_id})已开过仓,跳过")
return False
if self.last_open_time is not None and now - self.last_open_time < self.open_cooldown_seconds:
remain = self.open_cooldown_seconds - (now - self.last_open_time)
logger.info(f"开仓冷却中,剩余 {remain:.0f}")
return False
return True
def can_reverse(self, current_price, trigger_price):
"""反手前过滤:冷却时间 + 最小价差"""
now = time.time()
if self.last_reverse_time and now - self.last_reverse_time < self.reverse_cooldown_seconds:
remain = self.reverse_cooldown_seconds - (now - self.last_reverse_time)
logger.info(f"反手冷却中,剩余 {remain:.0f}")
return False
if trigger_price and trigger_price > 0:
move_pct = abs(current_price - trigger_price) / trigger_price * 100
if move_pct < self.reverse_min_move_pct:
logger.info(f"反手价差不足: {move_pct:.4f}% < {self.reverse_min_move_pct}%")
return False
return True
def verify_no_position(self, max_retries=5, retry_interval=3):
"""
验证当前无持仓
返回: True 表示无持仓可以开仓False 表示有持仓不能开仓
"""
for i in range(max_retries):
if self.get_position_status():
if self.start == 0:
logger.info(f"确认无持仓,可以开仓")
return True
else:
logger.warning(
f"仍有持仓 (方向: {self.start}),等待 {retry_interval} 秒后重试 ({i + 1}/{max_retries})")
time.sleep(retry_interval)
else:
logger.warning(f"查询持仓状态失败,等待 {retry_interval} 秒后重试 ({i + 1}/{max_retries})")
time.sleep(retry_interval)
logger.error(f"经过 {max_retries} 次重试仍有持仓或查询失败,放弃开仓")
return False
def verify_position_direction(self, expected_direction):
"""
验证当前持仓方向是否与预期一致
expected_direction: 1 多仓, -1 空仓
返回: True 表示持仓方向正确False 表示不正确
"""
if self.get_position_status():
if self.start == expected_direction:
logger.info(f"持仓方向验证成功: {self.start}")
return True
else:
logger.warning(f"持仓方向不符: 期望 {expected_direction}, 实际 {self.start}")
return False
else:
logger.error("查询持仓状态失败")
return False
def execute_trade(self, signal, size=None):
"""执行交易。size 不传或为 None 时使用 default_order_size。"""
signal_type, trigger_price = signal
size = self.default_order_size if size is None else size
if signal_type == 'long':
# 开多前先确认无持仓
logger.info(f"准备开多,触发价: {trigger_price:.2f}")
if not self.get_position_status():
logger.error("开仓前查询持仓状态失败,放弃开仓")
return False
if self.start != 0:
logger.warning(f"开多前发现已有持仓 (方向: {self.start}),放弃开仓避免双向持仓")
return False
logger.info(f"确认无持仓,执行开多")
self.开单(marketPriceLongOrder=1, size=size)
time.sleep(3) # 等待订单执行
# 验证开仓是否成功
if self.verify_position_direction(1):
self.max_unrealized_pnl_seen = None # 新仓位重置移动止损记录
self.last_open_time = time.time()
self.last_open_kline_id = getattr(self, "_current_kline_id_for_open", None)
logger.success("开多成功")
return True
else:
logger.error("开多后持仓验证失败")
return False
elif signal_type == 'short':
# 开空前先确认无持仓
logger.info(f"准备开空,触发价: {trigger_price:.2f}")
if not self.get_position_status():
logger.error("开仓前查询持仓状态失败,放弃开仓")
return False
if self.start != 0:
logger.warning(f"开空前发现已有持仓 (方向: {self.start}),放弃开仓避免双向持仓")
return False
logger.info(f"确认无持仓,执行开空")
self.开单(marketPriceLongOrder=-1, size=size)
time.sleep(3) # 等待订单执行
# 验证开仓是否成功
if self.verify_position_direction(-1):
self.max_unrealized_pnl_seen = None # 新仓位重置移动止损记录
self.last_open_time = time.time()
self.last_open_kline_id = getattr(self, "_current_kline_id_for_open", None)
logger.success("开空成功")
return True
else:
logger.error("开空后持仓验证失败")
return False
elif signal_type == 'reverse_long':
# 平空 + 开多(反手做多):先平仓,确认无仓后再开多,避免双向持仓
logger.info(f"执行反手做多,触发价: {trigger_price:.2f}")
self.平仓()
time.sleep(1) # 给交易所处理平仓的时间
# 轮询确认已无持仓再开多(最多等约 10 秒)
for _ in range(10):
if self.get_position_status() and self.start == 0:
break
time.sleep(1)
if self.start != 0:
logger.warning("反手做多:平仓后仍有持仓,放弃本次开多")
return False
logger.info("已确认无持仓,执行开多")
self.开单(marketPriceLongOrder=1, size=size)
time.sleep(3)
if self.verify_position_direction(1):
self.max_unrealized_pnl_seen = None
logger.success("反手做多成功")
self.last_reverse_time = time.time()
time.sleep(20)
return True
else:
logger.error("反手做多后持仓验证失败")
return False
elif signal_type == 'reverse_short':
# 平多 + 开空(反手做空):先平仓,确认无仓后再开空
logger.info(f"执行反手做空,触发价: {trigger_price:.2f}")
self.平仓()
time.sleep(1)
for _ in range(10):
if self.get_position_status() and self.start == 0:
break
time.sleep(1)
if self.start != 0:
logger.warning("反手做空:平仓后仍有持仓,放弃本次开空")
return False
logger.info("已确认无持仓,执行开空")
self.开单(marketPriceLongOrder=-1, size=size)
time.sleep(3)
if self.verify_position_direction(-1):
self.max_unrealized_pnl_seen = None
logger.success("反手做空成功")
self.last_reverse_time = time.time()
time.sleep(20)
return True
else:
logger.error("反手做空后持仓验证失败")
return False
return False
def action(self):
"""主循环"""
logger.info("开始运行四分之一策略交易...")
# 启动时设置全仓高杠杆
if not self.set_leverage():
logger.error("杠杆设置失败,程序继续运行但可能下单失败")
return
page_start = True
while True:
if page_start:
# 打开浏览器
for i in range(5):
if self.openBrowser():
logger.info("浏览器打开成功")
break
else:
self.ding("打开浏览器失败!", error=True)
return
# 进入交易页面
self.page.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
self.click_safe('x://button[normalize-space(text()) ="市价"]')
self.page.ele('x://*[@id="size_0"]').input(vals=25, clear=True)
page_start = False
try:
# 1. 获取K线数据当前K线和上一根K线
prev_kline, current_kline = self.get_klines()
if not prev_kline or not current_kline:
logger.warning("获取K线失败等待重试...")
time.sleep(5)
continue
# 记录进入新的K线
current_kline_time = current_kline['id']
if self.last_kline_time != current_kline_time:
self.last_kline_time = current_kline_time
logger.info(f"进入新K线: {current_kline_time}")
# 2. 获取当前价格
current_price = self.get_current_price()
if not current_price:
logger.warning("获取价格失败,等待重试...")
time.sleep(2)
continue
# 3. 每次循环都通过SDK获取真实持仓状态避免状态不同步导致双向持仓
if not self.get_position_status():
logger.warning("获取持仓状态失败,等待重试...")
time.sleep(2)
continue
logger.debug(f"当前持仓状态: {self.start} (0=无, 1=多, -1=空)")
# 3.5 止损/止盈/移动止损
if self.start != 0:
pnl_usd = self.get_unrealized_pnl_usd()
if pnl_usd is not None:
# 固定止损:亏损达到 3 美元平仓
if pnl_usd <= self.stop_loss_usd:
logger.info(f"仓位亏损 {pnl_usd:.2f} 美元 <= 止损 {self.stop_loss_usd} 美元,执行止损平仓")
self.平仓()
self.max_unrealized_pnl_seen = None
time.sleep(3)
continue
# 更新持仓期间最大盈利(用于移动止损)
if self.max_unrealized_pnl_seen is None:
self.max_unrealized_pnl_seen = pnl_usd
else:
self.max_unrealized_pnl_seen = max(self.max_unrealized_pnl_seen, pnl_usd)
# 移动止损:盈利曾达到 activation 后,从最高盈利回撤 trailing_distance 则平仓
if self.max_unrealized_pnl_seen >= self.trailing_activation_usd:
if pnl_usd < self.max_unrealized_pnl_seen - self.trailing_distance_usd:
logger.info(f"移动止损:当前盈利 {pnl_usd:.2f} 从最高 {self.max_unrealized_pnl_seen:.2f} 回撤 >= {self.trailing_distance_usd} 美元,平仓")
self.平仓()
self.max_unrealized_pnl_seen = None
time.sleep(3)
continue
# 止盈:盈利达到 take_profit_usd 平仓
if pnl_usd >= self.take_profit_usd:
logger.info(f"仓位盈利 {pnl_usd:.2f} 美元 >= {self.take_profit_usd} 美元,执行止盈平仓")
self.平仓()
self.max_unrealized_pnl_seen = None
time.sleep(3)
continue
# 4. 检查信号
signal = self.check_signal(current_price, prev_kline, current_kline)
# 5. 反手过滤:冷却时间 + 最小价差
if signal and signal[0].startswith('reverse_'):
if not self.can_reverse(current_price, signal[1]):
signal = None
# 5.5 开仓频率过滤:同一根 K 线只开一次 + 开仓冷却
if signal and signal[0] in ('long', 'short'):
if not self.can_open(current_kline_time):
signal = None
else:
self._current_kline_id_for_open = current_kline_time # 供 execute_trade 成功后记录
# 6. 有信号则执行交易
if signal:
trade_success = self.execute_trade(signal)
if trade_success:
logger.success(f"交易执行完成: {signal[0]}, 当前持仓状态: {self.start}")
page_start = True
else:
logger.warning(f"交易执行失败或被阻止: {signal[0]}")
# 短暂等待后继续循环同一根K线遇到信号就操作
time.sleep(0.1)
if page_start:
self.page.close()
time.sleep(5)
except KeyboardInterrupt:
logger.info("用户中断,程序退出")
break
except Exception as e:
logger.error(f"主循环异常: {e}")
time.sleep(5)
if __name__ == '__main__':
BitmartFuturesTransaction(bit_id="f2320f57e24c45529a009e1541e25961").action()

View File

@@ -0,0 +1,992 @@
import sys
import time
from datetime import datetime
from tqdm import tqdm
from loguru import logger
from bit_tools import openBrowser
from DrissionPage import ChromiumPage
from DrissionPage import ChromiumOptions
from bitmart.api_contract import APIContract
from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.layout import Layout
from rich.align import Align
from rich.text import Text
from rich.live import Live
# 是否使用 Rich 仪表盘(否则用 loguru 普通输出)
USE_RICH_DASHBOARD = True
console = Console()
# 颜色标签loguru 用,无 Rich 时)
_R = "\033[0m"
_B = "\033[1m"
_C = "\033[36m"
_Y = "\033[33m"
_G = "\033[32m"
_M = "\033[90m"
_W = "\033[97m"
def _tag(t: str, color: str) -> str:
return color + "[" + t + "]" + _R + " "
LOG_PRICE = _tag("价格", _C)
LOG_SIGNAL = _tag("信号", _Y)
LOG_POSITION = _tag("仓位", _G)
LOG_SYSTEM = _tag("系统", _M)
if not USE_RICH_DASHBOARD:
logger.remove()
logger.add(sys.stderr, format="\033[2m│\033[0m {message}", colorize=False)
def log_kline_header(kline_id):
"""新 K 线分块头(仅非 Rich 模式使用)"""
s = f" K 线 {kline_id} "
width = max(52, len(s) + 4)
line = "" * (width - 2)
pad_left = (width - 2 - len(s)) // 2
pad_right = width - 2 - len(s) - pad_left
logger.info(_M + "" + line + "" + _R)
logger.info(_M + "" + _R + " " * pad_left + _B + _W + s + _R + " " * pad_right + _M + "" + _R)
logger.info(_M + "" + line + "" + _R)
# ---------- Rich 仪表盘 ----------
def make_header() -> Panel:
title = Text("四分之一策略 · ETHUSDT 5m", style="bold cyan")
subtitle = Text(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), style="dim")
return Panel(Align.center(title + Text("\n") + subtitle), border_style="cyan")
def make_metrics_panel(state: dict) -> Panel:
t = Table(show_header=True, header_style="bold magenta", expand=True)
t.add_column("指标", style="cyan")
t.add_column("数值", justify="right", style="green")
t.add_row("当前价", f"{state.get('price', 0):.2f}")
pos_map = {0: "", 1: "", -1: ""}
t.add_row("持仓", pos_map.get(state.get("position", 0), "?"))
t.add_row("K线 ID", str(state.get("kline_id", "-")))
t.add_row("做多触发", f"{state.get('long_trigger', 0):.2f}")
t.add_row("做空触发", f"{state.get('short_trigger', 0):.2f}")
t.add_row("突破做多", f"{state.get('long_breakout', 0):.2f}")
t.add_row("突破做空", f"{state.get('short_breakout', 0):.2f}")
ema10 = state.get("ema10")
atr14 = state.get("atr14")
t.add_row("EMA10", f"{ema10:.2f}" if ema10 is not None else "-")
t.add_row("ATR14", f"{atr14:.2f}" if atr14 is not None else "-")
pnl = state.get("unrealized_pnl")
t.add_row("未实现盈亏", f"{pnl:.2f}$" if pnl is not None else "-")
return Panel(t, title="[bold]价格 / 指标[/bold]", border_style="magenta")
def make_logs_panel(logs: list) -> Panel:
body = "\n".join(logs[-12:]) if logs else "等待日志..."
text = Text.from_ansi(body) if body else Text("等待日志...", style="dim")
return Panel(text, title="[bold]状态 / 日志[/bold]", border_style="green")
def make_footer(msg: str = "Ctrl+C 退出") -> Panel:
return Panel(Align.center(Text(msg, style="bold yellow")), border_style="yellow")
def build_dashboard_layout(state: dict, logs: list) -> Layout:
layout = Layout()
layout.split_column(
Layout(make_header(), name="header", size=5),
Layout(name="body", ratio=1),
Layout(make_footer(), name="footer", size=3),
)
layout["body"].split_row(
Layout(make_metrics_panel(state), name="left", ratio=1),
Layout(make_logs_panel(logs), name="right", ratio=2),
)
return layout
class BitmartFuturesTransaction:
def __init__(self, bit_id):
self.page: ChromiumPage | None = None
self.api_key = "a0fb7b98464fd9bcce67e7c519d58ec10d0c38a8"
self.secret_key = "4eaeba78e77aeaab1c2027f846a276d164f264a44c2c1bb1c5f3be50c8de1ca5"
self.memo = "合约交易"
self.contract_symbol = "ETHUSDT"
self.contractAPI = APIContract(self.api_key, self.secret_key, self.memo, timeout=(5, 15))
self.start = 0 # 持仓状态: -1 空, 0 无, 1 多
self.pbar = tqdm(total=30, desc="等待K线", ncols=80) # 可选:用于长时间等待时展示进度
self.last_kline_time = None # 上一次处理的K线时间戳用于判断是否是新K线
# 反手频率控制
self.reverse_cooldown_seconds = 1.5 * 60 # 反手冷却时间(秒)
self.reverse_min_move_pct = 0.05 # 反手最小价差过滤(百分比)
self.last_reverse_time = None # 上次反手时间
# 开仓频率控制
self.open_cooldown_seconds = 60 # 开仓冷却时间(秒),两次开仓至少间隔此时长
self.last_open_time = None # 上次开仓时间
self.last_open_kline_id = None # 上次开仓所在 K 线 id仅记录不限制单 K 线开仓次数)
self.leverage = "100" # 高杠杆(全仓模式下可开更大仓位)
self.open_type = "cross" # 全仓模式
self.risk_percent = 0 # 未使用;若启用则可为每次开仓占可用余额的百分比
self.stop_loss_usd = -3 # 固定止损:亏损达到 3 美元平仓
self.trailing_activation_usd = 2 # 盈利达到此金额后启动移动止损
self.trailing_distance_usd = 1.5 # 从最高盈利回撤此金额则平仓
self.max_unrealized_pnl_seen = None # 持仓期间见过的最大盈利(用于移动止损)
# 当前K线从极值回落平仓
# 模式: 'fixed'=固定点数(drop_from_high_to_close)'pct_retrace'=按本K线涨幅比例动态算回撤
self.drop_from_high_mode = 'pct_retrace' # 'fixed' | 'pct_retrace'
self.drop_from_high_to_close = 2 # fixed 模式下:回落/反弹超过此价格点数则平仓0 表示关闭
# pct_retrace 模式本K线涨幅 = (最高-开盘)/开盘*100允许回撤% = 涨幅% * retrace_ratio从最高点回撤超过则平仓
self.retrace_ratio = 0.5 # 回撤系数,如 0.5 表示允许回撤涨幅的 50%(类似斐波那契 50% 回撤)
self.min_rise_pct_to_activate = 0.02 # 至少涨/跌这么多才启用动态回撤,避免噪音
self.min_drop_pct_from_high = 0.03 # 至少从最高点回撤这么多%才平仓(保底,避免过于敏感)
# EMA(10) + ATR(14) 平仓(多/空一致):多单跌破 EMA10 或从最高回撤≥ATR 平;空单涨破 EMA10 或从最低反弹≥ATR 平
self.use_ema_atr_exit = True # 是否启用 EMA/ATR 平仓规则(多单+空单)
self.atr_multiplier = 1.1 # 追踪止盈:从极值回撤/反弹 ≥ 此倍数 × ATR(14) 则平仓
self._candle_high_seen = None # 当前K线内见过的最高价多头用
self._candle_low_seen = None # 当前K线内见过的最低价空头用
self._candle_id_for_high_low = None # 记录高低对应的K线 id换线则重置
self.open_avg_price = None # 开仓价格
self.current_amount = None # 持仓量
self.bit_id = bit_id
self.default_order_size = 25 # 开仓/反手张数,统一在此修改
# 策略相关变量
self.prev_kline = None
self.current_kline = None
self.prev_entity = None
self.current_open = None
# Rich 仪表盘:状态与日志(供 build_dashboard_layout 使用)
self._display_state = {}
self._display_logs = []
self._display_triggers = {}
def get_klines(self):
"""获取最近2根K线当前K线和上一根K线"""
try:
end_time = int(time.time())
# 获取足够多的条目确保有最新的K线
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=5, # 5分钟
start_time=end_time - 3600 * 3, # 取最近3小时
end_time=end_time
)[0]["data"]
# 每根: [timestamp, open, high, low, close, volume]
formatted = []
for k in response:
formatted.append({
'id': int(k["timestamp"]),
'open': float(k["open_price"]),
'high': float(k["high_price"]),
'low': float(k["low_price"]),
'close': float(k["close_price"])
})
formatted.sort(key=lambda x: x['id'])
# 返回最近2根K线倒数第二根上一根和最后一根当前
if len(formatted) >= 2:
return formatted[-2], formatted[-1]
return None, None
except Exception as e:
logger.error(f"获取K线异常: {e}")
self.ding(text="获取K线异常", error=True)
return None, None
def get_klines_series(self, count=35):
"""获取最近 count 根 5 分钟 K 线(用于 EMA/ATR按时间正序。最后一根为当前未收盘 K 线。"""
try:
end_time = int(time.time())
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=5,
start_time=end_time - 3600 * 4,
end_time=end_time
)[0]["data"]
formatted = []
for k in response:
formatted.append({
'id': int(k["timestamp"]),
'open': float(k["open_price"]),
'high': float(k["high_price"]),
'low': float(k["low_price"]),
'close': float(k["close_price"])
})
formatted.sort(key=lambda x: x['id'])
return formatted[-count:] if len(formatted) >= count else formatted
except Exception as e:
logger.error(f"获取K线序列异常: {e}")
return []
@staticmethod
def _ema(series, period):
"""对序列 series从旧到新计算 EMA(period),返回最后一个 EMA 值。"""
if not series or len(series) < period:
return None
alpha = 2.0 / (period + 1)
ema = sum(series[:period]) / period # 用前 period 根收盘的 SMA 做种子
for i in range(period, len(series)):
ema = alpha * series[i] + (1 - alpha) * ema
return ema
@staticmethod
def _atr(klines, period=14):
"""对 klines从旧到新每项含 high/low/close计算 ATR(period),返回最后一个 ATR 值。"""
if not klines or len(klines) < period + 1:
return None
tr_list = []
for i in range(1, len(klines)):
high, low = klines[i]['high'], klines[i]['low']
prev_close = klines[i - 1]['close']
tr = max(high - low, abs(high - prev_close), abs(low - prev_close))
tr_list.append(tr)
if len(tr_list) < period:
return None
# ATR = EMA(TR, period)
alpha = 2.0 / (period + 1)
atr = sum(tr_list[:period]) / period
for i in range(period, len(tr_list)):
atr = alpha * tr_list[i] + (1 - alpha) * atr
return atr
def get_ema_atr_for_exit(self, kline_series):
"""
基于已收盘 K 线计算 EMA10、EMA20、ATR(14)。
kline_series 最后一根可为当前未收盘 K 线,计算时用倒数第 2~N 根作为已收盘。
返回 (ema10, ema20, atr14),任一不足则对应为 None。
"""
if not kline_series or len(kline_series) < 21:
return None, None, None
# 用除最后一根外的已收盘 K 线(若只有 21 根则用前 20 根)
closed = kline_series[:-1] if len(kline_series) >= 21 else kline_series[:20]
closes = [k['close'] for k in closed]
ema10 = self._ema(closes, 10)
ema20 = self._ema(closes, 20)
atr14 = self._atr(closed, 14)
return ema10, ema20, atr14
def get_current_price(self):
"""获取当前最新价格"""
try:
end_time = int(time.time())
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=1, # 1分钟
start_time=end_time - 3600 * 1, # 取最近1小时
end_time=end_time
)[0]
if response['code'] == 1000:
return float(response['data'][-1]["close_price"])
return None
except Exception as e:
logger.error(f"获取价格异常: {e}")
return None
def get_available_balance(self):
"""获取合约账户可用USDT余额"""
try:
response = self.contractAPI.get_assets_detail()[0]
if response['code'] == 1000:
data = response['data']
if isinstance(data, dict):
return float(data.get('available_balance', 0))
elif isinstance(data, list):
for asset in data:
if asset.get('currency') == 'USDT':
return float(asset.get('available_balance', 0))
return None
except Exception as e:
logger.error(f"余额查询异常: {e}")
return None
def get_position_status(self):
"""获取当前持仓方向"""
try:
response = self.contractAPI.get_position(contract_symbol=self.contract_symbol)[0]
if response['code'] == 1000:
positions = response['data']
if not positions:
self.start = 0
self.open_avg_price = None
self.current_amount = None
self.unrealized_pnl = None
return True
pos = positions[0]
self.start = 1 if pos['position_type'] == 1 else -1
self.open_avg_price = float(pos['open_avg_price'])
self.current_amount = float(pos['current_amount'])
self.position_cross = pos["position_cross"]
# 直接从API获取未实现盈亏Bitmart返回的是 unrealized_value 字段)
self.unrealized_pnl = float(pos.get('unrealized_value', 0))
logger.debug(f"持仓详情: 方向={self.start}, 开仓均价={self.open_avg_price}, "
f"持仓量={self.current_amount}, 未实现盈亏={self.unrealized_pnl:.2f}")
return True
else:
return False
except Exception as e:
logger.error(f"持仓查询异常: {e}")
return False
def get_unrealized_pnl_usd(self):
"""
获取当前持仓未实现盈亏美元直接使用API返回值
"""
if self.start == 0 or self.unrealized_pnl is None:
return None
return self.unrealized_pnl
def set_leverage(self):
"""程序启动时设置全仓 + 高杠杆"""
try:
response = self.contractAPI.post_submit_leverage(
contract_symbol=self.contract_symbol,
leverage=self.leverage,
open_type=self.open_type
)[0]
if response['code'] == 1000:
logger.success(f"全仓模式 + {self.leverage}x 杠杆设置成功")
return True
else:
logger.error(f"杠杆设置失败: {response}")
return False
except Exception as e:
logger.error(f"设置杠杆异常: {e}")
return False
def openBrowser(self):
"""打开 TGE 对应浏览器实例"""
try:
bit_port = openBrowser(id=self.bit_id)
co = ChromiumOptions()
co.set_local_port(port=bit_port)
self.page = ChromiumPage(addr_or_opts=co)
return True
except:
return False
def click_safe(self, xpath, sleep=0.5):
"""安全点击"""
try:
ele = self.page.ele(xpath)
if not ele:
return False
# ele.scroll.to_see(center=True)
# time.sleep(sleep)
ele.click(by_js=True)
return True
except:
return False
def 平仓(self):
"""平仓操作"""
self.click_safe('x://span[normalize-space(text()) ="市价"]')
def 开单(self, marketPriceLongOrder=0, limitPriceShortOrder=0, size=None, price=None):
"""
marketPriceLongOrder 市价做多或者做空1是做多-1是做空
limitPriceShortOrder 限价做多或者做空
"""
if marketPriceLongOrder == -1:
# self.click_safe('x://button[normalize-space(text()) ="市价"]')
# self.page.ele('x://*[@id="size_0"]').input(vals=size, clear=True)
self.click_safe('x://span[normalize-space(text()) ="卖出/做空"]')
elif marketPriceLongOrder == 1:
# self.click_safe('x://button[normalize-space(text()) ="市价"]')
# self.page.ele('x://*[@id="size_0"]').input(vals=size, clear=True)
self.click_safe('x://span[normalize-space(text()) ="买入/做多"]')
if limitPriceShortOrder == -1:
self.click_safe('x://button[normalize-space(text()) ="限价"]')
self.page.ele('x://*[@id="price_0"]').input(vals=price, clear=True)
time.sleep(1)
self.page.ele('x://*[@id="size_0"]').input(1)
self.click_safe('x://span[normalize-space(text()) ="卖出/做空"]')
elif limitPriceShortOrder == 1:
self.click_safe('x://button[normalize-space(text()) ="限价"]')
self.page.ele('x://*[@id="price_0"]').input(vals=price, clear=True)
time.sleep(1)
self.page.ele('x://*[@id="size_0"]').input(1)
self.click_safe('x://span[normalize-space(text()) ="买入/做多"]')
def ding(self, text, error=False):
"""日志通知"""
if error:
logger.error(text)
else:
logger.info(text)
def calculate_entity(self, kline):
"""计算K线实体大小绝对值"""
return abs(kline['close'] - kline['open'])
def calculate_upper_shadow(self, kline):
"""计算上阴线(上影线)涨幅百分比"""
# 上阴线 = (最高价 - max(开盘价, 收盘价)) / max(开盘价, 收盘价)
body_top = max(kline['open'], kline['close'])
if body_top == 0:
return 0
return (kline['high'] - body_top) / body_top * 100
def calculate_lower_shadow(self, kline):
"""计算下阴线(下影线)跌幅百分比"""
# 下阴线 = (min(开盘价, 收盘价) - 最低价) / min(开盘价, 收盘价)
body_bottom = min(kline['open'], kline['close'])
if body_bottom == 0:
return 0
return (body_bottom - kline['low']) / body_bottom * 100
def get_entity_edge(self, kline):
"""获取K线实体边收盘价或开盘价取决于是阳线还是阴线"""
# 阳线(收盘>开盘):实体上边=收盘价,实体下边=开盘价
# 阴线(收盘<开盘):实体上边=开盘价,实体下边=收盘价
return {
'upper': max(kline['open'], kline['close']), # 实体上边
'lower': min(kline['open'], kline['close']) # 实体下边
}
def check_signal(self, current_price, prev_kline, current_kline):
"""
检查交易信号
返回: ('long', trigger_price) / ('short', trigger_price) / None
"""
# 计算上一根K线实体
prev_entity = self.calculate_entity(prev_kline)
# 实体过小不交易(实体 < 0.1
if prev_entity < 0.1:
logger.info(LOG_PRICE + f"上一根K线实体过小: {prev_entity:.4f},跳过信号检测")
return None
# 获取上一根K线的实体上下边
prev_entity_edge = self.get_entity_edge(prev_kline)
prev_entity_upper = prev_entity_edge['upper'] # 实体上边
prev_entity_lower = prev_entity_edge['lower'] # 实体下边
# 优化:以下两种情况以当前这根的开盘价作为计算基准
# 1) 上一根阳线 且 当前开盘价 > 上一根收盘价(跳空高开)
# 2) 上一根阴线 且 当前开盘价 < 上一根收盘价(跳空低开)
prev_is_bullish_for_calc = prev_kline['close'] > prev_kline['open']
prev_is_bearish_for_calc = prev_kline['close'] < prev_kline['open']
current_open_above_prev_close = current_kline['open'] > prev_kline['close']
current_open_below_prev_close = current_kline['open'] < prev_kline['close']
use_current_open_as_base = (prev_is_bullish_for_calc and current_open_above_prev_close) or (prev_is_bearish_for_calc and current_open_below_prev_close)
if use_current_open_as_base:
# 以当前K线开盘价为基准计算跳空时用当前开盘价参与计算
calc_lower = current_kline['open']
calc_upper = current_kline['open'] # 同一基准,上下四分之一对称
long_trigger = calc_lower + prev_entity / 4
short_trigger = calc_upper - prev_entity / 4
long_breakout = calc_upper + prev_entity / 4
short_breakout = calc_lower - prev_entity / 4
else:
# 原有计算方式
long_trigger = prev_entity_lower + prev_entity / 4 # 做多触发价 = 实体下边 + 实体/4下四分之一处
short_trigger = prev_entity_upper - prev_entity / 4 # 做空触发价 = 实体上边 - 实体/4上四分之一处
long_breakout = prev_entity_upper + prev_entity / 4 # 做多突破价 = 实体上边 + 实体/4
short_breakout = prev_entity_lower - prev_entity / 4 # 做空突破价 = 实体下边 - 实体/4
# 上一根阴线 + 当前阳线做多形态不按上一根K线上三分之一做空
prev_is_bearish = prev_kline['close'] < prev_kline['open']
current_is_bullish = current_kline['close'] > current_kline['open']
skip_short_by_upper_third = prev_is_bearish and current_is_bullish
# 上一根阳线 + 当前阴线做空形态不按上一根K线下三分之一做多
prev_is_bullish = prev_kline['close'] > prev_kline['open']
current_is_bearish = current_kline['close'] < current_kline['open']
skip_long_by_lower_third = prev_is_bullish and current_is_bearish
if use_current_open_as_base:
if prev_is_bullish_for_calc and current_open_above_prev_close:
logger.info(LOG_PRICE + f"上一根阳线且当前开盘价({current_kline['open']:.2f})>上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
else:
logger.info(LOG_PRICE + f"上一根阴线且当前开盘价({current_kline['open']:.2f})<上一根收盘价({prev_kline['close']:.2f}),以当前开盘价为基准计算")
logger.info(LOG_PRICE + f"当前价: {current_price:.2f} | 上一根实体: {prev_entity:.4f} | 实体上边: {prev_entity_upper:.2f} 下边: {prev_entity_lower:.2f}")
logger.info(LOG_PRICE + f"做多触发(下1/4): {long_trigger:.2f} | 做空触发(上1/4): {short_trigger:.2f} | 突破做多: {long_breakout:.2f} | 突破做空: {short_breakout:.2f}")
if skip_short_by_upper_third:
logger.info(LOG_PRICE + "上一根阴+当前阳(做多形态)不按上1/4做空")
if skip_long_by_lower_third:
logger.info(LOG_PRICE + "上一根阳+当前阴(做空形态)不按下1/4做多")
self._display_triggers = {"long_trigger": long_trigger, "short_trigger": short_trigger, "long_breakout": long_breakout, "short_breakout": short_breakout}
# 无持仓时检查开仓信号
if self.start == 0:
if current_price >= long_breakout and not skip_long_by_lower_third:
logger.info(LOG_SIGNAL + f"触发做多 | 价 {current_price:.2f} >= 突破价 {long_breakout:.2f}")
return ('long', long_breakout)
elif current_price <= short_breakout and not skip_short_by_upper_third:
logger.info(LOG_SIGNAL + f"触发做空 | 价 {current_price:.2f} <= 突破价 {short_breakout:.2f}")
return ('short', short_breakout)
# 持仓时检查反手信号
elif self.start == 1: # 持多仓
if current_price <= short_trigger and not skip_short_by_upper_third:
logger.info(LOG_SIGNAL + f"持多→反手做空 | 价 {current_price:.2f} <= 触发价 {short_trigger:.2f}")
return ('reverse_short', short_trigger)
upper_shadow_pct = self.calculate_upper_shadow(prev_kline)
if upper_shadow_pct > 0.01 and current_price <= prev_entity_lower:
logger.info(LOG_SIGNAL + f"持多→反手做空 | 上阴线 {upper_shadow_pct:.4f}% 价<=实体下边 {prev_entity_lower:.2f}")
return ('reverse_short', prev_entity_lower)
elif self.start == -1: # 持空仓
if current_price >= long_trigger and not skip_long_by_lower_third:
logger.info(LOG_SIGNAL + f"持空→反手做多 | 价 {current_price:.2f} >= 触发价 {long_trigger:.2f}")
return ('reverse_long', long_trigger)
lower_shadow_pct = self.calculate_lower_shadow(prev_kline)
if lower_shadow_pct > 0.01 and current_price >= prev_entity_upper:
logger.info(LOG_SIGNAL + f"持空→反手做多 | 下阴线 {lower_shadow_pct:.4f}% 价>=实体上边 {prev_entity_upper:.2f}")
return ('reverse_long', prev_entity_upper)
return None
def can_open(self, current_kline_id):
"""开仓前过滤:仅开仓冷却时间。单根 K 线符合规则可多次开仓。"""
now = time.time()
if self.last_open_time is not None and now - self.last_open_time < self.open_cooldown_seconds:
remain = self.open_cooldown_seconds - (now - self.last_open_time)
logger.info(LOG_SYSTEM + f"开仓冷却中,剩余 {remain:.0f}")
return False
return True
def can_reverse(self, current_price, trigger_price):
"""反手前过滤:冷却时间 + 最小价差"""
now = time.time()
if self.last_reverse_time and now - self.last_reverse_time < self.reverse_cooldown_seconds:
remain = self.reverse_cooldown_seconds - (now - self.last_reverse_time)
logger.info(LOG_SYSTEM + f"反手冷却中,剩余 {remain:.0f}")
return False
if trigger_price and trigger_price > 0:
move_pct = abs(current_price - trigger_price) / trigger_price * 100
if move_pct < self.reverse_min_move_pct:
logger.info(LOG_SYSTEM + f"反手价差不足: {move_pct:.4f}% < {self.reverse_min_move_pct}%")
return False
return True
def verify_no_position(self, max_retries=5, retry_interval=3):
"""
验证当前无持仓
返回: True 表示无持仓可以开仓False 表示有持仓不能开仓
"""
for i in range(max_retries):
if self.get_position_status():
if self.start == 0:
logger.info(LOG_POSITION + "确认无持仓,可以开仓")
return True
else:
logger.warning(
f"仍有持仓 (方向: {self.start}),等待 {retry_interval} 秒后重试 ({i + 1}/{max_retries})")
time.sleep(retry_interval)
else:
logger.warning(f"查询持仓状态失败,等待 {retry_interval} 秒后重试 ({i + 1}/{max_retries})")
time.sleep(retry_interval)
logger.error(f"经过 {max_retries} 次重试仍有持仓或查询失败,放弃开仓")
return False
def verify_position_direction(self, expected_direction):
"""
验证当前持仓方向是否与预期一致
expected_direction: 1 多仓, -1 空仓
返回: True 表示持仓方向正确False 表示不正确
"""
if self.get_position_status():
if self.start == expected_direction:
logger.info(LOG_POSITION + f"持仓方向验证成功: {self.start}")
return True
else:
logger.warning(f"持仓方向不符: 期望 {expected_direction}, 实际 {self.start}")
return False
else:
logger.error("查询持仓状态失败")
return False
def execute_trade(self, signal, size=None):
"""执行交易。size 不传或为 None 时使用 default_order_size。"""
signal_type, trigger_price = signal
size = self.default_order_size if size is None else size
if signal_type == 'long':
# 开多前先确认无持仓
logger.info(LOG_POSITION + f"准备开多,触发价: {trigger_price:.2f}")
if not self.get_position_status():
logger.error("开仓前查询持仓状态失败,放弃开仓")
return False
if self.start != 0:
logger.warning(f"开多前发现已有持仓 (方向: {self.start}),放弃开仓避免双向持仓")
return False
logger.info(LOG_POSITION + "确认无持仓,执行开多")
self.开单(marketPriceLongOrder=1, size=size)
time.sleep(3) # 等待订单执行
# 验证开仓是否成功
if self.verify_position_direction(1):
self.max_unrealized_pnl_seen = None # 新仓位重置移动止损记录
self.last_open_time = time.time()
self.last_open_kline_id = getattr(self, "_current_kline_id_for_open", None)
logger.success(LOG_POSITION + "开多成功")
return True
else:
logger.error("开多后持仓验证失败")
return False
elif signal_type == 'short':
# 开空前先确认无持仓
logger.info(LOG_POSITION + f"准备开空,触发价: {trigger_price:.2f}")
if not self.get_position_status():
logger.error("开仓前查询持仓状态失败,放弃开仓")
return False
if self.start != 0:
logger.warning(f"开空前发现已有持仓 (方向: {self.start}),放弃开仓避免双向持仓")
return False
logger.info(LOG_POSITION + "确认无持仓,执行开空")
self.开单(marketPriceLongOrder=-1, size=size)
time.sleep(3) # 等待订单执行
# 验证开仓是否成功
if self.verify_position_direction(-1):
self.max_unrealized_pnl_seen = None # 新仓位重置移动止损记录
self.last_open_time = time.time()
self.last_open_kline_id = getattr(self, "_current_kline_id_for_open", None)
logger.success(LOG_POSITION + "开空成功")
return True
else:
logger.error("开空后持仓验证失败")
return False
elif signal_type == 'reverse_long':
# 平空 + 开多(反手做多):先平仓,确认无仓后再开多,避免双向持仓
logger.info(LOG_POSITION + f"执行反手做多,触发价: {trigger_price:.2f}")
self.平仓()
time.sleep(1) # 给交易所处理平仓的时间
# 轮询确认已无持仓再开多(最多等约 10 秒)
for _ in range(10):
if self.get_position_status() and self.start == 0:
break
time.sleep(1)
if self.start != 0:
logger.warning("反手做多:平仓后仍有持仓,放弃本次开多")
return False
logger.info(LOG_POSITION + "已确认无持仓,执行开多")
self.开单(marketPriceLongOrder=1, size=size)
time.sleep(3)
if self.verify_position_direction(1):
self.max_unrealized_pnl_seen = None
logger.success(LOG_POSITION + "反手做多成功")
self.last_reverse_time = time.time()
time.sleep(20)
return True
else:
logger.error("反手做多后持仓验证失败")
return False
elif signal_type == 'reverse_short':
# 平多 + 开空(反手做空):先平仓,确认无仓后再开空
logger.info(LOG_POSITION + f"执行反手做空,触发价: {trigger_price:.2f}")
self.平仓()
time.sleep(1)
for _ in range(10):
if self.get_position_status() and self.start == 0:
break
time.sleep(1)
if self.start != 0:
logger.warning("反手做空:平仓后仍有持仓,放弃本次开空")
return False
logger.info(LOG_POSITION + "已确认无持仓,执行开空")
self.开单(marketPriceLongOrder=-1, size=size)
time.sleep(3)
if self.verify_position_direction(-1):
self.max_unrealized_pnl_seen = None
logger.success(LOG_POSITION + "反手做空成功")
self.last_reverse_time = time.time()
time.sleep(20)
return True
else:
logger.error("反手做空后持仓验证失败")
return False
return False
def action(self):
"""主循环"""
logger.info(LOG_SYSTEM + "开始运行四分之一策略交易...")
# 启动时设置全仓高杠杆
if not self.set_leverage():
logger.error("杠杆设置失败,程序继续运行但可能下单失败")
return
page_start = True
if USE_RICH_DASHBOARD:
self._display_logs = []
logger.remove()
def _sink(msg):
self._display_logs.append(msg.record["message"])
if len(self._display_logs) > 50:
self._display_logs.pop(0)
logger.add(_sink, format="{message}")
live = None
if USE_RICH_DASHBOARD:
live = Live(console=console, refresh_per_second=8, screen=True)
live.start()
try:
while True:
if live is not None:
try:
live.update(build_dashboard_layout(self._display_state, self._display_logs))
except Exception:
pass
if page_start:
# 打开浏览器
for i in range(5):
if self.openBrowser():
logger.info(LOG_SYSTEM + "浏览器打开成功")
break
else:
self.ding("打开浏览器失败!", error=True)
return
# 进入交易页面
self.page.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
self.click_safe('x://button[normalize-space(text()) ="市价"]')
self.page.ele('x://*[@id="size_0"]').input(vals=25, clear=True)
page_start = False
try:
# 1. 获取K线数据当前K线和上一根K线
prev_kline, current_kline = self.get_klines()
if not prev_kline or not current_kline:
logger.warning(LOG_SYSTEM + "获取K线失败等待重试...")
time.sleep(5)
continue
# 记录进入新的K线分块分隔便于阅读
current_kline_time = current_kline['id']
if self.last_kline_time != current_kline_time:
self.last_kline_time = current_kline_time
logger.info("")
log_kline_header(current_kline_time)
# 2. 获取当前价格
current_price = self.get_current_price()
if not current_price:
logger.warning(LOG_SYSTEM + "获取价格失败,等待重试...")
time.sleep(2)
continue
# 3. 每次循环都通过SDK获取真实持仓状态避免状态不同步导致双向持仓
if not self.get_position_status():
logger.warning(LOG_SYSTEM + "获取持仓状态失败,等待重试...")
time.sleep(2)
continue
logger.debug(f"当前持仓状态: {self.start} (0=无, 1=多, -1=空)")
# 更新仪表盘左侧数据(供 Rich 展示)
try:
self._display_state["price"] = current_price
self._display_state["position"] = self.start
self._display_state["kline_id"] = current_kline_time
self._display_state["unrealized_pnl"] = self.get_unrealized_pnl_usd()
kline_series = self.get_klines_series(35)
ema10, ema20, atr14 = self.get_ema_atr_for_exit(kline_series)
self._display_state["ema10"] = ema10
self._display_state["atr14"] = atr14
if getattr(self, "_display_triggers", None):
self._display_state.update(self._display_triggers)
except Exception:
pass
# 3.5 止损/止盈/移动止损 + EMA/ATR 平仓 + 当前K线从极值回落平仓
if self.start != 0:
# 当前K线从最高/最低点回落平仓换线重置跟踪有持仓时更新本K线内最高/最低价并检查
if self._candle_id_for_high_low != current_kline_time:
self._candle_high_seen = None
self._candle_low_seen = None
self._candle_id_for_high_low = current_kline_time
# 多头:先更新本 K 线最高价(供 ATR 追踪与后续回落逻辑用)
if self.start == 1:
self._candle_high_seen = max(self._candle_high_seen or 0, current_price)
elif self.start == -1:
self._candle_low_seen = min(self._candle_low_seen or float('inf'), current_price)
# 多单EMA(10) + ATR(14) 平仓 —— 收盘跌破 EMA10 先平;或从最高价回撤 ≥ 1.1×ATR 平
if self.start == 1 and self.use_ema_atr_exit:
kline_series = self.get_klines_series(35)
ema10, ema20, atr14 = self.get_ema_atr_for_exit(kline_series)
if ema10 is not None and current_price < ema10:
logger.info(LOG_POSITION + f"多单 EMA10 平仓 | 价 {current_price:.2f} 跌破 EMA10 {ema10:.2f}")
self.平仓()
self.max_unrealized_pnl_seen = None
self._candle_high_seen = None
time.sleep(3)
continue
if atr14 is not None and self._candle_high_seen and (self._candle_high_seen - current_price) >= self.atr_multiplier * atr14:
logger.info(LOG_POSITION + f"多单 ATR 追踪止盈 | 最高 {self._candle_high_seen:.2f} 当前 {current_price:.2f} 回撤≥{self.atr_multiplier}×ATR={atr14:.2f}")
self.平仓()
self.max_unrealized_pnl_seen = None
self._candle_high_seen = None
time.sleep(3)
continue
# 空单EMA(10) + ATR(14) 平仓 —— 收盘涨破 EMA10 先平;或从最低价反弹 ≥ 1.1×ATR 平
if self.start == -1 and self.use_ema_atr_exit:
kline_series = self.get_klines_series(35)
ema10, ema20, atr14 = self.get_ema_atr_for_exit(kline_series)
if ema10 is not None and current_price > ema10:
logger.info(LOG_POSITION + f"空单 EMA10 平仓 | 价 {current_price:.2f} 涨破 EMA10 {ema10:.2f}")
self.平仓()
self.max_unrealized_pnl_seen = None
self._candle_low_seen = None
time.sleep(3)
continue
if atr14 is not None and self._candle_low_seen and (current_price - self._candle_low_seen) >= self.atr_multiplier * atr14:
logger.info(LOG_POSITION + f"空单 ATR 追踪止盈 | 最低 {self._candle_low_seen:.2f} 当前 {current_price:.2f} 反弹≥{self.atr_multiplier}×ATR={atr14:.2f}")
self.平仓()
self.max_unrealized_pnl_seen = None
self._candle_low_seen = None
time.sleep(3)
continue
use_fixed = self.drop_from_high_mode == 'fixed' and self.drop_from_high_to_close and self.drop_from_high_to_close > 0
use_pct = self.drop_from_high_mode == 'pct_retrace'
if use_fixed or use_pct:
if self.start == 1: # 多头:最高价已在上面更新,这里只做回落判断
do_close = False
if use_fixed and self._candle_high_seen and current_price <= self._candle_high_seen - self.drop_from_high_to_close:
do_close = True
reason = f"固定回落 {self.drop_from_high_to_close}"
elif use_pct and self._candle_high_seen and current_kline.get('open'):
candle_open = float(current_kline['open'])
rise_pct = (self._candle_high_seen - candle_open) / candle_open * 100 if candle_open > 0 else 0
if rise_pct >= self.min_rise_pct_to_activate:
drop_trigger_pct = max(self.min_drop_pct_from_high, rise_pct * self.retrace_ratio)
drop_pct = (self._candle_high_seen - current_price) / self._candle_high_seen * 100 if self._candle_high_seen else 0
if drop_pct >= drop_trigger_pct:
do_close = True
reason = f"涨幅 {rise_pct:.3f}% → 允许回撤 {drop_trigger_pct:.3f}%,实际回撤 {drop_pct:.3f}%"
else:
pass # 涨幅不足,不启用动态回撤
if do_close:
logger.info(LOG_POSITION + f"多单K线回落平仓 | 最高 {self._candle_high_seen:.2f} 当前 {current_price:.2f} | {reason}")
self.平仓()
self.max_unrealized_pnl_seen = None
self._candle_high_seen = None
time.sleep(3)
continue
elif self.start == -1: # 空头跟踪当前K线最低价从最低点反弹超过阈值则平仓
self._candle_low_seen = min(self._candle_low_seen or float('inf'), current_price)
do_close = False
if use_fixed and self._candle_low_seen and current_price >= self._candle_low_seen + self.drop_from_high_to_close:
do_close = True
reason = f"固定反弹 {self.drop_from_high_to_close}"
elif use_pct and self._candle_low_seen and current_kline.get('open'):
candle_open = float(current_kline['open'])
rise_pct = (candle_open - self._candle_low_seen) / candle_open * 100 if candle_open > 0 else 0 # 对空头是“跌幅”
if rise_pct >= self.min_rise_pct_to_activate:
drop_trigger_pct = max(self.min_drop_pct_from_high, rise_pct * self.retrace_ratio)
bounce_pct = (current_price - self._candle_low_seen) / self._candle_low_seen * 100 if self._candle_low_seen else 0
if bounce_pct >= drop_trigger_pct:
do_close = True
reason = f"跌幅 {rise_pct:.3f}% → 允许反弹 {drop_trigger_pct:.3f}%,实际反弹 {bounce_pct:.3f}%"
if do_close:
logger.info(LOG_POSITION + f"空单K线反弹平仓 | 最低 {self._candle_low_seen:.2f} 当前 {current_price:.2f} | {reason}")
self.平仓()
self.max_unrealized_pnl_seen = None
self._candle_low_seen = None
time.sleep(3)
continue
pnl_usd = self.get_unrealized_pnl_usd()
if pnl_usd is not None:
# 固定止损:亏损达到 3 美元平仓
if pnl_usd <= self.stop_loss_usd:
logger.info(LOG_POSITION + f"固定止损平仓 | 亏损 {pnl_usd:.2f} 美元")
self.平仓()
self.max_unrealized_pnl_seen = None
time.sleep(3)
continue
# 更新持仓期间最大盈利(用于移动止损)
if self.max_unrealized_pnl_seen is None:
self.max_unrealized_pnl_seen = pnl_usd
else:
self.max_unrealized_pnl_seen = max(self.max_unrealized_pnl_seen, pnl_usd)
# 移动止损:盈利曾达到 activation 后,从最高盈利回撤 trailing_distance 则平仓
if self.max_unrealized_pnl_seen >= self.trailing_activation_usd:
if pnl_usd < self.max_unrealized_pnl_seen - self.trailing_distance_usd:
logger.info(LOG_POSITION + f"移动止损平仓 | 盈利 {pnl_usd:.2f} 从最高 {self.max_unrealized_pnl_seen:.2f} 回撤≥{self.trailing_distance_usd}$")
self.平仓()
self.max_unrealized_pnl_seen = None
time.sleep(3)
continue
# 4. 检查信号
signal = self.check_signal(current_price, prev_kline, current_kline)
# 5. 反手过滤:冷却时间 + 最小价差
if signal and signal[0].startswith('reverse_'):
if not self.can_reverse(current_price, signal[1]):
signal = None
# 5.5 开仓频率过滤:仅冷却时间,单根 K 线符合规则可多次开仓
if signal and signal[0] in ('long', 'short'):
if not self.can_open(current_kline_time):
signal = None
else:
self._current_kline_id_for_open = current_kline_time # 供 execute_trade 成功后记录
# 6. 有信号则执行交易
if signal:
trade_success = self.execute_trade(signal)
if trade_success:
logger.success(LOG_POSITION + f"交易执行完成: {signal[0]} | 当前持仓: {self.start}")
page_start = True
else:
logger.warning(f"交易执行失败或被阻止: {signal[0]}")
# 短暂等待后继续循环同一根K线遇到信号就操作
time.sleep(0.1)
if page_start:
self.page.close()
time.sleep(5)
except KeyboardInterrupt:
logger.info(LOG_SYSTEM + "用户中断,程序退出")
break
except Exception as e:
logger.error(f"主循环异常: {e}")
time.sleep(5)
finally:
if live is not None:
try:
live.stop()
except Exception:
pass
if USE_RICH_DASHBOARD:
logger.remove()
logger.add(sys.stderr, format="{message}")
if __name__ == '__main__':
BitmartFuturesTransaction(bit_id="f2320f57e24c45529a009e1541e25961").action()

View File

@@ -1,745 +0,0 @@
"""
BitMart 五分之一回归策略回测(精准版)
使用3分钟K线周期计算触发价格1分钟K线判断触发顺序
========== 策略规则 ==========
1. 触发价格计算基于有效的前一根K线实体>=0.1
- 做多触发价格 = 收盘价 + 实体/5从收盘价往上涨1/5
- 做空触发价格 = 收盘价 - 实体/5从收盘价往下跌1/5
2. 信号触发条件:
- 当前K线最高价 >= 做多触发价格 → 做多信号
- 当前K线最低价 <= 做空触发价格 → 做空信号
3. 执行逻辑:
- 做多时遇到做空信号 -> 平多并反手开空
- 做空时遇到做多信号 -> 平空并反手开多
- 同一根3分钟K线内只交易一次
4. 精准判断使用1分钟K线
- 当一根3分钟K线同时触及做多和做空价格时
- 使用该3分钟K线对应的3根1分钟K线来判断哪个方向先被触发
- 这样可以更精准地还原真实交易场景
"""
import datetime
import calendar
from pathlib import Path
from typing import List, Dict, Optional
from loguru import logger
from peewee import *
# 数据库配置
DB_PATH = Path(__file__).parent.parent / 'models' / 'database.db'
db = SqliteDatabase(str(DB_PATH))
# ========================= 数据库模型 =========================
class BitMartETH1m(Model):
"""1分钟K线模型"""
id = BigIntegerField(primary_key=True) # 时间戳(毫秒级)
open = FloatField(null=True)
high = FloatField(null=True)
low = FloatField(null=True)
close = FloatField(null=True)
class Meta:
database = db
table_name = 'bitmart_eth_1m'
class BitMartETH3m(Model):
"""3分钟K线模型"""
id = BigIntegerField(primary_key=True) # 时间戳(毫秒级)
open = FloatField(null=True)
high = FloatField(null=True)
low = FloatField(null=True)
close = FloatField(null=True)
class Meta:
database = db
table_name = 'bitmart_eth_3m'
# 连接数据库
db.connect(reuse_if_open=True)
# ========================= 工具函数 =========================
def is_bullish(c):
"""判断阳线"""
return float(c['close']) > float(c['open'])
def is_bearish(c):
"""判断阴线"""
return float(c['close']) < float(c['open'])
def get_body_size(candle):
"""计算K线实体大小绝对值"""
return abs(float(candle['open']) - float(candle['close']))
def find_valid_prev_bar(all_data, current_idx, min_body_size=0.1):
"""
从当前索引往前查找,直到找到实体>=min_body_size的K线
返回:(有效K线的索引, K线数据) 或 (None, None)
"""
if current_idx <= 0:
return None, None
for i in range(current_idx - 1, -1, -1):
prev = all_data[i]
body_size = get_body_size(prev)
if body_size >= min_body_size:
return i, prev
return None, None
def get_one_fifth_levels(prev):
"""
计算前一根K线实体的 1/5 双向触发价格
返回:(做多触发价格, 做空触发价格)
基于收盘价计算(无论阴线阳线):
- 做多触发价格 = 收盘价 + 实体/5从收盘价往上涨1/5实体
- 做空触发价格 = 收盘价 - 实体/5从收盘价往下跌1/5实体
"""
p_open = float(prev['open'])
p_close = float(prev['close'])
body = abs(p_open - p_close)
if body < 0.001: # 十字星,忽略
return None, None
# 基于收盘价的双向触发价格
long_trigger = p_close + body / 5
short_trigger = p_close - body / 5
return long_trigger, short_trigger
def get_3m_data_by_date(date_str: str) -> List[Dict]:
"""按天获取3分钟K线数据"""
try:
target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
except ValueError:
logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。")
return []
start_ts = int(target_date.timestamp() * 1000)
end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1
query = BitMartETH3m.select().where(
BitMartETH3m.id.between(start_ts, end_ts)
).order_by(BitMartETH3m.id.asc())
data = [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query]
return data
def get_1m_data_by_range(start_ts: int, end_ts: int) -> List[Dict]:
"""
获取指定时间范围内的1分钟K线数据
:param start_ts: 开始时间戳(毫秒)
:param end_ts: 结束时间戳(毫秒)
:return: 1分钟K线数据列表
"""
query = BitMartETH1m.select().where(
BitMartETH1m.id.between(start_ts, end_ts - 1)
).order_by(BitMartETH1m.id.asc())
data = [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query]
return data
def get_1m_data_for_3m_bar(bar_3m: Dict) -> List[Dict]:
"""
获取3分钟K线对应的3根1分钟K线
:param bar_3m: 3分钟K线数据
:return: 对应的1分钟K线数据列表最多3根
"""
start_ts = bar_3m['id']
end_ts = start_ts + 3 * 60 * 1000 # 3分钟后
return get_1m_data_by_range(start_ts, end_ts)
def determine_trigger_order_by_1m(
bars_1m: List[Dict],
long_trigger: float,
short_trigger: float
) -> str:
"""
使用1分钟K线精确判断在3分钟周期内是先触发做多还是做空
:param bars_1m: 3根1分钟K线数据
:param long_trigger: 做多触发价格
:param short_trigger: 做空触发价格
:return: 'long', 'short', 或 None
"""
if not bars_1m:
return None
for bar in bars_1m:
high = float(bar['high'])
low = float(bar['low'])
open_price = float(bar['open'])
long_triggered = high >= long_trigger
short_triggered = low <= short_trigger
# 如果只触发了一个方向
if long_triggered and not short_triggered:
return 'long'
if short_triggered and not long_triggered:
return 'short'
# 如果两个方向都触发了在同一根1分钟K线内
if long_triggered and short_triggered:
# 根据开盘价判断:
# 如果开盘价更接近做空触发价,说明先往下走,先触发做空
# 如果开盘价更接近做多触发价,说明先往上走,先触发做多
dist_to_long = abs(long_trigger - open_price)
dist_to_short = abs(short_trigger - open_price)
if dist_to_short < dist_to_long:
return 'short'
else:
return 'long'
return None
def check_reverse_signal_in_first_minute(
bars_1m: List[Dict],
long_trigger: float,
short_trigger: float,
current_direction: str
) -> bool:
"""
检查反手信号是否在第一分钟触发
:param bars_1m: 3根1分钟K线数据
:param long_trigger: 做多触发价格
:param short_trigger: 做空触发价格
:param current_direction: 当前持仓方向 ('long''short')
:return: True 表示反手信号在第一分钟触发False 表示不是
"""
if not bars_1m:
return False
# 只检查第一分钟K线
first_bar = bars_1m[0]
high = float(first_bar['high'])
low = float(first_bar['low'])
# 如果当前是多仓,检查空信号是否在第一分钟触发
if current_direction == 'long':
return low <= short_trigger
# 如果当前是空仓,检查多信号是否在第一分钟触发
if current_direction == 'short':
return high >= long_trigger
return False
def get_body_percent(candle) -> float:
"""
计算K线实体占价格的百分比
:param candle: K线数据
:return: 实体百分比如0.1表示0.1%
"""
body = abs(float(candle['open']) - float(candle['close']))
price = (float(candle['open']) + float(candle['close'])) / 2
if price == 0:
return 0
return (body / price) * 100
def check_breakout_reverse_signal(
all_data_3m: List[Dict],
current_idx: int,
current_position_direction: str,
min_body_percent: float = 0.1
) -> tuple:
"""
检查"突破上一根K线高低点"的反手信号
规则:
- 持多单时当前K线跌破上一根K线最低点 → 反手开空
条件上一根K线是阴线且实体>0.1%波动
- 持空单时当前K线涨破上一根K线最高点 → 反手开多
条件上一根K线是阳线且实体>0.1%波动
:param all_data_3m: 3分钟K线数据
:param current_idx: 当前K线索引
:param current_position_direction: 当前持仓方向 ('long''short')
:param min_body_percent: 最小实体百分比默认0.1%
:return: (方向, 触发价格, 信号类型) 或 (None, None, None)
"""
if current_idx <= 0 or current_position_direction is None:
return None, None, None
curr = all_data_3m[current_idx]
prev = all_data_3m[current_idx - 1]
c_high = float(curr['high'])
c_low = float(curr['low'])
prev_high = float(prev['high'])
prev_low = float(prev['low'])
# 计算上一根K线的实体百分比
body_percent = get_body_percent(prev)
# 持多单时检查是否跌破上一根K线最低点
if current_position_direction == 'long':
# 条件上一根K线是阴线且实体>min_body_percent%
if is_bearish(prev) and body_percent >= min_body_percent:
if c_low < prev_low:
# 触发反手开空信号
logger.debug(f"突破反手信号持多单当前K线低点{c_low:.2f}跌破上一根阴线低点{prev_low:.2f},实体{body_percent:.3f}%")
return 'short', prev_low, 'breakout'
# 持空单时检查是否涨破上一根K线最高点
elif current_position_direction == 'short':
# 条件上一根K线是阳线且实体>min_body_percent%
if is_bullish(prev) and body_percent >= min_body_percent:
if c_high > prev_high:
# 触发反手开多信号
logger.debug(f"突破反手信号持空单当前K线高点{c_high:.2f}涨破上一根阳线高点{prev_high:.2f},实体{body_percent:.3f}%")
return 'long', prev_high, 'breakout'
return None, None, None
def check_trigger_with_1m(
all_data_3m: List[Dict],
current_idx: int,
min_body_size: float = 0.1,
current_position_direction: str = None,
first_minute_only: bool = True
) -> tuple:
"""
检查当前3分钟K线是否触发了交易信号
如果同时触发两个方向使用1分钟K线精确判断顺序
新增逻辑:如果有持仓且 first_minute_only=True反手信号必须在第一分钟触发才有效
:param all_data_3m: 3分钟K线数据
:param current_idx: 当前K线索引
:param min_body_size: 最小实体大小
:param current_position_direction: 当前持仓方向 ('long', 'short', 或 None)
:param first_minute_only: 是否只在第一分钟触发反手信号才有效
返回:(方向, 触发价格, 有效前一根K线索引, 1分钟数据是否使用)
"""
if current_idx <= 0:
return None, None, None, False
curr = all_data_3m[current_idx]
# 查找实体>=min_body_size的前一根K线
valid_prev_idx, prev = find_valid_prev_bar(all_data_3m, current_idx, min_body_size)
if prev is None:
return None, None, None, False
long_trigger, short_trigger = get_one_fifth_levels(prev)
if long_trigger is None:
return None, None, None, False
c_high = float(curr['high'])
c_low = float(curr['low'])
# 检测是否触发
long_triggered = c_high >= long_trigger
short_triggered = c_low <= short_trigger
# 如果两个方向都触发使用1分钟K线精确判断
if long_triggered and short_triggered:
bars_1m = get_1m_data_for_3m_bar(curr)
if bars_1m:
direction = determine_trigger_order_by_1m(bars_1m, long_trigger, short_trigger)
if direction:
trigger_price = long_trigger if direction == 'long' else short_trigger
# 检查反手信号是否需要在第一分钟触发
if first_minute_only and current_position_direction and direction != current_position_direction:
# 这是一个反手信号,检查是否在第一分钟触发
if not check_reverse_signal_in_first_minute(bars_1m, long_trigger, short_trigger, current_position_direction):
# 反手信号不是在第一分钟触发,忽略
logger.debug(f"反手信号 {direction} 不在第一分钟触发,忽略")
return None, None, None, False
return direction, trigger_price, valid_prev_idx, True
# 如果没有1分钟数据使用开盘价距离判断
c_open = float(curr['open'])
dist_to_long = abs(long_trigger - c_open)
dist_to_short = abs(short_trigger - c_open)
if dist_to_short <= dist_to_long:
return 'short', short_trigger, valid_prev_idx, False
else:
return 'long', long_trigger, valid_prev_idx, False
if short_triggered:
# 检查是否是反手信号且需要第一分钟触发
if first_minute_only and current_position_direction == 'long':
bars_1m = get_1m_data_for_3m_bar(curr)
if bars_1m and not check_reverse_signal_in_first_minute(bars_1m, long_trigger, short_trigger, 'long'):
logger.debug(f"空信号不在第一分钟触发,忽略(当前持多仓)")
return None, None, None, False
return 'short', short_trigger, valid_prev_idx, False
if long_triggered:
# 检查是否是反手信号且需要第一分钟触发
if first_minute_only and current_position_direction == 'short':
bars_1m = get_1m_data_for_3m_bar(curr)
if bars_1m and not check_reverse_signal_in_first_minute(bars_1m, long_trigger, short_trigger, 'short'):
logger.debug(f"多信号不在第一分钟触发,忽略(当前持空仓)")
return None, None, None, False
return 'long', long_trigger, valid_prev_idx, False
return None, None, None, False
# ========================= 回测逻辑 =========================
def backtest_one_third_strategy(
dates: List[str],
min_body_size: float = 0.1,
first_minute_only: bool = True,
enable_breakout_reverse: bool = True,
breakout_min_body_percent: float = 0.1
):
"""
三分之一策略回测(精准版)
:param dates: 日期列表
:param min_body_size: 最小实体大小(绝对值)
:param first_minute_only: 是否只在第一分钟触发反手信号才有效默认True
:param enable_breakout_reverse: 是否启用"突破上一根K线高低点"反手信号默认True
:param breakout_min_body_percent: 突破反手信号的最小实体百分比默认0.1%
:return: (trades, stats)
"""
# 获取所有3分钟K线数据
all_data: List[Dict] = []
total_queried = 0
for d in dates:
day_data = get_3m_data_by_date(d)
all_data.extend(day_data)
if day_data:
total_queried += len(day_data)
logger.info(f"总共查询了 {len(dates)} 天,获取到 {total_queried} 条3分钟K线数据")
logger.info(f"反手信号仅第一分钟有效: {first_minute_only}")
logger.info(f"突破反手信号启用: {enable_breakout_reverse},最小实体百分比: {breakout_min_body_percent}%")
if not all_data:
logger.warning("未获取到任何数据,请检查数据库")
return [], {'long': {'count': 0, 'wins': 0, 'total_profit': 0.0},
'short': {'count': 0, 'wins': 0, 'total_profit': 0.0}}
# 按时间戳排序
all_data.sort(key=lambda x: x['id'])
# 验证排序结果
if len(all_data) > 1:
first_ts = all_data[0]['id']
last_ts = all_data[-1]['id']
first_time = datetime.datetime.fromtimestamp(first_ts / 1000)
last_time = datetime.datetime.fromtimestamp(last_ts / 1000)
logger.info(f"数据范围:{first_time.strftime('%Y-%m-%d %H:%M:%S')}{last_time.strftime('%Y-%m-%d %H:%M:%S')}")
stats = {
'long': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '做多'},
'short': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '做空'},
}
trades: List[Dict] = []
current_position: Optional[Dict] = None
# 统计使用1分钟数据精准判断的次数
precise_count = 0
fallback_count = 0
# 统计突破反手信号触发次数
breakout_reverse_count = 0
# 记录每根K线是否已经执行过突破反手当前K线只执行一次
last_breakout_bar_id = None
idx = 1
while idx < len(all_data):
curr = all_data[idx]
curr_bar_id = curr['id']
# 获取当前持仓方向(用于判断反手信号是否在第一分钟触发)
current_pos_dir = current_position['direction'] if current_position else None
# 检测信号使用1分钟K线精准判断并考虑反手信号第一分钟限制
direction, trigger_price, valid_prev_idx, used_1m = check_trigger_with_1m(
all_data, idx, min_body_size,
current_position_direction=current_pos_dir,
first_minute_only=first_minute_only
)
# 如果没有五分之一信号,且有持仓,检查突破反手信号
signal_type = 'one_fifth' # 信号类型one_fifth五分之一或 breakout突破
if direction is None and current_position is not None and enable_breakout_reverse:
# 检查当前K线是否已经执行过突破反手
if last_breakout_bar_id != curr_bar_id:
breakout_dir, breakout_price, breakout_type = check_breakout_reverse_signal(
all_data, idx, current_pos_dir, breakout_min_body_percent
)
if breakout_dir:
direction = breakout_dir
trigger_price = breakout_price
signal_type = 'breakout'
if used_1m:
precise_count += 1
elif direction and signal_type == 'one_fifth':
fallback_count += 1
# 无持仓 -> 开仓(只用五分之一信号开仓,突破信号不用于开仓)
if current_position is None:
if direction and signal_type == 'one_fifth':
current_position = {
'direction': direction,
'entry_price': trigger_price,
'entry_time': curr['id'],
'entry_bar_idx': idx
}
stats[direction]['count'] += 1
time_str = datetime.datetime.fromtimestamp(curr['id'] / 1000).strftime('%Y-%m-%d %H:%M')
logger.debug(f"[{time_str}] 开仓{direction} @ {trigger_price:.2f}")
idx += 1
continue
# 有持仓 -> 检查是否需要反向
pos_dir = current_position['direction']
if direction and direction != pos_dir:
# 反向信号,平仓并反手
exit_price = trigger_price
if pos_dir == 'long':
diff = exit_price - current_position['entry_price']
else:
diff = current_position['entry_price'] - exit_price
# 记录信号类型
signal_type_str = '突破' if signal_type == 'breakout' else '五分之一'
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000),
'direction': '做多' if pos_dir == 'long' else '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff,
'signal_type': signal_type_str
})
stats[pos_dir]['total_profit'] += diff
if diff > 0:
stats[pos_dir]['wins'] += 1
# 如果是突破反手信号记录当前K线ID防止重复执行
if signal_type == 'breakout':
last_breakout_bar_id = curr_bar_id
breakout_reverse_count += 1
# 反手开仓
current_position = {
'direction': direction,
'entry_price': trigger_price,
'entry_time': curr['id'],
'entry_bar_idx': idx
}
stats[direction]['count'] += 1
time_str = datetime.datetime.fromtimestamp(curr['id'] / 1000).strftime('%Y-%m-%d %H:%M')
logger.debug(f"[{time_str}] 平{pos_dir}反手{direction}({signal_type_str}) @ {trigger_price:.2f} 盈亏={diff:.2f}")
idx += 1
# 尾仓处理最后一根K线收盘价平仓
if current_position:
last = all_data[-1]
exit_price = float(last['close'])
pos_dir = current_position['direction']
if pos_dir == 'long':
diff = exit_price - current_position['entry_price']
else:
diff = current_position['entry_price'] - exit_price
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(last['id'] / 1000),
'direction': '做多' if pos_dir == 'long' else '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[pos_dir]['total_profit'] += diff
if diff > 0:
stats[pos_dir]['wins'] += 1
logger.info(f"回测完成使用1分钟精准判断 {precise_count} 次,使用开盘价距离判断 {fallback_count} 次,突破反手信号 {breakout_reverse_count}")
return trades, stats
# ========================= 运行回测 =========================
if __name__ == '__main__':
# ==================== 配置参数 ====================
START_DATE = "2025-01-01"
END_DATE = "2025-12-31"
MIN_BODY_SIZE = 0.1 # 最小实体大小(绝对值)
FIRST_MINUTE_ONLY = True # 反手信号仅在3分钟K线的第一分钟触发才有效
# 突破反手信号配置
ENABLE_BREAKOUT_REVERSE = True # 是否启用"突破上一根K线高低点"反手信号
BREAKOUT_MIN_BODY_PERCENT = 0.1 # 突破反手信号的最小实体百分比0.1表示0.1%
# ==================== 生成查询日期列表 ====================
dates = []
try:
start_dt = datetime.datetime.strptime(START_DATE, '%Y-%m-%d')
end_dt = datetime.datetime.strptime(END_DATE, '%Y-%m-%d')
if start_dt > end_dt:
logger.error(f"开始日期 {START_DATE} 不能晚于结束日期 {END_DATE}")
exit(1)
current_dt = start_dt
while current_dt <= end_dt:
dates.append(current_dt.strftime('%Y-%m-%d'))
current_dt += datetime.timedelta(days=1)
logger.info(f"回测日期范围:{START_DATE}{END_DATE},共 {len(dates)}")
except ValueError as e:
logger.error(f"日期格式错误:{e}")
exit(1)
# ==================== 执行回测 ====================
trades, stats = backtest_one_third_strategy(
dates,
MIN_BODY_SIZE,
FIRST_MINUTE_ONLY,
ENABLE_BREAKOUT_REVERSE,
BREAKOUT_MIN_BODY_PERCENT
)
# ==================== 输出交易详情 ====================
logger.info("===== 每笔交易详情 =====")
# 参数设定
contract_size = 10000 # 合约规模
open_fee_fixed = 5 # 固定开仓手续费
close_fee_rate = 0.0005 # 平仓手续费率
total_points_profit = 0
total_money_profit = 0
total_fee = 0
for t in trades:
entry = t['entry']
exit_price = t['exit']
direction = t['direction']
# 原始价差
point_diff = t['diff']
# 金额盈利
money_profit = point_diff / entry * contract_size
# 手续费
fee = open_fee_fixed + (contract_size / entry * exit_price * close_fee_rate)
# 净利润
net_profit = money_profit - fee
t.update({
'point_diff': point_diff,
'raw_profit': money_profit,
'fee': fee,
'net_profit': net_profit
})
total_points_profit += point_diff
total_money_profit += money_profit
total_fee += fee
logger.info(
f"{t['entry_time']} {direction} "
f"入={entry:.2f} 出={exit_price:.2f} 差价={point_diff:.2f} "
f"原始盈利={money_profit:.2f} 手续费={fee:.2f} 净利润={net_profit:.2f} {t['exit_time']}"
)
# ==================== 汇总统计 ====================
total_net_profit = total_money_profit - total_fee
print(f"\n{'='*60}")
print(f"【BitMart 五分之一策略回测结果3分钟K线 + 1分钟精准判断")
print(f"{'='*60}")
print(f"回测周期:{START_DATE}{END_DATE}")
print(f"最小实体要求:{MIN_BODY_SIZE}")
print(f"反手信号仅第一分钟有效:{'' if FIRST_MINUTE_ONLY else ''}")
print(f"突破反手信号:{'启用' if ENABLE_BREAKOUT_REVERSE else '禁用'}(最小实体{BREAKOUT_MIN_BODY_PERCENT}%")
print(f"{'='*60}")
print(f"总交易笔数:{len(trades)}")
print(f"总点差:{total_points_profit:.2f}")
print(f"总原始盈利(未扣费):{total_money_profit:.2f}")
print(f"总手续费:{total_fee:.2f}")
print(f"总净利润:{total_net_profit:.2f}")
print(f"{'='*60}")
print("\n===== 方向统计 =====")
for k, v in stats.items():
name = v['name']
count = v['count']
wins = v['wins']
total_p = v['total_profit']
win_rate = (wins / count * 100) if count > 0 else 0.0
avg_p = (total_p / count) if count > 0 else 0.0
print(f"{name}: 次数={count} 胜率={win_rate:.2f}% 总价差={total_p:.2f} 平均价差={avg_p:.2f}")
# 保存交易记录到CSV
if trades:
import csv
csv_path = Path(__file__).parent / 'backtest_one_third_trades.csv'
with open(csv_path, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=[
'entry_time', 'exit_time', 'direction', 'entry', 'exit',
'point_diff', 'raw_profit', 'fee', 'net_profit', 'signal_type'
])
writer.writeheader()
for t in trades:
writer.writerow({
'entry_time': t['entry_time'],
'exit_time': t['exit_time'],
'direction': t['direction'],
'entry': t['entry'],
'exit': t['exit'],
'point_diff': t['point_diff'],
'raw_profit': t['raw_profit'],
'fee': t['fee'],
'net_profit': t['net_profit'],
'signal_type': t.get('signal_type', '五分之一')
})
print(f"\n交易记录已保存到:{csv_path}")

View File

@@ -1,764 +0,0 @@
"""
量化交易回测系统 - 三分之一回归策略(双向触发版)
========== 策略规则 ==========
1. 触发价格计算基于有效的前一根K线实体>=0.1
- 做多触发价格 = 收盘价 + 实体/3从收盘价往上涨1/3
- 做空触发价格 = 收盘价 - 实体/3从收盘价往下跌1/3
2. 信号触发条件:
- 当前K线最高价 >= 做多触发价格 → 做多信号
- 当前K线最低价 <= 做空触发价格 → 做空信号
3. 执行逻辑:
- 做多时遇到做空信号 -> 平多并反手开空
- 做空时遇到做多信号 -> 平空并反手开多
- 同一根K线内只交易一次防止频繁反手
4. 实体过滤:
- 如果前一根K线的实体部分|open - close|< 0.1,继续往前查找
- 直到找到实体>=0.1的K线再用那根K线来计算触发价格
示例1阳线
前一根K线开盘3000收盘3100阳线实体=100
- 做多触发价格 = 3100 + 33 = 3133继续上涨做多
- 做空触发价格 = 3100 - 33 = 3067回调做空
示例2阴线
前一根K线开盘3100收盘3000阴线实体=100
- 做多触发价格 = 3000 + 33 = 3033反弹做多
- 做空触发价格 = 3000 - 33 = 2967继续下跌做空
"""
import datetime
import calendar
import os
from typing import List, Dict, Optional
from loguru import logger
import pandas as pd
import mplfinance as mpf
import matplotlib.pyplot as plt
import matplotlib
try:
import plotly.graph_objects as go
except Exception:
go = None
from models.bitmart_klines import BitMartETH5M
# 配置中文字体
import matplotlib.font_manager as fm
import warnings
# 忽略matplotlib的字体警告
warnings.filterwarnings('ignore', category=UserWarning, module='matplotlib.font_manager')
warnings.filterwarnings('ignore', message='.*Glyph.*missing.*', category=UserWarning)
# 尝试设置中文字体,按优先级尝试
chinese_fonts = ['SimHei', 'Microsoft YaHei', 'SimSun', 'KaiTi', 'FangSong', 'STSong', 'STHeiti']
available_fonts = [f.name for f in fm.fontManager.ttflist]
# 找到第一个可用的中文字体
font_found = None
for font_name in chinese_fonts:
if font_name in available_fonts:
font_found = font_name
break
if font_found:
plt.rcParams['font.sans-serif'] = [font_found] + ['DejaVu Sans']
logger.info(f"使用中文字体: {font_found}")
else:
# 如果没有找到中文字体,尝试使用系统默认字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'SimSun', 'Arial Unicode MS', 'DejaVu Sans']
logger.warning("未找到中文字体,使用默认配置")
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
plt.rcParams['font.size'] = 10 # 设置默认字体大小
# 尝试清除字体缓存(如果可能)
try:
# 不强制重建,避免性能问题
pass
except:
pass
# 获取当前脚本所在目录
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
# ========================= 工具函数 =========================
def is_bullish(c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(c): # 阴线
return float(c['close']) < float(c['open'])
def get_body_size(candle):
"""计算K线实体大小绝对值"""
return abs(float(candle['open']) - float(candle['close']))
def find_valid_prev_bar(all_data: List[Dict], current_idx: int, min_body_size: float = 0.1):
"""
从当前索引往前查找,直到找到实体>=min_body_size的K线
返回:(有效K线的索引, K线数据) 或 (None, None)
"""
if current_idx <= 0:
return None, None
for i in range(current_idx - 1, -1, -1):
prev = all_data[i]
body_size = get_body_size(prev)
if body_size >= min_body_size:
return i, prev
return None, None
def get_one_third_levels(prev):
"""
计算前一根K线实体的 1/3 双向触发价格
返回:(做多触发价格, 做空触发价格)
基于收盘价计算(无论阴线阳线):
- 做多触发价格 = 收盘价 + 实体/3从收盘价往上涨1/3实体
- 做空触发价格 = 收盘价 - 实体/3从收盘价往下跌1/3实体
示例:
阳线 open=3000, close=3100, 实体=100
- 做多触发 = 3100 + 33 = 3133继续涨
- 做空触发 = 3100 - 33 = 3067回调
阴线 open=3100, close=3000, 实体=100
- 做多触发 = 3000 + 33 = 3033反弹
- 做空触发 = 3000 - 33 = 2967继续跌
"""
p_open = float(prev['open'])
p_close = float(prev['close'])
body = abs(p_open - p_close)
if body < 0.001: # 十字星,忽略
return None, None
# 基于收盘价的双向触发价格
long_trigger = p_close + body / 3 # 从收盘价往上涨1/3触发做多
short_trigger = p_close - body / 3 # 从收盘价往下跌1/3触发做空
return long_trigger, short_trigger
def check_trigger(all_data: List[Dict], current_idx: int, min_body_size: float = 0.1):
"""
检查当前K线是否触发了交易信号双向检测
返回:(方向, 触发价格, 有效前一根K线索引) 或 (None, None, None)
规则:
- 当前K线高点 >= 做多触发价格 → 做多信号
- 当前K线低点 <= 做空触发价格 → 做空信号
- 如果同时触发两个方向,以先触发的为准(这里简化为优先做空,因为下跌更快)
"""
if current_idx <= 0:
return None, None, None
curr = all_data[current_idx]
# 查找实体>=min_body_size的前一根K线
valid_prev_idx, prev = find_valid_prev_bar(all_data, current_idx, min_body_size)
if prev is None:
return None, None, None
long_trigger, short_trigger = get_one_third_levels(prev)
if long_trigger is None:
return None, None, None
# 使用影线部分high/low来判断
c_high = float(curr['high'])
c_low = float(curr['low'])
# 检测是否触发
long_triggered = c_high >= long_trigger
short_triggered = c_low <= short_trigger
# 如果两个方向都触发,需要判断哪个先触发
# 简化处理:比较触发价格距离开盘价的远近,更近的先触发
if long_triggered and short_triggered:
c_open = float(curr['open'])
dist_to_long = abs(long_trigger - c_open)
dist_to_short = abs(short_trigger - c_open)
if dist_to_short <= dist_to_long:
return 'short', short_trigger, valid_prev_idx
else:
return 'long', long_trigger, valid_prev_idx
if short_triggered:
return 'short', short_trigger, valid_prev_idx
if long_triggered:
return 'long', long_trigger, valid_prev_idx
return None, None, None
def get_data_by_date(model, date_str: str):
"""按天获取指定表的数据"""
try:
target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
except ValueError:
logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。")
return []
start_ts = int(target_date.timestamp() * 1000)
end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1
query = model.select().where(model.id.between(start_ts, end_ts)).order_by(model.id.asc())
data = [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query]
if data:
data.sort(key=lambda x: x['id'])
return data
# ========================= 回测逻辑 =========================
def backtest_one_third_strategy(dates: List[str]):
"""三分之一回归策略回测(优化版)"""
all_data: List[Dict] = []
for d in dates:
day_data = get_data_by_date(BitMartETH5M, d)
all_data.extend(day_data)
logger.info(f"总共查询了 {len(dates)} 天,获取到 {len(all_data)} 条K线数据")
if not all_data:
logger.warning("未获取到任何数据")
return [], {'long': {'count': 0, 'wins': 0, 'total_profit': 0.0},
'short': {'count': 0, 'wins': 0, 'total_profit': 0.0}}
all_data.sort(key=lambda x: x['id'])
if len(all_data) > 1:
first_time = datetime.datetime.fromtimestamp(all_data[0]['id'] / 1000)
last_time = datetime.datetime.fromtimestamp(all_data[-1]['id'] / 1000)
logger.info(f"数据范围:{first_time.strftime('%Y-%m-%d %H:%M')}{last_time.strftime('%Y-%m-%d %H:%M')}")
# 验证排序打印前5条数据
logger.info("===== 前5条数据验证排序=====")
for i in range(min(5, len(all_data))):
d = all_data[i]
t = datetime.datetime.fromtimestamp(d['id'] / 1000).strftime('%Y-%m-%d %H:%M:%S')
k_type = "阳线" if is_bullish(d) else ("阴线" if is_bearish(d) else "十字星")
logger.info(f" [{i}] {t} | {k_type} | O={d['open']:.2f} H={d['high']:.2f} L={d['low']:.2f} C={d['close']:.2f}")
stats = {
'long': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '做多'},
'short': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '做空'},
}
# 额外统计信息
extra_stats = {
'same_dir_ignored': 0, # 同向信号被忽略次数
'no_signal_bars': 0, # 无信号K线数
'total_bars': len(all_data) - 1, # 总K线数排除第一根
}
trades: List[Dict] = []
current_position: Optional[Dict] = None
last_trade_bar: Optional[int] = None # 记录上次交易的K线索引防止同一K线重复交易
for idx in range(1, len(all_data)):
curr = all_data[idx]
# 使用check_trigger函数它会自动查找实体>=0.1的前一根K线
direction, trigger_price, valid_prev_idx = check_trigger(all_data, idx, min_body_size=0.1)
# 获取有效的前一根K线用于日志输出
valid_prev = all_data[valid_prev_idx] if valid_prev_idx is not None else None
# 无信号时跳过
if direction is None:
extra_stats['no_signal_bars'] += 1
continue
# 同一K线内已交易跳过与交易代码逻辑一致
if last_trade_bar == idx:
continue
# 空仓时,有信号就开仓
if current_position is None:
if valid_prev is not None:
# 打印开仓时的K线信息
prev_time = datetime.datetime.fromtimestamp(valid_prev['id'] / 1000).strftime('%Y-%m-%d %H:%M')
curr_time = datetime.datetime.fromtimestamp(curr['id'] / 1000).strftime('%Y-%m-%d %H:%M')
prev_type = "阳线" if is_bullish(valid_prev) else ("阴线" if is_bearish(valid_prev) else "十字星")
curr_type = "阳线" if is_bullish(curr) else ("阴线" if is_bearish(curr) else "十字星")
prev_body = get_body_size(valid_prev)
logger.info(f"【开仓】{direction} @ {trigger_price:.2f}")
logger.info(f" 有效前一根[{prev_time}]: {prev_type} 实体={prev_body:.2f} O={valid_prev['open']:.2f} H={valid_prev['high']:.2f} L={valid_prev['low']:.2f} C={valid_prev['close']:.2f}")
logger.info(f" 当前根[{curr_time}]: {curr_type} O={curr['open']:.2f} H={curr['high']:.2f} L={curr['low']:.2f} C={curr['close']:.2f}")
current_position = {
'direction': direction,
'entry_price': trigger_price,
'entry_time': curr['id'],
'entry_bar': idx
}
stats[direction]['count'] += 1
last_trade_bar = idx # 记录交易K线
continue
# 有仓位时,检查信号
pos_dir = current_position['direction']
# 同向信号,忽略(与交易代码逻辑一致)
if direction == pos_dir:
extra_stats['same_dir_ignored'] += 1
continue
# 反向信号,平仓反手
if valid_prev is not None:
exit_price = trigger_price
if pos_dir == 'long':
diff = exit_price - current_position['entry_price']
else:
diff = current_position['entry_price'] - exit_price
# 打印平仓时的K线信息
prev_time = datetime.datetime.fromtimestamp(valid_prev['id'] / 1000).strftime('%Y-%m-%d %H:%M')
curr_time = datetime.datetime.fromtimestamp(curr['id'] / 1000).strftime('%Y-%m-%d %H:%M')
prev_type = "阳线" if is_bullish(valid_prev) else ("阴线" if is_bearish(valid_prev) else "十字星")
curr_type = "阳线" if is_bullish(curr) else ("阴线" if is_bearish(curr) else "十字星")
prev_body = get_body_size(valid_prev)
logger.info(f"【平仓反手】{pos_dir} -> {direction} @ {exit_price:.2f}, 盈亏: {diff:.2f}")
logger.info(f" 有效前一根[{prev_time}]: {prev_type} 实体={prev_body:.2f} O={valid_prev['open']:.2f} H={valid_prev['high']:.2f} L={valid_prev['low']:.2f} C={valid_prev['close']:.2f}")
logger.info(f" 当前根[{curr_time}]: {curr_type} O={curr['open']:.2f} H={curr['high']:.2f} L={curr['low']:.2f} C={curr['close']:.2f}")
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000),
'entry_time_ms': current_position['entry_time'],
'exit_time_ms': curr['id'],
'direction': '做多' if pos_dir == 'long' else '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff,
'hold_bars': idx - current_position['entry_bar'] # 持仓K线数
})
stats[pos_dir]['total_profit'] += diff
if diff > 0:
stats[pos_dir]['wins'] += 1
# 反手开仓
current_position = {
'direction': direction,
'entry_price': trigger_price,
'entry_time': curr['id'],
'entry_bar': idx
}
stats[direction]['count'] += 1
last_trade_bar = idx # 记录交易K线
# 尾仓处理
if current_position:
last = all_data[-1]
last_idx = len(all_data) - 1
exit_price = float(last['close'])
pos_dir = current_position['direction']
if pos_dir == 'long':
diff = exit_price - current_position['entry_price']
else:
diff = current_position['entry_price'] - exit_price
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(last['id'] / 1000),
'entry_time_ms': current_position['entry_time'],
'exit_time_ms': last['id'],
'direction': '做多' if pos_dir == 'long' else '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff,
'hold_bars': last_idx - current_position['entry_bar'], # 持仓K线数
'is_tail': True # 标记为尾仓平仓
})
stats[pos_dir]['total_profit'] += diff
if diff > 0:
stats[pos_dir]['wins'] += 1
logger.info(f"【尾仓平仓】{pos_dir} @ {exit_price:.2f}, 盈亏: {diff:.2f}")
# 打印额外统计信息
logger.info(f"\n===== 信号统计 =====")
logger.info(f"总K线数: {extra_stats['total_bars']}")
logger.info(f"无信号K线: {extra_stats['no_signal_bars']} ({extra_stats['no_signal_bars']/extra_stats['total_bars']*100:.1f}%)")
logger.info(f"同向信号忽略: {extra_stats['same_dir_ignored']}")
return trades, stats, all_data, extra_stats
# ========================= 绘图函数 =========================
def plot_trades(all_data: List[Dict], trades: List[Dict], save_path: str = None):
"""
绘制K线图并标注交易点位
"""
if not all_data:
logger.warning("没有数据可绘制")
return
# 转换为 DataFrame
df = pd.DataFrame(all_data)
df['datetime'] = pd.to_datetime(df['id'], unit='ms')
df.set_index('datetime', inplace=True)
df = df.rename(columns={'open': 'Open', 'high': 'High', 'low': 'Low', 'close': 'Close'})
df = df[['Open', 'High', 'Low', 'Close']]
# 准备标记点
buy_signals = [] # 做多开仓
sell_signals = [] # 做空开仓
buy_exits = [] # 做多平仓
sell_exits = [] # 做空平仓
for trade in trades:
entry_time = pd.to_datetime(trade['entry_time_ms'], unit='ms')
exit_time = pd.to_datetime(trade['exit_time_ms'], unit='ms')
direction = trade['direction']
entry_price = trade['entry']
exit_price = trade['exit']
if direction == '做多':
buy_signals.append((entry_time, entry_price))
buy_exits.append((exit_time, exit_price))
else:
sell_signals.append((entry_time, entry_price))
sell_exits.append((exit_time, exit_price))
# 创建标记序列
buy_markers = pd.Series(index=df.index, dtype=float)
sell_markers = pd.Series(index=df.index, dtype=float)
buy_exit_markers = pd.Series(index=df.index, dtype=float)
sell_exit_markers = pd.Series(index=df.index, dtype=float)
for t, p in buy_signals:
if t in buy_markers.index:
buy_markers[t] = p
for t, p in sell_signals:
if t in sell_markers.index:
sell_markers[t] = p
for t, p in buy_exits:
if t in buy_exit_markers.index:
buy_exit_markers[t] = p
for t, p in sell_exits:
if t in sell_exit_markers.index:
sell_exit_markers[t] = p
# 添加标记
add_plots = []
if buy_markers.notna().any():
add_plots.append(mpf.make_addplot(buy_markers, type='scatter', markersize=100,
marker='^', color='green', label='做多开仓'))
if sell_markers.notna().any():
add_plots.append(mpf.make_addplot(sell_markers, type='scatter', markersize=100,
marker='v', color='red', label='做空开仓'))
if buy_exit_markers.notna().any():
add_plots.append(mpf.make_addplot(buy_exit_markers, type='scatter', markersize=80,
marker='x', color='darkgreen', label='做多平仓'))
if sell_exit_markers.notna().any():
add_plots.append(mpf.make_addplot(sell_exit_markers, type='scatter', markersize=80,
marker='x', color='darkred', label='做空平仓'))
# 绘制K线图更接近交易所风格
market_colors = mpf.make_marketcolors(
up='#26a69a', # 常见交易所绿色
down='#ef5350', # 常见交易所红色
edge='inherit',
wick='inherit',
volume='inherit'
)
style = mpf.make_mpf_style(
base_mpf_style='binance',
marketcolors=market_colors,
gridstyle='-',
gridcolor='#e6e6e6'
)
fig, axes = mpf.plot(
df,
type='candle',
style=style,
title='三分之一回归策略回测',
ylabel='价格',
addplot=add_plots if add_plots else None,
figsize=(16, 9),
returnfig=True
)
# 添加图例
axes[0].legend(['做多开仓 ▲', '做空开仓 ▼', '做多平仓 ✕', '做空平仓 ✕'], loc='upper left')
# 标注开仓细节(方向、价格、时间)
if trades:
ax = axes[0]
max_annotate = 60 # 过多会拥挤,可按需调大/调小
annotated = 0
for i, trade in enumerate(trades):
if annotated >= max_annotate:
break
entry_time = pd.to_datetime(trade['entry_time_ms'], unit='ms')
if entry_time not in df.index:
continue
entry_price = trade['entry']
direction = trade['direction']
color = 'green' if direction == '做多' else 'red'
text = f"{direction} @ {entry_price:.2f}\n{entry_time.strftime('%m-%d %H:%M')}"
y_offset = 20 if (i % 2 == 0) else -30
ax.annotate(
text,
xy=(entry_time, entry_price),
xytext=(0, y_offset),
textcoords='offset points',
ha='center',
va='bottom' if y_offset > 0 else 'top',
fontsize=8,
color=color,
arrowprops=dict(arrowstyle='->', color=color, lw=0.6, alpha=0.6)
)
annotated += 1
if save_path:
plt.savefig(save_path, dpi=150, bbox_inches='tight')
logger.info(f"图表已保存到: {save_path}")
plt.show()
def plot_trades_interactive(all_data: List[Dict], trades: List[Dict], html_path: str = None):
"""
交互式K线图TradingView风格支持缩放、时间区间/价格区间平移缩放)
"""
if not all_data:
logger.warning("没有数据可绘制")
return
if go is None:
logger.warning("未安装 plotly无法绘制交互式图。请先安装pip install plotly")
return
df = pd.DataFrame(all_data)
df['datetime'] = pd.to_datetime(df['id'], unit='ms')
df.sort_values('datetime', inplace=True)
fig = go.Figure(
data=[
go.Candlestick(
x=df['datetime'],
open=df['open'],
high=df['high'],
low=df['low'],
close=df['close'],
increasing_line_color='#26a69a',
decreasing_line_color='#ef5350',
name='K线'
)
]
)
# 标注开仓点
if trades:
entry_x = []
entry_y = []
entry_text = []
entry_color = []
for t in trades:
entry_x.append(pd.to_datetime(t['entry_time_ms'], unit='ms'))
entry_y.append(t['entry'])
entry_text.append(f"{t['direction']} @ {t['entry']:.2f}<br>{t['entry_time']}")
entry_color.append('#26a69a' if t['direction'] == '做多' else '#ef5350')
fig.add_trace(
go.Scatter(
x=entry_x,
y=entry_y,
mode='markers',
marker=dict(size=8, color=entry_color),
name='开仓',
text=entry_text,
hoverinfo='text'
)
)
# TradingView风格深色背景 + 交互缩放
fig.update_layout(
title='三分之一回归策略回测(交互式)',
xaxis=dict(
rangeslider=dict(visible=True),
type='date',
showgrid=False
),
yaxis=dict(
showgrid=False,
fixedrange=False
),
plot_bgcolor='#0b0e11',
paper_bgcolor='#0b0e11',
font=dict(color='#d1d4dc'),
hovermode='x unified',
dragmode='zoom'
)
fig.show()
if html_path:
fig.write_html(html_path)
logger.info(f"交互图已保存到: {html_path}")
# ========================= 主程序 =========================
if __name__ == '__main__':
# ==================== 配置参数 ====================
START_DATE = "2025-01-01"
END_DATE = "2025-12-31"
# ==================== 生成日期列表 ====================
dates = []
if START_DATE and END_DATE:
start_dt = datetime.datetime.strptime(START_DATE, '%Y-%m-%d')
end_dt = datetime.datetime.strptime(END_DATE, '%Y-%m-%d')
current_dt = start_dt
while current_dt <= end_dt:
dates.append(current_dt.strftime('%Y-%m-%d'))
current_dt += datetime.timedelta(days=1)
logger.info(f"查询日期范围:{START_DATE}{END_DATE},共 {len(dates)}")
# ==================== 执行回测 ====================
trades, stats, all_data, extra_stats = backtest_one_third_strategy(dates)
# ==================== 输出结果 ====================
logger.info("===== 每笔交易详情 =====")
contract_size = 10000
open_fee_fixed = 5
close_fee_rate = 0.0005
total_points_profit = 0
total_money_profit = 0
total_fee = 0
for t in trades:
entry = t['entry']
exit_p = t['exit']
direction = t['direction']
point_diff = t['diff']
money_profit = point_diff / entry * contract_size
fee = open_fee_fixed + (contract_size / entry * exit_p * close_fee_rate)
net_profit = money_profit - fee
t.update({
'point_diff': point_diff,
'raw_profit': money_profit,
'fee': fee,
'net_profit': net_profit
})
total_points_profit += point_diff
total_money_profit += money_profit
total_fee += fee
logger.info(
f"{t['entry_time']} {direction} "
f"入={entry:.2f} 出={exit_p:.2f} 差价={point_diff:.2f} "
f"原始盈利={money_profit:.2f} 手续费={fee:.2f} 净利润={net_profit:.2f}"
)
# ==================== 汇总统计 ====================
total_net_profit = total_money_profit - total_fee
# 计算额外统计
win_count = len([t for t in trades if t['diff'] > 0])
lose_count = len([t for t in trades if t['diff'] <= 0])
total_win_rate = (win_count / len(trades) * 100) if trades else 0
# 计算平均持仓K线数
hold_bars_list = [t.get('hold_bars', 0) for t in trades if 'hold_bars' in t]
avg_hold_bars = sum(hold_bars_list) / len(hold_bars_list) if hold_bars_list else 0
# 计算最大连续亏损
max_consecutive_loss = 0
current_consecutive_loss = 0
for t in trades:
if t['diff'] <= 0:
current_consecutive_loss += 1
max_consecutive_loss = max(max_consecutive_loss, current_consecutive_loss)
else:
current_consecutive_loss = 0
# 计算最大回撤
cumulative_profit = 0
peak = 0
max_drawdown = 0
for t in trades:
cumulative_profit += t.get('net_profit', t['diff'])
peak = max(peak, cumulative_profit)
drawdown = peak - cumulative_profit
max_drawdown = max(max_drawdown, drawdown)
print(f"\n{'='*60}")
print(f"【三分之一回归策略 回测结果】")
print(f"{'='*60}")
print(f"交易笔数:{len(trades)}")
print(f"盈利笔数:{win_count} 亏损笔数:{lose_count}")
print(f"总胜率:{total_win_rate:.2f}%")
print(f"平均持仓K线数{avg_hold_bars:.1f}")
print(f"最大连续亏损:{max_consecutive_loss}")
print(f"{'='*60}")
print(f"总点差:{total_points_profit:.2f}")
print(f"总原始盈利:{total_money_profit:.2f}")
print(f"总手续费:{total_fee:.2f}")
print(f"总净利润:{total_net_profit:.2f}")
print(f"最大回撤:{max_drawdown:.2f}")
print(f"{'='*60}")
print("\n===== 方向统计 =====")
for k, v in stats.items():
count = v['count']
wins = v['wins']
total_p = v['total_profit']
win_rate = (wins / count * 100) if count > 0 else 0.0
avg_p = (total_p / count) if count > 0 else 0.0
print(f"{v['name']}: 次数={count} 胜率={win_rate:.2f}% 总价差={total_p:.2f} 平均价差={avg_p:.2f}")
print("\n===== 信号统计 =====")
print(f"总K线数: {extra_stats['total_bars']}")
print(f"无信号K线: {extra_stats['no_signal_bars']} ({extra_stats['no_signal_bars']/extra_stats['total_bars']*100:.1f}%)")
print(f"同向信号忽略: {extra_stats['same_dir_ignored']}")
# ==================== 绘制图表 ====================
if trades and all_data:
# 如果数据太多只绘制最近一部分比如最近500根K线
max_bars = 500
if len(all_data) > max_bars:
logger.info(f"数据量较大({len(all_data)}条),只绘制最近 {max_bars} 根K线")
plot_data = all_data[-max_bars:]
# 过滤出在这个时间范围内的交易
min_time = datetime.datetime.fromtimestamp(plot_data[0]['id'] / 1000)
plot_trades_filtered = [t for t in trades if t['entry_time'] >= min_time]
else:
plot_data = all_data
plot_trades_filtered = trades
save_path = os.path.join(SCRIPT_DIR, '回测图表.png')
plot_trades(plot_data, plot_trades_filtered, save_path=save_path)
# 交互式版本TradingView风格支持时间区间/价格缩放
html_path = os.path.join(SCRIPT_DIR, '回测图表_交互式.html')
plot_trades_interactive(plot_data, plot_trades_filtered, html_path=html_path)

View File

@@ -1,418 +0,0 @@
"""
量化交易回测系统 - 30分钟K线策略回测BitMart数据源
========== 策略规则 ==========
重要所有开仓和平仓操作都在下一根K线的开盘价执行
1. 开仓条件信号出现时下一根K线开盘价开仓
- 阳包阴(涨包跌):前一根是跌(阴线),后一根是涨(阳线),且涨的收盘价 > 跌的开盘价
-> 下一根K线开盘价开多
- 阴包阳(跌包涨):前一根是涨(阳线),后一根是跌(阴线),且跌的收盘价 < 涨的开盘价
-> 下一根K线开盘价开空
2. 平仓条件所有平仓都在下一根K线开盘价执行
- 持有多单时:遇到两根连续的阴线 -> 下一根K线开盘价平仓
- 持有空单时:遇到两根连续的阳线 -> 下一根K线开盘价平仓
- 遇到反向信号下一根K线开盘价平仓并反手开仓
3. 续持条件:
- 遇到同向信号:续持
- 未满足平仓条件:续持
"""
import datetime
import calendar
from dataclasses import dataclass
from typing import List, Dict, Optional
from loguru import logger
from models.bitmart import BitMart30
# ========================= 工具函数 =========================
def is_bullish(c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(c): # 阴线
return float(c['close']) < float(c['open'])
def check_signal(prev, curr):
"""
包住形态信号判定(优化版):
只看两种信号,严格按照收盘价与开盘价的比较:
1. 跌包涨(前涨后跌)-> 做空:
- 前一根是涨阳线close > open
- 后一根是跌阴线close < open
- 且:跌的收盘价 < 涨的开盘价curr['close'] < prev['open']
2. 涨包跌(前跌后涨)-> 做多:
- 前一根是跌阴线close < open
- 后一根是涨阳线close > open
- 且:涨的收盘价 > 跌的开盘价curr['close'] > prev['open']
"""
p_open = float(prev['open'])
c_close = float(curr['close'])
# 跌包涨(前涨后跌) -> 做空:跌的收盘价 < 涨的开盘价
if is_bullish(prev) and is_bearish(curr) and c_close < p_open:
return "short", "bull_bear_engulf"
# 涨包跌(前跌后涨) -> 做多:涨的收盘价 > 跌的开盘价
if is_bearish(prev) and is_bullish(curr) and c_close > p_open:
return "long", "bear_bull_engulf"
return None, None
def get_data_by_date(model, date_str: str):
"""
按天获取指定表的数据30分钟K线
数据格式:时间戳(毫秒级) 开盘价 最高价 最低价 收盘价
例如1767461400000 3106.68 3109.1 3106.22 3107.22
注意返回的数据已按时间戳id升序排序
"""
try:
target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
except ValueError:
logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。")
return []
# 将日期转换为毫秒级时间戳进行查询
start_ts = int(target_date.timestamp() * 1000)
end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1
# 查询时按时间戳升序排序
query = model.select().where(model.id.between(start_ts, end_ts)).order_by(model.id.asc())
data = [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query]
# 确保数据已排序
if data:
data.sort(key=lambda x: x['id'])
return data
# ========================= 回测逻辑 =========================
def backtest_15m_trend_optimized(dates: List[str]):
all_data: List[Dict] = []
total_queried = 0
for d in dates:
day_data = get_data_by_date(BitMart30, d)
all_data.extend(day_data)
if day_data:
total_queried += len(day_data)
logger.info(f"总共查询了 {len(dates)} 天,获取到 {total_queried} 条K线数据")
if not all_data:
logger.warning("未获取到任何数据,请检查:")
logger.warning("1. 数据库连接是否正常")
logger.warning("2. 查询的日期范围是否在数据范围内")
logger.warning("3. 时间戳格式是否正确(毫秒级)")
return [], {
'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'},
'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'},
}
# 重要合并所有数据后必须先按时间戳id排序
all_data.sort(key=lambda x: x['id'])
# 验证排序结果
if len(all_data) > 1:
first_ts = all_data[0]['id']
last_ts = all_data[-1]['id']
first_time = datetime.datetime.fromtimestamp(first_ts / 1000)
last_time = datetime.datetime.fromtimestamp(last_ts / 1000)
logger.info(f"数据已按时间排序:{first_time.strftime('%Y-%m-%d %H:%M:%S')}{last_time.strftime('%Y-%m-%d %H:%M:%S')}")
stats = {
'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'},
'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'},
}
trades: List[Dict] = []
current_position: Optional[Dict] = None # 开仓信息
consecutive_opposite_count = 0 # 连续反色K线计数
idx = 1
while idx < len(all_data) - 1:
prev, curr, next_bar = all_data[idx - 1], all_data[idx], all_data[idx + 1]
direction, signal_key = check_signal(prev, curr)
# 空仓 -> 碰到信号则开仓下一根K线开盘价
if current_position is None:
if direction:
entry_price = float(next_bar['open'])
current_position = {
'direction': direction,
'signal': stats[signal_key]['name'],
'signal_key': signal_key,
'entry_price': entry_price,
'entry_time': next_bar['id']
}
consecutive_opposite_count = 0 # 重置连续反色计数
stats[signal_key]['count'] += 1
idx += 1
continue
# 有仓位状态:检查平仓条件
pos_dir = current_position['direction']
pos_sig_key = current_position['signal_key']
# 1. 反向信号 -> 下一根K线开盘价平仓并反手开仓
if direction and direction != pos_dir:
exit_price = float(next_bar['open'])
diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else (
current_position['entry_price'] - exit_price)
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000),
'signal': current_position['signal'],
'direction': '做多' if pos_dir == 'long' else '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[pos_sig_key]['total_profit'] += diff
if diff > 0: stats[pos_sig_key]['wins'] += 1
# 反手开仓
current_position = {
'direction': direction,
'signal': stats[signal_key]['name'],
'signal_key': signal_key,
'entry_price': exit_price,
'entry_time': next_bar['id']
}
consecutive_opposite_count = 0 # 重置连续反色计数
stats[signal_key]['count'] += 1
idx += 1
continue
# 2. 检查连续反色K线平仓条件下一根K线开盘价平仓
# 持有多单:检查是否连续两根阴线
if pos_dir == 'long' and is_bearish(curr):
consecutive_opposite_count += 1
# 如果已经连续两根阴线下一根K线开盘价平仓
if consecutive_opposite_count >= 2:
exit_price = float(next_bar['open'])
diff = exit_price - current_position['entry_price']
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000),
'signal': current_position['signal'],
'direction': '做多',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[pos_sig_key]['total_profit'] += diff
if diff > 0: stats[pos_sig_key]['wins'] += 1
current_position = None
consecutive_opposite_count = 0
idx += 1
continue
else:
# 只有一根阴线,续持
idx += 1
continue
# 持有空单:检查是否连续两根阳线
elif pos_dir == 'short' and is_bullish(curr):
consecutive_opposite_count += 1
# 如果已经连续两根阳线下一根K线开盘价平仓
if consecutive_opposite_count >= 2:
exit_price = float(next_bar['open'])
diff = current_position['entry_price'] - exit_price
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000),
'signal': current_position['signal'],
'direction': '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[pos_sig_key]['total_profit'] += diff
if diff > 0: stats[pos_sig_key]['wins'] += 1
current_position = None
consecutive_opposite_count = 0
idx += 1
continue
else:
# 只有一根阳线,续持
idx += 1
continue
# 3. 同向K线或同向信号 -> 续持,重置连续反色计数
if (pos_dir == 'long' and is_bullish(curr)) or (pos_dir == 'short' and is_bearish(curr)):
consecutive_opposite_count = 0 # 重置连续反色计数
# 同向信号 -> 续持
if direction and direction == pos_dir:
consecutive_opposite_count = 0 # 重置连续反色计数
idx += 1
continue
idx += 1
# 尾仓:最后一根收盘价平仓
if current_position:
last = all_data[-1]
exit_price = float(last['close'])
pos_dir = current_position['direction']
diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else (
current_position['entry_price'] - exit_price)
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(last['id'] / 1000),
'signal': current_position['signal'],
'direction': '做多' if pos_dir == 'long' else '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[current_position['signal_key']]['total_profit'] += diff
if diff > 0: stats[current_position['signal_key']]['wins'] += 1
return trades, stats
# ========================= 运行示例(优化版盈利计算) =========================
if __name__ == '__main__':
# ==================== 配置参数:指定查询时间范围 ====================
# 方式1指定开始和结束日期推荐
START_DATE = "2025-01-01" # 开始日期格式YYYY-MM-DD
END_DATE = "2025-12-31" # 结束日期格式YYYY-MM-DD
# 方式2如果上面两个为空则使用年份和月份范围
START_YEAR = None # 开始年份例如2025
START_MONTH = None # 开始月份例如1
END_YEAR = None # 结束年份例如2025
END_MONTH = None # 结束月份例如12
# ==================== 生成查询日期列表 ====================
dates = []
# 优先使用指定的日期范围
if START_DATE and END_DATE:
try:
start_dt = datetime.datetime.strptime(START_DATE, '%Y-%m-%d')
end_dt = datetime.datetime.strptime(END_DATE, '%Y-%m-%d')
if start_dt > end_dt:
logger.error(f"开始日期 {START_DATE} 不能晚于结束日期 {END_DATE}")
exit(1)
current_dt = start_dt
while current_dt <= end_dt:
dates.append(current_dt.strftime('%Y-%m-%d'))
current_dt += datetime.timedelta(days=1)
logger.info(f"使用指定日期范围:{START_DATE}{END_DATE},共 {len(dates)}")
except ValueError as e:
logger.error(f"日期格式错误:{e},请使用 YYYY-MM-DD 格式")
exit(1)
# 如果未指定日期范围,使用年份和月份范围
elif START_YEAR and END_YEAR:
start_m = START_MONTH if START_MONTH else 1
end_m = END_MONTH if END_MONTH else 12
for year in range(START_YEAR, END_YEAR + 1):
month_start = start_m if year == START_YEAR else 1
month_end = end_m if year == END_YEAR else 12
for month in range(month_start, month_end + 1):
days_in_month = calendar.monthrange(year, month)[1]
for day in range(1, days_in_month + 1):
dates.append(f"{year}-{month:02d}-{day:02d}")
logger.info(f"使用年份月份范围:{START_YEAR}{start_m}月 到 {END_YEAR}{end_m}月,共 {len(dates)}")
# 如果都没有指定,使用默认范围
else:
logger.warning("未指定日期范围使用默认2025年1-12月")
for month in range(1, 13):
days_in_month = calendar.monthrange(2025, month)[1]
for day in range(1, days_in_month + 1):
dates.append(f"2025-{month:02d}-{day:02d}")
if dates:
logger.info(f"准备查询 {len(dates)} 天的数据,日期范围:{dates[0]}{dates[-1]}")
else:
logger.error("未生成任何查询日期,请检查配置参数")
exit(1)
trades, stats = backtest_15m_trend_optimized(dates)
logger.info("===== 每笔交易详情 =====")
# === 参数设定 ===
contract_size = 10000 # 合约规模1手对应多少基础货币
open_fee_fixed = 5 # 固定开仓手续费
close_fee_rate = 0.0005 # 按成交额比例的平仓手续费率
total_points_profit = 0 # 累计点差
total_money_profit = 0 # 累计金额盈利
total_fee = 0 # 累计手续费
for t in trades:
entry = t['entry']
exit = t['exit']
direction = t['direction']
# === 1⃣ 原始价差(点差) ===
point_diff = (exit - entry) if direction == '做多' else (entry - exit)
# === 2⃣ 金额盈利(考虑合约规模) ===
money_profit = point_diff / entry * contract_size # 利润以基础货币计例如USD
# === 3⃣ 手续费计算 ===
# 开仓 + 平仓手续费(按比例计算 + 固定)
fee = open_fee_fixed + (contract_size / entry * exit * close_fee_rate)
# === 4⃣ 净利润 ===
net_profit = money_profit - fee
# 保存计算结果
t.update({
'point_diff': point_diff,
'raw_profit': money_profit,
'fee': fee,
'net_profit': net_profit
})
total_points_profit += point_diff
total_money_profit += money_profit
total_fee += fee
# if net_profit < -400:
logger.info(
f"{t['entry_time']} {direction}({t['signal']}) "
f"入={entry:.2f} 出={exit:.2f} 差价={point_diff:.2f} "
f"原始盈利={money_profit:.2f} 手续费={fee:.2f} 净利润={net_profit:.2f} {t['exit_time']}"
)
# === 汇总统计 ===
total_net_profit = total_money_profit - total_fee
print(f"\n【BitMart 回测结果】")
print(f"一共交易笔数:{len(trades)}")
print(f"总点差:{total_points_profit:.2f}")
print(f"总原始盈利(未扣费):{total_money_profit:.2f}")
print(f"总手续费:{total_fee:.2f}")
print(f"总净利润:{total_net_profit:.2f}\n")
print(total_money_profit - total_fee * 0.1)
print("===== 信号统计 =====")
for k, v in stats.items():
name, count, wins, total_p = v['name'], v['count'], v['wins'], v['total_profit']
win_rate = (wins / count * 100) if count > 0 else 0.0
avg_p = (total_p / count) if count > 0 else 0.0
print(f"{name}: 次数={count} 胜率={win_rate:.2f}% 总价差={total_p:.2f} 平均价差={avg_p:.2f}")

View File

@@ -1,7 +1,8 @@
"""
BitMart 多周期K线数据抓取脚本
支持同时获取 1分钟、3分钟、5分钟、15分钟、30分钟、1小时 K线数据
自动创建对应的数据库表
支持秒级价格数据通过成交记录API
支持断点续传,从数据库最新/最早记录继续抓取
"""
import time
@@ -26,6 +27,34 @@ KLINE_CONFIGS = {
}
class BitMartETHTrades(Model):
"""成交记录模型(秒级/毫秒级原始数据)"""
id = BigIntegerField(primary_key=True) # 成交ID
timestamp = BigIntegerField(index=True) # 成交时间戳(毫秒)
price = FloatField() # 成交价格
volume = FloatField() # 成交量
side = IntegerField() # 方向: 1=买, -1=卖
class Meta:
database = db
table_name = 'bitmart_eth_trades'
class BitMartETHSecond(Model):
"""秒级K线模型由成交记录聚合而来"""
id = BigIntegerField(primary_key=True) # 时间戳(毫秒,取整到秒)
open = FloatField(null=True)
high = FloatField(null=True)
low = FloatField(null=True)
close = FloatField(null=True)
volume = FloatField(null=True)
trade_count = IntegerField(null=True) # 该秒内成交笔数
class Meta:
database = db
table_name = 'bitmart_eth_1s'
def create_kline_model(step: int):
"""
动态创建K线数据模型
@@ -85,67 +114,100 @@ class BitMartMultiKlineCollector:
# 创建表(如果不存在)
db.create_tables([model], safe=True)
logger.info(f"初始化表: {model._meta.table_name}")
# 创建成交记录表和秒级K线表
db.create_tables([BitMartETHTrades, BitMartETHSecond], safe=True)
logger.info(f"初始化表: bitmart_eth_trades (成交记录)")
logger.info(f"初始化表: bitmart_eth_1s (秒级K线)")
def get_klines(self, step: int, start_time: int, end_time: int):
def get_db_time_range(self, step: int):
"""
获取K线数据
获取数据库中已有数据的时间范围
:param step: K线周期
:return: (earliest_ts, latest_ts) 毫秒时间戳,无数据返回 (None, None)
"""
model = self.models.get(step)
if not model:
return None, None
try:
# 获取最早记录
earliest = model.select(fn.MIN(model.id)).scalar()
# 获取最新记录
latest = model.select(fn.MAX(model.id)).scalar()
return earliest, latest
except Exception as e:
logger.error(f"查询数据库时间范围异常: {e}")
return None, None
def get_klines(self, step: int, start_time: int, end_time: int, max_retries: int = 3):
"""
获取K线数据带重试
:param step: K线周期分钟
:param start_time: 开始时间戳(秒级)
:param end_time: 结束时间戳(秒级)
:param max_retries: 最大重试次数
:return: K线数据列表
"""
try:
# 确保是整数
start_time = int(start_time)
end_time = int(end_time)
logger.debug(f"API请求: step={step}, start={start_time}, end={end_time}")
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=step,
start_time=start_time,
end_time=end_time
)[0]
if response['code'] != 1000:
logger.error(f"获取 {step}分钟 K线失败: {response}")
for attempt in range(max_retries):
try:
start_time = int(start_time)
end_time = int(end_time)
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=step,
start_time=start_time,
end_time=end_time
)[0]
if response['code'] != 1000:
logger.warning(f"API返回错误 (尝试 {attempt+1}/{max_retries}): {response}")
if attempt < max_retries - 1:
time.sleep(1)
continue
return []
klines = response.get('data', [])
formatted = []
for k in klines:
timestamp_ms = int(k["timestamp"]) * 1000
formatted.append({
'id': timestamp_ms,
'open': float(k["open_price"]),
'high': float(k["high_price"]),
'low': float(k["low_price"]),
'close': float(k["close_price"])
})
formatted.sort(key=lambda x: x['id'])
return formatted
except Exception as e:
logger.error(f"获取K线异常 (尝试 {attempt+1}/{max_retries}): {e}")
if attempt < max_retries - 1:
time.sleep(2)
continue
return []
klines = response.get('data', [])
formatted = []
for k in klines:
timestamp_ms = int(k["timestamp"]) * 1000
formatted.append({
'id': timestamp_ms,
'open': float(k["open_price"]),
'high': float(k["high_price"]),
'low': float(k["low_price"]),
'close': float(k["close_price"])
})
formatted.sort(key=lambda x: x['id'])
return formatted
except Exception as e:
logger.error(f"获取 {step}分钟 K线异常: {e}")
return []
return []
def save_klines(self, step: int, klines: list):
"""
保存K线数据到数据库
:param step: K线周期
:param klines: K线数据列表
:return: 保存的数量
:return: 保存的数量
"""
model = self.models.get(step)
if not model:
logger.error(f"未找到 {step}分钟 的数据模型")
return 0
saved_count = 0
new_count = 0
for kline in klines:
try:
model.get_or_create(
_, created = model.get_or_create(
id=kline['id'],
defaults={
'open': kline['open'],
@@ -154,87 +216,164 @@ class BitMartMultiKlineCollector:
'close': kline['close'],
}
)
saved_count += 1
if created:
new_count += 1
except Exception as e:
logger.error(f"保存 {step}分钟 K线数据失败 {kline['id']}: {e}")
logger.error(f"保存K线数据失败 {kline['id']}: {e}")
return saved_count
return new_count
def collect_single_period(self, step: int, start_date: str = None, days: int = None):
def get_batch_seconds(self, step: int):
"""根据周期获取合适的批次大小"""
if step == 1:
return 3600 * 4 # 1分钟: 每次4小时
elif step == 3:
return 3600 * 8 # 3分钟: 每次8小时
elif step == 5:
return 3600 * 12 # 5分钟: 每次12小时
elif step == 15:
return 3600 * 24 # 15分钟: 每次1天
elif step == 30:
return 3600 * 48 # 30分钟: 每次2天
else:
return 3600 * 72 # 1小时: 每次3天
def collect_period_range(self, step: int, target_start: int, target_end: int):
"""
抓取单个周期的历史数据从当前时间向前抓取直到遇到API限制
抓取指定时间范围的K线数据支持断点续传
:param step: K线周期分钟
:param start_date: 起始日期 'YYYY-MM-DD'(目标,可能无法达到
:param days: 抓取天数(目标,可能无法达到
:param target_start: 目标开始时间戳(秒
:param target_end: 目标结束时间戳(秒
:return: 保存的总数量
"""
suffix = KLINE_CONFIGS.get(step, f'{step}m')
now = int(time.time())
batch_seconds = self.get_batch_seconds(step)
if start_date:
start_dt = datetime.datetime.strptime(start_date, '%Y-%m-%d')
target_start_time = int(start_dt.timestamp())
logger.info(f"开始抓取 {suffix} K线数据: 目标从 {start_date} 开始(从现在向前抓取)")
elif days:
target_start_time = now - 3600 * 24 * days
logger.info(f"开始抓取 {suffix} K线数据: 目标最近 {days}")
else:
target_start_time = now - 3600 * 24 * 30
logger.info(f"开始抓取 {suffix} K线数据: 目标最近 30 天")
# 获取数据库已有数据范围
db_earliest, db_latest = self.get_db_time_range(step)
# 根据周期调整批次大小
if step <= 5:
batch_seconds = 3600 * 6 # 小周期每次6小时
elif step <= 30:
batch_seconds = 3600 * 24 # 中周期每次1天
if db_earliest and db_latest:
db_earliest_sec = db_earliest // 1000
db_latest_sec = db_latest // 1000
logger.info(f"[{suffix}] 数据库已有数据: "
f"{time.strftime('%Y-%m-%d %H:%M', time.localtime(db_earliest_sec))} ~ "
f"{time.strftime('%Y-%m-%d %H:%M', time.localtime(db_latest_sec))}")
else:
batch_seconds = 3600 * 24 * 3 # 大周期每次3天
db_earliest_sec = None
db_latest_sec = None
logger.info(f"[{suffix}] 数据库暂无数据")
total_saved = 0
fail_count = 0
max_fail = 3
# 从当前时间向前抓取
current_end = now
while current_end > target_start_time:
current_start = current_end - batch_seconds
# 打印时间范围
start_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(current_start))
end_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(current_end))
logger.info(f"[{suffix}] 抓取: {start_str} -> {end_str}")
klines = self.get_klines(step, current_start, current_end)
if klines:
saved = self.save_klines(step, klines)
total_saved += saved
logger.info(f"[{suffix}] 保存 {saved} 条,累计 {total_saved}")
fail_count = 0
else:
fail_count += 1
logger.warning(f"[{suffix}] 未获取到数据 (连续失败 {fail_count} 次)")
if fail_count >= max_fail:
earliest = time.strftime('%Y-%m-%d', time.localtime(current_end))
logger.warning(f"[{suffix}] 达到API历史数据限制最早可用数据约 {earliest}")
break
current_end = current_start
time.sleep(0.3) # API请求间隔
# === 第一阶段:向前抓取历史数据(从数据库最早记录向前,直到 target_start===
if db_earliest_sec:
backward_end = db_earliest_sec
else:
backward_end = target_end
if backward_end > target_start:
logger.info(f"[{suffix}] === 开始向前抓取历史数据 ===")
total_backward = backward_end - target_start
current_end = backward_end
fail_count = 0
max_fail = 5
while current_end > target_start and fail_count < max_fail:
current_start = max(current_end - batch_seconds, target_start)
# 计算进度
progress = (backward_end - current_end) / total_backward * 100 if total_backward > 0 else 0
start_str = time.strftime('%Y-%m-%d %H:%M', time.localtime(current_start))
end_str = time.strftime('%Y-%m-%d %H:%M', time.localtime(current_end))
klines = self.get_klines(step, current_start, current_end)
if klines:
saved = self.save_klines(step, klines)
total_saved += saved
logger.info(f"[{suffix}] ← 历史 {start_str} ~ {end_str} | "
f"获取 {len(klines)} 条, 新增 {saved} 条 | 进度 {progress:.1f}%")
fail_count = 0
else:
fail_count += 1
logger.warning(f"[{suffix}] ← 历史 {start_str} 无数据 (连续失败 {fail_count}/{max_fail})")
if fail_count >= max_fail:
earliest_date = time.strftime('%Y-%m-%d', time.localtime(current_end))
logger.warning(f"[{suffix}] 已达到API历史数据限制最早可获取: {earliest_date}")
break
current_end = current_start
time.sleep(0.3)
# === 第二阶段:向后抓取最新数据(从数据库最新记录向后,直到 target_end===
if db_latest_sec:
forward_start = db_latest_sec
else:
# 如果没有数据,从第一阶段结束的地方开始
forward_start = target_start
if forward_start < target_end:
logger.info(f"[{suffix}] === 开始向后抓取最新数据 ===")
total_forward = target_end - forward_start
current_start = forward_start
fail_count = 0
max_fail = 3
while current_start < target_end and fail_count < max_fail:
current_end = min(current_start + batch_seconds, target_end)
# 计算进度
progress = (current_start - forward_start) / total_forward * 100 if total_forward > 0 else 0
start_str = time.strftime('%Y-%m-%d %H:%M', time.localtime(current_start))
end_str = time.strftime('%Y-%m-%d %H:%M', time.localtime(current_end))
klines = self.get_klines(step, current_start, current_end)
if klines:
saved = self.save_klines(step, klines)
total_saved += saved
logger.info(f"[{suffix}] → 最新 {start_str} ~ {end_str} | "
f"获取 {len(klines)} 条, 新增 {saved} 条 | 进度 {progress:.1f}%")
fail_count = 0
else:
fail_count += 1
logger.warning(f"[{suffix}] → 最新 {start_str} 无数据 (失败 {fail_count}/{max_fail})")
current_start = current_end
time.sleep(0.3)
# 统计最终数据范围
final_earliest, final_latest = self.get_db_time_range(step)
if final_earliest and final_latest:
logger.success(f"[{suffix}] 抓取完成!本次新增 {total_saved} 条 | 数据范围: "
f"{time.strftime('%Y-%m-%d', time.localtime(final_earliest//1000))} ~ "
f"{time.strftime('%Y-%m-%d', time.localtime(final_latest//1000))}")
else:
logger.success(f"[{suffix}] 抓取完成!本次新增 {total_saved}")
logger.success(f"[{suffix}] 抓取完成,共保存 {total_saved} 条数据")
return total_saved
def collect_all_periods(self, start_date: str = None, days: int = None,
periods: list = None):
def collect_from_date(self, start_date: str, periods: list = None):
"""
抓取所有周期的历史数据
从指定日期抓取到当前时间
:param start_date: 起始日期 'YYYY-MM-DD'
:param days: 抓取天数
:param periods: 要抓取的周期列表,如 [1, 5, 15],默认全部
"""
if periods is None:
periods = list(KLINE_CONFIGS.keys())
logger.info(f"开始抓取多周期K线数据周期: {[KLINE_CONFIGS[p] for p in periods]}")
# 计算时间范围
start_dt = datetime.datetime.strptime(start_date, '%Y-%m-%d')
target_start = int(start_dt.timestamp())
target_end = int(time.time())
start_str = start_dt.strftime('%Y-%m-%d')
end_str = datetime.datetime.now().strftime('%Y-%m-%d %H:%M')
logger.info(f"{'='*60}")
logger.info(f"目标时间范围: {start_str} ~ {end_str}")
logger.info(f"抓取周期: {[KLINE_CONFIGS[p] for p in periods]}")
logger.info(f"{'='*60}")
results = {}
for step in periods:
@@ -242,23 +381,347 @@ class BitMartMultiKlineCollector:
logger.warning(f"不支持的周期: {step}分钟,跳过")
continue
logger.info(f"\n{'='*50}")
logger.info(f"\n{'='*60}")
logger.info(f"开始抓取 {KLINE_CONFIGS[step]} K线")
logger.info(f"{'='*50}")
logger.info(f"{'='*60}")
saved = self.collect_single_period(step, start_date, days)
saved = self.collect_period_range(step, target_start, target_end)
results[KLINE_CONFIGS[step]] = saved
time.sleep(1) # 不同周期之间间隔
logger.info(f"\n{'='*50}")
# 打印总结
logger.info(f"\n{'='*60}")
logger.info("所有周期抓取完成!统计:")
for period, count in results.items():
logger.info(f" {period}: {count}")
logger.info(f"{'='*50}")
logger.info(f" {period}: 新增 {count}")
logger.info(f"{'='*60}")
return results
def get_stats(self):
"""获取各周期数据统计"""
logger.info(f"\n{'='*60}")
logger.info("数据库统计:")
logger.info(f"{'='*60}")
for step, model in self.models.items():
suffix = KLINE_CONFIGS.get(step, f'{step}m')
try:
count = model.select().count()
earliest, latest = self.get_db_time_range(step)
if earliest and latest:
earliest_str = time.strftime('%Y-%m-%d %H:%M', time.localtime(earliest//1000))
latest_str = time.strftime('%Y-%m-%d %H:%M', time.localtime(latest//1000))
logger.info(f" {suffix:>4}: {count:>8} 条 | {earliest_str} ~ {latest_str}")
else:
logger.info(f" {suffix:>4}: {count:>8}")
except Exception as e:
logger.error(f" {suffix}: 查询失败 - {e}")
# 成交记录统计
try:
trades_count = BitMartETHTrades.select().count()
if trades_count > 0:
earliest_trade = BitMartETHTrades.select(fn.MIN(BitMartETHTrades.timestamp)).scalar()
latest_trade = BitMartETHTrades.select(fn.MAX(BitMartETHTrades.timestamp)).scalar()
earliest_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(earliest_trade//1000))
latest_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(latest_trade//1000))
logger.info(f"trades: {trades_count:>8} 条 | {earliest_str} ~ {latest_str}")
else:
logger.info(f"trades: {trades_count:>8}")
except Exception as e:
logger.error(f"trades: 查询失败 - {e}")
# 秒级K线统计
try:
second_count = BitMartETHSecond.select().count()
if second_count > 0:
earliest_sec = BitMartETHSecond.select(fn.MIN(BitMartETHSecond.id)).scalar()
latest_sec = BitMartETHSecond.select(fn.MAX(BitMartETHSecond.id)).scalar()
earliest_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(earliest_sec//1000))
latest_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(latest_sec//1000))
logger.info(f" 1s: {second_count:>8} 条 | {earliest_str} ~ {latest_str}")
else:
logger.info(f" 1s: {second_count:>8}")
except Exception as e:
logger.error(f" 1s: 查询失败 - {e}")
logger.info(f"{'='*60}")
# ==================== 秒级数据相关方法 ====================
def get_trades(self, limit: int = 100):
"""
获取最近成交记录
:param limit: 获取条数
:return: 成交记录列表
"""
try:
response = self.contractAPI.get_trades(
contract_symbol=self.contract_symbol,
)[0]
if response['code'] != 1000:
logger.error(f"获取成交记录失败: {response}")
return []
trades = response.get('data', {}).get('trades', [])
formatted = []
for t in trades:
formatted.append({
'id': int(t.get('trade_id', 0)),
'timestamp': int(t.get('create_time', 0)),
'price': float(t.get('deal_price', 0)),
'volume': float(t.get('deal_vol', 0)),
'side': int(t.get('way', 0)),
})
return formatted
except Exception as e:
logger.error(f"获取成交记录异常: {e}")
return []
def save_trades(self, trades: list):
"""保存成交记录到数据库"""
new_count = 0
for trade in trades:
try:
_, created = BitMartETHTrades.get_or_create(
id=trade['id'],
defaults={
'timestamp': trade['timestamp'],
'price': trade['price'],
'volume': trade['volume'],
'side': trade['side'],
}
)
if created:
new_count += 1
except Exception as e:
pass # 忽略重复数据
return new_count
def collect_trades_realtime(self, duration_seconds: int = 3600, interval: float = 0.3):
"""
实时持续采集成交记录(秒级数据源)
:param duration_seconds: 采集时长默认1小时
:param interval: 采集间隔默认0.3秒
"""
logger.info(f"{'='*60}")
logger.info(f"开始实时采集成交记录")
logger.info(f"时长: {duration_seconds}秒 ({duration_seconds/3600:.1f}小时)")
logger.info(f"间隔: {interval}")
logger.info(f"{'='*60}")
start_time = time.time()
end_time = start_time + duration_seconds
total_saved = 0
batch_count = 0
while time.time() < end_time:
trades = self.get_trades(limit=100)
if trades:
saved = self.save_trades(trades)
total_saved += saved
batch_count += 1
# 每10批显示一次进度
if batch_count % 10 == 0:
elapsed = time.time() - start_time
remaining = end_time - time.time()
latest = trades[-1]
ts_str = datetime.datetime.fromtimestamp(
latest['timestamp']/1000
).strftime('%H:%M:%S')
logger.info(f"[{ts_str}] 价格: {latest['price']:.2f} | "
f"本批新增: {saved} | 累计: {total_saved} | "
f"剩余: {remaining/60:.1f}分钟")
time.sleep(interval)
logger.success(f"采集完成!共新增 {total_saved} 条成交记录")
# 自动聚合为秒级K线
logger.info("正在将成交记录聚合为秒级K线...")
self.aggregate_trades_to_seconds()
return total_saved
def aggregate_trades_to_seconds(self, start_ts: int = None, end_ts: int = None):
"""
将成交记录聚合为秒级K线数据
:param start_ts: 开始时间戳(毫秒),默认全部
:param end_ts: 结束时间戳(毫秒),默认全部
:return: 聚合的秒级K线数量
"""
# 构建查询
query = BitMartETHTrades.select().order_by(BitMartETHTrades.timestamp)
if start_ts:
query = query.where(BitMartETHTrades.timestamp >= start_ts)
if end_ts:
query = query.where(BitMartETHTrades.timestamp <= end_ts)
# 按秒聚合
second_data = {}
trade_count = 0
for trade in query:
trade_count += 1
# 取整到秒(毫秒时间戳)
second_ts = (trade.timestamp // 1000) * 1000
if second_ts not in second_data:
second_data[second_ts] = {
'open': trade.price,
'high': trade.price,
'low': trade.price,
'close': trade.price,
'volume': trade.volume,
'trade_count': 1
}
else:
second_data[second_ts]['high'] = max(second_data[second_ts]['high'], trade.price)
second_data[second_ts]['low'] = min(second_data[second_ts]['low'], trade.price)
second_data[second_ts]['close'] = trade.price
second_data[second_ts]['volume'] += trade.volume
second_data[second_ts]['trade_count'] += 1
# 保存到数据库
saved_count = 0
for ts, ohlc in second_data.items():
try:
BitMartETHSecond.insert(
id=ts,
open=ohlc['open'],
high=ohlc['high'],
low=ohlc['low'],
close=ohlc['close'],
volume=ohlc['volume'],
trade_count=ohlc['trade_count']
).on_conflict(
conflict_target=[BitMartETHSecond.id],
update={
BitMartETHSecond.open: ohlc['open'],
BitMartETHSecond.high: ohlc['high'],
BitMartETHSecond.low: ohlc['low'],
BitMartETHSecond.close: ohlc['close'],
BitMartETHSecond.volume: ohlc['volume'],
BitMartETHSecond.trade_count: ohlc['trade_count'],
}
).execute()
saved_count += 1
except Exception as e:
logger.error(f"保存秒级K线失败 {ts}: {e}")
logger.success(f"聚合完成!{trade_count} 条成交记录 → {saved_count} 条秒级K线")
return saved_count
def get_second_klines(self, start_ts: int = None, end_ts: int = None):
"""
获取秒级K线数据
:param start_ts: 开始时间戳(毫秒)
:param end_ts: 结束时间戳(毫秒)
:return: 秒级K线列表
"""
query = BitMartETHSecond.select().order_by(BitMartETHSecond.id)
if start_ts:
query = query.where(BitMartETHSecond.id >= start_ts)
if end_ts:
query = query.where(BitMartETHSecond.id <= end_ts)
return [{
'timestamp': k.id,
'open': k.open,
'high': k.high,
'low': k.low,
'close': k.close,
'volume': k.volume,
'trade_count': k.trade_count
} for k in query]
def aggregate_trades_custom(self, interval_ms: int = 100, start_ts: int = None, end_ts: int = None):
"""
将成交记录聚合为自定义毫秒级K线数据不保存到数据库直接返回
:param interval_ms: 聚合周期(毫秒),如 100=100ms, 500=500ms, 1000=1秒
:param start_ts: 开始时间戳(毫秒)
:param end_ts: 结束时间戳(毫秒)
:return: K线列表 [{'timestamp', 'open', 'high', 'low', 'close', 'volume', 'trade_count'}, ...]
"""
# 构建查询
query = BitMartETHTrades.select().order_by(BitMartETHTrades.timestamp)
if start_ts:
query = query.where(BitMartETHTrades.timestamp >= start_ts)
if end_ts:
query = query.where(BitMartETHTrades.timestamp <= end_ts)
# 按指定间隔聚合
interval_data = {}
trade_count = 0
for trade in query:
trade_count += 1
# 取整到指定间隔
interval_ts = (trade.timestamp // interval_ms) * interval_ms
if interval_ts not in interval_data:
interval_data[interval_ts] = {
'open': trade.price,
'high': trade.price,
'low': trade.price,
'close': trade.price,
'volume': trade.volume,
'trade_count': 1
}
else:
interval_data[interval_ts]['high'] = max(interval_data[interval_ts]['high'], trade.price)
interval_data[interval_ts]['low'] = min(interval_data[interval_ts]['low'], trade.price)
interval_data[interval_ts]['close'] = trade.price
interval_data[interval_ts]['volume'] += trade.volume
interval_data[interval_ts]['trade_count'] += 1
# 转换为列表
result = []
for ts, ohlc in sorted(interval_data.items()):
result.append({
'timestamp': ts,
'datetime': datetime.datetime.fromtimestamp(ts/1000).strftime('%Y-%m-%d %H:%M:%S.%f')[:-3],
'open': ohlc['open'],
'high': ohlc['high'],
'low': ohlc['low'],
'close': ohlc['close'],
'volume': ohlc['volume'],
'trade_count': ohlc['trade_count']
})
logger.info(f"聚合完成: {trade_count} 条成交记录 → {len(result)}{interval_ms}ms K线")
return result
def get_raw_trades(self, start_ts: int = None, end_ts: int = None, limit: int = None):
"""
获取原始成交记录(逐笔数据,毫秒级)
:param start_ts: 开始时间戳(毫秒)
:param end_ts: 结束时间戳(毫秒)
:param limit: 最大返回条数
:return: 成交记录列表
"""
query = BitMartETHTrades.select().order_by(BitMartETHTrades.timestamp)
if start_ts:
query = query.where(BitMartETHTrades.timestamp >= start_ts)
if end_ts:
query = query.where(BitMartETHTrades.timestamp <= end_ts)
if limit:
query = query.limit(limit)
return [{
'id': t.id,
'timestamp': t.timestamp,
'datetime': datetime.datetime.fromtimestamp(t.timestamp/1000).strftime('%Y-%m-%d %H:%M:%S.%f')[:-3],
'price': t.price,
'volume': t.volume,
'side': '' if t.side == 1 else ''
} for t in query]
def close(self):
"""关闭数据库连接"""
if not db.is_closed():
@@ -269,11 +732,30 @@ if __name__ == '__main__':
collector = BitMartMultiKlineCollector()
try:
# 抓取尽可能多的历史数据从现在向前直到遇到API限制自动停止
# 目标2025-01-01但实际能抓取多少取决于 BitMart API 的历史数据限制
collector.collect_all_periods(
start_date='2025-01-01', # 目标起始日期
# 查看当前数据统计
collector.get_stats()
# ============ 选择要执行的任务 ============
# 任务1: 抓取K线数据1分钟~1小时周期
# 从 2025-01-01 抓取到当前时间(支持断点续传)
collector.collect_from_date(
start_date='2025-01-01',
periods=[1, 3, 5, 15, 30, 60] # 所有周期
)
# 任务2: 实时采集秒级数据(成交记录)
# 注意: 秒级数据只能实时采集,无法获取历史
# collector.collect_trades_realtime(
# duration_seconds=3600, # 采集1小时
# interval=0.3 # 每0.3秒请求一次
# )
# 任务3: 将已采集的成交记录聚合为秒级K线
# collector.aggregate_trades_to_seconds()
# 再次查看统计
collector.get_stats()
finally:
collector.close()

View File

@@ -1,382 +0,0 @@
import time
import datetime
import openBrowser
from tqdm import tqdm
from loguru import logger
from bit_tools import openBrowser
from DrissionPage import ChromiumPage
from DrissionPage import ChromiumOptions
from bitmart.api_contract import APIContract
class BitmartFuturesTransaction:
def __init__(self, bit_id):
self.page: ChromiumPage | None = None
self.api_key = "a0fb7b98464fd9bcce67e7c519d58ec10d0c38a8"
self.secret_key = "4eaeba78e77aeaab1c2027f846a276d164f264a44c2c1bb1c5f3be50c8de1ca5"
self.memo = "合约交易"
self.contract_symbol = "ETHUSDT"
self.contractAPI = APIContract(self.api_key, self.secret_key, self.memo, timeout=(5, 15))
self.start = 0 # 持仓状态: -1 空, 0 无, 1 多
self.direction = None
self.pbar = tqdm(total=30, desc="等待K线", ncols=80)
self.last_kline_time = None
self.leverage = "100" # 高杠杆(全仓模式下可开更大仓位)
self.open_type = "cross" # 全仓模式(你的“成本开仓”需求)
self.risk_percent = 0.01 # 每次开仓使用可用余额的 1%
self.open_avg_price = None # 开仓价格
self.current_amount = None # 持仓量
self.bit_id = bit_id
def get_klines(self):
"""获取最近3根30分钟K线step=30"""
try:
end_time = int(time.time())
# 获取足够多的条目确保有最新3根
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=30, # 30分钟
start_time=end_time - 3600 * 10, # 取最近10小时
end_time=end_time
)[0]["data"]
# 每根: [timestamp, open, high, low, close, volume]
formatted = []
for k in response:
formatted.append({
'id': int(k["timestamp"]),
'open': float(k["open_price"]),
'high': float(k["high_price"]),
'low': float(k["low_price"]),
'close': float(k["close_price"])
})
formatted.sort(key=lambda x: x['id'])
return formatted # 最近3根: kline_1 (最老), kline_2, kline_3 (最新)
except Exception as e:
logger.error(f"获取K线异常: {e}")
self.ding(error=True, msg="获取K线异常")
return None
def get_current_price(self):
"""获取当前最新价格,用于计算张数"""
try:
end_time = int(time.time())
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=1, # 1分钟
start_time=end_time - 3600 * 3, # 取最近10小时
end_time=end_time
)[0]
if response['code'] == 1000:
return float(response['data'][-1]["close_price"])
return None
except Exception as e:
logger.error(f"获取价格异常: {e}")
return None
def get_available_balance(self):
"""获取合约账户可用USDT余额"""
try:
response = self.contractAPI.get_assets_detail()[0]
if response['code'] == 1000:
data = response['data']
if isinstance(data, dict):
return float(data.get('available_balance', 0))
elif isinstance(data, list):
for asset in data:
if asset.get('currency') == 'USDT':
return float(asset.get('available_balance', 0))
return None
except Exception as e:
logger.error(f"余额查询异常: {e}")
return None
# 获取当前持仓方向
def get_position_status(self):
"""获取当前持仓方向"""
try:
response = self.contractAPI.get_position(contract_symbol=self.contract_symbol)[0]
if response['code'] == 1000:
positions = response['data']
if not positions:
self.start = 0
return True
self.start = 1 if positions[0]['position_type'] == 1 else -1
self.open_avg_price = positions[0]['open_avg_price']
self.current_amount = positions[0]['current_amount']
self.position_cross = positions[0]["position_cross"]
return True
else:
return False
except Exception as e:
logger.error(f"持仓查询异常: {e}")
return False
# 设置杠杆和全仓
def set_leverage(self):
"""程序启动时设置全仓 + 高杠杆"""
try:
response = self.contractAPI.post_submit_leverage(
contract_symbol=self.contract_symbol,
leverage=self.leverage,
open_type=self.open_type
)[0]
if response['code'] == 1000:
logger.success(f"全仓模式 + {self.leverage}x 杠杆设置成功")
return True
else:
logger.error(f"杠杆设置失败: {response}")
return False
except Exception as e:
logger.error(f"设置杠杆异常: {e}")
return False
def openBrowser(self):
"""打开 TGE 对应浏览器实例"""
try:
bit_port = openBrowser(id=self.bit_id)
co = ChromiumOptions()
co.set_local_port(port=bit_port)
self.page = ChromiumPage(addr_or_opts=co)
return True
except:
return False
def take_over_browser(self):
"""接管浏览器"""
try:
co = ChromiumOptions()
co.set_local_port(self.tge_port)
self.page = ChromiumPage(addr_or_opts=co)
self.page.set.window.max()
return True
except:
return False
def close_extra_tabs(self):
"""关闭多余 tab"""
try:
for idx, tab in enumerate(self.page.get_tabs()):
if idx > 0:
tab.close()
return True
except:
return False
def click_safe(self, xpath, sleep=0.5):
"""安全点击"""
try:
ele = self.page.ele(xpath)
if not ele:
return False
ele.scroll.to_see(center=True)
time.sleep(sleep)
ele.click()
return True
except:
return False
def 平仓(self):
self.click_safe('x://span[normalize-space(text()) ="市价"]')
def 开单(self, marketPriceLongOrder=0, limitPriceShortOrder=0, size=None, price=None):
"""
marketPriceLongOrder 市价最多或者做空1是做多-1是做空
limitPriceShortOrder 限价最多或者做空
"""
if marketPriceLongOrder == -1:
self.click_safe('x://button[normalize-space(text()) ="市价"]')
self.page.ele('x://*[@id="size_0"]').input(size)
self.click_safe('x://span[normalize-space(text()) ="卖出/做空"]')
elif marketPriceLongOrder == 1:
self.click_safe('x://button[normalize-space(text()) ="市价"]')
self.page.ele('x://*[@id="size_0"]').input(size)
self.click_safe('x://span[normalize-space(text()) ="买入/做多"]')
if limitPriceShortOrder == -1:
self.click_safe('x://button[normalize-space(text()) ="限价"]')
self.page.ele('x://*[@id="price_0"]').input(vals=price, clear=True)
time.sleep(1)
self.page.ele('x://*[@id="size_0"]').input(1)
self.click_safe('x://span[normalize-space(text()) ="卖出/做空"]')
elif limitPriceShortOrder == 1:
self.click_safe('x://button[normalize-space(text()) ="限价"]')
self.page.ele('x://*[@id="price_0"]').input(vals=price, clear=True)
time.sleep(1)
self.page.ele('x://*[@id="size_0"]').input(1)
self.click_safe('x://span[normalize-space(text()) ="买入/做多"]')
def ding(self, text, error=False):
logger.info(text)
def close_extra_tabs_in_browser(self):
try:
for _, i in enumerate(self.page.get_tabs()):
if _ == 0:
continue
i.close()
return True
except:
pass
return False
def get_now_time(self):
# 获取当前时间戳
current_timestamp = time.time()
# 将当前时间戳转换为 datetime 对象
current_datetime = datetime.datetime.fromtimestamp(current_timestamp)
# 计算距离当前时间最近的整点或 30 分时刻
if current_datetime.minute < 30:
target_datetime = current_datetime.replace(minute=0, second=0, microsecond=0)
else:
target_datetime = current_datetime.replace(minute=30, second=0, microsecond=0)
# 将目标 datetime 对象转换为时间戳
target_timestamp = target_datetime.timestamp()
return int(target_timestamp)
def is_bullish(self, c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(self, c): # 阴线
return float(c['close']) < float(c['open'])
def check_signal(self, prev, curr):
"""
包住形态信号判定(优化版):
只看两种信号,严格按照收盘价与开盘价的比较:
1. 阳包阴(涨包跌,前跌后涨)-> 做多:
- 前一根是跌阴线close < open
- 后一根是涨阳线close > open
- 且:涨的收盘价 > 跌的开盘价curr['close'] > prev['open']
2. 阴包阳(跌包涨,前涨后跌)-> 做空:
- 前一根是涨阳线close > open
- 后一根是跌阴线close < open
- 且:跌的收盘价 < 涨的开盘价curr['close'] < prev['open']
"""
p_open = float(prev['open'])
c_close = float(curr['close'])
# 阳包阴(涨包跌,前跌后涨) -> 做多:涨的收盘价 > 跌的开盘价
if self.is_bearish(prev) and self.is_bullish(curr) and c_close > p_open:
return "long", "bear_bull_engulf"
# 阴包阳(跌包涨,前涨后跌) -> 做空:跌的收盘价 < 涨的开盘价
if self.is_bullish(prev) and self.is_bearish(curr) and c_close < p_open:
return "short", "bull_bear_engulf"
return None, None
def action(self):
# 启动时设置全仓高杠杆
if not self.set_leverage():
logger.error("杠杆设置失败,程序继续运行但可能下单失败")
return
# 1. 打开浏览器
if not self.openBrowser():
self.ding("打开 TGE 失败!", error=True)
return
logger.info("TGE 端口获取成功")
if self.close_extra_tabs_in_browser():
logger.info('关闭多余标签页成功!!!')
else:
logger.info('关闭多余标签页失败!!!')
self.page.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
self.click_safe('x://button[normalize-space(text()) ="市价"]')
self.pbar = tqdm(total=30, desc="等待时间中", ncols=80) # desc进度条说明ncols长度
self.time_start = None # 时间状态 避免同一个时段,发生太多消息
while True:
# 获取当前时间
current_time = time.localtime()
current_minute = current_time.tm_min
if current_minute < 30:
self.pbar.n = current_minute
self.pbar.refresh()
else:
self.pbar.n = current_minute - 30
self.pbar.refresh()
if self.time_start == self.get_now_time():
time.sleep(5)
continue
new_price_datas = self.get_klines()
if not new_price_datas:
logger.info("获取最新价格有问题!!!")
new_price_datas1 = sorted(new_price_datas, key=lambda x: x["id"])
self.kline_1, self.kline_2, self.kline_3 = new_price_datas1[-3:]
# 判断抓取的数据是否正确
if self.get_now_time() != self.kline_3["id"]:
continue
self.time_start = self.get_now_time()
if self.get_position_status():
logger.info("获取仓位信息成功!!!")
else:
logger.info("获取仓位信息失败!!!")
self.send_dingtalk_message(message_content=f"获取仓位信息失败!!!", type=0)
continue
if self.start == 1:
if self.is_bearish(self.kline_1) and self.is_bearish(self.kline_2):
self.平仓()
elif self.start == -1:
if self.is_bullish(self.kline_1) and self.is_bullish(self.kline_2):
self.平仓()
self.direction, signal_key = self.check_signal(prev=self.kline_1, curr=self.kline_2) # 判断信号
if self.direction == "long":
if self.start == -1:
self.平仓()
self.开单(marketPriceLongOrder=1, size=self.get_available_balance() * self.risk_percent)
elif self.start == 0:
self.开单(marketPriceLongOrder=1, size=self.get_available_balance() * self.risk_percent)
if self.direction == "short":
if self.start == 1:
self.平仓()
self.开单(marketPriceLongOrder=-1, size=self.get_available_balance() * self.risk_percent)
elif self.start == 0:
self.开单(marketPriceLongOrder=-1, size=self.get_available_balance() * self.risk_percent)
self.pbar.reset() # 重置进度条
if __name__ == '__main__':
BitmartFuturesTransaction(bit_id="f2320f57e24c45529a009e1541e25961").action()

View File

@@ -1,21 +0,0 @@
2025-12-20 02:51:09.247 | WARNING | __main__:__init__:28 - 请确认Memo是否正确默认Memo可能导致签名失败
2025-12-20 02:51:09.252 | INFO | __main__:init_api_client:57 - 尝试初始化API客户端 (尝试 1/3)
2025-12-20 02:51:09.253 | ERROR | __main__:test_api_connection:112 - API连接测试失败: APIContract.get_depth() got an unexpected keyword argument 'limit'
2025-12-20 02:51:09.254 | SUCCESS | __main__:init_api_client:87 - API客户端初始化成功
2025-12-20 02:51:09.254 | INFO | __main__:action:220 - 启动BitMart合约策略...
2025-12-20 02:51:09.254 | INFO | __main__:set_leverage_with_retry:121 - 尝试设置杠杆 (尝试 1/3)
2025-12-20 02:51:09.814 | ERROR | __main__:set_leverage_with_retry:149 - API异常: APIException(http status=401): response={"code":30005,"msg":"Header X-BM-SIGN is wrong","trace":"d9c107e3-7564-474e-9eaf-59667f869ae5"}
2025-12-20 02:51:09.814 | INFO | __main__:set_leverage_with_retry:161 - 等待1秒后重试...
2025-12-20 02:51:10.815 | INFO | __main__:set_leverage_with_retry:121 - 尝试设置杠杆 (尝试 2/3)
2025-12-20 02:51:10.923 | ERROR | __main__:set_leverage_with_retry:149 - API异常: APIException(http status=401): response={"trace":"a7fa76a2-2e34-435b-acbe-90e37b47fe48","code":30005,"msg":"Header X-BM-SIGN is wrong"}
2025-12-20 02:51:10.923 | INFO | __main__:set_leverage_with_retry:161 - 等待2秒后重试...
2025-12-20 02:51:12.923 | INFO | __main__:set_leverage_with_retry:121 - 尝试设置杠杆 (尝试 3/3)
2025-12-20 02:51:13.029 | ERROR | __main__:set_leverage_with_retry:149 - API异常: APIException(http status=401): response={"code":30005,"msg":"Header X-BM-SIGN is wrong","trace":"97b6c791-5812-4285-a659-dbba3f6170e6"}
2025-12-20 02:51:13.029 | WARNING | __main__:set_leverage_with_retry:168 - 杠杆设置失败,但程序将继续运行
2025-12-20 02:51:13.030 | WARNING | __main__:action:226 - 杠杆设置失败,使用系统默认杠杆继续运行
2025-12-20 02:51:13.150 | SUCCESS | __main__:action:254 - 获取到新K线: 2025-12-20 02:30:00
2025-12-20 02:51:13.150 | INFO | __main__:action:259 - 当前价格: 2959.49
2025-12-20 02:51:13.311 | INFO | __main__:action:268 - 用户中断程序

View File

@@ -1,46 +0,0 @@
2025-12-20 03:08:42.274 | INFO | __main__:initialize_api:66 - 尝试API配置 1/3
2025-12-20 03:08:42.275 | INFO | __main__:initialize_api:67 - Memo: ''
2025-12-20 03:08:42.275 | ERROR | __main__:test_api_connection:108 - API连接测试失败: 'APIContract' object has no attribute 'get_contracts'
2025-12-20 03:08:42.276 | WARNING | __main__:initialize_api:84 - API配置 1 连接失败,尝试下一个配置
2025-12-20 03:08:42.276 | INFO | __main__:initialize_api:66 - 尝试API配置 2/3
2025-12-20 03:08:42.276 | INFO | __main__:initialize_api:67 - Memo: '合约交易'
2025-12-20 03:08:42.276 | ERROR | __main__:test_api_connection:108 - API连接测试失败: 'APIContract' object has no attribute 'get_contracts'
2025-12-20 03:08:42.276 | WARNING | __main__:initialize_api:84 - API配置 2 连接失败,尝试下一个配置
2025-12-20 03:08:42.276 | INFO | __main__:initialize_api:66 - 尝试API配置 3/3
2025-12-20 03:08:42.277 | INFO | __main__:initialize_api:67 - Memo: 'None'
2025-12-20 03:08:42.277 | ERROR | __main__:test_api_connection:108 - API连接测试失败: 'APIContract' object has no attribute 'get_contracts'
2025-12-20 03:08:42.277 | WARNING | __main__:initialize_api:84 - API配置 3 连接失败,尝试下一个配置
2025-12-20 03:08:42.277 | ERROR | __main__:initialize_api:89 - 所有API配置都失败
2025-12-20 03:08:42.281 | ERROR | __main__:action:408 - API初始化失败程序无法运行
2025-12-20 03:08:48.311 | INFO | __main__:initialize_api:66 - 尝试API配置 1/3
2025-12-20 03:08:48.312 | INFO | __main__:initialize_api:67 - Memo: ''
2025-12-20 03:08:48.313 | ERROR | __main__:test_api_connection:108 - API连接测试失败: 'APIContract' object has no attribute 'get_contracts'
2025-12-20 03:08:48.313 | WARNING | __main__:initialize_api:84 - API配置 1 连接失败,尝试下一个配置
2025-12-20 03:08:48.313 | INFO | __main__:initialize_api:66 - 尝试API配置 2/3
2025-12-20 03:08:48.313 | INFO | __main__:initialize_api:67 - Memo: '合约交易'
2025-12-20 03:08:48.313 | ERROR | __main__:test_api_connection:108 - API连接测试失败: 'APIContract' object has no attribute 'get_contracts'
2025-12-20 03:08:48.313 | WARNING | __main__:initialize_api:84 - API配置 2 连接失败,尝试下一个配置
2025-12-20 03:08:48.313 | INFO | __main__:initialize_api:66 - 尝试API配置 3/3
2025-12-20 03:08:48.313 | INFO | __main__:initialize_api:67 - Memo: 'None'
2025-12-20 03:08:48.313 | ERROR | __main__:test_api_connection:108 - API连接测试失败: 'APIContract' object has no attribute 'get_contracts'
2025-12-20 03:08:48.313 | WARNING | __main__:initialize_api:84 - API配置 3 连接失败,尝试下一个配置
2025-12-20 03:08:48.314 | ERROR | __main__:initialize_api:89 - 所有API配置都失败
2025-12-20 03:08:48.317 | ERROR | __main__:action:408 - API初始化失败程序无法运行
2025-12-20 03:09:25.953 | INFO | __main__:initialize_api:66 - 尝试API配置 1/3
2025-12-20 03:09:25.954 | INFO | __main__:initialize_api:67 - Memo: ''
2025-12-20 03:09:25.954 | ERROR | __main__:test_api_connection:108 - API连接测试失败: 'APIContract' object has no attribute 'get_contracts'
2025-12-20 03:09:25.954 | WARNING | __main__:initialize_api:84 - API配置 1 连接失败,尝试下一个配置
2025-12-20 03:09:25.954 | INFO | __main__:initialize_api:66 - 尝试API配置 2/3
2025-12-20 03:09:25.954 | INFO | __main__:initialize_api:67 - Memo: '合约交易'
2025-12-20 03:09:25.954 | ERROR | __main__:test_api_connection:108 - API连接测试失败: 'APIContract' object has no attribute 'get_contracts'
2025-12-20 03:09:25.954 | WARNING | __main__:initialize_api:84 - API配置 2 连接失败,尝试下一个配置
2025-12-20 03:09:25.954 | INFO | __main__:initialize_api:66 - 尝试API配置 3/3
2025-12-20 03:09:25.954 | INFO | __main__:initialize_api:67 - Memo: 'None'
2025-12-20 03:09:25.955 | ERROR | __main__:test_api_connection:108 - API连接测试失败: 'APIContract' object has no attribute 'get_contracts'
2025-12-20 03:09:25.955 | WARNING | __main__:initialize_api:84 - API配置 3 连接失败,尝试下一个配置
2025-12-20 03:09:25.955 | ERROR | __main__:initialize_api:89 - 所有API配置都失败
2025-12-20 03:09:25.958 | ERROR | __main__:action:408 - API初始化失败程序无法运行
2025-12-20 03:12:23.884 | INFO | __main__:action:396 - 启动BitMart合约交易策略...
2025-12-20 03:12:23.885 | INFO | __main__:test_api_connection:48 - 测试API连接...
2025-12-20 03:12:24.359 | ERROR | __main__:test_api_connection:90 - API连接测试异常: 'tuple' object has no attribute 'get'
2025-12-20 03:12:24.359 | ERROR | __main__:action:400 - API连接测试失败

View File

@@ -1,415 +0,0 @@
"""
EVM助记词碰撞工具 - 高速版本
批量生成助记词并检查余额,发现有钱包自动保存
依赖安装:
pip install mnemonic eth-account web3 loguru
使用方法:
python evm_助记词查询余额.py
"""
import os
import json
import threading
from datetime import datetime
from mnemonic import Mnemonic
from eth_account import Account
from web3 import Web3
from loguru import logger
import time
# 尝试导入POA中间件
try:
from web3.middleware import geth_poa_middleware
except ImportError:
try:
from web3.middleware.geth_poa import geth_poa_middleware
except ImportError:
geth_poa_middleware = None
# 配置日志
logger.remove()
logger.add(lambda msg: print(msg, end=''), format="<green>{time:HH:mm:ss}</green> | <level>{level: <8}</level> | {message}", level="INFO")
# 全局统计
stats = {
'total_checked': 0,
'found_balance': 0,
'start_time': time.time(),
'lock': threading.Lock()
}
# 结果保存文件
RESULTS_FILE = "found_wallets.txt"
SAVE_LOCK = threading.Lock()
class FastEVMWallet:
"""高速EVM钱包碰撞工具"""
# 优化的RPC端点使用多个备用节点提高速度
RPC_ENDPOINTS = {
"ethereum": [
"https://eth.llamarpc.com",
"https://rpc.ankr.com/eth",
"https://ethereum.publicnode.com",
],
"bsc": [
"https://bsc-dataseed1.binance.org",
"https://bsc-dataseed2.binance.org",
"https://rpc.ankr.com/bsc",
],
# "polygon": [
# "https://polygon-rpc.com",
# "https://rpc.ankr.com/polygon",
# ],
# "arbitrum": [
# "https://arb1.arbitrum.io/rpc",
# "https://rpc.ankr.com/arbitrum",
# ],
# "optimism": [
# "https://mainnet.optimism.io",
# "https://rpc.ankr.com/optimism",
# ],
"base": [
"https://mainnet.base.org",
"https://rpc.ankr.com/base",
],
}
def __init__(self, chains=None):
"""
初始化
Args:
chains: 要查询的链列表None表示查询所有链
"""
self.mnemo = Mnemonic("english")
Account.enable_unaudited_hdwallet_features()
# 选择要查询的链(默认只查询主要链以提高速度)
if chains is None:
self.chains = ["ethereum", "bsc", "polygon", "arbitrum", "base"]
else:
self.chains = chains
# 为每个链创建Web3连接池
self.w3_pools = {}
self._init_connections()
def _init_connections(self):
"""初始化RPC连接"""
logger.info("正在初始化RPC连接...")
for chain in self.chains:
if chain in self.RPC_ENDPOINTS:
# 尝试所有RPC节点直到找到一个可用的
w3 = None
for rpc_url in self.RPC_ENDPOINTS[chain]:
try:
# 设置更短的超时时间,避免阻塞
w3 = Web3(Web3.HTTPProvider(rpc_url, request_kwargs={'timeout': 3}))
# 某些链需要POA中间件
if chain in ["bsc", "polygon"] and geth_poa_middleware is not None:
try:
w3.middleware_onion.inject(geth_poa_middleware, layer=0)
except:
pass
# 测试连接(快速测试)
try:
if w3.is_connected():
self.w3_pools[chain] = w3
logger.info(f"{chain} 连接成功: {rpc_url}")
break
except:
continue
except Exception as e:
continue
if chain not in self.w3_pools:
logger.warning(f"{chain} 连接失败,将跳过该链")
def generate_mnemonic(self, strength=128):
"""快速生成助记词"""
return self.mnemo.generate(strength=strength)
def mnemonic_to_address(self, mnemonic, account_index=0):
"""
从助记词快速生成地址(不生成私钥,节省时间)
Returns:
str: 钱包地址失败返回None
"""
try:
account = Account.from_mnemonic(mnemonic, account_path=f"m/44'/60'/0'/0/{account_index}")
return account.address
except:
return None
def quick_check_balance(self, address):
"""
快速检查地址是否有余额(只检查主要链,一旦发现余额就返回)
Returns:
dict: 如果有余额返回余额信息否则返回None
"""
# 只检查最快的链ethereum和bsc提高速度
priority_chains = ["ethereum", "bsc"]
for chain in priority_chains:
if chain not in self.chains:
continue
try:
w3 = self.w3_pools.get(chain)
if not w3:
continue
# 查询余额(设置超时,避免阻塞)
try:
balance_wei = w3.eth.get_balance(address)
if balance_wei > 0:
balance_eth = Web3.from_wei(balance_wei, 'ether')
return {
'chain': chain,
'address': address,
'balance_wei': balance_wei,
'balance_eth': float(balance_eth),
'balance_formatted': f"{balance_eth:.6f} ETH"
}
except Exception as e:
# 查询失败,尝试下一个链
continue
except:
continue
return None
def check_all_chains(self, address):
"""
检查所有链的余额(发现余额后调用)
Returns:
list: 所有有余额的链信息
"""
results = []
for chain in self.chains:
try:
w3 = self.w3_pools.get(chain)
if not w3 or not w3.is_connected():
continue
balance_wei = w3.eth.get_balance(address)
if balance_wei > 0:
balance_eth = Web3.from_wei(balance_wei, 'ether')
results.append({
'chain': chain,
'balance_wei': balance_wei,
'balance_eth': float(balance_eth),
'balance_formatted': f"{balance_eth:.6f} ETH"
})
except:
continue
return results
def save_found_wallet(mnemonic, address, private_key, balances):
"""保存发现的钱包信息"""
with SAVE_LOCK:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
info = {
'timestamp': timestamp,
'mnemonic': mnemonic,
'address': address,
'private_key': private_key,
'balances': balances
}
# 保存到文件
with open(RESULTS_FILE, 'a', encoding='utf-8') as f:
f.write("="*80 + "\n")
f.write(f"发现时间: {timestamp}\n")
f.write(f"助记词: {mnemonic}\n")
f.write(f"地址: {address}\n")
f.write(f"私钥: {private_key}\n")
f.write("余额信息:\n")
for balance in balances:
f.write(f" {balance['chain'].upper()}: {balance['balance_formatted']}\n")
f.write("="*80 + "\n\n")
# 同时保存JSON格式
json_file = RESULTS_FILE.replace('.txt', '.json')
try:
if os.path.exists(json_file):
with open(json_file, 'r', encoding='utf-8') as f:
data = json.load(f)
else:
data = []
data.append(info)
with open(json_file, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
except:
pass
def worker_thread(wallet_tool, thread_id):
"""工作线程:生成助记词并检查余额"""
global stats
# 每个线程独立计数,减少锁竞争
local_count = 0
thread_start_time = time.time()
while True:
try:
# 生成助记词
mnemonic = wallet_tool.generate_mnemonic()
# 生成地址
address = wallet_tool.mnemonic_to_address(mnemonic)
if not address:
local_count += 1
# 立即更新统计(不等待)
if local_count >= 1: # 每次都更新,确保统计正常
with stats['lock']:
stats['total_checked'] += local_count
local_count = 0
continue
# 先更新统计(在查询余额之前)
local_count += 1
if local_count >= 1: # 每次都更新
with stats['lock']:
stats['total_checked'] += local_count
total = stats['total_checked']
found = stats['found_balance']
if total % 20 == 0: # 每20次打印一次
elapsed = time.time() - stats['start_time']
speed = total / elapsed if elapsed > 0 else 0
logger.info(f"已检查: {total} | 发现: {found} | 速度: {speed:.1f} 个/秒")
local_count = 0
# 快速检查余额(只检查主要链,设置超时)
try:
balance_info = wallet_tool.quick_check_balance(address)
except:
balance_info = None
# 如果发现余额
if balance_info:
# 生成私钥
account = Account.from_mnemonic(mnemonic, account_path="m/44'/60'/0'/0/0")
private_key = account.key.hex()
# 检查所有链的余额
all_balances = wallet_tool.check_all_chains(address)
# 保存结果
save_found_wallet(mnemonic, address, private_key, all_balances)
# 更新统计并打印
with stats['lock']:
stats['found_balance'] += 1
logger.success(f"🎉 发现余额钱包!")
logger.success(f"地址: {address}")
logger.success(f"助记词: {mnemonic}")
for bal in all_balances:
logger.success(f" {bal['chain'].upper()}: {bal['balance_formatted']}")
except Exception as e:
# 即使出错也更新统计
local_count += 1
if local_count >= 1:
with stats['lock']:
stats['total_checked'] += local_count
local_count = 0
continue
def main():
"""主函数"""
print("="*80)
print("EVM助记词碰撞工具 - 高速版本")
print("="*80)
print(f"结果将保存到: {RESULTS_FILE}")
print(f"查询的链: ethereum, bsc, polygon, arbitrum, base")
print("="*80)
print()
# 选择要查询的链(可以修改这里)
chains = ["ethereum", "bsc", "polygon", "arbitrum", "base"]
# 创建钱包工具
wallet_tool = FastEVMWallet(chains=chains)
# 设置线程数根据CPU核心数调整
num_threads = os.cpu_count() or 4
print(f"启动 {num_threads} 个工作线程...")
print("按 Ctrl+C 停止程序\n")
# 创建线程
threads = []
for i in range(num_threads):
t = threading.Thread(target=worker_thread, args=(wallet_tool, i), daemon=True)
t.start()
threads.append(t)
# 等待一小段时间确保线程启动
time.sleep(1)
# 检查是否有线程在运行
active_threads = sum(1 for t in threads if t.is_alive())
if active_threads == 0:
logger.error("所有工作线程都停止了请检查RPC连接")
return
else:
logger.info(f"{active_threads} 个工作线程正在运行")
# 测试:生成一个测试地址并查询,验证功能是否正常
logger.info("正在测试功能...")
test_mnemonic = wallet_tool.generate_mnemonic()
test_address = wallet_tool.mnemonic_to_address(test_mnemonic)
if test_address:
logger.info(f"测试地址生成成功: {test_address[:10]}...")
test_balance = wallet_tool.quick_check_balance(test_address)
if test_balance is None:
logger.info("测试余额查询成功(无余额,正常)")
else:
logger.warning(f"测试发现余额!这不太可能,请检查")
else:
logger.error("测试地址生成失败!")
try:
# 主线程等待
last_count = 0
while True:
time.sleep(2) # 每2秒更新一次显示
# 定期打印统计信息
elapsed = time.time() - stats['start_time']
current_count = stats['total_checked']
# 如果计数没有变化,可能是线程有问题
if elapsed > 10 and current_count == last_count and current_count == 0:
logger.warning("警告工作线程可能没有正常工作请检查RPC连接")
if elapsed > 0:
speed = current_count / elapsed if current_count > 0 else 0
print(f"\r运行时间: {int(elapsed)}秒 | 已检查: {current_count} | 发现: {stats['found_balance']} | 速度: {speed:.1f} 个/秒", end='', flush=True)
last_count = current_count
except KeyboardInterrupt:
print("\n\n正在停止...")
print(f"\n最终统计:")
print(f" 总检查数: {stats['total_checked']}")
print(f" 发现余额: {stats['found_balance']}")
print(f" 结果已保存到: {RESULTS_FILE}")
if __name__ == "__main__":
main()

Binary file not shown.

View File

@@ -1,483 +0,0 @@
"""
量化交易回测系统 - 30分钟K线策略回测Weex数据源
========== 策略规则 ==========
重要所有开仓和平仓操作都在下一根K线的开盘价执行
【策略流程】
1. 开仓条件信号出现时下一根K线开盘价开仓
- 阳包阴(涨包跌)信号 -> 开多
* 前一根是跌(阴线),后一根是涨(阳线)
* 且:涨的收盘价 > 跌的开盘价
- 阴包阳(跌包涨)信号 -> 开空
* 前一根是涨(阳线),后一根是跌(阴线)
* 且:跌的收盘价 < 涨的开盘价
2. 平仓条件所有平仓都在下一根K线开盘价执行
- 持有多单时:遇到两根连续的阴线 -> 下一根K线开盘价平仓
- 持有空单时:遇到两根连续的阳线 -> 下一根K线开盘价平仓
- 遇到反向信号下一根K线开盘价平仓并反手开仓
* 例如:持有多单时遇到阴包阳信号 -> 平多开空
3. 续持条件:
- 遇到同向信号:续持
- 未满足平仓条件:续持
【数据处理流程】
1. 从数据库读取数据
2. 数据排序(按时间戳升序)
3. 开始回测
"""
import datetime
import calendar
from dataclasses import dataclass
from typing import List, Dict, Optional
from loguru import logger
from models.mexc import Mexc30
# ========================= 工具函数 =========================
# 交易对的最小价格单位tick size配置
# 格式:交易对符号 -> 最小单位
TICK_SIZE_MAP = {
'SOLUSDT': 0.01,
'BTCUSDT': 0.1,
'ETHUSDT': 0.01,
'BNBUSDT': 0.01,
# 可以根据需要添加更多交易对
}
# 默认最小单位(如果交易对不在配置中)
DEFAULT_TICK_SIZE = 0.01
def get_tick_size(symbol: str) -> float:
"""
获取交易对的最小价格单位
:param symbol: 交易对符号,如 'SOLUSDT'
:return: 最小单位,如 0.01
"""
return TICK_SIZE_MAP.get(symbol.upper(), DEFAULT_TICK_SIZE)
def adjust_price_for_trade(price: float, direction: str, symbol: str = 'SOLUSDT') -> float:
"""
根据交易方向调整价格,考虑买卖价差
买入(开多/平空):价格 + tick_size
卖出(开空/平多):价格 - tick_size
:param price: 原始价格K线开盘价或收盘价
:param direction: 交易方向,'long' 表示买入,'short' 表示卖出
:param symbol: 交易对符号,用于获取最小单位
:return: 调整后的价格
"""
tick_size = get_tick_size(symbol)
if direction == 'long':
# 买入:价格 + tick_size
adjusted = price + tick_size
elif direction == 'short':
# 卖出:价格 - tick_size
adjusted = price - tick_size
else:
# 未知方向,返回原价
adjusted = price
# 确保价格不会为负
return max(adjusted, tick_size)
def is_bullish(c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(c): # 阴线
return float(c['close']) < float(c['open'])
def check_signal(prev, curr):
"""
包住形态信号判定(优化版):
只看两种信号,严格按照收盘价与开盘价的比较:
1. 阳包阴(涨包跌,前跌后涨)-> 做多:
- 前一根是跌阴线close < open
- 后一根是涨阳线close > open
- 且:涨的收盘价 > 跌的开盘价curr['close'] > prev['open']
2. 阴包阳(跌包涨,前涨后跌)-> 做空:
- 前一根是涨阳线close > open
- 后一根是跌阴线close < open
- 且:跌的收盘价 < 涨的开盘价curr['close'] < prev['open']
"""
p_open = float(prev['open'])
c_close = float(curr['close'])
# 阳包阴(涨包跌,前跌后涨) -> 做多:涨的收盘价 > 跌的开盘价
if is_bearish(prev) and is_bullish(curr) and c_close > p_open:
return "long", "bear_bull_engulf"
# 阴包阳(跌包涨,前涨后跌) -> 做空:跌的收盘价 < 涨的开盘价
if is_bullish(prev) and is_bearish(curr) and c_close < p_open:
return "short", "bull_bear_engulf"
return None, None
def get_data_by_date(model, date_str: str):
"""
按天获取指定表的数据30分钟K线
数据格式:时间戳(毫秒级) 开盘价 最高价 最低价 收盘价
例如1767461400000 3106.68 3109.1 3106.22 3107.22
注意返回的数据已按时间戳id升序排序
"""
try:
target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
except ValueError:
logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。")
return []
# 将日期转换为毫秒级时间戳进行查询
start_ts = int(target_date.timestamp() * 1000)
end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1
# 查询时按时间戳升序排序
query = model.select().where(model.id.between(start_ts, end_ts)).order_by(model.id.asc())
data = [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query]
# 确保数据已排序
if data:
data.sort(key=lambda x: x['id'])
return data
# ========================= 回测逻辑 =========================
def backtest_15m_trend_optimized(dates: List[str], symbol: str = 'SOLUSDT'):
"""
回测策略逻辑:
1. 开仓条件信号出现时下一根K线开盘价开仓
- 阳包阴(涨包跌)信号 -> 开多
- 阴包阳(跌包涨)信号 -> 开空
2. 平仓条件所有平仓都在下一根K线开盘价执行
- 持有多单时:遇到两根连续的阴线 -> 下一根K线开盘价平仓
- 持有空单时:遇到两根连续的阳线 -> 下一根K线开盘价平仓
- 遇到反向信号下一根K线开盘价平仓并反手开仓
(例如:持有多单时遇到阴包阳信号 -> 平多开空)
3. 续持条件:
- 遇到同向信号:续持
- 未满足平仓条件:续持
"""
# ==================== 步骤1从数据库读取数据 ====================
all_data: List[Dict] = []
total_queried = 0
for d in dates:
day_data = get_data_by_date(Mexc30, d)
all_data.extend(day_data)
if day_data:
total_queried += len(day_data)
logger.info(f"总共查询了 {len(dates)} 天,获取到 {total_queried} 条K线数据")
if not all_data:
logger.warning("未获取到任何数据,请检查数据库连接和日期范围")
return [], {
'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'},
'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'},
}
# ==================== 步骤2数据去重 + 排序(重要!必须先处理再回测) ====================
# 以时间戳(id)为唯一键去重,保留最先出现的一条
unique_by_id: Dict[int, Dict] = {}
for item in all_data:
if item['id'] not in unique_by_id:
unique_by_id[item['id']] = item
all_data = list(unique_by_id.values())
all_data.sort(key=lambda x: x['id'])
# 验证排序结果
if len(all_data) > 1:
first_ts = all_data[0]['id']
last_ts = all_data[-1]['id']
first_time = datetime.datetime.fromtimestamp(first_ts / 1000)
last_time = datetime.datetime.fromtimestamp(last_ts / 1000)
logger.info(f"数据已按时间排序:{first_time.strftime('%Y-%m-%d %H:%M:%S')}{last_time.strftime('%Y-%m-%d %H:%M:%S')}")
# ==================== 步骤3开始回测 ====================
stats = {
'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'},
'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'},
}
trades: List[Dict] = []
current_position: Optional[Dict] = None # 开仓信息
consecutive_opposite_count = 0 # 连续反色K线计数
idx = 1
while idx < len(all_data) - 1:
prev, curr, next_bar = all_data[idx - 1], all_data[idx], all_data[idx + 1]
direction, signal_key = check_signal(prev, curr)
# ==================== 空仓状态:遇到信号则开仓 ====================
# 策略:阳包阴信号 -> 开多,阴包阳信号 -> 开空
if current_position is None:
if direction:
# 信号出现prev和curr形成信号在下一根K线next_bar的开盘价开仓
# 应用买卖价差:买入(开多)时价格+0.01,卖出(开空)时价格-0.01
raw_price = float(next_bar['open'])
entry_price = adjust_price_for_trade(raw_price, direction, symbol)
current_position = {
'direction': direction,
'signal': stats[signal_key]['name'],
'signal_key': signal_key,
'entry_price': entry_price,
'entry_time': next_bar['id']
}
consecutive_opposite_count = 0 # 重置连续反色计数
stats[signal_key]['count'] += 1
logger.debug(f"开仓: {stats[signal_key]['name']} {'做多' if direction == 'long' else '做空'} @ {entry_price:.2f} (原始价格: {raw_price:.2f})")
idx += 1
continue
# ==================== 有仓位状态:检查平仓条件 ====================
pos_dir = current_position['direction']
pos_sig_key = current_position['signal_key']
# 1. 反向信号 -> 下一根K线开盘价平仓并反手开仓
# 策略:遇到反向信号(如持有多单时遇到阴包阳),平仓并反手开仓
if direction and direction != pos_dir:
# 平仓:持有多单时卖出(价格-0.01),持有空单时买入(价格+0.01
raw_exit_price = float(next_bar['open'])
exit_direction = 'short' if pos_dir == 'long' else 'long' # 平仓方向与持仓方向相反
exit_price = adjust_price_for_trade(raw_exit_price, exit_direction, symbol)
diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else (
current_position['entry_price'] - exit_price)
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000),
'signal': current_position['signal'],
'direction': '做多' if pos_dir == 'long' else '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[pos_sig_key]['total_profit'] += diff
if diff > 0: stats[pos_sig_key]['wins'] += 1
# 反手开仓下一根K线开盘价应用买卖价差
raw_entry_price = float(next_bar['open'])
entry_price = adjust_price_for_trade(raw_entry_price, direction, symbol)
current_position = {
'direction': direction,
'signal': stats[signal_key]['name'],
'signal_key': signal_key,
'entry_price': entry_price,
'entry_time': next_bar['id']
}
consecutive_opposite_count = 0 # 重置连续反色计数
stats[signal_key]['count'] += 1
logger.debug(f"反向信号反手: 平{'做多' if pos_dir == 'long' else '做空'} @ {exit_price:.2f} (原始: {raw_exit_price:.2f}), 开{'做多' if direction == 'long' else '做空'} @ {entry_price:.2f} (原始: {raw_entry_price:.2f})")
idx += 1
continue
# 2. 检查连续反色K线平仓条件下一根K线开盘价平仓
# 策略:持有多单时,遇到两根连续的阴线 -> 平仓
# 持有空单时,遇到两根连续的阳线 -> 平仓
if pos_dir == 'long' and is_bearish(curr):
consecutive_opposite_count += 1
# 如果已经连续两根阴线下一根K线开盘价平仓
if consecutive_opposite_count >= 2:
logger.debug(f"平仓: 做多遇到连续两根阴线")
# 平多单:卖出,价格 - 0.01
raw_exit_price = float(next_bar['open'])
exit_price = adjust_price_for_trade(raw_exit_price, 'short', symbol)
diff = exit_price - current_position['entry_price']
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000),
'signal': current_position['signal'],
'direction': '做多',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[pos_sig_key]['total_profit'] += diff
if diff > 0: stats[pos_sig_key]['wins'] += 1
current_position = None
consecutive_opposite_count = 0
idx += 1
continue
else:
# 只有一根阴线,续持
idx += 1
continue
# 持有空单:检查是否连续两根阳线
elif pos_dir == 'short' and is_bullish(curr):
consecutive_opposite_count += 1
# 如果已经连续两根阳线下一根K线开盘价平仓
if consecutive_opposite_count >= 2:
logger.debug(f"平仓: 做空遇到连续两根阳线")
# 平空单:买入,价格 + 0.01
raw_exit_price = float(next_bar['open'])
exit_price = adjust_price_for_trade(raw_exit_price, 'long', symbol)
diff = current_position['entry_price'] - exit_price
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000),
'signal': current_position['signal'],
'direction': '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[pos_sig_key]['total_profit'] += diff
if diff > 0: stats[pos_sig_key]['wins'] += 1
current_position = None
consecutive_opposite_count = 0
idx += 1
continue
else:
# 只有一根阳线,续持
idx += 1
continue
# 3. 同向K线或同向信号 -> 续持,重置连续反色计数
if (pos_dir == 'long' and is_bullish(curr)) or (pos_dir == 'short' and is_bearish(curr)):
consecutive_opposite_count = 0 # 重置连续反色计数
# 同向信号 -> 续持
if direction and direction == pos_dir:
consecutive_opposite_count = 0 # 重置连续反色计数
idx += 1
continue
idx += 1
# 尾仓:最后一根收盘价平仓
if current_position:
last = all_data[-1]
pos_dir = current_position['direction']
# 平仓:持有多单时卖出(价格-0.01),持有空单时买入(价格+0.01
raw_exit_price = float(last['close'])
exit_direction = 'short' if pos_dir == 'long' else 'long' # 平仓方向与持仓方向相反
exit_price = adjust_price_for_trade(raw_exit_price, exit_direction, symbol)
diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else (
current_position['entry_price'] - exit_price)
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(last['id'] / 1000),
'signal': current_position['signal'],
'direction': '做多' if pos_dir == 'long' else '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[current_position['signal_key']]['total_profit'] += diff
if diff > 0: stats[current_position['signal_key']]['wins'] += 1
return trades, stats
# ========================= 运行示例(优化版盈利计算) =========================
if __name__ == '__main__':
dates = []
# 获取当前日期
today = datetime.datetime.now()
target_year = 2025
for month in range(1, 13):
# 获取该月的实际天数
days_in_month = calendar.monthrange(target_year, month)[1]
for day in range(1, days_in_month + 1):
# 只添加今天及之前的日期
date_str = f"{target_year}-{month:02d}-{day:02d}"
date_obj = datetime.datetime.strptime(date_str, '%Y-%m-%d')
# 如果日期在今天之后,跳过
if date_obj > today:
break
dates.append(date_str)
print(dates)
# dates = [f"2025-09-{i}" for i in range(1, 32)]
# 指定交易对符号,用于获取正确的最小价格单位
symbol = 'SOLUSDT'
trades, stats = backtest_15m_trend_optimized(dates, symbol=symbol)
logger.info("===== 每笔交易详情 =====")
# === 参数设定 ===
contract_size = 10000 # 合约规模1手对应多少基础货币
open_fee_fixed = 5 # 固定开仓手续费
close_fee_rate = 0.0005 # 按成交额比例的平仓手续费率
total_points_profit = 0 # 累计点差
total_money_profit = 0 # 累计金额盈利
total_fee = 0 # 累计手续费
for t in trades:
entry = t['entry']
exit = t['exit']
direction = t['direction']
# === 1⃣ 原始价差(点差) ===
point_diff = (exit - entry) if direction == '做多' else (entry - exit)
# === 2⃣ 金额盈利(考虑合约规模) ===
money_profit = point_diff / entry * contract_size # 利润以基础货币计例如USD
# === 3⃣ 手续费计算 ===
# 开仓 + 平仓手续费(按比例计算 + 固定)
fee = open_fee_fixed + (contract_size / entry * exit * close_fee_rate)
# === 4⃣ 净利润 ===
net_profit = money_profit - fee
# 保存计算结果
t.update({
'point_diff': point_diff,
'raw_profit': money_profit,
'fee': fee,
'net_profit': net_profit
})
total_points_profit += point_diff
total_money_profit += money_profit
total_fee += fee
# if net_profit < -400:
logger.info(
f"{t['entry_time']} {direction}({t['signal']}) "
f"入={entry:.2f} 出={exit:.2f} 差价={point_diff:.2f} "
f"原始盈利={money_profit:.2f} 手续费={fee:.2f} 净利润={net_profit:.2f} {t['exit_time']}"
)
# === 汇总统计 ===
total_net_profit = total_money_profit - total_fee
print(f"\n一共交易笔数:{len(trades)}")
print(f"总点差:{total_points_profit:.2f}")
print(f"总原始盈利(未扣费):{total_money_profit:.2f}")
print(f"总手续费:{total_fee:.2f}")
print(f"总净利润:{total_net_profit:.2f}\n")
print(total_money_profit - total_fee * 0.1)
print("===== 信号统计 =====")
for k, v in stats.items():
name, count, wins, total_p = v['name'], v['count'], v['wins'], v['total_profit']
win_rate = (wins / count * 100) if count > 0 else 0.0
avg_p = (total_p / count) if count > 0 else 0.0
print(f"{name}: 次数={count} 胜率={win_rate:.2f}% 总价差={total_p:.2f} 平均价差={avg_p:.2f}")

View File

@@ -1,659 +0,0 @@
import requests
import pandas as pd
import datetime
import time
from models.mexc import Mexc1, Mexc15, Mexc30, Mexc1Hour
def get_mexc_klines(symbol="SOLUSDT", interval="30m", limit=500):
url = "https://api.mexc.com/api/v3/klines"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
params = {
"symbol": symbol.upper(),
"interval": interval,
"limit": limit
}
try:
resp = requests.get(url, params=params, headers=headers, timeout=10)
resp.raise_for_status() # 提前抛出 HTTP 错误
data = resp.json()
if not isinstance(data, list) or not data:
print("返回数据异常:", data)
return None
# 使用正确的 8 列
columns = [
"open_time", "open", "high", "low", "close",
"volume", "close_time", "quote_volume"
]
df = pd.DataFrame(data, columns=columns)
# 保存原始时间戳用于数据库id
df["open_time_ms"] = df["open_time"].astype(int)
# 时间戳转可读时间
df["open_time"] = pd.to_datetime(df["open_time"], unit="ms")
df["close_time"] = pd.to_datetime(df["close_time"], unit="ms")
# 常用字段排序 + 类型转换
df = df[[
"open_time", "open", "high", "low", "close",
"volume", "quote_volume", "open_time_ms"
]]
# 转成浮点数(方便后续计算)
for col in ["open", "high", "low", "close", "volume", "quote_volume"]:
df[col] = pd.to_numeric(df[col], errors="coerce")
print(f"成功获取 {len(df)}{interval} K线{symbol}")
return df
except Exception as e:
print("请求失败:", str(e))
return None
def normalize_futures_symbol(symbol):
"""将现货格式转换为合约格式,如 SOLUSDT -> SOL_USDT"""
if "_" in symbol:
return symbol.upper()
symbol = symbol.upper()
for quote in ["USDT", "USDC", "USD", "BTC", "ETH"]:
if symbol.endswith(quote):
base = symbol[:-len(quote)]
return f"{base}_{quote}"
return symbol
def map_futures_interval(interval):
"""合约K线周期映射"""
mapping = {
"1m": "Min1",
"5m": "Min5",
"15m": "Min15",
"30m": "Min30",
"1h": "Min60",
"4h": "Hour4",
"8h": "Hour8",
"1d": "Day1",
"1w": "Week1",
"1M": "Month1",
}
return mapping.get(interval, interval)
def get_mexc_klines_with_time(symbol="SOLUSDT", interval="30m", start_time_ms=None, end_time_ms=None, limit=1000):
"""
获取指定时间范围内的K线数据
:param symbol: 交易对符号
:param interval: 时间间隔,如 "30m", "1m", "15m", "1h"
:param start_time_ms: 开始时间(毫秒级时间戳)
:param end_time_ms: 结束时间(毫秒级时间戳)
:param limit: 单次获取数量最大1000
:return: DataFrame或None
"""
def _fetch(params):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
resp = requests.get(url, params=params, headers=headers, timeout=10)
resp.raise_for_status()
data = resp.json()
return resp, data
url = "https://api.mexc.com/api/v3/klines"
params = {
"symbol": symbol.upper(),
"interval": interval,
"limit": limit
}
if start_time_ms:
params["startTime"] = start_time_ms
if end_time_ms:
params["endTime"] = end_time_ms
try:
resp, data = _fetch(params)
# 检查是否是错误响应
if isinstance(data, dict) and 'code' in data:
print(f"API返回错误: {data}, 请求参数: {params}")
return None
# 尝试秒级时间戳回退(部分接口可能只接受秒)
if (not isinstance(data, list) or not data) and (start_time_ms or end_time_ms):
params_s = params.copy()
if start_time_ms:
params_s["startTime"] = int(start_time_ms // 1000)
if end_time_ms:
params_s["endTime"] = int(end_time_ms // 1000)
resp_s, data_s = _fetch(params_s)
if isinstance(data_s, list) and data_s:
print("检测到秒级时间戳可用,已自动回退到秒级参数")
resp, data = resp_s, data_s
params = params_s
if not isinstance(data, list) or not data:
print(f"API返回数据异常: {data}, 请求参数: {params}")
print(f"完整URL: {resp.url}")
return None
columns = [
"open_time", "open", "high", "low", "close",
"volume", "close_time", "quote_volume"
]
df = pd.DataFrame(data, columns=columns)
# 判断时间单位(秒/毫秒)
max_open = pd.to_numeric(df["open_time"], errors="coerce").max()
if max_open < 1_000_000_000_000: # 小于1e12视为秒
df["open_time_ms"] = (df["open_time"].astype(int) * 1000)
df["open_time"] = pd.to_datetime(df["open_time"], unit="s")
df["close_time"] = pd.to_datetime(df["close_time"], unit="s")
else:
df["open_time_ms"] = df["open_time"].astype(int)
df["open_time"] = pd.to_datetime(df["open_time"], unit="ms")
df["close_time"] = pd.to_datetime(df["close_time"], unit="ms")
df = df[[
"open_time", "open", "high", "low", "close",
"volume", "quote_volume", "open_time_ms"
]]
for col in ["open", "high", "low", "close", "volume", "quote_volume"]:
df[col] = pd.to_numeric(df[col], errors="coerce")
return df
except Exception as e:
print(f"请求失败: {str(e)}")
return None
def get_mexc_futures_klines(symbol="SOLUSDT", interval="30m", limit=500):
return get_mexc_futures_klines_with_time(
symbol=symbol,
interval=interval,
start_time_ms=None,
end_time_ms=None,
limit=limit
)
def get_mexc_futures_klines_with_time(symbol="SOLUSDT", interval="30m", start_time_ms=None, end_time_ms=None, limit=1000):
"""
获取合约K线数据使用 contract.mexc.com
"""
url = "https://contract.mexc.com/api/v1/contract/kline"
symbol = normalize_futures_symbol(symbol)
interval = map_futures_interval(interval)
def _fetch(params):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
"Accept": "application/json, text/plain, */*",
"Content-Type": "application/json"
}
resp = requests.get(url, params=params, headers=headers, timeout=10)
resp.raise_for_status()
return resp, resp.json()
params = {
"symbol": symbol,
"interval": interval,
"limit": limit
}
# 合约接口通常使用 start/end秒级这里默认秒级
if start_time_ms:
params["start"] = int(start_time_ms // 1000)
if end_time_ms:
params["end"] = int(end_time_ms // 1000)
try:
resp, data = _fetch(params)
# 兼容错误结构
if isinstance(data, dict) and ("success" in data and data.get("success") is False):
print(f"合约API返回错误: {data}, 请求参数: {params}")
return None
payload = data
if isinstance(data, dict) and "data" in data:
payload = data["data"]
# 兼容返回为 dict of arrays
if isinstance(payload, dict) and "time" in payload:
times = payload.get("time", [])
opens = payload.get("open", [])
highs = payload.get("high", [])
lows = payload.get("low", [])
closes = payload.get("close", [])
vols = payload.get("vol", [])
rows = list(zip(times, opens, highs, lows, closes, vols))
payload = rows
if not isinstance(payload, list) or not payload:
print(f"合约API返回数据异常: {payload}, 请求参数: {params}")
print(f"完整URL: {resp.url}")
return None
# 兼容 list of lists: [time, open, high, low, close, vol, ...]
columns = ["open_time", "open", "high", "low", "close", "volume"]
df = pd.DataFrame(payload, columns=columns + list(range(len(payload[0]) - len(columns))))
df = df[columns]
# 判断时间单位(秒/毫秒)
max_open = pd.to_numeric(df["open_time"], errors="coerce").max()
if max_open < 1_000_000_000_000:
df["open_time_ms"] = (df["open_time"].astype(int) * 1000)
df["open_time"] = pd.to_datetime(df["open_time"], unit="s")
else:
df["open_time_ms"] = df["open_time"].astype(int)
df["open_time"] = pd.to_datetime(df["open_time"], unit="ms")
for col in ["open", "high", "low", "close", "volume"]:
df[col] = pd.to_numeric(df[col], errors="coerce")
# 合约接口不一定返回 quote_volume这里保持一致字段结构
df["quote_volume"] = pd.NA
df = df[[
"open_time", "open", "high", "low", "close",
"volume", "quote_volume", "open_time_ms"
]]
return df
except Exception as e:
print(f"合约请求失败: {str(e)}")
return None
def get_interval_ms(interval):
"""
将时间间隔字符串转换为毫秒数
:param interval: 如 "1m", "15m", "30m", "1h"
:return: 毫秒数
"""
if interval.endswith("m"):
minutes = int(interval[:-1])
return minutes * 60 * 1000
elif interval.endswith("h"):
hours = int(interval[:-1])
return hours * 60 * 60 * 1000
elif interval.endswith("d"):
days = int(interval[:-1])
return days * 24 * 60 * 60 * 1000
else:
return 60 * 1000 # 默认1分钟
def fetch_historical_data(symbol="SOLUSDT", interval="30m", start_date="2024-01-01", end_date=None, auto_save=True, mode="auto", market="spot"):
"""
批量获取历史K线数据并存储到数据库
:param symbol: 交易对符号
:param interval: 时间间隔,如 "30m", "1m", "15m", "1h"
:param start_date: 开始日期,格式 "YYYY-MM-DD",默认 "2024-01-01"
:param end_date: 结束日期,格式 "YYYY-MM-DD",默认当前时间
:param auto_save: 是否自动保存到数据库默认True
:param mode: 获取模式,"auto" 自动判断,"forward" 正向,"reverse" 反向
:return: 总共获取的数据条数
"""
# 转换日期为时间戳(毫秒)
start_dt = datetime.datetime.strptime(start_date, "%Y-%m-%d")
start_dt = start_dt.replace(hour=0, minute=0, second=0, microsecond=0)
start_time_ms = int(start_dt.timestamp() * 1000)
if end_date:
end_dt = datetime.datetime.strptime(end_date, "%Y-%m-%d")
end_dt = end_dt.replace(hour=23, minute=59, second=59, microsecond=999999)
else:
end_dt = datetime.datetime.now()
end_time_ms = int(end_dt.timestamp() * 1000)
print(f"开始获取 {symbol} {interval} K线数据")
print(f"时间范围: {start_date}{end_dt.strftime('%Y-%m-%d %H:%M:%S')}")
current_start = start_time_ms
total_count = 0
limit = 1000 # API最大限制
interval_ms = get_interval_ms(interval)
# 计算每次请求的时间窗口1000条数据的时间跨度
window_ms = limit * interval_ms
if mode == "reverse":
return fetch_historical_data_reverse(
symbol=symbol,
interval=interval,
start_date=start_date,
end_date=end_date,
auto_save=auto_save,
market=market
)
fetch_fn = get_mexc_klines_with_time
latest_fn = get_mexc_klines
if market == "futures":
fetch_fn = get_mexc_futures_klines_with_time
latest_fn = get_mexc_futures_klines
if mode == "auto":
# 探测:如果 start+end 为空、start 单独返回最新数据,说明 startTime 被忽略,改用反向获取
probe_end = min(start_time_ms + window_ms, end_time_ms)
probe_df = fetch_fn(
symbol=symbol,
interval=interval,
start_time_ms=start_time_ms,
end_time_ms=probe_end,
limit=10
)
if probe_df is None or probe_df.empty:
probe_df2 = fetch_fn(
symbol=symbol,
interval=interval,
start_time_ms=start_time_ms,
end_time_ms=None,
limit=10
)
if probe_df2 is not None and not probe_df2.empty:
latest_ms = int(probe_df2.iloc[-1]["open_time_ms"])
if latest_ms > probe_end:
print("检测到 startTime 被忽略,自动改为反向获取模式")
return fetch_historical_data_reverse(
symbol=symbol,
interval=interval,
start_date=start_date,
end_date=end_date,
auto_save=auto_save,
market=market
)
while current_start < end_time_ms:
current_end = min(current_start + window_ms, end_time_ms)
print(f"正在获取: {datetime.datetime.fromtimestamp(current_start/1000)}{datetime.datetime.fromtimestamp(current_end/1000)}")
print(f"时间戳: {current_start}{current_end}")
df = fetch_fn(
symbol=symbol,
interval=interval,
start_time_ms=current_start,
end_time_ms=current_end,
limit=limit
)
if df is None or df.empty:
# 先测试一下不带时间参数的最新数据是否能获取到
if current_start == start_time_ms and total_count == 0:
print("\n=== 开始调试 ===")
print("测试1尝试获取最新数据不带时间参数...")
test_df = latest_fn(symbol=symbol, interval=interval, limit=10)
if test_df is not None and not test_df.empty:
print(f"✓ 测试1成功最新数据可以获取")
print(f" 最新时间: {test_df.iloc[-1]['open_time']}")
print(f" 最新时间戳: {test_df.iloc[-1]['open_time_ms']}")
# 测试2只带startTime不带endTime
print(f"\n测试2尝试只带startTime{start_date}开始)...")
test_df2 = fetch_fn(
symbol=symbol,
interval=interval,
start_time_ms=current_start,
end_time_ms=None,
limit=100
)
if test_df2 is not None and not test_df2.empty:
print(f"✓ 测试2成功从指定时间开始获取数据")
print(f" 获取到 {len(test_df2)} 条数据")
print(f" 第一条时间: {test_df2.iloc[0]['open_time']}")
print(f" 最后一条时间: {test_df2.iloc[-1]['open_time']}")
print("=== 调试结束 ===\n")
# 使用测试2的方法继续赋值给df
df = test_df2
# 不break继续下面的处理流程
else:
print("✗ 测试2失败带startTime无法获取数据")
print("\n建议MEXC API可能不支持从历史日期开始查询")
print("可以尝试1. 检查时间范围是否在API支持范围内")
print(" 2. 使用反向获取:从最新数据往前推")
print("=== 调试结束 ===\n")
break
else:
print("✗ 测试1失败即使不带时间参数也无法获取数据")
print("可能原因:交易对符号或时间间隔不正确")
print("=== 调试结束 ===\n")
break
# 如果测试后df仍然是None或空说明无法获取数据
if df is None or df.empty:
if total_count > 0:
print("已到达数据末尾")
else:
print("本次获取数据为空,跳过")
break
count = len(df)
total_count += count
print(f"本次获取 {count} 条数据,累计 {total_count}")
# 自动保存到数据库
if auto_save:
save_to_database(df, interval=interval, symbol=symbol)
# 更新下一次的起始时间(从最后一条数据的开盘时间 + 一个间隔)
last_open_ms = int(df.iloc[-1]['open_time_ms'])
current_start = last_open_ms + interval_ms
# 避免请求过快
time.sleep(0.2)
print(f"完成!总共获取 {total_count}{symbol} {interval} K线数据")
return total_count
def fetch_historical_data_reverse(symbol="SOLUSDT", interval="30m", start_date="2024-01-01", end_date=None, auto_save=True, market="spot"):
"""
反向获取历史K线数据从最新往前推使用startTime参数
"""
start_dt = datetime.datetime.strptime(start_date, "%Y-%m-%d")
start_dt = start_dt.replace(hour=0, minute=0, second=0, microsecond=0)
start_time_ms = int(start_dt.timestamp() * 1000)
if end_date:
end_dt = datetime.datetime.strptime(end_date, "%Y-%m-%d")
end_dt = end_dt.replace(hour=23, minute=59, second=59, microsecond=999999)
else:
end_dt = datetime.datetime.now()
end_time_ms = int(end_dt.timestamp() * 1000)
print(f"开始反向获取 {symbol} {interval} K线数据从最新往前推")
print(f"目标时间范围: {start_date}{end_dt.strftime('%Y-%m-%d %H:%M:%S')}")
total_count = 0
limit = 1000 # 每次尝试获取1000条
interval_ms = get_interval_ms(interval)
# 使用带时间参数的函数
fetch_fn = get_mexc_klines_with_time
if market == "futures":
fetch_fn = get_mexc_futures_klines_with_time
# 先获取最新数据,确定当前最新时间
print("\n第 1 批:获取最新数据...")
df_latest = get_mexc_klines(symbol=symbol, interval=interval, limit=100)
if df_latest is None or df_latest.empty:
print("无法获取最新数据,停止")
return 0
latest_time_ms = int(df_latest.iloc[-1]["open_time_ms"])
earliest_fetched_ms = int(df_latest.iloc[0]["open_time_ms"])
# 保存第一批数据
df_latest_filtered = df_latest[df_latest["open_time_ms"] >= start_time_ms]
if not df_latest_filtered.empty:
count = len(df_latest_filtered)
total_count += count
print(f"获取 {count} 条最新数据,时间范围: {datetime.datetime.fromtimestamp(earliest_fetched_ms/1000)}{datetime.datetime.fromtimestamp(latest_time_ms/1000)}")
if auto_save:
save_to_database(df_latest_filtered, interval=interval, symbol=symbol)
# 从已获取的最早时间往前推
current_start_ms = earliest_fetched_ms - interval_ms
batch_num = 1
while current_start_ms >= start_time_ms:
batch_num += 1
# 计算本次请求的时间窗口往前推limit条数据的时间跨度
window_ms = limit * interval_ms
batch_start_ms = max(current_start_ms - window_ms, start_time_ms)
print(f"\n{batch_num} 批:从 {datetime.datetime.fromtimestamp(batch_start_ms/1000)} 开始获取...")
# 使用startTime参数尝试获取更早的数据
df = fetch_fn(
symbol=symbol,
interval=interval,
start_time_ms=batch_start_ms,
end_time_ms=current_start_ms,
limit=limit
)
if df is None or df.empty:
# 如果返回空尝试只使用startTime不带endTime
print(" 带endTime返回空尝试只使用startTime...")
df = fetch_fn(
symbol=symbol,
interval=interval,
start_time_ms=batch_start_ms,
end_time_ms=None,
limit=limit
)
if df is None or df.empty:
print(f" 无法获取数据可能已到达API历史数据限制")
break
# 检查返回的数据是否真的从startTime开始判断startTime是否被忽略
returned_earliest = int(df.iloc[0]["open_time_ms"])
returned_latest = int(df.iloc[-1]["open_time_ms"])
# 如果返回的数据仍然是最新的说明startTime被忽略
if returned_latest >= latest_time_ms - 1000: # 允许1秒误差
print(f" 检测到startTime被忽略返回最新数据无法继续往前获取")
break
# 过滤掉已获取的数据和早于start_date的数据
df = df[df["open_time_ms"] < current_start_ms]
df = df[df["open_time_ms"] >= start_time_ms]
if df.empty:
print(f" 过滤后无新数据")
# 如果已经到达目标起始时间,完成
if batch_start_ms <= start_time_ms:
print(f"已到达目标起始时间({start_date}),完成")
break
# 否则继续往前推
current_start_ms = batch_start_ms - interval_ms
time.sleep(0.3)
continue
# 更新已获取的最早时间戳
current_earliest = int(df.iloc[0]["open_time_ms"])
if current_earliest < earliest_fetched_ms:
earliest_fetched_ms = current_earliest
count = len(df)
total_count += count
print(f" 获取 {count} 条新数据,最早时间: {datetime.datetime.fromtimestamp(current_earliest/1000)}")
print(f" 累计获取 {total_count} 条数据")
if auto_save:
save_to_database(df, interval=interval, symbol=symbol)
# 更新下一次的起始时间
current_start_ms = current_earliest - interval_ms
# 避免请求过快
time.sleep(0.3)
# 安全限制
if batch_num > 500:
print("批次过多,停止")
break
print(f"\n完成!总共获取 {total_count}{symbol} {interval} K线数据")
if earliest_fetched_ms:
print(f"最早数据时间: {datetime.datetime.fromtimestamp(earliest_fetched_ms/1000)}")
if earliest_fetched_ms > start_time_ms:
print(f"⚠️ 注意:最早数据时间 ({datetime.datetime.fromtimestamp(earliest_fetched_ms/1000)}) 晚于目标起始时间 ({start_date})")
print(f" 这可能是因为MEXC API的历史数据限制无法获取更早的数据")
return total_count
def save_to_database(df, interval="30m", symbol="SOLUSDT"):
"""
将K线数据存储到数据库
:param df: pandas DataFrame包含K线数据
:param interval: 时间间隔,如 "30m", "1m", "15m", "1h"
:param symbol: 交易对符号
"""
if df is None or df.empty:
print("数据为空,无法存储")
return
# 根据时间间隔选择对应的模型
interval_map = {
"1m": Mexc1,
"15m": Mexc15,
"30m": Mexc30,
"1h": Mexc1Hour,
}
model_class = interval_map.get(interval)
if model_class is None:
print(f"不支持的时间间隔: {interval}")
return
# 存储数据到数据库
saved_count = 0
for _, row in df.iterrows():
# 使用原始时间戳(毫秒级)作为 id
timestamp_ms = int(row['open_time_ms'])
model_class.get_or_create(
id=timestamp_ms,
defaults={
'open': float(row['open']),
'high': float(row['high']),
'low': float(row['low']),
'close': float(row['close']),
}
)
saved_count += 1
print(f"成功存储 {saved_count}{interval} K线数据{symbol})到数据库")
# 使用示例
if __name__ == "__main__":
# 方式1: 获取最新200条数据
# df = get_mexc_klines("SOLUSDT", "30m", 200)
# if df is not None:
# print(df.tail(8))
# save_to_database(df, interval="30m", symbol="SOLUSDT")
# 方式2: 批量获取2024年至今的历史数据使用现货接口反向获取
fetch_historical_data(
symbol="SOLUSDT",
interval="30m",
start_date="2024-01-01",
end_date=None, # None表示到当前时间
auto_save=True,
market="spot", # 使用现货接口
mode="reverse" # 强制使用反向获取模式(从最新往前推)
)

Binary file not shown.

View File

@@ -1 +0,0 @@
[]

View File

@@ -1,211 +0,0 @@
import datetime
import json
import time
import requests
from loguru import logger
# ================== 通用请求头 ==================
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh,zh-CN;q=0.9,zh-HK;q=0.8,en;q=0.7',
'cache-control': 'no-cache',
'origin': 'https://www.okx.com',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://www.okx.com/',
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36',
}
# ================== 获取 OKX K线数据 ==================
def fetch_kline_okx(day: int, year: int = 2025, month: int = 9, period='15m', symbol="ETH-USDT"):
"""
从 OKX 获取指定日期的K线数据
:param day: 日期
:param year: 年份
:param month: 月份
:param period: K线周期 (如 '1m', '5m', '15m', '1H')
:param symbol: 交易对
"""
time_ser = datetime.datetime(year, month, day)
start_of_day = int(time_ser.replace(hour=0, minute=0, second=0, microsecond=0).timestamp() * 1000)
end_of_day = int(time_ser.replace(hour=23, minute=59, second=59, microsecond=0).timestamp() * 1000)
url = "https://www.okx.com/api/v5/market/candles"
params = {
"instId": symbol,
"bar": period,
"limit": "1000"
}
all_data = []
next_start = end_of_day
while True:
params["after"] = next_start
resp = requests.get(url, params=params, headers=headers)
data = resp.json().get("data", [])
if not data:
break
for d in data:
candle = {
"id": int(int(d[0]) / 1000), # 秒级时间戳
"open": d[1],
"high": d[2],
"low": d[3],
"close": d[4],
"volume": d[5]
}
all_data.append(candle)
next_start = int(data[-1][0])
if len(data) < 1000:
break
# OKX返回数据按时间倒序排列
return sorted(all_data, key=lambda x: x['id'])
# ================== 辅助函数 ==================
def is_bullish(candle):
"""判断是否是阳线(涨)"""
return float(candle['open']) < float(candle['close'])
def is_bearish(candle):
"""判断是否是阴线(跌)"""
return float(candle['open']) > float(candle['close'])
def check_signal(prev, curr):
"""
判断包住形态信号:
1. 前跌后涨包住 -> 做多信号 (bear_bull_engulf)
2. 前涨后跌包住 -> 做空信号 (bull_bear_engulf)
"""
p_open, p_close = float(prev['open']), float(prev['close'])
c_open, c_close = float(curr['open']), float(curr['close'])
# 前跌后涨包住 -> 做多
if is_bullish(curr) and is_bearish(prev):
if c_open < p_close and c_close > p_open:
return "long", "bear_bull_engulf"
# 前涨后跌包住 -> 做空
if is_bearish(curr) and is_bullish(prev):
if c_open > p_close and c_close < p_open:
return "short", "bull_bear_engulf"
return None, None
def simulate_trade(direction, entry_price, future_candles, take_profit_diff=30, stop_loss_diff=-10):
"""
模拟逐根K线的止盈止损
"""
for candle in future_candles:
high, low, close = float(candle['high']), float(candle['low']), float(candle['close'])
if direction == "long":
if high >= entry_price + take_profit_diff:
return entry_price + take_profit_diff, take_profit_diff, candle['id'] # 止盈
if low <= entry_price + stop_loss_diff:
return entry_price + stop_loss_diff, stop_loss_diff, candle['id'] # 止损
elif direction == "short":
if low <= entry_price - take_profit_diff:
return entry_price - take_profit_diff, take_profit_diff, candle['id']
if high >= entry_price - stop_loss_diff:
return entry_price - stop_loss_diff, stop_loss_diff, candle['id']
final_price = float(future_candles[-1]['close'])
diff_money = (final_price - entry_price) if direction == "long" else (entry_price - final_price)
return final_price, diff_money, future_candles[-1]['id']
# ================== 主程序 ==================
if __name__ == '__main__':
all_trades = []
signal_stats = {
"bear_bull_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "涨包跌"},
"bull_bear_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "跌包涨"}
}
datas = []
for i in range(1, 31):
logger.info(f"Fetching 2025-09-{i}")
sorted_data = fetch_kline_okx(year=2025, month=1, day=i, period='15m', symbol="ETH-USDT")
datas.extend(sorted_data)
time.sleep(0.3)
# # 可选:保存数据方便离线分析
# with open("okx_eth_15m_sep2025.json", "w", encoding="utf-8") as f:
# json.dump(datas, f, ensure_ascii=False, indent=2)
datas = sorted(datas, key=lambda x: x["id"])
daily_signals = daily_wins = daily_profit = 0
for idx in range(1, len(datas) - 2):
prev, curr = datas[idx - 1], datas[idx]
entry_candle = datas[idx + 1]
future_candles = datas[idx + 2:]
entry_open = float(entry_candle['open'])
direction, signal_type = check_signal(prev, curr)
if direction and signal_type:
daily_signals += 1
exit_price, diff, exit_time = simulate_trade(direction, entry_open, future_candles,
take_profit_diff=30, stop_loss_diff=-2)
signal_stats[signal_type]["count"] += 1
signal_stats[signal_type]["total_profit"] += diff
if diff > 0:
signal_stats[signal_type]["wins"] += 1
daily_wins += 1
daily_profit += diff
local_time = datetime.datetime.fromtimestamp(entry_candle['id'])
formatted_time = local_time.strftime("%Y-%m-%d %H:%M")
all_trades.append((
formatted_time,
"做多" if direction == "long" else "做空",
signal_stats[signal_type]["name"],
entry_open,
exit_price,
diff,
exit_time
))
# ================= 输出交易详情 =================
logger.info("===== 每笔交易详情 =====")
n = n1 = 0
for date, direction, signal_name, entry, exit, diff, end_time in all_trades:
profit_amount = diff / entry * 10000
close_fee = 10000 / entry * exit * 0.0005
logger.info(
f"{date} {direction}({signal_name}) 入场={entry:.2f} 出场={exit:.2f} 出场时间={end_time} "
f"差价={diff:.2f} 盈利={profit_amount:.2f} "
f"开仓手续费=5u 平仓手续费={close_fee:.2f}"
)
n1 += 5 + close_fee
n += profit_amount
print("=" * 60)
print(f"交易总数:{len(all_trades)}")
print(f"总盈利:{n:.2f} u")
print(f"总手续费:{n1:.2f} u")
print(f"净利润:{n - n1:.2f} u")
print("=" * 60)

View File

@@ -1,25 +0,0 @@
# 基于开盘价的五分之一策略
策略规则1111
- **做多触发价** = 当前K线开盘价 + 前一根实体/5
- **做空触发价** = 当前K线开盘价 - 前一根实体/5
- **前一根有效K线**:实体 ≥ 0.1
## 执行逻辑
- 当前K线最高价 ≥ 做多触发价 → 做多信号
- 当前K线最低价 ≤ 做空触发价 → 做空信号
- 同根K线多空都触及时用1分钟K线判断先后
- 触及信号则开仓或反手同根3分钟K线只交易一次
## 运行
```bash
cd /path/to/lm_code
python open_fifth_strategy/main.py
```
## 配置
`config.py` 中修改 API、合约、杠杆等参数。

View File

@@ -1,2 +0,0 @@
# -*- coding: utf-8 -*-
"""基于开盘价的五分之一策略"""

View File

@@ -1,26 +0,0 @@
# -*- coding: utf-8 -*-
"""
基于开盘价的五分之一策略 - 配置文件
策略规则1111
- 做多触发价 = 当前K线开盘价 + 前一根实体/5
- 做空触发价 = 当前K线开盘价 - 前一根实体/5
- 前一根有效K线实体 >= 0.1
"""
# BitMart API请勿提交敏感信息到版本库
API_KEY = "a0fb7b98464fd9bcce67e7c519d58ec10d0c38a8"
SECRET_KEY = "4eaeba78e77aeaab1c2027f846a276d164f264a44c2c1bb1c5f3be50c8de1ca5"
MEMO = "合约交易"
# 交易参数
CONTRACT_SYMBOL = "ETHUSDT"
KLINE_STEP = 3 # 3分钟K线
MIN_BODY_SIZE = 0.1 # 有效K线最小实体
CHECK_INTERVAL = 3 # 检测间隔(秒)
LEVERAGE = "100"
OPEN_TYPE = "cross" # 全仓
RISK_PERCENT = 0.01 # 每次开仓占用可用余额的比例
# 比特浏览器ID用于网页下单
BIT_ID = "f2320f57e24c45529a009e1541e25961"

View File

@@ -1,536 +0,0 @@
# -*- coding: utf-8 -*-
"""
BitMart 基于开盘价的五分之一策略交易
策略规则1111
- 做多触发价 = 当前K线开盘价 + 实体/5
- 做空触发价 = 当前K线开盘价 - 实体/5
- 基于前一根有效K线实体 >= 0.1
执行:触及做多/做空触发价则开仓或反手同根K线只交易一次
运行python open_fifth_strategy/main.py在项目根目录 lm_code 下)
"""
import sys
from pathlib import Path
_root = Path(__file__).resolve().parent.parent
if str(_root) not in sys.path:
sys.path.insert(0, str(_root))
import random
import time
from concurrent.futures import ThreadPoolExecutor
from loguru import logger
from bit_tools import openBrowser
from DrissionPage import ChromiumPage
from DrissionPage import ChromiumOptions
from bitmart.api_contract import APIContract
from 交易.tools import send_dingtalk_message
from open_fifth_strategy.config import (
API_KEY,
SECRET_KEY,
MEMO,
CONTRACT_SYMBOL,
KLINE_STEP,
MIN_BODY_SIZE,
CHECK_INTERVAL,
LEVERAGE,
OPEN_TYPE,
RISK_PERCENT,
BIT_ID,
)
ding_executor = ThreadPoolExecutor(max_workers=2, thread_name_prefix="dingtalk")
class OpenBasedFifthStrategy:
"""基于开盘价的五分之一策略"""
def __init__(self, bit_id=None):
self.page = None
self.api_key = API_KEY
self.secret_key = SECRET_KEY
self.memo = MEMO
self.contract_symbol = CONTRACT_SYMBOL
self.contractAPI = APIContract(
self.api_key, self.secret_key, self.memo, timeout=(5, 15)
)
self.start = 0 # 持仓: -1空, 0无, 1多
self.open_avg_price = None
self.current_amount = None
self.position_cross = None
self.bit_id = bit_id or BIT_ID
self.min_body_size = MIN_BODY_SIZE
self.kline_step = KLINE_STEP
self.check_interval = CHECK_INTERVAL
self.leverage = LEVERAGE
self.open_type = OPEN_TYPE
self.risk_percent = RISK_PERCENT
self.last_trigger_kline_id = None
self.last_trigger_direction = None
self.last_trade_kline_id = None
# ==================== 策略核心 ====================
def get_body_size(self, candle):
return abs(float(candle["open"]) - float(candle["close"]))
def find_valid_prev_bar(self, all_data, current_idx):
"""找前一根有效K线实体>=min_body_size"""
if current_idx <= 0:
return None, None
for i in range(current_idx - 1, -1, -1):
prev = all_data[i]
if self.get_body_size(prev) >= self.min_body_size:
return i, prev
return None, None
def get_trigger_levels(self, prev, curr_open):
"""
基于当前K线开盘价计算触发价1111
做多触发 = 当前K线开盘价 + 实体/5
做空触发 = 当前K线开盘价 - 实体/5
"""
body = self.get_body_size(prev)
if body < 0.001:
return None, None
curr_o = float(curr_open)
return curr_o + body / 5, curr_o - body / 5
def get_1m_bars_for_3m_bar(self, bar_3m):
"""获取当前3分钟K线对应的3根1分钟K线"""
try:
start_ts = int(bar_3m["id"])
end_ts = start_ts + 3 * 60
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=1,
start_time=start_ts,
end_time=end_ts,
)[0]
if response.get("code") != 1000:
return []
data = response.get("data", [])
out = []
for k in data:
out.append(
{
"id": int(k["timestamp"]),
"open": float(k["open_price"]),
"high": float(k["high_price"]),
"low": float(k["low_price"]),
"close": float(k["close_price"]),
}
)
out.sort(key=lambda x: x["id"])
return out
except Exception as e:
logger.warning(f"获取1分钟K线失败: {e}")
return []
def determine_trigger_order_by_1m(self, bars_1m, long_trigger, short_trigger):
"""同根K线多空都触及时用1分钟K线判断先后"""
if not bars_1m:
return None
for bar in bars_1m:
high = float(bar["high"])
low = float(bar["low"])
open_price = float(bar["open"])
long_ok = high >= long_trigger
short_ok = low <= short_trigger
if long_ok and not short_ok:
return "long"
if short_ok and not long_ok:
return "short"
if long_ok and short_ok:
d_long = abs(long_trigger - open_price)
d_short = abs(short_trigger - open_price)
return "short" if d_short < d_long else "long"
return None
def check_trigger(self, kline_data):
"""
检测当前K线是否触发信号1111当前开盘价±实体/5
返回:(方向, 触发价, 有效前一根, 当前K线) 或 (None,...)
"""
if len(kline_data) < 2:
return None, None, None, None
curr = kline_data[-1]
curr_kline_id = curr["id"]
curr_open = curr["open"]
_, prev = self.find_valid_prev_bar(kline_data, len(kline_data) - 1)
if prev is None:
return None, None, None, None
long_trigger, short_trigger = self.get_trigger_levels(prev, curr_open)
if long_trigger is None:
return None, None, None, None
c_high = float(curr["high"])
c_low = float(curr["low"])
long_triggered = c_high >= long_trigger
short_triggered = c_low <= short_trigger
direction = None
trigger_price = None
if long_triggered and short_triggered:
bars_1m = self.get_1m_bars_for_3m_bar(curr)
if bars_1m:
direction = self.determine_trigger_order_by_1m(
bars_1m, long_trigger, short_trigger
)
trigger_price = long_trigger if direction == "long" else short_trigger
if direction is None:
c_open_f = float(curr["open"])
d_long = abs(long_trigger - c_open_f)
d_short = abs(short_trigger - c_open_f)
direction = "short" if d_short <= d_long else "long"
trigger_price = long_trigger if direction == "long" else short_trigger
elif short_triggered:
direction = "short"
trigger_price = short_trigger
elif long_triggered:
direction = "long"
trigger_price = long_trigger
if direction is None:
return None, None, None, None
if (
self.last_trigger_kline_id == curr_kline_id
and self.last_trigger_direction == direction
):
return None, None, None, None
return direction, trigger_price, prev, curr
# ==================== BitMart API ====================
def get_klines(self):
try:
end_time = int(time.time())
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=self.kline_step,
start_time=end_time - 3600 * 3,
end_time=end_time,
)[0]["data"]
formatted = []
for k in response:
formatted.append(
{
"id": int(k["timestamp"]),
"open": float(k["open_price"]),
"high": float(k["high_price"]),
"low": float(k["low_price"]),
"close": float(k["close_price"]),
}
)
formatted.sort(key=lambda x: x["id"])
return formatted
except Exception as e:
if "429" in str(e) or "too many requests" in str(e).lower():
logger.warning(f"API限流等待60秒: {e}")
time.sleep(60)
else:
logger.error(f"获取K线异常: {e}")
self.ding("获取K线异常", error=True)
return None
def get_available_balance(self):
try:
response = self.contractAPI.get_assets_detail()[0]
if response["code"] == 1000:
data = response["data"]
if isinstance(data, dict):
return float(data.get("available_balance", 0))
for asset in data:
if asset.get("currency") == "USDT":
return float(asset.get("available_balance", 0))
return None
except Exception as e:
logger.error(f"余额查询异常: {e}")
return None
def get_position_status(self):
try:
response = self.contractAPI.get_position(
contract_symbol=self.contract_symbol
)[0]
if response["code"] == 1000:
positions = response["data"]
if not positions:
self.start = 0
self.open_avg_price = None
self.current_amount = None
self.position_cross = None
return True
self.start = 1 if positions[0]["position_type"] == 1 else -1
self.open_avg_price = positions[0]["open_avg_price"]
self.current_amount = positions[0]["current_amount"]
self.position_cross = positions[0]["position_cross"]
return True
return False
except Exception as e:
logger.error(f"持仓查询异常: {e}")
return False
def set_leverage(self):
try:
response = self.contractAPI.post_submit_leverage(
contract_symbol=self.contract_symbol,
leverage=self.leverage,
open_type=self.open_type,
)[0]
if response["code"] == 1000:
logger.success(f"全仓 {self.leverage}x 杠杆设置成功")
return True
logger.error(f"杠杆设置失败: {response}")
return False
except Exception as e:
logger.error(f"设置杠杆异常: {e}")
return False
# ==================== 浏览器 ====================
def _open_browser(self):
try:
bit_port = openBrowser(id=self.bit_id)
co = ChromiumOptions()
co.set_local_port(port=bit_port)
self.page = ChromiumPage(addr_or_opts=co)
return True
except Exception:
return False
def close_extra_tabs(self):
try:
for idx, tab in enumerate(self.page.get_tabs()):
if idx > 0:
tab.close()
return True
except Exception:
return False
def click_safe(self, xpath, sleep=0.5):
try:
ele = self.page.ele(xpath)
if not ele:
return False
ele.scroll.to_see(center=True)
time.sleep(sleep)
ele.click(by_js=True)
return True
except Exception:
return False
def 平仓(self):
logger.info("执行平仓...")
self.click_safe('x://span[normalize-space(text()) ="市价"]')
time.sleep(0.5)
self.ding("执行平仓操作")
def 开单(self, marketPriceLongOrder=0, size=None):
if size is None or size <= 0:
logger.warning("开单金额无效")
return False
direction_str = "做多" if marketPriceLongOrder == 1 else "做空"
logger.info(f"执行{direction_str},金额: {size}")
size = max(1, min(25, int(size)))
try:
self.click_safe('x://button[normalize-space(text()) ="市价"]')
self.page.ele('x://*[@id="size_0"]').input(str(size))
if marketPriceLongOrder == -1:
self.click_safe('x://span[normalize-space(text()) ="卖出/做空"]')
else:
self.click_safe('x://span[normalize-space(text()) ="买入/做多"]')
self.ding(f"执行{direction_str},金额: {size}")
return True
except Exception as e:
logger.error(f"开单异常: {e}")
return False
def ding(self, msg, error=False):
prefix = "❌五分之一:" if error else "🔔五分之一:"
full_msg = f"{prefix}{msg}"
if error:
logger.error(msg)
for _ in range(3):
ding_executor.submit(self._send_ding_safe, full_msg)
else:
logger.info(msg)
ding_executor.submit(self._send_ding_safe, full_msg)
def _send_ding_safe(self, msg):
try:
send_dingtalk_message(msg)
except Exception as e:
logger.warning(f"消息发送失败: {e}")
def _send_position_message(self, latest_kline):
current_price = float(latest_kline["close"])
balance = self.get_available_balance()
self.balance = balance if balance is not None else 0.0
if self.start != 0:
open_avg_price = float(self.open_avg_price)
current_amount = float(self.current_amount)
position_cross = float(getattr(self, "position_cross", 0) or 0)
if self.start == 1:
unrealized_pnl = current_amount * 0.001 * (
current_price - open_avg_price
)
else:
unrealized_pnl = current_amount * 0.001 * (
open_avg_price - current_price
)
pnl_rate = (
(current_price - open_avg_price) / open_avg_price * 100
if self.start == 1
else (open_avg_price - current_price) / open_avg_price * 100
)
direction_str = "" if self.start == -1 else ""
msg = (
f"【五分之一 {self.contract_symbol}\n"
f"方向:{direction_str}\n"
f"现价:{current_price:.2f}\n"
f"开仓均价:{open_avg_price:.2f}\n"
f"浮动盈亏:{unrealized_pnl:+.2f} USDT ({pnl_rate:+.2f}%)\n"
f"余额:{self.balance:.2f}"
)
else:
msg = (
f"【五分之一 {self.contract_symbol}\n"
f"方向:无\n"
f"现价:{current_price:.2f}\n"
f"余额:{self.balance:.2f}"
)
self.ding(msg)
# ==================== 主循环 ====================
def action(self):
if not self.set_leverage():
logger.error("杠杆设置失败")
return
if not self._open_browser():
self.ding("打开浏览器失败!", error=True)
return
logger.info("浏览器打开成功")
self.close_extra_tabs()
self.page.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
time.sleep(2)
self.click_safe('x://button[normalize-space(text()) ="市价"]')
logger.info(
f"五分之一策略3分钟K线开始监测间隔: {self.check_interval}"
)
last_report_time = 0
report_interval = 300
while True:
for _ in range(5):
if self._open_browser():
break
time.sleep(5)
else:
self.ding("打开浏览器失败!", error=True)
return
self.close_extra_tabs()
self.page.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
time.sleep(2)
self.click_safe('x://button[normalize-space(text()) ="市价"]')
try:
kline_data = self.get_klines()
if not kline_data or len(kline_data) < 3:
logger.warning("K线数据不足...")
time.sleep(self.check_interval)
continue
curr = kline_data[-1]
if not self.get_position_status():
logger.warning("获取仓位失败,使用缓存")
direction, trigger_price, valid_prev, curr_kline = (
self.check_trigger(kline_data)
)
if direction:
curr_kline_id = curr_kline["id"]
if self.last_trade_kline_id == curr_kline_id:
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
time.sleep(self.check_interval)
continue
if (direction == "long" and self.start == 1) or (
direction == "short" and self.start == -1
):
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
time.sleep(self.check_interval)
continue
balance = self.get_available_balance()
trade_size = (balance or 0) * self.risk_percent
executed = False
if direction == "long":
if self.start == -1:
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=1, size=trade_size)
executed = True
elif self.start == 0:
self.开单(marketPriceLongOrder=1, size=trade_size)
executed = True
elif direction == "short":
if self.start == 1:
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=-1, size=trade_size)
executed = True
elif self.start == 0:
self.开单(marketPriceLongOrder=-1, size=trade_size)
executed = True
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
if executed:
self.last_trade_kline_id = curr_kline_id
self.get_position_status()
self._send_position_message(curr_kline)
last_report_time = time.time()
if time.time() - last_report_time >= report_interval:
if self.get_position_status():
self._send_position_message(kline_data[-1])
last_report_time = time.time()
time.sleep(self.check_interval)
except Exception as e:
logger.error(f"主循环异常: {e}")
time.sleep(self.check_interval)
time.sleep(3)
if random.randint(1, 10) > 7:
self.page.close()
time.sleep(15)
if __name__ == "__main__":
try:
OpenBasedFifthStrategy(bit_id=BIT_ID).action()
except KeyboardInterrupt:
logger.info("程序被用户中断")
finally:
ding_executor.shutdown(wait=True)
logger.info("已退出")

Binary file not shown.

View File

@@ -31,10 +31,10 @@ LOCAL_TZ = ZoneInfo("America/New_York")
# 代理(可选)
PROXY = {
'proxy_type': "socks5",
'addr': "202.155.144.102",
'port': 31102,
'username': "SyNuejCtrQ",
'password': "MH8ioL7EXf"
'addr': "199.168.137.123",
'port': 12345,
'username': "haha",
'password': "haha"
}
INVITE_LINK = "https://www.websea.my/en/signup?key=77346588" # 请填入您的邀请链接
@@ -134,6 +134,7 @@ main_buttons = [
[Button.inline("Jemputan Saya", command_payload("my_invites")),
Button.inline("Harga Koin", command_payload("btc"))],
[Button.inline("Mata Saya", command_payload("points")), Button.inline("Bantuan", command_payload("help"))],
[Button.url("Official Customer Service", "https://t.me/uogrrr")],
]
@@ -514,6 +515,7 @@ def get_crypto_buttons():
if row:
buttons.append(row)
buttons.append([Button.inline("Kembali ke Menu", command_payload("help"))])
buttons.append([Button.url("Official Customer Service", "https://t.me/uogrrr")])
return buttons

77
test.py
View File

@@ -1,3 +1,76 @@
from time import sleep
from datetime import datetime
import random
from pathlib import Path
print(Path(__file__).parent)
from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.layout import Layout
from rich.align import Align
from rich.text import Text
from rich.live import Live
console = Console()
def make_header() -> Panel:
title = Text("SYSTEM DASHBOARD", style="bold cyan")
subtitle = Text(datetime.now().strftime("%Y-%m-%d %H:%M:%S"), style="dim")
return Panel(Align.center(title + "\n" + subtitle), border_style="cyan")
def make_metrics_table(cpu: int, mem: int, qps: int) -> Panel:
t = Table(show_header=True, header_style="bold magenta", expand=True)
t.add_column("Metric")
t.add_column("Value", justify="right")
t.add_row("CPU", f"{cpu}%")
t.add_row("Memory", f"{mem}%")
t.add_row("QPS", str(qps))
return Panel(t, title="Metrics", border_style="magenta")
def make_status_panel(status: str, logs: list[str]) -> Panel:
body = "\n".join(logs[-8:]) if logs else "No logs yet."
text = Text(f"[bold]Status:[/bold] {status}\n\n", style="white")
text.append(body, style="dim")
return Panel(text, title="Status / Logs", border_style="green")
def make_footer(msg: str) -> Panel:
return Panel(Text(msg, style="bold yellow"), border_style="yellow")
def build_layout(cpu: int, mem: int, qps: int, status: str, logs: list[str]) -> Layout:
layout = Layout()
layout.split_column(
Layout(make_header(), name="header", size=5),
Layout(name="body", ratio=1),
Layout(make_footer("Press Ctrl+C to exit"), name="footer", size=3),
)
layout["body"].split_row(
Layout(make_metrics_table(cpu, mem, qps), name="left", ratio=1),
Layout(make_status_panel(status, logs), name="right", ratio=2),
)
return layout
def main():
logs = []
status = "OK"
with Live(console=console, refresh_per_second=8, screen=True):
while True:
cpu = random.randint(1, 100)
mem = random.randint(1, 100)
qps = random.randint(50, 5000)
if cpu > 85 or mem > 90:
status = "WARN"
logs.append(f"{datetime.now().strftime('%H:%M:%S')} - High load detected")
else:
status = "OK"
if random.random() < 0.2:
logs.append(f"{datetime.now().strftime('%H:%M:%S')} - Heartbeat")
layout = build_layout(cpu, mem, qps, status, logs)
Live.get_renderable = lambda self: layout # 小技巧:避免重复创建 Live
sleep(0.15)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
console.print("\nBye!", style="bold red")

1283
test1.py

File diff suppressed because it is too large Load Diff

949
test2.py
View File

@@ -1,949 +0,0 @@
import os
import time
import uuid
import datetime
from dataclasses import dataclass
from tqdm import tqdm
from loguru import logger
from bitmart.api_contract import APIContract
from bitmart.lib.cloud_exceptions import APIException
from 交易.tools import send_dingtalk_message
@dataclass
class StrategyConfig:
# =============================
# 1m | ETH 永续 | 控止损≤5/日
# =============================
# ===== 合约 =====
contract_symbol: str = "ETHUSDT"
open_type: str = "cross"
leverage: str = "30"
# ===== K线与指标 =====
step_min: int = 1
lookback_min: int = 240
ema_len: int = 36
atr_len: int = 14
# ===== ADX 趋势过滤(新增)=====
# 目的单边趋势ADX高抑制/禁止逆势均值回归单,避免反复反向开仓止损
enable_adx_filter: bool = True
adx_len: int = 14
adx_threshold: float = 25.0 # 常用20~30区间你可按回测调整
# 过滤模式:
# - "block_countertrend": 只禁止逆着 DI 的方向开仓(推荐,既防反手又不完全停机)
# - "block_all": ADX 高时直接不允许任何新开仓(更保守)
adx_mode: str = "block_countertrend"
# 趋势保护冷却:当 ADX 高且刚止损,延长冷却,减少“止损->立刻反手”的连环
cooldown_sec_after_sl_extra: int = 40
# =========================================================
# ✅ 自动阈值ATR/Price 分位数基准(更稳,不被短时噪声带跑)
# =========================================================
vol_baseline_window: int = 60
vol_baseline_quantile: float = 0.65
vol_scale_min: float = 0.80
vol_scale_max: float = 1.60
# ✅ baseline 每 60 秒刷新一次体感更明显、也省CPU
base_ratio_refresh_sec: int = 180
# =========================================================
# ✅ 动态 floor方案一
# floor = clamp(min, base_k * base_ratio, max)
# 目的跟着典型波动变过滤小噪声tp/sl 也随环境自适应
# =========================================================
# entry_dev_floor 动态
entry_dev_floor_min: float = 0.0012 # 0.12%
entry_dev_floor_max: float = 0.0030 # 0.30%
entry_dev_floor_base_k: float = 1.10 # entry_floor = 1.10 * base_ratio
# tp_floor 动态
tp_floor_min: float = 0.0006 # 0.06%
tp_floor_max: float = 0.0020 # 0.20%
tp_floor_base_k: float = 0.55 # tp_floor = 0.55 * base_ratio
# sl_floor 动态
sl_floor_min: float = 0.0018 # 0.18%
sl_floor_max: float = 0.0060 # 0.60%
sl_floor_base_k: float = 1.35 # sl_floor = 1.35 * base_ratio
# =========================================================
# ✅ 动态阈值倍率
# =========================================================
entry_k: float = 1.45
tp_k: float = 0.65
sl_k: float = 1.05
# ===== 时间/冷却 =====
max_hold_sec: int = 75
cooldown_sec_after_exit: int = 20
# ===== 下单/仓位 =====
risk_percent: float = 0.004
min_size: int = 1
max_size: int = 5000
# ===== 日内风控 =====
daily_loss_limit: float = 0.02
daily_profit_cap: float = 0.01
# ===== 危险模式过滤 =====
atr_ratio_kill: float = 0.0038
big_body_kill: float = 0.010
# ===== 轮询节奏 =====
klines_refresh_sec: int = 10
tick_refresh_sec: int = 1
status_notify_sec: int = 60
# =========================================================
# ✅ 止损后同向入场加门槛(你原来的逻辑保留)
# =========================================================
reentry_penalty_mult: float = 1.55
reentry_penalty_max_sec: int = 180
reset_band_k: float = 0.45
reset_band_floor: float = 0.0006
# =========================================================
# ✅ 止损后同方向 SL 放宽幅度与"止损时 vol_scale"联动
# =========================================================
post_sl_sl_max_sec: int = 90
post_sl_mult_min: float = 1.02
post_sl_mult_max: float = 1.16
post_sl_vol_alpha: float = 0.20
class BitmartFuturesMeanReversionBot:
def __init__(self, cfg: StrategyConfig):
self.cfg = cfg
self.api_key = os.getenv("BITMART_API_KEY", "").strip()
self.secret_key = os.getenv("BITMART_SECRET_KEY", "").strip()
self.memo = os.getenv("BITMART_MEMO", "合约交易").strip()
if not self.api_key or not self.secret_key:
raise RuntimeError("请先设置环境变量 BITMART_API_KEY / BITMART_SECRET_KEY / BITMART_MEMO(可选)")
self.contractAPI = APIContract(self.api_key, self.secret_key, self.memo, timeout=(5, 15))
# 持仓状态: -1 空, 0 无, 1 多
self.pos = 0
self.entry_price = None
self.entry_ts = None
self.last_exit_ts = 0
# 日内权益基准
self.day_start_equity = None
self.trading_enabled = True
self.day_tag = datetime.date.today()
# 缓存
self._klines_cache = None
self._klines_cache_ts = 0
self._last_status_notify_ts = 0
# ✅ base_ratio 缓存
self._base_ratio_cached = 0.0015 # 初始化默认值 0.15%
self._base_ratio_ts = 0.0
# ✅ 止损后"同向入场加门槛"状态
self.last_sl_dir = 0 # 1=多止损,-1=空止损0=无
self.last_sl_ts = 0.0
# ✅ 止损后"同方向 SL 联动放宽"状态
self.post_sl_dir = 0
self.post_sl_ts = 0.0
self.post_sl_vol_scale = 1.0 # 记录止损时的 vol_scale
self.pbar = tqdm(total=60, desc="运行中(秒)", ncols=90)
logger.info(f"初始化完成,基准波动率默认值: {self._base_ratio_cached * 100:.4f}%")
# ----------------- 通用工具 -----------------
def ding(self, msg, error=False):
prefix = "❌bitmart" if error else "🔔bitmart"
if error:
for _ in range(3):
send_dingtalk_message(f"{prefix}{msg}")
else:
send_dingtalk_message(f"{prefix}{msg}")
def set_leverage(self) -> bool:
try:
resp = self.contractAPI.post_submit_leverage(
contract_symbol=self.cfg.contract_symbol,
leverage=self.cfg.leverage,
open_type=self.cfg.open_type
)[0]
if resp.get("code") == 1000:
logger.success(f"设置杠杆成功:{self.cfg.open_type} + {self.cfg.leverage}x")
return True
logger.error(f"设置杠杆失败: {resp}")
self.ding(f"设置杠杆失败: {resp}", error=True)
return False
except Exception as e:
logger.error(f"设置杠杆异常: {e}")
self.ding(f"设置杠杆异常: {e}", error=True)
return False
# ----------------- 行情/指标 -----------------
def get_klines_cached(self):
now = time.time()
if self._klines_cache is not None and (now - self._klines_cache_ts) < self.cfg.klines_refresh_sec:
return self._klines_cache
kl = self.get_klines()
if kl:
self._klines_cache = kl
self._klines_cache_ts = now
return self._klines_cache
def get_klines(self):
try:
end_time = int(time.time())
start_time = end_time - 60 * self.cfg.lookback_min
resp = self.contractAPI.get_kline(
contract_symbol=self.cfg.contract_symbol,
step=self.cfg.step_min,
start_time=start_time,
end_time=end_time
)[0]
if resp.get("code") != 1000:
logger.error(f"获取K线失败: {resp}")
return None
data = resp.get("data", [])
formatted = []
for k in data:
formatted.append({
"id": int(k["timestamp"]),
"open": float(k["open_price"]),
"high": float(k["high_price"]),
"low": float(k["low_price"]),
"close": float(k["close_price"]),
})
formatted.sort(key=lambda x: x["id"])
return formatted
except Exception as e:
logger.error(f"获取K线异常: {e}")
self.ding(f"获取K线异常: {e}", error=True)
return None
def get_last_price(self, fallback_close: float) -> float:
try:
if hasattr(self.contractAPI, "get_contract_details"):
r = self.contractAPI.get_contract_details(contract_symbol=self.cfg.contract_symbol)[0]
d = r.get("data") if isinstance(r, dict) else None
if isinstance(d, dict):
for key in ("last_price", "mark_price", "index_price"):
if key in d and d[key] is not None:
return float(d[key])
if hasattr(self.contractAPI, "get_ticker"):
r = self.contractAPI.get_ticker(contract_symbol=self.cfg.contract_symbol)[0]
d = r.get("data") if isinstance(r, dict) else None
if isinstance(d, dict):
for key in ("last_price", "price", "last", "close"):
if key in d and d[key] is not None:
return float(d[key])
except Exception:
pass
return float(fallback_close)
@staticmethod
def ema(values, n: int) -> float:
k = 2 / (n + 1)
e = values[0]
for v in values[1:]:
e = v * k + e * (1 - k)
return e
@staticmethod
def atr(klines, n: int) -> float:
if len(klines) < n + 1:
return 0.0
trs = []
for i in range(-n, 0):
cur = klines[i]
prev = klines[i - 1]
tr = max(
cur["high"] - cur["low"],
abs(cur["high"] - prev["close"]),
abs(cur["low"] - prev["close"]),
)
trs.append(tr)
return sum(trs) / len(trs)
@staticmethod
def _wilder_smooth(prev: float, val: float, n: int) -> float:
# Wilder smoothing: prev - prev/n + val
return prev - (prev / n) + val
def adx(self, klines, n: int):
"""
返回 (adx, plus_di, minus_di)
采用经典 Wilder ADX/DI 计算(足够稳,避免趋势期逆势反复开仓)
"""
if len(klines) < (2 * n + 2):
return 0.0, 0.0, 0.0
highs = [k["high"] for k in klines]
lows = [k["low"] for k in klines]
closes = [k["close"] for k in klines]
# 计算 TR, +DM, -DM 序列从1开始
tr_list = []
pdm_list = []
mdm_list = []
for i in range(1, len(klines)):
high = highs[i]
low = lows[i]
prev_close = closes[i - 1]
prev_high = highs[i - 1]
prev_low = lows[i - 1]
tr = max(high - low, abs(high - prev_close), abs(low - prev_close))
up_move = high - prev_high
down_move = prev_low - low
pdm = up_move if (up_move > down_move and up_move > 0) else 0.0
mdm = down_move if (down_move > up_move and down_move > 0) else 0.0
tr_list.append(tr)
pdm_list.append(pdm)
mdm_list.append(mdm)
# 初始平滑值第一个n段的和
tr14 = sum(tr_list[:n])
pdm14 = sum(pdm_list[:n])
mdm14 = sum(mdm_list[:n])
def safe_div(a, b):
return (a / b) if b != 0 else 0.0
plus_di = 100.0 * safe_div(pdm14, tr14)
minus_di = 100.0 * safe_div(mdm14, tr14)
dx = 100.0 * safe_div(abs(plus_di - minus_di), (plus_di + minus_di))
dx_list = [dx]
# 继续平滑并计算后续 DX
for i in range(n, len(tr_list)):
tr14 = self._wilder_smooth(tr14, tr_list[i], n)
pdm14 = self._wilder_smooth(pdm14, pdm_list[i], n)
mdm14 = self._wilder_smooth(mdm14, mdm_list[i], n)
plus_di = 100.0 * safe_div(pdm14, tr14)
minus_di = 100.0 * safe_div(mdm14, tr14)
dx = 100.0 * safe_div(abs(plus_di - minus_di), (plus_di + minus_di))
dx_list.append(dx)
# ADX 是 DX 的 Wilder 平滑,常见做法:先取前 n 个 DX 的均值作为初值
if len(dx_list) < (n + 1):
return 0.0, plus_di, minus_di
adx0 = sum(dx_list[:n]) / n
adx_val = adx0
for j in range(n, len(dx_list)):
adx_val = (adx_val * (n - 1) + dx_list[j]) / n
return float(adx_val), float(plus_di), float(minus_di)
def is_danger_market(self, klines, price: float) -> bool:
last = klines[-1]
body = abs(last["close"] - last["open"]) / last["open"] if last["open"] else 0.0
if body >= self.cfg.big_body_kill:
return True
a = self.atr(klines, self.cfg.atr_len)
atr_ratio = (a / price) if price > 0 else 0.0
if atr_ratio >= self.cfg.atr_ratio_kill:
return True
return False
def atr_ratio_baseline(self, klines) -> float:
"""简化版ATR基准计算"""
window = min(self.cfg.vol_baseline_window, len(klines) - self.cfg.atr_len - 1)
if window <= 10:
logger.warning(f"数据不足计算基准: {len(klines)}根K线")
return 0.0
ratios = []
step = 3
for i in range(-window, 0, step):
if len(klines) + i < self.cfg.atr_len + 1:
continue
start_idx = len(klines) + i - self.cfg.atr_len
end_idx = len(klines) + i
if start_idx < 0 or end_idx <= start_idx:
continue
sub_klines = klines[start_idx:end_idx]
if len(sub_klines) >= self.cfg.atr_len + 1:
a = self.atr(sub_klines, self.cfg.atr_len)
price = klines[end_idx - 1]["close"]
if a > 0 and price > 0:
ratio = a / price
if 0.0001 < ratio < 0.01:
ratios.append(ratio)
if len(ratios) < 5:
a = self.atr(klines[-60:], self.cfg.atr_len)
price = klines[-1]["close"]
if a > 0 and price > 0:
baseline = a / price
logger.debug(f"使用全量数据计算基准: {baseline * 100:.4f}%")
return baseline
return 0.0
ratios.sort()
idx = min(len(ratios) - 1, max(0, int(self.cfg.vol_baseline_quantile * (len(ratios) - 1))))
baseline = ratios[idx]
logger.debug(
f"基准计算: 样本数={len(ratios)}, 基准={baseline * 100:.4f}%, "
f"范围=[{ratios[0] * 100:.4f}%, {ratios[-1] * 100:.4f}%]"
)
return baseline
def get_base_ratio_cached(self, klines) -> float:
"""获取缓存的基准波动率,定期刷新"""
now = time.time()
refresh_sec = self.cfg.base_ratio_refresh_sec
if (self._base_ratio_cached is None or (now - self._base_ratio_ts) >= refresh_sec):
baseline = self.atr_ratio_baseline(klines)
if baseline > 0.0001:
self._base_ratio_cached = baseline
self._base_ratio_ts = now
logger.info(f"基准波动率更新: {baseline * 100:.4f}%")
else:
current_price = klines[-1]["close"] if klines else 3000
if current_price > 4000:
default_baseline = 0.0010
elif current_price > 3500:
default_baseline = 0.0012
elif current_price > 3000:
default_baseline = 0.0015
elif current_price > 2500:
default_baseline = 0.0018
else:
default_baseline = 0.0020
self._base_ratio_cached = default_baseline
self._base_ratio_ts = now
logger.warning(
f"使用价格动态默认基准: {default_baseline * 100:.4f}% (价格=${current_price:.0f})"
)
return self._base_ratio_cached
@staticmethod
def _clamp(x: float, lo: float, hi: float) -> float:
return max(lo, min(hi, x))
def dynamic_thresholds(self, atr_ratio: float, base_ratio: float):
"""
✅ entry/tp/sl 全部动态(修复版):
- vol_scaleatr_ratio/base_ratio 限幅
- floor方案一 (floor = clamp(min, k*base_ratio, max))
- 最终阈值max(floor, k * vol_scale * atr_ratio)
"""
if atr_ratio <= 0:
logger.warning(f"ATR比率异常: {atr_ratio}")
atr_ratio = 0.001
if base_ratio < 0.0005:
base_ratio = max(0.001, atr_ratio * 1.2)
logger.debug(f"基准太小使用调整后的atr_ratio: {base_ratio * 100:.4f}%")
if base_ratio > 0:
raw_scale = atr_ratio / base_ratio
vol_scale = self._clamp(raw_scale, self.cfg.vol_scale_min, self.cfg.vol_scale_max)
logger.debug(
f"vol_scale: {raw_scale:.2f}{vol_scale:.2f} (atr={atr_ratio * 100:.3f}%, base={base_ratio * 100:.3f}%)"
)
else:
vol_scale = 1.0
logger.warning("基准无效使用默认vol_scale=1.0")
entry_floor_raw = self.cfg.entry_dev_floor_base_k * base_ratio
entry_floor = self._clamp(entry_floor_raw, self.cfg.entry_dev_floor_min, self.cfg.entry_dev_floor_max)
tp_floor_raw = self.cfg.tp_floor_base_k * base_ratio
tp_floor = self._clamp(tp_floor_raw, self.cfg.tp_floor_min, self.cfg.tp_floor_max)
sl_floor_raw = self.cfg.sl_floor_base_k * base_ratio
sl_floor = self._clamp(sl_floor_raw, self.cfg.sl_floor_min, self.cfg.sl_floor_max)
entry_dev_atr_part = self.cfg.entry_k * vol_scale * atr_ratio
entry_dev = max(entry_floor, entry_dev_atr_part)
tp_atr_part = self.cfg.tp_k * vol_scale * atr_ratio
tp = max(tp_floor, tp_atr_part)
sl_atr_part = self.cfg.sl_k * vol_scale * atr_ratio
sl = max(sl_floor, sl_atr_part)
entry_dev = max(entry_dev, self.cfg.entry_dev_floor_min)
logger.info(
f"动态阈值: atr={atr_ratio * 100:.4f}%, base={base_ratio * 100:.4f}%, "
f"vol_scale={vol_scale:.2f}, floor={entry_floor * 100:.4f}%, "
f"atr_part={entry_dev_atr_part * 100:.4f}%, 最终entry_dev={entry_dev * 100:.4f}%"
)
return entry_dev, tp, sl, vol_scale, entry_floor, tp_floor, sl_floor
# ----------------- 账户/仓位 -----------------
def get_assets_available(self) -> float:
try:
resp = self.contractAPI.get_assets_detail()[0]
if resp.get("code") != 1000:
return 0.0
data = resp.get("data")
if isinstance(data, dict):
return float(data.get("available_balance", 0))
if isinstance(data, list):
for asset in data:
if asset.get("currency") == "USDT":
return float(asset.get("available_balance", 0))
return 0.0
except Exception as e:
logger.error(f"余额查询异常: {e}")
return 0.0
def get_position_status(self) -> bool:
try:
resp = self.contractAPI.get_position(contract_symbol=self.cfg.contract_symbol)[0]
if resp.get("code") != 1000:
return False
positions = resp.get("data", [])
if not positions:
self.pos = 0
return True
p = positions[0]
self.pos = 1 if p["position_type"] == 1 else -1
return True
except Exception as e:
logger.error(f"持仓查询异常: {e}")
self.ding(f"持仓查询异常: {e}", error=True)
return False
def get_equity_proxy(self) -> float:
return self.get_assets_available()
def refresh_daily_baseline(self):
today = datetime.date.today()
if today != self.day_tag:
self.day_tag = today
self.day_start_equity = None
self.trading_enabled = True
self.ding(f"新的一天({today}):重置日内风控基准")
def risk_kill_switch(self):
self.refresh_daily_baseline()
equity = self.get_equity_proxy()
if equity <= 0:
return
if self.day_start_equity is None:
self.day_start_equity = equity
logger.info(f"日内权益基准设定:{equity:.2f} USDT")
return
pnl = (equity - self.day_start_equity) / self.day_start_equity
if pnl <= -self.cfg.daily_loss_limit:
self.trading_enabled = False
self.ding(f"触发日止损:{pnl * 100:.2f}% -> 停机", error=True)
if pnl >= self.cfg.daily_profit_cap:
self.trading_enabled = False
self.ding(f"达到日盈利封顶:{pnl * 100:.2f}% -> 停机")
# ----------------- 下单 -----------------
def calculate_size(self, price: float) -> int:
bal = self.get_assets_available()
if bal < 10:
return 0
margin = bal * self.cfg.risk_percent
lev = int(self.cfg.leverage)
# ⚠️ 沿用你的原假设1张≈0.001ETH
size = int((margin * lev) / (price * 0.001))
size = max(self.cfg.min_size, size)
size = min(self.cfg.max_size, size)
return size
def place_market_order(self, side: int, size: int) -> bool:
if size <= 0:
return False
client_order_id = f"mr_{int(time.time())}_{uuid.uuid4().hex[:8]}"
try:
resp = self.contractAPI.post_submit_order(
contract_symbol=self.cfg.contract_symbol,
client_order_id=client_order_id,
side=side,
mode=1,
type="market",
leverage=self.cfg.leverage,
open_type=self.cfg.open_type,
size=size
)[0]
logger.info(f"order_resp: {resp}")
if resp.get("code") == 1000:
return True
self.ding(f"下单失败: {resp}", error=True)
return False
except APIException as e:
logger.error(f"API下单异常: {e}")
self.ding(f"API下单异常: {e}", error=True)
return False
except Exception as e:
logger.error(f"下单未知异常: {e}")
self.ding(f"下单未知异常: {e}", error=True)
return False
def close_position_all(self):
if self.pos == 1:
ok = self.place_market_order(3, 999999)
if ok:
self.pos = 0
elif self.pos == -1:
ok = self.place_market_order(2, 999999)
if ok:
self.pos = 0
# ----------------- 止损后机制 -----------------
def _reentry_penalty_active(self, dev: float, entry_dev: float) -> bool:
"""检查是否需要应用重新入场惩罚(你原逻辑保留)"""
if self.last_sl_dir == 0:
return False
if (time.time() - self.last_sl_ts) > self.cfg.reentry_penalty_max_sec:
self.last_sl_dir = 0
return False
reset_band = max(self.cfg.reset_band_floor, self.cfg.reset_band_k * entry_dev)
if abs(dev) <= reset_band:
self.last_sl_dir = 0
return False
return True
def _post_sl_dynamic_mult(self) -> float:
"""计算止损后SL放宽倍数"""
if self.post_sl_dir == 0:
return 1.0
if (time.time() - self.post_sl_ts) > self.cfg.post_sl_sl_max_sec:
self.post_sl_dir = 0
self.post_sl_vol_scale = 1.0
return 1.0
raw = 1.0 + self.cfg.post_sl_vol_alpha * (self.post_sl_vol_scale - 1.0)
raw = max(1.0, raw) # 不缩小止损,只放宽
return max(self.cfg.post_sl_mult_min, min(self.cfg.post_sl_mult_max, raw))
# ----------------- 交易逻辑 -----------------
def in_cooldown(self) -> bool:
"""检查是否在冷却期内(新增:止损后可额外延长冷却,用于抑制反手连环)"""
cd = self.cfg.cooldown_sec_after_exit
if self.last_sl_ts and (time.time() - self.last_sl_ts) < self.cfg.reentry_penalty_max_sec:
cd += max(0, self.cfg.cooldown_sec_after_sl_extra)
return (time.time() - self.last_exit_ts) < cd
def _adx_blocks_entry(self, adx_val: float, plus_di: float, minus_di: float, want_dir: int) -> bool:
"""
ADX 趋势过滤:
- want_dir: 1=想开多, -1=想开空
"""
if not self.cfg.enable_adx_filter:
return False
if adx_val < self.cfg.adx_threshold:
return False
if self.cfg.adx_mode == "block_all":
return True
# block_countertrend只禁止逆 DI 方向
# 上升趋势:+DI > -DI => 禁止开空
# 下降趋势:-DI > +DI => 禁止开多
if plus_di > minus_di and want_dir == -1:
return True
if minus_di > plus_di and want_dir == 1:
return True
return False
def maybe_enter(self, price: float, ema_value: float, entry_dev: float,
adx_val: float, plus_di: float, minus_di: float):
"""检查并执行入场新增ADX趋势过滤防止趋势期逆势反复开仓"""
if self.pos != 0:
return
if self.in_cooldown():
return
dev = (price - ema_value) / ema_value if ema_value else 0.0
size = self.calculate_size(price)
if size <= 0:
return
penalty_active = self._reentry_penalty_active(dev, entry_dev)
long_th = -entry_dev
short_th = entry_dev
if penalty_active:
if self.last_sl_dir == 1:
long_th = -entry_dev * self.cfg.reentry_penalty_mult
logger.info(f"多头止损后惩罚生效: long_th={long_th * 100:.3f}%")
elif self.last_sl_dir == -1:
short_th = entry_dev * self.cfg.reentry_penalty_mult
logger.info(f"空头止损后惩罚生效: short_th={short_th * 100:.3f}%")
logger.info(
f"入场检查: price={price:.2f}, ema={ema_value:.2f}, dev={dev * 100:.3f}% "
f"(entry_dev={entry_dev * 100:.3f}%, long_th={long_th * 100:.3f}%, short_th={short_th * 100:.3f}%) "
f"ADX={adx_val:.2f} +DI={plus_di:.2f} -DI={minus_di:.2f} "
f"size={size}, penalty={penalty_active}, last_sl_dir={self.last_sl_dir}"
)
# 先判断信号,再用 ADX 过滤(这样日志更直观)
if dev <= long_th:
if self._adx_blocks_entry(adx_val, plus_di, minus_di, want_dir=1):
logger.warning(
f"ADX过滤趋势期禁止逆势开多ADX={adx_val:.2f}, +DI={plus_di:.2f}, -DI={minus_di:.2f}"
)
return
if self.place_market_order(1, size):
self.pos = 1
self.entry_price = price
self.entry_ts = time.time()
self.ding(f"✅开多dev={dev * 100:.3f}% size={size} entry={price:.2f}")
elif dev >= short_th:
if self._adx_blocks_entry(adx_val, plus_di, minus_di, want_dir=-1):
logger.warning(
f"ADX过滤趋势期禁止逆势开空ADX={adx_val:.2f}, +DI={plus_di:.2f}, -DI={minus_di:.2f}"
)
return
if self.place_market_order(4, size):
self.pos = -1
self.entry_price = price
self.entry_ts = time.time()
self.ding(f"✅开空dev={dev * 100:.3f}% size={size} entry={price:.2f}")
def maybe_exit(self, price: float, tp: float, sl: float, vol_scale: float):
"""检查并执行出场"""
if self.pos == 0 or self.entry_price is None or self.entry_ts is None:
return
hold = time.time() - self.entry_ts
if self.pos == 1:
pnl = (price - self.entry_price) / self.entry_price
else:
pnl = (self.entry_price - price) / self.entry_price
sl_mult = 1.0
if self.post_sl_dir == self.pos and self.post_sl_dir != 0:
sl_mult = self._post_sl_dynamic_mult()
effective_sl = sl * sl_mult
if pnl >= tp:
self.close_position_all()
self.ding(f"🎯止盈pnl={pnl * 100:.3f}% price={price:.2f} tp={tp * 100:.3f}%")
self.entry_price, self.entry_ts = None, None
self.last_exit_ts = time.time()
elif pnl <= -effective_sl:
sl_dir = self.pos
self.close_position_all()
self.ding(
f"🛑止损pnl={pnl * 100:.3f}% price={price:.2f} "
f"sl={sl * 100:.3f}% effective_sl={effective_sl * 100:.3f}%(×{sl_mult:.2f})",
error=True
)
# 记录止损方向与时间
self.last_sl_dir = sl_dir
self.last_sl_ts = time.time()
self.post_sl_dir = sl_dir
self.post_sl_ts = time.time()
self.post_sl_vol_scale = float(vol_scale)
self.entry_price, self.entry_ts = None, None
self.last_exit_ts = time.time()
elif hold >= self.cfg.max_hold_sec:
self.close_position_all()
self.ding(f"⏱超时hold={int(hold)}s pnl={pnl * 100:.3f}% price={price:.2f}")
self.entry_price, self.entry_ts = None, None
self.last_exit_ts = time.time()
def notify_status_throttled(self, price: float, ema_value: float, dev: float, bal: float,
atr_ratio: float, base_ratio: float, vol_scale: float,
entry_dev: float, tp: float, sl: float,
entry_floor: float, tp_floor: float, sl_floor: float,
adx_val: float, plus_di: float, minus_di: float):
"""限频状态通知"""
now = time.time()
if (now - self._last_status_notify_ts) < self.cfg.status_notify_sec:
return
self._last_status_notify_ts = now
direction_str = "" if self.pos == 1 else ("" if self.pos == -1 else "")
penalty_active = self._reentry_penalty_active(dev, entry_dev)
sl_mult = 1.0
if self.pos != 0 and self.post_sl_dir == self.pos:
sl_mult = self._post_sl_dynamic_mult()
base_age = int(now - self._base_ratio_ts) if self._base_ratio_ts else -1
msg = (
f"【BitMart {self.cfg.contract_symbol}1m均值回归(动态阈值+ADX过滤)】\n"
f"📊 状态:{direction_str}\n"
f"💰 现价:{price:.2f} | EMA{self.cfg.ema_len}{ema_value:.2f}\n"
f"📈 偏离:{dev * 100:.3f}% (入场阈值:±{entry_dev * 100:.3f}%)\n"
f"🌊 波动率ATR比={atr_ratio * 100:.3f}% | 基准={base_ratio * 100:.3f}% | 缩放={vol_scale:.2f}\n"
f"🧭 趋势ADX={adx_val:.2f} | +DI={plus_di:.2f} | -DI={minus_di:.2f} "
f"(阈值={self.cfg.adx_threshold:.1f}, 模式={self.cfg.adx_mode})\n"
f"🎯 动态Floor入场={entry_floor * 100:.3f}% | 止盈={tp_floor * 100:.3f}% | 止损={sl_floor * 100:.3f}%\n"
f"💰 止盈/止损:{tp * 100:.3f}% / {sl * 100:.3f}% (盈亏比:{tp / sl:.2f})\n"
f"🔄 基准刷新:{self.cfg.base_ratio_refresh_sec}s (已过={base_age}s)\n"
f"⚠️ 止损同向加门槛:{'开启' if penalty_active else '关闭'} (方向={self.last_sl_dir})\n"
f"💳 可用余额:{bal:.2f} USDT | 杠杆:{self.cfg.leverage}x\n"
f"⏱️ 持仓限制:{self.cfg.max_hold_sec}s | 冷却:{self.cfg.cooldown_sec_after_exit}s"
)
self.ding(msg)
def action(self):
"""主循环"""
if not self.set_leverage():
self.ding("杠杆设置失败,停止运行", error=True)
return
while True:
now_dt = datetime.datetime.now()
self.pbar.n = now_dt.second
self.pbar.refresh()
# 1. 获取K线数据
klines = self.get_klines_cached()
if not klines or len(klines) < (max(self.cfg.ema_len + 5, 2 * self.cfg.adx_len + 5)):
logger.warning("K线数据不足等待...")
time.sleep(1)
continue
# 2. 计算技术指标
last_k = klines[-1]
closes = [k["close"] for k in klines[-(self.cfg.ema_len + 1):]]
ema_value = self.ema(closes, self.cfg.ema_len)
price = self.get_last_price(fallback_close=float(last_k["close"]))
dev = (price - ema_value) / ema_value if ema_value else 0.0
# 3. 计算波动率相关指标
a = self.atr(klines, self.cfg.atr_len)
atr_ratio = (a / price) if price > 0 else 0.0
base_ratio = self.get_base_ratio_cached(klines)
# 4. 计算动态阈值
entry_dev, tp, sl, vol_scale, entry_floor, tp_floor, sl_floor = self.dynamic_thresholds(
atr_ratio, base_ratio
)
# 5. 计算 ADX新增
adx_val, plus_di, minus_di = self.adx(klines, self.cfg.adx_len)
logger.info(f"ADX: {adx_val:.2f} (+DI={plus_di:.2f}, -DI={minus_di:.2f})")
# 6. 风控检查
self.risk_kill_switch()
# 7. 获取持仓状态
if not self.get_position_status():
time.sleep(1)
continue
# 8. 检查交易是否启用
if not self.trading_enabled:
if self.pos != 0:
self.close_position_all()
logger.warning("交易被禁用(风控触发),等待...")
time.sleep(5)
continue
# 9. 检查危险市场
if self.is_danger_market(klines, price):
logger.warning("危险模式:高波动/大实体K暂停开仓")
self.maybe_exit(price, tp, sl, vol_scale)
time.sleep(self.cfg.tick_refresh_sec)
continue
# 10. 执行交易逻辑
self.maybe_exit(price, tp, sl, vol_scale)
self.maybe_enter(price, ema_value, entry_dev, adx_val, plus_di, minus_di)
# 11. 状态通知
bal = self.get_assets_available()
self.notify_status_throttled(
price, ema_value, dev, bal,
atr_ratio, base_ratio, vol_scale,
entry_dev, tp, sl,
entry_floor, tp_floor, sl_floor,
adx_val, plus_di, minus_di
)
time.sleep(self.cfg.tick_refresh_sec)
if __name__ == "__main__":
"""
Windows PowerShell:
setx BITMART_API_KEY "你的key"
setx BITMART_SECRET_KEY "你的secret"
setx BITMART_MEMO "合约交易"
重新打开终端再运行。
Linux/macOS:
export BITMART_API_KEY="你的key"
export BITMART_SECRET_KEY="你的secret"
export BITMART_MEMO "合约交易"
"""
cfg = StrategyConfig()
bot = BitmartFuturesMeanReversionBot(cfg)
logger.remove()
logger.add(lambda msg: tqdm.write(msg, end=""), level="INFO")
try:
bot.action()
except KeyboardInterrupt:
logger.info("程序被用户中断")
bot.ding("🤖 策略已手动停止")
except Exception as e:
logger.error(f"程序异常退出: {e}")
bot.ding(f"❌ 策略异常退出: {e}", error=True)
raise

View File

@@ -1,212 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Stock Details</title>
<style>
:root {
--gap-size: 32px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Trebuchet MS', Roboto,
Ubuntu, sans-serif;
color: #000;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
align-items: center;
background: #fff;
}
header,
footer {
display: flex;
width: 100%;
align-items: center;
background: rgba(0, 0, 0, 0.05);
gap: 12px;
}
header {
justify-content: space-between;
padding: 0 var(--gap-size);
gap: calc(var(--gap-size) * 2);
box-shadow: rgba(0, 0, 0, 0.05) 0 2px 6px 0;
flex-direction: row;
}
header #site-logo {
font-weight: 600;
font-size: 32px;
padding: 16px;
background: var(
--18-promo-gradient-02,
linear-gradient(90deg, #00bce5 0%, #2962ff 100%)
);
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
background-clip: text;
}
header input[type='search'] {
padding: 10px;
width: 100%;
height: 32px;
max-width: 400px;
border: 1px solid #ccc;
border-radius: 20px;
}
footer {
flex-direction: column;
padding: calc(var(--gap-size) * 0.5) var(--gap-size);
margin-top: var(--gap-size);
border-top: solid 2px rgba(0, 0, 0, 0.1);
justify-content: center;
}
footer p,
#powered-by-tv p {
margin: 0;
font-size: 12px;
color: rgba(0, 0, 0, 0.6);
}
main {
display: grid;
width: 100%;
padding: 0 calc(var(--gap-size) * 0.5);
max-width: 960px;
grid-template-columns: 1fr 1fr;
grid-gap: var(--gap-size);
}
.span-full-grid,
#symbol-info,
#advanced-chart,
#company-profile,
#fundamental-data {
grid-column: span 2;
}
.span-one-column,
#technical-analysis,
#top-stories,
#powered-by-tv {
grid-column: span 1;
}
.skeleton,
#ticker-tape,
#symbol-info,
#advanced-chart,
#company-profile,
#fundamental-data,
#technical-analysis,
#top-stories,
#ticker-tape {
text-align: center;
padding: 16px;
font-size: 24px;
background: rgba(0, 0, 0, 0.075);
border-radius: 4px;
}
#ticker-tape {
width: 100%;
margin-bottom: var(--gap-size);
height: 75px;
}
#symbol-info {
height: 175px;
}
#advanced-chart {
height: 500px;
}
#company-profile {
height:390px;
}
#fundamental-data {
height: 490px;
}
#technical-analysis,
#top-stories {
height: 425px;
}
#powered-by-tv {
display: flex;
background: #f8f9fd;
border: solid 1px #e0e3eb;
text-align: justify;
flex-direction: column;
gap: 8px;
font-size: 14px;
padding: 16px;
border-radius: 6px;
}
#powered-by-tv a, #powered-by-tv a:visited {
color: #2962ff;
}
@media (max-width: 800px) {
main > section,
.span-full-grid,
#technical-analysis,
#top-stories,
#powered-by-tv {
grid-column: span 2;
}
}
</style>
</head>
<body>
<header>
<a id="site-logo" href="#">TradingVista</a>
<input type="search" placeholder="Search..." />
</header>
<nav id="ticker-tape">Ticker Tape</nav>
<main>
<section id="symbol-info">Symbol Info</section>
<section id="advanced-chart">Advanced Chart</section>
<section id="company-profile">Company Profile</section>
<section id="fundamental-data">Fundamental Data</section>
<section id="technical-analysis">Technical Analysis</section>
<section id="top-stories">Top Stories</section>
<section id="powered-by-tv">
<svg xmlns="http://www.w3.org/2000/svg" width="157" height="21">
<use href="/widget-docs/tradingview-logo.svg#tradingview-logo"></use>
</svg>
<p>
Charts and financial information provided by TradingView, a popular
charting & trading platform. Check out even more
<a href="https://www.tradingview.com/features/">advanced features</a>
or <a href="https://www.tradingview.com/widget/">grab charts</a> for
your website.
</p>
</section>
</main>
<footer>
<p>
This example page is part of a tutorial for integrating TradingView
widgets into your website.
</p>
<p><a href="https://www.tradingview.com/widget-docs/tutorials/build-page/#build-a-page">View the tutorial</a></p>
</footer>
</body>
<script></script>
</html>

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -0,0 +1,293 @@
"""
WEEX 三分之一策略 — 5分钟K线交易
基于 weex/框架.py策略逻辑与 bitmart/三分之一策略-5分钟交易.py 一致。
策略规则:
1. 触发价前一根有效K线实体>=0.1):做多=收盘+实体/3做空=收盘-实体/3
2. 信号当前5分钟K线最高>=做多触发→多;最低<=做空触发→空;同根都触发用开盘价距离判断先后
3. 反手一:持空且当前涨到上根最高且上根上影线>0.01%→反手多;持多且当前跌到上根最低且上根下影线>0.01%→反手空
4. 反手二:持多且上根上影线>0.01%且当前跌到上根开盘→反手空;持空且上根下影线>0.01%且当前涨到上根开盘→反手多
5. 同一根5分钟K线内只交易一次
"""
import random
import sys
import time
import datetime
from pathlib import Path
from typing import Optional, Dict, List, Tuple
from tqdm import tqdm
from loguru import logger
# 保证可导入同目录下的 框架
_weex_dir = Path(__file__).resolve().parent
if str(_weex_dir) not in sys.path:
sys.path.insert(0, str(_weex_dir))
from 框架 import Config, WeexFuturesTransaction
# 5 分钟 K 线类型(若 WEEX 接口名不同可改为实际值)
KLINE_TYPE_5M = "MINUTE_5"
class WeexOneThirdStrategy(WeexFuturesTransaction):
"""WEEX 三分之一策略5分钟K线继承 weex/框架.py"""
def __init__(self, tge_id):
super().__init__(tge_id)
self.pbar = tqdm(total=5, desc="等待5分钟K线", ncols=80)
self.min_body_size = 0.1
self.min_shadow_pct = 0.01
self.check_interval = 5
self.position_ratio = 100 # 开仓金额 = 余额 / position_ratio
self.last_trigger_kline_id: Optional[int] = None
self.last_trigger_direction: Optional[str] = None
self.last_trade_kline_id: Optional[int] = None
# ------------------------- 5分钟K线 -------------------------
def get_klines_5m(self) -> Optional[List[Dict]]:
"""获取 5 分钟 K 线"""
return self.get_klines(kline_type=KLINE_TYPE_5M, limit=100)
# ------------------------- 三分之一策略核心 -------------------------
def get_body_size(self, candle: Dict) -> float:
return abs(float(candle["open"]) - float(candle["close"]))
def find_valid_prev_bar(self, all_data: List[Dict], current_idx: int) -> Tuple[Optional[int], Optional[Dict]]:
if current_idx <= 0:
return None, None
for i in range(current_idx - 1, -1, -1):
prev = all_data[i]
if self.get_body_size(prev) >= self.min_body_size:
return i, prev
return None, None
def get_one_third_levels(self, prev: Dict) -> Tuple[Optional[float], Optional[float]]:
p_open, p_close = float(prev["open"]), float(prev["close"])
body = abs(p_open - p_close)
if body < 0.001:
return None, None
return p_close + body / 3, p_close - body / 3
def get_upper_shadow(self, candle: Dict) -> float:
o, c, h = float(candle["open"]), float(candle["close"]), float(candle["high"])
return h - max(o, c)
def get_lower_shadow(self, candle: Dict) -> float:
o, c, l = float(candle["open"]), float(candle["close"]), float(candle["low"])
return min(o, c) - l
def upper_shadow_pct(self, candle: Dict) -> float:
o = float(candle["open"])
return (self.get_upper_shadow(candle) / o * 100) if o > 0 else 0.0
def lower_shadow_pct(self, candle: Dict) -> float:
o = float(candle["open"])
return (self.get_lower_shadow(candle) / o * 100) if o > 0 else 0.0
def check_reverse_by_prev_high_low(self, kline_data: List[Dict]) -> Tuple[Optional[str], Optional[Dict]]:
if len(kline_data) < 2:
return None, None
curr, prev = kline_data[-1], kline_data[-2]
curr_high = float(curr["high"])
curr_low = float(curr["low"])
prev_high = float(prev["high"])
prev_low = float(prev["low"])
if self.start == -1 and curr_high >= prev_high and self.upper_shadow_pct(prev) > self.min_shadow_pct:
return "long", prev
if self.start == 1 and curr_low <= prev_low and self.lower_shadow_pct(prev) > self.min_shadow_pct:
return "short", prev
return None, None
def check_reverse_by_prev_open(self, kline_data: List[Dict]) -> Tuple[Optional[str], Optional[Dict]]:
if len(kline_data) < 2:
return None, None
curr, prev = kline_data[-1], kline_data[-2]
curr_high = float(curr["high"])
curr_low = float(curr["low"])
prev_open = float(prev["open"])
if self.start == 1 and self.upper_shadow_pct(prev) > self.min_shadow_pct and curr_low <= prev_open:
return "short", prev
if self.start == -1 and self.lower_shadow_pct(prev) > self.min_shadow_pct and curr_high >= prev_open:
return "long", prev
return None, None
def check_realtime_trigger(
self, kline_data: List[Dict]
) -> Tuple[Optional[str], Optional[float], Optional[Dict], Optional[Dict]]:
if len(kline_data) < 2:
return None, None, None, None
curr = kline_data[-1]
curr_kline_id = curr["id"]
curr_high = float(curr["high"])
curr_low = float(curr["low"])
curr_open = float(curr["open"])
valid_prev_idx, prev = self.find_valid_prev_bar(kline_data, len(kline_data) - 1)
if prev is None:
return None, None, None, None
long_trigger, short_trigger = self.get_one_third_levels(prev)
if long_trigger is None:
return None, None, None, None
long_triggered = curr_high >= long_trigger
short_triggered = curr_low <= short_trigger
both_triggered = long_triggered and short_triggered
direction = None
trigger_price = None
if both_triggered:
dist_to_long = abs(long_trigger - curr_open)
dist_to_short = abs(short_trigger - curr_open)
if dist_to_short <= dist_to_long:
direction, trigger_price = "short", short_trigger
else:
direction, trigger_price = "long", long_trigger
elif short_triggered:
direction, trigger_price = "short", short_trigger
elif long_triggered:
direction, trigger_price = "long", long_trigger
if direction is None:
return None, None, None, None
if self.last_trigger_kline_id == curr_kline_id and self.last_trigger_direction == direction:
return None, None, None, None
return direction, trigger_price, prev, curr
# ------------------------- 主循环 -------------------------
def action(self) -> None:
n = 0
while True:
for i in range(3):
if self.openBrowser():
break
else:
self.ding("打开 TGE 失败!", error=True)
continue
logger.info("TGE 浏览器已打开")
self.close_extra_tabs()
self.page.get(url=Config.TRADING_URL)
time.sleep(self.check_interval)
if n == 0 or random.randint(1,11)> 6:
n = 1
if not self._get_token():
self.ding("获取 token 失败", error=True)
return
self.click_safe('x:(//button[normalize-space(text()) = "市价"])')
logger.info("WEEX 三分之一策略5分钟K线开始监测")
try:
kline_data = self.get_klines_5m()
if not kline_data or len(kline_data) < 3:
logger.warning("K线数据不足等待重试...")
time.sleep(self.check_interval)
continue
curr = kline_data[-1]
curr_kline_id = curr["id"]
curr_time_str = datetime.datetime.fromtimestamp(curr["id"] / 1000).strftime("%H:%M:%S")
if not self.get_position_status():
logger.warning("获取仓位失败,使用缓存")
# 反手一:涨到上根最高/跌到上根最低 + 影线>0.01%
rev_dir, rev_prev = self.check_reverse_by_prev_high_low(kline_data)
rev_type = ""
if not rev_dir:
rev_dir, rev_prev = self.check_reverse_by_prev_open(kline_data)
rev_type = ""
if rev_dir and self.last_trade_kline_id != curr_kline_id:
balance = self.get_available_balance()
amount = int((balance or 0) / self.position_ratio)
if amount > 0:
self.ding(f"反手信号{rev_type} {rev_dir} 金额={amount}")
if rev_dir == "long":
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=1, size=amount)
else:
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=-1, size=amount)
self.last_trade_kline_id = curr_kline_id
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = rev_dir
time.sleep(self.check_interval)
continue
# 主信号:三分之一触发
direction, trigger_price, valid_prev, curr_kline = self.check_realtime_trigger(kline_data)
if direction:
if self.last_trade_kline_id == curr_kline_id:
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
time.sleep(self.check_interval)
continue
if (direction == "long" and self.start == 1) or (direction == "short" and self.start == -1):
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
time.sleep(self.check_interval)
continue
balance = self.get_available_balance()
amount = int((balance or 0) / self.position_ratio)
if amount <= 0:
time.sleep(self.check_interval)
continue
executed = False
if direction == "long":
if self.start == -1:
self.ding("平空反手开多")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=1, size=amount)
executed = True
elif self.start == 0:
self.ding("无仓位开多")
self.开单(marketPriceLongOrder=1, size=amount)
executed = True
elif direction == "short":
if self.start == 1:
self.ding("平多反手开空")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=-1, size=amount)
executed = True
elif self.start == 0:
self.ding("无仓位开空")
self.开单(marketPriceLongOrder=-1, size=amount)
executed = True
if executed:
self.last_trade_kline_id = curr_kline_id
self.get_position_status()
self.ding(f"三分之一信号 {direction} 触发价={trigger_price:.2f} 金额={amount}")
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
else:
logger.debug(f"[{curr_time_str}] O={curr['open']:.2f} H={curr['high']:.2f} L={curr['low']:.2f}")
time.sleep(self.check_interval)
if random.randint(1, 11) > 7:
self.page.close()
time.sleep(5)
except KeyboardInterrupt:
logger.info("用户中断")
break
except Exception as e:
logger.error(f"主循环异常: {e}")
self.ding(f"运行异常: {e}", error=True)
time.sleep(self.check_interval)
if __name__ == "__main__":
WeexOneThirdStrategy(tge_id="86837a981aba4576be6916a0ef6ad785").action()

View File

@@ -1,398 +0,0 @@
"""
量化交易回测系统 - 优化版
功能:基于包住形态的交易信号识别和回测分析
作者:量化交易团队
版本2.0
"""
import datetime
from typing import List, Dict, Tuple, Optional, Any
from dataclasses import dataclass
from loguru import logger
from peewee import fn
from models.weex import Weex15, Weex1
# ===============================================================
# 📊 配置管理类
# ===============================================================
@dataclass
class BacktestConfig:
"""回测配置类"""
# 交易参数
take_profit: float = 8.0 # 止盈点数
stop_loss: float = -1.0 # 止损点数
contract_size: float = 10000 # 合约规模
open_fee: float = 5.0 # 开仓手续费
close_fee_rate: float = 0.0005 # 平仓手续费率
# 回测日期范围
start_date: str = "2025-7-1"
end_date: str = "2025-7-31"
# 信号参数
enable_bear_bull_engulf: bool = True # 涨包跌信号
enable_bull_bear_engulf: bool = True # 跌包涨信号
def __post_init__(self):
"""验证配置参数"""
if self.take_profit <= 0:
raise ValueError("止盈点数必须大于0")
if self.stop_loss >= 0:
raise ValueError("止损点数必须小于0")
@dataclass
class TradeRecord:
"""交易记录类"""
entry_time: datetime.datetime
exit_time: datetime.datetime
signal_type: str
direction: str
entry_price: float
exit_price: float
profit_loss: float
profit_amount: float
total_fee: float
net_profit: float
@dataclass
class SignalStats:
"""信号统计类"""
signal_name: str
count: int = 0
wins: int = 0
total_profit: float = 0.0
@property
def win_rate(self) -> float:
"""胜率计算"""
return (self.wins / self.count * 100) if self.count > 0 else 0.0
@property
def avg_profit(self) -> float:
"""平均盈利"""
return self.total_profit / self.count if self.count > 0 else 0.0
# ===============================================================
# 📊 数据获取模块
# ===============================================================
def get_data_by_date(model, date_str):
"""按天获取指定表的数据"""
try:
target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
except ValueError:
logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。")
return []
start_ts = int(target_date.timestamp() * 1000)
end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1
query = (model
.select()
.where(model.id.between(start_ts, end_ts))
.order_by(model.id.asc()))
return [
{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close}
for i in query
]
def get_future_data_1min(start_ts, end_ts):
"""获取指定时间范围内的 1 分钟数据"""
query = (Weex1
.select()
.where(Weex1.id.between(start_ts, end_ts))
.order_by(Weex1.id.asc()))
return [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query]
# ===============================================================
# 📈 信号判定模块
# ===============================================================
def is_bullish(c): return float(c['open']) < float(c['close'])
def is_bearish(c): return float(c['open']) > float(c['close'])
def check_signal(prev, curr):
"""判断是否出现包住形态"""
p_open, p_close = float(prev['open']), float(prev['close'])
c_open, c_close = float(curr['open']), float(curr['close'])
# 前跌后涨包住 -> 做多
if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open:
return "long", "bear_bull_engulf"
# 前涨后跌包住 -> 做空
if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open:
return "short", "bull_bear_engulf"
return None, None
# ===============================================================
# 💹 回测模拟模块(使用 1 分钟数据)
# ===============================================================
# ---------- 替换后的 simulate_trade ----------
def simulate_trade(direction, entry_price, entry_time, next_15min_time, tp=8, sl=-1):
"""
返回 (exit_price, profit_diff, exit_time, exit_reason)
exit_reason: 'tp' (触及止盈并以tp价平仓),
'sl' (触及止损并以sl价平仓),
'open_tp' (开盘跳空并以开盘价止盈),
'open_sl' (开盘跳空并以开盘价止损),
'timeout' (到分析窗口末尾,用最后一根收盘价平仓)
注意sl 参数为负数(你的设定),但在计算止损价时已处理方向
"""
future_candles = get_future_data_1min(entry_time, next_15min_time)
if not future_candles:
return None, 0.0, None, None
# 计算目标价位(数值)
tp_price = entry_price + tp if direction == "long" else entry_price - tp
sl_price = entry_price + sl if direction == "long" else entry_price - sl # sl 为负数long 情况为 entry + (负数) -> 小于 entry
for candle in future_candles:
open_p = float(candle['open'])
high = float(candle['high'])
low = float(candle['low'])
ts = candle['id']
if direction == "long":
# 开盘跳空(以开盘价直接触及止盈/止损)
if open_p >= tp_price:
return open_p, open_p - entry_price, ts, 'open_tp'
if open_p <= sl_price:
return open_p, open_p - entry_price, ts, 'open_sl'
# 盘中触及
if high >= tp_price:
return tp_price, tp, ts, 'tp'
if low <= sl_price:
return sl_price, sl, ts, 'sl'
else: # short
if open_p <= tp_price:
return open_p, entry_price - open_p, ts, 'open_tp'
if open_p >= sl_price:
return open_p, entry_price - open_p, ts, 'open_sl'
if low <= tp_price:
return tp_price, tp, ts, 'tp'
if high >= sl_price:
return sl_price, sl, ts, 'sl'
# 未触发止盈止损,用最后一根收盘价平仓(视为 timeout
final = future_candles[-1]
final_price = float(final['close'])
diff = (final_price - entry_price) if direction == "long" else (entry_price - final_price)
return final_price, diff, final['id'], 'timeout'
# ---------- 替换后的 backtest_single_position ----------
def backtest_single_position(dates, tp, sl):
"""
单笔持仓回测增强版加入连续3次止损触发反向开仓转向单逻辑
- 只有当 exit_reason 属于 'sl''open_sl' 时才算“真实止损”
- 当连续真实止损计数达到 3 时,**下一笔**信号反向开仓(且该转向单不计入连续止损统计)
"""
all_data = []
for date_str in dates:
all_data.extend(get_data_by_date(Weex15, date_str))
all_data.sort(key=lambda x: x['id'])
stats = {
"bear_bull_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "涨包跌"},
"bull_bear_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "跌包涨"},
}
trades = []
current_position = None # 当前持仓信息 dict or None
consec_sl_count = 0 # 连续真实止损计数(只有 exit_reason 为 'sl' 或 'open_sl' 时 +1
reverse_next_signal = False # 是否需要将下一笔信号取反由连续3次止损触发
ignore_next_result = False # 标记下一笔成交的结果是否要被忽略(用于转向单:转向单不计入连续止损计数,也不影响计数)
for idx in range(1, len(all_data) - 1):
prev, curr = all_data[idx - 1], all_data[idx]
entry_candle = all_data[idx + 1]
# 原始信号判定
direction, signal = check_signal(prev, curr)
if not direction:
continue
# 如果需要反向下一笔信号(由之前三次止损触发),则翻转 direction 并标记为转向单(只对这一次有效)
is_reversal_trade = False
if reverse_next_signal:
direction = 'long' if direction == 'short' else 'short'
is_reversal_trade = True
reverse_next_signal = False
ignore_next_result = True # 这笔成交的平仓结果不影响 consec_sl_count
# 下一个 15 分钟K线的时间范围用 idx+50 作为 15min 窗口近似)
next_15min_time = all_data[idx + 50]['id'] if idx + 50 < len(all_data) else all_data[-1]['id']
entry_price = float(entry_candle['open'])
# 如果已有持仓
if current_position:
# 同向信号 -> 跳过(维持现有持仓)
if current_position['direction'] == direction:
continue
# 反向信号 -> 先按当前位置止盈止损平仓,再根据规则决定是否开新仓
else:
exit_price, diff, exit_time, exit_reason = simulate_trade(
current_position['direction'],
current_position['entry_price'],
current_position['entry_time'],
entry_candle['id'],
tp=tp,
sl=sl
)
if exit_price is not None:
trades.append({
"entry_time": datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
"exit_time": datetime.datetime.fromtimestamp(exit_time / 1000),
"signal": current_position['signal'],
"direction": "做多" if current_position['direction'] == "long" else "做空",
"entry": current_position['entry_price'],
"exit": exit_price,
"diff": diff,
"exit_reason": exit_reason,
"is_reversal_trade": current_position.get('is_reversal_trade', False)
})
# 更新统计(只有非转向单会计入统计?按你原逻辑计入)
stats_key = 'bear_bull_engulf' if current_position['signal'] == '涨包跌' else 'bull_bear_engulf'
stats[stats_key]['count'] += 1
stats[stats_key]['total_profit'] += diff
if diff > 0:
stats[stats_key]['wins'] += 1
# 根据 exit_reason 更新 consec_sl_count但如果当时该仓为被标记为 ignore_result则不变
if not current_position.get('ignore_result', False):
if exit_reason in ('sl', 'open_sl'):
consec_sl_count += 1
else:
consec_sl_count = 0
# 如果累计达到 3 次真实止损 -> 标记下一笔反向
if consec_sl_count >= 3:
reverse_next_signal = True
consec_sl_count = 0 # 触发后清零(下一笔为转向单)
else:
# 如果这笔被标记为 ignore通常是前面是转向单则不影响计数
pass
current_position = None # 清空持仓
# 开新仓(注意:如果这笔是转向单,我们之前已经取反了 direction并设置了 is_reversal_trade 和 ignore_next_result
current_position = {
"direction": direction,
"signal": stats[signal]['name'],
"entry_price": entry_price,
"entry_time": entry_candle['id'],
"is_reversal_trade": is_reversal_trade,
"ignore_result": ignore_next_result # 如果为 True则本仓平仓结果不计入 consec_sl_count
}
# 如果我们标记了 ignore_next_result说明这是转向单只在刚开仓后清除标记确保仅忽略这笔的**平仓**结果
if ignore_next_result:
# 清掉,只有这笔仓的平仓结果需要被忽略(记录在 current_position 中),
# 后续在处理平仓时会读取 current_position['ignore_result'] 并决定是否影响计数
ignore_next_result = False
# 最后一笔持仓如果未平仓,用最后收盘价平掉
if current_position:
exit_price, diff, exit_time, exit_reason = simulate_trade(
current_position['direction'],
current_position['entry_price'],
current_position['entry_time'],
all_data[-1]['id'],
tp=tp,
sl=sl
)
if exit_price is not None:
trades.append({
"entry_time": datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
"exit_time": datetime.datetime.fromtimestamp(exit_time / 1000),
"signal": current_position['signal'],
"direction": "做多" if current_position['direction'] == "long" else "做空",
"entry": current_position['entry_price'],
"exit": exit_price,
"diff": diff,
"exit_reason": exit_reason,
"is_reversal_trade": current_position.get('is_reversal_trade', False)
})
stats_key = 'bear_bull_engulf' if current_position['signal'] == '涨包跌' else 'bull_bear_engulf'
stats[stats_key]['count'] += 1
stats[stats_key]['total_profit'] += diff
if diff > 0:
stats[stats_key]['wins'] += 1
# 最后一笔是否计入连续止损计数
if not current_position.get('ignore_result', False):
if exit_reason in ('sl', 'open_sl'):
consec_sl_count += 1
else:
consec_sl_count = 0
if consec_sl_count >= 3:
# 可选择记录或告警,这里仅重置计数
consec_sl_count = 0
return trades, stats
# ===============================================================
# 🚀 启动主流程
# ===============================================================
if __name__ == '__main__':
dates = [f"2025-9-{i}" for i in range(1, 31)]
trades, stats = backtest_single_position(dates, tp=50, sl=-10)
logger.info("===== 每笔交易详情 =====")
for t in trades:
logger.info(
f"{t['entry_time']} {t['direction']}({t['signal']}) "
f"入场={t['entry']:.2f} 出场={t['exit']:.2f} 出场时间={t['exit_time']} "
f"差价={t['diff']:.2f}"
)
total_profit = sum(t['diff'] / t['entry'] * 10000 for t in trades)
total_fee = sum(5 + 10000 / t['entry'] * t['exit'] * 0.0005 for t in trades)
print(f"\n一共交易笔数:{len(trades)}")
print(f"一共盈利:{total_profit:.2f}")
print(f"一共手续费:{total_fee:.2f}")
print(f"净利润:{total_profit - total_fee:.2f}")
print("\n===== 信号统计 =====")
# ===============================================================================================================================
# for i in range(1, 16):
# for i1 in range(1, 51):
# trades, stats = backtest_single_position(dates, tp=i1, sl=-i)
#
# total_profit = sum(t['diff'] / t['entry'] * 10000 for t in trades)
# total_fee = sum(5 + 10000 / t['entry'] * t['exit'] * 0.0005 for t in trades)
#
# if total_profit > total_fee * 0.1:
# print("\n===== 信号统计 =====")
# print(f"止盈:{i1}, 止损:{i}")
# print(f"\n一共交易笔数{len(trades)}")
# print(f"一共盈利:{total_profit:.2f}")
# print(f"一共手续费:{total_fee:.2f}")
# print(f"净利润:{total_profit - total_fee * 0.1}")
# 需要优化,目前有两种情况,第一种,同向,不如说上一单开单是涨,上一单还没有结束,当前信号来了,就不开单,等上一单到了上一单的止损位或者止盈位在平仓
# 第二种,方向,上一单是涨,上一单还没有结束,当前信号来了,是跌,然后就按照现在这个信号要开仓的位置,平掉上一单,然后开一单方向的,
# 一笔中可能有好几次信号,都按照上面的规则去判断,要保证同一时间,只会有一笔持仓,
# 打印每笔的交易详细,如果一笔中同向,输入为一条交易记录

View File

@@ -1,789 +0,0 @@
import re
from datetime import datetime
log_data = """
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 02:00:00号 做空(跌包涨) 入场=4474.69 出场=4476.69 出场时间=1756664100000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 03:15:00号 做空(跌包涨) 入场=4472.09 出场=4474.09 出场时间=1756668600000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 03:45:00号 做多(涨包跌) 入场=4474.15 出场=4472.15 出场时间=1756670400000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 04:00:00号 做空(跌包涨) 入场=4453.24 出场=4455.24 出场时间=1756671300000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 05:45:00号 做多(涨包跌) 入场=4473.88 出场=4471.88 出场时间=1756677600000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 06:45:00号 做空(跌包涨) 入场=4439.92 出场=4441.92 出场时间=1756681200000 差价=-2.00 盈利=-4.50 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 07:15:00号 做空(跌包涨) 入场=4432.11 出场=4402.11 出场时间=1756683000000 差价=30.00 盈利=67.69 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 08:15:00号 做空(跌包涨) 入场=4384.50 出场=4386.50 出场时间=1756686600000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 08:45:00号 做多(涨包跌) 入场=4393.52 出场=4391.52 出场时间=1756688400000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 09:15:00号 做空(跌包涨) 入场=4391.40 出场=4393.40 出场时间=1756690200000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 09:30:00号 做多(涨包跌) 入场=4405.79 出场=4403.79 出场时间=1756692000000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 12:30:00号 做空(跌包涨) 入场=4386.76 出场=4388.76 出场时间=1756702800000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 13:15:00号 做空(跌包涨) 入场=4372.37 出场=4374.37 出场时间=1756704600000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 13:30:00号 做多(涨包跌) 入场=4390.78 出场=4388.78 出场时间=1756706400000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 14:30:00号 做多(涨包跌) 入场=4394.00 出场=4392.00 出场时间=1756710000000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 15:30:00号 做多(涨包跌) 入场=4419.10 出场=4449.10 出场时间=1756712700000 差价=30.00 盈利=67.89 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 18:30:00号 做空(跌包涨) 入场=4429.31 出场=4399.31 出场时间=1756723500000 差价=30.00 盈利=67.73 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 19:15:00号 做空(跌包涨) 入场=4399.49 出场=4401.49 出场时间=1756728000000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 20:45:00号 做空(跌包涨) 入场=4395.36 出场=4397.36 出场时间=1756731600000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 21:45:00号 做空(跌包涨) 入场=4384.90 出场=4386.90 出场时间=1756735200000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 22:15:00号 做多(涨包跌) 入场=4396.00 出场=4394.00 出场时间=1756737000000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 22:45:00号 做空(跌包涨) 入场=4389.51 出场=4391.51 出场时间=1756738800000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 23:15:00号 做空(跌包涨) 入场=4381.89 出场=4351.89 出场时间=1756741500000 差价=30.00 盈利=68.46 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 00:30:00号 做空(跌包涨) 入场=4358.69 出场=4360.69 出场时间=1756745100000 差价=-2.00 盈利=-4.59 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 01:00:00号 做空(跌包涨) 入场=4353.30 出场=4323.30 出场时间=1756746900000 差价=30.00 盈利=68.91 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 02:15:00号 做多(涨包跌) 入场=4337.86 出场=4335.86 出场时间=1756751400000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 03:00:00号 做多(涨包跌) 入场=4345.08 出场=4343.08 出场时间=1756757700000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 03:45:00号 做多(涨包跌) 入场=4363.92 出场=4361.92 出场时间=1756756800000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 04:15:00号 做空(跌包涨) 入场=4358.28 出场=4328.28 出场时间=1756758600000 差价=30.00 盈利=68.83 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 07:00:00号 做多(涨包跌) 入场=4282.53 出场=4312.53 出场时间=1756770300000 差价=30.00 盈利=70.05 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 08:45:00号 做空(跌包涨) 入场=4291.71 出场=4293.71 出场时间=1756774800000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 09:00:00号 做多(涨包跌) 入场=4302.49 出场=4300.49 出场时间=1756775700000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 09:30:00号 做多(涨包跌) 入场=4308.80 出场=4338.80 出场时间=1756777500000 差价=30.00 盈利=69.62 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 11:00:00号 做多(涨包跌) 入场=4359.11 出场=4389.11 出场时间=1756782900000 差价=30.00 盈利=68.82 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 12:00:00号 做空(跌包涨) 入场=4365.21 出场=4367.21 出场时间=1756786500000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 12:15:00号 做多(涨包跌) 入场=4374.91 出场=4372.91 出场时间=1756789200000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 13:15:00号 做空(跌包涨) 入场=4377.72 出场=4379.72 出场时间=1756791000000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 14:45:00号 做多(涨包跌) 入场=4406.35 出场=4404.35 出场时间=1756796400000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 15:15:00号 做空(跌包涨) 入场=4391.65 出场=4393.65 出场时间=1756798200000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 15:45:00号 做空(跌包涨) 入场=4384.00 出场=4386.00 出场时间=1756800900000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 16:30:00号 做多(涨包跌) 入场=4394.20 出场=4392.20 出场时间=1756802700000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 17:00:00号 做空(跌包涨) 入场=4389.98 出场=4391.98 出场时间=1756804500000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 18:15:00号 做空(跌包涨) 入场=4394.30 出场=4364.30 出场时间=1756812600000 差价=30.00 盈利=68.27 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 19:00:00号 做多(涨包跌) 入场=4389.96 出场=4387.96 出场时间=1756811700000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 19:15:00号 做空(跌包涨) 入场=4375.68 出场=4345.68 出场时间=1756813500000 差价=30.00 盈利=68.56 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 20:00:00号 做空(跌包涨) 入场=4346.32 出场=4316.32 出场时间=1756816200000 差价=30.00 盈利=69.02 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 20:45:00号 做空(跌包涨) 入场=4300.58 出场=4302.58 出场时间=1756818900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-03 00:30:00号 做空(跌包涨) 入场=4280.64 出场=4282.64 出场时间=1756831500000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.367 | INFO | __main__:<module>:216 - 2025-09-03 01:15:00号 做空(跌包涨) 入场=4289.63 出场=4291.63 出场时间=1756834200000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 01:30:00号 做多(涨包跌) 入场=4307.71 出场=4305.71 出场时间=1756835100000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 02:00:00号 做多(涨包跌) 入场=4317.18 出场=4315.18 出场时间=1756836900000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 02:15:00号 做空(跌包涨) 入场=4293.70 出场=4295.70 出场时间=1756837800000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 03:00:00号 做多(涨包跌) 入场=4294.57 出场=4292.57 出场时间=1756840500000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 03:15:00号 做空(跌包涨) 入场=4271.11 出场=4273.11 出场时间=1756841400000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 03:45:00号 做多(涨包跌) 入场=4275.15 出场=4273.15 出场时间=1756843200000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 04:15:00号 做多(涨包跌) 入场=4294.16 出场=4324.16 出场时间=1756845000000 差价=30.00 盈利=69.86 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 05:15:00号 做多(涨包跌) 入场=4321.16 出场=4319.16 出场时间=1756848600000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 05:30:00号 做空(跌包涨) 入场=4308.71 出场=4310.71 出场时间=1756849500000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 05:45:00号 做多(涨包跌) 入场=4326.63 出场=4324.63 出场时间=1756850400000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 06:15:00号 做空(跌包涨) 入场=4323.50 出场=4325.50 出场时间=1756852200000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 06:45:00号 做多(涨包跌) 入场=4325.63 出场=4323.63 出场时间=1756854000000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 07:30:00号 做空(跌包涨) 入场=4318.13 出场=4320.13 出场时间=1756856700000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 08:00:00号 做多(涨包跌) 入场=4324.58 出场=4322.58 出场时间=1756858500000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 08:30:00号 做多(涨包跌) 入场=4325.28 出场=4323.28 出场时间=1756860300000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 08:45:00号 做空(跌包涨) 入场=4315.84 出场=4285.84 出场时间=1756862100000 差价=30.00 盈利=69.51 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 10:30:00号 做多(涨包跌) 入场=4351.50 出场=4349.50 出场时间=1756867500000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 12:00:00号 做多(涨包跌) 入场=4332.54 出场=4330.54 出场时间=1756872900000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 12:15:00号 做空(跌包涨) 入场=4318.84 出场=4320.84 出场时间=1756873800000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 13:15:00号 做空(跌包涨) 入场=4332.97 出场=4302.97 出场时间=1756879200000 差价=30.00 盈利=69.24 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 14:30:00号 做多(涨包跌) 入场=4314.99 出场=4312.99 出场时间=1756881900000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 15:45:00号 做多(涨包跌) 入场=4309.16 出场=4307.16 出场时间=1756886400000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 16:15:00号 做多(涨包跌) 入场=4321.12 出场=4319.12 出场时间=1756888200000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 16:45:00号 做多(涨包跌) 入场=4323.65 出场=4321.65 出场时间=1756890000000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 17:00:00号 做空(跌包涨) 入场=4316.15 出场=4318.15 出场时间=1756890900000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 17:30:00号 做多(涨包跌) 入场=4318.40 出场=4348.40 出场时间=1756892700000 差价=30.00 盈利=69.47 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 19:00:00号 做多(涨包跌) 入场=4369.61 出场=4367.61 出场时间=1756898100000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 19:45:00号 做多(涨包跌) 入场=4380.09 出场=4378.09 出场时间=1756900800000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 20:00:00号 做空(跌包涨) 入场=4369.58 出场=4371.58 出场时间=1756902600000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 20:45:00号 做空(跌包涨) 入场=4349.99 出场=4351.99 出场时间=1756904400000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 21:45:00号 做多(涨包跌) 入场=4417.77 出场=4447.77 出场时间=1756908000000 差价=30.00 盈利=67.91 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 23:45:00号 做多(涨包跌) 入场=4469.03 出场=4467.03 出场时间=1756915200000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-04 01:00:00号 做多(涨包跌) 入场=4464.29 出场=4462.29 出场时间=1756923300000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-04 02:30:00号 做空(跌包涨) 入场=4467.09 出场=4469.09 出场时间=1756928700000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-04 03:45:00号 做多(涨包跌) 入场=4463.71 出场=4461.71 出场时间=1756931400000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-04 05:15:00号 做多(涨包跌) 入场=4465.31 出场=4463.31 出场时间=1756935000000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-04 05:45:00号 做空(跌包涨) 入场=4454.44 出场=4456.44 出场时间=1756936800000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-04 07:15:00号 做空(跌包涨) 入场=4458.63 出场=4460.63 出场时间=1756942200000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 07:45:00号 做空(跌包涨) 入场=4446.35 出场=4448.35 出场时间=1756944000000 差价=-2.00 盈利=-4.50 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 09:15:00号 做空(跌包涨) 入场=4453.05 出场=4455.05 出场时间=1756949400000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 10:15:00号 做空(跌包涨) 入场=4458.70 出场=4428.70 出场时间=1756953000000 差价=30.00 盈利=67.28 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 11:45:00号 做空(跌包涨) 入场=4396.51 出场=4398.51 出场时间=1756958400000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 12:15:00号 做多(涨包跌) 入场=4401.01 出场=4399.01 出场时间=1756960200000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 12:45:00号 做多(涨包跌) 入场=4403.00 出场=4401.00 出场时间=1756962000000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 13:00:00号 做空(跌包涨) 入场=4389.87 出场=4359.87 出场时间=1756966500000 差价=30.00 盈利=68.34 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 14:00:00号 做多(涨包跌) 入场=4372.82 出场=4370.82 出场时间=1756966500000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 14:30:00号 做空(跌包涨) 入场=4366.72 出场=4368.72 出场时间=1756969200000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 16:00:00号 做多(涨包跌) 入场=4368.80 出场=4366.80 出场时间=1756975500000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 16:45:00号 做空(跌包涨) 入场=4373.25 出场=4375.25 出场时间=1756976400000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 17:15:00号 做多(涨包跌) 入场=4380.98 出场=4378.98 出场时间=1756978200000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 17:45:00号 做多(涨包跌) 入场=4384.86 出场=4414.86 出场时间=1756980900000 差价=30.00 盈利=68.42 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 18:45:00号 做多(涨包跌) 入场=4419.81 出场=4417.81 出场时间=1756983600000 差价=-2.00 盈利=-4.53 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 19:00:00号 做空(跌包涨) 入场=4405.14 出场=4407.14 出场时间=1756984500000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 19:15:00号 做多(涨包跌) 入场=4423.54 出场=4421.54 出场时间=1756985400000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-04 20:00:00号 做空(跌包涨) 入场=4404.40 出场=4406.40 出场时间=1756988100000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-04 21:00:00号 做多(涨包跌) 入场=4414.04 出场=4412.04 出场时间=1756991700000 差价=-2.00 盈利=-4.53 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-04 21:45:00号 做空(跌包涨) 入场=4381.48 出场=4351.48 出场时间=1756994400000 差价=30.00 盈利=68.47 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-04 23:00:00号 做空(跌包涨) 入场=4339.69 出场=4309.69 出场时间=1756998900000 差价=30.00 盈利=69.13 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 00:15:00号 做多(涨包跌) 入场=4306.10 出场=4304.10 出场时间=1757003400000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 00:30:00号 做空(跌包涨) 入场=4287.51 出场=4289.51 出场时间=1757004300000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 01:15:00号 做多(涨包跌) 入场=4305.80 出场=4303.80 出场时间=1757007000000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 01:45:00号 做空(跌包涨) 入场=4301.01 出场=4303.01 出场时间=1757008800000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 02:30:00号 做空(跌包涨) 入场=4278.68 出场=4280.68 出场时间=1757011500000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 03:00:00号 做空(跌包涨) 入场=4271.51 出场=4273.51 出场时间=1757013300000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 04:15:00号 做多(涨包跌) 入场=4294.31 出场=4324.31 出场时间=1757024100000 差价=30.00 盈利=69.86 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 05:30:00号 做多(涨包跌) 入场=4309.65 出场=4339.65 出场时间=1757025900000 差价=30.00 盈利=69.61 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 06:45:00号 做空(跌包涨) 入场=4315.58 出场=4317.58 出场时间=1757026800000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 07:00:00号 做多(涨包跌) 入场=4339.52 出场=4337.52 出场时间=1757027700000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 09:00:00号 做空(跌包涨) 入场=4298.93 出场=4300.93 出场时间=1757034900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 11:00:00号 做多(涨包跌) 入场=4321.58 出场=4319.58 出场时间=1757042100000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 11:15:00号 做空(跌包涨) 入场=4303.41 出场=4305.41 出场时间=1757043000000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 11:45:00号 做多(涨包跌) 入场=4312.51 出场=4342.51 出场时间=1757055600000 差价=30.00 盈利=69.57 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 13:45:00号 做多(涨包跌) 入场=4336.36 出场=4334.36 出场时间=1757052000000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-05 15:15:00号 做多(涨包跌) 入场=4354.09 出场=4384.09 出场时间=1757057400000 差价=30.00 盈利=68.90 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-05 17:15:00号 做空(跌包涨) 入场=4394.99 出场=4396.99 出场时间=1757064600000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-05 20:00:00号 做空(跌包涨) 入场=4415.56 出场=4417.56 出场时间=1757074500000 差价=-2.00 盈利=-4.53 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-05 21:00:00号 做多(涨包跌) 入场=4469.26 出场=4467.26 出场时间=1757078100000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 00:00:00号 做空(跌包涨) 入场=4280.44 出场=4282.44 出场时间=1757088900000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 00:45:00号 做多(涨包跌) 入场=4297.13 出场=4295.13 出场时间=1757091600000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 02:00:00号 做多(涨包跌) 入场=4287.32 出场=4285.32 出场时间=1757096100000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 02:30:00号 做多(涨包跌) 入场=4295.81 出场=4325.81 出场时间=1757099700000 差价=30.00 盈利=69.84 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 04:00:00号 做多(涨包跌) 入场=4328.97 出场=4326.97 出场时间=1757103300000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 04:45:00号 做多(涨包跌) 入场=4337.01 出场=4335.01 出场时间=1757106000000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 06:00:00号 做空(跌包涨) 入场=4294.51 出场=4296.51 出场时间=1757110500000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 06:45:00号 做多(涨包跌) 入场=4314.65 出场=4312.65 出场时间=1757113200000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 07:45:00号 做空(跌包涨) 入场=4308.19 出场=4310.19 出场时间=1757117700000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 08:30:00号 做多(涨包跌) 入场=4314.27 出场=4312.27 出场时间=1757122200000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 09:30:00号 做空(跌包涨) 入场=4313.82 出场=4315.82 出场时间=1757123100000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 13:00:00号 做多(涨包跌) 入场=4307.45 出场=4305.45 出场时间=1757135700000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 13:30:00号 做空(跌包涨) 入场=4295.99 出场=4297.99 出场时间=1757138400000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 14:15:00号 做多(涨包跌) 入场=4299.28 出场=4297.28 出场时间=1757149200000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 15:15:00号 做多(涨包跌) 入场=4306.50 出场=4304.50 出场时间=1757143800000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 15:45:00号 做多(涨包跌) 入场=4307.61 出场=4305.61 出场时间=1757145600000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 16:15:00号 做空(跌包涨) 入场=4305.07 出场=4307.07 出场时间=1757147400000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 17:45:00号 做多(涨包跌) 入场=4296.51 出场=4294.51 出场时间=1757152800000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 18:00:00号 做空(跌包涨) 入场=4291.09 出场=4293.09 出场时间=1757153700000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 18:45:00号 做多(涨包跌) 入场=4301.16 出场=4299.16 出场时间=1757156400000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 19:45:00号 做空(跌包涨) 入场=4293.71 出场=4295.71 出场时间=1757160000000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 20:00:00号 做多(涨包跌) 入场=4298.08 出场=4296.08 出场时间=1757160900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 20:30:00号 做空(跌包涨) 入场=4297.58 出场=4299.58 出场时间=1757162700000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 21:45:00号 做空(跌包涨) 入场=4291.70 出场=4293.70 出场时间=1757167200000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 23:00:00号 做空(跌包涨) 入场=4294.19 出场=4264.19 出场时间=1757173500000 差价=30.00 盈利=69.86 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 00:30:00号 做空(跌包涨) 入场=4257.59 出场=4259.59 出场时间=1757177100000 差价=-2.00 盈利=-4.70 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 00:45:00号 做多(涨包跌) 入场=4271.27 出场=4269.27 出场时间=1757179800000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 03:00:00号 做多(涨包跌) 入场=4276.85 出场=4274.85 出场时间=1757186100000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 04:15:00号 做多(涨包跌) 入场=4260.10 出场=4290.10 出场时间=1757206800000 差价=30.00 盈利=70.42 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 05:45:00号 做空(跌包涨) 入场=4271.09 出场=4273.09 出场时间=1757196000000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 06:00:00号 做多(涨包跌) 入场=4281.89 出场=4279.89 出场时间=1757196900000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 07:00:00号 做多(涨包跌) 入场=4275.91 出场=4273.91 出场时间=1757200500000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 07:45:00号 做空(跌包涨) 入场=4273.27 出场=4275.27 出场时间=1757203200000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 08:15:00号 做多(涨包跌) 入场=4277.06 出场=4275.06 出场时间=1757205000000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.375 | INFO | __main__:<module>:216 - 2025-09-07 08:45:00号 做多(涨包跌) 入场=4283.66 出场=4281.66 出场时间=1757206800000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 09:15:00号 做多(涨包跌) 入场=4289.62 出场=4287.62 出场时间=1757210400000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 10:30:00号 做多(涨包跌) 入场=4293.75 出场=4291.75 出场时间=1757216700000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 11:00:00号 做多(涨包跌) 入场=4297.65 出场=4295.65 出场时间=1757214900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 11:30:00号 做多(涨包跌) 入场=4300.79 出场=4298.79 出场时间=1757216700000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 13:00:00号 做多(涨包跌) 入场=4299.27 出场=4297.27 出场时间=1757222100000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 13:30:00号 做多(涨包跌) 入场=4300.38 出场=4298.38 出场时间=1757223900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 13:45:00号 做空(跌包涨) 入场=4292.60 出场=4294.60 出场时间=1757230200000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 14:15:00号 做空(跌包涨) 入场=4288.76 出场=4290.76 出场时间=1757226600000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 14:45:00号 做空(跌包涨) 入场=4284.83 出场=4286.83 出场时间=1757229300000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 16:15:00号 做多(涨包跌) 入场=4299.99 出场=4297.99 出场时间=1757235600000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 17:15:00号 做多(涨包跌) 入场=4304.68 出场=4302.68 出场时间=1757237400000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 17:30:00号 做空(跌包涨) 入场=4299.22 出场=4301.22 出场时间=1757239200000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 18:30:00号 做空(跌包涨) 入场=4297.80 出场=4299.80 出场时间=1757241900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 19:30:00号 做空(跌包涨) 入场=4301.86 出场=4303.86 出场时间=1757245500000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 20:15:00号 做空(跌包涨) 入场=4298.00 出场=4300.00 出场时间=1757248200000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 21:15:00号 做空(跌包涨) 入场=4294.46 出场=4296.46 出场时间=1757251800000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 22:45:00号 做多(涨包跌) 入场=4309.11 出场=4307.11 出场时间=1757257200000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 23:00:00号 做空(跌包涨) 入场=4298.01 出场=4300.01 出场时间=1757258100000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 23:30:00号 做多(涨包跌) 入场=4298.19 出场=4296.19 出场时间=1757259900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 00:00:00号 做空(跌包涨) 入场=4297.13 出场=4299.13 出场时间=1757283300000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 01:00:00号 做空(跌包涨) 入场=4281.91 出场=4283.91 出场时间=1757271600000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 01:45:00号 做多(涨包跌) 入场=4281.14 出场=4279.14 出场时间=1757268000000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 03:30:00号 做多(涨包跌) 入场=4279.60 出场=4309.60 出场时间=1757286000000 差价=30.00 盈利=70.10 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 06:00:00号 做空(跌包涨) 入场=4286.10 出场=4288.10 出场时间=1757283300000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 06:15:00号 做多(涨包跌) 入场=4294.90 出场=4292.90 出场时间=1757284200000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 07:00:00号 做多(涨包跌) 入场=4308.01 出场=4306.01 出场时间=1757288700000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 08:30:00号 做多(涨包跌) 入场=4314.79 出场=4312.79 出场时间=1757292300000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 10:15:00号 做空(跌包涨) 入场=4289.77 出场=4291.77 出场时间=1757298600000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 10:45:00号 做多(涨包跌) 入场=4301.19 出场=4299.19 出场时间=1757304000000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 11:30:00号 做多(涨包跌) 入场=4307.14 出场=4305.14 出场时间=1757304000000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 12:45:00号 做空(跌包涨) 入场=4301.22 出场=4303.22 出场时间=1757315700000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 13:45:00号 做空(跌包涨) 入场=4287.64 出场=4289.64 出场时间=1757311200000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 14:30:00号 做多(涨包跌) 入场=4299.95 出场=4297.95 出场时间=1757313900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 15:45:00号 做空(跌包涨) 入场=4293.26 出场=4295.26 出场时间=1757319300000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 17:15:00号 做多(涨包跌) 入场=4315.78 出场=4313.78 出场时间=1757323800000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 17:45:00号 做空(跌包涨) 入场=4310.70 出场=4312.70 出场时间=1757325600000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 19:00:00号 做空(跌包涨) 入场=4327.00 出场=4329.00 出场时间=1757336400000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 20:30:00号 做多(涨包跌) 入场=4313.57 出场=4343.57 出场时间=1757336400000 差价=30.00 盈利=69.55 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 21:15:00号 做多(涨包跌) 入场=4357.36 出场=4355.36 出场时间=1757338200000 差价=-2.00 盈利=-4.59 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 00:45:00号 做空(跌包涨) 入场=4345.02 出场=4315.02 出场时间=1757353500000 差价=30.00 盈利=69.04 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 01:30:00号 做多(涨包跌) 入场=4339.20 出场=4337.20 出场时间=1757353500000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 01:45:00号 做空(跌包涨) 入场=4323.36 出场=4325.36 出场时间=1757355300000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 03:00:00号 做多(涨包跌) 入场=4327.57 出场=4325.57 出场时间=1757358900000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 03:15:00号 做空(跌包涨) 入场=4312.48 出场=4282.48 出场时间=1757359800000 差价=30.00 盈利=69.57 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 06:30:00号 做空(跌包涨) 入场=4316.91 出场=4286.91 出场时间=1757377800000 差价=30.00 盈利=69.49 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 07:30:00号 做空(跌包涨) 入场=4301.76 出场=4303.76 出场时间=1757375100000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 08:00:00号 做多(涨包跌) 入场=4303.99 出场=4301.99 出场时间=1757376900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 08:30:00号 做空(跌包涨) 入场=4298.46 出场=4300.46 出场时间=1757378700000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 09:00:00号 做多(涨包跌) 入场=4299.61 出场=4297.61 出场时间=1757380500000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 09:15:00号 做空(跌包涨) 入场=4296.12 出场=4298.12 出场时间=1757387700000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 10:00:00号 做空(跌包涨) 入场=4284.98 出场=4286.98 出场时间=1757384100000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 12:00:00号 做多(涨包跌) 入场=4304.98 出场=4302.98 出场时间=1757391300000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 12:30:00号 做多(涨包跌) 入场=4309.18 出场=4307.18 出场时间=1757393100000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 13:00:00号 做多(涨包跌) 入场=4311.76 出场=4309.76 出场时间=1757394900000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 13:15:00号 做空(跌包涨) 入场=4304.94 出场=4306.94 出场时间=1757395800000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 17:30:00号 做多(涨包跌) 入场=4364.44 出场=4362.44 出场时间=1757411100000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 18:30:00号 做空(跌包涨) 入场=4344.37 出场=4346.37 出场时间=1757414700000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 18:45:00号 做多(涨包跌) 入场=4357.24 出场=4355.24 出场时间=1757415600000 差价=-2.00 盈利=-4.59 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 20:15:00号 做多(涨包跌) 入场=4354.99 出场=4352.99 出场时间=1757421000000 差价=-2.00 盈利=-4.59 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 20:45:00号 做空(跌包涨) 入场=4346.93 出场=4348.93 出场时间=1757424600000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 23:15:00号 做空(跌包涨) 入场=4289.80 出场=4291.80 出场时间=1757432700000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 01:00:00号 做多(涨包跌) 入场=4286.31 出场=4284.31 出场时间=1757438100000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 01:30:00号 做空(跌包涨) 入场=4282.03 出场=4284.03 出场时间=1757439900000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 02:15:00号 做空(跌包涨) 入场=4283.63 出场=4285.63 出场时间=1757442600000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 02:30:00号 做多(涨包跌) 入场=4288.33 出场=4286.33 出场时间=1757443500000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 02:45:00号 做空(跌包涨) 入场=4280.97 出场=4282.97 出场时间=1757444400000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 04:15:00号 做空(跌包涨) 入场=4285.42 出场=4287.42 出场时间=1757449800000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 05:30:00号 做空(跌包涨) 入场=4297.59 出场=4299.59 出场时间=1757454300000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 06:45:00号 做多(涨包跌) 入场=4313.02 出场=4311.02 出场时间=1757458800000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 07:15:00号 做空(跌包涨) 入场=4310.76 出场=4312.76 出场时间=1757460600000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 07:45:00号 做多(涨包跌) 入场=4313.64 出场=4311.64 出场时间=1757462400000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 08:30:00号 做空(跌包涨) 入场=4296.21 出场=4298.21 出场时间=1757466900000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 09:00:00号 做空(跌包涨) 入场=4284.80 出场=4286.80 出场时间=1757466900000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 10:15:00号 做多(涨包跌) 入场=4311.47 出场=4309.47 出场时间=1757473200000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 11:00:00号 做空(跌包涨) 入场=4315.73 出场=4317.73 出场时间=1757474100000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 11:30:00号 做空(跌包涨) 入场=4308.70 出场=4310.70 出场时间=1757475900000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 13:15:00号 做空(跌包涨) 入场=4308.49 出场=4310.49 出场时间=1757482200000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 13:30:00号 做多(涨包跌) 入场=4312.14 出场=4310.14 出场时间=1757483100000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 14:00:00号 做空(跌包涨) 入场=4306.35 出场=4308.35 出场时间=1757484900000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 14:30:00号 做多(涨包跌) 入场=4308.01 出场=4338.01 出场时间=1757506500000 差价=30.00 盈利=69.64 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 15:15:00号 做多(涨包跌) 入场=4317.26 出场=4315.26 出场时间=1757494800000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 16:30:00号 做空(跌包涨) 入场=4327.00 出场=4329.00 出场时间=1757493900000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 17:15:00号 做空(跌包涨) 入场=4316.58 出场=4318.58 出场时间=1757496600000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 18:30:00号 做多(涨包跌) 入场=4327.20 出场=4325.20 出场时间=1757501100000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 19:00:00号 做空(跌包涨) 入场=4325.23 出场=4327.23 出场时间=1757502900000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 19:15:00号 做多(涨包跌) 入场=4330.73 出场=4328.73 出场时间=1757503800000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 20:00:00号 做多(涨包跌) 入场=4329.56 出场=4359.56 出场时间=1757507400000 差价=30.00 盈利=69.29 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 21:15:00号 做多(涨包跌) 入场=4382.99 出场=4380.99 出场时间=1757511000000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 21:45:00号 做多(涨包跌) 入场=4386.20 出场=4416.20 出场时间=1757512800000 差价=30.00 盈利=68.40 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.381 | INFO | __main__:<module>:216 - 2025-09-10 23:15:00号 做多(涨包跌) 入场=4421.51 出场=4419.51 出场时间=1757518200000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 00:00:00号 做空(跌包涨) 入场=4403.47 出场=4373.47 出场时间=1757520900000 差价=30.00 盈利=68.13 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 01:30:00号 做空(跌包涨) 入场=4346.68 出场=4348.68 出场时间=1757526300000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 05:15:00号 做多(涨包跌) 入场=4337.51 出场=4335.51 出场时间=1757539800000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 05:45:00号 做多(涨包跌) 入场=4346.90 出场=4344.90 出场时间=1757542500000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 06:30:00号 做空(跌包涨) 入场=4344.22 出场=4346.22 出场时间=1757544300000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 07:30:00号 做空(跌包涨) 入场=4342.82 出场=4344.82 出场时间=1757547900000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 08:15:00号 做空(跌包涨) 入场=4336.86 出场=4338.86 出场时间=1757550600000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 09:00:00号 做多(涨包跌) 入场=4357.50 出场=4387.50 出场时间=1757560500000 差价=30.00 盈利=68.85 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 10:15:00号 做多(涨包跌) 入场=4373.00 出场=4371.00 出场时间=1757557800000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 10:45:00号 做多(涨包跌) 入场=4379.99 出场=4377.99 出场时间=1757559600000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 12:00:00号 做多(涨包跌) 入场=4402.00 出场=4400.00 出场时间=1757567700000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 12:30:00号 做多(涨包跌) 入场=4411.97 出场=4409.97 出场时间=1757565900000 差价=-2.00 盈利=-4.53 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 13:00:00号 做空(跌包涨) 入场=4409.99 出场=4411.99 出场时间=1757567700000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 15:30:00号 做空(跌包涨) 入场=4435.47 出场=4437.47 出场时间=1757576700000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 16:45:00号 做多(涨包跌) 入场=4436.04 出场=4434.04 出场时间=1757581200000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 18:00:00号 做多(涨包跌) 入场=4415.02 出场=4445.02 出场时间=1757592000000 差价=30.00 盈利=67.95 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 19:00:00号 做多(涨包跌) 入场=4426.37 出场=4424.37 出场时间=1757590200000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 19:30:00号 做空(跌包涨) 入场=4425.53 出场=4427.53 出场时间=1757591100000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 19:45:00号 做多(涨包跌) 入场=4434.28 出场=4432.28 出场时间=1757592000000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 20:15:00号 做多(涨包跌) 入场=4452.46 出场=4450.46 出场时间=1757593800000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 20:45:00号 做空(跌包涨) 入场=4413.23 出场=4383.23 出场时间=1757595600000 差价=30.00 盈利=67.98 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 21:15:00号 做空(跌包涨) 入场=4390.85 出场=4392.85 出场时间=1757597400000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 22:00:00号 做多(涨包跌) 入场=4434.65 出场=4432.65 出场时间=1757600100000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 22:45:00号 做多(涨包跌) 入场=4428.48 出场=4426.48 出场时间=1757602800000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 00:30:00号 做空(跌包涨) 入场=4409.53 出场=4411.53 出场时间=1757609100000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 01:15:00号 做多(涨包跌) 入场=4428.67 出场=4426.67 出场时间=1757611800000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 01:45:00号 做多(涨包跌) 入场=4434.41 出场=4432.41 出场时间=1757613600000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 03:30:00号 做多(涨包跌) 入场=4421.36 出场=4419.36 出场时间=1757620800000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 05:45:00号 做多(涨包跌) 入场=4421.45 出场=4451.45 出场时间=1757630700000 差价=30.00 盈利=67.85 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 06:30:00号 做多(涨包跌) 入场=4441.44 出场=4471.44 出场时间=1757637000000 差价=30.00 盈利=67.55 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 08:30:00号 做多(涨包跌) 入场=4461.82 出场=4491.82 出场时间=1757637900000 差价=30.00 盈利=67.24 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 12:00:00号 做多(涨包跌) 入场=4503.64 出场=4533.64 出场时间=1757655900000 差价=30.00 盈利=66.61 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 13:15:00号 做空(跌包涨) 入场=4514.86 出场=4516.86 出场时间=1757655000000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 15:15:00号 做多(涨包跌) 入场=4544.41 出场=4542.41 出场时间=1757662200000 差价=-2.00 盈利=-4.40 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 15:30:00号 做空(跌包涨) 入场=4537.01 出场=4507.01 出场时间=1757670300000 差价=30.00 盈利=66.12 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 17:15:00号 做多(涨包跌) 入场=4522.01 出场=4520.01 出场时间=1757669400000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 17:30:00号 做空(跌包涨) 入场=4516.28 出场=4518.28 出场时间=1757670300000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-12 18:00:00号 做空(跌包涨) 入场=4513.69 出场=4515.69 出场时间=1757672100000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-12 18:30:00号 做空(跌包涨) 入场=4509.80 出场=4511.80 出场时间=1757673900000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-12 21:00:00号 做多(涨包跌) 入场=4524.96 出场=4522.96 出场时间=1757682900000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-12 22:00:00号 做多(涨包跌) 入场=4537.98 出场=4567.98 出场时间=1757686500000 差价=30.00 盈利=66.11 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-12 22:45:00号 做空(跌包涨) 入场=4523.25 出场=4525.25 出场时间=1757689200000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-12 23:45:00号 做多(涨包跌) 入场=4539.35 出场=4537.35 出场时间=1757692800000 差价=-2.00 盈利=-4.41 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-13 01:00:00号 做多(涨包跌) 入场=4573.66 出场=4571.66 出场时间=1757697300000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-13 02:30:00号 做多(涨包跌) 入场=4612.59 出场=4610.59 出场时间=1757702700000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-13 03:30:00号 做多(涨包跌) 入场=4627.09 出场=4657.09 出场时间=1757706300000 差价=30.00 盈利=64.84 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-13 04:15:00号 做空(跌包涨) 入场=4640.52 出场=4642.52 出场时间=1757709000000 差价=-2.00 盈利=-4.31 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-13 06:15:00号 做多(涨包跌) 入场=4662.69 出场=4692.69 出场时间=1757716200000 差价=30.00 盈利=64.34 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-13 07:30:00号 做多(涨包跌) 入场=4705.12 出场=4703.12 出场时间=1757720700000 差价=-2.00 盈利=-4.25 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.385 | INFO | __main__:<module>:216 - 2025-09-13 08:00:00号 做多(涨包跌) 入场=4710.83 出场=4708.83 出场时间=1757722500000 差价=-2.00 盈利=-4.25 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 08:45:00号 做多(涨包跌) 入场=4699.24 出场=4729.24 出场时间=1757725200000 差价=30.00 盈利=63.84 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 11:15:00号 做多(涨包跌) 入场=4711.38 出场=4741.38 出场时间=1757734200000 差价=30.00 盈利=63.68 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 12:15:00号 做空(跌包涨) 入场=4736.89 出场=4738.89 出场时间=1757737800000 差价=-2.00 盈利=-4.22 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 12:45:00号 做多(涨包跌) 入场=4745.06 出场=4743.06 出场时间=1757739600000 差价=-2.00 盈利=-4.21 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 14:15:00号 做多(涨包跌) 入场=4726.83 出场=4724.83 出场时间=1757745000000 差价=-2.00 盈利=-4.23 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 14:30:00号 做空(跌包涨) 入场=4713.13 出场=4715.13 出场时间=1757747700000 差价=-2.00 盈利=-4.24 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 15:15:00号 做多(涨包跌) 入场=4712.78 出场=4710.78 出场时间=1757749500000 差价=-2.00 盈利=-4.24 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 16:15:00号 做多(涨包跌) 入场=4716.82 出场=4714.82 出场时间=1757759400000 差价=-2.00 盈利=-4.24 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 16:45:00号 做多(涨包跌) 入场=4722.10 出场=4720.10 出场时间=1757754900000 差价=-2.00 盈利=-4.24 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 18:30:00号 做空(跌包涨) 入场=4718.32 出场=4720.32 出场时间=1757763000000 差价=-2.00 盈利=-4.24 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 21:30:00号 做多(涨包跌) 入场=4722.50 出场=4720.50 出场时间=1757771100000 差价=-2.00 盈利=-4.24 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 21:45:00号 做空(跌包涨) 入场=4710.16 出场=4680.16 出场时间=1757772000000 差价=30.00 盈利=63.69 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 22:30:00号 做多(涨包跌) 入场=4699.16 出场=4697.16 出场时间=1757774700000 差价=-2.00 盈利=-4.26 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 23:30:00号 做空(跌包涨) 入场=4679.37 出场=4649.37 出场时间=1757778300000 差价=30.00 盈利=64.11 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-14 04:00:00号 做空(跌包涨) 入场=4635.56 出场=4637.56 出场时间=1757794500000 差价=-2.00 盈利=-4.31 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-14 04:15:00号 做多(涨包跌) 入场=4655.26 出场=4653.26 出场时间=1757795400000 差价=-2.00 盈利=-4.30 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-14 05:00:00号 做多(涨包跌) 入场=4655.22 出场=4653.22 出场时间=1757801700000 差价=-2.00 盈利=-4.30 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-14 06:00:00号 做多(涨包跌) 入场=4661.08 出场=4659.08 出场时间=1757801700000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 07:00:00号 做多(涨包跌) 入场=4656.48 出场=4654.48 出场时间=1757806200000 差价=-2.00 盈利=-4.30 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 08:00:00号 做多(涨包跌) 入场=4664.77 出场=4662.77 出场时间=1757810700000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 09:15:00号 做空(跌包涨) 入场=4653.35 出场=4655.35 出场时间=1757813400000 差价=-2.00 盈利=-4.30 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 11:00:00号 做多(涨包跌) 入场=4681.64 出场=4679.64 出场时间=1757819700000 差价=-2.00 盈利=-4.27 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 11:15:00号 做空(跌包涨) 入场=4673.93 出场=4643.93 出场时间=1757823300000 差价=30.00 盈利=64.19 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 13:15:00号 做多(涨包跌) 入场=4666.86 出场=4664.86 出场时间=1757829600000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 14:15:00号 做空(跌包涨) 入场=4668.51 出场=4670.51 出场时间=1757841300000 差价=-2.00 盈利=-4.28 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 14:45:00号 做空(跌包涨) 入场=4660.54 出场=4662.54 出场时间=1757833200000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 15:15:00号 做空(跌包涨) 入场=4659.38 出场=4661.38 出场时间=1757835000000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 15:45:00号 做空(跌包涨) 入场=4658.02 出场=4660.02 出场时间=1757838600000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 17:00:00号 做空(跌包涨) 入场=4654.18 出场=4656.18 出场时间=1757841300000 差价=-2.00 盈利=-4.30 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 18:00:00号 做空(跌包涨) 入场=4663.76 出场=4665.76 出场时间=1757844900000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 19:30:00号 做空(跌包涨) 入场=4638.18 出场=4640.18 出场时间=1757852100000 差价=-2.00 盈利=-4.31 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 20:30:00号 做多(涨包跌) 入场=4640.66 出场=4638.66 出场时间=1757853900000 差价=-2.00 盈利=-4.31 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 20:45:00号 做空(跌包涨) 入场=4625.76 出场=4627.76 出场时间=1757854800000 差价=-2.00 盈利=-4.32 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 21:15:00号 做空(跌包涨) 入场=4621.87 出场=4623.87 出场时间=1757856600000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 22:00:00号 做空(跌包涨) 入场=4610.66 出场=4612.66 出场时间=1757859300000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 22:15:00号 做多(涨包跌) 入场=4630.71 出场=4628.71 出场时间=1757860200000 差价=-2.00 盈利=-4.32 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 23:15:00号 做空(跌包涨) 入场=4586.03 出场=4588.03 出场时间=1757863800000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 23:45:00号 做空(跌包涨) 入场=4584.48 出场=4586.48 出场时间=1757865600000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 00:15:00号 做多(涨包跌) 入场=4586.68 出场=4616.68 出场时间=1757870100000 差价=30.00 盈利=65.41 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 01:00:00号 做空(跌包涨) 入场=4595.18 出场=4597.18 出场时间=1757870100000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 03:15:00号 做多(涨包跌) 入场=4609.78 出场=4607.78 出场时间=1757883600000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 04:00:00号 做空(跌包涨) 入场=4613.99 出场=4615.99 出场时间=1757880900000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 04:15:00号 做多(涨包跌) 入场=4624.18 出场=4622.18 出场时间=1757881800000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 05:00:00号 做空(跌包涨) 入场=4614.96 出场=4616.96 出场时间=1757884500000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 05:30:00号 做空(跌包涨) 入场=4613.57 出场=4615.57 出场时间=1757886300000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 05:45:00号 做多(涨包跌) 入场=4633.00 出场=4631.00 出场时间=1757887200000 差价=-2.00 盈利=-4.32 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 08:30:00号 做多(涨包跌) 入场=4613.20 出场=4611.20 出场时间=1757897100000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 09:30:00号 做多(涨包跌) 入场=4601.91 出场=4631.91 出场时间=1757905200000 差价=30.00 盈利=65.19 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 10:30:00号 做空(跌包涨) 入场=4615.91 出场=4617.91 出场时间=1757904300000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 11:15:00号 做多(涨包跌) 入场=4630.48 出场=4628.48 出场时间=1757907000000 差价=-2.00 盈利=-4.32 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 12:00:00号 做多(涨包跌) 入场=4634.46 出场=4664.46 出场时间=1757916000000 差价=30.00 盈利=64.73 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 13:15:00号 做多(涨包跌) 入场=4648.29 出场=4646.29 出场时间=1757917800000 差价=-2.00 盈利=-4.30 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 14:00:00号 做多(涨包跌) 入场=4660.51 出场=4658.51 出场时间=1757916900000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 14:30:00号 做空(跌包涨) 入场=4649.31 出场=4619.31 出场时间=1757918700000 差价=30.00 盈利=64.53 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-15 15:30:00号 做空(跌包涨) 入场=4623.51 出场=4593.51 出场时间=1757922300000 差价=30.00 盈利=64.89 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-15 19:30:00号 做空(跌包涨) 入场=4527.63 出场=4529.63 出场时间=1757936700000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-15 20:30:00号 做空(跌包涨) 入场=4512.65 出场=4514.65 出场时间=1757940300000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-15 21:45:00号 做空(跌包涨) 入场=4495.32 出场=4497.32 出场时间=1757944800000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-15 22:30:00号 做多(涨包跌) 入场=4525.84 出场=4523.84 出场时间=1757947500000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 00:00:00号 做多(涨包跌) 入场=4497.47 出场=4495.47 出场时间=1757952900000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 00:30:00号 做空(跌包涨) 入场=4490.54 出场=4492.54 出场时间=1757954700000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 00:45:00号 做多(涨包跌) 入场=4508.90 出场=4506.90 出场时间=1757955600000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 01:30:00号 做空(跌包涨) 入场=4484.02 出场=4486.02 出场时间=1757958300000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 02:15:00号 做空(跌包涨) 入场=4492.05 出场=4494.05 出场时间=1757961000000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 03:00:00号 做多(涨包跌) 入场=4499.06 出场=4497.06 出场时间=1757963700000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 04:15:00号 做多(涨包跌) 入场=4499.05 出场=4529.05 出场时间=1757985300000 差价=30.00 盈利=66.68 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 05:15:00号 做多(涨包跌) 入场=4508.91 出场=4506.91 出场时间=1757977200000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 06:15:00号 做空(跌包涨) 入场=4519.44 出场=4521.44 出场时间=1757978100000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 07:15:00号 做多(涨包跌) 入场=4517.10 出场=4515.10 出场时间=1757980800000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 08:15:00号 做空(跌包涨) 入场=4514.54 出场=4516.54 出场时间=1757984400000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 10:15:00号 做多(涨包跌) 入场=4525.99 出场=4523.99 出场时间=1757989800000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 14:30:00号 做空(跌包涨) 入场=4514.40 出场=4516.40 出场时间=1758009600000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 15:15:00号 做空(跌包涨) 入场=4503.94 出场=4505.94 出场时间=1758007800000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 15:30:00号 做多(涨包跌) 入场=4508.98 出场=4506.98 出场时间=1758011400000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 16:00:00号 做多(涨包跌) 入场=4510.63 出场=4508.63 出场时间=1758011400000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 18:00:00号 做多(涨包跌) 入场=4509.35 出场=4507.35 出场时间=1758017700000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 19:30:00号 做多(涨包跌) 入场=4498.85 出场=4496.85 出场时间=1758023100000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 20:00:00号 做多(涨包跌) 入场=4499.40 出场=4497.40 出场时间=1758024900000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 20:45:00号 做多(涨包跌) 入场=4499.52 出场=4497.52 出场时间=1758027600000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 21:30:00号 做多(涨包跌) 入场=4506.71 出场=4504.71 出场时间=1758030300000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 21:45:00号 做空(跌包涨) 入场=4452.91 出场=4422.91 出场时间=1758031200000 差价=30.00 盈利=67.37 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 22:15:00号 做空(跌包涨) 入场=4432.50 出场=4434.50 出场时间=1758033000000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 23:15:00号 做空(跌包涨) 入场=4431.53 出场=4433.53 出场时间=1758036600000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-17 00:45:00号 做空(跌包涨) 入场=4456.88 出场=4458.88 出场时间=1758042000000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-17 01:00:00号 做多(涨包跌) 入场=4461.10 出场=4491.10 出场时间=1758042900000 差价=30.00 盈利=67.25 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 02:30:00号 做空(跌包涨) 入场=4481.50 出场=4483.50 出场时间=1758050100000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 05:15:00号 做空(跌包涨) 入场=4490.49 出场=4492.49 出场时间=1758058200000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 06:30:00号 做空(跌包涨) 入场=4505.59 出场=4507.59 出场时间=1758062700000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 06:45:00号 做多(涨包跌) 入场=4517.88 出场=4515.88 出场时间=1758063600000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 08:15:00号 做空(跌包涨) 入场=4495.76 出场=4497.76 出场时间=1758069000000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 08:30:00号 做多(涨包跌) 入场=4509.69 出场=4507.69 出场时间=1758069900000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 09:30:00号 做多(涨包跌) 入场=4514.84 出场=4512.84 出场时间=1758073500000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 09:45:00号 做空(跌包涨) 入场=4504.59 出场=4506.59 出场时间=1758074400000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 10:30:00号 做多(涨包跌) 入场=4514.12 出场=4544.12 出场时间=1758077100000 差价=30.00 盈利=66.46 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 12:30:00号 做空(跌包涨) 入场=4485.88 出场=4487.88 出场时间=1758085200000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 13:15:00号 做多(涨包跌) 入场=4484.36 出场=4482.36 出场时间=1758087000000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 13:45:00号 做多(涨包跌) 入场=4488.67 出场=4518.67 出场时间=1758089700000 差价=30.00 盈利=66.83 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 15:30:00号 做空(跌包涨) 入场=4539.99 出场=4541.99 出场时间=1758095100000 差价=-2.00 盈利=-4.41 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 16:00:00号 做多(涨包跌) 入场=4542.30 出场=4540.30 出场时间=1758096900000 差价=-2.00 盈利=-4.40 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 16:15:00号 做空(跌包涨) 入场=4515.06 出场=4485.06 出场时间=1758104100000 差价=30.00 盈利=66.44 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 17:00:00号 做多(涨包跌) 入场=4509.28 出场=4507.28 出场时间=1758100500000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 17:45:00号 做空(跌包涨) 入场=4501.69 出场=4503.69 出场时间=1758111300000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-17 19:00:00号 做空(跌包涨) 入场=4482.16 出场=4484.16 出场时间=1758107700000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-17 19:15:00号 做多(涨包跌) 入场=4487.54 出场=4485.54 出场时间=1758110400000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-17 20:15:00号 做空(跌包涨) 入场=4488.35 出场=4490.35 出场时间=1758112200000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-17 20:30:00号 做多(涨包跌) 入场=4504.63 出场=4502.63 出场时间=1758113100000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-17 22:30:00号 做空(跌包涨) 入场=4472.54 出场=4474.54 出场时间=1758120300000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-17 23:30:00号 做空(跌包涨) 入场=4480.00 出场=4482.00 出场时间=1758123900000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 01:15:00号 做空(跌包涨) 入场=4479.93 出场=4481.93 出场时间=1758130200000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 02:00:00号 做空(跌包涨) 入场=4436.71 出场=4438.71 出场时间=1758132900000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 02:45:00号 做空(跌包涨) 入场=4440.70 出场=4442.70 出场时间=1758135600000 差价=-2.00 盈利=-4.50 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 04:30:00号 做空(跌包涨) 入场=4512.43 出场=4514.43 出场时间=1758141900000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 05:15:00号 做多(涨包跌) 入场=4515.31 出场=4545.31 出场时间=1758146400000 差价=30.00 盈利=66.44 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 05:45:00号 做多(涨包跌) 入场=4528.32 出场=4526.32 出场时间=1758146400000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 06:15:00号 做多(涨包跌) 入场=4546.07 出场=4576.07 出场时间=1758149100000 差价=30.00 盈利=65.99 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 08:00:00号 做多(涨包跌) 入场=4588.29 出场=4586.29 出场时间=1758156300000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 09:00:00号 做空(跌包涨) 入场=4582.62 出场=4584.62 出场时间=1758158100000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 09:15:00号 做多(涨包跌) 入场=4602.25 出场=4632.25 出场时间=1758164400000 差价=30.00 盈利=65.19 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 12:30:00号 做空(跌包涨) 入场=4605.82 出场=4607.82 出场时间=1758170700000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.393 | INFO | __main__:<module>:216 - 2025-09-18 13:00:00号 做多(涨包跌) 入场=4609.48 出场=4607.48 出场时间=1758172500000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.393 | INFO | __main__:<module>:216 - 2025-09-18 13:15:00号 做空(跌包涨) 入场=4600.42 出场=4570.42 出场时间=1758175200000 差价=30.00 盈利=65.21 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.393 | INFO | __main__:<module>:216 - 2025-09-18 14:15:00号 做空(跌包涨) 入场=4561.37 出场=4563.37 出场时间=1758177000000 差价=-2.00 盈利=-4.38 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 14:45:00号 做多(涨包跌) 入场=4566.29 出场=4596.29 出场时间=1758184200000 差价=30.00 盈利=65.70 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 16:00:00号 做空(跌包涨) 入场=4573.09 出场=4575.09 出场时间=1758183300000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 16:15:00号 做多(涨包跌) 入场=4581.08 出场=4579.08 出场时间=1758190500000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 17:45:00号 做空(跌包涨) 入场=4590.39 出场=4592.39 出场时间=1758189600000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 18:15:00号 做空(跌包涨) 入场=4585.79 出场=4587.79 出场时间=1758202200000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 19:15:00号 做多(涨包跌) 入场=4579.55 出场=4577.55 出场时间=1758195000000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 19:45:00号 做空(跌包涨) 入场=4573.40 出场=4575.40 出场时间=1758196800000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 20:45:00号 做空(跌包涨) 入场=4576.54 出场=4578.54 出场时间=1758200400000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 21:15:00号 做多(涨包跌) 入场=4579.42 出场=4577.42 出场时间=1758202200000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 21:45:00号 做空(跌包涨) 入场=4571.96 出场=4573.96 出场时间=1758204000000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 22:00:00号 做多(涨包跌) 入场=4586.05 出场=4616.05 出场时间=1758204900000 差价=30.00 盈利=65.42 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 22:45:00号 做空(跌包涨) 入场=4598.00 出场=4600.00 出场时间=1758207600000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 00:30:00号 做多(涨包跌) 入场=4613.82 出场=4611.82 出场时间=1758214800000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 02:00:00号 做多(涨包跌) 入场=4607.20 出场=4605.20 出场时间=1758219300000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 03:00:00号 做多(涨包跌) 入场=4616.17 出场=4614.17 出场时间=1758222900000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 03:15:00号 做空(跌包涨) 入场=4604.49 出场=4574.49 出场时间=1758236400000 差价=30.00 盈利=65.15 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 04:00:00号 做空(跌包涨) 入场=4586.07 出场=4588.07 出场时间=1758226500000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 04:15:00号 做多(涨包跌) 入场=4594.26 出场=4592.26 出场时间=1758227400000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 04:45:00号 做多(涨包跌) 入场=4600.84 出场=4598.84 出场时间=1758229200000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 05:15:00号 做空(跌包涨) 入场=4592.22 出场=4594.22 出场时间=1758231000000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 06:00:00号 做空(跌包涨) 入场=4592.68 出场=4594.68 出场时间=1758233700000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 06:30:00号 做多(涨包跌) 入场=4593.16 出场=4591.16 出场时间=1758235500000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 07:00:00号 做空(跌包涨) 入场=4589.04 出场=4591.04 出场时间=1758240000000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 07:45:00号 做多(涨包跌) 入场=4583.92 出场=4613.92 出场时间=1758244500000 差价=30.00 盈利=65.45 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 09:30:00号 做多(涨包跌) 入场=4614.98 出场=4612.98 出场时间=1758246300000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 10:15:00号 做空(跌包涨) 入场=4596.00 出场=4598.00 出场时间=1758249000000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 11:00:00号 做空(跌包涨) 入场=4586.87 出场=4588.87 出场时间=1758251700000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 11:15:00号 做多(涨包跌) 入场=4594.12 出场=4592.12 出场时间=1758252600000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 11:30:00号 做空(跌包涨) 入场=4575.51 出场=4545.51 出场时间=1758253500000 差价=30.00 盈利=65.57 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 14:15:00号 做空(跌包涨) 入场=4531.27 出场=4533.27 出场时间=1758263400000 差价=-2.00 盈利=-4.41 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 14:45:00号 做空(跌包涨) 入场=4531.00 出场=4533.00 出场时间=1758266100000 差价=-2.00 盈利=-4.41 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 16:15:00号 做多(涨包跌) 入场=4540.60 出场=4538.60 出场时间=1758270600000 差价=-2.00 盈利=-4.40 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 17:15:00号 做多(涨包跌) 入场=4539.75 出场=4537.75 出场时间=1758274200000 差价=-2.00 盈利=-4.41 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 17:30:00号 做空(跌包涨) 入场=4529.53 出场=4531.53 出场时间=1758287700000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-19 18:15:00号 做多(涨包跌) 入场=4526.68 出场=4524.68 出场时间=1758277800000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-19 18:45:00号 做多(涨包跌) 入场=4529.15 出场=4527.15 出场时间=1758279600000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-19 20:30:00号 做空(跌包涨) 入场=4511.06 出场=4513.06 出场时间=1758285900000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-19 20:45:00号 做多(涨包跌) 入场=4516.78 出场=4514.78 出场时间=1758288600000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-19 21:15:00号 做多(涨包跌) 入场=4524.99 出场=4522.99 出场时间=1758288600000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-19 22:00:00号 做多(涨包跌) 入场=4525.81 出场=4523.81 出场时间=1758292200000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 00:15:00号 做多(涨包跌) 入场=4480.10 出场=4478.10 出场时间=1758299400000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 01:00:00号 做空(跌包涨) 入场=4478.90 出场=4448.90 出场时间=1758304800000 差价=30.00 盈利=66.98 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 03:00:00号 做空(跌包涨) 入场=4446.67 出场=4448.67 出场时间=1758309300000 差价=-2.00 盈利=-4.50 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 03:15:00号 做多(涨包跌) 入场=4457.43 出场=4455.43 出场时间=1758310200000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 03:45:00号 做空(跌包涨) 入场=4450.00 出场=4452.00 出场时间=1758312000000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 05:00:00号 做空(跌包涨) 入场=4457.40 出场=4459.40 出场时间=1758316500000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 07:45:00号 做多(涨包跌) 入场=4457.59 出场=4455.59 出场时间=1758331800000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 08:30:00号 做空(跌包涨) 入场=4460.41 出场=4462.41 出场时间=1758329100000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 08:45:00号 做多(涨包跌) 入场=4470.38 出场=4468.38 出场时间=1758330000000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 09:15:00号 做空(跌包涨) 入场=4464.23 出场=4466.23 出场时间=1758331800000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 11:45:00号 做多(涨包跌) 入场=4463.37 出场=4461.37 出场时间=1758340800000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 12:30:00号 做空(跌包涨) 入场=4462.81 出场=4464.81 出场时间=1758343500000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 12:45:00号 做多(涨包跌) 入场=4471.24 出场=4469.24 出场时间=1758344400000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 14:00:00号 做多(涨包跌) 入场=4476.31 出场=4474.31 出场时间=1758348900000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 14:15:00号 做空(跌包涨) 入场=4468.99 出场=4470.99 出场时间=1758349800000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 15:30:00号 做空(跌包涨) 入场=4468.61 出场=4470.61 出场时间=1758354300000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 15:45:00号 做多(涨包跌) 入场=4473.80 出场=4471.80 出场时间=1758357900000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 16:45:00号 做多(涨包跌) 入场=4474.98 出场=4472.98 出场时间=1758358800000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 17:00:00号 做空(跌包涨) 入场=4463.04 出场=4465.04 出场时间=1758359700000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-20 17:30:00号 做空(跌包涨) 入场=4463.00 出场=4465.00 出场时间=1758361500000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-20 18:00:00号 做多(涨包跌) 入场=4463.69 出场=4461.69 出场时间=1758365100000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-20 19:15:00号 做多(涨包跌) 入场=4467.67 出场=4465.67 出场时间=1758367800000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-20 21:30:00号 做多(涨包跌) 入场=4467.02 出场=4465.02 出场时间=1758376800000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-20 22:00:00号 做空(跌包涨) 入场=4466.11 出场=4468.11 出场时间=1758378600000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 00:15:00号 做多(涨包跌) 入场=4497.37 出场=4495.37 出场时间=1758385800000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 00:30:00号 做空(跌包涨) 入场=4492.10 出场=4494.10 出场时间=1758386700000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 00:45:00号 做多(涨包跌) 入场=4502.10 出场=4500.10 出场时间=1758387600000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 02:15:00号 做空(跌包涨) 入场=4479.14 出场=4481.14 出场时间=1758393000000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 05:00:00号 做空(跌包涨) 入场=4481.76 出场=4483.76 出场时间=1758402900000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 05:15:00号 做多(涨包跌) 入场=4489.11 出场=4487.11 出场时间=1758404700000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 06:45:00号 做空(跌包涨) 入场=4487.79 出场=4489.79 出场时间=1758409200000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 07:15:00号 做空(跌包涨) 入场=4486.31 出场=4456.31 出场时间=1758420900000 差价=30.00 盈利=66.87 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 08:15:00号 做多(涨包跌) 入场=4480.64 出场=4478.64 出场时间=1758414600000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 08:30:00号 做空(跌包涨) 入场=4474.88 出场=4476.88 出场时间=1758415500000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 08:45:00号 做多(涨包跌) 入场=4480.98 出场=4478.98 出场时间=1758418200000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 09:45:00号 做空(跌包涨) 入场=4479.33 出场=4481.33 出场时间=1758420000000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 10:15:00号 做多(涨包跌) 入场=4484.00 出场=4482.00 出场时间=1758421800000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 10:30:00号 做空(跌包涨) 入场=4473.56 出场=4475.56 出场时间=1758422700000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 12:00:00号 做多(涨包跌) 入场=4476.07 出场=4474.07 出场时间=1758428100000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 12:15:00号 做空(跌包涨) 入场=4468.37 出场=4470.37 出场时间=1758429000000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 12:45:00号 做多(涨包跌) 入场=4469.16 出场=4467.16 出场时间=1758430800000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 13:15:00号 做空(跌包涨) 入场=4465.52 出场=4467.52 出场时间=1758432600000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 14:45:00号 做多(涨包跌) 入场=4489.61 出场=4487.61 出场时间=1758438000000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 16:00:00号 做空(跌包涨) 入场=4475.86 出场=4445.86 出场时间=1758447000000 差价=30.00 盈利=67.03 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 20:00:00号 做空(跌包涨) 入场=4458.25 出场=4460.25 出场时间=1758456900000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 20:15:00号 做多(涨包跌) 入场=4463.00 出场=4461.00 出场时间=1758458700000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 20:45:00号 做空(跌包涨) 入场=4462.99 出场=4464.99 出场时间=1758459600000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 22:00:00号 做多(涨包跌) 入场=4473.99 出场=4471.99 出场时间=1758465000000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 22:30:00号 做空(跌包涨) 入场=4473.49 出场=4475.49 出场时间=1758465900000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 22:45:00号 做多(涨包跌) 入场=4477.45 出场=4475.45 出场时间=1758466800000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 23:00:00号 做空(跌包涨) 入场=4470.65 出场=4472.65 出场时间=1758467700000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 23:15:00号 做多(涨包跌) 入场=4480.89 出场=4478.89 出场时间=1758468600000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 23:45:00号 做多(涨包跌) 入场=4482.23 出场=4480.23 出场时间=1758471300000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-22 00:45:00号 做空(跌包涨) 入场=4468.98 出场=4470.98 出场时间=1758474000000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 02:45:00号 做多(涨包跌) 入场=4490.40 出场=4488.40 出场时间=1758481200000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 03:15:00号 做空(跌包涨) 入场=4478.59 出场=4480.59 出场时间=1758483000000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 04:00:00号 做多(涨包跌) 入场=4492.20 出场=4490.20 出场时间=1758485700000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 04:45:00号 做空(跌包涨) 入场=4477.81 出场=4447.81 出场时间=1758492900000 差价=30.00 盈利=67.00 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 05:30:00号 做空(跌包涨) 入场=4465.73 出场=4467.73 出场时间=1758491100000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 05:45:00号 做多(涨包跌) 入场=4474.17 出场=4472.17 出场时间=1758492000000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 06:45:00号 做多(涨包跌) 入场=4464.29 出场=4462.29 出场时间=1758495600000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 08:00:00号 做空(跌包涨) 入场=4443.01 出场=4445.01 出场时间=1758500100000 差价=-2.00 盈利=-4.50 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 08:30:00号 做空(跌包涨) 入场=4425.29 出场=4395.29 出场时间=1758501900000 差价=30.00 盈利=67.79 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 09:45:00号 做多(涨包跌) 入场=4343.62 出场=4341.62 出场时间=1758506400000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 10:00:00号 做空(跌包涨) 入场=4325.73 出场=4295.73 出场时间=1758507300000 差价=30.00 盈利=69.35 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 10:30:00号 做空(跌包涨) 入场=4307.52 出场=4277.52 出场时间=1758519000000 差价=30.00 盈利=69.65 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 11:15:00号 做多(涨包跌) 入场=4296.63 出场=4294.63 出场时间=1758511800000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 11:45:00号 做空(跌包涨) 入场=4292.42 出场=4294.42 出场时间=1758513600000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 12:00:00号 做多(涨包跌) 入场=4303.62 出场=4301.62 出场时间=1758514500000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 13:45:00号 做空(跌包涨) 入场=4277.81 出场=4247.81 出场时间=1758520800000 差价=30.00 盈利=70.13 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 16:00:00号 做空(跌包涨) 入场=4191.65 出场=4193.65 出场时间=1758528900000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 16:45:00号 做多(涨包跌) 入场=4198.38 出场=4196.38 出场时间=1758531600000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 18:45:00号 做空(跌包涨) 入场=4156.51 出场=4158.51 出场时间=1758538800000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 19:00:00号 做多(涨包跌) 入场=4179.99 出场=4177.99 出场时间=1758539700000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 19:45:00号 做多(涨包跌) 入场=4180.81 出场=4178.81 出场时间=1758542400000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 20:30:00号 做多(涨包跌) 入场=4181.83 出场=4179.83 出场时间=1758545100000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 21:00:00号 做多(涨包跌) 入场=4190.34 出场=4188.34 出场时间=1758547800000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 22:00:00号 做多(涨包跌) 入场=4205.46 出场=4203.46 出场时间=1758550500000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 22:30:00号 做多(涨包跌) 入场=4214.47 出场=4212.47 出场时间=1758552300000 差价=-2.00 盈利=-4.75 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 23:45:00号 做空(跌包涨) 入场=4168.92 出场=4170.92 出场时间=1758556800000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-23 00:15:00号 做多(涨包跌) 入场=4177.10 出场=4175.10 出场时间=1758558600000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-23 01:30:00号 做多(涨包跌) 入场=4165.93 出场=4163.93 出场时间=1758563100000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-23 02:00:00号 做空(跌包涨) 入场=4162.98 出场=4164.98 出场时间=1758564900000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-23 02:15:00号 做多(涨包跌) 入场=4171.60 出场=4169.60 出场时间=1758565800000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 04:15:00号 做多(涨包跌) 入场=4149.68 出场=4179.68 出场时间=1758573900000 差价=30.00 盈利=72.29 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 05:30:00号 做多(涨包跌) 入场=4186.81 出场=4184.81 出场时间=1758578400000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 06:15:00号 做空(跌包涨) 入场=4189.66 出场=4191.66 出场时间=1758580200000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 07:15:00号 做多(涨包跌) 入场=4195.96 出场=4193.96 出场时间=1758584700000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 08:00:00号 做空(跌包涨) 入场=4196.86 出场=4198.86 出场时间=1758586500000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 08:15:00号 做多(涨包跌) 入场=4203.24 出场=4201.24 出场时间=1758587400000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 08:45:00号 做空(跌包涨) 入场=4193.50 出场=4195.50 出场时间=1758590100000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 09:30:00号 做多(涨包跌) 入场=4195.96 出场=4193.96 出场时间=1758591900000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 09:45:00号 做空(跌包涨) 入场=4171.89 出场=4173.89 出场时间=1758592800000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 10:15:00号 做多(涨包跌) 入场=4175.71 出场=4173.71 出场时间=1758594600000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 10:30:00号 做空(跌包涨) 入场=4157.11 出场=4159.11 出场时间=1758595500000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 11:00:00号 做空(跌包涨) 入场=4141.99 出场=4143.99 出场时间=1758597300000 差价=-2.00 盈利=-4.83 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 11:30:00号 做多(涨包跌) 入场=4175.25 出场=4173.25 出场时间=1758600900000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 12:15:00号 做空(跌包涨) 入场=4175.15 出场=4177.15 出场时间=1758602700000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 14:00:00号 做空(跌包涨) 入场=4181.07 出场=4183.07 出场时间=1758608100000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 14:15:00号 做多(涨包跌) 入场=4192.78 出场=4222.78 出场时间=1758618000000 差价=30.00 盈利=71.55 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 15:30:00号 做空(跌包涨) 入场=4199.93 出场=4201.93 出场时间=1758613500000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 15:45:00号 做多(涨包跌) 入场=4205.71 出场=4203.71 出场时间=1758614400000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 17:00:00号 做空(跌包涨) 入场=4206.84 出场=4208.84 出场时间=1758618900000 差价=-2.00 盈利=-4.75 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 17:15:00号 做多(涨包跌) 入场=4219.98 出场=4217.98 出场时间=1758619800000 差价=-2.00 盈利=-4.74 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 17:30:00号 做空(跌包涨) 入场=4202.54 出场=4204.54 出场时间=1758634200000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 18:30:00号 做空(跌包涨) 入场=4188.92 出场=4190.92 出场时间=1758624300000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 19:00:00号 做多(涨包跌) 入场=4191.02 出场=4189.02 出场时间=1758626100000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 19:15:00号 做空(跌包涨) 入场=4182.13 出场=4184.13 出场时间=1758627000000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 20:15:00号 做多(涨包跌) 入场=4193.35 出场=4191.35 出场时间=1758630600000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 20:30:00号 做空(跌包涨) 入场=4184.09 出场=4186.09 出场时间=1758631500000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 20:45:00号 做多(涨包跌) 入场=4196.15 出场=4194.15 出场时间=1758632400000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 21:30:00号 做多(涨包跌) 入场=4194.30 出场=4192.30 出场时间=1758635100000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 21:45:00号 做空(跌包涨) 入场=4186.77 出场=4188.77 出场时间=1758636000000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 22:15:00号 做多(涨包跌) 入场=4196.04 出场=4194.04 出场时间=1758637800000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 22:30:00号 做空(跌包涨) 入场=4182.60 出场=4184.60 出场时间=1758638700000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 23:00:00号 做空(跌包涨) 入场=4172.55 出场=4174.55 出场时间=1758640500000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 23:45:00号 做空(跌包涨) 入场=4178.60 出场=4180.60 出场时间=1758643200000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 00:15:00号 做空(跌包涨) 入场=4172.91 出场=4174.91 出场时间=1758645000000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 00:30:00号 做多(涨包跌) 入场=4186.91 出场=4184.91 出场时间=1758645900000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 00:45:00号 做空(跌包涨) 入场=4170.16 出场=4172.16 出场时间=1758646800000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 01:00:00号 做多(涨包跌) 入场=4190.21 出场=4188.21 出场时间=1758647700000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 02:45:00号 做空(跌包涨) 入场=4149.15 出场=4151.15 出场时间=1758654000000 差价=-2.00 盈利=-4.82 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 03:45:00号 做空(跌包涨) 入场=4155.56 出场=4157.56 出场时间=1758657600000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 04:15:00号 做多(涨包跌) 入场=4157.54 出场=4155.54 出场时间=1758659400000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 04:30:00号 做空(跌包涨) 入场=4149.61 出场=4151.61 出场时间=1758660300000 差价=-2.00 盈利=-4.82 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 04:45:00号 做多(涨包跌) 入场=4163.34 出场=4161.34 出场时间=1758669300000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 06:45:00号 做多(涨包跌) 入场=4182.21 出场=4180.21 出场时间=1758668400000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 09:15:00号 做多(涨包跌) 入场=4182.12 出场=4180.12 出场时间=1758679200000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 10:15:00号 做空(跌包涨) 入场=4168.31 出场=4170.31 出场时间=1758681000000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 12:15:00号 做空(跌包涨) 入场=4098.12 出场=4100.12 出场时间=1758688200000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 16:15:00号 做多(涨包跌) 入场=4174.81 出场=4172.81 出场时间=1758702600000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 16:30:00号 做空(跌包涨) 入场=4168.12 出场=4170.12 出场时间=1758703500000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 16:45:00号 做多(涨包跌) 入场=4175.13 出场=4173.13 出场时间=1758704400000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 17:30:00号 做多(涨包跌) 入场=4174.40 出场=4172.40 出场时间=1758708900000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 18:15:00号 做空(跌包涨) 入场=4177.63 出场=4179.63 出场时间=1758711600000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 20:45:00号 做多(涨包跌) 入场=4181.50 出场=4179.50 出场时间=1758718800000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-25 00:30:00号 做多(涨包跌) 入场=4167.86 出场=4165.86 出场时间=1758733200000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-25 01:15:00号 做多(涨包跌) 入场=4178.77 出场=4176.77 出场时间=1758735000000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-25 01:45:00号 做多(涨包跌) 入场=4186.01 出场=4184.01 出场时间=1758736800000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 07:00:00号 做空(跌包涨) 入场=4151.98 出场=4153.98 出场时间=1758755700000 差价=-2.00 盈利=-4.82 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 07:15:00号 做多(涨包跌) 入场=4158.00 出场=4156.00 出场时间=1758756600000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 08:30:00号 做空(跌包涨) 入场=4137.01 出场=4139.01 出场时间=1758761100000 差价=-2.00 盈利=-4.83 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 09:00:00号 做空(跌包涨) 入场=4126.96 出场=4096.96 出场时间=1758762900000 差价=30.00 盈利=72.69 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 10:45:00号 做多(涨包跌) 入场=4099.28 出场=4097.28 出场时间=1758769200000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 11:15:00号 做空(跌包涨) 入场=4086.56 出场=4056.56 出场时间=1758771000000 差价=30.00 盈利=73.41 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 12:15:00号 做空(跌包涨) 入场=4045.83 出场=4015.83 出场时间=1758774600000 差价=30.00 盈利=74.15 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 13:00:00号 做空(跌包涨) 入场=4000.17 出场=4002.17 出场时间=1758777300000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 16:00:00号 做空(跌包涨) 入场=4006.93 出场=4008.93 出场时间=1758788100000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 16:15:00号 做多(涨包跌) 入场=4029.59 出场=4027.59 出场时间=1758789000000 差价=-2.00 盈利=-4.96 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 16:45:00号 做空(跌包涨) 入场=4010.29 出场=4012.29 出场时间=1758790800000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 19:45:00号 做空(跌包涨) 入场=3998.02 出场=4000.02 出场时间=1758801600000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 20:30:00号 做空(跌包涨) 入场=3939.54 出场=3941.54 出场时间=1758804300000 差价=-2.00 盈利=-5.08 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 21:30:00号 做多(涨包跌) 入场=4001.35 出场=3999.35 出场时间=1758807900000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 21:45:00号 做空(跌包涨) 入场=3957.31 出场=3959.31 出场时间=1758808800000 差价=-2.00 盈利=-5.05 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-26 00:15:00号 做空(跌包涨) 入场=3996.68 出场=3966.68 出场时间=1758817800000 差价=30.00 盈利=75.06 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-26 01:45:00号 做空(跌包涨) 入场=3865.17 出场=3835.17 出场时间=1758823200000 差价=30.00 盈利=77.62 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-26 03:30:00号 做多(涨包跌) 入场=3937.43 出场=3935.43 出场时间=1758829500000 差价=-2.00 盈利=-5.08 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 04:45:00号 做空(跌包涨) 入场=3891.53 出场=3893.53 出场时间=1758834000000 差价=-2.00 盈利=-5.14 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 05:15:00号 做多(涨包跌) 入场=3898.34 出场=3896.34 出场时间=1758835800000 差价=-2.00 盈利=-5.13 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 06:00:00号 做多(涨包跌) 入场=3903.57 出场=3933.57 出场时间=1758838500000 差价=30.00 盈利=76.85 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 08:45:00号 做空(跌包涨) 入场=3872.95 出场=3874.95 出场时间=1758848400000 差价=-2.00 盈利=-5.16 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 09:00:00号 做多(涨包跌) 入场=3930.76 出场=3928.76 出场时间=1758849300000 差价=-2.00 盈利=-5.09 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 09:30:00号 做空(跌包涨) 入场=3927.77 出场=3929.77 出场时间=1758851100000 差价=-2.00 盈利=-5.09 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 09:45:00号 做多(涨包跌) 入场=3941.60 出场=3971.60 出场时间=1758860100000 差价=30.00 盈利=76.11 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 10:45:00号 做多(涨包跌) 入场=3957.81 出场=3955.81 出场时间=1758855600000 差价=-2.00 盈利=-5.05 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 11:15:00号 做多(涨包跌) 入场=3959.57 出场=3957.57 出场时间=1758857400000 差价=-2.00 盈利=-5.05 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 11:30:00号 做空(跌包涨) 入场=3954.21 出场=3956.21 出场时间=1758858300000 差价=-2.00 盈利=-5.06 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 12:30:00号 做空(跌包涨) 入场=3960.89 出场=3930.89 出场时间=1758865500000 差价=30.00 盈利=75.74 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 13:45:00号 做空(跌包涨) 入场=3942.77 出场=3912.77 出场时间=1758866400000 差价=30.00 盈利=76.09 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 15:00:00号 做空(跌包涨) 入场=3919.00 出场=3921.00 出场时间=1758870900000 差价=-2.00 盈利=-5.10 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 16:00:00号 做多(涨包跌) 入场=3936.60 出场=3934.60 出场时间=1758874500000 差价=-2.00 盈利=-5.08 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 16:45:00号 做多(涨包跌) 入场=3937.94 出场=3935.94 出场时间=1758877200000 差价=-2.00 盈利=-5.08 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 17:00:00号 做空(跌包涨) 入场=3932.27 出场=3934.27 出场时间=1758878100000 差价=-2.00 盈利=-5.09 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 17:30:00号 做空(跌包涨) 入场=3925.74 出场=3895.74 出场时间=1758880800000 差价=30.00 盈利=76.42 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 18:15:00号 做空(跌包涨) 入场=3885.27 出场=3887.27 出场时间=1758882600000 差价=-2.00 盈利=-5.15 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 18:45:00号 做多(涨包跌) 入场=3886.20 出场=3884.20 出场时间=1758884400000 差价=-2.00 盈利=-5.15 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 19:15:00号 做空(跌包涨) 入场=3875.50 出场=3877.50 出场时间=1758886200000 差价=-2.00 盈利=-5.16 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 19:30:00号 做多(涨包跌) 入场=3888.98 出场=3886.98 出场时间=1758888000000 差价=-2.00 盈利=-5.14 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 21:45:00号 做多(涨包跌) 入场=3937.17 出场=3967.17 出场时间=1758895200000 差价=30.00 盈利=76.20 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 23:00:00号 做空(跌包涨) 入场=3929.62 出场=3931.62 出场时间=1758899700000 差价=-2.00 盈利=-5.09 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 00:15:00号 做多(涨包跌) 入场=3962.86 出场=3992.86 出场时间=1758906000000 差价=30.00 盈利=75.70 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 02:45:00号 做空(跌包涨) 入场=4040.09 出场=4042.09 出场时间=1758913200000 差价=-2.00 盈利=-4.95 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 03:15:00号 做空(跌包涨) 入场=4036.73 出场=4006.73 出场时间=1758915000000 差价=30.00 盈利=74.32 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 04:00:00号 做多(涨包跌) 入场=4021.39 出场=4019.39 出场时间=1758917700000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 04:30:00号 做空(跌包涨) 入场=4016.00 出场=4018.00 出场时间=1758922200000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 05:15:00号 做多(涨包跌) 入场=4014.71 出场=4012.71 出场时间=1758922200000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 05:45:00号 做空(跌包涨) 入场=4010.24 出场=4012.24 出场时间=1758924000000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 06:00:00号 做多(涨包跌) 入场=4021.35 出场=4019.35 出场时间=1758927600000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 07:00:00号 做空(跌包涨) 入场=4024.56 出场=4026.56 出场时间=1758929400000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 08:45:00号 做空(跌包涨) 入场=4020.15 出场=4022.15 出场时间=1758934800000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 10:00:00号 做多(涨包跌) 入场=4016.68 出场=4014.68 出场时间=1758939300000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 10:30:00号 做空(跌包涨) 入场=4011.24 出场=4013.24 出场时间=1758941100000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 11:00:00号 做空(跌包涨) 入场=4010.82 出场=4012.82 出场时间=1758942900000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 11:30:00号 做多(涨包跌) 入场=4021.64 出场=4019.64 出场时间=1758944700000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 12:00:00号 做空(跌包涨) 入场=4017.19 出场=4019.19 出场时间=1758946500000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 12:30:00号 做多(涨包跌) 入场=4024.64 出场=4022.64 出场时间=1758948300000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 13:45:00号 做多(涨包跌) 入场=4017.61 出场=4015.61 出场时间=1758952800000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 14:15:00号 做空(跌包涨) 入场=4013.01 出场=4015.01 出场时间=1758954600000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 14:45:00号 做多(涨包跌) 入场=4014.09 出场=4012.09 出场时间=1758957300000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 15:30:00号 做空(跌包涨) 入场=4011.76 出场=3981.76 出场时间=1758962700000 差价=30.00 盈利=74.78 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 18:45:00号 做多(涨包跌) 入场=4011.07 出场=4009.07 出场时间=1758970800000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 19:30:00号 做多(涨包跌) 入场=4011.08 出场=4009.08 出场时间=1758973500000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-27 19:45:00号 做空(跌包涨) 入场=4003.03 出场=4005.03 出场时间=1758976200000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-27 22:00:00号 做空(跌包涨) 入场=4018.39 出场=4020.39 出场时间=1758982500000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-27 22:30:00号 做空(跌包涨) 入场=4017.14 出场=4019.14 出场时间=1758987900000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 00:15:00号 做空(跌包涨) 入场=4010.03 出场=4012.03 出场时间=1758990600000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 01:45:00号 做多(涨包跌) 入场=3994.29 出场=3992.29 出场时间=1758996000000 差价=-2.00 盈利=-5.01 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 03:00:00号 做多(涨包跌) 入场=3994.64 出场=3992.64 出场时间=1759000500000 差价=-2.00 盈利=-5.01 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 03:30:00号 做多(涨包跌) 入场=3997.57 出场=3995.57 出场时间=1759002300000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 04:00:00号 做多(涨包跌) 入场=4000.64 出场=4030.64 出场时间=1759011300000 差价=30.00 盈利=74.99 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 05:45:00号 做多(涨包跌) 入场=4014.84 出场=4012.84 出场时间=1759010400000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 06:15:00号 做多(涨包跌) 入场=4021.22 出场=4019.22 出场时间=1759012200000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 06:45:00号 做空(跌包涨) 入场=4017.93 出场=4019.93 出场时间=1759014000000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 07:30:00号 做空(跌包涨) 入场=4016.91 出场=4018.91 出场时间=1759016700000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 08:00:00号 做多(涨包跌) 入场=4016.99 出场=4014.99 出场时间=1759018500000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 08:15:00号 做空(跌包涨) 入场=4011.14 出场=4013.14 出场时间=1759019400000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 08:30:00号 做多(涨包跌) 入场=4027.69 出场=4025.69 出场时间=1759020300000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 09:45:00号 做空(跌包涨) 入场=3995.87 出场=3997.87 出场时间=1759024800000 差价=-2.00 盈利=-5.01 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 10:30:00号 做多(涨包跌) 入场=4002.88 出场=4000.88 出场时间=1759027500000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 11:15:00号 做多(涨包跌) 入场=4003.08 出场=4001.08 出场时间=1759030200000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 12:15:00号 做空(跌包涨) 入场=3996.98 出场=3998.98 出场时间=1759033800000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 12:45:00号 做多(涨包跌) 入场=4002.57 出场=4000.57 出场时间=1759040100000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 13:15:00号 做空(跌包涨) 入场=4001.69 出场=4003.69 出场时间=1759037400000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 13:30:00号 做多(涨包跌) 入场=4009.87 出场=4007.87 出场时间=1759038300000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 14:00:00号 做空(跌包涨) 入场=4008.99 出场=4010.99 出场时间=1759040100000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 14:30:00号 做空(跌包涨) 入场=3998.62 出场=4000.62 出场时间=1759041900000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 16:15:00号 做空(跌包涨) 入场=4010.49 出场=3980.49 出场时间=1759062600000 差价=30.00 盈利=74.80 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 18:00:00号 做空(跌包涨) 入场=3993.77 出场=3995.77 出场时间=1759055400000 差价=-2.00 盈利=-5.01 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 18:45:00号 做多(涨包跌) 入场=3996.14 出场=3994.14 出场时间=1759057200000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 20:45:00号 做空(跌包涨) 入场=3969.72 出场=3971.72 出场时间=1759064400000 差价=-2.00 盈利=-5.04 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 23:00:00号 做多(涨包跌) 入场=4022.99 出场=4020.99 出场时间=1759072500000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 23:45:00号 做空(跌包涨) 入场=4019.98 出场=4021.98 出场时间=1759075200000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-29 00:15:00号 做多(涨包跌) 入场=4032.80 出场=4030.80 出场时间=1759077000000 差价=-2.00 盈利=-4.96 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-29 01:00:00号 做多(涨包跌) 入场=4031.84 出场=4029.84 出场时间=1759079700000 差价=-2.00 盈利=-4.96 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 01:45:00号 做多(涨包跌) 入场=4043.55 出场=4041.55 出场时间=1759082400000 差价=-2.00 盈利=-4.95 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 02:45:00号 做多(涨包跌) 入场=4038.12 出场=4036.12 出场时间=1759086000000 差价=-2.00 盈利=-4.95 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 03:15:00号 做空(跌包涨) 入场=4032.23 出场=4034.23 出场时间=1759087800000 差价=-2.00 盈利=-4.96 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 04:00:00号 做多(涨包跌) 入场=4037.42 出场=4035.42 出场时间=1759090500000 差价=-2.00 盈利=-4.95 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 04:30:00号 做多(涨包跌) 入场=4046.49 出场=4044.49 出场时间=1759095000000 差价=-2.00 盈利=-4.94 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 05:30:00号 做空(跌包涨) 入场=4048.44 出场=4050.44 出场时间=1759096800000 差价=-2.00 盈利=-4.94 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 07:45:00号 做多(涨包跌) 入场=4137.26 出场=4135.26 出场时间=1759104000000 差价=-2.00 盈利=-4.83 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 08:15:00号 做空(跌包涨) 入场=4134.85 出场=4136.85 出场时间=1759105800000 差价=-2.00 盈利=-4.84 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 08:45:00号 做空(跌包涨) 入场=4126.53 出场=4128.53 出场时间=1759107600000 差价=-2.00 盈利=-4.85 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 09:15:00号 做多(涨包跌) 入场=4131.72 出场=4129.72 出场时间=1759109400000 差价=-2.00 盈利=-4.84 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 09:30:00号 做空(跌包涨) 入场=4117.93 出场=4119.93 出场时间=1759110300000 差价=-2.00 盈利=-4.86 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 10:00:00号 做空(跌包涨) 入场=4112.65 出场=4114.65 出场时间=1759112100000 差价=-2.00 盈利=-4.86 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 10:45:00号 做空(跌包涨) 入场=4107.29 出场=4109.29 出场时间=1759114800000 差价=-2.00 盈利=-4.87 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 11:15:00号 做空(跌包涨) 入场=4102.41 出场=4104.41 出场时间=1759116600000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 12:00:00号 做多(涨包跌) 入场=4119.67 出场=4117.67 出场时间=1759119300000 差价=-2.00 盈利=-4.85 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 12:45:00号 做多(涨包跌) 入场=4118.75 出场=4116.75 出场时间=1759122000000 差价=-2.00 盈利=-4.86 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 13:45:00号 做多(涨包跌) 入场=4109.88 出场=4107.88 出场时间=1759125600000 差价=-2.00 盈利=-4.87 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 14:15:00号 做空(跌包涨) 入场=4097.98 出场=4099.98 出场时间=1759127400000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 15:00:00号 做空(跌包涨) 入场=4095.36 出场=4097.36 出场时间=1759130100000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 15:30:00号 做空(跌包涨) 入场=4092.53 出场=4094.53 出场时间=1759131900000 差价=-2.00 盈利=-4.89 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 15:45:00号 做多(涨包跌) 入场=4104.99 出场=4134.99 出场时间=1759137300000 差价=30.00 盈利=73.08 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 20:00:00号 做空(跌包涨) 入场=4100.87 出场=4102.87 出场时间=1759148100000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 20:15:00号 做多(涨包跌) 入场=4108.92 出场=4106.92 出场时间=1759149000000 差价=-2.00 盈利=-4.87 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 20:45:00号 做空(跌包涨) 入场=4102.06 出场=4104.06 出场时间=1759150800000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 21:15:00号 做多(涨包跌) 入场=4102.99 出场=4132.99 出场时间=1759152600000 差价=30.00 盈利=73.12 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 22:45:00号 做多(涨包跌) 入场=4189.88 出场=4187.88 出场时间=1759158000000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 00:30:00号 做空(跌包涨) 入场=4156.52 出场=4126.52 出场时间=1759165200000 差价=30.00 盈利=72.18 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 01:30:00号 做多(涨包跌) 入场=4145.04 出场=4143.04 出场时间=1759168800000 差价=-2.00 盈利=-4.83 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 02:00:00号 做多(涨包跌) 入场=4153.13 出场=4151.13 出场时间=1759169700000 差价=-2.00 盈利=-4.82 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 03:45:00号 做多(涨包跌) 入场=4180.31 出场=4210.31 出场时间=1759177800000 差价=30.00 盈利=71.77 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 04:45:00号 做多(涨包跌) 入场=4229.13 出场=4227.13 出场时间=1759179600000 差价=-2.00 盈利=-4.73 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 07:00:00号 做多(涨包跌) 入场=4224.09 出场=4222.09 出场时间=1759187700000 差价=-2.00 盈利=-4.73 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 08:45:00号 做多(涨包跌) 入场=4216.80 出场=4214.80 出场时间=1759194000000 差价=-2.00 盈利=-4.74 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 10:15:00号 做空(跌包涨) 入场=4198.83 出场=4200.83 出场时间=1759199400000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 10:45:00号 做多(涨包跌) 入场=4201.68 出场=4199.68 出场时间=1759201200000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 11:30:00号 做多(涨包跌) 入场=4199.59 出场=4197.59 出场时间=1759203900000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 12:00:00号 做空(跌包涨) 入场=4196.16 出场=4198.16 出场时间=1759205700000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 14:00:00号 做多(涨包跌) 入场=4182.43 出场=4180.43 出场时间=1759217400000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 15:00:00号 做空(跌包涨) 入场=4188.05 出场=4190.05 出场时间=1759216500000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 17:30:00号 做多(涨包跌) 入场=4168.78 出场=4166.78 出场时间=1759225500000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 19:15:00号 做空(跌包涨) 入场=4153.02 出场=4155.02 出场时间=1759231800000 差价=-2.00 盈利=-4.82 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 19:30:00号 做多(涨包跌) 入场=4158.87 出场=4156.87 出场时间=1759233600000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 20:30:00号 做多(涨包跌) 入场=4165.40 出场=4163.40 出场时间=1759236300000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 21:00:00号 做空(跌包涨) 入场=4156.14 出场=4158.14 出场时间=1759238100000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 21:30:00号 做多(涨包跌) 入场=4164.44 出场=4162.44 出场时间=1759239900000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 22:00:00号 做空(跌包涨) 入场=4152.29 出场=4122.29 出场时间=1759241700000 差价=30.00 盈利=72.25 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 23:15:00号 做空(跌包涨) 入场=4115.98 出场=4117.98 出场时间=1759247100000 差价=-2.00 盈利=-4.86 开仓手续费=5u 平仓手续费=5.00
""" # ← 这里粘贴你的完整日志文本
pattern = re.compile(
r"(?P<time>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}).*?(?P<direction>做多|做空).*?入场=(?P<entry>[\d.]+).*?出场=(?P<exit>[\d.]+).*?盈利=(?P<profit>[-\d.]+)"
)
trades = []
for match in pattern.finditer(log_data):
t = match.groupdict()
t["entry"] = float(t["entry"])
t["exit"] = float(t["exit"])
t["profit"] = float(t["profit"])
t["time"] = datetime.strptime(t["time"], "%Y-%m-%d %H:%M:%S")
trades.append(t)
# 按时间排序
trades.sort(key=lambda x: x["time"])
# 模式A禁止重叠开仓
no_overlap_trades = []
last_close_time = None
for t in trades:
if last_close_time and t["time"] < last_close_time:
continue # 忽略重叠交易
no_overlap_trades.append(t)
last_close_time = t["time"] # 这里假设出场时间等于该记录时间
# 模式B信号来了就开单全部计算
all_trades = trades
# 汇总
def summary(name, trade_list):
total = sum(t["profit"] for t in trade_list)
print(f"\n{name}")
print(f"交易次数:{len(trade_list)}")
print(f"总盈利:{total:.2f} USDT")
if trade_list:
print(f"平均每单:{total / len(trade_list):.2f} USDT")
summary("模式A不允许重叠", no_overlap_trades)
summary("模式B信号即开", all_trades)

View File

@@ -1,83 +0,0 @@
import random
import time
from curl_cffi import requests
from models.weex import Weex1
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9,zh-HK;q=0.8,en;q=0.7',
'appversion': '2.0.0',
'bundleid': '',
'cache-control': 'no-cache',
'language': 'zh_CN',
'origin': 'https://www.weex.com',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://www.weex.com/',
'sec-ch-ua': '"Google Chrome";v="141", "Not?A_Brand";v="8", "Chromium";v="141"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'cross-site',
'sidecar': '0115665ae5d5a18da1543cd0deabd52588c09f4d3b028876659f0801ca7af5a3ba',
'terminalcode': '55a01525ddf9e8f4bb158345db69b510',
'terminaltype': '1',
'traceid': 'mgotla61s5segrwkkw',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36',
'vs': 'Z567O6188nsWfe9Njo9N7KsAbL0RO6ho',
'x-sig': 'bb0f194c38f69c38ffbcb361c27c7295',
'x-timestamp': '1760341017529',
}
klineId = None
klineTime = None
contractId = None
while True:
for i in range(500):
print(i)
params = {
'languageType': '1',
'sign': 'SIGN',
'timeZone': 'string',
'contractId': '10000002',
'productCode': 'ethusdt',
'priceType': 'LAST_PRICE',
'klineType': 'MINUTE_1',
'limit': '200',
}
if klineId:
params['nextKey.klineId'] = klineId
params['nextKey.contractId'] = contractId
if klineTime:
params['nextKey.klineTime'] = klineTime
response = requests.get('https://http-gateway1.janapw.com/api/v1/public/quote/v1/getKlineV2', params=params,
headers=headers)
klineId = response.json()["data"]["nextKey"]["klineId"]
klineTime = response.json()["data"]["nextKey"]["klineTime"]
contractId = response.json()["data"]["nextKey"]["contractId"]
for data in response.json()["data"]["dataList"]:
# print(data)
Weex1.get_or_create(
id=int(data[4]),
defaults={
'open': float(data[3]),
'high': float(data[1]),
'low': float(data[2]),
'close': float(data[0]),
}
)
time.sleep(random.randint(1, 50))
# time.sleep(3600)

View File

@@ -1,83 +0,0 @@
import time
from curl_cffi import requests
from models.weex import Weex15
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'appversion': '2.0.0',
'bundleid': '',
'cache-control': 'no-cache',
'dnt': '1',
'language': 'zh_CN',
'origin': 'https://www.weeaxs.site',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://www.weeaxs.site/',
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Microsoft Edge";v="140"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'cross-site',
'sidecar': '01bfdfef90d2d6213c86b09f3a00d696d366752996a0b6692a33969a67fcd243df',
'terminalcode': '89adf61538715df59eb4f6414981484e',
'terminaltype': '1',
'traceid': 'mgoh8eoehxp15lxnbv',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0',
'vs': 'G5h7sX78yNSykC9xtTmA7O2lSKqAk6Sp',
'x-sig': '74ec6a65f3886f24a8b062e3b41edb1a',
'x-timestamp': '1760320261454',
}
klineId = None
klineTime = None
contractId = None
while True:
for i in range(10):
print(i)
params = {
'languageType': '1',
'sign': 'SIGN',
'timeZone': 'string',
'contractId': '10000002',
'productCode': 'ethusdt',
'priceType': 'LAST_PRICE',
'klineType': 'MINUTE_15',
'limit': '329',
}
if klineId:
params['nextKey.klineId'] = klineId
params['nextKey.contractId'] = contractId
if klineTime:
params['nextKey.klineTime'] = klineTime
response = requests.get('https://http-gateway1.janapw.com/api/v1/public/quote/v1/getKlineV2', params=params,
headers=headers)
klineId = response.json()["data"]["nextKey"]["klineId"]
klineTime = response.json()["data"]["nextKey"]["klineTime"]
contractId = response.json()["data"]["nextKey"]["contractId"]
for data in response.json()["data"]["dataList"]:
# print(data)
Weex15.get_or_create(
id=int(data[4]),
defaults={
'open': float(data[3]),
'high': float(data[1]),
'low': float(data[2]),
'close': float(data[0]),
}
)
# time.sleep(1)
time.sleep(3600)

View File

@@ -1,83 +0,0 @@
import time
from curl_cffi import requests
from models.weex import Weex1Hour
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
'appversion': '2.0.0',
'bundleid': '',
'cache-control': 'no-cache',
'dnt': '1',
'language': 'zh_CN',
'origin': 'https://www.weeaxs.site',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://www.weeaxs.site/',
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Microsoft Edge";v="140"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'cross-site',
'sidecar': '01bfdfef90d2d6213c86b09f3a00d696d366752996a0b6692a33969a67fcd243df',
'terminalcode': '89adf61538715df59eb4f6414981484e',
'terminaltype': '1',
'traceid': 'mgoh8eoehxp15lxnbv',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0',
'vs': 'G5h7sX78yNSykC9xtTmA7O2lSKqAk6Sp',
'x-sig': '74ec6a65f3886f24a8b062e3b41edb1a',
'x-timestamp': '1760320261454',
}
klineId = None
klineTime = None
contractId = None
while True:
for i in range(10):
print(i)
params = {
'languageType': '1',
'sign': 'SIGN',
'timeZone': 'string',
'contractId': '10000002',
'productCode': 'ethusdt',
'priceType': 'LAST_PRICE',
'klineType': 'HOUR_1',
'limit': '570',
}
if klineId:
params['nextKey.klineId'] = klineId
params['nextKey.contractId'] = contractId
if klineTime:
params['nextKey.klineTime'] = klineTime
response = requests.get('https://http-gateway1.janapw.com/api/v1/public/quote/v1/getKlineV2', params=params,
headers=headers)
klineId = response.json()["data"]["nextKey"]["klineId"]
klineTime = response.json()["data"]["nextKey"]["klineTime"]
contractId = response.json()["data"]["nextKey"]["contractId"]
for data in response.json()["data"]["dataList"]:
# print(data)
Weex1Hour.get_or_create(
id=int(data[4]),
defaults={
'open': float(data[3]),
'high': float(data[1]),
'low': float(data[2]),
'close': float(data[0]),
}
)
# time.sleep(1)
time.sleep(3600)

View File

@@ -1,866 +0,0 @@
import re
from datetime import datetime
def calculate_max_drawdown(log_data):
"""
计算交易日志的最大回撤
"""
# 解析日志数据,提取每笔交易的盈利
profits = []
for line in log_data.split('\n'):
if not line.strip():
continue
# 使用正则表达式提取盈利数值
match = re.search(r'盈利=([-\d.]+)', line)
if match:
profit = float(match.group(1))
profits.append(profit)
if not profits:
return 0, 0, 0, 0, []
# 计算累计收益
cumulative_returns = []
cumulative = 0
for profit in profits:
cumulative += profit
cumulative_returns.append(cumulative)
# 计算最大回撤
max_drawdown = 0
max_drawdown_start = 0
max_drawdown_end = 0
peak = cumulative_returns[0]
for i in range(1, len(cumulative_returns)):
if cumulative_returns[i] > peak:
peak = cumulative_returns[i]
else:
drawdown = peak - cumulative_returns[i]
if drawdown > max_drawdown:
max_drawdown = drawdown
max_drawdown_start = cumulative_returns.index(peak)
max_drawdown_end = i
# 计算其他统计指标
total_trades = len(profits)
winning_trades = len([p for p in profits if p > 0])
losing_trades = len([p for p in profits if p < 0])
win_rate = winning_trades / total_trades if total_trades > 0 else 0
total_profit = sum(profits)
return {
'max_drawdown': max_drawdown,
'max_drawdown_percentage': (max_drawdown / peak * 100) if peak != 0 else 0,
'max_drawdown_period': (max_drawdown_start, max_drawdown_end),
'total_trades': total_trades,
'winning_trades': winning_trades,
'losing_trades': losing_trades,
'win_rate': win_rate,
'total_profit': total_profit,
'average_profit': total_profit / total_trades if total_trades > 0 else 0,
'cumulative_returns': cumulative_returns,
'individual_profits': profits
}
def print_analysis_results(results):
"""打印分析结果"""
print("=" * 60)
print("交易策略分析报告")
print("=" * 60)
print(f"总交易次数: {results['total_trades']}")
print(f"盈利交易: {results['winning_trades']}")
print(f"亏损交易: {results['losing_trades']}")
print(f"胜率: {results['win_rate']:.2%}")
print(f"总盈利: {results['total_profit']:.2f} u")
print(f"平均每笔盈利: {results['average_profit']:.2f} u")
print("-" * 60)
print(f"最大回撤: {results['max_drawdown']:.2f} u")
print(f"最大回撤百分比: {results['max_drawdown_percentage']:.2f}%")
print(f"最大回撤期间: 第{results['max_drawdown_period'][0] + 1}笔到第{results['max_drawdown_period'][1] + 1}笔交易")
print("=" * 60)
# 使用示例
if __name__ == "__main__":
# 你的日志数据
log_data = """
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 02:00:00号 做空(跌包涨) 入场=4474.69 出场=4476.69 出场时间=1756664100000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 03:15:00号 做空(跌包涨) 入场=4472.09 出场=4474.09 出场时间=1756668600000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 03:45:00号 做多(涨包跌) 入场=4474.15 出场=4472.15 出场时间=1756670400000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 04:00:00号 做空(跌包涨) 入场=4453.24 出场=4455.24 出场时间=1756671300000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 05:45:00号 做多(涨包跌) 入场=4473.88 出场=4471.88 出场时间=1756677600000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 06:45:00号 做空(跌包涨) 入场=4439.92 出场=4441.92 出场时间=1756681200000 差价=-2.00 盈利=-4.50 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 07:15:00号 做空(跌包涨) 入场=4432.11 出场=4402.11 出场时间=1756683000000 差价=30.00 盈利=67.69 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 08:15:00号 做空(跌包涨) 入场=4384.50 出场=4386.50 出场时间=1756686600000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 08:45:00号 做多(涨包跌) 入场=4393.52 出场=4391.52 出场时间=1756688400000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 09:15:00号 做空(跌包涨) 入场=4391.40 出场=4393.40 出场时间=1756690200000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 09:30:00号 做多(涨包跌) 入场=4405.79 出场=4403.79 出场时间=1756692000000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 12:30:00号 做空(跌包涨) 入场=4386.76 出场=4388.76 出场时间=1756702800000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 13:15:00号 做空(跌包涨) 入场=4372.37 出场=4374.37 出场时间=1756704600000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 13:30:00号 做多(涨包跌) 入场=4390.78 出场=4388.78 出场时间=1756706400000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.364 | INFO | __main__:<module>:216 - 2025-09-01 14:30:00号 做多(涨包跌) 入场=4394.00 出场=4392.00 出场时间=1756710000000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 15:30:00号 做多(涨包跌) 入场=4419.10 出场=4449.10 出场时间=1756712700000 差价=30.00 盈利=67.89 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 18:30:00号 做空(跌包涨) 入场=4429.31 出场=4399.31 出场时间=1756723500000 差价=30.00 盈利=67.73 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 19:15:00号 做空(跌包涨) 入场=4399.49 出场=4401.49 出场时间=1756728000000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 20:45:00号 做空(跌包涨) 入场=4395.36 出场=4397.36 出场时间=1756731600000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 21:45:00号 做空(跌包涨) 入场=4384.90 出场=4386.90 出场时间=1756735200000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 22:15:00号 做多(涨包跌) 入场=4396.00 出场=4394.00 出场时间=1756737000000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 22:45:00号 做空(跌包涨) 入场=4389.51 出场=4391.51 出场时间=1756738800000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-01 23:15:00号 做空(跌包涨) 入场=4381.89 出场=4351.89 出场时间=1756741500000 差价=30.00 盈利=68.46 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 00:30:00号 做空(跌包涨) 入场=4358.69 出场=4360.69 出场时间=1756745100000 差价=-2.00 盈利=-4.59 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 01:00:00号 做空(跌包涨) 入场=4353.30 出场=4323.30 出场时间=1756746900000 差价=30.00 盈利=68.91 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 02:15:00号 做多(涨包跌) 入场=4337.86 出场=4335.86 出场时间=1756751400000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 03:00:00号 做多(涨包跌) 入场=4345.08 出场=4343.08 出场时间=1756757700000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 03:45:00号 做多(涨包跌) 入场=4363.92 出场=4361.92 出场时间=1756756800000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 04:15:00号 做空(跌包涨) 入场=4358.28 出场=4328.28 出场时间=1756758600000 差价=30.00 盈利=68.83 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 07:00:00号 做多(涨包跌) 入场=4282.53 出场=4312.53 出场时间=1756770300000 差价=30.00 盈利=70.05 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 08:45:00号 做空(跌包涨) 入场=4291.71 出场=4293.71 出场时间=1756774800000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 09:00:00号 做多(涨包跌) 入场=4302.49 出场=4300.49 出场时间=1756775700000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 09:30:00号 做多(涨包跌) 入场=4308.80 出场=4338.80 出场时间=1756777500000 差价=30.00 盈利=69.62 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.365 | INFO | __main__:<module>:216 - 2025-09-02 11:00:00号 做多(涨包跌) 入场=4359.11 出场=4389.11 出场时间=1756782900000 差价=30.00 盈利=68.82 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 12:00:00号 做空(跌包涨) 入场=4365.21 出场=4367.21 出场时间=1756786500000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 12:15:00号 做多(涨包跌) 入场=4374.91 出场=4372.91 出场时间=1756789200000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 13:15:00号 做空(跌包涨) 入场=4377.72 出场=4379.72 出场时间=1756791000000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 14:45:00号 做多(涨包跌) 入场=4406.35 出场=4404.35 出场时间=1756796400000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 15:15:00号 做空(跌包涨) 入场=4391.65 出场=4393.65 出场时间=1756798200000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 15:45:00号 做空(跌包涨) 入场=4384.00 出场=4386.00 出场时间=1756800900000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 16:30:00号 做多(涨包跌) 入场=4394.20 出场=4392.20 出场时间=1756802700000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 17:00:00号 做空(跌包涨) 入场=4389.98 出场=4391.98 出场时间=1756804500000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 18:15:00号 做空(跌包涨) 入场=4394.30 出场=4364.30 出场时间=1756812600000 差价=30.00 盈利=68.27 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 19:00:00号 做多(涨包跌) 入场=4389.96 出场=4387.96 出场时间=1756811700000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 19:15:00号 做空(跌包涨) 入场=4375.68 出场=4345.68 出场时间=1756813500000 差价=30.00 盈利=68.56 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 20:00:00号 做空(跌包涨) 入场=4346.32 出场=4316.32 出场时间=1756816200000 差价=30.00 盈利=69.02 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-02 20:45:00号 做空(跌包涨) 入场=4300.58 出场=4302.58 出场时间=1756818900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.366 | INFO | __main__:<module>:216 - 2025-09-03 00:30:00号 做空(跌包涨) 入场=4280.64 出场=4282.64 出场时间=1756831500000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.367 | INFO | __main__:<module>:216 - 2025-09-03 01:15:00号 做空(跌包涨) 入场=4289.63 出场=4291.63 出场时间=1756834200000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 01:30:00号 做多(涨包跌) 入场=4307.71 出场=4305.71 出场时间=1756835100000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 02:00:00号 做多(涨包跌) 入场=4317.18 出场=4315.18 出场时间=1756836900000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 02:15:00号 做空(跌包涨) 入场=4293.70 出场=4295.70 出场时间=1756837800000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 03:00:00号 做多(涨包跌) 入场=4294.57 出场=4292.57 出场时间=1756840500000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 03:15:00号 做空(跌包涨) 入场=4271.11 出场=4273.11 出场时间=1756841400000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 03:45:00号 做多(涨包跌) 入场=4275.15 出场=4273.15 出场时间=1756843200000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 04:15:00号 做多(涨包跌) 入场=4294.16 出场=4324.16 出场时间=1756845000000 差价=30.00 盈利=69.86 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 05:15:00号 做多(涨包跌) 入场=4321.16 出场=4319.16 出场时间=1756848600000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 05:30:00号 做空(跌包涨) 入场=4308.71 出场=4310.71 出场时间=1756849500000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 05:45:00号 做多(涨包跌) 入场=4326.63 出场=4324.63 出场时间=1756850400000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 06:15:00号 做空(跌包涨) 入场=4323.50 出场=4325.50 出场时间=1756852200000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 06:45:00号 做多(涨包跌) 入场=4325.63 出场=4323.63 出场时间=1756854000000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 07:30:00号 做空(跌包涨) 入场=4318.13 出场=4320.13 出场时间=1756856700000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 08:00:00号 做多(涨包跌) 入场=4324.58 出场=4322.58 出场时间=1756858500000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 08:30:00号 做多(涨包跌) 入场=4325.28 出场=4323.28 出场时间=1756860300000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 08:45:00号 做空(跌包涨) 入场=4315.84 出场=4285.84 出场时间=1756862100000 差价=30.00 盈利=69.51 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 10:30:00号 做多(涨包跌) 入场=4351.50 出场=4349.50 出场时间=1756867500000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 12:00:00号 做多(涨包跌) 入场=4332.54 出场=4330.54 出场时间=1756872900000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 12:15:00号 做空(跌包涨) 入场=4318.84 出场=4320.84 出场时间=1756873800000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 13:15:00号 做空(跌包涨) 入场=4332.97 出场=4302.97 出场时间=1756879200000 差价=30.00 盈利=69.24 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 14:30:00号 做多(涨包跌) 入场=4314.99 出场=4312.99 出场时间=1756881900000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 15:45:00号 做多(涨包跌) 入场=4309.16 出场=4307.16 出场时间=1756886400000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 16:15:00号 做多(涨包跌) 入场=4321.12 出场=4319.12 出场时间=1756888200000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 16:45:00号 做多(涨包跌) 入场=4323.65 出场=4321.65 出场时间=1756890000000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 17:00:00号 做空(跌包涨) 入场=4316.15 出场=4318.15 出场时间=1756890900000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 17:30:00号 做多(涨包跌) 入场=4318.40 出场=4348.40 出场时间=1756892700000 差价=30.00 盈利=69.47 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 19:00:00号 做多(涨包跌) 入场=4369.61 出场=4367.61 出场时间=1756898100000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 19:45:00号 做多(涨包跌) 入场=4380.09 出场=4378.09 出场时间=1756900800000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 20:00:00号 做空(跌包涨) 入场=4369.58 出场=4371.58 出场时间=1756902600000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 20:45:00号 做空(跌包涨) 入场=4349.99 出场=4351.99 出场时间=1756904400000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 21:45:00号 做多(涨包跌) 入场=4417.77 出场=4447.77 出场时间=1756908000000 差价=30.00 盈利=67.91 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-03 23:45:00号 做多(涨包跌) 入场=4469.03 出场=4467.03 出场时间=1756915200000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-04 01:00:00号 做多(涨包跌) 入场=4464.29 出场=4462.29 出场时间=1756923300000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-04 02:30:00号 做空(跌包涨) 入场=4467.09 出场=4469.09 出场时间=1756928700000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-04 03:45:00号 做多(涨包跌) 入场=4463.71 出场=4461.71 出场时间=1756931400000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-04 05:15:00号 做多(涨包跌) 入场=4465.31 出场=4463.31 出场时间=1756935000000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-04 05:45:00号 做空(跌包涨) 入场=4454.44 出场=4456.44 出场时间=1756936800000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.368 | INFO | __main__:<module>:216 - 2025-09-04 07:15:00号 做空(跌包涨) 入场=4458.63 出场=4460.63 出场时间=1756942200000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 07:45:00号 做空(跌包涨) 入场=4446.35 出场=4448.35 出场时间=1756944000000 差价=-2.00 盈利=-4.50 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 09:15:00号 做空(跌包涨) 入场=4453.05 出场=4455.05 出场时间=1756949400000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 10:15:00号 做空(跌包涨) 入场=4458.70 出场=4428.70 出场时间=1756953000000 差价=30.00 盈利=67.28 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 11:45:00号 做空(跌包涨) 入场=4396.51 出场=4398.51 出场时间=1756958400000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 12:15:00号 做多(涨包跌) 入场=4401.01 出场=4399.01 出场时间=1756960200000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 12:45:00号 做多(涨包跌) 入场=4403.00 出场=4401.00 出场时间=1756962000000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 13:00:00号 做空(跌包涨) 入场=4389.87 出场=4359.87 出场时间=1756966500000 差价=30.00 盈利=68.34 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 14:00:00号 做多(涨包跌) 入场=4372.82 出场=4370.82 出场时间=1756966500000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 14:30:00号 做空(跌包涨) 入场=4366.72 出场=4368.72 出场时间=1756969200000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 16:00:00号 做多(涨包跌) 入场=4368.80 出场=4366.80 出场时间=1756975500000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 16:45:00号 做空(跌包涨) 入场=4373.25 出场=4375.25 出场时间=1756976400000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 17:15:00号 做多(涨包跌) 入场=4380.98 出场=4378.98 出场时间=1756978200000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 17:45:00号 做多(涨包跌) 入场=4384.86 出场=4414.86 出场时间=1756980900000 差价=30.00 盈利=68.42 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 18:45:00号 做多(涨包跌) 入场=4419.81 出场=4417.81 出场时间=1756983600000 差价=-2.00 盈利=-4.53 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 19:00:00号 做空(跌包涨) 入场=4405.14 出场=4407.14 出场时间=1756984500000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.370 | INFO | __main__:<module>:216 - 2025-09-04 19:15:00号 做多(涨包跌) 入场=4423.54 出场=4421.54 出场时间=1756985400000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-04 20:00:00号 做空(跌包涨) 入场=4404.40 出场=4406.40 出场时间=1756988100000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-04 21:00:00号 做多(涨包跌) 入场=4414.04 出场=4412.04 出场时间=1756991700000 差价=-2.00 盈利=-4.53 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-04 21:45:00号 做空(跌包涨) 入场=4381.48 出场=4351.48 出场时间=1756994400000 差价=30.00 盈利=68.47 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-04 23:00:00号 做空(跌包涨) 入场=4339.69 出场=4309.69 出场时间=1756998900000 差价=30.00 盈利=69.13 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 00:15:00号 做多(涨包跌) 入场=4306.10 出场=4304.10 出场时间=1757003400000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 00:30:00号 做空(跌包涨) 入场=4287.51 出场=4289.51 出场时间=1757004300000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 01:15:00号 做多(涨包跌) 入场=4305.80 出场=4303.80 出场时间=1757007000000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 01:45:00号 做空(跌包涨) 入场=4301.01 出场=4303.01 出场时间=1757008800000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 02:30:00号 做空(跌包涨) 入场=4278.68 出场=4280.68 出场时间=1757011500000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 03:00:00号 做空(跌包涨) 入场=4271.51 出场=4273.51 出场时间=1757013300000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 04:15:00号 做多(涨包跌) 入场=4294.31 出场=4324.31 出场时间=1757024100000 差价=30.00 盈利=69.86 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 05:30:00号 做多(涨包跌) 入场=4309.65 出场=4339.65 出场时间=1757025900000 差价=30.00 盈利=69.61 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 06:45:00号 做空(跌包涨) 入场=4315.58 出场=4317.58 出场时间=1757026800000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 07:00:00号 做多(涨包跌) 入场=4339.52 出场=4337.52 出场时间=1757027700000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 09:00:00号 做空(跌包涨) 入场=4298.93 出场=4300.93 出场时间=1757034900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 11:00:00号 做多(涨包跌) 入场=4321.58 出场=4319.58 出场时间=1757042100000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 11:15:00号 做空(跌包涨) 入场=4303.41 出场=4305.41 出场时间=1757043000000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 11:45:00号 做多(涨包跌) 入场=4312.51 出场=4342.51 出场时间=1757055600000 差价=30.00 盈利=69.57 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.371 | INFO | __main__:<module>:216 - 2025-09-05 13:45:00号 做多(涨包跌) 入场=4336.36 出场=4334.36 出场时间=1757052000000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-05 15:15:00号 做多(涨包跌) 入场=4354.09 出场=4384.09 出场时间=1757057400000 差价=30.00 盈利=68.90 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-05 17:15:00号 做空(跌包涨) 入场=4394.99 出场=4396.99 出场时间=1757064600000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-05 20:00:00号 做空(跌包涨) 入场=4415.56 出场=4417.56 出场时间=1757074500000 差价=-2.00 盈利=-4.53 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-05 21:00:00号 做多(涨包跌) 入场=4469.26 出场=4467.26 出场时间=1757078100000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 00:00:00号 做空(跌包涨) 入场=4280.44 出场=4282.44 出场时间=1757088900000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 00:45:00号 做多(涨包跌) 入场=4297.13 出场=4295.13 出场时间=1757091600000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 02:00:00号 做多(涨包跌) 入场=4287.32 出场=4285.32 出场时间=1757096100000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 02:30:00号 做多(涨包跌) 入场=4295.81 出场=4325.81 出场时间=1757099700000 差价=30.00 盈利=69.84 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 04:00:00号 做多(涨包跌) 入场=4328.97 出场=4326.97 出场时间=1757103300000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 04:45:00号 做多(涨包跌) 入场=4337.01 出场=4335.01 出场时间=1757106000000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 06:00:00号 做空(跌包涨) 入场=4294.51 出场=4296.51 出场时间=1757110500000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 06:45:00号 做多(涨包跌) 入场=4314.65 出场=4312.65 出场时间=1757113200000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 07:45:00号 做空(跌包涨) 入场=4308.19 出场=4310.19 出场时间=1757117700000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 08:30:00号 做多(涨包跌) 入场=4314.27 出场=4312.27 出场时间=1757122200000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 09:30:00号 做空(跌包涨) 入场=4313.82 出场=4315.82 出场时间=1757123100000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 13:00:00号 做多(涨包跌) 入场=4307.45 出场=4305.45 出场时间=1757135700000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.373 | INFO | __main__:<module>:216 - 2025-09-06 13:30:00号 做空(跌包涨) 入场=4295.99 出场=4297.99 出场时间=1757138400000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 14:15:00号 做多(涨包跌) 入场=4299.28 出场=4297.28 出场时间=1757149200000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 15:15:00号 做多(涨包跌) 入场=4306.50 出场=4304.50 出场时间=1757143800000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 15:45:00号 做多(涨包跌) 入场=4307.61 出场=4305.61 出场时间=1757145600000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 16:15:00号 做空(跌包涨) 入场=4305.07 出场=4307.07 出场时间=1757147400000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 17:45:00号 做多(涨包跌) 入场=4296.51 出场=4294.51 出场时间=1757152800000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 18:00:00号 做空(跌包涨) 入场=4291.09 出场=4293.09 出场时间=1757153700000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 18:45:00号 做多(涨包跌) 入场=4301.16 出场=4299.16 出场时间=1757156400000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 19:45:00号 做空(跌包涨) 入场=4293.71 出场=4295.71 出场时间=1757160000000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 20:00:00号 做多(涨包跌) 入场=4298.08 出场=4296.08 出场时间=1757160900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 20:30:00号 做空(跌包涨) 入场=4297.58 出场=4299.58 出场时间=1757162700000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 21:45:00号 做空(跌包涨) 入场=4291.70 出场=4293.70 出场时间=1757167200000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-06 23:00:00号 做空(跌包涨) 入场=4294.19 出场=4264.19 出场时间=1757173500000 差价=30.00 盈利=69.86 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 00:30:00号 做空(跌包涨) 入场=4257.59 出场=4259.59 出场时间=1757177100000 差价=-2.00 盈利=-4.70 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 00:45:00号 做多(涨包跌) 入场=4271.27 出场=4269.27 出场时间=1757179800000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 03:00:00号 做多(涨包跌) 入场=4276.85 出场=4274.85 出场时间=1757186100000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 04:15:00号 做多(涨包跌) 入场=4260.10 出场=4290.10 出场时间=1757206800000 差价=30.00 盈利=70.42 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 05:45:00号 做空(跌包涨) 入场=4271.09 出场=4273.09 出场时间=1757196000000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 06:00:00号 做多(涨包跌) 入场=4281.89 出场=4279.89 出场时间=1757196900000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 07:00:00号 做多(涨包跌) 入场=4275.91 出场=4273.91 出场时间=1757200500000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 07:45:00号 做空(跌包涨) 入场=4273.27 出场=4275.27 出场时间=1757203200000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.374 | INFO | __main__:<module>:216 - 2025-09-07 08:15:00号 做多(涨包跌) 入场=4277.06 出场=4275.06 出场时间=1757205000000 差价=-2.00 盈利=-4.68 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.375 | INFO | __main__:<module>:216 - 2025-09-07 08:45:00号 做多(涨包跌) 入场=4283.66 出场=4281.66 出场时间=1757206800000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 09:15:00号 做多(涨包跌) 入场=4289.62 出场=4287.62 出场时间=1757210400000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 10:30:00号 做多(涨包跌) 入场=4293.75 出场=4291.75 出场时间=1757216700000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 11:00:00号 做多(涨包跌) 入场=4297.65 出场=4295.65 出场时间=1757214900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 11:30:00号 做多(涨包跌) 入场=4300.79 出场=4298.79 出场时间=1757216700000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 13:00:00号 做多(涨包跌) 入场=4299.27 出场=4297.27 出场时间=1757222100000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 13:30:00号 做多(涨包跌) 入场=4300.38 出场=4298.38 出场时间=1757223900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 13:45:00号 做空(跌包涨) 入场=4292.60 出场=4294.60 出场时间=1757230200000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 14:15:00号 做空(跌包涨) 入场=4288.76 出场=4290.76 出场时间=1757226600000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 14:45:00号 做空(跌包涨) 入场=4284.83 出场=4286.83 出场时间=1757229300000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 16:15:00号 做多(涨包跌) 入场=4299.99 出场=4297.99 出场时间=1757235600000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 17:15:00号 做多(涨包跌) 入场=4304.68 出场=4302.68 出场时间=1757237400000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 17:30:00号 做空(跌包涨) 入场=4299.22 出场=4301.22 出场时间=1757239200000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 18:30:00号 做空(跌包涨) 入场=4297.80 出场=4299.80 出场时间=1757241900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 19:30:00号 做空(跌包涨) 入场=4301.86 出场=4303.86 出场时间=1757245500000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 20:15:00号 做空(跌包涨) 入场=4298.00 出场=4300.00 出场时间=1757248200000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 21:15:00号 做空(跌包涨) 入场=4294.46 出场=4296.46 出场时间=1757251800000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 22:45:00号 做多(涨包跌) 入场=4309.11 出场=4307.11 出场时间=1757257200000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 23:00:00号 做空(跌包涨) 入场=4298.01 出场=4300.01 出场时间=1757258100000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-07 23:30:00号 做多(涨包跌) 入场=4298.19 出场=4296.19 出场时间=1757259900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 00:00:00号 做空(跌包涨) 入场=4297.13 出场=4299.13 出场时间=1757283300000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 01:00:00号 做空(跌包涨) 入场=4281.91 出场=4283.91 出场时间=1757271600000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 01:45:00号 做多(涨包跌) 入场=4281.14 出场=4279.14 出场时间=1757268000000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 03:30:00号 做多(涨包跌) 入场=4279.60 出场=4309.60 出场时间=1757286000000 差价=30.00 盈利=70.10 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 06:00:00号 做空(跌包涨) 入场=4286.10 出场=4288.10 出场时间=1757283300000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 06:15:00号 做多(涨包跌) 入场=4294.90 出场=4292.90 出场时间=1757284200000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 07:00:00号 做多(涨包跌) 入场=4308.01 出场=4306.01 出场时间=1757288700000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 08:30:00号 做多(涨包跌) 入场=4314.79 出场=4312.79 出场时间=1757292300000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 10:15:00号 做空(跌包涨) 入场=4289.77 出场=4291.77 出场时间=1757298600000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 10:45:00号 做多(涨包跌) 入场=4301.19 出场=4299.19 出场时间=1757304000000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 11:30:00号 做多(涨包跌) 入场=4307.14 出场=4305.14 出场时间=1757304000000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 12:45:00号 做空(跌包涨) 入场=4301.22 出场=4303.22 出场时间=1757315700000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 13:45:00号 做空(跌包涨) 入场=4287.64 出场=4289.64 出场时间=1757311200000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 14:30:00号 做多(涨包跌) 入场=4299.95 出场=4297.95 出场时间=1757313900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 15:45:00号 做空(跌包涨) 入场=4293.26 出场=4295.26 出场时间=1757319300000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 17:15:00号 做多(涨包跌) 入场=4315.78 出场=4313.78 出场时间=1757323800000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 17:45:00号 做空(跌包涨) 入场=4310.70 出场=4312.70 出场时间=1757325600000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 19:00:00号 做空(跌包涨) 入场=4327.00 出场=4329.00 出场时间=1757336400000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 20:30:00号 做多(涨包跌) 入场=4313.57 出场=4343.57 出场时间=1757336400000 差价=30.00 盈利=69.55 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-08 21:15:00号 做多(涨包跌) 入场=4357.36 出场=4355.36 出场时间=1757338200000 差价=-2.00 盈利=-4.59 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 00:45:00号 做空(跌包涨) 入场=4345.02 出场=4315.02 出场时间=1757353500000 差价=30.00 盈利=69.04 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 01:30:00号 做多(涨包跌) 入场=4339.20 出场=4337.20 出场时间=1757353500000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 01:45:00号 做空(跌包涨) 入场=4323.36 出场=4325.36 出场时间=1757355300000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 03:00:00号 做多(涨包跌) 入场=4327.57 出场=4325.57 出场时间=1757358900000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 03:15:00号 做空(跌包涨) 入场=4312.48 出场=4282.48 出场时间=1757359800000 差价=30.00 盈利=69.57 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 06:30:00号 做空(跌包涨) 入场=4316.91 出场=4286.91 出场时间=1757377800000 差价=30.00 盈利=69.49 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 07:30:00号 做空(跌包涨) 入场=4301.76 出场=4303.76 出场时间=1757375100000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.376 | INFO | __main__:<module>:216 - 2025-09-09 08:00:00号 做多(涨包跌) 入场=4303.99 出场=4301.99 出场时间=1757376900000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 08:30:00号 做空(跌包涨) 入场=4298.46 出场=4300.46 出场时间=1757378700000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 09:00:00号 做多(涨包跌) 入场=4299.61 出场=4297.61 出场时间=1757380500000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 09:15:00号 做空(跌包涨) 入场=4296.12 出场=4298.12 出场时间=1757387700000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 10:00:00号 做空(跌包涨) 入场=4284.98 出场=4286.98 出场时间=1757384100000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 12:00:00号 做多(涨包跌) 入场=4304.98 出场=4302.98 出场时间=1757391300000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 12:30:00号 做多(涨包跌) 入场=4309.18 出场=4307.18 出场时间=1757393100000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 13:00:00号 做多(涨包跌) 入场=4311.76 出场=4309.76 出场时间=1757394900000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 13:15:00号 做空(跌包涨) 入场=4304.94 出场=4306.94 出场时间=1757395800000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 17:30:00号 做多(涨包跌) 入场=4364.44 出场=4362.44 出场时间=1757411100000 差价=-2.00 盈利=-4.58 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 18:30:00号 做空(跌包涨) 入场=4344.37 出场=4346.37 出场时间=1757414700000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 18:45:00号 做多(涨包跌) 入场=4357.24 出场=4355.24 出场时间=1757415600000 差价=-2.00 盈利=-4.59 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 20:15:00号 做多(涨包跌) 入场=4354.99 出场=4352.99 出场时间=1757421000000 差价=-2.00 盈利=-4.59 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 20:45:00号 做空(跌包涨) 入场=4346.93 出场=4348.93 出场时间=1757424600000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.377 | INFO | __main__:<module>:216 - 2025-09-09 23:15:00号 做空(跌包涨) 入场=4289.80 出场=4291.80 出场时间=1757432700000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 01:00:00号 做多(涨包跌) 入场=4286.31 出场=4284.31 出场时间=1757438100000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 01:30:00号 做空(跌包涨) 入场=4282.03 出场=4284.03 出场时间=1757439900000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 02:15:00号 做空(跌包涨) 入场=4283.63 出场=4285.63 出场时间=1757442600000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 02:30:00号 做多(涨包跌) 入场=4288.33 出场=4286.33 出场时间=1757443500000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 02:45:00号 做空(跌包涨) 入场=4280.97 出场=4282.97 出场时间=1757444400000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 04:15:00号 做空(跌包涨) 入场=4285.42 出场=4287.42 出场时间=1757449800000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 05:30:00号 做空(跌包涨) 入场=4297.59 出场=4299.59 出场时间=1757454300000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 06:45:00号 做多(涨包跌) 入场=4313.02 出场=4311.02 出场时间=1757458800000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 07:15:00号 做空(跌包涨) 入场=4310.76 出场=4312.76 出场时间=1757460600000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 07:45:00号 做多(涨包跌) 入场=4313.64 出场=4311.64 出场时间=1757462400000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 08:30:00号 做空(跌包涨) 入场=4296.21 出场=4298.21 出场时间=1757466900000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 09:00:00号 做空(跌包涨) 入场=4284.80 出场=4286.80 出场时间=1757466900000 差价=-2.00 盈利=-4.67 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.378 | INFO | __main__:<module>:216 - 2025-09-10 10:15:00号 做多(涨包跌) 入场=4311.47 出场=4309.47 出场时间=1757473200000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 11:00:00号 做空(跌包涨) 入场=4315.73 出场=4317.73 出场时间=1757474100000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 11:30:00号 做空(跌包涨) 入场=4308.70 出场=4310.70 出场时间=1757475900000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 13:15:00号 做空(跌包涨) 入场=4308.49 出场=4310.49 出场时间=1757482200000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 13:30:00号 做多(涨包跌) 入场=4312.14 出场=4310.14 出场时间=1757483100000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 14:00:00号 做空(跌包涨) 入场=4306.35 出场=4308.35 出场时间=1757484900000 差价=-2.00 盈利=-4.64 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 14:30:00号 做多(涨包跌) 入场=4308.01 出场=4338.01 出场时间=1757506500000 差价=30.00 盈利=69.64 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 15:15:00号 做多(涨包跌) 入场=4317.26 出场=4315.26 出场时间=1757494800000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 16:30:00号 做空(跌包涨) 入场=4327.00 出场=4329.00 出场时间=1757493900000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 17:15:00号 做空(跌包涨) 入场=4316.58 出场=4318.58 出场时间=1757496600000 差价=-2.00 盈利=-4.63 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 18:30:00号 做多(涨包跌) 入场=4327.20 出场=4325.20 出场时间=1757501100000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 19:00:00号 做空(跌包涨) 入场=4325.23 出场=4327.23 出场时间=1757502900000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 19:15:00号 做多(涨包跌) 入场=4330.73 出场=4328.73 出场时间=1757503800000 差价=-2.00 盈利=-4.62 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 20:00:00号 做多(涨包跌) 入场=4329.56 出场=4359.56 出场时间=1757507400000 差价=30.00 盈利=69.29 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 21:15:00号 做多(涨包跌) 入场=4382.99 出场=4380.99 出场时间=1757511000000 差价=-2.00 盈利=-4.56 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.380 | INFO | __main__:<module>:216 - 2025-09-10 21:45:00号 做多(涨包跌) 入场=4386.20 出场=4416.20 出场时间=1757512800000 差价=30.00 盈利=68.40 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.381 | INFO | __main__:<module>:216 - 2025-09-10 23:15:00号 做多(涨包跌) 入场=4421.51 出场=4419.51 出场时间=1757518200000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 00:00:00号 做空(跌包涨) 入场=4403.47 出场=4373.47 出场时间=1757520900000 差价=30.00 盈利=68.13 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 01:30:00号 做空(跌包涨) 入场=4346.68 出场=4348.68 出场时间=1757526300000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 05:15:00号 做多(涨包跌) 入场=4337.51 出场=4335.51 出场时间=1757539800000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 05:45:00号 做多(涨包跌) 入场=4346.90 出场=4344.90 出场时间=1757542500000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 06:30:00号 做空(跌包涨) 入场=4344.22 出场=4346.22 出场时间=1757544300000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 07:30:00号 做空(跌包涨) 入场=4342.82 出场=4344.82 出场时间=1757547900000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 08:15:00号 做空(跌包涨) 入场=4336.86 出场=4338.86 出场时间=1757550600000 差价=-2.00 盈利=-4.61 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 09:00:00号 做多(涨包跌) 入场=4357.50 出场=4387.50 出场时间=1757560500000 差价=30.00 盈利=68.85 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 10:15:00号 做多(涨包跌) 入场=4373.00 出场=4371.00 出场时间=1757557800000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 10:45:00号 做多(涨包跌) 入场=4379.99 出场=4377.99 出场时间=1757559600000 差价=-2.00 盈利=-4.57 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 12:00:00号 做多(涨包跌) 入场=4402.00 出场=4400.00 出场时间=1757567700000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 12:30:00号 做多(涨包跌) 入场=4411.97 出场=4409.97 出场时间=1757565900000 差价=-2.00 盈利=-4.53 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 13:00:00号 做空(跌包涨) 入场=4409.99 出场=4411.99 出场时间=1757567700000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 15:30:00号 做空(跌包涨) 入场=4435.47 出场=4437.47 出场时间=1757576700000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 16:45:00号 做多(涨包跌) 入场=4436.04 出场=4434.04 出场时间=1757581200000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.382 | INFO | __main__:<module>:216 - 2025-09-11 18:00:00号 做多(涨包跌) 入场=4415.02 出场=4445.02 出场时间=1757592000000 差价=30.00 盈利=67.95 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 19:00:00号 做多(涨包跌) 入场=4426.37 出场=4424.37 出场时间=1757590200000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 19:30:00号 做空(跌包涨) 入场=4425.53 出场=4427.53 出场时间=1757591100000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 19:45:00号 做多(涨包跌) 入场=4434.28 出场=4432.28 出场时间=1757592000000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 20:15:00号 做多(涨包跌) 入场=4452.46 出场=4450.46 出场时间=1757593800000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 20:45:00号 做空(跌包涨) 入场=4413.23 出场=4383.23 出场时间=1757595600000 差价=30.00 盈利=67.98 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 21:15:00号 做空(跌包涨) 入场=4390.85 出场=4392.85 出场时间=1757597400000 差价=-2.00 盈利=-4.55 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 22:00:00号 做多(涨包跌) 入场=4434.65 出场=4432.65 出场时间=1757600100000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-11 22:45:00号 做多(涨包跌) 入场=4428.48 出场=4426.48 出场时间=1757602800000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 00:30:00号 做空(跌包涨) 入场=4409.53 出场=4411.53 出场时间=1757609100000 差价=-2.00 盈利=-4.54 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 01:15:00号 做多(涨包跌) 入场=4428.67 出场=4426.67 出场时间=1757611800000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 01:45:00号 做多(涨包跌) 入场=4434.41 出场=4432.41 出场时间=1757613600000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 03:30:00号 做多(涨包跌) 入场=4421.36 出场=4419.36 出场时间=1757620800000 差价=-2.00 盈利=-4.52 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 05:45:00号 做多(涨包跌) 入场=4421.45 出场=4451.45 出场时间=1757630700000 差价=30.00 盈利=67.85 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 06:30:00号 做多(涨包跌) 入场=4441.44 出场=4471.44 出场时间=1757637000000 差价=30.00 盈利=67.55 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 08:30:00号 做多(涨包跌) 入场=4461.82 出场=4491.82 出场时间=1757637900000 差价=30.00 盈利=67.24 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 12:00:00号 做多(涨包跌) 入场=4503.64 出场=4533.64 出场时间=1757655900000 差价=30.00 盈利=66.61 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 13:15:00号 做空(跌包涨) 入场=4514.86 出场=4516.86 出场时间=1757655000000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 15:15:00号 做多(涨包跌) 入场=4544.41 出场=4542.41 出场时间=1757662200000 差价=-2.00 盈利=-4.40 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 15:30:00号 做空(跌包涨) 入场=4537.01 出场=4507.01 出场时间=1757670300000 差价=30.00 盈利=66.12 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 17:15:00号 做多(涨包跌) 入场=4522.01 出场=4520.01 出场时间=1757669400000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.383 | INFO | __main__:<module>:216 - 2025-09-12 17:30:00号 做空(跌包涨) 入场=4516.28 出场=4518.28 出场时间=1757670300000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-12 18:00:00号 做空(跌包涨) 入场=4513.69 出场=4515.69 出场时间=1757672100000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-12 18:30:00号 做空(跌包涨) 入场=4509.80 出场=4511.80 出场时间=1757673900000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-12 21:00:00号 做多(涨包跌) 入场=4524.96 出场=4522.96 出场时间=1757682900000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-12 22:00:00号 做多(涨包跌) 入场=4537.98 出场=4567.98 出场时间=1757686500000 差价=30.00 盈利=66.11 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-12 22:45:00号 做空(跌包涨) 入场=4523.25 出场=4525.25 出场时间=1757689200000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-12 23:45:00号 做多(涨包跌) 入场=4539.35 出场=4537.35 出场时间=1757692800000 差价=-2.00 盈利=-4.41 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-13 01:00:00号 做多(涨包跌) 入场=4573.66 出场=4571.66 出场时间=1757697300000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-13 02:30:00号 做多(涨包跌) 入场=4612.59 出场=4610.59 出场时间=1757702700000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-13 03:30:00号 做多(涨包跌) 入场=4627.09 出场=4657.09 出场时间=1757706300000 差价=30.00 盈利=64.84 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-13 04:15:00号 做空(跌包涨) 入场=4640.52 出场=4642.52 出场时间=1757709000000 差价=-2.00 盈利=-4.31 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-13 06:15:00号 做多(涨包跌) 入场=4662.69 出场=4692.69 出场时间=1757716200000 差价=30.00 盈利=64.34 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.384 | INFO | __main__:<module>:216 - 2025-09-13 07:30:00号 做多(涨包跌) 入场=4705.12 出场=4703.12 出场时间=1757720700000 差价=-2.00 盈利=-4.25 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.385 | INFO | __main__:<module>:216 - 2025-09-13 08:00:00号 做多(涨包跌) 入场=4710.83 出场=4708.83 出场时间=1757722500000 差价=-2.00 盈利=-4.25 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 08:45:00号 做多(涨包跌) 入场=4699.24 出场=4729.24 出场时间=1757725200000 差价=30.00 盈利=63.84 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 11:15:00号 做多(涨包跌) 入场=4711.38 出场=4741.38 出场时间=1757734200000 差价=30.00 盈利=63.68 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 12:15:00号 做空(跌包涨) 入场=4736.89 出场=4738.89 出场时间=1757737800000 差价=-2.00 盈利=-4.22 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 12:45:00号 做多(涨包跌) 入场=4745.06 出场=4743.06 出场时间=1757739600000 差价=-2.00 盈利=-4.21 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 14:15:00号 做多(涨包跌) 入场=4726.83 出场=4724.83 出场时间=1757745000000 差价=-2.00 盈利=-4.23 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 14:30:00号 做空(跌包涨) 入场=4713.13 出场=4715.13 出场时间=1757747700000 差价=-2.00 盈利=-4.24 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 15:15:00号 做多(涨包跌) 入场=4712.78 出场=4710.78 出场时间=1757749500000 差价=-2.00 盈利=-4.24 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 16:15:00号 做多(涨包跌) 入场=4716.82 出场=4714.82 出场时间=1757759400000 差价=-2.00 盈利=-4.24 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 16:45:00号 做多(涨包跌) 入场=4722.10 出场=4720.10 出场时间=1757754900000 差价=-2.00 盈利=-4.24 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 18:30:00号 做空(跌包涨) 入场=4718.32 出场=4720.32 出场时间=1757763000000 差价=-2.00 盈利=-4.24 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 21:30:00号 做多(涨包跌) 入场=4722.50 出场=4720.50 出场时间=1757771100000 差价=-2.00 盈利=-4.24 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 21:45:00号 做空(跌包涨) 入场=4710.16 出场=4680.16 出场时间=1757772000000 差价=30.00 盈利=63.69 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 22:30:00号 做多(涨包跌) 入场=4699.16 出场=4697.16 出场时间=1757774700000 差价=-2.00 盈利=-4.26 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-13 23:30:00号 做空(跌包涨) 入场=4679.37 出场=4649.37 出场时间=1757778300000 差价=30.00 盈利=64.11 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-14 04:00:00号 做空(跌包涨) 入场=4635.56 出场=4637.56 出场时间=1757794500000 差价=-2.00 盈利=-4.31 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-14 04:15:00号 做多(涨包跌) 入场=4655.26 出场=4653.26 出场时间=1757795400000 差价=-2.00 盈利=-4.30 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-14 05:00:00号 做多(涨包跌) 入场=4655.22 出场=4653.22 出场时间=1757801700000 差价=-2.00 盈利=-4.30 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.386 | INFO | __main__:<module>:216 - 2025-09-14 06:00:00号 做多(涨包跌) 入场=4661.08 出场=4659.08 出场时间=1757801700000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 07:00:00号 做多(涨包跌) 入场=4656.48 出场=4654.48 出场时间=1757806200000 差价=-2.00 盈利=-4.30 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 08:00:00号 做多(涨包跌) 入场=4664.77 出场=4662.77 出场时间=1757810700000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 09:15:00号 做空(跌包涨) 入场=4653.35 出场=4655.35 出场时间=1757813400000 差价=-2.00 盈利=-4.30 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 11:00:00号 做多(涨包跌) 入场=4681.64 出场=4679.64 出场时间=1757819700000 差价=-2.00 盈利=-4.27 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 11:15:00号 做空(跌包涨) 入场=4673.93 出场=4643.93 出场时间=1757823300000 差价=30.00 盈利=64.19 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 13:15:00号 做多(涨包跌) 入场=4666.86 出场=4664.86 出场时间=1757829600000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 14:15:00号 做空(跌包涨) 入场=4668.51 出场=4670.51 出场时间=1757841300000 差价=-2.00 盈利=-4.28 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 14:45:00号 做空(跌包涨) 入场=4660.54 出场=4662.54 出场时间=1757833200000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 15:15:00号 做空(跌包涨) 入场=4659.38 出场=4661.38 出场时间=1757835000000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 15:45:00号 做空(跌包涨) 入场=4658.02 出场=4660.02 出场时间=1757838600000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 17:00:00号 做空(跌包涨) 入场=4654.18 出场=4656.18 出场时间=1757841300000 差价=-2.00 盈利=-4.30 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 18:00:00号 做空(跌包涨) 入场=4663.76 出场=4665.76 出场时间=1757844900000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 19:30:00号 做空(跌包涨) 入场=4638.18 出场=4640.18 出场时间=1757852100000 差价=-2.00 盈利=-4.31 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 20:30:00号 做多(涨包跌) 入场=4640.66 出场=4638.66 出场时间=1757853900000 差价=-2.00 盈利=-4.31 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 20:45:00号 做空(跌包涨) 入场=4625.76 出场=4627.76 出场时间=1757854800000 差价=-2.00 盈利=-4.32 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 21:15:00号 做空(跌包涨) 入场=4621.87 出场=4623.87 出场时间=1757856600000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 22:00:00号 做空(跌包涨) 入场=4610.66 出场=4612.66 出场时间=1757859300000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 22:15:00号 做多(涨包跌) 入场=4630.71 出场=4628.71 出场时间=1757860200000 差价=-2.00 盈利=-4.32 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 23:15:00号 做空(跌包涨) 入场=4586.03 出场=4588.03 出场时间=1757863800000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.387 | INFO | __main__:<module>:216 - 2025-09-14 23:45:00号 做空(跌包涨) 入场=4584.48 出场=4586.48 出场时间=1757865600000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 00:15:00号 做多(涨包跌) 入场=4586.68 出场=4616.68 出场时间=1757870100000 差价=30.00 盈利=65.41 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 01:00:00号 做空(跌包涨) 入场=4595.18 出场=4597.18 出场时间=1757870100000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 03:15:00号 做多(涨包跌) 入场=4609.78 出场=4607.78 出场时间=1757883600000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 04:00:00号 做空(跌包涨) 入场=4613.99 出场=4615.99 出场时间=1757880900000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 04:15:00号 做多(涨包跌) 入场=4624.18 出场=4622.18 出场时间=1757881800000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 05:00:00号 做空(跌包涨) 入场=4614.96 出场=4616.96 出场时间=1757884500000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 05:30:00号 做空(跌包涨) 入场=4613.57 出场=4615.57 出场时间=1757886300000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 05:45:00号 做多(涨包跌) 入场=4633.00 出场=4631.00 出场时间=1757887200000 差价=-2.00 盈利=-4.32 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 08:30:00号 做多(涨包跌) 入场=4613.20 出场=4611.20 出场时间=1757897100000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 09:30:00号 做多(涨包跌) 入场=4601.91 出场=4631.91 出场时间=1757905200000 差价=30.00 盈利=65.19 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 10:30:00号 做空(跌包涨) 入场=4615.91 出场=4617.91 出场时间=1757904300000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 11:15:00号 做多(涨包跌) 入场=4630.48 出场=4628.48 出场时间=1757907000000 差价=-2.00 盈利=-4.32 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 12:00:00号 做多(涨包跌) 入场=4634.46 出场=4664.46 出场时间=1757916000000 差价=30.00 盈利=64.73 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 13:15:00号 做多(涨包跌) 入场=4648.29 出场=4646.29 出场时间=1757917800000 差价=-2.00 盈利=-4.30 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 14:00:00号 做多(涨包跌) 入场=4660.51 出场=4658.51 出场时间=1757916900000 差价=-2.00 盈利=-4.29 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.388 | INFO | __main__:<module>:216 - 2025-09-15 14:30:00号 做空(跌包涨) 入场=4649.31 出场=4619.31 出场时间=1757918700000 差价=30.00 盈利=64.53 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-15 15:30:00号 做空(跌包涨) 入场=4623.51 出场=4593.51 出场时间=1757922300000 差价=30.00 盈利=64.89 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-15 19:30:00号 做空(跌包涨) 入场=4527.63 出场=4529.63 出场时间=1757936700000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-15 20:30:00号 做空(跌包涨) 入场=4512.65 出场=4514.65 出场时间=1757940300000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-15 21:45:00号 做空(跌包涨) 入场=4495.32 出场=4497.32 出场时间=1757944800000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-15 22:30:00号 做多(涨包跌) 入场=4525.84 出场=4523.84 出场时间=1757947500000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 00:00:00号 做多(涨包跌) 入场=4497.47 出场=4495.47 出场时间=1757952900000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 00:30:00号 做空(跌包涨) 入场=4490.54 出场=4492.54 出场时间=1757954700000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 00:45:00号 做多(涨包跌) 入场=4508.90 出场=4506.90 出场时间=1757955600000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 01:30:00号 做空(跌包涨) 入场=4484.02 出场=4486.02 出场时间=1757958300000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 02:15:00号 做空(跌包涨) 入场=4492.05 出场=4494.05 出场时间=1757961000000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 03:00:00号 做多(涨包跌) 入场=4499.06 出场=4497.06 出场时间=1757963700000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 04:15:00号 做多(涨包跌) 入场=4499.05 出场=4529.05 出场时间=1757985300000 差价=30.00 盈利=66.68 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 05:15:00号 做多(涨包跌) 入场=4508.91 出场=4506.91 出场时间=1757977200000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 06:15:00号 做空(跌包涨) 入场=4519.44 出场=4521.44 出场时间=1757978100000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.389 | INFO | __main__:<module>:216 - 2025-09-16 07:15:00号 做多(涨包跌) 入场=4517.10 出场=4515.10 出场时间=1757980800000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 08:15:00号 做空(跌包涨) 入场=4514.54 出场=4516.54 出场时间=1757984400000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 10:15:00号 做多(涨包跌) 入场=4525.99 出场=4523.99 出场时间=1757989800000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 14:30:00号 做空(跌包涨) 入场=4514.40 出场=4516.40 出场时间=1758009600000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 15:15:00号 做空(跌包涨) 入场=4503.94 出场=4505.94 出场时间=1758007800000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 15:30:00号 做多(涨包跌) 入场=4508.98 出场=4506.98 出场时间=1758011400000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 16:00:00号 做多(涨包跌) 入场=4510.63 出场=4508.63 出场时间=1758011400000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 18:00:00号 做多(涨包跌) 入场=4509.35 出场=4507.35 出场时间=1758017700000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 19:30:00号 做多(涨包跌) 入场=4498.85 出场=4496.85 出场时间=1758023100000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 20:00:00号 做多(涨包跌) 入场=4499.40 出场=4497.40 出场时间=1758024900000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 20:45:00号 做多(涨包跌) 入场=4499.52 出场=4497.52 出场时间=1758027600000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 21:30:00号 做多(涨包跌) 入场=4506.71 出场=4504.71 出场时间=1758030300000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 21:45:00号 做空(跌包涨) 入场=4452.91 出场=4422.91 出场时间=1758031200000 差价=30.00 盈利=67.37 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 22:15:00号 做空(跌包涨) 入场=4432.50 出场=4434.50 出场时间=1758033000000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-16 23:15:00号 做空(跌包涨) 入场=4431.53 出场=4433.53 出场时间=1758036600000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-17 00:45:00号 做空(跌包涨) 入场=4456.88 出场=4458.88 出场时间=1758042000000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.390 | INFO | __main__:<module>:216 - 2025-09-17 01:00:00号 做多(涨包跌) 入场=4461.10 出场=4491.10 出场时间=1758042900000 差价=30.00 盈利=67.25 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 02:30:00号 做空(跌包涨) 入场=4481.50 出场=4483.50 出场时间=1758050100000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 05:15:00号 做空(跌包涨) 入场=4490.49 出场=4492.49 出场时间=1758058200000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 06:30:00号 做空(跌包涨) 入场=4505.59 出场=4507.59 出场时间=1758062700000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 06:45:00号 做多(涨包跌) 入场=4517.88 出场=4515.88 出场时间=1758063600000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 08:15:00号 做空(跌包涨) 入场=4495.76 出场=4497.76 出场时间=1758069000000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 08:30:00号 做多(涨包跌) 入场=4509.69 出场=4507.69 出场时间=1758069900000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 09:30:00号 做多(涨包跌) 入场=4514.84 出场=4512.84 出场时间=1758073500000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 09:45:00号 做空(跌包涨) 入场=4504.59 出场=4506.59 出场时间=1758074400000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 10:30:00号 做多(涨包跌) 入场=4514.12 出场=4544.12 出场时间=1758077100000 差价=30.00 盈利=66.46 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 12:30:00号 做空(跌包涨) 入场=4485.88 出场=4487.88 出场时间=1758085200000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 13:15:00号 做多(涨包跌) 入场=4484.36 出场=4482.36 出场时间=1758087000000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 13:45:00号 做多(涨包跌) 入场=4488.67 出场=4518.67 出场时间=1758089700000 差价=30.00 盈利=66.83 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 15:30:00号 做空(跌包涨) 入场=4539.99 出场=4541.99 出场时间=1758095100000 差价=-2.00 盈利=-4.41 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 16:00:00号 做多(涨包跌) 入场=4542.30 出场=4540.30 出场时间=1758096900000 差价=-2.00 盈利=-4.40 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 16:15:00号 做空(跌包涨) 入场=4515.06 出场=4485.06 出场时间=1758104100000 差价=30.00 盈利=66.44 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 17:00:00号 做多(涨包跌) 入场=4509.28 出场=4507.28 出场时间=1758100500000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.391 | INFO | __main__:<module>:216 - 2025-09-17 17:45:00号 做空(跌包涨) 入场=4501.69 出场=4503.69 出场时间=1758111300000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-17 19:00:00号 做空(跌包涨) 入场=4482.16 出场=4484.16 出场时间=1758107700000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-17 19:15:00号 做多(涨包跌) 入场=4487.54 出场=4485.54 出场时间=1758110400000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-17 20:15:00号 做空(跌包涨) 入场=4488.35 出场=4490.35 出场时间=1758112200000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-17 20:30:00号 做多(涨包跌) 入场=4504.63 出场=4502.63 出场时间=1758113100000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-17 22:30:00号 做空(跌包涨) 入场=4472.54 出场=4474.54 出场时间=1758120300000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-17 23:30:00号 做空(跌包涨) 入场=4480.00 出场=4482.00 出场时间=1758123900000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 01:15:00号 做空(跌包涨) 入场=4479.93 出场=4481.93 出场时间=1758130200000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 02:00:00号 做空(跌包涨) 入场=4436.71 出场=4438.71 出场时间=1758132900000 差价=-2.00 盈利=-4.51 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 02:45:00号 做空(跌包涨) 入场=4440.70 出场=4442.70 出场时间=1758135600000 差价=-2.00 盈利=-4.50 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 04:30:00号 做空(跌包涨) 入场=4512.43 出场=4514.43 出场时间=1758141900000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 05:15:00号 做多(涨包跌) 入场=4515.31 出场=4545.31 出场时间=1758146400000 差价=30.00 盈利=66.44 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 05:45:00号 做多(涨包跌) 入场=4528.32 出场=4526.32 出场时间=1758146400000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 06:15:00号 做多(涨包跌) 入场=4546.07 出场=4576.07 出场时间=1758149100000 差价=30.00 盈利=65.99 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 08:00:00号 做多(涨包跌) 入场=4588.29 出场=4586.29 出场时间=1758156300000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 09:00:00号 做空(跌包涨) 入场=4582.62 出场=4584.62 出场时间=1758158100000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 09:15:00号 做多(涨包跌) 入场=4602.25 出场=4632.25 出场时间=1758164400000 差价=30.00 盈利=65.19 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.392 | INFO | __main__:<module>:216 - 2025-09-18 12:30:00号 做空(跌包涨) 入场=4605.82 出场=4607.82 出场时间=1758170700000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.393 | INFO | __main__:<module>:216 - 2025-09-18 13:00:00号 做多(涨包跌) 入场=4609.48 出场=4607.48 出场时间=1758172500000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.393 | INFO | __main__:<module>:216 - 2025-09-18 13:15:00号 做空(跌包涨) 入场=4600.42 出场=4570.42 出场时间=1758175200000 差价=30.00 盈利=65.21 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.393 | INFO | __main__:<module>:216 - 2025-09-18 14:15:00号 做空(跌包涨) 入场=4561.37 出场=4563.37 出场时间=1758177000000 差价=-2.00 盈利=-4.38 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 14:45:00号 做多(涨包跌) 入场=4566.29 出场=4596.29 出场时间=1758184200000 差价=30.00 盈利=65.70 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 16:00:00号 做空(跌包涨) 入场=4573.09 出场=4575.09 出场时间=1758183300000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 16:15:00号 做多(涨包跌) 入场=4581.08 出场=4579.08 出场时间=1758190500000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 17:45:00号 做空(跌包涨) 入场=4590.39 出场=4592.39 出场时间=1758189600000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 18:15:00号 做空(跌包涨) 入场=4585.79 出场=4587.79 出场时间=1758202200000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 19:15:00号 做多(涨包跌) 入场=4579.55 出场=4577.55 出场时间=1758195000000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 19:45:00号 做空(跌包涨) 入场=4573.40 出场=4575.40 出场时间=1758196800000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 20:45:00号 做空(跌包涨) 入场=4576.54 出场=4578.54 出场时间=1758200400000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 21:15:00号 做多(涨包跌) 入场=4579.42 出场=4577.42 出场时间=1758202200000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 21:45:00号 做空(跌包涨) 入场=4571.96 出场=4573.96 出场时间=1758204000000 差价=-2.00 盈利=-4.37 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 22:00:00号 做多(涨包跌) 入场=4586.05 出场=4616.05 出场时间=1758204900000 差价=30.00 盈利=65.42 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-18 22:45:00号 做空(跌包涨) 入场=4598.00 出场=4600.00 出场时间=1758207600000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 00:30:00号 做多(涨包跌) 入场=4613.82 出场=4611.82 出场时间=1758214800000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 02:00:00号 做多(涨包跌) 入场=4607.20 出场=4605.20 出场时间=1758219300000 差价=-2.00 盈利=-4.34 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 03:00:00号 做多(涨包跌) 入场=4616.17 出场=4614.17 出场时间=1758222900000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 03:15:00号 做空(跌包涨) 入场=4604.49 出场=4574.49 出场时间=1758236400000 差价=30.00 盈利=65.15 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 04:00:00号 做空(跌包涨) 入场=4586.07 出场=4588.07 出场时间=1758226500000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 04:15:00号 做多(涨包跌) 入场=4594.26 出场=4592.26 出场时间=1758227400000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.394 | INFO | __main__:<module>:216 - 2025-09-19 04:45:00号 做多(涨包跌) 入场=4600.84 出场=4598.84 出场时间=1758229200000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 05:15:00号 做空(跌包涨) 入场=4592.22 出场=4594.22 出场时间=1758231000000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 06:00:00号 做空(跌包涨) 入场=4592.68 出场=4594.68 出场时间=1758233700000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 06:30:00号 做多(涨包跌) 入场=4593.16 出场=4591.16 出场时间=1758235500000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 07:00:00号 做空(跌包涨) 入场=4589.04 出场=4591.04 出场时间=1758240000000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 07:45:00号 做多(涨包跌) 入场=4583.92 出场=4613.92 出场时间=1758244500000 差价=30.00 盈利=65.45 开仓手续费=5u 平仓手续费=5.03
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 09:30:00号 做多(涨包跌) 入场=4614.98 出场=4612.98 出场时间=1758246300000 差价=-2.00 盈利=-4.33 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 10:15:00号 做空(跌包涨) 入场=4596.00 出场=4598.00 出场时间=1758249000000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 11:00:00号 做空(跌包涨) 入场=4586.87 出场=4588.87 出场时间=1758251700000 差价=-2.00 盈利=-4.36 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 11:15:00号 做多(涨包跌) 入场=4594.12 出场=4592.12 出场时间=1758252600000 差价=-2.00 盈利=-4.35 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 11:30:00号 做空(跌包涨) 入场=4575.51 出场=4545.51 出场时间=1758253500000 差价=30.00 盈利=65.57 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 14:15:00号 做空(跌包涨) 入场=4531.27 出场=4533.27 出场时间=1758263400000 差价=-2.00 盈利=-4.41 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 14:45:00号 做空(跌包涨) 入场=4531.00 出场=4533.00 出场时间=1758266100000 差价=-2.00 盈利=-4.41 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 16:15:00号 做多(涨包跌) 入场=4540.60 出场=4538.60 出场时间=1758270600000 差价=-2.00 盈利=-4.40 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 17:15:00号 做多(涨包跌) 入场=4539.75 出场=4537.75 出场时间=1758274200000 差价=-2.00 盈利=-4.41 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.396 | INFO | __main__:<module>:216 - 2025-09-19 17:30:00号 做空(跌包涨) 入场=4529.53 出场=4531.53 出场时间=1758287700000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-19 18:15:00号 做多(涨包跌) 入场=4526.68 出场=4524.68 出场时间=1758277800000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-19 18:45:00号 做多(涨包跌) 入场=4529.15 出场=4527.15 出场时间=1758279600000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-19 20:30:00号 做空(跌包涨) 入场=4511.06 出场=4513.06 出场时间=1758285900000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-19 20:45:00号 做多(涨包跌) 入场=4516.78 出场=4514.78 出场时间=1758288600000 差价=-2.00 盈利=-4.43 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-19 21:15:00号 做多(涨包跌) 入场=4524.99 出场=4522.99 出场时间=1758288600000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-19 22:00:00号 做多(涨包跌) 入场=4525.81 出场=4523.81 出场时间=1758292200000 差价=-2.00 盈利=-4.42 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 00:15:00号 做多(涨包跌) 入场=4480.10 出场=4478.10 出场时间=1758299400000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 01:00:00号 做空(跌包涨) 入场=4478.90 出场=4448.90 出场时间=1758304800000 差价=30.00 盈利=66.98 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 03:00:00号 做空(跌包涨) 入场=4446.67 出场=4448.67 出场时间=1758309300000 差价=-2.00 盈利=-4.50 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 03:15:00号 做多(涨包跌) 入场=4457.43 出场=4455.43 出场时间=1758310200000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 03:45:00号 做空(跌包涨) 入场=4450.00 出场=4452.00 出场时间=1758312000000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 05:00:00号 做空(跌包涨) 入场=4457.40 出场=4459.40 出场时间=1758316500000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 07:45:00号 做多(涨包跌) 入场=4457.59 出场=4455.59 出场时间=1758331800000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 08:30:00号 做空(跌包涨) 入场=4460.41 出场=4462.41 出场时间=1758329100000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 08:45:00号 做多(涨包跌) 入场=4470.38 出场=4468.38 出场时间=1758330000000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 09:15:00号 做空(跌包涨) 入场=4464.23 出场=4466.23 出场时间=1758331800000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 11:45:00号 做多(涨包跌) 入场=4463.37 出场=4461.37 出场时间=1758340800000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 12:30:00号 做空(跌包涨) 入场=4462.81 出场=4464.81 出场时间=1758343500000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 12:45:00号 做多(涨包跌) 入场=4471.24 出场=4469.24 出场时间=1758344400000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 14:00:00号 做多(涨包跌) 入场=4476.31 出场=4474.31 出场时间=1758348900000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 14:15:00号 做空(跌包涨) 入场=4468.99 出场=4470.99 出场时间=1758349800000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 15:30:00号 做空(跌包涨) 入场=4468.61 出场=4470.61 出场时间=1758354300000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 15:45:00号 做多(涨包跌) 入场=4473.80 出场=4471.80 出场时间=1758357900000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 16:45:00号 做多(涨包跌) 入场=4474.98 出场=4472.98 出场时间=1758358800000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.397 | INFO | __main__:<module>:216 - 2025-09-20 17:00:00号 做空(跌包涨) 入场=4463.04 出场=4465.04 出场时间=1758359700000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-20 17:30:00号 做空(跌包涨) 入场=4463.00 出场=4465.00 出场时间=1758361500000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-20 18:00:00号 做多(涨包跌) 入场=4463.69 出场=4461.69 出场时间=1758365100000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-20 19:15:00号 做多(涨包跌) 入场=4467.67 出场=4465.67 出场时间=1758367800000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-20 21:30:00号 做多(涨包跌) 入场=4467.02 出场=4465.02 出场时间=1758376800000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-20 22:00:00号 做空(跌包涨) 入场=4466.11 出场=4468.11 出场时间=1758378600000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 00:15:00号 做多(涨包跌) 入场=4497.37 出场=4495.37 出场时间=1758385800000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 00:30:00号 做空(跌包涨) 入场=4492.10 出场=4494.10 出场时间=1758386700000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 00:45:00号 做多(涨包跌) 入场=4502.10 出场=4500.10 出场时间=1758387600000 差价=-2.00 盈利=-4.44 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 02:15:00号 做空(跌包涨) 入场=4479.14 出场=4481.14 出场时间=1758393000000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 05:00:00号 做空(跌包涨) 入场=4481.76 出场=4483.76 出场时间=1758402900000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 05:15:00号 做多(涨包跌) 入场=4489.11 出场=4487.11 出场时间=1758404700000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 06:45:00号 做空(跌包涨) 入场=4487.79 出场=4489.79 出场时间=1758409200000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 07:15:00号 做空(跌包涨) 入场=4486.31 出场=4456.31 出场时间=1758420900000 差价=30.00 盈利=66.87 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 08:15:00号 做多(涨包跌) 入场=4480.64 出场=4478.64 出场时间=1758414600000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 08:30:00号 做空(跌包涨) 入场=4474.88 出场=4476.88 出场时间=1758415500000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.399 | INFO | __main__:<module>:216 - 2025-09-21 08:45:00号 做多(涨包跌) 入场=4480.98 出场=4478.98 出场时间=1758418200000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 09:45:00号 做空(跌包涨) 入场=4479.33 出场=4481.33 出场时间=1758420000000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 10:15:00号 做多(涨包跌) 入场=4484.00 出场=4482.00 出场时间=1758421800000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 10:30:00号 做空(跌包涨) 入场=4473.56 出场=4475.56 出场时间=1758422700000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 12:00:00号 做多(涨包跌) 入场=4476.07 出场=4474.07 出场时间=1758428100000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 12:15:00号 做空(跌包涨) 入场=4468.37 出场=4470.37 出场时间=1758429000000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 12:45:00号 做多(涨包跌) 入场=4469.16 出场=4467.16 出场时间=1758430800000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 13:15:00号 做空(跌包涨) 入场=4465.52 出场=4467.52 出场时间=1758432600000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 14:45:00号 做多(涨包跌) 入场=4489.61 出场=4487.61 出场时间=1758438000000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 16:00:00号 做空(跌包涨) 入场=4475.86 出场=4445.86 出场时间=1758447000000 差价=30.00 盈利=67.03 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 20:00:00号 做空(跌包涨) 入场=4458.25 出场=4460.25 出场时间=1758456900000 差价=-2.00 盈利=-4.49 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 20:15:00号 做多(涨包跌) 入场=4463.00 出场=4461.00 出场时间=1758458700000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 20:45:00号 做空(跌包涨) 入场=4462.99 出场=4464.99 出场时间=1758459600000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 22:00:00号 做多(涨包跌) 入场=4473.99 出场=4471.99 出场时间=1758465000000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 22:30:00号 做空(跌包涨) 入场=4473.49 出场=4475.49 出场时间=1758465900000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 22:45:00号 做多(涨包跌) 入场=4477.45 出场=4475.45 出场时间=1758466800000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 23:00:00号 做空(跌包涨) 入场=4470.65 出场=4472.65 出场时间=1758467700000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 23:15:00号 做多(涨包跌) 入场=4480.89 出场=4478.89 出场时间=1758468600000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-21 23:45:00号 做多(涨包跌) 入场=4482.23 出场=4480.23 出场时间=1758471300000 差价=-2.00 盈利=-4.46 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.400 | INFO | __main__:<module>:216 - 2025-09-22 00:45:00号 做空(跌包涨) 入场=4468.98 出场=4470.98 出场时间=1758474000000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 02:45:00号 做多(涨包跌) 入场=4490.40 出场=4488.40 出场时间=1758481200000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 03:15:00号 做空(跌包涨) 入场=4478.59 出场=4480.59 出场时间=1758483000000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 04:00:00号 做多(涨包跌) 入场=4492.20 出场=4490.20 出场时间=1758485700000 差价=-2.00 盈利=-4.45 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 04:45:00号 做空(跌包涨) 入场=4477.81 出场=4447.81 出场时间=1758492900000 差价=30.00 盈利=67.00 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 05:30:00号 做空(跌包涨) 入场=4465.73 出场=4467.73 出场时间=1758491100000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 05:45:00号 做多(涨包跌) 入场=4474.17 出场=4472.17 出场时间=1758492000000 差价=-2.00 盈利=-4.47 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 06:45:00号 做多(涨包跌) 入场=4464.29 出场=4462.29 出场时间=1758495600000 差价=-2.00 盈利=-4.48 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 08:00:00号 做空(跌包涨) 入场=4443.01 出场=4445.01 出场时间=1758500100000 差价=-2.00 盈利=-4.50 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 08:30:00号 做空(跌包涨) 入场=4425.29 出场=4395.29 出场时间=1758501900000 差价=30.00 盈利=67.79 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 09:45:00号 做多(涨包跌) 入场=4343.62 出场=4341.62 出场时间=1758506400000 差价=-2.00 盈利=-4.60 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 10:00:00号 做空(跌包涨) 入场=4325.73 出场=4295.73 出场时间=1758507300000 差价=30.00 盈利=69.35 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 10:30:00号 做空(跌包涨) 入场=4307.52 出场=4277.52 出场时间=1758519000000 差价=30.00 盈利=69.65 开仓手续费=5u 平仓手续费=4.97
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 11:15:00号 做多(涨包跌) 入场=4296.63 出场=4294.63 出场时间=1758511800000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 11:45:00号 做空(跌包涨) 入场=4292.42 出场=4294.42 出场时间=1758513600000 差价=-2.00 盈利=-4.66 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.402 | INFO | __main__:<module>:216 - 2025-09-22 12:00:00号 做多(涨包跌) 入场=4303.62 出场=4301.62 出场时间=1758514500000 差价=-2.00 盈利=-4.65 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 13:45:00号 做空(跌包涨) 入场=4277.81 出场=4247.81 出场时间=1758520800000 差价=30.00 盈利=70.13 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 16:00:00号 做空(跌包涨) 入场=4191.65 出场=4193.65 出场时间=1758528900000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 16:45:00号 做多(涨包跌) 入场=4198.38 出场=4196.38 出场时间=1758531600000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 18:45:00号 做空(跌包涨) 入场=4156.51 出场=4158.51 出场时间=1758538800000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 19:00:00号 做多(涨包跌) 入场=4179.99 出场=4177.99 出场时间=1758539700000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 19:45:00号 做多(涨包跌) 入场=4180.81 出场=4178.81 出场时间=1758542400000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 20:30:00号 做多(涨包跌) 入场=4181.83 出场=4179.83 出场时间=1758545100000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 21:00:00号 做多(涨包跌) 入场=4190.34 出场=4188.34 出场时间=1758547800000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 22:00:00号 做多(涨包跌) 入场=4205.46 出场=4203.46 出场时间=1758550500000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 22:30:00号 做多(涨包跌) 入场=4214.47 出场=4212.47 出场时间=1758552300000 差价=-2.00 盈利=-4.75 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-22 23:45:00号 做空(跌包涨) 入场=4168.92 出场=4170.92 出场时间=1758556800000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-23 00:15:00号 做多(涨包跌) 入场=4177.10 出场=4175.10 出场时间=1758558600000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-23 01:30:00号 做多(涨包跌) 入场=4165.93 出场=4163.93 出场时间=1758563100000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-23 02:00:00号 做空(跌包涨) 入场=4162.98 出场=4164.98 出场时间=1758564900000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.404 | INFO | __main__:<module>:216 - 2025-09-23 02:15:00号 做多(涨包跌) 入场=4171.60 出场=4169.60 出场时间=1758565800000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 04:15:00号 做多(涨包跌) 入场=4149.68 出场=4179.68 出场时间=1758573900000 差价=30.00 盈利=72.29 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 05:30:00号 做多(涨包跌) 入场=4186.81 出场=4184.81 出场时间=1758578400000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 06:15:00号 做空(跌包涨) 入场=4189.66 出场=4191.66 出场时间=1758580200000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 07:15:00号 做多(涨包跌) 入场=4195.96 出场=4193.96 出场时间=1758584700000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 08:00:00号 做空(跌包涨) 入场=4196.86 出场=4198.86 出场时间=1758586500000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 08:15:00号 做多(涨包跌) 入场=4203.24 出场=4201.24 出场时间=1758587400000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 08:45:00号 做空(跌包涨) 入场=4193.50 出场=4195.50 出场时间=1758590100000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 09:30:00号 做多(涨包跌) 入场=4195.96 出场=4193.96 出场时间=1758591900000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 09:45:00号 做空(跌包涨) 入场=4171.89 出场=4173.89 出场时间=1758592800000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 10:15:00号 做多(涨包跌) 入场=4175.71 出场=4173.71 出场时间=1758594600000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 10:30:00号 做空(跌包涨) 入场=4157.11 出场=4159.11 出场时间=1758595500000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 11:00:00号 做空(跌包涨) 入场=4141.99 出场=4143.99 出场时间=1758597300000 差价=-2.00 盈利=-4.83 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 11:30:00号 做多(涨包跌) 入场=4175.25 出场=4173.25 出场时间=1758600900000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 12:15:00号 做空(跌包涨) 入场=4175.15 出场=4177.15 出场时间=1758602700000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 14:00:00号 做空(跌包涨) 入场=4181.07 出场=4183.07 出场时间=1758608100000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 14:15:00号 做多(涨包跌) 入场=4192.78 出场=4222.78 出场时间=1758618000000 差价=30.00 盈利=71.55 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 15:30:00号 做空(跌包涨) 入场=4199.93 出场=4201.93 出场时间=1758613500000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 15:45:00号 做多(涨包跌) 入场=4205.71 出场=4203.71 出场时间=1758614400000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 17:00:00号 做空(跌包涨) 入场=4206.84 出场=4208.84 出场时间=1758618900000 差价=-2.00 盈利=-4.75 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 17:15:00号 做多(涨包跌) 入场=4219.98 出场=4217.98 出场时间=1758619800000 差价=-2.00 盈利=-4.74 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 17:30:00号 做空(跌包涨) 入场=4202.54 出场=4204.54 出场时间=1758634200000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 18:30:00号 做空(跌包涨) 入场=4188.92 出场=4190.92 出场时间=1758624300000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 19:00:00号 做多(涨包跌) 入场=4191.02 出场=4189.02 出场时间=1758626100000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 19:15:00号 做空(跌包涨) 入场=4182.13 出场=4184.13 出场时间=1758627000000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.405 | INFO | __main__:<module>:216 - 2025-09-23 20:15:00号 做多(涨包跌) 入场=4193.35 出场=4191.35 出场时间=1758630600000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 20:30:00号 做空(跌包涨) 入场=4184.09 出场=4186.09 出场时间=1758631500000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 20:45:00号 做多(涨包跌) 入场=4196.15 出场=4194.15 出场时间=1758632400000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 21:30:00号 做多(涨包跌) 入场=4194.30 出场=4192.30 出场时间=1758635100000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 21:45:00号 做空(跌包涨) 入场=4186.77 出场=4188.77 出场时间=1758636000000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 22:15:00号 做多(涨包跌) 入场=4196.04 出场=4194.04 出场时间=1758637800000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 22:30:00号 做空(跌包涨) 入场=4182.60 出场=4184.60 出场时间=1758638700000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 23:00:00号 做空(跌包涨) 入场=4172.55 出场=4174.55 出场时间=1758640500000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-23 23:45:00号 做空(跌包涨) 入场=4178.60 出场=4180.60 出场时间=1758643200000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 00:15:00号 做空(跌包涨) 入场=4172.91 出场=4174.91 出场时间=1758645000000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 00:30:00号 做多(涨包跌) 入场=4186.91 出场=4184.91 出场时间=1758645900000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 00:45:00号 做空(跌包涨) 入场=4170.16 出场=4172.16 出场时间=1758646800000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 01:00:00号 做多(涨包跌) 入场=4190.21 出场=4188.21 出场时间=1758647700000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 02:45:00号 做空(跌包涨) 入场=4149.15 出场=4151.15 出场时间=1758654000000 差价=-2.00 盈利=-4.82 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 03:45:00号 做空(跌包涨) 入场=4155.56 出场=4157.56 出场时间=1758657600000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.406 | INFO | __main__:<module>:216 - 2025-09-24 04:15:00号 做多(涨包跌) 入场=4157.54 出场=4155.54 出场时间=1758659400000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 04:30:00号 做空(跌包涨) 入场=4149.61 出场=4151.61 出场时间=1758660300000 差价=-2.00 盈利=-4.82 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 04:45:00号 做多(涨包跌) 入场=4163.34 出场=4161.34 出场时间=1758669300000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 06:45:00号 做多(涨包跌) 入场=4182.21 出场=4180.21 出场时间=1758668400000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 09:15:00号 做多(涨包跌) 入场=4182.12 出场=4180.12 出场时间=1758679200000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 10:15:00号 做空(跌包涨) 入场=4168.31 出场=4170.31 出场时间=1758681000000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 12:15:00号 做空(跌包涨) 入场=4098.12 出场=4100.12 出场时间=1758688200000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 16:15:00号 做多(涨包跌) 入场=4174.81 出场=4172.81 出场时间=1758702600000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 16:30:00号 做空(跌包涨) 入场=4168.12 出场=4170.12 出场时间=1758703500000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 16:45:00号 做多(涨包跌) 入场=4175.13 出场=4173.13 出场时间=1758704400000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 17:30:00号 做多(涨包跌) 入场=4174.40 出场=4172.40 出场时间=1758708900000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 18:15:00号 做空(跌包涨) 入场=4177.63 出场=4179.63 出场时间=1758711600000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-24 20:45:00号 做多(涨包跌) 入场=4181.50 出场=4179.50 出场时间=1758718800000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-25 00:30:00号 做多(涨包跌) 入场=4167.86 出场=4165.86 出场时间=1758733200000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-25 01:15:00号 做多(涨包跌) 入场=4178.77 出场=4176.77 出场时间=1758735000000 差价=-2.00 盈利=-4.79 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.407 | INFO | __main__:<module>:216 - 2025-09-25 01:45:00号 做多(涨包跌) 入场=4186.01 出场=4184.01 出场时间=1758736800000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 07:00:00号 做空(跌包涨) 入场=4151.98 出场=4153.98 出场时间=1758755700000 差价=-2.00 盈利=-4.82 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 07:15:00号 做多(涨包跌) 入场=4158.00 出场=4156.00 出场时间=1758756600000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 08:30:00号 做空(跌包涨) 入场=4137.01 出场=4139.01 出场时间=1758761100000 差价=-2.00 盈利=-4.83 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 09:00:00号 做空(跌包涨) 入场=4126.96 出场=4096.96 出场时间=1758762900000 差价=30.00 盈利=72.69 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 10:45:00号 做多(涨包跌) 入场=4099.28 出场=4097.28 出场时间=1758769200000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 11:15:00号 做空(跌包涨) 入场=4086.56 出场=4056.56 出场时间=1758771000000 差价=30.00 盈利=73.41 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 12:15:00号 做空(跌包涨) 入场=4045.83 出场=4015.83 出场时间=1758774600000 差价=30.00 盈利=74.15 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 13:00:00号 做空(跌包涨) 入场=4000.17 出场=4002.17 出场时间=1758777300000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 16:00:00号 做空(跌包涨) 入场=4006.93 出场=4008.93 出场时间=1758788100000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 16:15:00号 做多(涨包跌) 入场=4029.59 出场=4027.59 出场时间=1758789000000 差价=-2.00 盈利=-4.96 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 16:45:00号 做空(跌包涨) 入场=4010.29 出场=4012.29 出场时间=1758790800000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 19:45:00号 做空(跌包涨) 入场=3998.02 出场=4000.02 出场时间=1758801600000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 20:30:00号 做空(跌包涨) 入场=3939.54 出场=3941.54 出场时间=1758804300000 差价=-2.00 盈利=-5.08 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 21:30:00号 做多(涨包跌) 入场=4001.35 出场=3999.35 出场时间=1758807900000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-25 21:45:00号 做空(跌包涨) 入场=3957.31 出场=3959.31 出场时间=1758808800000 差价=-2.00 盈利=-5.05 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-26 00:15:00号 做空(跌包涨) 入场=3996.68 出场=3966.68 出场时间=1758817800000 差价=30.00 盈利=75.06 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-26 01:45:00号 做空(跌包涨) 入场=3865.17 出场=3835.17 出场时间=1758823200000 差价=30.00 盈利=77.62 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.408 | INFO | __main__:<module>:216 - 2025-09-26 03:30:00号 做多(涨包跌) 入场=3937.43 出场=3935.43 出场时间=1758829500000 差价=-2.00 盈利=-5.08 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 04:45:00号 做空(跌包涨) 入场=3891.53 出场=3893.53 出场时间=1758834000000 差价=-2.00 盈利=-5.14 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 05:15:00号 做多(涨包跌) 入场=3898.34 出场=3896.34 出场时间=1758835800000 差价=-2.00 盈利=-5.13 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 06:00:00号 做多(涨包跌) 入场=3903.57 出场=3933.57 出场时间=1758838500000 差价=30.00 盈利=76.85 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 08:45:00号 做空(跌包涨) 入场=3872.95 出场=3874.95 出场时间=1758848400000 差价=-2.00 盈利=-5.16 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 09:00:00号 做多(涨包跌) 入场=3930.76 出场=3928.76 出场时间=1758849300000 差价=-2.00 盈利=-5.09 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 09:30:00号 做空(跌包涨) 入场=3927.77 出场=3929.77 出场时间=1758851100000 差价=-2.00 盈利=-5.09 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 09:45:00号 做多(涨包跌) 入场=3941.60 出场=3971.60 出场时间=1758860100000 差价=30.00 盈利=76.11 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 10:45:00号 做多(涨包跌) 入场=3957.81 出场=3955.81 出场时间=1758855600000 差价=-2.00 盈利=-5.05 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 11:15:00号 做多(涨包跌) 入场=3959.57 出场=3957.57 出场时间=1758857400000 差价=-2.00 盈利=-5.05 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 11:30:00号 做空(跌包涨) 入场=3954.21 出场=3956.21 出场时间=1758858300000 差价=-2.00 盈利=-5.06 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 12:30:00号 做空(跌包涨) 入场=3960.89 出场=3930.89 出场时间=1758865500000 差价=30.00 盈利=75.74 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 13:45:00号 做空(跌包涨) 入场=3942.77 出场=3912.77 出场时间=1758866400000 差价=30.00 盈利=76.09 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 15:00:00号 做空(跌包涨) 入场=3919.00 出场=3921.00 出场时间=1758870900000 差价=-2.00 盈利=-5.10 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 16:00:00号 做多(涨包跌) 入场=3936.60 出场=3934.60 出场时间=1758874500000 差价=-2.00 盈利=-5.08 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.409 | INFO | __main__:<module>:216 - 2025-09-26 16:45:00号 做多(涨包跌) 入场=3937.94 出场=3935.94 出场时间=1758877200000 差价=-2.00 盈利=-5.08 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 17:00:00号 做空(跌包涨) 入场=3932.27 出场=3934.27 出场时间=1758878100000 差价=-2.00 盈利=-5.09 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 17:30:00号 做空(跌包涨) 入场=3925.74 出场=3895.74 出场时间=1758880800000 差价=30.00 盈利=76.42 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 18:15:00号 做空(跌包涨) 入场=3885.27 出场=3887.27 出场时间=1758882600000 差价=-2.00 盈利=-5.15 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 18:45:00号 做多(涨包跌) 入场=3886.20 出场=3884.20 出场时间=1758884400000 差价=-2.00 盈利=-5.15 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 19:15:00号 做空(跌包涨) 入场=3875.50 出场=3877.50 出场时间=1758886200000 差价=-2.00 盈利=-5.16 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 19:30:00号 做多(涨包跌) 入场=3888.98 出场=3886.98 出场时间=1758888000000 差价=-2.00 盈利=-5.14 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 21:45:00号 做多(涨包跌) 入场=3937.17 出场=3967.17 出场时间=1758895200000 差价=30.00 盈利=76.20 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-26 23:00:00号 做空(跌包涨) 入场=3929.62 出场=3931.62 出场时间=1758899700000 差价=-2.00 盈利=-5.09 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 00:15:00号 做多(涨包跌) 入场=3962.86 出场=3992.86 出场时间=1758906000000 差价=30.00 盈利=75.70 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 02:45:00号 做空(跌包涨) 入场=4040.09 出场=4042.09 出场时间=1758913200000 差价=-2.00 盈利=-4.95 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 03:15:00号 做空(跌包涨) 入场=4036.73 出场=4006.73 出场时间=1758915000000 差价=30.00 盈利=74.32 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 04:00:00号 做多(涨包跌) 入场=4021.39 出场=4019.39 出场时间=1758917700000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 04:30:00号 做空(跌包涨) 入场=4016.00 出场=4018.00 出场时间=1758922200000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 05:15:00号 做多(涨包跌) 入场=4014.71 出场=4012.71 出场时间=1758922200000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.411 | INFO | __main__:<module>:216 - 2025-09-27 05:45:00号 做空(跌包涨) 入场=4010.24 出场=4012.24 出场时间=1758924000000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 06:00:00号 做多(涨包跌) 入场=4021.35 出场=4019.35 出场时间=1758927600000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 07:00:00号 做空(跌包涨) 入场=4024.56 出场=4026.56 出场时间=1758929400000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 08:45:00号 做空(跌包涨) 入场=4020.15 出场=4022.15 出场时间=1758934800000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 10:00:00号 做多(涨包跌) 入场=4016.68 出场=4014.68 出场时间=1758939300000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 10:30:00号 做空(跌包涨) 入场=4011.24 出场=4013.24 出场时间=1758941100000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 11:00:00号 做空(跌包涨) 入场=4010.82 出场=4012.82 出场时间=1758942900000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 11:30:00号 做多(涨包跌) 入场=4021.64 出场=4019.64 出场时间=1758944700000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 12:00:00号 做空(跌包涨) 入场=4017.19 出场=4019.19 出场时间=1758946500000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 12:30:00号 做多(涨包跌) 入场=4024.64 出场=4022.64 出场时间=1758948300000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 13:45:00号 做多(涨包跌) 入场=4017.61 出场=4015.61 出场时间=1758952800000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 14:15:00号 做空(跌包涨) 入场=4013.01 出场=4015.01 出场时间=1758954600000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 14:45:00号 做多(涨包跌) 入场=4014.09 出场=4012.09 出场时间=1758957300000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 15:30:00号 做空(跌包涨) 入场=4011.76 出场=3981.76 出场时间=1758962700000 差价=30.00 盈利=74.78 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 18:45:00号 做多(涨包跌) 入场=4011.07 出场=4009.07 出场时间=1758970800000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.413 | INFO | __main__:<module>:216 - 2025-09-27 19:30:00号 做多(涨包跌) 入场=4011.08 出场=4009.08 出场时间=1758973500000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-27 19:45:00号 做空(跌包涨) 入场=4003.03 出场=4005.03 出场时间=1758976200000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-27 22:00:00号 做空(跌包涨) 入场=4018.39 出场=4020.39 出场时间=1758982500000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-27 22:30:00号 做空(跌包涨) 入场=4017.14 出场=4019.14 出场时间=1758987900000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 00:15:00号 做空(跌包涨) 入场=4010.03 出场=4012.03 出场时间=1758990600000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 01:45:00号 做多(涨包跌) 入场=3994.29 出场=3992.29 出场时间=1758996000000 差价=-2.00 盈利=-5.01 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 03:00:00号 做多(涨包跌) 入场=3994.64 出场=3992.64 出场时间=1759000500000 差价=-2.00 盈利=-5.01 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 03:30:00号 做多(涨包跌) 入场=3997.57 出场=3995.57 出场时间=1759002300000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 04:00:00号 做多(涨包跌) 入场=4000.64 出场=4030.64 出场时间=1759011300000 差价=30.00 盈利=74.99 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 05:45:00号 做多(涨包跌) 入场=4014.84 出场=4012.84 出场时间=1759010400000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 06:15:00号 做多(涨包跌) 入场=4021.22 出场=4019.22 出场时间=1759012200000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 06:45:00号 做空(跌包涨) 入场=4017.93 出场=4019.93 出场时间=1759014000000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 07:30:00号 做空(跌包涨) 入场=4016.91 出场=4018.91 出场时间=1759016700000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 08:00:00号 做多(涨包跌) 入场=4016.99 出场=4014.99 出场时间=1759018500000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 08:15:00号 做空(跌包涨) 入场=4011.14 出场=4013.14 出场时间=1759019400000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.415 | INFO | __main__:<module>:216 - 2025-09-28 08:30:00号 做多(涨包跌) 入场=4027.69 出场=4025.69 出场时间=1759020300000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 09:45:00号 做空(跌包涨) 入场=3995.87 出场=3997.87 出场时间=1759024800000 差价=-2.00 盈利=-5.01 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 10:30:00号 做多(涨包跌) 入场=4002.88 出场=4000.88 出场时间=1759027500000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 11:15:00号 做多(涨包跌) 入场=4003.08 出场=4001.08 出场时间=1759030200000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 12:15:00号 做空(跌包涨) 入场=3996.98 出场=3998.98 出场时间=1759033800000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 12:45:00号 做多(涨包跌) 入场=4002.57 出场=4000.57 出场时间=1759040100000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 13:15:00号 做空(跌包涨) 入场=4001.69 出场=4003.69 出场时间=1759037400000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 13:30:00号 做多(涨包跌) 入场=4009.87 出场=4007.87 出场时间=1759038300000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 14:00:00号 做空(跌包涨) 入场=4008.99 出场=4010.99 出场时间=1759040100000 差价=-2.00 盈利=-4.99 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 14:30:00号 做空(跌包涨) 入场=3998.62 出场=4000.62 出场时间=1759041900000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 16:15:00号 做空(跌包涨) 入场=4010.49 出场=3980.49 出场时间=1759062600000 差价=30.00 盈利=74.80 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 18:00:00号 做空(跌包涨) 入场=3993.77 出场=3995.77 出场时间=1759055400000 差价=-2.00 盈利=-5.01 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 18:45:00号 做多(涨包跌) 入场=3996.14 出场=3994.14 出场时间=1759057200000 差价=-2.00 盈利=-5.00 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 20:45:00号 做空(跌包涨) 入场=3969.72 出场=3971.72 出场时间=1759064400000 差价=-2.00 盈利=-5.04 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 23:00:00号 做多(涨包跌) 入场=4022.99 出场=4020.99 出场时间=1759072500000 差价=-2.00 盈利=-4.97 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-28 23:45:00号 做空(跌包涨) 入场=4019.98 出场=4021.98 出场时间=1759075200000 差价=-2.00 盈利=-4.98 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-29 00:15:00号 做多(涨包跌) 入场=4032.80 出场=4030.80 出场时间=1759077000000 差价=-2.00 盈利=-4.96 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.416 | INFO | __main__:<module>:216 - 2025-09-29 01:00:00号 做多(涨包跌) 入场=4031.84 出场=4029.84 出场时间=1759079700000 差价=-2.00 盈利=-4.96 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 01:45:00号 做多(涨包跌) 入场=4043.55 出场=4041.55 出场时间=1759082400000 差价=-2.00 盈利=-4.95 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 02:45:00号 做多(涨包跌) 入场=4038.12 出场=4036.12 出场时间=1759086000000 差价=-2.00 盈利=-4.95 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 03:15:00号 做空(跌包涨) 入场=4032.23 出场=4034.23 出场时间=1759087800000 差价=-2.00 盈利=-4.96 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 04:00:00号 做多(涨包跌) 入场=4037.42 出场=4035.42 出场时间=1759090500000 差价=-2.00 盈利=-4.95 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 04:30:00号 做多(涨包跌) 入场=4046.49 出场=4044.49 出场时间=1759095000000 差价=-2.00 盈利=-4.94 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 05:30:00号 做空(跌包涨) 入场=4048.44 出场=4050.44 出场时间=1759096800000 差价=-2.00 盈利=-4.94 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 07:45:00号 做多(涨包跌) 入场=4137.26 出场=4135.26 出场时间=1759104000000 差价=-2.00 盈利=-4.83 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 08:15:00号 做空(跌包涨) 入场=4134.85 出场=4136.85 出场时间=1759105800000 差价=-2.00 盈利=-4.84 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 08:45:00号 做空(跌包涨) 入场=4126.53 出场=4128.53 出场时间=1759107600000 差价=-2.00 盈利=-4.85 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.417 | INFO | __main__:<module>:216 - 2025-09-29 09:15:00号 做多(涨包跌) 入场=4131.72 出场=4129.72 出场时间=1759109400000 差价=-2.00 盈利=-4.84 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 09:30:00号 做空(跌包涨) 入场=4117.93 出场=4119.93 出场时间=1759110300000 差价=-2.00 盈利=-4.86 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 10:00:00号 做空(跌包涨) 入场=4112.65 出场=4114.65 出场时间=1759112100000 差价=-2.00 盈利=-4.86 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 10:45:00号 做空(跌包涨) 入场=4107.29 出场=4109.29 出场时间=1759114800000 差价=-2.00 盈利=-4.87 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 11:15:00号 做空(跌包涨) 入场=4102.41 出场=4104.41 出场时间=1759116600000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 12:00:00号 做多(涨包跌) 入场=4119.67 出场=4117.67 出场时间=1759119300000 差价=-2.00 盈利=-4.85 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 12:45:00号 做多(涨包跌) 入场=4118.75 出场=4116.75 出场时间=1759122000000 差价=-2.00 盈利=-4.86 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.418 | INFO | __main__:<module>:216 - 2025-09-29 13:45:00号 做多(涨包跌) 入场=4109.88 出场=4107.88 出场时间=1759125600000 差价=-2.00 盈利=-4.87 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 14:15:00号 做空(跌包涨) 入场=4097.98 出场=4099.98 出场时间=1759127400000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 15:00:00号 做空(跌包涨) 入场=4095.36 出场=4097.36 出场时间=1759130100000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 15:30:00号 做空(跌包涨) 入场=4092.53 出场=4094.53 出场时间=1759131900000 差价=-2.00 盈利=-4.89 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 15:45:00号 做多(涨包跌) 入场=4104.99 出场=4134.99 出场时间=1759137300000 差价=30.00 盈利=73.08 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 20:00:00号 做空(跌包涨) 入场=4100.87 出场=4102.87 出场时间=1759148100000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 20:15:00号 做多(涨包跌) 入场=4108.92 出场=4106.92 出场时间=1759149000000 差价=-2.00 盈利=-4.87 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 20:45:00号 做空(跌包涨) 入场=4102.06 出场=4104.06 出场时间=1759150800000 差价=-2.00 盈利=-4.88 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 21:15:00号 做多(涨包跌) 入场=4102.99 出场=4132.99 出场时间=1759152600000 差价=30.00 盈利=73.12 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-29 22:45:00号 做多(涨包跌) 入场=4189.88 出场=4187.88 出场时间=1759158000000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 00:30:00号 做空(跌包涨) 入场=4156.52 出场=4126.52 出场时间=1759165200000 差价=30.00 盈利=72.18 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 01:30:00号 做多(涨包跌) 入场=4145.04 出场=4143.04 出场时间=1759168800000 差价=-2.00 盈利=-4.83 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 02:00:00号 做多(涨包跌) 入场=4153.13 出场=4151.13 出场时间=1759169700000 差价=-2.00 盈利=-4.82 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 03:45:00号 做多(涨包跌) 入场=4180.31 出场=4210.31 出场时间=1759177800000 差价=30.00 盈利=71.77 开仓手续费=5u 平仓手续费=5.04
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 04:45:00号 做多(涨包跌) 入场=4229.13 出场=4227.13 出场时间=1759179600000 差价=-2.00 盈利=-4.73 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 07:00:00号 做多(涨包跌) 入场=4224.09 出场=4222.09 出场时间=1759187700000 差价=-2.00 盈利=-4.73 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.419 | INFO | __main__:<module>:216 - 2025-09-30 08:45:00号 做多(涨包跌) 入场=4216.80 出场=4214.80 出场时间=1759194000000 差价=-2.00 盈利=-4.74 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 10:15:00号 做空(跌包涨) 入场=4198.83 出场=4200.83 出场时间=1759199400000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 10:45:00号 做多(涨包跌) 入场=4201.68 出场=4199.68 出场时间=1759201200000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 11:30:00号 做多(涨包跌) 入场=4199.59 出场=4197.59 出场时间=1759203900000 差价=-2.00 盈利=-4.76 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 12:00:00号 做空(跌包涨) 入场=4196.16 出场=4198.16 出场时间=1759205700000 差价=-2.00 盈利=-4.77 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 14:00:00号 做多(涨包跌) 入场=4182.43 出场=4180.43 出场时间=1759217400000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 15:00:00号 做空(跌包涨) 入场=4188.05 出场=4190.05 出场时间=1759216500000 差价=-2.00 盈利=-4.78 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 17:30:00号 做多(涨包跌) 入场=4168.78 出场=4166.78 出场时间=1759225500000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 19:15:00号 做空(跌包涨) 入场=4153.02 出场=4155.02 出场时间=1759231800000 差价=-2.00 盈利=-4.82 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 19:30:00号 做多(涨包跌) 入场=4158.87 出场=4156.87 出场时间=1759233600000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 20:30:00号 做多(涨包跌) 入场=4165.40 出场=4163.40 出场时间=1759236300000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 21:00:00号 做空(跌包涨) 入场=4156.14 出场=4158.14 出场时间=1759238100000 差价=-2.00 盈利=-4.81 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 21:30:00号 做多(涨包跌) 入场=4164.44 出场=4162.44 出场时间=1759239900000 差价=-2.00 盈利=-4.80 开仓手续费=5u 平仓手续费=5.00
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 22:00:00号 做空(跌包涨) 入场=4152.29 出场=4122.29 出场时间=1759241700000 差价=30.00 盈利=72.25 开仓手续费=5u 平仓手续费=4.96
2025-10-11 14:00:27.420 | INFO | __main__:<module>:216 - 2025-09-30 23:15:00号 做空(跌包涨) 入场=4115.98 出场=4117.98 出场时间=1759247100000 差价=-2.00 盈利=-4.86 开仓手续费=5u 平仓手续费=5.00
""" # 这里放入你提供的完整日志数据
# 计算最大回撤
results = calculate_max_drawdown(log_data)
# 打印结果
print_analysis_results(results)
# 可选绘制累计收益曲线需要matplotlib
try:
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 6))
plt.plot(results['cumulative_returns'], label='累计收益', linewidth=2)
plt.axhline(y=0, color='r', linestyle='--', alpha=0.7, label='盈亏平衡线')
# 标记最大回撤区间
start_idx, end_idx = results['max_drawdown_period']
plt.axvspan(start_idx, end_idx, alpha=0.3, color='red', label='最大回撤区间')
plt.title('交易策略表现 - 累计收益曲线')
plt.xlabel('交易次数')
plt.ylabel('累计收益 (u)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
except ImportError:
print("如需可视化图表请安装matplotlib: pip install matplotlib")

327
weex/框架.py Normal file
View File

@@ -0,0 +1,327 @@
"""
WEEX ETH-USDT 永续合约交易框架
与 bitmart/框架.py 结构对应:浏览器 + APIK线/余额/持仓)+ 市价开平仓,供具体策略复用。
"""
import time
from typing import Optional, Dict, List, Tuple
from tqdm import tqdm
from loguru import logger
from bit_tools import openBrowser
from DrissionPage import ChromiumPage, ChromiumOptions
from curl_cffi import requests
# ==================== 配置 ====================
class Config:
TGE_URL = "http://127.0.0.1:50326"
TGE_AUTHORIZATION = "Bearer asp_174003986c9b0799677c5b2c1adb76e402735d753bc91a91"
CONTRACT_ID = "10000002"
PRODUCT_CODE = "cmt_ethusdt"
KLINE_TYPE = "MINUTE_30"
KLINE_LIMIT = 300
TRADING_URL = "https://www.weex.com/zh-CN/futures/ETH-USDT"
MAX_RETRY_ATTEMPTS = 3
RETRY_DELAY = 1
# ==================== 主框架类 ====================
class WeexFuturesTransaction:
"""WEEX 永续合约交易框架K线、余额、持仓、浏览器、市价开平仓"""
def __init__(self, tge_id):
self.page: Optional[ChromiumPage] = None
self.tge_port: Optional[int] = None
self.tge_id = tge_id
self.session = requests.Session()
self.headers: Optional[Dict] = None
self.start = 0 # 持仓: -1 空, 0 无, 1 多
self.open_avg_price = None
self.current_amount = None
self.position_data: Optional[List] = None
self.pbar = tqdm(total=30, desc="等待K线", ncols=80)
self.last_kline_time = None
# ------------------------- Token请求 API 前需先取 token-------------------------
def _get_token(self) -> bool:
"""从浏览器请求交易页时抓取 U-TOKEN写入 session headers"""
if not self.page:
return False
tab = self.page.new_tab()
tab.listen.start("/user/security/getLanguageType")
try:
for attempt in range(Config.MAX_RETRY_ATTEMPTS):
try:
tab.get(url=Config.TRADING_URL)
res = tab.listen.wait(timeout=5)
if res.request.headers.get("U-TOKEN"):
self.headers = dict(res.request.headers)
self.session.headers.update(self.headers)
logger.success("获取 token 成功")
return True
except Exception as e:
logger.warning(f"获取 token 第 {attempt + 1} 次失败: {e}")
if attempt < Config.MAX_RETRY_ATTEMPTS - 1:
time.sleep(Config.RETRY_DELAY)
return False
finally:
tab.close()
# ------------------------- API -------------------------
def get_klines(
self,
contract_id: str = Config.CONTRACT_ID,
product_code: str = Config.PRODUCT_CODE,
kline_type: str = Config.KLINE_TYPE,
limit: int = Config.KLINE_LIMIT,
) -> Optional[List[Dict]]:
"""获取 K 线,返回 [{'id', 'open', 'high', 'low', 'close'}, ...],按 id 升序。请求前需已取 token。"""
# if not self._get_token():
# logger.error("获取 token 失败,无法拉取 K 线")
# return None
params = {
"contractId": contract_id,
"productCode": product_code,
"priceType": "LAST_PRICE",
"klineType": kline_type,
"limit": str(limit),
"timeZone": "string",
"languageType": "1",
"sign": "SIGN",
}
for attempt in range(Config.MAX_RETRY_ATTEMPTS):
try:
response = self.session.get(
"https://http-gateway2.elconvo.com/api/v1/public/quote/v1/getKlineV2",
params=params,
timeout=15,
)
if response.status_code != 200:
if attempt < Config.MAX_RETRY_ATTEMPTS - 1:
time.sleep(Config.RETRY_DELAY)
continue
data = response.json()
if "data" not in data or "dataList" not in data["data"]:
continue
result = data["data"]["dataList"]
kline_data = []
for item in result:
# [close, high, low, open, id]
kline_data.append({
"id": int(item[4]),
"open": float(item[3]),
"high": float(item[1]),
"low": float(item[2]),
"close": float(item[0]),
})
kline_data.sort(key=lambda x: x["id"])
return kline_data
except Exception as e:
logger.error(f"获取 K 线异常: {e}")
if attempt < Config.MAX_RETRY_ATTEMPTS - 1:
time.sleep(Config.RETRY_DELAY)
return None
def get_current_price(self) -> Optional[float]:
"""用最近一根 K 线收盘价作为当前价"""
klines = self.get_klines(limit=3)
if klines:
return float(klines[-1]["close"])
return None
def get_available_balance(self) -> Optional[float]:
"""合约账户可用余额"""
if not self._get_token():
return None
for attempt in range(Config.MAX_RETRY_ATTEMPTS):
try:
response = self.session.post(
"https://gateway2.ngsvsfx.cn/v1/gw/assetsWithBalance/new",
timeout=15,
)
return float(response.json()["data"]["newContract"]["balanceList"][0]["available"])
except Exception as e:
logger.error(f"获取余额异常: {e}")
if attempt < Config.MAX_RETRY_ATTEMPTS - 1:
time.sleep(Config.RETRY_DELAY)
return None
def get_position_status(self) -> bool:
"""从成交历史解析持仓方向,更新 self.start (-1/0/1),成功返回 True"""
# if not self._get_token():
# return False
payload = {
"filterContractIdList": [10000002],
"limit": 100,
"languageType": 0,
"sign": "SIGN",
"timeZone": "string",
}
for attempt in range(Config.MAX_RETRY_ATTEMPTS):
try:
response = self.session.post(
"https://http-gateway2.janapw.com/api/v1/private/order/v2/getHistoryOrderFillTransactionPage",
json=payload,
timeout=15,
)
datas = response.json().get("data", {}).get("dataList")
self.position_data = datas or None
if not datas:
self.start = 0
return True
rev = list(datas)
rev.reverse()
start, start1 = 0, 0
for i in rev:
d = i.get("legacyOrderDirection")
if d == "CLOSE_SHORT":
start = 0
elif d == "CLOSE_LONG":
start1 = 0
elif d == "OPEN_SHORT":
start -= 1
elif d == "OPEN_LONG":
start1 += 1
if start1:
self.start = 1
elif start:
self.start = -1
else:
self.start = 0
return True
except Exception as e:
logger.error(f"获取持仓异常: {e}")
if attempt < Config.MAX_RETRY_ATTEMPTS - 1:
time.sleep(Config.RETRY_DELAY)
return False
# ------------------------- 浏览器 -------------------------
def openBrowser(self) -> bool:
"""打开 TGE 对应浏览器实例"""
try:
bit_port = openBrowser(id=self.tge_id)
co = ChromiumOptions()
co.set_local_port(port=bit_port)
self.page = ChromiumPage(addr_or_opts=co)
self.tge_port = bit_port
return True
except Exception:
return False
def take_over_browser(self) -> bool:
"""接管已有浏览器"""
if not self.tge_port:
return False
try:
co = ChromiumOptions()
co.set_local_port(self.tge_port)
self.page = ChromiumPage(addr_or_opts=co)
self.page.set.window.max()
return True
except Exception:
return False
def close_extra_tabs(self) -> bool:
"""关闭多余标签页,只保留第一个"""
if not self.page:
return False
try:
for idx, tab in enumerate(self.page.get_tabs()):
if idx > 0:
tab.close()
return True
except Exception:
return False
def click_safe(self, xpath: str, sleep: float = 0.5) -> bool:
"""安全点击"""
try:
ele = self.page.ele(xpath)
if not ele:
return False
ele.scroll.to_see(center=True)
time.sleep(sleep)
ele.click(by_js=True)
return True
except Exception:
return False
# ------------------------- 交易 -------------------------
def 平仓(self) -> bool:
"""市价平仓(闪电平仓)"""
try:
self.page.ele('x:(//span[normalize-space(text()) = "闪电平仓"])').scroll.to_see(center=True)
time.sleep(0.5)
self.page.ele('x:(//span[normalize-space(text()) = "闪电平仓"])').click(by_js=True)
time.sleep(2)
logger.info("执行平仓")
return True
except Exception as e:
logger.error(f"平仓异常: {e}")
return False
def 开单(self, marketPriceLongOrder: int = 0, size: Optional[float] = None) -> bool:
"""
市价开仓
marketPriceLongOrder: 1 做多, -1 做空
size: 数量(金额)
"""
if size is None or size <= 0:
logger.warning("开单数量无效")
return False
try:
self.click_safe('x:(//button[normalize-space(text()) = "市价"])')
time.sleep(0.5)
self.page.ele('x://input[@placeholder="请输入数量"]').input(size)
time.sleep(0.5)
if marketPriceLongOrder == -1:
self.page.ele('x://*[normalize-space(text()) ="卖出开空"]').click(by_js=True)
elif marketPriceLongOrder == 1:
self.page.ele('x://*[normalize-space(text()) ="买入开多"]').click(by_js=True)
else:
return False
logger.info(f"市价{'做空' if marketPriceLongOrder == -1 else '做多'} 数量={size}")
return True
except Exception as e:
logger.error(f"开单异常: {e}")
return False
def ding(self, text: str, error: bool = False) -> None:
"""日志/通知入口,可在此接入钉钉等"""
if error:
logger.error(text)
else:
logger.info(text)
def action(self) -> None:
"""框架入口:打开浏览器 -> 交易页 -> 取 token -> 拉 K 线 -> 切市价(示例)"""
if not self.openBrowser():
self.ding("打开 TGE 失败!", error=True)
return
logger.info("TGE 浏览器已打开")
self.close_extra_tabs()
self.page.get(url=Config.TRADING_URL)
time.sleep(2)
if not self._get_token():
self.ding("获取 token 失败", error=True)
return
klines = self.get_klines()
if klines:
logger.info(f"获取到 {len(klines)} 根 K 线,最新收盘 {klines[-1]['close']}")
self.click_safe('x:(//button[normalize-space(text()) = "市价"])')
# 此处可接具体策略循环get_klines -> 信号 -> 开单/平仓
# self.平仓()
self.开单(marketPriceLongOrder=1, size=100)
if __name__ == "__main__":
WeexFuturesTransaction(tge_id="86837a981aba4576be6916a0ef6ad785").action()

View File

@@ -1,237 +0,0 @@
import datetime
from loguru import logger
from models.weex import Weex15, Weex1
def is_bullish(candle):
"""判断是否是阳线(开盘价 < 收盘价,即涨)"""
return float(candle['open']) < float(candle['close'])
def is_bearish(candle):
"""判断是否是阴线(开盘价 > 收盘价,即跌)"""
return float(candle['open']) > float(candle['close'])
def check_signal(prev, curr):
"""
判断是否出现包住形态,返回信号类型和方向:
1. 前跌后涨包住 -> 做多信号 (bear_bull_engulf)
2. 前涨后跌包住 -> 做空信号 (bull_bear_engulf)
3. 前涨后涨包住 -> 做多信号 (bull_bull_engulf)
4. 前跌后跌包住 -> 做空信号 (bear_bear_engulf)
"""
p_open, p_close = float(prev['open']), float(prev['close']) # 前一笔
c_open, c_close = float(curr['open']), float(curr['close']) # 当前一笔
# 情况1前跌后涨且涨线包住前跌线 -> 做多信号
if is_bullish(curr) and is_bearish(prev):
if c_open <= p_close and c_close >= p_open:
return "long", "bear_bull_engulf"
# # 情况2前涨后跌且跌线包住前涨线 -> 做空信号
# if is_bearish(curr) and is_bullish(prev):
# if c_open >= p_close and c_close <= p_open:
# return "short", "bull_bear_engulf"
# # 情况3前涨后涨且后涨线包住前涨线 -> 做多信号
# if is_bullish(curr) and is_bullish(prev):
# if c_open <= p_open and c_close >= p_close:
# return "long", "bull_bull_engulf"
# # 情况4前跌后跌且后跌线包住前跌线 -> 做空信号
# if is_bearish(curr) and is_bearish(prev):
# if c_open >= p_open and c_close <= p_close:
# return "short", "bear_bear_engulf"
return None, None
def simulate_trade(direction, entry_price, future_candles, take_profit_diff=30, stop_loss_diff=-10):
"""
模拟交易逐根K线回测
改进版:考虑开盘跳空触发止盈/止损的情况
"""
for candle in future_candles:
open_p = float(candle['open'])
high = float(candle['high'])
low = float(candle['low'])
close = float(candle['close'])
if direction == "long":
tp_price = entry_price + take_profit_diff
sl_price = entry_price + stop_loss_diff
# 🧩 开盘就跳空止盈
if open_p >= tp_price:
return open_p, open_p - entry_price, candle['id']
# 🧩 开盘就跳空止损
if open_p <= sl_price:
return open_p, open_p - entry_price, candle['id']
# 正常区间内触发止盈/止损
if high >= tp_price:
return tp_price, take_profit_diff, candle['id']
if low <= sl_price:
return sl_price, stop_loss_diff, candle['id']
elif direction == "short":
tp_price = entry_price - take_profit_diff
sl_price = entry_price - stop_loss_diff
# 🧩 开盘就跳空止盈
if open_p <= tp_price:
return open_p, entry_price - open_p, candle['id']
# 🧩 开盘就跳空止损
if open_p >= sl_price:
return open_p, entry_price - open_p, candle['id']
# 正常区间内触发止盈/止损
if low <= tp_price:
return tp_price, take_profit_diff, candle['id']
if high >= sl_price:
return sl_price, stop_loss_diff, candle['id']
# 未触发止盈止损,按最后收盘价平仓
final_price = float(future_candles[-1]['close'])
if direction == "long":
diff_money = final_price - entry_price
else:
diff_money = entry_price - final_price
return final_price, diff_money, future_candles[-1]['id']
def get_data_by_date(date_str):
# 将日期字符串转换为 datetime 对象
try:
target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
except ValueError:
print("日期格式不正确,请使用 YYYY-MM-DD 格式。")
return []
# 计算该天的开始时间戳(毫秒级)
start_timestamp = int(target_date.timestamp() * 1000)
# 计算该天的结束时间戳(毫秒级),即下一天 00:00:00 的时间戳减去 1 毫秒
end_timestamp = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1
# 查询该天的数据,并按照 id 字段从小到大排序
query = Weex1.select().where(Weex1.id.between(start_timestamp, end_timestamp)).order_by(Weex1.id.asc())
results = list(query)
# 将结果转换为列表嵌套字典的形式
data_list = []
for item in results:
item_dict = {
'id': item.id,
'open': item.open,
'high': item.high,
'low': item.low,
'close': item.close
}
data_list.append(item_dict)
return data_list
if __name__ == '__main__':
# 示例调用
datas = []
for i in range(1, 31):
date_str = f'2025-9-{i}'
data = get_data_by_date(date_str)
datas.extend(data)
datas = sorted(datas, key=lambda x: x["id"])
for i in range(1, 51):
for i1 in range(1, 51):
zh_project = 0 # 累计盈亏
all_trades = [] # 保存所有交易明细
daily_signals = 0 # 信号总数
daily_wins = 0
daily_profit = 0 # 价差总和
# 四种信号类型的统计
signal_stats = {
"bear_bull_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "涨包跌"},
"bull_bear_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "跌包涨"},
# "bull_bull_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "涨包涨"},
# "bear_bear_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "跌包跌"}
}
# 遍历每根K线寻找信号
for idx in range(1, len(datas) - 1): # 留出未来K线
prev, curr = datas[idx - 1], datas[idx] # 前一笔,当前一笔
entry_candle = datas[idx + 1] # 下一根开盘价作为入场价
future_candles = datas[idx + 1:] # 未来行情
entry_open = float(entry_candle['open']) # 开仓价格
direction, signal_type = check_signal(prev, curr) # 判断开仓方向和信号类型
if direction and signal_type:
daily_signals += 1
exit_price, diff, exit_time = simulate_trade(
direction,
entry_open,
future_candles,
take_profit_diff=i1,
stop_loss_diff=-i
)
# 统计该信号类型的表现
signal_stats[signal_type]["count"] += 1
signal_stats[signal_type]["total_profit"] += diff
if diff > 0:
signal_stats[signal_type]["wins"] += 1
daily_wins += 1
daily_profit += diff
# 将时间戳转换为本地时间
local_time = datetime.datetime.fromtimestamp(entry_candle['id'] / 1000)
formatted_time = local_time.strftime("%Y-%m-%d %H:%M:%S")
exit_time = datetime.datetime.fromtimestamp(exit_time / 1000)
exit_time1 = exit_time.strftime("%Y-%m-%d %H:%M:%S")
# 保存交易详情
all_trades.append(
(
f"{formatted_time}",
"做多" if direction == "long" else "做空",
signal_stats[signal_type]["name"],
entry_open,
exit_price,
diff,
exit_time1
)
)
# ===== 输出每笔交易详情 =====
logger.info("===== 每笔交易详情 =====")
logger.info(f"{i},{i1}")
n = n1 = 0 # n = 总盈利n1 = 总手续费
for date, direction, signal_name, entry, exit, diff, end_time in all_trades:
profit_amount = diff / entry * 10000 # 计算盈利金额
close_fee = 10000 / entry * exit * 0.0005 # 平仓手续费
# logger.info(
# f"{date} {direction}({signal_name}) 入场={entry:.2f} 出场={exit:.2f} 出场时间={end_time} "
# f"差价={diff:.2f} 盈利={profit_amount:.2f} "
# f"开仓手续费=5u 平仓手续费={close_fee:.2f}"
# )
n1 += 5 + close_fee
n += profit_amount
if n > n1 * 0.1:
print(f'一共笔数:{len(all_trades)}')
print(f"一共盈利:{n:.2f}")
print(f'一共手续费:{n1:.2f}')

View File

@@ -1,331 +0,0 @@
"""
量化交易回测系统 - 策略方向反转版
功能:基于包住形态的交易信号识别和回测分析(信号方向已按用户要求反转)
作者量化交易团队修改ChatGPT
版本2.1
"""
import datetime
from typing import List, Dict, Tuple, Optional, Any
from dataclasses import dataclass
from loguru import logger
from peewee import fn
from models.weex import Weex15, Weex1
# ===============================================================
# 📊 配置管理类
# ===============================================================
@dataclass
class BacktestConfig:
"""回测配置类"""
# 交易参数
take_profit: float = 8.0 # 止盈点数
stop_loss: float = -1.0 # 止损点数(负数表示点差方向)
contract_size: float = 10000 # 合约规模
open_fee: float = 5.0 # 开仓手续费
close_fee_rate: float = 0.0005 # 平仓手续费率
# 回测日期范围
start_date: str = "2025-07-01"
end_date: str = "2025-07-31"
# 信号参数
enable_bear_bull_engulf: bool = True # 涨包跌(命名保留)
enable_bull_bear_engulf: bool = True # 跌包涨(命名保留)
def __post_init__(self):
"""验证配置参数"""
if self.take_profit <= 0:
raise ValueError("止盈点数必须大于0")
if self.stop_loss >= 0:
raise ValueError("止损点数必须小于0")
@dataclass
class TradeRecord:
"""交易记录类"""
entry_time: datetime.datetime
exit_time: datetime.datetime
signal_type: str
direction: str
entry_price: float
exit_price: float
profit_loss: float
profit_amount: float
total_fee: float
net_profit: float
@dataclass
class SignalStats:
"""信号统计类"""
signal_name: str
count: int = 0
wins: int = 0
total_profit: float = 0.0
@property
def win_rate(self) -> float:
"""胜率计算"""
return (self.wins / self.count * 100) if self.count > 0 else 0.0
@property
def avg_profit(self) -> float:
"""平均盈利"""
return self.total_profit / self.count if self.count > 0 else 0.0
# ===============================================================
# 📊 数据获取模块
# ===============================================================
def get_data_by_date(model, date_str):
"""按天获取指定表的数据date_str 需为 YYYY-MM-DD"""
try:
target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
except ValueError:
logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。")
return []
start_ts = int(target_date.timestamp() * 1000)
end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1
query = (model
.select()
.where(model.id.between(start_ts, end_ts))
.order_by(model.id.asc()))
return [
{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close}
for i in query
]
def get_future_data_1min(start_ts, end_ts):
"""获取指定时间范围内的 1 分钟数据"""
query = (Weex1
.select()
.where(Weex1.id.between(start_ts, end_ts))
.order_by(Weex1.id.asc()))
return [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query]
# ===============================================================
# 📈 信号判定模块(**方向已反转**
# ===============================================================
def is_bullish(c): return float(c['open']) < float(c['close'])
def is_bearish(c): return float(c['open']) > float(c['close'])
def check_signal(prev, curr):
"""
判断是否出现包住形态并返回direction, signal_key
注意:根据用户要求,这里把原来的方向映射“反转”:
- 如果是 前跌后涨包住(过去我们认为做多),现在**改为做空**
- 如果是 前涨后跌包住(过去我们认为做空),现在**改为做多**
signal_key 保持 "bear_bull_engulf" / "bull_bear_engulf" 以便统计区分信号种类
"""
p_open, p_close = float(prev['open']), float(prev['close'])
c_open, c_close = float(curr['open']), float(curr['close'])
# 前跌后涨包住 -> **原来做多,现在改为做空**
if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open:
return "short", "bear_bull_engulf"
# 前涨后跌包住 -> **原来做空,现在改为做多**
if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open:
return "long", "bull_bear_engulf"
return None, None
# ===============================================================
# 💹 回测模拟模块(使用 1 分钟数据)
# ===============================================================
def simulate_trade(direction, entry_price, entry_time, next_15min_time, tp=8, sl=-1):
"""
用 1 分钟数据进行精细化止盈止损模拟
entry_time: 当前信号的 entry candle id毫秒时间戳
next_15min_time: 下一个15min时间戳用于界定止盈止损分析范围
direction'long''short'
entry_price开仓价格
"""
# 查 15 分钟之间的 1 分钟数据
future_candles = get_future_data_1min(entry_time, next_15min_time)
if not future_candles:
return None, 0, None
# 止盈止损价格tp 为正sl 为负)
tp_price = entry_price + tp if direction == "long" else entry_price - tp
sl_price = entry_price + sl if direction == "long" else entry_price - sl
for candle in future_candles:
open_p, high, low = map(float, (candle['open'], candle['high'], candle['low']))
if direction == "long":
# 开盘跳空优先
if open_p >= tp_price:
return open_p, open_p - entry_price, candle['id']
if open_p <= sl_price:
return open_p, open_p - entry_price, candle['id']
# 盘中触及
if high >= tp_price:
return tp_price, tp, candle['id']
if low <= sl_price:
return sl_price, sl, candle['id']
else: # short
if open_p <= tp_price:
return open_p, entry_price - open_p, candle['id']
if open_p >= sl_price:
return open_p, entry_price - open_p, candle['id']
if low <= tp_price:
return tp_price, tp, candle['id']
if high >= sl_price:
return sl_price, sl, candle['id']
# 未触及 TP/SL用最后一根收盘价平仓
final = future_candles[-1]
final_price = float(final['close'])
diff = (final_price - entry_price) if direction == "long" else (entry_price - final_price)
return final_price, diff, final['id']
# ===============================================================
# 📊 主回测流程(含单笔持仓逻辑)
# ===============================================================
def backtest_single_position(dates: List[str], tp: float, sl: float):
"""单笔持仓回测,保证任意时刻只有一笔持仓"""
all_data = []
for date_str in dates:
all_data.extend(get_data_by_date(Weex15, date_str))
all_data.sort(key=lambda x: x['id'])
stats = {
"bear_bull_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "涨包跌bear_bull_engulf"},
"bull_bear_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "跌包涨bull_bear_engulf"},
}
trades = []
current_position = None # 当前持仓信息(字典或 None
for idx in range(1, len(all_data) - 1):
prev, curr = all_data[idx - 1], all_data[idx]
entry_candle = all_data[idx + 1]
direction, signal = check_signal(prev, curr)
if not direction:
continue
# 下一个 15 分钟K线的时间范围若长度不足则取到最后
next_15min_time = all_data[idx + 50]['id'] if idx + 50 < len(all_data) else all_data[-1]['id']
entry_price = float(entry_candle['open'])
# 如果有持仓
if current_position:
# 同向信号 -> 跳过不开(继续等待当前持仓结束)
if current_position['direction'] == direction:
continue
# 反向信号 -> 先按当前持仓的规则用 simulate_trade 平仓,然后再开新仓
else:
exit_price, diff, exit_time = simulate_trade(
current_position['direction'],
current_position['entry_price'],
current_position['entry_time'],
entry_candle['id'],
tp=tp,
sl=sl
)
if exit_price is not None:
# 记录平仓交易(一笔持仓作为一条记录)
trades.append({
"entry_time": datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
"exit_time": datetime.datetime.fromtimestamp(exit_time / 1000),
"signal": current_position['signal'],
"direction": "做多" if current_position['direction'] == "long" else "做空",
"entry": current_position['entry_price'],
"exit": exit_price,
"diff": diff
})
# 更新统计signal 字段是中文名)
stats_key = 'bear_bull_engulf' if current_position['signal'].startswith('涨包跌') else 'bull_bear_engulf'
stats[stats_key]['count'] += 1
stats[stats_key]['total_profit'] += diff
if diff > 0:
stats[stats_key]['wins'] += 1
# 清空当前持仓,接下来在下方开新仓
current_position = None
# 开新仓(无论之前是否有仓位,若有仓位已被平掉现在可以开仓)
current_position = {
"direction": direction,
"signal": stats[signal]['name'],
"entry_price": entry_price,
"entry_time": entry_candle['id']
}
# 最后一笔持仓如果未平仓,用最后收盘价平掉(以全数据范围最后时间为结算界限)
if current_position:
exit_price, diff, exit_time = simulate_trade(
current_position['direction'],
current_position['entry_price'],
current_position['entry_time'],
all_data[-1]['id'],
tp=tp,
sl=sl
)
if exit_price is not None:
trades.append({
"entry_time": datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
"exit_time": datetime.datetime.fromtimestamp(exit_time / 1000),
"signal": current_position['signal'],
"direction": "做多" if current_position['direction'] == "long" else "做空",
"entry": current_position['entry_price'],
"exit": exit_price,
"diff": diff
})
stats_key = 'bear_bull_engulf' if current_position['signal'].startswith('涨包跌') else 'bull_bear_engulf'
stats[stats_key]['count'] += 1
stats[stats_key]['total_profit'] += diff
if diff > 0:
stats[stats_key]['wins'] += 1
return trades, stats
# ===============================================================
# 🚀 启动主流程(示例)
# ===============================================================
if __name__ == '__main__':
# 修正日期格式为 YYYY-MM-DD零填充
dates = [f"2025-09-{i:02d}" for i in range(1, 31)]
# 示例参数:止盈 10 点,止损 -50 点(保留你的原调用方式)
trades, stats = backtest_single_position(dates, tp=50, sl=-10)
logger.info("===== 每笔交易详情 =====")
for t in trades:
logger.info(
f"{t['entry_time']} {t['direction']}({t['signal']}) "
f"入场={t['entry']:.2f} 出场={t['exit']:.2f} 出场时间={t['exit_time']} "
f"差价={t['diff']:.2f}"
)
total_profit = sum(t['diff'] / t['entry'] * 10000 for t in trades) if trades else 0.0
total_fee = sum(5 + 10000 / t['entry'] * t['exit'] * 0.0005 for t in trades) if trades else 0.0
print(f"\n一共交易笔数:{len(trades)}")
print(f"一共盈利(按手数/点值换算示例):{total_profit:.2f}")
print(f"一共手续费:{total_fee:.2f}")
print(f"净利润:{total_profit - total_fee:.2f}")
print("\n===== 信号统计 =====")
for k, v in stats.items():
print(f"{v['name']} -> 笔数: {v['count']}, 胜数: {v['wins']}, 总点差: {v['total_profit']:.2f}")

View File

@@ -1,409 +0,0 @@
"""
量化交易回测系统 - 优化版
功能:基于包住形态的交易信号识别和回测分析
作者:量化交易团队
版本2.0
"""
import datetime
from typing import List, Dict, Tuple, Optional, Any
from dataclasses import dataclass
from loguru import logger
from peewee import fn
from models.weex import Weex15, Weex1
# ===============================================================
# 📊 配置管理类
# ===============================================================
@dataclass
class BacktestConfig:
"""回测配置类"""
# 交易参数
take_profit: float = 8.0 # 止盈点数
stop_loss: float = -1.0 # 止损点数
contract_size: float = 10000 # 合约规模
open_fee: float = 5.0 # 开仓手续费
close_fee_rate: float = 0.0005 # 平仓手续费率
# 回测日期范围
start_date: str = "2025-7-1"
end_date: str = "2025-7-31"
# 信号参数
enable_bear_bull_engulf: bool = True # 涨包跌信号
enable_bull_bear_engulf: bool = True # 跌包涨信号
def __post_init__(self):
"""验证配置参数"""
if self.take_profit <= 0:
raise ValueError("止盈点数必须大于0")
if self.stop_loss >= 0:
raise ValueError("止损点数必须小于0")
@dataclass
class TradeRecord:
"""交易记录类"""
entry_time: datetime.datetime
exit_time: datetime.datetime
signal_type: str
direction: str
entry_price: float
exit_price: float
profit_loss: float
profit_amount: float
total_fee: float
net_profit: float
@dataclass
class SignalStats:
"""信号统计类"""
signal_name: str
count: int = 0
wins: int = 0
total_profit: float = 0.0
@property
def win_rate(self) -> float:
"""胜率计算"""
return (self.wins / self.count * 100) if self.count > 0 else 0.0
@property
def avg_profit(self) -> float:
"""平均盈利"""
return self.total_profit / self.count if self.count > 0 else 0.0
# ===============================================================
# 📊 数据获取模块
# ===============================================================
def get_data_by_date(model, date_str):
"""按天获取指定表的数据"""
try:
target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
except ValueError:
logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。")
return []
start_ts = int(target_date.timestamp() * 1000)
end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1
query = (model
.select()
.where(model.id.between(start_ts, end_ts))
.order_by(model.id.asc()))
return [
{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close}
for i in query
]
def get_future_data_1min(start_ts, end_ts):
"""获取指定时间范围内的 1 分钟数据"""
query = (Weex1
.select()
.where(Weex1.id.between(start_ts, end_ts))
.order_by(Weex1.id.asc()))
return [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query]
# ===============================================================
# 📈 信号判定模块
# ===============================================================
def is_bullish(c): return float(c['open']) < float(c['close'])
def is_bearish(c): return float(c['open']) > float(c['close'])
def check_signal(prev, curr):
"""判断是否出现包住形态"""
p_open, p_close = float(prev['open']), float(prev['close'])
c_open, c_close = float(curr['open']), float(curr['close'])
# 前跌后涨包住 -> 做多
if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open:
return "long", "bear_bull_engulf"
# 前涨后跌包住 -> 做空
if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open:
return "short", "bull_bear_engulf"
return None, None
# ===============================================================
# 💹 回测模拟模块(使用 1 分钟数据)
# ===============================================================
def simulate_trade(direction, entry_price, entry_time, next_15min_time, tp=8, sl=-1):
"""
用 1 分钟数据进行精细化止盈止损模拟
entry_time: 当前信号的 entry candle id毫秒时间戳
next_15min_time: 下一个15min时间戳用于界定止盈止损分析范围
direction信号类型
entry_price开仓价格
entry_time开仓时间
next_15min_time15分钟未来行情
"""
# 查 15 分钟之间的 1 分钟数据
future_candles = get_future_data_1min(entry_time, next_15min_time)
if not future_candles:
return None, 0, None
tp_price = entry_price + tp if direction == "long" else entry_price - tp # 止盈价位
sl_price = entry_price + sl if direction == "long" else entry_price - sl # 止损价位
for candle in future_candles:
open_p, high, low = map(float, (candle['open'], candle['high'], candle['low']))
if direction == "long": # long
if open_p >= tp_price: # 开盘跳空止盈 涨信号,
return open_p, open_p - entry_price, candle['id']
if open_p <= sl_price: # 开盘跳空止损
return open_p, open_p - entry_price, candle['id']
if high >= tp_price:
return tp_price, tp, candle['id']
if low <= sl_price:
return sl_price, sl, candle['id']
else: # short 跌信号
if open_p <= tp_price: #
return open_p, entry_price - open_p, candle['id']
if open_p >= sl_price:
return open_p, entry_price - open_p, candle['id']
if low <= tp_price:
return tp_price, tp, candle['id']
if high >= sl_price:
return sl_price, sl, candle['id']
# 未触发止盈止损,用最后一根收盘价平仓
final = future_candles[-1]
final_price = float(final['close'])
diff = (final_price - entry_price) if direction == "long" else (entry_price - final_price)
return final_price, diff, final['id']
# ===============================================================
# 📊 主回测流程
# ===============================================================
def backtest(dates, tp, sl):
"""
datas日期的列表
:param dates:
:param tp:
:param sl:
:return:
"""
all_data = []
for date_str in dates:
all_data.extend(get_data_by_date(Weex15, date_str)) # 获取每天的数据15分钟k线数据
all_data.sort(key=lambda x: x['id'])
stats = {
"bear_bull_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "涨包跌"},
"bull_bear_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "跌包涨"},
}
trades = []
for idx in range(1, len(all_data) - 1):
prev, curr = all_data[idx - 1], all_data[idx] # 前一笔,当前一笔
entry_candle = all_data[idx + 1] # 下一笔开仓k线
direction, signal = check_signal(prev, curr)
if not direction:
continue
# 下一个 15 分钟K线的时间范围
next_15min_time = all_data[idx + 50]['id'] if idx + 50 < len(all_data) else all_data[-1]['id']
entry_price = float(entry_candle['open']) # 开仓价格
exit_price, diff, exit_time = simulate_trade(
direction,
entry_price,
entry_candle['id'],
next_15min_time,
tp=tp,
sl=sl
)
if exit_price is None:
continue
stats[signal]['count'] += 1
stats[signal]['total_profit'] += diff
if diff > 0:
stats[signal]['wins'] += 1
trades.append({
"entry_time": datetime.datetime.fromtimestamp(entry_candle['id'] / 1000),
"exit_time": datetime.datetime.fromtimestamp(exit_time / 1000),
"signal": stats[signal]['name'],
"direction": "做多" if direction == "long" else "做空",
"entry": entry_price,
"exit": exit_price,
"diff": diff
})
return trades, stats
def backtest_single_position(dates, tp, sl):
"""单笔持仓回测,处理同向/反向信号"""
all_data = []
for date_str in dates:
all_data.extend(get_data_by_date(Weex15, date_str))
all_data.sort(key=lambda x: x['id'])
stats = {
"bear_bull_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "涨包跌"},
"bull_bear_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "跌包涨"},
}
trades = []
current_position = None # 当前持仓信息
for idx in range(1, len(all_data) - 1):
prev, curr = all_data[idx - 1], all_data[idx]
entry_candle = all_data[idx + 1]
direction, signal = check_signal(prev, curr)
if not direction:
continue
# 下一个 15 分钟K线的时间范围
next_15min_time = all_data[idx + 50]['id'] if idx + 50 < len(all_data) else all_data[-1]['id']
entry_price = float(entry_candle['open'])
# 有持仓
if current_position:
# 同向信号 -> 跳过
if current_position['direction'] == direction:
continue
# 反向信号 -> 先平掉当前持仓,再开新仓
else:
# 先按当前位置止盈止损平仓
exit_price, diff, exit_time = simulate_trade(
current_position['direction'],
current_position['entry_price'],
current_position['entry_time'],
entry_candle['id'],
tp=tp,
sl=sl
)
if exit_price is not None:
trades.append({
"entry_time": datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
"exit_time": datetime.datetime.fromtimestamp(exit_time / 1000),
"signal": current_position['signal'],
"direction": "做多" if current_position['direction'] == "long" else "做空",
"entry": current_position['entry_price'],
"exit": exit_price,
"diff": diff
})
# 更新统计
stats_key = 'bear_bull_engulf' if current_position['signal'] == '涨包跌' else 'bull_bear_engulf'
stats[stats_key]['count'] += 1
stats[stats_key]['total_profit'] += diff
if diff > 0:
stats[stats_key]['wins'] += 1
current_position = None # 清空持仓
# 开新仓
current_position = {
"direction": direction,
"signal": stats[signal]['name'],
"entry_price": entry_price,
"entry_time": entry_candle['id']
}
# 最后一笔持仓如果未平仓,用最后收盘价平掉
if current_position:
exit_price, diff, exit_time = simulate_trade(
current_position['direction'],
current_position['entry_price'],
current_position['entry_time'],
all_data[-1]['id'],
tp=tp,
sl=sl
)
if exit_price is not None:
trades.append({
"entry_time": datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
"exit_time": datetime.datetime.fromtimestamp(exit_time / 1000),
"signal": current_position['signal'],
"direction": "做多" if current_position['direction'] == "long" else "做空",
"entry": current_position['entry_price'],
"exit": exit_price,
"diff": diff
})
stats_key = 'bear_bull_engulf' if current_position['signal'] == '涨包跌' else 'bull_bear_engulf'
stats[stats_key]['count'] += 1
stats[stats_key]['total_profit'] += diff
if diff > 0:
stats[stats_key]['wins'] += 1
return trades, stats
# ===============================================================
# 🚀 启动主流程
# ===============================================================
if __name__ == '__main__':
dates = [f"2025-10-{i}" for i in range(1, 31)]
trades, stats = backtest_single_position(dates, tp=50, sl=-10)
logger.info("===== 每笔交易详情 =====")
for t in trades:
logger.info(
f"{t['entry_time']} {t['direction']}({t['signal']}) "
f"入场={t['entry']:.2f} 出场={t['exit']:.2f} 出场时间={t['exit_time']} "
f"差价={t['diff']:.2f}"
)
total_profit = sum(t['diff'] / t['entry'] * 10000 for t in trades)
total_fee = sum(5 + 10000 / t['entry'] * t['exit'] * 0.0005 for t in trades)
print(f"\n一共交易笔数:{len(trades)}")
print(f"一共盈利:{total_profit:.2f}")
print(f"一共手续费:{total_fee:.2f}")
print(f"净利润:{total_profit - total_fee:.2f}")
print("\n===== 信号统计 =====")
# ===============================================================================================================================
# for i in range(1, 16):
# for i1 in range(1, 51):
# trades, stats = backtest_single_position(dates, tp=i1, sl=-i)
#
# total_profit = sum(t['diff'] / t['entry'] * 10000 for t in trades)
# total_fee = sum(5 + 10000 / t['entry'] * t['exit'] * 0.0005 for t in trades)
#
# if total_profit > total_fee * 0.1:
# print("\n===== 信号统计 =====")
# print(f"止盈:{i1}, 止损:{i}")
# print(f"\n一共交易笔数{len(trades)}")
# print(f"一共盈利:{total_profit:.2f}")
# print(f"一共手续费:{total_fee:.2f}")
# print(f"净利润:{total_profit - total_fee * 0.1}")
# 需要优化,目前有两种情况,第一种,同向,不如说上一单开单是涨,上一单还没有结束,当前信号来了,就不开单,等上一单到了上一单的止损位或者止盈位在平仓
# 第二种,方向,上一单是涨,上一单还没有结束,当前信号来了,是跌,然后就按照现在这个信号要开仓的位置,平掉上一单,然后开一单方向的,
# 一笔中可能有好几次信号,都按照上面的规则去判断,要保证同一时间,只会有一笔持仓,
# 打印每笔的交易详细,如果一笔中同向,输入为一条交易记录

File diff suppressed because it is too large Load Diff

View File

@@ -1,312 +0,0 @@
"""
量化交易回测系统 - 优化版
功能:基于包住形态的交易信号识别和回测分析
作者:量化交易团队
版本2.0
"""
import datetime
from typing import List, Dict, Tuple, Optional, Any
from dataclasses import dataclass
from loguru import logger
from peewee import fn
from models.weex import Weex15, Weex1
# ===============================================================
# 📊 配置管理类
# ===============================================================
@dataclass
class BacktestConfig:
"""回测配置类"""
# 交易参数
take_profit: float = 8.0 # 止盈点数
stop_loss: float = -1.0 # 止损点数
contract_size: float = 10000 # 合约规模
open_fee: float = 5.0 # 开仓手续费
close_fee_rate: float = 0.0005 # 平仓手续费率
# 回测日期范围
start_date: str = "2025-7-1"
end_date: str = "2025-7-31"
# 信号参数
enable_bear_bull_engulf: bool = True # 涨包跌信号
enable_bull_bear_engulf: bool = True # 跌包涨信号
def __post_init__(self):
"""验证配置参数"""
if self.take_profit <= 0:
raise ValueError("止盈点数必须大于0")
if self.stop_loss >= 0:
raise ValueError("止损点数必须小于0")
@dataclass
class TradeRecord:
"""交易记录类"""
entry_time: datetime.datetime
exit_time: datetime.datetime
signal_type: str
direction: str
entry_price: float
exit_price: float
profit_loss: float
profit_amount: float
total_fee: float
net_profit: float
@dataclass
class SignalStats:
"""信号统计类"""
signal_name: str
count: int = 0
wins: int = 0
total_profit: float = 0.0
@property
def win_rate(self) -> float:
"""胜率计算"""
return (self.wins / self.count * 100) if self.count > 0 else 0.0
@property
def avg_profit(self) -> float:
"""平均盈利"""
return self.total_profit / self.count if self.count > 0 else 0.0
# ===============================================================
# 📊 数据获取模块
# ===============================================================
def get_data_by_date(model, date_str):
"""按天获取指定表的数据"""
try:
target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
except ValueError:
logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。")
return []
start_ts = int(target_date.timestamp() * 1000)
end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1
query = (model
.select()
.where(model.id.between(start_ts, end_ts))
.order_by(model.id.asc()))
return [
{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close}
for i in query
]
def get_future_data_1min(start_ts, end_ts):
"""获取指定时间范围内的 1 分钟数据"""
query = (Weex1
.select()
.where(Weex1.id.between(start_ts, end_ts))
.order_by(Weex1.id.asc()))
return [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query]
# ===============================================================
# 📈 信号判定模块
# ===============================================================
def is_bullish(c): return float(c['open']) < float(c['close'])
def is_bearish(c): return float(c['open']) > float(c['close'])
def check_signal(prev, curr):
"""判断是否出现包住形态"""
p_open, p_close = float(prev['open']), float(prev['close'])
c_open, c_close = float(curr['open']), float(curr['close'])
# 前跌后涨包住 -> 做多
if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open:
return "long", "bear_bull_engulf"
# 前涨后跌包住 -> 做空
if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open:
return "short", "bull_bear_engulf"
return None, None
# ===============================================================
# 💹 回测模拟模块(使用 1 分钟数据)
# ===============================================================
def simulate_trade(direction, entry_price, entry_time, next_15min_time, tp=8, sl=-1):
"""
用 1 分钟数据进行精细化止盈止损模拟
entry_time: 当前信号的 entry candle id毫秒时间戳
next_15min_time: 下一个15min时间戳用于界定止盈止损分析范围
direction信号类型
entry_price开仓价格
entry_time开仓时间
next_15min_time15分钟未来行情
"""
# 查 15 分钟之间的 1 分钟数据
future_candles = get_future_data_1min(entry_time, next_15min_time)
if not future_candles:
return None, 0, None
tp_price = entry_price + tp if direction == "long" else entry_price - tp # 止盈价位
sl_price = entry_price + sl if direction == "long" else entry_price - sl # 止损价位
for candle in future_candles:
open_p, high, low = map(float, (candle['open'], candle['high'], candle['low']))
if direction == "long": # long
if open_p >= tp_price: # 开盘跳空止盈 涨信号,
return open_p, open_p - entry_price, candle['id']
if open_p <= sl_price: # 开盘跳空止损
return open_p, open_p - entry_price, candle['id']
if high >= tp_price:
return tp_price, tp, candle['id']
if low <= sl_price:
return sl_price, sl, candle['id']
else: # short 跌信号
if open_p <= tp_price: #
return open_p, entry_price - open_p, candle['id']
if open_p >= sl_price:
return open_p, entry_price - open_p, candle['id']
if low <= tp_price:
return tp_price, tp, candle['id']
if high >= sl_price:
return sl_price, sl, candle['id']
# 未触发止盈止损,用最后一根收盘价平仓
final = future_candles[-1]
final_price = float(final['close'])
diff = (final_price - entry_price) if direction == "long" else (entry_price - final_price)
return final_price, diff, final['id']
# ===============================================================
# 📊 主回测流程
# ===============================================================
def backtest(dates, tp, sl):
"""
datas日期的列表
:param dates:
:param tp:
:param sl:
:return:
"""
all_data = []
for date_str in dates:
all_data.extend(get_data_by_date(Weex15, date_str)) # 获取每天的数据15分钟k线数据
all_data.sort(key=lambda x: x['id'])
stats = {
"bear_bull_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "涨包跌"},
"bull_bear_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "跌包涨"},
}
trades = []
for idx in range(1, len(all_data) - 1):
prev, curr = all_data[idx - 1], all_data[idx] # 前一笔,当前一笔
entry_candle = all_data[idx + 1] # 下一笔开仓k线
direction, signal = check_signal(prev, curr)
if not direction:
continue
# 下一个 15 分钟K线的时间范围
next_15min_time = all_data[idx + 50]['id'] if idx + 50 < len(all_data) else all_data[-1]['id']
entry_price = float(entry_candle['open']) # 开仓价格
exit_price, diff, exit_time = simulate_trade(
direction,
entry_price,
entry_candle['id'],
next_15min_time,
tp=tp,
sl=sl
)
if exit_price is None:
continue
stats[signal]['count'] += 1
stats[signal]['total_profit'] += diff
if diff > 0:
stats[signal]['wins'] += 1
trades.append({
"entry_time": datetime.datetime.fromtimestamp(entry_candle['id'] / 1000),
"exit_time": datetime.datetime.fromtimestamp(exit_time / 1000),
"signal": stats[signal]['name'],
"direction": "做多" if direction == "long" else "做空",
"entry": entry_price,
"exit": exit_price,
"diff": diff
})
return trades, stats
# ===============================================================
# 🚀 启动主流程
# ===============================================================
if __name__ == '__main__':
dates = [f"2025-9-{i}" for i in range(1, 31)]
# for i in range(5, 11):
# for i1 in range(25, 51):
trades, stats = backtest(dates, tp=50, sl=-10)
logger.info("===== 每笔交易详情 =====")
for t in trades:
logger.info(
f"{t['entry_time']} {t['direction']}({t['signal']}) "
f"入场={t['entry']:.2f} 出场={t['exit']:.2f} 出场时间={t['exit_time']} "
f"差价={t['diff']:.2f}"
)
total_profit = sum(t['diff'] / t['entry'] * 10000 for t in trades)
total_fee = sum(5 + 10000 / t['entry'] * t['exit'] * 0.0005 for t in trades)
# print(f"止盈:{i1}, 止损:{i}")
print(f"\n一共交易笔数:{len(trades)}")
print(f"一共盈利:{total_profit:.2f}")
print(f"一共手续费:{total_fee:.2f}")
print(f"净利润:{total_profit - total_fee:.2f}")
print("\n===== 信号统计 =====")
# if total_profit > total_fee * 0.1:
# print(f"止盈:{i1}, 止损:{i}")
# print(f"\n一共交易笔数{len(trades)}")
# print(f"一共盈利:{total_profit:.2f}")
# print(f"一共手续费:{total_fee:.2f}")
# print(f"净利润:{total_profit - total_fee * 0.1}")
#
# print("\n===== 信号统计 =====")
#
# for k, v in stats.items():
# win_rate = (v['wins'] / v['count'] * 100) if v['count'] > 0 else 0
# print(
# f"{v['name']} ({k}) - 信号数: {v['count']} | 胜率: {win_rate:.2f}% | 总盈利: {v['total_profit']:.2f}")
# 需要优化,目前有两种情况,第一种,同向,不如说上一单开单是涨,上一单还没有结束,当前信号来了,就不开单,等上一单到了上一单的止损位或者止盈位在平仓
# 第二种,方向,上一单是涨,上一单还没有结束,当前信号来了,是跌,然后就按照现在这个信号要开仓的位置,平掉上一单,然后开一单方向的,
# 一笔中可能有好几次信号,都按照上面的规则去判断,要保证同一时间,只会有一笔持仓,
# 打印每笔的交易详细,如果一笔中同向,输入为一条交易记录,一条加以记录能够直观的看出中间有多少笔

View File

@@ -1,259 +0,0 @@
"""
量化交易回测系统 - 仅15分钟K线 & 信号续持/反手/单根反色平仓逻辑(完整版)
"""
import datetime
from dataclasses import dataclass
from typing import List, Dict, Optional
from loguru import logger
from models.weex import Weex1Hour # 替换为你的15分钟K线模型
# ========================= 工具函数 =========================
def is_bullish(c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(c): # 阴线
return float(c['close']) < float(c['open'])
def check_signal(prev, curr):
"""
包住形态信号判定仅15分钟K线
- 前跌后涨包住 -> 做多
- 前涨后跌包住 -> 做空
"""
p_open, p_close = float(prev['open']), float(prev['close'])
c_open, c_close = float(curr['open']), float(curr['close'])
# 前跌后涨包住 -> 做多
if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open:
return "long", "bear_bull_engulf"
# 前涨后跌包住 -> 做空
if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open:
return "short", "bull_bear_engulf"
return None, None
def get_data_by_date(model, date_str: str):
"""按天获取指定表的数据15分钟"""
try:
target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
except ValueError:
logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。")
return []
start_ts = int(target_date.timestamp() * 1000)
end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1
query = model.select().where(model.id.between(start_ts, end_ts)).order_by(model.id.asc())
return [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query]
# ========================= 回测逻辑 =========================
def backtest_15m_trend_optimized(dates: List[str]):
all_data: List[Dict] = []
for d in dates:
all_data.extend(get_data_by_date(Weex1Hour, d))
if not all_data:
return [], {
'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'},
'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'},
}
all_data.sort(key=lambda x: x['id'])
stats = {
'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'},
'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'},
}
trades: List[Dict] = []
current_position: Optional[Dict] = None
idx = 1
while idx < len(all_data) - 1:
prev, curr, next_bar = all_data[idx - 1], all_data[idx], all_data[idx + 1]
direction, signal_key = check_signal(prev, curr)
# 空仓 -> 碰到信号则开仓
if current_position is None and direction:
entry_price = float(next_bar['open'])
current_position = {
'direction': direction,
'signal': stats[signal_key]['name'],
'signal_key': signal_key,
'entry_price': entry_price,
'entry_time': next_bar['id']
}
stats[signal_key]['count'] += 1
idx += 1
continue
if current_position:
pos_dir = current_position['direction']
pos_sig_key = current_position['signal_key']
# 反向信号 -> 下一根开盘平仓 + 同价反手
if direction and direction != pos_dir:
exit_price = float(next_bar['open'])
diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else (
current_position['entry_price'] - exit_price)
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000),
'signal': current_position['signal'],
'direction': '做多' if pos_dir == 'long' else '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[pos_sig_key]['total_profit'] += diff
if diff > 0: stats[pos_sig_key]['wins'] += 1
current_position = {
'direction': direction,
'signal': stats[signal_key]['name'],
'signal_key': signal_key,
'entry_price': exit_price,
'entry_time': next_bar['id']
}
stats[signal_key]['count'] += 1
idx += 1
continue
# 同向信号 -> 续持
if direction and direction == pos_dir:
idx += 1
continue
# 单根反色K线 -> 判断后续是否能组成信号
curr_is_opposite = (pos_dir == 'long' and is_bearish(curr)) or (pos_dir == 'short' and is_bullish(curr))
if curr_is_opposite:
can_peek = idx + 1 < len(all_data)
if can_peek:
lookahead_dir, _ = check_signal(curr, all_data[idx + 1])
if lookahead_dir is not None:
idx += 1
continue # 后续可组成信号,等待信号处理
# 否则按收盘价平仓
exit_price = float(next_bar['close'])
diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else (
current_position['entry_price'] - exit_price)
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000),
'signal': current_position['signal'],
'direction': '做多' if pos_dir == 'long' else '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[pos_sig_key]['total_profit'] += diff
if diff > 0: stats[pos_sig_key]['wins'] += 1
current_position = None
idx += 1
# 尾仓:最后一根收盘价平仓
if current_position:
last = all_data[-1]
exit_price = float(last['close'])
pos_dir = current_position['direction']
diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else (
current_position['entry_price'] - exit_price)
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(last['id'] / 1000),
'signal': current_position['signal'],
'direction': '做多' if pos_dir == 'long' else '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[current_position['signal_key']]['total_profit'] += diff
if diff > 0: stats[current_position['signal_key']]['wins'] += 1
return trades, stats
# ========================= 运行示例(优化版盈利计算) =========================
if __name__ == '__main__':
dates = []
for i in range(1, 11):
for i1 in range(1, 31):
dates.append(f"2025-{f'0{i}' if len(str(i)) < 2 else i}-{i1}")
#
# print(dates)
# dates = [f"2025-10-{i}" for i in range(1, 31)]
trades, stats = backtest_15m_trend_optimized(dates)
logger.info("===== 每笔交易详情 =====")
# === 参数设定 ===
contract_size = 10000 # 合约规模1手对应多少基础货币
open_fee_fixed = 5 # 固定开仓手续费
close_fee_rate = 0.0005 # 按成交额比例的平仓手续费率
total_points_profit = 0 # 累计点差
total_money_profit = 0 # 累计金额盈利
total_fee = 0 # 累计手续费
for t in trades:
entry = t['entry']
exit = t['exit']
direction = t['direction']
# === 1⃣ 原始价差(点差) ===
point_diff = (exit - entry) if direction == '做多' else (entry - exit)
# === 2⃣ 金额盈利(考虑合约规模) ===
money_profit = point_diff / entry * contract_size # 利润以基础货币计例如USD
# === 3⃣ 手续费计算 ===
# 开仓 + 平仓手续费(按比例计算 + 固定)
fee = open_fee_fixed + (contract_size / entry * exit * close_fee_rate)
# === 4⃣ 净利润 ===
net_profit = money_profit - fee
# 保存计算结果
t.update({
'point_diff': point_diff,
'raw_profit': money_profit,
'fee': fee,
'net_profit': net_profit
})
total_points_profit += point_diff
total_money_profit += money_profit
total_fee += fee
# if net_profit > 500 or net_profit < -500:
logger.info(
f"{t['entry_time']} {direction}({t['signal']}) "
f"入={entry:.2f} 出={exit:.2f} 差价={point_diff:.2f} "
f"原始盈利={money_profit:.2f} 手续费={fee:.2f} 净利润={net_profit:.2f} {t['exit_time']}"
)
# === 汇总统计 ===
total_net_profit = total_money_profit - total_fee
print(f"\n一共交易笔数:{len(trades)}")
print(f"总点差:{total_points_profit:.2f}")
print(f"总原始盈利(未扣费):{total_money_profit:.2f}")
print(f"总手续费:{total_fee:.2f}")
print(f"总净利润:{total_net_profit:.2f}\n")
print("===== 信号统计 =====")
for k, v in stats.items():
name, count, wins, total_p = v['name'], v['count'], v['wins'], v['total_profit']
win_rate = (wins / count * 100) if count > 0 else 0.0
avg_p = (total_p / count) if count > 0 else 0.0
print(f"{name}: 次数={count} 胜率={win_rate:.2f}% 总价差={total_p:.2f} 平均价差={avg_p:.2f}")

View File

@@ -1,265 +0,0 @@
"""
量化交易回测系统 - 仅15分钟K线 & 反向K线即时平仓逻辑完整版
"""
import datetime
from dataclasses import dataclass
from typing import List, Dict, Optional
from loguru import logger
from models.weex import Weex1Hour # 替换为你的15分钟K线模型
# ========================= 工具函数 =========================
def is_bullish(c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(c): # 阴线
return float(c['close']) < float(c['open'])
def check_signal(prev, curr):
"""
包住形态信号判定:
- 前跌后涨包住 -> 做多
- 前涨后跌包住 -> 做空
"""
p_open, p_close = float(prev['open']), float(prev['close'])
c_open, c_close = float(curr['open']), float(curr['close'])
if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open:
return "long", "bear_bull_engulf"
if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open:
return "short", "bull_bear_engulf"
return None, None
def get_data_by_date(model, date_str: str):
"""按天获取指定表的数据15分钟K线"""
try:
target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
except ValueError:
logger.error("日期格式不正确,请使用 YYYY-MM-DD 格式。")
return []
start_ts = int(target_date.timestamp() * 1000)
end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1
query = model.select().where(model.id.between(start_ts, end_ts)).order_by(model.id.asc())
return [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query]
# ========================= 回测逻辑 =========================
def backtest_15m_trend_simplified(dates: List[str]):
all_data: List[Dict] = []
for d in dates:
all_data.extend(get_data_by_date(Weex1Hour, d))
if not all_data:
return [], {
'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'},
'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'},
}
all_data.sort(key=lambda x: x['id'])
stats = {
'bear_bull_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '涨包跌'},
'bull_bear_engulf': {'count': 0, 'wins': 0, 'total_profit': 0.0, 'name': '跌包涨'},
}
trades: List[Dict] = []
current_position: Optional[Dict] = None
idx = 1
while idx < len(all_data) - 1:
prev, curr, next_bar = all_data[idx - 1], all_data[idx], all_data[idx + 1]
direction, signal_key = check_signal(prev, curr)
# 空仓 -> 碰到信号则开仓
if current_position is None and direction:
entry_price = float(next_bar['open'])
current_position = {
'direction': direction,
'signal': stats[signal_key]['name'],
'signal_key': signal_key,
'entry_price': entry_price,
'entry_time': next_bar['id']
}
stats[signal_key]['count'] += 1
idx += 1
continue
if current_position:
pos_dir = current_position['direction']
pos_sig_key = current_position['signal_key']
# 反向信号 -> 平仓 + 反手
if direction and direction != pos_dir:
exit_price = float(next_bar['open'])
diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else (
current_position['entry_price'] - exit_price)
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(next_bar['id'] / 1000),
'signal': current_position['signal'],
'direction': '做多' if pos_dir == 'long' else '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[pos_sig_key]['total_profit'] += diff
if diff > 0:
stats[pos_sig_key]['wins'] += 1
# 反手开仓
current_position = {
'direction': direction,
'signal': stats[signal_key]['name'],
'signal_key': signal_key,
'entry_price': exit_price,
'entry_time': next_bar['id']
}
stats[signal_key]['count'] += 1
idx += 1
continue
# === 新逻辑遇到反向K线立即平仓 ===
if pos_dir == 'long' and is_bearish(curr):
exit_price = float(curr['close'])
diff = exit_price - current_position['entry_price']
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000),
'signal': current_position['signal'],
'direction': '做多',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[pos_sig_key]['total_profit'] += diff
if diff > 0:
stats[pos_sig_key]['wins'] += 1
current_position = None
idx += 1
continue
if pos_dir == 'short' and is_bullish(curr):
exit_price = float(curr['close'])
diff = current_position['entry_price'] - exit_price
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(curr['id'] / 1000),
'signal': current_position['signal'],
'direction': '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[pos_sig_key]['total_profit'] += diff
if diff > 0:
stats[pos_sig_key]['wins'] += 1
current_position = None
idx += 1
continue
idx += 1
# 尾仓平仓
if current_position:
last = all_data[-1]
exit_price = float(last['close'])
pos_dir = current_position['direction']
diff = (exit_price - current_position['entry_price']) if pos_dir == 'long' else (
current_position['entry_price'] - exit_price)
trades.append({
'entry_time': datetime.datetime.fromtimestamp(current_position['entry_time'] / 1000),
'exit_time': datetime.datetime.fromtimestamp(last['id'] / 1000),
'signal': current_position['signal'],
'direction': '做多' if pos_dir == 'long' else '做空',
'entry': current_position['entry_price'],
'exit': exit_price,
'diff': diff
})
stats[current_position['signal_key']]['total_profit'] += diff
if diff > 0:
stats[current_position['signal_key']]['wins'] += 1
return trades, stats
# ========================= 运行示例 =========================
if __name__ == '__main__':
# dates = [f"2025-06-{i}" for i in range(1, 31)]
dates = []
for i in range(1, 11):
for i1 in range(1, 31):
dates.append(f"2025-{f'0{i}' if len(str(i)) < 2 else i}-{f'0{i1}' if len(str(i1)) < 2 else i1}")
trades, stats = backtest_15m_trend_simplified(dates)
logger.info("===== 每笔交易详情 =====")
# === 参数设定 ===
contract_size = 10000 # 合约规模1手对应多少基础货币
open_fee_fixed = 5 # 固定开仓手续费
close_fee_rate = 0.0005 # 按成交额比例的平仓手续费率
total_points_profit = 0 # 累计点差
total_money_profit = 0 # 累计金额盈利
total_fee = 0 # 累计手续费
for t in trades:
entry = t['entry']
exit = t['exit']
direction = t['direction']
# === 1⃣ 原始价差(点差) ===
point_diff = (exit - entry) if direction == '做多' else (entry - exit)
# === 2⃣ 金额盈利(考虑合约规模) ===
money_profit = point_diff / entry * contract_size # 利润以基础货币计例如USD
# === 3⃣ 手续费计算 ===
fee = open_fee_fixed + (contract_size / entry * exit * close_fee_rate)
# === 4⃣ 净利润 ===
net_profit = money_profit - fee
# 保存计算结果
t.update({
'point_diff': point_diff,
'raw_profit': money_profit,
'fee': fee,
'net_profit': net_profit
})
total_points_profit += point_diff
total_money_profit += money_profit
total_fee += fee
logger.info(
f"{t['entry_time']} {direction}({t['signal']}) "
f"入={entry:.2f} 出={exit:.2f} 差价={point_diff:.2f} "
f"原始盈利={money_profit:.2f} 手续费={fee:.2f} 净利润={net_profit:.2f} {t['exit_time']}"
)
# === 汇总统计 ===
total_net_profit = total_money_profit - total_fee
print(f"\n一共交易笔数:{len(trades)}")
print(f"总点差:{total_points_profit:.2f}")
print(f"总原始盈利(未扣费):{total_money_profit:.2f}")
print(f"总手续费:{total_fee:.2f}")
print(f"总净利润:{total_net_profit:.2f}\n")
print("===== 信号统计 =====")
for k, v in stats.items():
name, count, wins, total_p = v['name'], v['count'], v['wins'], v['total_profit']
win_rate = (wins / count * 100) if count > 0 else 0.0
avg_p = (total_p / count) if count > 0 else 0.0
print(f"{name}: 次数={count} 胜率={win_rate:.2f}% 总价差={total_p:.2f} 平均价差={avg_p:.2f}")

View File

@@ -1,244 +0,0 @@
import datetime
import pandas as pd
from pathlib import Path
from loguru import logger
# ================= 辅助函数 =================
def is_bullish(candle):
"""判断是否是阳线(开盘价 < 收盘价,即涨)"""
return float(candle['open']) < float(candle['close'])
def is_bearish(candle):
"""判断是否是阴线(开盘价 > 收盘价,即跌)"""
return float(candle['open']) > float(candle['close'])
def check_signal(prev, curr):
"""
判断是否出现包住形态,返回信号类型和方向:
1. 前跌后涨包住 -> 做多信号 (bear_bull_engulf)
2. 前涨后跌包住 -> 做空信号 (bull_bear_engulf)
3. 前涨后涨包住 -> 做多信号 (bull_bull_engulf)
4. 前跌后跌包住 -> 做空信号 (bear_bear_engulf)
"""
p_open, p_close = float(prev['open']), float(prev['close']) # 前一笔
c_open, c_close = float(curr['open']), float(curr['close']) # 当前一笔
# 情况1前跌后涨且涨线包住前跌线 -> 做多信号
if is_bullish(curr) and is_bearish(prev):
if c_open <= p_close and c_close >= p_open:
return "long", "bear_bull_engulf"
# 情况2前涨后跌且跌线包住前涨线 -> 做空信号
if is_bearish(curr) and is_bullish(prev):
if c_open >= p_close and c_close <= p_open:
return "short", "bull_bear_engulf"
# # 情况3前涨后涨且后涨线包住前涨线 -> 做多信号
# if is_bullish(curr) and is_bullish(prev):
# if c_open < p_open and c_close > p_close:
# return "long", "bull_bull_engulf"
# # 情况4前跌后跌且后跌线包住前跌线 -> 做空信号
# if is_bearish(curr) and is_bearish(prev):
# if c_open > p_open and c_close < p_close:
# return "short", "bear_bear_engulf"
return None, None
def simulate_trade(direction, entry_price, future_candles, take_profit_diff=30, stop_loss_diff=-10):
"""
模拟交易逐根K线回测
改进版:考虑开盘跳空触发止盈/止损的情况
"""
for candle in future_candles:
open_p = float(candle['open'])
high = float(candle['high'])
low = float(candle['low'])
close = float(candle['close'])
if direction == "long":
tp_price = entry_price + take_profit_diff
sl_price = entry_price + stop_loss_diff
# 🧩 开盘就跳空止盈
if open_p >= tp_price:
return open_p, open_p - entry_price, candle['id']
# 🧩 开盘就跳空止损
if open_p <= sl_price:
return open_p, open_p - entry_price, candle['id']
# 正常区间内触发止盈/止损
if high >= tp_price:
return tp_price, take_profit_diff, candle['id']
if low <= sl_price:
return sl_price, stop_loss_diff, candle['id']
elif direction == "short":
tp_price = entry_price - take_profit_diff
sl_price = entry_price - stop_loss_diff
# 🧩 开盘就跳空止盈
if open_p <= tp_price:
return open_p, entry_price - open_p, candle['id']
# 🧩 开盘就跳空止损
if open_p >= sl_price:
return open_p, entry_price - open_p, candle['id']
# 正常区间内触发止盈/止损
if low <= tp_price:
return tp_price, take_profit_diff, candle['id']
if high >= sl_price:
return sl_price, stop_loss_diff, candle['id']
# 未触发止盈止损,按最后收盘价平仓
final_price = float(future_candles[-1]['close'])
if direction == "long":
diff_money = final_price - entry_price
else:
diff_money = entry_price - final_price
return final_price, diff_money, future_candles[-1]['id']
def fetch_kline(day: int, year: int = 2025, month: int = 9, file_path: str = "stock_data.xlsx") -> list[dict]:
"""
获取指定日期的分钟级 K 线数据。
参数:
day (int): 日
year (int): 年(默认 2025
month (int): 月(默认 9
file_path (str): Excel 文件路径
返回:
list[dict]: 当日的 K 线记录(按时间升序且去重)
"""
try:
# 验证文件路径
file = Path(file_path)
if not file.exists():
raise FileNotFoundError(f"未找到文件: {file.resolve()}")
# 计算起止时间戳
start_of_day = datetime.datetime(year, month, day)
end_of_day = start_of_day + pd.Timedelta(days=1) - pd.Timedelta(microseconds=1)
start_ts, end_ts = int(start_of_day.timestamp() * 1000), int(end_of_day.timestamp() * 1000)
# 读取 Excel
df = pd.read_excel(file)
# 校验列名
if 'id' not in df.columns:
raise KeyError("Excel 文件缺少必要列:'id'")
# 筛选并排序 + 去重
filtered_df = (
df.loc[df['id'].between(start_ts, end_ts)]
.sort_values('id')
.drop_duplicates(subset='id', keep='first')
)
# 转换为字典列表
return filtered_df.to_dict(orient='records')
except Exception as e:
print(f"❌ 错误: {e}")
return []
if __name__ == '__main__':
datas = []
for i in range(1, 31):
data = fetch_kline(year=2025, month=9, day=i)
datas.extend(data)
print(i)
print(len(datas))
datas = sorted(datas, key=lambda x: x["id"])
zh_project = 0 # 累计盈亏
all_trades = [] # 保存所有交易明细
# 四种信号类型的统计
signal_stats = {
"bear_bull_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "涨包跌"},
"bull_bear_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "跌包涨"},
# "bull_bull_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "涨包涨"},
# "bear_bear_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "跌包跌"}
}
daily_signals = 0 # 信号总数
daily_wins = 0
daily_profit = 0 # 价差总和
# 遍历每根K线寻找信号
for idx in range(1, len(datas) - 2): # 留出未来K线
prev, curr = datas[idx - 1], datas[idx] # 前一笔,当前一笔
entry_candle = datas[idx + 1] # 下一根开盘价作为入场价
future_candles = datas[idx + 2:] # 未来行情
entry_open = float(entry_candle['open']) # 开仓价格
direction, signal_type = check_signal(prev, curr) # 判断开仓方向和信号类型
if direction and signal_type:
daily_signals += 1
exit_price, diff, exit_time = simulate_trade(direction, entry_open, future_candles, take_profit_diff=30,
stop_loss_diff=-5)
# 统计该信号类型的表现
signal_stats[signal_type]["count"] += 1
signal_stats[signal_type]["total_profit"] += diff
if diff > 0:
signal_stats[signal_type]["wins"] += 1
daily_wins += 1
daily_profit += diff
# 将时间戳转换为本地时间
local_time = datetime.datetime.fromtimestamp(int(entry_candle['id']) / 1000)
formatted_time = local_time.strftime("%Y-%m-%d %H:%M:%S")
# 保存交易详情
all_trades.append(
(
f"{formatted_time}",
"做多" if direction == "long" else "做空",
signal_stats[signal_type]["name"],
entry_open,
exit_price,
diff,
exit_time
)
)
# ===== 输出每笔交易详情 =====
logger.info("===== 每笔交易详情 =====")
n = n1 = 0 # n = 总盈利n1 = 总手续费
for date, direction, signal_name, entry, exit, diff, end_time in all_trades:
profit_amount = diff / entry * 10000 # 计算盈利金额
close_fee = 10000 / entry * exit * 0.0005 # 平仓手续费
logger.info(
f"{date} {direction}({signal_name}) 入场={entry:.2f} 出场={exit:.2f} 出场时间={end_time} "
f"差价={diff:.2f} 盈利={profit_amount:.2f} "
f"开仓手续费=5u 平仓手续费={close_fee:.2f}"
)
n1 += 5 + close_fee
n += profit_amount
print(f'一共笔数:{len(all_trades)}')
print(f"一共盈利:{n:.2f}")
print(f'一共手续费:{n1:.2f}')

View File

@@ -1,90 +0,0 @@
"""
调试信号检测逻辑,查看为什么没有检测到交易信号
"""
import datetime
from models.weex import Weex30
def get_data_by_date(model, date_str: str):
"""按天获取指定表的数据"""
try:
target_date = datetime.datetime.strptime(date_str, '%Y-%m-%d')
except ValueError:
print(f"日期格式不正确: {date_str}")
return []
start_ts = int(target_date.timestamp() * 1000)
end_ts = int((target_date + datetime.timedelta(days=1)).timestamp() * 1000) - 1
query = model.select().where(model.id.between(start_ts, end_ts)).order_by(model.id.asc())
return [{'id': i.id, 'open': i.open, 'high': i.high, 'low': i.low, 'close': i.close} for i in query]
def is_bullish(c):
return float(c['close']) > float(c['open'])
def is_bearish(c):
return float(c['close']) < float(c['open'])
def check_signal(prev, curr):
"""包住形态信号判定"""
p_open, p_close = float(prev['open']), float(prev['close'])
c_open, c_close = float(curr['open']), float(curr['close'])
# 前跌后涨包住 -> 做多
if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open:
return "long", "bear_bull_engulf"
# 前涨后跌包住 -> 做空
if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open:
return "short", "bull_bear_engulf"
return None, None
# 获取数据
dates = []
for i in range(2, 32):
dates.append(f"2025-12-{i:02d}")
for i in range(1, 5):
dates.append(f"2026-01-{i:02d}")
all_data = []
for d in dates:
day_data = get_data_by_date(Weex30, d)
all_data.extend(day_data)
if day_data:
print(f"{d}: 读取到 {len(day_data)} 条数据")
print(f"\n总共读取到 {len(all_data)} 条数据")
if len(all_data) < 2:
print("数据不足无法检测信号至少需要2条K线")
exit()
# 排序
all_data.sort(key=lambda x: x['id'])
# 检查信号
signal_count = 0
for idx in range(1, len(all_data)):
prev = all_data[idx - 1]
curr = all_data[idx]
direction, signal_key = check_signal(prev, curr)
if direction:
signal_count += 1
prev_time = datetime.datetime.fromtimestamp(prev['id'] / 1000)
curr_time = datetime.datetime.fromtimestamp(curr['id'] / 1000)
print(f"\n信号 #{signal_count}: {signal_key} ({direction})")
print(f" 前一根K线 ({prev_time}): O={prev['open']:.2f} H={prev['high']:.2f} L={prev['low']:.2f} C={prev['close']:.2f} {'' if is_bullish(prev) else ''}")
print(f" 当前K线 ({curr_time}): O={curr['open']:.2f} H={curr['high']:.2f} L={curr['low']:.2f} C={curr['close']:.2f} {'' if is_bullish(curr) else ''}")
print(f" 包住条件检查:")
print(f" - 前跌后涨: {is_bearish(prev)} and {is_bullish(curr)}")
print(f" - 开盘<=前收盘: {float(curr['open'])} <= {float(prev['close'])} = {float(curr['open']) <= float(prev['close'])}")
print(f" - 收盘>=前开盘: {float(curr['close'])} >= {float(prev['open'])} = {float(curr['close']) >= float(prev['open'])}")
if signal_count == 0:
print("\n未检测到任何信号!")
print("\n检查前10根K线的情况")
for idx in range(min(10, len(all_data))):
k = all_data[idx]
k_time = datetime.datetime.fromtimestamp(k['id'] / 1000)
print(f" {idx}: {k_time} O={k['open']:.2f} C={k['close']:.2f} {'' if is_bullish(k) else ''}")

View File

@@ -1,410 +0,0 @@
import re
import json
import hmac
import time
import base64
import hashlib
import datetime
import requests
from tqdm import *
from loguru import *
from DrissionPage import *
from bs4 import BeautifulSoup
def is_bullish(c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(c): # 阴线
return float(c['close']) < float(c['open'])
class WeexTransaction:
def __init__(self, tge_id):
self.tge_port = None # tge浏览器使用端口
self.tge_id = tge_id # tge id
self.tge_url = "http://127.0.0.1:50326" # tge本地服务url
self.tge_headers = {
"Authorization": f"Bearer asp_174003986c9b0799677c5b2c1adb76e402735d753bc91a91",
"Content-Type": "application/json"
}
# 替换为你自己的钉钉机器人 Webhook 地址
self.webhook_url = "https://oapi.dingtalk.com/robot/send?access_token=e2fafb3f46866d50fe52cbb29650ba9ef1cbc97915dde238192f04c906fe4125"
# 替换为你自己的钉钉机器人秘钥
self.secret = "SEC5f320e72d7a4eaca540c66c3d09edff2f74936517390dee99ece6dd1b3611998"
self.page = None # 浏览器对象
self.start = 0 # 持仓状态 -1:做空0维持仓1做多
self.kline_1 = None # 01
self.kline_2 = None # 01
self.direction = None # 信号类型
self.pbar = None # 进度条对象
def get_signature(self, timestamp):
# 将时间戳和密钥拼接
string_to_sign = f'{timestamp}\n{self.secret}'
string_to_sign = string_to_sign.encode('utf-8')
# 使用 HMAC-SHA256 算法进行签名
hmac_code = hmac.new(self.secret.encode('utf-8'), string_to_sign, digestmod=hashlib.sha256).digest()
# 对签名结果进行 Base64 编码
sign = base64.b64encode(hmac_code).decode('utf-8')
return sign
# def send_dingtalk_message(self, message_content):
# # 获取当前时间戳(毫秒)
# timestamp = str(round(time.time() * 1000))
# # 生成签名
# sign = self.get_signature(timestamp, )
# # 拼接带有签名信息的完整 Webhook URL
# full_url = f"{self.webhook_url}&timestamp={timestamp}&sign={sign}"
#
# # 定义消息内容
# message = {
# "msgtype": "text",
# "text": {
# "content": message_content
# }
# }
#
# # 设置请求头
# headers = {
# "Content-Type": "application/json"
# }
#
# try:
# # 发送 POST 请求
# response = requests.post(full_url, headers=headers, data=json.dumps(message))
#
# except requests.RequestException as e:
# print(f"请求发生错误: {e}")
def send_dingtalk_message(self, message_content):
pass
# url = "http://8.137.99.82:9005/api/send_click?token=fegergauiernguie&phone=8613661496481"
#
# res = requests.post(
# url=url,
# json={
# "phone": "8613661496481",
# "bot_name": "ergggreef",
# "datas": [
# {"send_message": [message_content], "click_button": [""], },
# ]
#
# }
# )
#
# print(res.json())
def openBrowser(self, ): # 直接指定ID打开窗口也可以使用 createBrowser 方法返回的ID
try:
response = requests.post(
f"{self.tge_url}/api/browser/start",
json={"envId": self.tge_id},
headers=self.tge_headers
)
self.tge_port = response.json()["data"]["port"]
return True
except:
return False
def take_over_browser(self):
try:
co = ChromiumOptions()
co.set_local_port(self.tge_port)
self.page = ChromiumPage(addr_or_opts=co)
self.page.set.window.max()
return True
except:
return False
def is_bullish(self, c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(self, c): # 阴线
return float(c['close']) < float(c['open'])
def check_signal(self, prev, curr):
"""
包住形态信号判定仅15分钟K线
- 前跌后涨包住 -> 做多
- 前涨后跌包住 -> 做空
"""
p_open, p_close = float(prev['open']), float(prev['close'])
c_open, c_close = float(curr['open']), float(curr['close'])
# 前跌后涨包住 -> 做多
if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open:
return "long", "bear_bull_engulf"
# 前涨后跌包住 -> 做空
if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open:
return "short", "bull_bear_engulf"
return None, None
def get_price(self):
for i in range(3):
try:
logger.info(f"获取最新数据:{i + 1}次。。。")
self.mn_tab.get(url="https://www.weeaxs.site/zh-CN/futures/demo-trading/ETH-SUSDT")
res = self.mn_tab.listen.wait(timeout=15) # 等待并获取一个数据包
datas = []
if res:
for data in res.response.body['data']["dataList"]:
insert_data = {
'id': int(data[4]),
'open': float(data[3]),
'high': float(data[1]),
'low': float(data[2]),
'close': float(data[0])
}
datas.append(insert_data)
return datas
except:
pass
return False
def remove_tags_and_spaces(self,html):
# 创建 BeautifulSoup 对象
soup = BeautifulSoup(html, 'html.parser')
# 获取去除标签后的文本
text = soup.get_text()
# 去除所有空格
text = text.replace(" ", "")
return text
def to_do_page(self):
# self.page.get("https://www.weeaxs.site/zh-CN/futures/demo-trading/ETH-SUSDT")
self.mn_tab.ele('x://*[contains(text(), "市价")]', timeout=15).click()
time.sleep(1)
html_text = self.remove_tags_and_spaces(html=self.mn_tab.html)
# 定义正则表达式模式,用于匹配包含逗号和小数点的数值
pattern = r'委托可用([\d,]+\.\d+)SUSDT'
# 使用 re.search 方法查找匹配项
match = re.search(pattern, html_text)
number = ""
if match:
# 提取匹配到的数值字符串
number_str = match.group(1).replace(',', '')
# 将提取的字符串转换为浮点数
number = float(number_str)
if not number:
return
self.mn_tab.ele('x://input[@placeholder="请输入数量"]').input(number/10)
time.sleep(1)
if self.direction == "long" and not self.start:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开多")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开多")
self.mn_tab.ele('x://*[contains(text(), "买入开多")]').click()
self.start = 1
elif self.direction == "short" and not self.start:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开空")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开空")
self.mn_tab.ele('x://*[contains(text(), "卖出开空")]').click()
self.start = -1
elif self.direction == "long" and self.start == -1:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平空做多")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平空做多")
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').scroll.to_see(center=True)
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').click()
time.sleep(3)
self.mn_tab.ele('x://*[contains(text(), "买入开多")]').click()
self.start = 1
elif self.direction == "short" and self.start == 1:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平多做空")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平多做空")
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').scroll.to_see(center=True)
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').click()
time.sleep(3)
self.mn_tab.ele('x://*[contains(text(), "卖出开空")]').click()
self.start = -1
def get_text(self, target_text):
# 去除目标文本中的空白字符
cleaned_target_text = re.sub(r'\s', '', target_text)
# 创建 BeautifulSoup 对象
soup = BeautifulSoup(self.mn_tab.html, 'html.parser')
# 遍历所有标签的文本内容
for tag in soup.find_all():
tag_text = tag.get_text()
# 去除标签文本中的空白字符
cleaned_tag_text = re.sub(r'\s', '', tag_text)
if cleaned_target_text in cleaned_tag_text:
return True
else:
return False
def get_now_time(self):
# 获取当前时间戳
current_timestamp = time.time()
# 将当前时间戳转换为 datetime 对象
current_datetime = datetime.datetime.fromtimestamp(current_timestamp)
# 计算距离当前时间最近的整点或 30 分时刻
if current_datetime.minute < 30:
target_datetime = current_datetime.replace(minute=0, second=0, microsecond=0)
else:
target_datetime = current_datetime.replace(minute=30, second=0, microsecond=0)
# 将目标 datetime 对象转换为时间戳
target_timestamp = target_datetime.timestamp()
return int(target_timestamp) * 1000
def close_extra_tabs_in_browser(self):
try:
for _, i in enumerate(self.page.get_tabs()):
if _ == 0:
continue
i.close()
return True
except:
pass
return False
def action(self):
# 获取比特端口
if self.openBrowser():
logger.info("获取打开比特成功,成功获取端口!!!")
else:
logger.error("打开比特失败!!!")
return
# 接管浏览器
if self.take_over_browser():
logger.info("接管比特浏览器成功!!!")
else:
logger.error("接管浏览器失败!!!")
return
if self.close_extra_tabs_in_browser():
logger.info('关闭多余标签页成功!!!')
else:
logger.info('关闭多余标签页失败!!!')
self.mn_tab = self.page.new_tab()
self.mn_tab.listen.start("public/quote/v1/getKlineV2")
logger.success("浏览器开启抓包模式。。。")
self.mn_tab.get(url="https://www.weeaxs.site/zh-CN/futures/demo-trading/ETH-SUSDT") # 打开网页
self.pbar = tqdm(total=30, desc="等待时间中", ncols=80) # desc进度条说明ncols长度
while True:
# 获取当前时间
current_time = time.localtime()
current_minute = current_time.tm_min
if current_minute < 30:
self.pbar.n = current_minute
self.pbar.refresh()
else:
self.pbar.n = current_minute - 30
self.pbar.refresh()
if current_minute not in [0, 1, 2, 3, 4, 5, 30, 31, 32, 33, 34, 58]: # 判断是否是 新的30分钟了
time.sleep(10)
continue
new_price_datas = self.get_price()
if new_price_datas:
logger.success("获取最新交易价格成功!!!")
else:
logger.info("获取最新价格有问题!!!")
continue
new_price_datas1 = sorted(new_price_datas, key=lambda x: x["id"])
self.kline_1, self.kline_2, self.kline_3 = new_price_datas1[-3:]
# 判断抓取的数据是否正确
if self.get_now_time() != self.kline_3["id"]:
continue
time.sleep(15)
if self.get_text(target_text="仓位(1)"):
if self.get_text(target_text="ETH/SUSDT多"):
self.start = 1
elif self.get_text(target_text="ETH/SUSDT空"):
self.start = -1
else:
self.start = 0
if self.start == 1:
if is_bearish(self.kline_1) and is_bearish(self.kline_2):
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平多")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平多")
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').scroll.to_see(center=True)
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').click()
self.start = 0
elif self.start == -1:
if is_bullish(self.kline_1) and is_bullish(self.kline_2):
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平空")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平空")
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').scroll.to_see(center=True)
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').click()
self.start = 0
self.direction, signal_key = self.check_signal(prev=self.kline_1, curr=self.kline_2) # 判断信号
if self.direction:
try:
self.to_do_page()
except Exception as e:
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()}{e}")
self.pbar.reset() # 重置进度条
self.send_dingtalk_message(
message_content=
f"{datetime.datetime.now()}"
f"目前有持仓:{"" if self.start == 0 else ("" if self.start == 1 else "")}"
f"当前信号:{"" if not self.direction else ("" if self.direction == "long" else "")}"
)
if __name__ == '__main__':
WeexTransaction(
tge_id=146473,
).action()
# //*[contains(text(), '特定文本')]

View File

@@ -1,408 +0,0 @@
import re
import json
import hmac
import time
import base64
import hashlib
import datetime
import requests
from tqdm import *
from loguru import *
from DrissionPage import *
from bs4 import BeautifulSoup
def is_bullish(c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(c): # 阴线
return float(c['close']) < float(c['open'])
class WeexTransaction:
def __init__(self, tge_id):
self.tge_port = None # tge浏览器使用端口
self.tge_id = tge_id # tge id
self.tge_url = "http://127.0.0.1:50326" # tge本地服务url
self.tge_headers = {
"Authorization": f"Bearer asp_174003986c9b0799677c5b2c1adb76e402735d753bc91a91",
"Content-Type": "application/json"
}
# 替换为你自己的钉钉机器人 Webhook 地址
self.webhook_url = "https://oapi.dingtalk.com/robot/send?access_token=e2fafb3f46866d50fe52cbb29650ba9ef1cbc97915dde238192f04c906fe4125"
# 替换为你自己的钉钉机器人秘钥
self.secret = "SEC5f320e72d7a4eaca540c66c3d09edff2f74936517390dee99ece6dd1b3611998"
self.page = None # 浏览器对象
self.start = 0 # 持仓状态 -1:做空0维持仓1做多
self.kline_1 = None # 01
self.kline_2 = None # 01
self.direction = None # 信号类型
self.pbar = None # 进度条对象
def get_signature(self, timestamp):
# 将时间戳和密钥拼接
string_to_sign = f'{timestamp}\n{self.secret}'
string_to_sign = string_to_sign.encode('utf-8')
# 使用 HMAC-SHA256 算法进行签名
hmac_code = hmac.new(self.secret.encode('utf-8'), string_to_sign, digestmod=hashlib.sha256).digest()
# 对签名结果进行 Base64 编码
sign = base64.b64encode(hmac_code).decode('utf-8')
return sign
# def send_dingtalk_message(self, message_content):
# # 获取当前时间戳(毫秒)
# timestamp = str(round(time.time() * 1000))
# # 生成签名
# sign = self.get_signature(timestamp, )
# # 拼接带有签名信息的完整 Webhook URL
# full_url = f"{self.webhook_url}&timestamp={timestamp}&sign={sign}"
#
# # 定义消息内容
# message = {
# "msgtype": "text",
# "text": {
# "content": message_content
# }
# }
#
# # 设置请求头
# headers = {
# "Content-Type": "application/json"
# }
#
# try:
# # 发送 POST 请求
# response = requests.post(full_url, headers=headers, data=json.dumps(message))
#
# except requests.RequestException as e:
# print(f"请求发生错误: {e}")
def send_dingtalk_message(self, message_content):
pass
# url = "http://8.137.99.82:9005/api/send_click?token=fegergauiernguie&phone=8613661496481"
#
# res = requests.post(
# url=url,
# json={
# "phone": "8613661496481",
# "bot_name": "ergggreef",
# "datas": [
# {"send_message": [message_content], "click_button": [""], },
# ]
#
# }
# )
#
# print(res.json())
def openBrowser(self, ): # 直接指定ID打开窗口也可以使用 createBrowser 方法返回的ID
try:
response = requests.post(
f"{self.tge_url}/api/browser/start",
json={"envId": self.tge_id},
headers=self.tge_headers
)
self.tge_port = response.json()["data"]["port"]
return True
except:
return False
def take_over_browser(self):
try:
co = ChromiumOptions()
co.set_local_port(self.tge_port)
self.page = ChromiumPage(addr_or_opts=co)
self.page.set.window.max()
return True
except:
return False
def is_bullish(self, c): # 阳线
return float(c['close']) > float(c['open'])
def is_bearish(self, c): # 阴线
return float(c['close']) < float(c['open'])
def check_signal(self, prev, curr):
"""
包住形态信号判定仅15分钟K线
- 前跌后涨包住 -> 做多
- 前涨后跌包住 -> 做空
"""
p_open, p_close = float(prev['open']), float(prev['close'])
c_open, c_close = float(curr['open']), float(curr['close'])
# 前跌后涨包住 -> 做多
if is_bullish(curr) and is_bearish(prev) and c_open <= p_close and c_close >= p_open:
return "long", "bear_bull_engulf"
# 前涨后跌包住 -> 做空
if is_bearish(curr) and is_bullish(prev) and c_open >= p_close and c_close <= p_open:
return "short", "bull_bear_engulf"
return None, None
def get_price(self):
for i in range(3):
try:
logger.info(f"获取最新数据:{i + 1}次。。。")
self.mn_tab.get(url="https://www.weeaxs.site/zh-CN/futures/ETH-USDT")
res = self.mn_tab.listen.wait(timeout=15) # 等待并获取一个数据包
datas = []
if res:
for data in res.response.body['data']["dataList"]:
insert_data = {
'id': int(data[4]),
'open': float(data[3]),
'high': float(data[1]),
'low': float(data[2]),
'close': float(data[0])
}
datas.append(insert_data)
return datas
except:
pass
return False
def remove_tags_and_spaces(self, html):
# 创建 BeautifulSoup 对象
soup = BeautifulSoup(html, 'html.parser')
# 获取去除标签后的文本
text = soup.get_text()
# 去除所有空格
text = text.replace(" ", "")
return text
def to_do_page(self):
# self.page.get("https://www.weeaxs.site/zh-CN/futures/ETH-USDT")
self.mn_tab.ele('x://*[contains(text(), "市价")]', timeout=15).click()
time.sleep(1)
html_text = self.remove_tags_and_spaces(html=self.mn_tab.html)
# 使用 re.search 方法查找匹配项
# match = re.search(r'委托可用\s*([0-9]+(?:\.[0-9]+)?)SUSDT', html_text)
match = re.search(r"可用\s*([0-9,]+(?:\.[0-9]+)?)", html_text)
number = ""
if match:
# 提取匹配到的数值字符串
number_str = match.group(1).replace(',', '')
# 将提取的字符串转换为浮点数
number = float(number_str)
if not number:
return
self.mn_tab.ele('x://input[@placeholder="请输入数量"]').input(number / 100)
time.sleep(1)
if self.direction == "long" and not self.start:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开多")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开多")
self.mn_tab.ele('x://*[contains(text(), "买入开多")]').click()
self.start = 1
elif self.direction == "short" and not self.start:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开空")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},开空")
self.mn_tab.ele('x://*[contains(text(), "卖出开空")]').click()
self.start = -1
elif self.direction == "long" and self.start == -1:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平空做多")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平空做多")
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').scroll.to_see(center=True)
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').click()
time.sleep(3)
self.mn_tab.ele('x://*[contains(text(), "买入开多")]').click()
self.start = 1
elif self.direction == "short" and self.start == 1:
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平多做空")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},反手平多做空")
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').scroll.to_see(center=True)
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').click()
time.sleep(3)
self.mn_tab.ele('x://*[contains(text(), "卖出开空")]').click()
self.start = -1
def get_text(self, target_text):
# 去除目标文本中的空白字符
cleaned_target_text = re.sub(r'\s', '', target_text)
# 创建 BeautifulSoup 对象
soup = BeautifulSoup(self.mn_tab.html, 'html.parser')
# 遍历所有标签的文本内容
for tag in soup.find_all():
tag_text = tag.get_text()
# 去除标签文本中的空白字符
cleaned_tag_text = re.sub(r'\s', '', tag_text)
if cleaned_target_text in cleaned_tag_text:
return True
else:
return False
def get_now_time(self):
# 获取当前时间戳
current_timestamp = time.time()
# 将当前时间戳转换为 datetime 对象
current_datetime = datetime.datetime.fromtimestamp(current_timestamp)
# 计算距离当前时间最近的整点或 30 分时刻
if current_datetime.minute < 30:
target_datetime = current_datetime.replace(minute=0, second=0, microsecond=0)
else:
target_datetime = current_datetime.replace(minute=30, second=0, microsecond=0)
# 将目标 datetime 对象转换为时间戳
target_timestamp = target_datetime.timestamp()
return int(target_timestamp) * 1000
def close_extra_tabs_in_browser(self):
try:
for _, i in enumerate(self.page.get_tabs()):
if _ == 0:
continue
i.close()
return True
except:
pass
return False
def action(self):
# 获取比特端口
if self.openBrowser():
logger.info("获取打开比特成功,成功获取端口!!!")
else:
logger.error("打开比特失败!!!")
return
# 接管浏览器
if self.take_over_browser():
logger.info("接管比特浏览器成功!!!")
else:
logger.error("接管浏览器失败!!!")
return
if self.close_extra_tabs_in_browser():
logger.info('关闭多余标签页成功!!!')
else:
logger.info('关闭多余标签页失败!!!')
self.mn_tab = self.page.new_tab()
self.mn_tab.listen.start("public/quote/v1/getKlineV2")
logger.success("浏览器开启抓包模式。。。")
self.mn_tab.get(url="https://www.weeaxs.site/zh-CN/futures/ETH-USDT") # 打开网页
self.pbar = tqdm(total=30, desc="等待时间中", ncols=80) # desc进度条说明ncols长度
while True:
# 获取当前时间
current_time = time.localtime()
current_minute = current_time.tm_min
if current_minute < 30:
self.pbar.n = current_minute
self.pbar.refresh()
else:
self.pbar.n = current_minute - 30
self.pbar.refresh()
# if current_minute not in range(60): # 判断是否是 新的30分钟了
if current_minute not in [0, 1, 2, 3, 4, 5, 30, 31, 32, 33, 34, 58]: # 判断是否是 新的30分钟了
time.sleep(10)
continue
new_price_datas = self.get_price()
if new_price_datas:
logger.success("获取最新交易价格成功!!!")
else:
logger.info("获取最新价格有问题!!!")
continue
new_price_datas1 = sorted(new_price_datas, key=lambda x: x["id"])
self.kline_1, self.kline_2, self.kline_3 = new_price_datas1[-3:]
# 判断抓取的数据是否正确
if self.get_now_time() != self.kline_3["id"]:
continue
time.sleep(15)
if self.get_text(target_text="ETH/USDT多"):
self.start = 1
elif self.get_text(target_text="ETH/USDT空"):
self.start = -1
else:
self.start = 0
if self.start == 1:
if is_bearish(self.kline_1) and is_bearish(self.kline_2):
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平多")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平多")
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').scroll.to_see(center=True)
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').click()
self.start = 0
elif self.start == -1:
if is_bullish(self.kline_1) and is_bullish(self.kline_2):
logger.success(f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平空")
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()},第一根信号:{self.kline_1}{self.kline_2},平空")
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').scroll.to_see(center=True)
self.mn_tab.ele('x://*[contains(text(), "闪电平仓")]').click()
self.start = 0
self.direction, signal_key = self.check_signal(prev=self.kline_1, curr=self.kline_2) # 判断信号
if self.direction:
try:
self.to_do_page()
except Exception as e:
self.send_dingtalk_message(
message_content=f"{datetime.datetime.now()}{e}")
self.pbar.reset() # 重置进度条
self.send_dingtalk_message(
message_content=
f"{datetime.datetime.now()}"
f"目前有持仓:{"" if self.start == 0 else ("" if self.start == 1 else "")}"
f"当前信号:{"" if not self.direction else ("" if self.direction == "long" else "")}"
)
if __name__ == '__main__':
WeexTransaction(
tge_id=146473,
).action()
# //*[contains(text(), '特定文本')]

View File

@@ -1,15 +0,0 @@
import requests
url = "http://8.137.99.82:9005/api/send_click?token=fegergauiernguie&phone=8613661496481"
res = requests.post(
url=url,
json={
"phone": "8613661496481",
"bot_name": "ergggreef",
"datas": [
{"send_message": ["grgegg"], "click_button": [""], },
]
}
)

424
三分之一策略交易.py Normal file
View File

@@ -0,0 +1,424 @@
import time
from tqdm import tqdm
from loguru import logger
from bit_tools import openBrowser
from DrissionPage import ChromiumPage
from DrissionPage import ChromiumOptions
from bitmart.api_contract import APIContract
class BitmartFuturesTransaction:
def __init__(self, bit_id):
self.page: ChromiumPage | None = None
self.api_key = "a0fb7b98464fd9bcce67e7c519d58ec10d0c38a8"
self.secret_key = "4eaeba78e77aeaab1c2027f846a276d164f264a44c2c1bb1c5f3be50c8de1ca5"
self.memo = "合约交易"
self.contract_symbol = "ETHUSDT"
self.contractAPI = APIContract(self.api_key, self.secret_key, self.memo, timeout=(5, 15))
self.start = 0 # 持仓状态: -1 空, 0 无, 1 多
self.direction = None
self.pbar = tqdm(total=30, desc="等待K线", ncols=80)
self.last_kline_time = None # 上一次处理的K线时间戳用于判断是否是新K线
self.leverage = "100" # 高杠杆(全仓模式下可开更大仓位)
self.open_type = "cross" # 全仓模式
self.risk_percent = 0.01 # 每次开仓使用可用余额的 1%
self.open_avg_price = None # 开仓价格
self.current_amount = None # 持仓量
self.bit_id = bit_id
# 策略相关变量
self.prev_kline = None # 上一根K线
self.current_kline = None # 当前K线
self.prev_entity = None # 上一根K线实体大小
self.current_open = None # 当前K线开盘价
def get_klines(self):
"""获取最近2根K线当前K线和上一根K线"""
try:
end_time = int(time.time())
# 获取足够多的条目确保有最新的K线
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=5, # 30分钟
start_time=end_time - 3600 * 3, # 取最近3小时
end_time=end_time
)[0]["data"]
# 每根: [timestamp, open, high, low, close, volume]
formatted = []
for k in response:
formatted.append({
'id': int(k["timestamp"]),
'open': float(k["open_price"]),
'high': float(k["high_price"]),
'low': float(k["low_price"]),
'close': float(k["close_price"])
})
formatted.sort(key=lambda x: x['id'])
# 返回最近2根K线倒数第二根上一根和最后一根当前
if len(formatted) >= 2:
return formatted[-2], formatted[-1]
return None, None
except Exception as e:
logger.error(f"获取K线异常: {e}")
self.ding(text="获取K线异常", error=True)
return None, None
def get_current_price(self):
"""获取当前最新价格"""
try:
end_time = int(time.time())
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=1, # 1分钟
start_time=end_time - 3600 * 1, # 取最近1小时
end_time=end_time
)[0]
if response['code'] == 1000:
return float(response['data'][-1]["close_price"])
return None
except Exception as e:
logger.error(f"获取价格异常: {e}")
return None
def get_available_balance(self):
"""获取合约账户可用USDT余额"""
try:
response = self.contractAPI.get_assets_detail()[0]
if response['code'] == 1000:
data = response['data']
if isinstance(data, dict):
return float(data.get('available_balance', 0))
elif isinstance(data, list):
for asset in data:
if asset.get('currency') == 'USDT':
return float(asset.get('available_balance', 0))
return None
except Exception as e:
logger.error(f"余额查询异常: {e}")
return None
def get_position_status(self):
"""获取当前持仓方向"""
try:
response = self.contractAPI.get_position(contract_symbol=self.contract_symbol)[0]
if response['code'] == 1000:
positions = response['data']
if not positions:
self.start = 0
return True
self.start = 1 if positions[0]['position_type'] == 1 else -1
self.open_avg_price = float(positions[0]['open_avg_price'])
self.current_amount = positions[0]['current_amount']
self.position_cross = positions[0]["position_cross"]
return True
else:
return False
except Exception as e:
logger.error(f"持仓查询异常: {e}")
return False
def set_leverage(self):
"""程序启动时设置全仓 + 高杠杆"""
try:
response = self.contractAPI.post_submit_leverage(
contract_symbol=self.contract_symbol,
leverage=self.leverage,
open_type=self.open_type
)[0]
if response['code'] == 1000:
logger.success(f"全仓模式 + {self.leverage}x 杠杆设置成功")
return True
else:
logger.error(f"杠杆设置失败: {response}")
return False
except Exception as e:
logger.error(f"设置杠杆异常: {e}")
return False
def openBrowser(self):
"""打开 TGE 对应浏览器实例"""
try:
bit_port = openBrowser(id=self.bit_id)
co = ChromiumOptions()
co.set_local_port(port=bit_port)
self.page = ChromiumPage(addr_or_opts=co)
return True
except:
return False
def click_safe(self, xpath, sleep=0.5):
"""安全点击"""
try:
ele = self.page.ele(xpath)
if not ele:
return False
ele.scroll.to_see(center=True)
time.sleep(sleep)
ele.click()
return True
except:
return False
def 平仓(self):
"""平仓操作"""
self.click_safe('x://span[normalize-space(text()) ="市价"]')
def 开单(self, marketPriceLongOrder=0, limitPriceShortOrder=0, size=None, price=None):
"""
marketPriceLongOrder 市价做多或者做空1是做多-1是做空
limitPriceShortOrder 限价做多或者做空
"""
if marketPriceLongOrder == -1:
self.click_safe('x://button[normalize-space(text()) ="市价"]')
self.page.ele('x://*[@id="size_0"]').input(size)
self.click_safe('x://span[normalize-space(text()) ="卖出/做空"]')
elif marketPriceLongOrder == 1:
self.click_safe('x://button[normalize-space(text()) ="市价"]')
self.page.ele('x://*[@id="size_0"]').input(size)
self.click_safe('x://span[normalize-space(text()) ="买入/做多"]')
if limitPriceShortOrder == -1:
self.click_safe('x://button[normalize-space(text()) ="限价"]')
self.page.ele('x://*[@id="price_0"]').input(vals=price, clear=True)
time.sleep(1)
self.page.ele('x://*[@id="size_0"]').input(1)
self.click_safe('x://span[normalize-space(text()) ="卖出/做空"]')
elif limitPriceShortOrder == 1:
self.click_safe('x://button[normalize-space(text()) ="限价"]')
self.page.ele('x://*[@id="price_0"]').input(vals=price, clear=True)
time.sleep(1)
self.page.ele('x://*[@id="size_0"]').input(1)
self.click_safe('x://span[normalize-space(text()) ="买入/做多"]')
def ding(self, text, error=False):
"""日志通知"""
if error:
logger.error(text)
else:
logger.info(text)
def calculate_entity(self, kline):
"""计算K线实体大小绝对值"""
return abs(kline['close'] - kline['open'])
def calculate_upper_shadow(self, kline):
"""计算上阴线(上影线)涨幅百分比"""
# 上阴线 = (最高价 - max(开盘价, 收盘价)) / max(开盘价, 收盘价)
body_top = max(kline['open'], kline['close'])
if body_top == 0:
return 0
return (kline['high'] - body_top) / body_top * 100
def calculate_lower_shadow(self, kline):
"""计算下阴线(下影线)跌幅百分比"""
# 下阴线 = (min(开盘价, 收盘价) - 最低价) / min(开盘价, 收盘价)
body_bottom = min(kline['open'], kline['close'])
if body_bottom == 0:
return 0
return (body_bottom - kline['low']) / body_bottom * 100
def get_entity_edge(self, kline):
"""获取K线实体边收盘价或开盘价取决于是阳线还是阴线"""
# 阳线(收盘>开盘):实体上边=收盘价,实体下边=开盘价
# 阴线(收盘<开盘):实体上边=开盘价,实体下边=收盘价
return {
'upper': max(kline['open'], kline['close']), # 实体上边
'lower': min(kline['open'], kline['close']) # 实体下边
}
def check_signal(self, current_price, prev_kline, current_kline):
"""
检查交易信号
返回: ('long', trigger_price) / ('short', trigger_price) / None
"""
# 计算上一根K线实体
prev_entity = self.calculate_entity(prev_kline)
# 实体过小不交易(实体 < 0.1
if prev_entity < 0.1:
logger.info(f"上一根K线实体过小: {prev_entity:.4f},跳过信号检测")
return None
# 获取上一根K线的实体上下边
prev_entity_edge = self.get_entity_edge(prev_kline)
prev_entity_upper = prev_entity_edge['upper'] # 实体上边
prev_entity_lower = prev_entity_edge['lower'] # 实体下边
# 计算触发价基于上一根K线实体位置
long_trigger = prev_entity_lower + prev_entity / 3 # 做多触发价 = 实体下边 + 实体/3下三分之一处
short_trigger = prev_entity_upper - prev_entity / 3 # 做空触发价 = 实体上边 - 实体/3上三分之一处
logger.info(f"当前价格: {current_price:.2f}, 上一根实体: {prev_entity:.4f}")
logger.info(f"上一根实体上边: {prev_entity_upper:.2f}, 下边: {prev_entity_lower:.2f}")
logger.info(f"做多触发价(下1/3): {long_trigger:.2f}, 做空触发价(上1/3): {short_trigger:.2f}")
# 无持仓时检查开仓信号
if self.start == 0:
if current_price >= long_trigger:
logger.info(f"触发做多信号!价格 {current_price:.2f} >= 触发价(下1/3) {long_trigger:.2f}")
return ('long', long_trigger)
elif current_price <= short_trigger:
logger.info(f"触发做空信号!价格 {current_price:.2f} <= 触发价(上1/3) {short_trigger:.2f}")
return ('short', short_trigger)
# 持仓时检查反手信号
elif self.start == 1: # 持多仓
# 反手条件1: 价格跌到上一根K线的上三分之一处做空触发价
if current_price <= short_trigger:
logger.info(f"持多反手做空!价格 {current_price:.2f} <= 触发价(上1/3) {short_trigger:.2f}")
return ('reverse_short', short_trigger)
# 反手条件2: 上一根K线上阴线涨幅>0.01%,当前跌到上一根实体下边
upper_shadow_pct = self.calculate_upper_shadow(prev_kline)
if upper_shadow_pct > 0.01 and current_price <= prev_entity_lower:
logger.info(f"持多反手做空!上阴线涨幅 {upper_shadow_pct:.4f}% > 0.01%"
f"价格 {current_price:.2f} <= 实体下边 {prev_entity_lower:.2f}")
return ('reverse_short', prev_entity_lower)
elif self.start == -1: # 持空仓
# 反手条件1: 价格涨到上一根K线的下三分之一处做多触发价
if current_price >= long_trigger:
logger.info(f"持空反手做多!价格 {current_price:.2f} >= 触发价(下1/3) {long_trigger:.2f}")
return ('reverse_long', long_trigger)
# 反手条件2: 上一根K线下阴线跌幅>0.01%,当前涨到上一根实体上边
lower_shadow_pct = self.calculate_lower_shadow(prev_kline)
if lower_shadow_pct > 0.01 and current_price >= prev_entity_upper:
logger.info(f"持空反手做多!下阴线跌幅 {lower_shadow_pct:.4f}% > 0.01%"
f"价格 {current_price:.2f} >= 实体上边 {prev_entity_upper:.2f}")
return ('reverse_long', prev_entity_upper)
return None
def execute_trade(self, signal, size=1):
"""执行交易"""
signal_type, trigger_price = signal
size= 25
if signal_type == 'long':
# 开多
logger.info(f"执行开多,触发价: {trigger_price:.2f}")
self.开单(marketPriceLongOrder=1, size=size)
self.start = 1
elif signal_type == 'short':
# 开空
logger.info(f"执行开空,触发价: {trigger_price:.2f}")
self.开单(marketPriceLongOrder=-1, size=size)
self.start = -1
elif signal_type == 'reverse_long':
# 平空 + 开多(反手做多)
logger.info(f"执行反手做多,触发价: {trigger_price:.2f}")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=1, size=size)
self.start = 1
elif signal_type == 'reverse_short':
# 平多 + 开空(反手做空)
logger.info(f"执行反手做空,触发价: {trigger_price:.2f}")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=-1, size=size)
self.start = -1
def action(self):
"""主循环"""
# 启动时设置全仓高杠杆
if not self.set_leverage():
logger.error("杠杆设置失败,程序继续运行但可能下单失败")
return
# 打开浏览器
if not self.openBrowser():
self.ding("打开浏览器失败!", error=True)
return
logger.info("浏览器打开成功")
# 进入交易页面
self.page.get("https://derivatives.bitmart.com/zh-CN/futures/ETHUSDT")
time.sleep(3)
logger.info("开始运行三分之一策略交易...")
# 标记是否刚执行过交易(用于跳过从交易所获取持仓状态,避免延迟问题)
just_traded = False
while True:
try:
# 1. 获取K线数据当前K线和上一根K线
prev_kline, current_kline = self.get_klines()
if not prev_kline or not current_kline:
logger.warning("获取K线失败等待重试...")
time.sleep(5)
continue
# 2. 获取当前价格
current_price = self.get_current_price()
if not current_price:
logger.warning("获取价格失败,等待重试...")
time.sleep(2)
continue
# 3. 获取持仓状态如果刚交易过信任本地状态跳过API查询避免延迟
if not just_traded:
if not self.get_position_status():
logger.warning("获取持仓状态失败,等待重试...")
time.sleep(2)
continue
else:
logger.info(f"刚执行交易,信任本地持仓状态: {self.start}")
just_traded = False # 重置标记
# 4. 检查信号
signal = self.check_signal(current_price, prev_kline, current_kline)
# 5. 有信号则执行交易
if signal:
self.execute_trade(signal, size=1)
logger.success(f"交易执行完成: {signal[0]}, 当前持仓状态: {self.start}")
just_traded = True # 标记刚执行过交易
# 交易后立即再次检查是否有反手信号同一根K线内可能多次反手
time.sleep(1) # 短暂等待
# 重新获取价格,检查是否需要再次反手
new_price = self.get_current_price()
if new_price:
new_signal = self.check_signal(new_price, prev_kline, current_kline)
if new_signal:
logger.info(f"检测到连续反手信号!当前价格: {new_price:.2f}")
self.execute_trade(new_signal, size=1)
logger.success(f"连续反手执行完成: {new_signal[0]}, 当前持仓状态: {self.start}")
time.sleep(1) # 交易后稍等
continue # 立即进入下一次循环继续监控
# 6. 短暂等待后继续循环同一根K线遇到信号就操作
time.sleep(3)
except KeyboardInterrupt:
logger.info("用户中断,程序退出")
break
except Exception as e:
logger.error(f"主循环异常: {e}")
time.sleep(5)
if __name__ == '__main__':
BitmartFuturesTransaction(bit_id="f2320f57e24c45529a009e1541e25961").action()

View File

@@ -1,23 +1,24 @@
"""
BitMart 五分之一回归策略交易(精准版)
使用3分钟K线周期计算触发价格实时监测同根K线内多空都触及时用1分钟K线判断先后
BitMart 五分之一策略交易(3分钟精准版)
使用3分钟K线周期计算触发价格实时监测同根K线内多空都触及时用开盘价距离判断先后
策略规则(与 bitmart/回测-三分之一策略-精准版.py 一致):
1. 触发价格计算基于有效的前一根K线实体>=0.1
策略规则(与 bitmart/回测数据-五分之一策略-3分钟精准版.py 完全一致):
1. 触发价格计算(基于有效的前一根3分钟K线实体>=0.1
- 做多触发价格 = 收盘价 + 实体/5从收盘价往上涨1/5
- 做空触发价格 = 收盘价 - 实体/5从收盘价往下跌1/5
2. 信号触发条件:
- 当前K线最高价 >= 做多触发价格 → 做多信号
- 当前K线最低价 <= 做空触发价格 → 做空信号
- 当前3分钟K线最高价 >= 做多触发价格 → 做多信号
- 当前3分钟K线最低价 <= 做空触发价格 → 做空信号
3. 执行逻辑:
- 做多时遇到做空信号 -> 平多并反手开空
- 做空时遇到做多信号 -> 平空并反手开多
- 同一根3分钟K线内只交易一次
4. 精准判断(使用1分钟K线
- 当当前3分钟K线同时触及做多和做空价格时拉取该3分钟对应的3根1分钟K线判断哪个方向先被触发
4. 同根触发判断(无需1分钟K线
- 当一根3分钟K线同时触及做多和做空价格时
- 使用该3分钟K线开盘价与触发价的距离判断先后
"""
import random
import time
@@ -71,18 +72,6 @@ class BitmartOneFifthStrategy:
self.last_trigger_kline_id = None
self.last_trigger_direction = None
self.last_trade_kline_id = None
# 反手信号当前价格容差(美元)
# 当检测到反手信号时,当前价格必须在触发价附近才执行
# 避免"先涨后跌"或"先跌后涨"的情况下错误开仓
self.reverse_price_tolerance = 2.0 # 2美元容差
# 基于开仓价格的反手信号参数
# 记录开仓时使用的前一根K线实体大小用于计算反手触发价
self.entry_prev_body = None # 开仓时前一根K线的实体大小
self.entry_price = None # 开仓价格(用于计算反手触发价)
self.entry_kline_id = None # 开仓时的K线ID用于判断是否在同一根K线内
self.first_minute_reverse_executed = False # 当前K线是否已执行过第一分钟反手
# ========================= 五分之一策略核心 =========================
@@ -118,156 +107,13 @@ class BitmartOneFifthStrategy:
short_trigger = p_close - body / 5
return long_trigger, short_trigger
def get_1m_bars_for_3m_bar(self, bar_3m):
"""获取当前3分钟K线对应的3根1分钟K线用于同根内多空都触发时判断先后"""
try:
start_ts = int(bar_3m['id'])
end_ts = start_ts + 3 * 60 # 秒
response = self.contractAPI.get_kline(
contract_symbol=self.contract_symbol,
step=1,
start_time=start_ts,
end_time=end_ts
)[0]
if response.get('code') != 1000:
return []
data = response.get('data', [])
out = []
for k in data:
out.append({
'id': int(k["timestamp"]),
'open': float(k["open_price"]),
'high': float(k["high_price"]),
'low': float(k["low_price"]),
'close': float(k["close_price"])
})
out.sort(key=lambda x: x['id'])
return out
except Exception as e:
logger.warning(f"获取1分钟K线失败: {e}")
return []
def determine_trigger_order_by_1m(self, bars_1m, long_trigger, short_trigger):
def check_realtime_trigger(self, kline_data):
"""
用1分钟K线判断在3分钟周期内先触发做多还是做空
返回 'long', 'short' 或 None
"""
if not bars_1m:
return None
for bar in bars_1m:
high = float(bar['high'])
low = float(bar['low'])
open_price = float(bar['open'])
long_ok = high >= long_trigger
short_ok = low <= short_trigger
if long_ok and not short_ok:
return 'long'
if short_ok and not long_ok:
return 'short'
if long_ok and short_ok:
d_long = abs(long_trigger - open_price)
d_short = abs(short_trigger - open_price)
return 'short' if d_short < d_long else 'long'
return None
def check_first_minute_reverse_signal(self, curr_kline, kline_data):
"""
检测基于开仓价格的反手信号只在3分钟K线的第一分钟有效
反手规则:
- 空仓反手开多:开空仓后,价格涨到 开仓价格 + 前一根K线实体/5 → 平空开多
- 多仓反手开空:开多仓后,价格跌到 开仓价格 - 前一根K线实体/5 → 平多开空
:param curr_kline: 当前3分钟K线数据
:param kline_data: 所有K线数据用于获取前一根K线实体
:return: (方向, 触发价格) 或 (None, None)
"""
# 检查是否有持仓
if self.start == 0:
return None, None
curr_kline_id = curr_kline['id']
# 如果K线切换了重置第一分钟反手标记
if self.entry_kline_id != curr_kline_id:
self.first_minute_reverse_executed = False
self.entry_kline_id = curr_kline_id # 更新当前K线ID
# 检查当前K线是否已执行过第一分钟反手
if self.first_minute_reverse_executed:
return None, None
# 获取开仓价格如果没有记录使用API返回的开仓均价
entry_price = self.entry_price
if entry_price is None and self.open_avg_price:
entry_price = float(self.open_avg_price)
if entry_price is None:
return None, None
# 获取前一根有效K线的实体大小
valid_prev_idx, valid_prev = self.find_valid_prev_bar(kline_data, len(kline_data) - 1, self.min_body_size)
if valid_prev is None:
return None, None
prev_body = self.get_body_size(valid_prev)
# 计算反手触发价格
reverse_offset = prev_body / 5
# 获取第一分钟K线
bars_1m = self.get_1m_bars_for_3m_bar(curr_kline)
if not bars_1m or len(bars_1m) < 1:
return None, None
first_1m = bars_1m[0] # 第一分钟K线
first_1m_high = float(first_1m['high'])
first_1m_low = float(first_1m['low'])
first_1m_close = float(first_1m['close'])
if self.start == -1:
# 持有空仓,检测反手开多信号
# 反手触发价 = 开仓价格 + 前一根实体/5
reverse_long_trigger = entry_price + reverse_offset
# 检查第一分钟是否触及反手触发价
if first_1m_high >= reverse_long_trigger:
# 第一分钟高点触及反手触发价,并且当前价格在触发价附近
if first_1m_close >= reverse_long_trigger - self.reverse_price_tolerance:
logger.info(f"🔄 第一分钟反手信号检测:持空仓,第一分钟高点{first_1m_high:.2f}>=反手触发价{reverse_long_trigger:.2f}")
logger.info(f" 开仓价={entry_price:.2f}, 前一根实体={prev_body:.2f}, 实体/5={reverse_offset:.2f}")
return 'long', reverse_long_trigger
else:
logger.debug(f"第一分钟反手信号被过滤:当前价格{first_1m_close:.2f}已远离触发价{reverse_long_trigger:.2f}")
elif self.start == 1:
# 持有多仓,检测反手开空信号
# 反手触发价 = 开仓价格 - 前一根实体/5
reverse_short_trigger = entry_price - reverse_offset
# 检查第一分钟是否触及反手触发价
if first_1m_low <= reverse_short_trigger:
# 第一分钟低点触及反手触发价,并且当前价格在触发价附近
if first_1m_close <= reverse_short_trigger + self.reverse_price_tolerance:
logger.info(f"🔄 第一分钟反手信号检测:持多仓,第一分钟低点{first_1m_low:.2f}<=反手触发价{reverse_short_trigger:.2f}")
logger.info(f" 开仓价={entry_price:.2f}, 前一根实体={prev_body:.2f}, 实体/5={reverse_offset:.2f}")
return 'short', reverse_short_trigger
else:
logger.debug(f"第一分钟反手信号被过滤:当前价格{first_1m_close:.2f}已远离触发价{reverse_short_trigger:.2f}")
return None, None
def check_realtime_trigger(self, kline_data, current_position=0):
"""
实时检测当前3分钟K线是否触发信号
检查当前3分钟K线是否触发交易信号与回测逻辑完全一致
若同时触发多空则用开盘价距离判断先后顺序不请求1分钟K线
参数:
kline_data: K线数据列表
current_position: 当前持仓状态 (1=多, -1=空, 0=无)
逻辑优化:
- 当已有持仓时,只关心反向信号(有多仓只看空信号,有空仓只看多信号)
- 无仓位时用1分钟K线判断先触发的方向
- 【重要】反手信号不仅要求K线高/低点触及触发价,还要求当前价格在触发价附近
避免"先涨后跌""先跌后涨"的情况下错误开仓
返回:(方向, 触发价格, 有效前一根K线, 当前K线) 或 (None, None, None, None)
"""
@@ -288,60 +134,35 @@ class BitmartOneFifthStrategy:
c_high = float(curr['high'])
c_low = float(curr['low'])
c_close = float(curr['close']) # 当前价格(用于检查价格是否仍在触发价附近)
long_triggered = c_high >= long_trigger
short_triggered = c_low <= short_trigger
both_triggered = long_triggered and short_triggered
direction = None
trigger_price = None
# 关键优化:根据当前持仓状态决定关注哪个方向的信号
if current_position == 1:
# 当前是多仓,只关心空信号(用于平多开空)
if short_triggered:
# 【重要】额外检查:当前价格必须在做空触发价附近或下方
# 如果价格已经涨回去了(当前价格远高于做空触发价),则不触发
if c_close <= short_trigger + self.reverse_price_tolerance:
direction = 'short'
trigger_price = short_trigger
else:
logger.debug(f"空信号被过滤:当前价格{c_close:.2f}已远离做空触发价{short_trigger:.2f}(容差{self.reverse_price_tolerance}")
elif current_position == -1:
# 当前是空仓,只关心多信号(用于平空开多)
if long_triggered:
# 【重要】额外检查:当前价格必须在做多触发价附近或上方
# 如果价格已经跌回去了(当前价格远低于做多触发价),则不触发
if c_close >= long_trigger - self.reverse_price_tolerance:
direction = 'long'
trigger_price = long_trigger
else:
logger.debug(f"多信号被过滤:当前价格{c_close:.2f}已远离做多触发价{long_trigger:.2f}(容差{self.reverse_price_tolerance}")
else:
# 无仓位,按原逻辑判断先触发的方向
if long_triggered and short_triggered:
bars_1m = self.get_1m_bars_for_3m_bar(curr)
if bars_1m:
direction = self.determine_trigger_order_by_1m(
bars_1m, long_trigger, short_trigger
)
trigger_price = long_trigger if direction == 'long' else short_trigger
if direction is None:
c_open = float(curr['open'])
d_long = abs(long_trigger - c_open)
d_short = abs(short_trigger - c_open)
direction = 'short' if d_short <= d_long else 'long'
trigger_price = long_trigger if direction == 'long' else short_trigger
elif short_triggered:
# 如果同时触发多空用开盘价距离判断先后顺序避免请求1分钟K线
if both_triggered:
c_open = float(curr['open'])
dist_to_long = abs(long_trigger - c_open)
dist_to_short = abs(short_trigger - c_open)
if dist_to_short <= dist_to_long:
direction = 'short'
trigger_price = short_trigger
elif long_triggered:
else:
direction = 'long'
trigger_price = long_trigger
elif short_triggered:
direction = 'short'
trigger_price = short_trigger
elif long_triggered:
direction = 'long'
trigger_price = long_trigger
if direction is None:
return None, None, None, None
# 避免同一根K线内重复触发相同信号
if self.last_trigger_kline_id == curr_kline_id and self.last_trigger_direction == direction:
return None, None, None, None
@@ -494,7 +315,6 @@ class BitmartOneFifthStrategy:
return False
direction_str = "做多" if marketPriceLongOrder == 1 else "做空"
logger.info(f"执行{direction_str}操作,金额: {size}")
size = 25
try:
if marketPriceLongOrder == -1:
self.click_safe('x://button[normalize-space(text()) ="市价"]')
@@ -583,73 +403,12 @@ class BitmartOneFifthStrategy:
curr = kline_data[-1]
curr_time_str = datetime.datetime.fromtimestamp(curr['id']).strftime('%H:%M:%S')
# 优化:先获取持仓状态,再检测信号(传入持仓状态以便只关注反向信号)
# 获取持仓状态
if not self.get_position_status():
logger.warning("获取仓位信息失败,使用缓存的持仓状态")
# ========== 第一分钟反手信号检测 ==========
# 如果有持仓,先检测基于开仓价格的第一分钟反手信号
first_min_direction = None
first_min_trigger_price = None
if self.start != 0:
first_min_direction, first_min_trigger_price = self.check_first_minute_reverse_signal(curr, kline_data)
# 如果检测到第一分钟反手信号,优先执行
if first_min_direction:
curr_kline_id = curr['id']
if self.last_trade_kline_id != curr_kline_id:
logger.info(f"{'=' * 50}")
# 安全获取开仓价格和前一根实体
entry_price_display = self.entry_price if self.entry_price else (float(self.open_avg_price) if self.open_avg_price else 0)
entry_body_display = self.entry_prev_body if self.entry_prev_body else 0
logger.info(f"🔄 第一分钟反手信号触发!方向: {first_min_direction}, 触发价: {first_min_trigger_price:.2f}")
logger.info(f" 开仓价: {entry_price_display:.2f}, 前一根实体/5: {entry_body_display/5:.2f}")
logger.info(f" 当前持仓: {self.start} (1=多, -1=空)")
balance = self.get_available_balance()
trade_size = (balance or 0) * self.risk_percent
if first_min_direction == 'long' and self.start == -1:
logger.info("📈 第一分钟反手:平空仓,反手开多")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=1, size=trade_size)
self.first_minute_reverse_executed = True
self.last_trade_kline_id = curr_kline_id
# 更新开仓信息
valid_prev_idx, valid_prev = self.find_valid_prev_bar(kline_data, len(kline_data) - 1, self.min_body_size)
if valid_prev:
self.entry_prev_body = self.get_body_size(valid_prev)
self.entry_price = float(curr['close'])
self.entry_kline_id = curr_kline_id
self.get_position_status()
self._send_position_message(curr)
elif first_min_direction == 'short' and self.start == 1:
logger.info("📉 第一分钟反手:平多仓,反手开空")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=-1, size=trade_size)
self.first_minute_reverse_executed = True
self.last_trade_kline_id = curr_kline_id
# 更新开仓信息
valid_prev_idx, valid_prev = self.find_valid_prev_bar(kline_data, len(kline_data) - 1, self.min_body_size)
if valid_prev:
self.entry_prev_body = self.get_body_size(valid_prev)
self.entry_price = float(curr['close'])
self.entry_kline_id = curr_kline_id
self.get_position_status()
self._send_position_message(curr)
logger.info(f"{'=' * 50}")
time.sleep(self.check_interval)
continue
# ========== 原有的五分之一信号检测 ==========
# 传入当前持仓状态,确保有持仓时只关注反向信号
direction, trigger_price, valid_prev, curr_kline = self.check_realtime_trigger(
kline_data, current_position=self.start
)
# 检测五分之一策略信号(与回测逻辑完全一致)
direction, trigger_price, valid_prev, curr_kline = self.check_realtime_trigger(kline_data)
if direction:
curr_kline_id = curr_kline['id']
@@ -663,15 +422,6 @@ class BitmartOneFifthStrategy:
prev_type = "阳线" if self.is_bullish(valid_prev) else "阴线"
prev_body = self.get_body_size(valid_prev)
# 由于 check_realtime_trigger 已经考虑了持仓状态,这里理论上不会出现同向信号
# 但保留这个检查作为安全措施
if (direction == "long" and self.start == 1) or (direction == "short" and self.start == -1):
logger.debug(f"同向信号被过滤: direction={direction}, position={self.start}")
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
time.sleep(self.check_interval)
continue
logger.info(f"{'=' * 50}")
logger.info(f"🚨 检测到{direction}信号!触发价格: {trigger_price:.2f}")
logger.info(
@@ -684,40 +434,44 @@ class BitmartOneFifthStrategy:
trade_size = (balance or 0) * self.risk_percent
executed = False
# 执行交易逻辑(与回测一致)
if direction == "long":
if self.start == -1:
# 持空仓遇到做多信号 -> 平空并反手开多
logger.info("📈 平空仓,反手开多")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=1, size=trade_size)
executed = True
elif self.start == 0:
# 无仓位遇到做多信号 -> 开多
logger.info("📈 无仓位,开多")
self.开单(marketPriceLongOrder=1, size=trade_size)
executed = True
elif self.start == 1:
# 持多仓遇到做多信号 -> 不操作
logger.debug("已持有多仓,忽略做多信号")
elif direction == "short":
if self.start == 1:
# 持多仓遇到做空信号 -> 平多并反手开空
logger.info("📉 平多仓,反手开空")
self.平仓()
time.sleep(1)
self.开单(marketPriceLongOrder=-1, size=trade_size)
executed = True
elif self.start == 0:
# 无仓位遇到做空信号 -> 开空
logger.info("📉 无仓位,开空")
self.开单(marketPriceLongOrder=-1, size=trade_size)
executed = True
elif self.start == -1:
# 持空仓遇到做空信号 -> 不操作
logger.debug("已持有空仓,忽略做空信号")
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
if executed:
self.last_trade_kline_id = curr_kline_id
# 记录开仓信息,用于第一分钟反手信号检测
self.entry_price = trigger_price # 开仓触发价格
self.entry_prev_body = self.get_body_size(valid_prev) # 前一根K线实体大小
self.entry_kline_id = curr_kline_id # 开仓时的K线ID
self.first_minute_reverse_executed = False # 重置第一分钟反手标记
logger.info(f" 记录开仓信息:开仓价={self.entry_price:.2f}, 前一根实体={self.entry_prev_body:.2f}, K线ID={self.entry_kline_id}")
self.get_position_status()
self._send_position_message(curr_kline)
last_report_time = time.time()

View File

@@ -0,0 +1,641 @@
"""
WEEX ETH-USDT 永续合约 — 三分之一策略5分钟K线
策略规则(与 bitmart/三分之一策略-5分钟交易.py 一致):
1. 触发价格前一根有效K线实体>=0.1
- 做多触发价 = 收盘价 + 实体/3做空触发价 = 收盘价 - 实体/3
2. 信号当前5分钟K线最高>=做多触发→多;最低<=做空触发→空;同根多空都触发用开盘价距离判断先后
3. 反手一:持空且当前涨到上根最高且上根上影线>0.01%→反手多;持多且当前跌到上根最低且上根下影线>0.01%→反手空
4. 反手二:持多且上根上影线>0.01%且当前跌到上根开盘→反手空;持空且上根下影线>0.01%且当前涨到上根开盘→反手多
5. 同一根5分钟K线内只交易一次
"""
import random
import time
import datetime
from typing import Optional, Dict, List, Tuple
from tqdm import tqdm
from loguru import logger
from DrissionPage import ChromiumOptions, ChromiumPage
from curl_cffi import requests
from bit_tools import openBrowser
from 交易.tools import send_dingtalk_message
# ==================== 配置常量 ====================
class Config:
TGE_URL = "http://127.0.0.1:50326"
TGE_AUTHORIZATION = "Bearer asp_174003986c9b0799677c5b2c1adb76e402735d753bc91a91"
CONTRACT_ID = "10000002"
PRODUCT_CODE = "cmt_ethusdt"
KLINE_TYPE = "MINUTE_5" # 5分钟K线三分之一策略
KLINE_LIMIT = 100
TRADING_URL = "https://www.weex.com/zh-CN/futures/ETH-USDT"
POSITION_RATIO = 100
MAX_RETRY_ATTEMPTS = 3
RETRY_DELAY = 1
# 三分之一策略参数
MIN_BODY_SIZE = 0.1
MIN_SHADOW_PCT = 0.01
# ==================== 三分之一策略分析器 ====================
class OneThirdStrategyAnalyzer:
"""三分之一策略 K 线分析5分钟触发价=收盘价±实体/3 + 两个反手信号"""
@staticmethod
def get_body_size(candle: Dict) -> float:
return abs(float(candle['open']) - float(candle['close']))
@staticmethod
def find_valid_prev_bar(all_data: List[Dict], current_idx: int, min_body_size: float = 0.1) -> Tuple[
Optional[int], Optional[Dict]]:
if current_idx <= 0:
return None, None
for i in range(current_idx - 1, -1, -1):
prev = all_data[i]
if OneThirdStrategyAnalyzer.get_body_size(prev) >= min_body_size:
return i, prev
return None, None
@staticmethod
def get_one_third_levels(prev: Dict) -> Tuple[Optional[float], Optional[float]]:
p_open, p_close = float(prev['open']), float(prev['close'])
body = abs(p_open - p_close)
if body < 0.001:
return None, None
return p_close + body / 3, p_close - body / 3
@staticmethod
def get_upper_shadow(candle: Dict) -> float:
o, c, h = float(candle['open']), float(candle['close']), float(candle['high'])
return h - max(o, c)
@staticmethod
def get_lower_shadow(candle: Dict) -> float:
o, c, l = float(candle['open']), float(candle['close']), float(candle['low'])
return min(o, c) - l
@staticmethod
def upper_shadow_pct(candle: Dict) -> float:
o = float(candle['open'])
return (OneThirdStrategyAnalyzer.get_upper_shadow(candle) / o * 100) if o > 0 else 0.0
@staticmethod
def lower_shadow_pct(candle: Dict) -> float:
o = float(candle['open'])
return (OneThirdStrategyAnalyzer.get_lower_shadow(candle) / o * 100) if o > 0 else 0.0
@staticmethod
def check_reverse_by_prev_high_low(kline_data: List[Dict], start: int) -> Tuple[Optional[str], Optional[Dict]]:
if len(kline_data) < 2:
return None, None
curr, prev = kline_data[-1], kline_data[-2]
curr_high = float(curr['high'])
curr_low = float(curr['low'])
prev_high = float(prev['high'])
prev_low = float(prev['low'])
if start == -1 and curr_high >= prev_high and OneThirdStrategyAnalyzer.upper_shadow_pct(
prev) > Config.MIN_SHADOW_PCT:
return 'long', prev
if start == 1 and curr_low <= prev_low and OneThirdStrategyAnalyzer.lower_shadow_pct(
prev) > Config.MIN_SHADOW_PCT:
return 'short', prev
return None, None
@staticmethod
def check_reverse_by_prev_open(kline_data: List[Dict], start: int) -> Tuple[Optional[str], Optional[Dict]]:
if len(kline_data) < 2:
return None, None
curr, prev = kline_data[-1], kline_data[-2]
curr_high = float(curr['high'])
curr_low = float(curr['low'])
prev_open = float(prev['open'])
if start == 1 and OneThirdStrategyAnalyzer.upper_shadow_pct(
prev) > Config.MIN_SHADOW_PCT and curr_low <= prev_open:
return 'short', prev
if start == -1 and OneThirdStrategyAnalyzer.lower_shadow_pct(
prev) > Config.MIN_SHADOW_PCT and curr_high >= prev_open:
return 'long', prev
return None, None
@staticmethod
def check_realtime_trigger(
kline_data: List[Dict],
last_trigger_kline_id: Optional[int],
last_trigger_direction: Optional[str],
) -> Tuple[Optional[str], Optional[float], Optional[Dict], Optional[Dict]]:
if len(kline_data) < 2:
return None, None, None, None
curr = kline_data[-1]
curr_kline_id = curr['id']
curr_high = float(curr['high'])
curr_low = float(curr['low'])
curr_open = float(curr['open'])
valid_prev_idx, prev = OneThirdStrategyAnalyzer.find_valid_prev_bar(
kline_data, len(kline_data) - 1, Config.MIN_BODY_SIZE
)
if prev is None:
return None, None, None, None
long_trigger, short_trigger = OneThirdStrategyAnalyzer.get_one_third_levels(prev)
if long_trigger is None:
return None, None, None, None
long_triggered = curr_high >= long_trigger
short_triggered = curr_low <= short_trigger
both_triggered = long_triggered and short_triggered
direction = None
trigger_price = None
if both_triggered:
dist_to_long = abs(long_trigger - curr_open)
dist_to_short = abs(short_trigger - curr_open)
if dist_to_short <= dist_to_long:
direction, trigger_price = 'short', short_trigger
else:
direction, trigger_price = 'long', long_trigger
elif short_triggered:
direction, trigger_price = 'short', short_trigger
elif long_triggered:
direction, trigger_price = 'long', long_trigger
if direction is None:
return None, None, None, None
if last_trigger_kline_id == curr_kline_id and last_trigger_direction == direction:
return None, None, None, None
return direction, trigger_price, prev, curr
# ==================== 浏览器管理器 ====================
class BrowserManager:
def __init__(self, tge_id, tge_url: str, tge_headers: Dict):
self.tge_id = tge_id
self.tge_url = tge_url
self.tge_headers = tge_headers
self.tge_port: Optional[int] = None
self.page: Optional[ChromiumPage] = None
def openBrowser(self):
try:
bit_port = openBrowser(id=self.tge_id)
co = ChromiumOptions()
co.set_local_port(port=bit_port)
self.page = ChromiumPage(addr_or_opts=co)
self.tge_port = bit_port
return True
except Exception:
return False
def take_over_browser(self) -> bool:
if not self.tge_port:
return False
try:
co = ChromiumOptions()
co.set_local_port(self.tge_port)
self.page = ChromiumPage(addr_or_opts=co)
self.page.set.window.max()
return True
except Exception:
return False
def close_extra_tabs(self) -> bool:
if not self.page:
return False
try:
for idx, tab in enumerate(self.page.get_tabs()):
if idx > 0:
tab.close()
return True
except Exception:
return False
# ==================== WEEX API 客户端 ====================
class WEEXApiClient:
def __init__(self):
self.session = requests.Session()
self.headers: Optional[Dict] = None
def update_headers(self, headers: Dict) -> None:
if not self.headers:
self.session.headers = headers
else:
self.session.headers.update(headers)
self.headers = headers
def get_kline_data(
self,
contract_id: str = Config.CONTRACT_ID,
product_code: str = Config.PRODUCT_CODE,
kline_type: str = Config.KLINE_TYPE,
limit: int = Config.KLINE_LIMIT,
) -> List[Dict]:
params = {
'contractId': contract_id,
'productCode': product_code,
'priceType': 'LAST_PRICE',
'klineType': kline_type,
'limit': str(limit),
'timeZone': 'string',
'languageType': '1',
'sign': 'SIGN',
}
for attempt in range(Config.MAX_RETRY_ATTEMPTS):
try:
response = self.session.get(
'https://http-gateway2.elconvo.com/api/v1/public/quote/v1/getKlineV2',
params=params,
timeout=15,
)
if response.status_code != 200:
if attempt < Config.MAX_RETRY_ATTEMPTS - 1:
time.sleep(Config.RETRY_DELAY)
continue
response_data = response.json()
if "data" not in response_data or "dataList" not in response_data["data"]:
continue
result = response_data["data"]["dataList"]
kline_data = []
for item in result:
kline_data.append({
'id': int(item[4]),
'open': float(item[3]),
'high': float(item[1]),
'low': float(item[2]),
'close': float(item[0]),
})
return kline_data
except Exception as e:
if attempt < Config.MAX_RETRY_ATTEMPTS - 1:
time.sleep(Config.RETRY_DELAY)
return []
def get_available_balance(self) -> Optional[float]:
for attempt in range(Config.MAX_RETRY_ATTEMPTS):
try:
response = self.session.post(
'https://gateway2.ngsvsfx.cn/v1/gw/assetsWithBalance/new',
timeout=15,
)
return float(response.json()["data"]["newContract"]["balanceList"][0]["available"])
except Exception:
if attempt < Config.MAX_RETRY_ATTEMPTS - 1:
time.sleep(Config.RETRY_DELAY)
return None
def get_position_status(self) -> Tuple[bool, Optional[List]]:
json_data = {
'filterContractIdList': [10000002],
'limit': 100,
'languageType': 0,
'sign': 'SIGN',
'timeZone': 'string',
}
for attempt in range(Config.MAX_RETRY_ATTEMPTS):
try:
response = self.session.post(
'https://http-gateway2.janapw.com/api/v1/private/order/v2/getHistoryOrderFillTransactionPage',
json=json_data,
timeout=15,
)
datas = response.json()["data"]["dataList"]
if not datas:
return True, None
return True, datas
except Exception:
if attempt < Config.MAX_RETRY_ATTEMPTS - 1:
time.sleep(Config.RETRY_DELAY)
return False, None
# ==================== Token 管理器 ====================
class TokenManager:
def __init__(self, api_client: WEEXApiClient, page: ChromiumPage):
self.api_client = api_client
self.page = page
def get_token(self) -> bool:
tab = self.page.new_tab()
tab.listen.start("/user/security/getLanguageType")
try:
for attempt in range(Config.MAX_RETRY_ATTEMPTS):
try:
tab.get(url=Config.TRADING_URL)
res = tab.listen.wait(timeout=5)
if res.request.headers.get("U-TOKEN"):
self.api_client.update_headers(res.request.headers)
return True
except Exception:
if attempt < Config.MAX_RETRY_ATTEMPTS - 1:
time.sleep(Config.RETRY_DELAY)
return False
finally:
tab.close()
# ==================== 交易执行器 ====================
class TradingExecutor:
def __init__(self, page: ChromiumPage, api_client: WEEXApiClient):
self.page = page
self.api_client = api_client
def navigate_to_trading_page(self) -> bool:
try:
self.page.ele('x:(//button[normalize-space(text()) = "市价"])').click()
time.sleep(1)
return True
except Exception:
return False
def close_all_positions(self) -> bool:
try:
self.page.ele('x:(//span[normalize-space(text()) = "闪电平仓"])').scroll.to_see(center=True)
time.sleep(1)
self.page.ele('x:(//span[normalize-space(text()) = "闪电平仓"])').click(by_js=True)
time.sleep(3)
return True
except Exception:
return False
def open_long(self, amount: float) -> bool:
try:
self.page.ele('x://input[@placeholder="请输入数量"]').input(amount)
time.sleep(1)
self.page.ele('x://*[normalize-space(text()) ="买入开多"]').click(by_js=True)
return True
except Exception:
return False
def open_short(self, amount: float) -> bool:
try:
self.page.ele('x://input[@placeholder="请输入数量"]').input(amount)
time.sleep(1)
self.page.ele('x://*[normalize-space(text()) ="卖出开空"]').click(by_js=True)
return True
except Exception:
return False
def execute_trade(self, direction: str, current_position: int, amount: float) -> bool:
if (direction == "long" and current_position == PositionManager.POSITION_LONG) or \
(direction == "short" and current_position == PositionManager.POSITION_SHORT):
return True
if not self.navigate_to_trading_page():
return False
try:
if direction == "long":
if current_position == 0:
return self.open_long(amount)
elif current_position == -1:
if self.close_all_positions():
time.sleep(1)
return self.open_long(amount)
elif direction == "short":
if current_position == 0:
return self.open_short(amount)
elif current_position == 1:
if self.close_all_positions():
time.sleep(1)
return self.open_short(amount)
except Exception:
pass
return False
# ==================== 持仓管理器 ====================
class PositionManager:
POSITION_SHORT = -1
POSITION_NONE = 0
POSITION_LONG = 1
def __init__(self, trading_executor: TradingExecutor):
self.trading_executor = trading_executor
self.current_position: int = self.POSITION_NONE
self.position_data: Optional[List] = None
def update_position(self, position_data: Optional[List]) -> None:
self.position_data = position_data
if not position_data:
self.current_position = self.POSITION_NONE
return
position_data = list(position_data)
position_data.reverse()
start, start1 = 0, 0
for i in position_data:
direction = i.get("legacyOrderDirection")
if direction == "CLOSE_SHORT":
start = 0
elif direction == "CLOSE_LONG":
start1 = 0
elif direction == "OPEN_SHORT":
start -= 1
elif direction == "OPEN_LONG":
start1 += 1
if start1:
self.current_position = self.POSITION_LONG
elif start:
self.current_position = self.POSITION_SHORT
else:
self.current_position = self.POSITION_NONE
# ==================== 消息发送 ====================
class MessageSender:
@staticmethod
def send(msg: str, is_error: bool = False) -> None:
prefix = "❌weex三分之一" if is_error else "🔔weex三分之一"
for _ in range(15 if is_error else 1):
send_dingtalk_message(f"{prefix}{msg}")
# ==================== 5分钟K线时间工具 ====================
class TimeUtils5m:
@staticmethod
def get_current_kline_timestamp() -> int:
"""当前所在 5 分钟 K 线的时间戳(毫秒)"""
t = time.time()
dt = datetime.datetime.fromtimestamp(t)
minute = (dt.minute // 5) * 5
target = dt.replace(minute=minute, second=0, microsecond=0)
return int(target.timestamp()) * 1000
@staticmethod
def get_progress_bar_value() -> int:
"""0~4 表示当前 5 分钟内的分钟数"""
return datetime.datetime.now().minute % 5
# ==================== 主交易类 ====================
class WeexOneThirdTransaction:
"""WEEX 三分之一策略5分钟K线自动交易"""
def __init__(self, tge_id):
self.tge_id = tge_id
self.tge_headers = {
"Authorization": Config.TGE_AUTHORIZATION,
"Content-Type": "application/json",
}
self.browser_manager = BrowserManager(tge_id, Config.TGE_URL, self.tge_headers)
self.api_client = WEEXApiClient()
self.position_manager: Optional[PositionManager] = None
self.trading_executor: Optional[TradingExecutor] = None
self.token_manager: Optional[TokenManager] = None
self.pbar: Optional[tqdm] = None
self.last_kline_timestamp: Optional[int] = None
self.kline_data: List[Dict] = []
self.last_trigger_kline_id: Optional[int] = None
self.last_trigger_direction: Optional[str] = None
self.last_trade_kline_id: Optional[int] = None
def initialize(self) -> bool:
for i in range(3):
if self.browser_manager.openBrowser():
break
else:
MessageSender.send("打开浏览器失败", is_error=True)
if not self.browser_manager.take_over_browser():
MessageSender.send("接管浏览器失败", is_error=True)
return False
self.browser_manager.close_extra_tabs()
page = self.browser_manager.page
self.trading_executor = TradingExecutor(page, self.api_client)
self.position_manager = PositionManager(self.trading_executor)
self.token_manager = TokenManager(self.api_client, page)
page.get(url=Config.TRADING_URL)
if not self.token_manager.get_token():
logger.warning("初始化获取 token 失败将在获取K线时重试")
self.pbar = tqdm(total=5, desc="等待5分钟K线", ncols=80)
return True
def fetch_and_update_kline(self) -> bool:
if not self.token_manager.get_token():
return False
kline_data = self.api_client.get_kline_data()
if not kline_data or len(kline_data) < 3:
return False
sorted_data = sorted(kline_data, key=lambda x: x["id"])
self.kline_data = sorted_data
current_kline_id = sorted_data[-1]["id"]
current_ts = TimeUtils5m.get_current_kline_timestamp()
if current_kline_id != current_ts:
return False
if self.last_kline_timestamp == current_ts:
return False
self.last_kline_timestamp = current_ts
return True
def sync_position_status(self) -> bool:
success, position_data = self.api_client.get_position_status()
if not success:
return False
self.position_manager.update_position(position_data)
return True
def process_trading_logic(self) -> None:
self.token_manager.get_token()
self.browser_manager.page.get(url=Config.TRADING_URL)
if not self.sync_position_status():
return
kline_data = self.kline_data
curr = kline_data[-1]
curr_kline_id = curr["id"]
start = self.position_manager.current_position
# 反手一:涨到上根最高/跌到上根最低 + 影线>0.01%
rev_dir, rev_prev = OneThirdStrategyAnalyzer.check_reverse_by_prev_high_low(kline_data, start)
rev_type = ""
if not rev_dir:
rev_dir, rev_prev = OneThirdStrategyAnalyzer.check_reverse_by_prev_open(kline_data, start)
rev_type = ""
if rev_dir and self.last_trade_kline_id != curr_kline_id:
balance = self.api_client.get_available_balance()
amount = int((balance or 0) / Config.POSITION_RATIO)
if self.trading_executor.execute_trade(rev_dir, start, amount):
self.last_trade_kline_id = curr_kline_id
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = rev_dir
if rev_dir == "long":
self.position_manager.current_position = PositionManager.POSITION_LONG
else:
self.position_manager.current_position = PositionManager.POSITION_SHORT
MessageSender.send(f"反手信号{rev_type} {rev_dir},金额 {amount}")
return
# 主信号:三分之一触发
direction, trigger_price, valid_prev, curr_kline = OneThirdStrategyAnalyzer.check_realtime_trigger(
kline_data, self.last_trigger_kline_id, self.last_trigger_direction
)
if not direction:
return
if self.last_trade_kline_id == curr_kline_id:
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
return
if (direction == "long" and start == PositionManager.POSITION_LONG) or \
(direction == "short" and start == PositionManager.POSITION_SHORT):
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
return
balance = self.api_client.get_available_balance()
if balance is None:
return
amount = int(balance / Config.POSITION_RATIO)
if self.trading_executor.execute_trade(direction, start, amount):
self.last_trade_kline_id = curr_kline_id
self.last_trigger_kline_id = curr_kline_id
self.last_trigger_direction = direction
if direction == "long":
self.position_manager.current_position = PositionManager.POSITION_LONG
else:
self.position_manager.current_position = PositionManager.POSITION_SHORT
MessageSender.send(f"三分之一信号 {direction} 触发价={trigger_price:.2f} 金额={amount}")
def run(self) -> None:
logger.info("WEEX 三分之一策略5分钟K线开始运行")
while True:
if not self.initialize():
return
try:
if self.pbar:
self.pbar.n = TimeUtils5m.get_progress_bar_value()
self.pbar.refresh()
current_ts = TimeUtils5m.get_current_kline_timestamp()
if self.last_kline_timestamp == current_ts:
time.sleep(10)
continue
if not self.fetch_and_update_kline():
time.sleep(10)
continue
self.process_trading_logic()
if self.pbar:
self.pbar.reset()
time.sleep(5)
except KeyboardInterrupt:
break
except Exception as e:
logger.error(e)
MessageSender.send(f"运行出错: {e}", is_error=True)
time.sleep(10)
if random.randint(1, 10) > 7:
self.browser_manager.page.close()
time.sleep(5)
def action(self) -> None:
self.run()
if __name__ == '__main__':
WeexOneThirdTransaction(tge_id="86837a981aba4576be6916a0ef6ad785").action()

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -1,277 +0,0 @@
开仓时间,平仓时间,数量,开仓价,平仓价,盈亏,类型,开仓订单ID,平仓订单ID,时间_x
2025-08-28 09:35:18+08:00,2025-08-28 09:44:18+08:00,664.0,4514.69,4507.43,4820.639999999541,平空,e1d3a2da-219e-436f-ac9e-a7ea93de15bd,abfa0508-9399-4f1b-90c7-7716c3e7f511,2025-08-28 01:44:00
2025-08-28 10:06:42+08:00,2025-08-28 10:10:07+08:00,1106.0,4519.88,4515.64,-4689.439999999759,平多,594bd10c-2120-4692-a8eb-9f5325e26ef0,bd643cab-14d4-414d-912e-e9257ddb96de,2025-08-28 02:10:00
2025-08-28 10:45:07+08:00,2025-08-28 10:51:41+08:00,1108.0,4512.13,4516.84,-5218.68000000004,平空,fc0c73ab-9fff-41b5-98c1-ef6f7d300256,206688da-848a-4822-9571-c05302ab7a29,2025-08-28 02:51:00
2025-08-28 11:07:30+08:00,2025-08-28 11:13:19+08:00,200.0,4525.0,4529.25,850.0,平多,6197fb5c-6202-422f-9012-5395c5393fb3,59d8859f-2b64-4e8b-aefe-57998b198841,2025-08-28 03:13:00
2025-08-28 11:07:30+08:00,2025-08-28 11:13:19+08:00,100.0,4525.0,4529.25,425.0,平多,794c0925-6e48-4b9a-a162-d31d7a3c42cc,59d8859f-2b64-4e8b-aefe-57998b198841,2025-08-28 03:13:00
2025-08-28 11:07:31+08:00,2025-08-28 11:13:19+08:00,483.0,4525.0,4529.25,2052.75,平多,65f7d764-ad05-40c7-bce1-6b227ad5f5c0,59d8859f-2b64-4e8b-aefe-57998b198841,2025-08-28 03:13:00
2025-08-28 11:07:31+08:00,2025-08-28 11:13:19+08:00,100.0,4525.0,4529.25,425.0,平多,35e1c160-4129-425a-ae46-b8fb45d53ec8,59d8859f-2b64-4e8b-aefe-57998b198841,2025-08-28 03:13:00
2025-08-28 11:28:58+08:00,2025-08-28 11:34:21+08:00,400.0,4533.74,4537.34,1440.0000000001455,平多,a983b8f5-70d1-441b-87df-397c6c1ce843,3e161e4e-f367-421a-bc0d-8095f7b79675,2025-08-28 03:34:00
2025-08-28 11:28:58+08:00,2025-08-28 11:34:21+08:00,482.0,4533.74,4537.34,1735.2000000001754,平多,a983b8f5-70d1-441b-87df-397c6c1ce843,45ddb145-d637-4985-9c4b-3dee2fd189b5,2025-08-28 03:34:00
2025-08-28 12:22:53+08:00,2025-08-28 12:23:33+08:00,478.0,4550.8,4545.04,-2753.2800000001043,平多,37d97b24-c1fd-4a2d-ba0e-75b818062686,fcfe39c7-0bcf-47f6-9b48-a1dd70bd5444,2025-08-28 04:23:00
2025-08-28 12:22:53+08:00,2025-08-28 12:23:33+08:00,400.0,4550.8,4545.04,-2304.0000000000873,平多,37d97b24-c1fd-4a2d-ba0e-75b818062686,867b1b2c-0fe5-466b-a89f-ec8dce25bcda,2025-08-28 04:23:00
2025-08-28 12:26:39+08:00,2025-08-28 12:34:19+08:00,879.0,4549.6,4555.44,5133.3599999993285,平多,0a3a08a1-61c7-4997-b13c-4da05b2c5dbc,ad149e7f-7088-4dd9-9698-9b7bd615478e,2025-08-28 04:34:00
2025-08-28 12:46:19+08:00,2025-08-28 12:48:10+08:00,600.0,4561.8,4567.53,-3437.999999999738,平空,18929fa1-2cc7-4e7f-8e76-c3937f16f877,8283a8b1-17f1-4818-843d-33877996af35,2025-08-28 04:48:00
2025-08-28 12:46:19+08:00,2025-08-28 12:48:10+08:00,276.0,4561.8,4567.53,-1581.4799999998795,平空,18929fa1-2cc7-4e7f-8e76-c3937f16f877,c0a1d021-0708-476e-a766-722bc73ab740,2025-08-28 04:48:00
2025-08-28 12:53:40+08:00,2025-08-28 12:57:03+08:00,873.0,4577.05,4569.51,6582.419999999968,平空,16f8970d-ef44-4026-ba19-9c9ff6dc70e1,e1f9de7d-115e-4289-8acd-bbba16e04ff0,2025-08-28 04:57:00
2025-08-28 12:58:03+08:00,2025-08-28 13:01:30+08:00,475.0,4567.45,4572.58,-2436.750000000052,平空,8dbfcfc8-466c-4111-acdf-316a2a8c7428,3e0a22b4-7707-4332-b80d-87d3b07cf3cc,2025-08-28 05:01:00
2025-08-28 12:58:03+08:00,2025-08-28 13:01:30+08:00,400.0,4567.45,4572.58,-2052.0000000000437,平空,8dbfcfc8-466c-4111-acdf-316a2a8c7428,29775823-c3fc-4dbc-8afa-f9587f803f2a,2025-08-28 05:01:00
2025-08-28 13:32:49+08:00,2025-08-28 13:41:18+08:00,721.0,4564.18,4565.88,1225.6999999998689,平多,6c0a64d8-b890-42bc-ae09-152919931d57,5bba77bd-b49f-4c6d-9a12-fe062c687cae,2025-08-28 05:41:00
2025-08-28 13:32:49+08:00,2025-08-28 13:41:18+08:00,155.0,4564.18,4565.88,263.4999999999718,平多,c0e17c5e-6a39-465c-a3b3-347f1af3d772,5bba77bd-b49f-4c6d-9a12-fe062c687cae,2025-08-28 05:41:00
2025-08-28 13:52:44+08:00,2025-08-28 13:57:25+08:00,400.0,4555.2,4559.95,-1900.0,平空,8f641745-890a-4b9c-8d83-10163234429d,dd5f8c6a-74da-4984-aa24-eebfbceb6d22,2025-08-28 05:57:00
2025-08-28 13:52:44+08:00,2025-08-28 13:57:25+08:00,478.0,4555.2,4559.95,-2270.5,平空,66c5bcfb-02ef-4a8c-a314-bd9d672decb5,dd5f8c6a-74da-4984-aa24-eebfbceb6d22,2025-08-28 05:57:00
2025-08-28 14:40:01+08:00,2025-08-28 14:41:47+08:00,874.0,4572.59,4578.98,-5584.859999999491,平空,1b1efa90-7dd5-4b5f-a170-eb87df7fb7db,26b0c5e5-f4a4-4f47-9fdc-12c6ecd05704,2025-08-28 06:41:00
2025-08-28 15:05:18+08:00,2025-08-28 15:07:11+08:00,60.0,4582.63,4577.98,-279.00000000003274,平多,61f7b24d-18b1-44ee-bc9e-60666e4b2346,e53afe94-f3fa-42c1-9e49-619cd77261ab,2025-08-28 07:07:00
2025-08-28 15:05:18+08:00,2025-08-28 15:07:11+08:00,600.0,4582.63,4578.03,-2760.0000000002183,平多,61f7b24d-18b1-44ee-bc9e-60666e4b2346,b9cf7c9c-d909-4dad-ae66-64aa0706566f,2025-08-28 07:07:00
2025-08-28 15:05:18+08:00,2025-08-28 15:07:11+08:00,212.0,4582.63,4577.52,-1083.3199999999306,平多,61f7b24d-18b1-44ee-bc9e-60666e4b2346,05d46d57-d923-4d18-8c18-5a49927ac910,2025-08-28 07:07:00
2025-08-28 15:22:41+08:00,2025-08-28 15:23:11+08:00,600.0,4572.88,4567.91,-2982.000000000153,平多,184c5b21-ed98-43c2-8003-8cc5f8c1bb0a,10d151ec-2891-44fe-8527-89643b3f3b46,2025-08-28 07:23:00
2025-08-28 15:22:41+08:00,2025-08-28 15:23:11+08:00,274.0,4572.88,4567.53,-1465.9000000000997,平多,184c5b21-ed98-43c2-8003-8cc5f8c1bb0a,2a5ef255-f800-4e98-a10c-ca3ed33bb372,2025-08-28 07:23:00
2025-08-28 15:57:55+08:00,2025-08-28 16:02:09+08:00,547.0,4589.48,4607.47,9840.530000000377,平多,6fdd3eb9-13a9-4e2a-90b6-78e7d71f3fbc,81bc2d5e-8099-4d48-b968-d695a7f1fee4,2025-08-28 08:02:00
2025-08-28 15:57:55+08:00,2025-08-28 16:02:09+08:00,324.0,4589.48,4607.47,5828.760000000224,平多,aec18848-d3b5-4786-8c51-a4fdfc454ee2,81bc2d5e-8099-4d48-b968-d695a7f1fee4,2025-08-28 08:02:00
2025-08-28 16:05:54+08:00,2025-08-28 16:09:19+08:00,866.0,4614.86,4624.89,8685.980000000567,平多,8e6d3e81-c813-4759-b608-9ed4e547b24d,25509f73-848d-4620-b662-f7f93d76becc,2025-08-28 08:09:00
2025-08-28 16:09:50+08:00,2025-08-28 16:15:00+08:00,865.0,4621.56,4617.66,-3373.500000000472,平多,29739f4f-b289-4a1e-a5e7-f6925dd72b4c,7e4c74ac-902f-47c5-9e0a-b2ef07f31e8e,2025-08-28 08:15:00
2025-08-28 16:23:59+08:00,2025-08-28 16:28:31+08:00,867.0,4609.17,4602.01,6207.719999999874,平空,6e8dc270-512a-4826-84c9-cfdf82c6cd59,0df8cd52-9db6-4532-99e1-923fcd9c134d,2025-08-28 08:28:00
2025-08-28 16:54:47+08:00,2025-08-28 16:58:41+08:00,870.0,4595.28,4599.69,-3836.6999999998734,平空,35598fc3-567f-4ee2-a9fe-db14aab8228b,9777e233-baa8-4238-8f48-ef3e303ff883,2025-08-28 08:58:00
2025-08-28 17:06:53+08:00,2025-08-28 17:15:11+08:00,870.0,4595.19,4592.66,2201.0999999997784,平空,3432672f-ced3-401f-981d-7686ddd396e6,bf9ffdef-56bd-4d35-9eef-f92a668d5829,2025-08-28 09:15:00
2025-08-28 17:43:59+08:00,2025-08-28 17:49:12+08:00,258.0,4584.79,4581.95,732.7200000000375,平空,c0b26494-b8c4-434e-bc49-e3b317c1fa88,ffbc0ba2-aa7f-4377-bade-cf31e3697b19,2025-08-28 09:49:00
2025-08-28 17:43:59+08:00,2025-08-28 17:49:12+08:00,114.0,4584.79,4581.95,323.7600000000166,平空,6fdb9fc7-e0f4-4033-896b-a13160b4fd18,ffbc0ba2-aa7f-4377-bade-cf31e3697b19,2025-08-28 09:49:00
2025-08-28 17:43:59+08:00,2025-08-28 17:49:12+08:00,500.0,4584.79,4581.95,1420.0000000000728,平空,b064c485-653b-4f88-a0d1-86961284dc70,ffbc0ba2-aa7f-4377-bade-cf31e3697b19,2025-08-28 09:49:00
2025-08-28 17:49:44+08:00,2025-08-28 17:50:54+08:00,500.0,4579.81,4584.85,-2519.999999999982,平空,1f97429c-1de1-467a-8985-8f9bb17000b5,cf389028-3cfb-4521-bf8c-59c3d9782e85,2025-08-28 09:50:00
2025-08-28 17:49:44+08:00,2025-08-28 17:50:54+08:00,139.0,4579.81,4584.85,-700.559999999995,平空,989c44a3-a81f-4939-ab13-d9884d845a65,cf389028-3cfb-4521-bf8c-59c3d9782e85,2025-08-28 09:50:00
2025-08-28 17:49:44+08:00,2025-08-28 17:50:54+08:00,234.0,4579.58,4584.85,-1233.1800000001022,平空,0b83f7ef-0985-4168-a211-d009f6c6ff1a,cf389028-3cfb-4521-bf8c-59c3d9782e85,2025-08-28 09:50:00
2025-08-28 18:36:51+08:00,2025-08-28 18:43:09+08:00,533.0,4609.97,4604.0,-3182.0100000001357,平多,b8391ca4-74b4-41bc-85cd-b4c82cf6e8f3,2926d3da-8a19-4fae-938f-e2556e994376,2025-08-28 10:43:00
2025-08-28 18:36:51+08:00,2025-08-28 18:43:09+08:00,84.0,4610.0,4604.0,-504.0,平多,e441f55d-693a-4301-b6c9-10d54ab10357,2926d3da-8a19-4fae-938f-e2556e994376,2025-08-28 10:43:00
2025-08-28 18:36:51+08:00,2025-08-28 18:43:09+08:00,33.0,4609.97,4604.0,-197.0100000000084,平多,9dbce008-1d12-422c-80f8-a2c928610074,2926d3da-8a19-4fae-938f-e2556e994376,2025-08-28 10:43:00
2025-08-28 19:46:14+08:00,2025-08-28 19:54:40+08:00,654.0,4586.91,4591.36,-2910.299999999881,平空,005b10f4-329d-4d34-8263-b8f63f526ac8,ea07e34c-cd41-4c80-b13f-6b8308257b92,2025-08-28 11:54:00
2025-08-28 20:30:04+08:00,2025-08-28 20:30:34+08:00,517.0,4587.25,4588.6,697.9500000001881,平多,26fe1b1b-f4f0-4c49-b6d0-f8445d4e996e,9011ad7e-ef83-4c62-ac90-3e538965ad3f,2025-08-28 12:30:00
2025-08-28 20:30:05+08:00,2025-08-28 20:30:34+08:00,354.0,4587.44,4588.6,410.64000000027045,平多,32f1db9d-6a9b-413f-abba-3f698a83ec65,9011ad7e-ef83-4c62-ac90-3e538965ad3f,2025-08-28 12:30:00
2025-08-28 20:31:22+08:00,2025-08-28 20:31:28+08:00,400.0,4583.96,4585.9,-775.9999999998399,平空,dd7d8a55-c4bf-4ff8-82b9-ec8591888b0d,ca1e611c-1ba6-4418-9f86-8e492a7726c5,2025-08-28 12:31:00
2025-08-28 20:31:22+08:00,2025-08-28 20:31:29+08:00,472.0,4583.96,4585.9,-915.6799999998111,平空,dd7d8a55-c4bf-4ff8-82b9-ec8591888b0d,04792496-7da0-4a9b-95cf-293b41d8292a,2025-08-28 12:31:00
2025-08-28 20:43:41+08:00,2025-08-28 20:46:26+08:00,92.0,4609.77,4603.6,-567.6400000000067,平多,da034c24-f333-4197-ae9d-7dfa8639be45,9d59670d-a478-4432-8ec0-e3a8c4ec4d8a,2025-08-28 12:46:00
2025-08-28 20:43:41+08:00,2025-08-28 20:46:26+08:00,600.0,4609.77,4603.6,-3702.0000000000437,平多,da034c24-f333-4197-ae9d-7dfa8639be45,e83ff9d3-3078-4f5c-8e6a-fa5750c97b55,2025-08-28 12:46:00
2025-08-28 20:43:41+08:00,2025-08-28 20:46:27+08:00,175.0,4609.77,4604.08,-995.7500000000891,平多,da034c24-f333-4197-ae9d-7dfa8639be45,433dc03b-8b85-4951-9f21-dfaa5d6a0de5,2025-08-28 12:46:00
2025-08-29 09:45:36+08:00,2025-08-29 09:49:22+08:00,447.0,4466.85,4458.15,3888.9000000003252,平空,87d823b2-675d-4501-bb36-b40eef344b7c,28bb7706-f2ce-480e-b606-fc5073ce4153,2025-08-29 01:49:00
2025-08-29 10:13:26+08:00,2025-08-29 10:18:05+08:00,2.0,4470.7,4473.08,4.760000000000218,平多,6d7fe294-0553-46ac-9179-e22446e727dc,b50fd6a4-865b-4cd4-8b83-015dde307912,2025-08-29 02:18:00
2025-08-29 10:13:27+08:00,2025-08-29 10:18:05+08:00,445.0,4470.71,4473.08,1054.6499999999514,平多,3d441a61-f852-4d4d-88d9-a2c4494e3a5f,b50fd6a4-865b-4cd4-8b83-015dde307912,2025-08-29 02:18:00
2025-08-29 10:21:04+08:00,2025-08-29 10:25:10+08:00,446.0,4479.68,4483.07,1511.9399999997404,平多,9ac71ec9-58a8-43af-83ca-cac772d44dce,7db1d0e0-cdda-45a4-af09-9ec2f6a830a5,2025-08-29 02:25:00
2025-08-29 11:08:08+08:00,2025-08-29 11:10:24+08:00,446.0,4477.82,4481.35,1574.380000000292,平多,4c447405-283c-40f7-bc05-42ae2aeaaaeb,de3c12d5-ba88-4b3d-8e8a-2158228465cb,2025-08-29 03:10:00
2025-08-29 11:25:26+08:00,2025-08-29 11:31:14+08:00,446.0,4478.16,4482.39,1886.580000000211,平多,877eb021-8a47-4d55-8efd-789fde87699c,33addd17-0151-418d-b11e-d68a26c179e6,2025-08-29 03:31:00
2025-08-29 11:35:59+08:00,2025-08-29 11:43:49+08:00,446.0,4484.05,4494.74,4767.7399999998215,平多,913408fa-2541-48c8-a8a0-d352b8b74a93,a7fd376e-dd1c-4350-8c58-1913d130902c,2025-08-29 03:43:00
2025-08-29 11:55:41+08:00,2025-08-29 12:00:52+08:00,444.0,4498.11,4489.03,4031.5199999999677,平空,6450e48b-f901-4907-b065-18e073f86534,7cfe2e33-9b17-4785-9e45-dd5654c483c2,2025-08-29 04:00:00
2025-08-29 12:54:59+08:00,2025-08-29 12:58:10+08:00,670.0,4477.15,4471.43,3832.3999999995613,平空,13bb04ff-529a-48f4-a062-bdbda01abe9a,01a6ebd4-6c63-4e58-9f52-4317a83a6c27,2025-08-29 04:58:00
2025-08-29 13:05:31+08:00,2025-08-29 13:06:05+08:00,671.0,4466.57,4472.34,-3871.670000000293,平空,5c439227-9432-48c1-8c70-184e65586599,398e954e-0534-4f4c-bdda-5d14d858afae,2025-08-29 05:06:00
2025-08-29 13:17:39+08:00,2025-08-29 13:19:35+08:00,448.0,4461.42,4468.3,-3082.240000000049,平空,d770f2c0-6aed-4bc2-bee2-f98209775454,14ce65ce-8af2-4c07-8441-bdeea724197e,2025-08-29 05:19:00
2025-08-29 13:59:25+08:00,2025-08-29 14:01:39+08:00,46.0,4476.01,4484.33,382.7199999999866,平多,1f80cf00-8910-42af-a7ac-dd2199579d04,96e160f6-0a35-4ac4-9f3e-295065a56092,2025-08-29 06:01:00
2025-08-29 13:59:25+08:00,2025-08-29 14:01:39+08:00,400.0,4476.01,4484.33,3327.9999999998836,平多,1f80cf00-8910-42af-a7ac-dd2199579d04,db2ea541-8ece-4876-baa0-f803629d4675,2025-08-29 06:01:00
2025-08-29 14:15:38+08:00,2025-08-29 14:18:12+08:00,448.0,4457.41,4451.26,2755.199999999837,平空,2616d754-2ae8-43c0-a382-46901e0dba21,913e0886-23e4-467d-932d-79e960df2947,2025-08-29 06:18:00
2025-08-29 14:37:31+08:00,2025-08-29 14:39:31+08:00,449.0,4451.44,4451.34,-44.89999999975498,平多,9f225f1e-cdc5-42cc-8c22-6d39f68da6d6,db5c616d-faf7-4183-8e46-b95f09dbad99,2025-08-29 06:39:00
2025-08-29 14:41:21+08:00,2025-08-29 14:44:17+08:00,449.0,4451.53,4455.7,1872.3300000000327,平多,5ba24885-5747-405a-8fa9-6a9749dbe6b4,f7e02df2-857b-4e3a-a6aa-c0d7362cb5bb,2025-08-29 06:44:00
2025-08-29 15:01:14+08:00,2025-08-29 15:02:16+08:00,449.0,4448.83,4428.34,9200.009999999902,平空,a605bd22-e12e-44a4-9e1c-87c145bc5aa4,365ff72f-891a-4314-a005-d320d2074d5f,2025-08-29 07:02:00
2025-08-29 15:12:00+08:00,2025-08-29 15:15:04+08:00,453.0,4412.37,4393.89,8371.439999999802,平空,03169227-80cc-4c41-89e5-7cbc59174c90,7939f969-7566-453d-a718-dfa6b96ee987,2025-08-29 07:15:00
2025-08-29 15:44:10+08:00,2025-08-29 15:51:01+08:00,683.0,4387.22,4391.19,-2711.5099999995527,平空,e2151c19-3f56-4239-8368-77af88a0c2c1,f90b5024-cd5b-44d5-a140-4d6253d49d6a,2025-08-29 07:51:00
2025-08-29 15:57:12+08:00,2025-08-29 16:00:46+08:00,400.0,4383.78,4387.09,-1324.00000000016,平空,f2affaff-2beb-481f-b346-c9453422f536,70cc7f5d-b472-40a1-b00b-7e4b032722fc,2025-08-29 08:00:00
2025-08-29 15:57:12+08:00,2025-08-29 16:00:46+08:00,284.0,4383.78,4387.09,-940.0400000001137,平空,f2affaff-2beb-481f-b346-c9453422f536,676c76cd-7afa-40db-a0a7-89004bb9387b,2025-08-29 08:00:00
2025-08-29 16:08:15+08:00,2025-08-29 16:11:24+08:00,383.0,4386.41,4376.76,3695.9499999998607,平空,da4365c6-5bed-4bff-824c-580b3be527bc,0fdf84b4-d9bd-419e-8fd0-037e8631eefd,2025-08-29 08:11:00
2025-08-29 16:08:15+08:00,2025-08-29 16:11:24+08:00,300.0,4386.5,4376.76,2921.9999999999345,平空,940d2d22-8103-4bdd-8eaa-ade1277111da,0fdf84b4-d9bd-419e-8fd0-037e8631eefd,2025-08-29 08:11:00
2025-08-29 16:17:21+08:00,2025-08-29 16:17:29+08:00,187.0,4364.59,4365.41,-153.33999999994558,平空,89b93201-dfd2-408c-a5de-b6ecd72424cd,db922d70-7a90-4cf4-9a17-a598fe213f8b,2025-08-29 08:17:00
2025-08-29 16:17:21+08:00,2025-08-29 16:17:29+08:00,400.0,4364.59,4365.41,-327.9999999998836,平空,89b93201-dfd2-408c-a5de-b6ecd72424cd,574a0e60-b26e-46bf-a696-cae5868b7af2,2025-08-29 08:17:00
2025-08-29 16:17:21+08:00,2025-08-29 16:17:29+08:00,100.0,4365.0,4365.41,-40.99999999998545,平空,e6be51d9-e746-45dd-8522-877cf7eafd33,574a0e60-b26e-46bf-a696-cae5868b7af2,2025-08-29 08:17:00
2025-08-29 16:20:18+08:00,2025-08-29 16:20:36+08:00,688.0,4359.92,4362.29,-1630.559999999925,平空,d302895c-7318-4851-838d-396e7100fc09,719a6eff-a759-4947-8f0a-45f2ac94dfc4,2025-08-29 08:20:00
2025-08-29 16:29:12+08:00,2025-08-29 16:33:21+08:00,527.0,4355.55,4362.63,3731.1599999999617,平多,f587dcce-e557-4b34-a55f-bf449234faca,e833feb6-8ba7-4fa5-adea-678f690e16b3,2025-08-29 08:33:00
2025-08-29 16:29:12+08:00,2025-08-29 16:33:21+08:00,161.0,4355.55,4362.63,1139.8799999999883,平多,22c48502-01b1-4efd-9809-3bc8487b0a9b,e833feb6-8ba7-4fa5-adea-678f690e16b3,2025-08-29 08:33:00
2025-08-29 16:37:39+08:00,2025-08-29 16:40:08+08:00,688.0,4356.21,4352.88,2291.03999999995,平空,b209c4ae-8c33-4ba5-ad48-7559d1eafc6a,f7b8931f-1568-4387-a132-8ac6f7f34891,2025-08-29 08:40:00
2025-08-29 16:40:40+08:00,2025-08-29 16:41:12+08:00,140.0,4348.53,4353.19,-652.3999999999796,平空,9f88809c-8f0c-4dd4-b83c-552c6b78da3a,b2c3aa90-dcc1-469d-bf31-6c74b8e4099b,2025-08-29 08:41:00
2025-08-29 16:40:40+08:00,2025-08-29 16:41:12+08:00,549.0,4348.53,4353.19,-2558.33999999992,平空,3efb68fb-7389-44fd-b48a-d749af57e70f,b2c3aa90-dcc1-469d-bf31-6c74b8e4099b,2025-08-29 08:41:00
2025-08-29 18:24:56+08:00,2025-08-29 18:28:40+08:00,500.0,4354.11,4357.4,1644.9999999999818,平多,5b3555c7-8c22-45ad-a4b5-ef6b586335d5,88db631a-7f3b-4b85-9887-94f906259583,2025-08-29 10:28:00
2025-08-29 18:24:56+08:00,2025-08-29 18:28:40+08:00,189.0,4354.11,4357.4,621.8099999999931,平多,f6c1a4f1-6aa0-4645-b991-503a320913be,6132d1a3-6d55-4517-b5ba-115198948b85,2025-08-29 10:28:00
2025-08-29 18:30:45+08:00,2025-08-29 18:49:35+08:00,189.0,4351.51,4343.72,1472.3099999999931,平空,b67b7a3a-cf62-4731-bc9c-1d333f42e639,2d4f2adb-d806-4f37-8ff1-a46eddccc6b1,2025-08-29 10:49:00
2025-08-29 18:30:45+08:00,2025-08-29 18:49:35+08:00,500.0,4351.51,4343.72,3894.999999999982,平空,0acabab2-2ab4-4921-82a0-df806d4eb40d,2d4f2adb-d806-4f37-8ff1-a46eddccc6b1,2025-08-29 10:49:00
2025-08-29 18:58:56+08:00,2025-08-29 19:02:25+08:00,690.0,4345.89,4340.99,-3381.0000000003765,平多,b525febe-c7eb-4db9-a4f8-4a09406c9f7d,51ddc961-238a-4c9d-b985-e6ad6ef2aac7,2025-08-29 11:02:00
2025-08-29 19:14:13+08:00,2025-08-29 19:18:33+08:00,689.0,4351.49,4346.64,-3341.649999999624,平多,da8dccbd-f79c-476b-9471-d28b719da66f,cfbfe97f-e085-41db-8679-58574bd165fd,2025-08-29 11:18:00
2025-08-29 19:49:41+08:00,2025-08-29 19:51:55+08:00,690.0,4345.68,4340.66,-3463.800000000301,平多,98c03fb1-dca8-43ef-9ca7-0fe6d842946b,e0c7b8be-c842-412e-bb4f-e43b51fa53bb,2025-08-29 11:51:00
2025-08-29 20:22:08+08:00,2025-08-29 20:30:35+08:00,687.0,4365.85,4411.23,31176.059999999452,平多,7ab49fe4-9bd7-4368-bb45-ffe9970e4999,c3d6e447-288e-48d1-8977-ccceda6a2e41,2025-08-29 12:30:00
2025-08-29 20:31:05+08:00,2025-08-29 20:31:21+08:00,16.0,4439.0,4448.35,149.60000000000582,平多,76a58764-fd12-4fb4-8ee9-407aa2213a12,e3f58dbc-6a93-4c16-9dc3-7e351493f00f,2025-08-29 12:31:00
2025-08-29 20:31:05+08:00,2025-08-29 20:31:21+08:00,659.0,4439.0,4448.35,6161.65000000024,平多,cdd4a741-4195-4fac-9896-35ee5c09a7b9,e3f58dbc-6a93-4c16-9dc3-7e351493f00f,2025-08-29 12:31:00
2025-08-29 20:31:46+08:00,2025-08-29 20:33:05+08:00,180.0,4409.9,4406.3,-647.9999999999018,平多,a47f68a7-9565-4ea7-b3ab-770d376ffcea,46e071a8-871b-4373-92a5-8cd6cd46cc56,2025-08-29 12:33:00
2025-08-29 20:31:46+08:00,2025-08-29 20:33:05+08:00,500.0,4409.9,4406.3,-1799.9999999997272,平多,a47f68a7-9565-4ea7-b3ab-770d376ffcea,c67209e2-0598-443d-85fa-752bdae6059b,2025-08-29 12:33:00
2025-08-29 20:43:25+08:00,2025-08-29 20:44:07+08:00,684.0,4382.62,4386.13,-2400.8400000001493,平空,af3305f0-ec39-48fe-bf71-ac9acb281b25,7556c209-5046-4e8b-8682-99dc36803a62,2025-08-29 12:44:00
2025-08-29 20:45:44+08:00,2025-08-29 20:49:11+08:00,102.0,4389.13,4407.06,1828.8600000000297,平多,a19435e4-fbf9-4217-bc5d-d7fc07d9818f,cc0577e9-e4b6-45fd-bf5a-47ccf6aec320,2025-08-29 12:49:00
2025-08-29 20:45:44+08:00,2025-08-29 20:49:11+08:00,581.0,4389.13,4407.06,10417.33000000017,平多,a19435e4-fbf9-4217-bc5d-d7fc07d9818f,4fa96e6c-6692-426b-beca-c138c8505a82,2025-08-29 12:49:00
2025-08-29 20:49:46+08:00,2025-08-29 20:53:14+08:00,500.0,4406.49,4406.02,234.99999999967258,平空,d11f3a55-a1d8-41ff-a979-778c232459c9,b2de5ff9-9281-4c2e-86bd-a071a5e1e864,2025-08-29 12:53:00
2025-08-29 20:49:46+08:00,2025-08-29 20:53:14+08:00,180.0,4406.49,4406.02,84.59999999988213,平空,d11f3a55-a1d8-41ff-a979-778c232459c9,a4e3c4e5-4280-417c-8018-8386a63c318a,2025-08-29 12:53:00
2025-08-29 21:00:24+08:00,2025-08-29 21:00:33+08:00,680.0,4408.35,4405.11,-2203.20000000047,平多,26e94954-9b31-48a9-9b2b-cb08da0f8e3e,14772435-8e33-4ee5-a87c-81342a7f8449,2025-08-29 13:00:00
2025-08-29 21:01:47+08:00,2025-08-29 21:06:54+08:00,39.0,4406.15,4391.41,574.8599999999915,平空,8665f24a-3e13-4d3f-ad28-a702c79c73ed,7addab21-fcf3-4921-97ab-d77462067550,2025-08-29 13:06:00
2025-08-29 21:01:47+08:00,2025-08-29 21:06:54+08:00,141.0,4406.15,4391.41,2078.339999999969,平空,0170663d-0cf1-43a4-8595-4511c59b3107,7addab21-fcf3-4921-97ab-d77462067550,2025-08-29 13:06:00
2025-08-29 21:01:47+08:00,2025-08-29 21:06:54+08:00,500.0,4406.15,4391.41,7369.999999999891,平空,0170663d-0cf1-43a4-8595-4511c59b3107,3b754022-7c7c-4b14-8251-c2da4478df27,2025-08-29 13:06:00
2025-08-29 21:10:41+08:00,2025-08-29 21:11:27+08:00,14.0,4400.55,4392.88,-107.38000000000102,平多,37e79409-f3ed-4e62-811c-6cc437396a41,f3a43d61-4d64-4d82-aada-31b38d441baa,2025-08-29 13:11:00
2025-08-29 21:10:41+08:00,2025-08-29 21:11:27+08:00,67.0,4400.55,4392.79,-519.9200000000146,平多,37e79409-f3ed-4e62-811c-6cc437396a41,86bfa728-af41-4e41-9e87-d6ef88b1a063,2025-08-29 13:11:00
2025-08-29 21:10:41+08:00,2025-08-29 21:11:27+08:00,600.0,4400.55,4392.88,-4602.000000000044,平多,37e79409-f3ed-4e62-811c-6cc437396a41,af01f0d0-8844-4267-8476-4000d0b2dd8b,2025-08-29 13:11:00
2025-08-29 21:30:11+08:00,2025-08-29 21:34:27+08:00,72.0,4386.05,4373.6,896.3999999999869,平空,fecb81e1-3b36-4ae6-91ad-b6a2616ee608,aee7c322-ba5d-4b89-8b93-1c50ce5be75b,2025-08-29 13:34:00
2025-08-29 21:30:11+08:00,2025-08-29 21:34:27+08:00,211.0,4386.05,4372.44,2871.710000000123,平空,fecb81e1-3b36-4ae6-91ad-b6a2616ee608,e20951ed-ff4e-4a06-8bb5-8112a72e38bf,2025-08-29 13:34:00
2025-08-29 21:30:11+08:00,2025-08-29 21:34:27+08:00,99.0,4386.05,4372.44,1347.3900000000576,平空,fecb81e1-3b36-4ae6-91ad-b6a2616ee608,16329965-69b4-42a4-8145-79d1a0d2e92b,2025-08-29 13:34:00
2025-08-29 21:30:11+08:00,2025-08-29 21:34:27+08:00,101.0,4386.29,4372.44,1398.8500000000367,平空,f1e4b54c-d392-4dc4-8f73-40a8733b85fe,16329965-69b4-42a4-8145-79d1a0d2e92b,2025-08-29 13:34:00
2025-08-29 21:30:11+08:00,2025-08-29 21:34:27+08:00,200.0,4386.29,4372.44,2770.0000000000728,平空,f1e4b54c-d392-4dc4-8f73-40a8733b85fe,1b66a876-041a-480e-a9d6-428a3e301ec4,2025-08-29 13:34:00
2025-08-30 08:15:30+08:00,2025-08-30 08:25:24+08:00,400.0,4343.62,4355.47,4740.0000000001455,平多,fb636839-9fb2-4e2f-bdb0-14bd57ade58a,6b8d4b73-132c-4c86-92f9-2a5df18943fd,2025-08-30 00:25:00
2025-08-30 08:15:30+08:00,2025-08-30 08:25:24+08:00,290.0,4343.62,4355.47,3436.5000000001055,平多,fb636839-9fb2-4e2f-bdb0-14bd57ade58a,a744bd39-3c81-4cb1-a153-60ed71d6748f,2025-08-30 00:25:00
2025-08-30 08:32:12+08:00,2025-08-30 08:35:26+08:00,64.0,4342.48,4337.98,-288.0,平多,e6185c1c-debd-4a9c-928c-edd28b360578,401ccb35-f82c-4df2-9a29-f9cd57481767,2025-08-30 00:35:00
2025-08-30 08:32:12+08:00,2025-08-30 08:35:26+08:00,563.0,4342.48,4335.64,-3850.91999999957,平多,e6185c1c-debd-4a9c-928c-edd28b360578,69d6c400-d534-47b6-b2a8-8da09b2986aa,2025-08-30 00:35:00
2025-08-30 08:32:12+08:00,2025-08-30 08:35:26+08:00,63.0,4342.48,4335.73,-425.25,平多,e6185c1c-debd-4a9c-928c-edd28b360578,4aa4a001-f8b0-4aea-93c3-546c71b81ee0,2025-08-30 00:35:00
2025-08-30 08:37:25+08:00,2025-08-30 08:41:59+08:00,691.0,4336.85,4332.05,3316.8000000001257,平空,5cc6dd95-ec96-4864-a085-95b875673f0f,07f9b455-a026-41df-95c6-f9cf37f23a90,2025-08-30 00:41:00
2025-08-30 09:26:28+08:00,2025-08-30 09:29:48+08:00,293.0,4326.54,4324.64,556.6999999998934,平空,ce7db548-7de1-448e-92c9-25139a5f23a4,70062cb1-9074-49a9-8e7f-b5b7bae639d4,2025-08-30 01:29:00
2025-08-30 09:26:28+08:00,2025-08-30 09:29:48+08:00,400.0,4326.54,4323.46,1231.999999999971,平空,ce7db548-7de1-448e-92c9-25139a5f23a4,6145a0a3-248c-4822-8e8c-5efb6daf7d24,2025-08-30 01:29:00
2025-08-30 09:51:41+08:00,2025-08-30 09:55:09+08:00,177.0,4312.57,4289.19,4138.260000000019,平空,4b786a41-410d-4c93-b1c6-30b118f9e7f2,f78be76a-092e-4e0e-b8c3-26867d78c1de,2025-08-30 01:55:00
2025-08-30 09:51:41+08:00,2025-08-30 09:55:09+08:00,518.0,4312.57,4289.19,12110.840000000057,平空,96fbc46a-1dd3-4fc6-9e14-4a032e9464bf,f78be76a-092e-4e0e-b8c3-26867d78c1de,2025-08-30 01:55:00
2025-08-30 09:55:49+08:00,2025-08-30 09:55:50+08:00,700.0,4282.58,4282.19,-273.0000000002292,平多,201dbee0-8f0d-427d-95d5-ef84e08a8aab,37ff5d0c-e10e-480c-91ca-0506e61330b6,2025-08-30 01:55:00
2025-08-30 09:58:19+08:00,2025-08-30 09:58:59+08:00,700.0,4281.59,4280.23,-952.0000000004075,平多,0e651112-db3b-402d-a268-1ea200cf8729,65b07548-3473-4570-be22-0172c49bdb94,2025-08-30 01:58:00
2025-08-30 10:00:09+08:00,2025-08-30 10:00:52+08:00,703.0,4264.04,4268.35,-3029.9300000002813,平空,d9703fdd-ea02-410d-8303-d1d13b94748f,17fca37e-fc89-48a9-92ed-671ab0b9088e,2025-08-30 02:00:00
2025-08-30 10:01:23+08:00,2025-08-30 10:02:02+08:00,110.0,4268.54,4271.97,-377.300000000032,平空,022ce461-b78f-4127-9157-8c34a5e9272e,89468587-89ce-49cc-a9e3-343e24cb8036,2025-08-30 02:02:00
2025-08-30 10:01:23+08:00,2025-08-30 10:02:02+08:00,592.0,4268.54,4271.97,-2030.5600000001723,平空,9bdcfab5-9b8e-447c-b4ac-a82724e2774d,89468587-89ce-49cc-a9e3-343e24cb8036,2025-08-30 02:02:00
2025-08-30 10:02:55+08:00,2025-08-30 10:04:26+08:00,400.0,4275.14,4280.56,-2168.000000000029,平空,1b938bf4-dc99-4d2f-9e0b-c2fa5092d19d,4e6c40d8-e7c7-45ac-800e-5f71611479f1,2025-08-30 02:04:00
2025-08-30 10:02:55+08:00,2025-08-30 10:04:26+08:00,141.0,4275.14,4280.56,-764.2200000000103,平空,1b938bf4-dc99-4d2f-9e0b-c2fa5092d19d,864390a3-33dd-4a47-a3c2-471b8a0104f1,2025-08-30 02:04:00
2025-08-30 10:02:55+08:00,2025-08-30 10:04:26+08:00,160.0,4275.14,4280.56,-867.2000000000116,平空,7eb3eaf4-30fa-495d-a74c-61d725625c42,864390a3-33dd-4a47-a3c2-471b8a0104f1,2025-08-30 02:04:00
2025-08-30 10:11:35+08:00,2025-08-30 10:18:43+08:00,232.0,4296.88,4306.91,2326.959999999941,平多,b1a002d6-951f-4912-b8cf-19bfc98f61ba,743a1e0f-48f3-43fe-9b6a-47536fa12ce1,2025-08-30 02:18:00
2025-08-30 10:11:35+08:00,2025-08-30 10:18:43+08:00,466.0,4296.91,4306.91,4660.0,平多,94664c85-6be6-42d8-984a-f3293ed9750f,743a1e0f-48f3-43fe-9b6a-47536fa12ce1,2025-08-30 02:18:00
2025-08-30 10:21:54+08:00,2025-08-30 10:27:07+08:00,696.0,4307.47,4306.32,800.4000000003798,平空,641e7574-db24-4c78-8782-566b13de1e39,817cbe73-8f5f-4c27-893c-ddfe59e1890d,2025-08-30 02:27:00
2025-08-30 10:28:32+08:00,2025-08-30 10:35:18+08:00,500.0,4305.75,4311.46,2855.000000000018,平多,dee31b34-3e7f-4b74-8774-ccd70f3cb124,d37eec35-4b90-42c7-82e7-7a56e909d268,2025-08-30 02:35:00
2025-08-30 10:28:32+08:00,2025-08-30 10:35:18+08:00,196.0,4305.75,4311.25,1078.0,平多,dee31b34-3e7f-4b74-8774-ccd70f3cb124,9cbf242a-7e93-4a3c-b798-6e3f7a88025d,2025-08-30 02:35:00
2025-08-30 10:48:32+08:00,2025-08-30 10:57:53+08:00,695.0,4313.05,4303.81,6421.799999999848,平空,0efcab97-a0b6-4cd6-ad7e-22911ea32fa2,57fa177a-12c5-4127-91c4-289668a191ae,2025-08-30 02:57:00
2025-08-30 11:03:45+08:00,2025-08-30 11:10:25+08:00,296.0,4308.11,4322.99,4404.480000000032,平多,36e3b573-d4be-4d54-9af3-8190731448c9,1e9213a7-3443-4209-a26a-d3e0feeaf325,2025-08-30 03:10:00
2025-08-30 11:03:45+08:00,2025-08-30 11:10:25+08:00,400.0,4308.11,4322.99,5952.000000000044,平多,36e3b573-d4be-4d54-9af3-8190731448c9,a344d092-7b22-4230-8ba9-0702dd353041,2025-08-30 03:10:00
2025-08-30 11:11:04+08:00,2025-08-30 11:17:45+08:00,693.0,4323.24,4328.87,3901.5900000000756,平多,c2e861bb-6de2-4dc0-aed3-7a385c0f34b8,d786c18b-8199-4335-ad6b-6115f39e089f,2025-08-30 03:17:00
2025-08-30 11:18:36+08:00,2025-08-30 11:23:02+08:00,400.0,4333.76,4358.0,9695.999999999913,平多,3c5242f4-5844-46a7-8b84-a6c73fed27c7,d71ce99c-8d8e-4f15-be2e-85d21e853298,2025-08-30 03:23:00
2025-08-30 11:18:36+08:00,2025-08-30 11:23:02+08:00,134.0,4333.76,4358.0,3248.1599999999708,平多,3c5242f4-5844-46a7-8b84-a6c73fed27c7,fe3607bd-9257-42ce-a0b3-06d882cb74af,2025-08-30 03:23:00
2025-08-30 11:18:36+08:00,2025-08-30 11:23:02+08:00,158.0,4333.76,4358.0,3829.9199999999655,平多,ce9f82f0-70a9-44b1-9175-4ee31dbc8fd6,fe3607bd-9257-42ce-a0b3-06d882cb74af,2025-08-30 03:23:00
2025-08-30 11:52:34+08:00,2025-08-30 11:57:42+08:00,69.0,4352.62,4352.32,-20.70000000001255,平多,a7a38452-b2e4-46c1-a14c-d85c0a79b250,078499df-67ff-4bdd-acaf-4e4fcf4457c0,2025-08-30 03:57:00
2025-08-30 11:52:34+08:00,2025-08-30 11:57:42+08:00,620.0,4352.62,4352.32,-186.00000000011278,平多,76c6328b-ae56-4313-9b73-3bc43f644ef4,078499df-67ff-4bdd-acaf-4e4fcf4457c0,2025-08-30 03:57:00
2025-08-30 12:01:25+08:00,2025-08-30 12:07:56+08:00,500.0,4351.41,4357.44,-3014.9999999998727,平空,2228c2d3-6d7b-4835-8065-42ce6ad3a5af,3544a077-b511-45ef-b088-c380928048ee,2025-08-30 04:07:00
2025-08-30 12:01:25+08:00,2025-08-30 12:07:56+08:00,121.0,4351.7,4357.44,-694.5399999999736,平空,e33d8985-328c-4a44-829e-b8ebf6127582,3544a077-b511-45ef-b088-c380928048ee,2025-08-30 04:07:00
2025-08-30 12:01:25+08:00,2025-08-30 12:07:56+08:00,527.0,4351.41,4357.44,-3177.809999999866,平空,6f169ccd-3d5a-4e35-9653-7efd0a1580dc,3544a077-b511-45ef-b088-c380928048ee,2025-08-30 04:07:00
2025-08-30 13:01:32+08:00,2025-08-30 13:07:24+08:00,577.0,4353.26,4358.47,-3006.170000000021,平空,27412351-b7db-41d2-941e-014723b46c1a,f65cc5f5-8a78-4a59-bb58-cf0af4df8448,2025-08-30 05:07:00
2025-08-30 13:01:33+08:00,2025-08-30 13:07:24+08:00,298.0,4353.26,4358.47,-1552.5800000000108,平空,cab58243-ce8d-4149-b279-3417eac36fcd,f65cc5f5-8a78-4a59-bb58-cf0af4df8448,2025-08-30 05:07:00
2025-08-30 13:01:33+08:00,2025-08-30 13:07:24+08:00,273.0,4353.26,4359.1,-1594.3200000000397,平空,cab58243-ce8d-4149-b279-3417eac36fcd,c28367f5-fcb9-4345-82f2-c56451e2e462,2025-08-30 05:07:00
2025-08-30 13:20:13+08:00,2025-08-30 13:32:38+08:00,1143.0,4373.03,4377.0,-4537.710000000291,平空,0f73205b-a08a-4fad-9e77-f5d2fbbf1aee,6d5e0a1c-53e6-4fac-a76a-77cb3341a976,2025-08-30 05:32:00
2025-08-30 13:33:46+08:00,2025-08-30 13:42:14+08:00,1140.0,4385.31,4391.97,7592.399999999834,平多,11f0898c-7cba-49da-91d9-1fc6e9b57ab2,e7744350-f030-4566-bdeb-8a76060f8066,2025-08-30 05:42:00
2025-08-30 13:48:01+08:00,2025-08-30 13:56:36+08:00,1137.0,4395.74,4382.93,14564.96999999942,平空,d00ac585-7cde-477d-af47-a5889aa5ef70,e99ef7df-85e7-46b4-bc8a-4a6f2fc811fe,2025-08-30 05:56:00
2025-08-30 13:58:04+08:00,2025-08-30 14:03:08+08:00,1141.0,4381.43,4385.01,-4084.779999999917,平空,76216a51-657b-4659-86cb-2295aa642dac,8a9ab27e-38f2-4ec3-bbaf-642afd20a6e5,2025-08-30 06:03:00
2025-08-30 14:10:44+08:00,2025-08-30 14:15:13+08:00,601.0,4383.15,4377.63,3317.5199999997158,平空,587020d7-a3eb-4e44-b6c7-5c95b8c5451a,8ecfa693-c528-405b-8db4-0b02ccc7b9b3,2025-08-30 06:15:00
2025-08-30 14:10:44+08:00,2025-08-30 14:15:13+08:00,500.0,4383.15,4377.63,2759.9999999997635,平空,587020d7-a3eb-4e44-b6c7-5c95b8c5451a,babe1585-607c-4004-9aa9-19e1f5374ac1,2025-08-30 06:15:00
2025-08-30 14:10:44+08:00,2025-08-30 14:15:13+08:00,39.0,4383.15,4377.63,215.27999999998156,平空,587020d7-a3eb-4e44-b6c7-5c95b8c5451a,ab4e9d81-4133-42b0-9460-9a2efd36ec0b,2025-08-30 06:15:00
2025-08-30 14:26:36+08:00,2025-08-30 14:33:14+08:00,1140.0,4384.3,4391.39,8082.600000000166,平多,f703a5cc-3428-4796-a288-bfa6442800cb,a4e60efd-9afc-48b1-8850-6054e1330780,2025-08-30 06:33:00
2025-08-30 14:45:13+08:00,2025-08-30 14:52:41+08:00,1137.0,4395.22,4390.35,5537.189999999876,平空,b1f16517-7b15-43a4-a3e7-8f0b60f9f732,0445e9e3-c80c-4beb-a121-18b6094f52eb,2025-08-30 06:52:00
2025-08-30 15:20:15+08:00,2025-08-30 15:40:40+08:00,52.0,4392.17,4398.92,-351.0,平空,504ad303-3016-470e-9deb-a717d25a761c,9a648f36-ef00-45a4-8e56-868ab74acce6,2025-08-30 07:40:00
2025-08-30 15:20:15+08:00,2025-08-30 15:40:40+08:00,500.0,4392.17,4398.92,-3375.0,平空,59f674e3-aff1-4b79-b8b0-c650b299d27d,9a648f36-ef00-45a4-8e56-868ab74acce6,2025-08-30 07:40:00
2025-08-30 15:20:15+08:00,2025-08-30 15:40:40+08:00,586.0,4392.17,4398.92,-3955.5,平空,77548f6a-59ae-4ac2-880c-ea1f5679f507,9a648f36-ef00-45a4-8e56-868ab74acce6,2025-08-30 07:40:00
2025-08-30 15:46:04+08:00,2025-08-30 15:50:09+08:00,1134.0,4408.51,4402.78,-6497.820000000536,平多,76eb4bce-ff36-4d4c-b97a-cda6d9f7b544,63f7184c-7211-417f-b594-e39436d14940,2025-08-30 07:50:00
2025-08-30 16:11:35+08:00,2025-08-30 16:32:13+08:00,400.0,4393.35,4389.12,1692.0000000001892,平空,be9ff2ce-0d9e-4184-8d43-c49b33c71c95,754db465-b458-43a3-b2b5-3fb4f9fc2aaf,2025-08-30 08:32:00
2025-08-30 16:11:35+08:00,2025-08-30 16:32:13+08:00,500.0,4393.35,4389.12,2115.0000000002365,平空,cdf388db-68a2-47ea-ba94-431f02dadeac,754db465-b458-43a3-b2b5-3fb4f9fc2aaf,2025-08-30 08:32:00
2025-08-30 16:11:35+08:00,2025-08-30 16:32:13+08:00,237.0,4393.35,4389.12,1002.5100000001121,平空,e6f8d379-c20f-4a9d-90a4-7a5904bff1f9,754db465-b458-43a3-b2b5-3fb4f9fc2aaf,2025-08-30 08:32:00
2025-08-30 17:05:10+08:00,2025-08-30 17:11:26+08:00,133.0,4390.54,4387.01,469.48999999996613,平空,d4db2208-ba63-42c7-af51-9cec92bfe6f1,46858333-121c-4020-9567-bc44d63dec01,2025-08-30 09:11:00
2025-08-30 17:05:10+08:00,2025-08-30 17:11:26+08:00,190.0,4390.54,4387.01,670.6999999999516,平空,d4db2208-ba63-42c7-af51-9cec92bfe6f1,4d19376a-cfb7-4da9-8859-982e073624d1,2025-08-30 09:11:00
2025-08-30 17:05:10+08:00,2025-08-30 17:11:26+08:00,310.0,4390.54,4387.01,1094.299999999921,平空,00dda8f5-7156-4d25-9ea0-29e5fb2a4aca,4d19376a-cfb7-4da9-8859-982e073624d1,2025-08-30 09:11:00
2025-08-30 17:05:10+08:00,2025-08-30 17:11:26+08:00,505.0,4390.54,4387.01,1782.6499999998714,平空,00dda8f5-7156-4d25-9ea0-29e5fb2a4aca,e28b9838-7c48-4c78-a369-8259844cc3f4,2025-08-30 09:11:00
2025-08-30 17:18:39+08:00,2025-08-30 17:28:37+08:00,1139.0,4389.73,4385.08,-5296.349999999586,平多,2789c169-8a5d-47da-a6f9-6800e72ec26e,cd9481fb-33de-4e75-beb8-119ace92b5f6,2025-08-30 09:28:00
2025-08-30 17:31:17+08:00,2025-08-30 17:37:08+08:00,1141.0,4379.77,4384.13,-4974.759999999626,平空,434fc13a-925d-4abd-8677-0cd2b1a412f0,1e63ca1f-7f77-4ed9-a885-159f5dac641e,2025-08-30 09:37:00
2025-08-30 17:44:10+08:00,2025-08-30 17:48:40+08:00,1140.0,4384.13,4388.17,-4605.5999999999585,平空,288b4dc7-affd-4b36-897a-e02a024dbae0,70c0e310-219d-45d2-a91d-6b685af4a065,2025-08-30 09:48:00
2025-08-30 17:50:34+08:00,2025-08-30 17:54:02+08:00,1138.0,4389.94,4393.0,3482.2800000004554,平多,b78acf6a-d3b3-44c2-b484-ad95dfedd167,9473c228-7657-44cd-9038-38aeb833c3ab,2025-08-30 09:54:00
2025-08-30 18:05:09+08:00,2025-08-30 18:07:30+08:00,1138.0,4392.24,4394.52,2594.640000000745,平多,44cd4f02-5250-47d0-8e71-a66f856405ba,81abc1fa-1789-4f69-aaaa-2da1f3f34186,2025-08-30 10:07:00
2025-08-31 10:28:55+08:00,2025-08-31 10:34:47+08:00,326.0,4450.3,4446.25,-1320.3000000000593,平多,0fe00795-d7d9-4586-b864-e445017c7f9d,716e265c-d39a-46b3-92e2-99f5d8a6b45f,2025-08-31 02:34:00
2025-08-31 10:28:55+08:00,2025-08-31 10:34:47+08:00,572.0,4450.3,4446.25,-2316.600000000104,平多,0fe00795-d7d9-4586-b864-e445017c7f9d,e7b360d6-da94-4cb7-b8c7-0b10db53a03b,2025-08-31 02:34:00
2025-08-31 11:08:10+08:00,2025-08-31 11:12:01+08:00,897.0,4454.6,4458.68,-3659.7599999999347,平空,c31d66e2-a558-4b86-a520-3a9eb9d55346,f737efdc-5818-4bc5-b3db-1da76e7caf71,2025-08-31 03:12:00
2025-08-31 11:24:10+08:00,2025-08-31 11:27:33+08:00,508.0,4457.8,4453.59,-2138.6800000000185,平多,38413547-9d48-43fc-a2be-12d2a8e0cd9f,ce5c15c0-d938-4b48-ab08-807531847f2e,2025-08-31 03:27:00
2025-08-31 11:24:10+08:00,2025-08-31 11:27:33+08:00,389.0,4457.8,4453.59,-1637.6900000000142,平多,816792ec-d409-4688-b7fd-2ee3e3f4491e,ce5c15c0-d938-4b48-ab08-807531847f2e,2025-08-31 03:27:00
2025-08-31 11:49:43+08:00,2025-08-31 11:53:50+08:00,500.0,4462.28,4469.74,3730.000000000018,平多,b1e2c3bf-db41-4762-b152-7a6a469c8cdb,52c185f1-3f74-42b6-afe5-6032df9dcb11,2025-08-31 03:53:00
2025-08-31 11:49:43+08:00,2025-08-31 11:53:50+08:00,396.0,4462.28,4469.74,2954.1600000000144,平多,b1e2c3bf-db41-4762-b152-7a6a469c8cdb,5fbbe739-8d3c-4aab-8333-7860bdca1d69,2025-08-31 03:53:00
2025-08-31 11:54:26+08:00,2025-08-31 12:00:20+08:00,293.0,4475.79,4483.53,2267.819999999936,平多,614c6489-c5a5-451d-a2a0-699e38d5a695,5da7f47f-33e3-45b8-9dfe-8232807978fc,2025-08-31 04:00:00
2025-08-31 11:54:26+08:00,2025-08-31 12:00:20+08:00,200.0,4475.79,4483.53,1547.9999999999563,平多,c443995b-f986-4a55-b6d9-59c43fa71fd2,5da7f47f-33e3-45b8-9dfe-8232807978fc,2025-08-31 04:00:00
2025-08-31 11:54:26+08:00,2025-08-31 12:00:20+08:00,400.0,4475.79,4483.53,3095.9999999999127,平多,c443995b-f986-4a55-b6d9-59c43fa71fd2,7d96c3c9-b227-48f3-b9fe-9a5c08871cfe,2025-08-31 04:00:00
2025-08-31 12:15:25+08:00,2025-08-31 12:25:03+08:00,894.0,4473.35,4467.05,5632.200000000163,平空,d5064049-73a7-4a01-8d14-3d0ba056d572,b4537133-4056-4afc-80c2-7656e28cff88,2025-08-31 04:25:00
2025-08-31 12:30:21+08:00,2025-08-31 12:33:51+08:00,500.0,4461.85,4465.99,-2069.999999999709,平空,516d9754-0fe4-4f2e-9289-5827765f7c67,13f52cac-de10-4bba-93d5-8376ba2c5139,2025-08-31 04:33:00
2025-08-31 12:30:21+08:00,2025-08-31 12:33:51+08:00,100.0,4461.85,4465.88,-402.99999999997453,平空,516d9754-0fe4-4f2e-9289-5827765f7c67,a77196b2-cc47-482b-8fb0-a140d25da936,2025-08-31 04:33:00
2025-08-31 12:30:21+08:00,2025-08-31 12:33:51+08:00,296.0,4461.85,4465.99,-1225.4399999998277,平空,516d9754-0fe4-4f2e-9289-5827765f7c67,c529dbf2-2dd4-46aa-b5b6-dd0ed4f473e2,2025-08-31 04:33:00
2025-08-31 12:42:50+08:00,2025-08-31 12:48:13+08:00,661.0,4464.2,4468.3,-2710.1000000002405,平空,0f3ef65f-e754-4229-87e6-e0f102020ce9,bce7cdc5-2c37-4bda-9b2a-05c865dd69ba,2025-08-31 04:48:00
2025-08-31 12:42:50+08:00,2025-08-31 12:48:13+08:00,235.0,4464.2,4468.3,-963.5000000000855,平空,10e40e0b-a920-4e80-8d17-ea6f73d645e3,bce7cdc5-2c37-4bda-9b2a-05c865dd69ba,2025-08-31 04:48:00
2025-08-31 13:31:35+08:00,2025-08-31 13:38:28+08:00,100.0,4453.99,4450.23,-376.0000000000218,平多,e65553ad-4738-4b5f-af08-c7373301aef8,ce3b836f-f3c8-4e27-bdd5-33b9e1ba2bc9,2025-08-31 05:38:00
2025-08-31 13:31:35+08:00,2025-08-31 13:38:28+08:00,600.0,4454.98,4450.23,-2850.0,平多,57f64aba-942f-4563-a3c7-9dfdfeaf98e4,ce3b836f-f3c8-4e27-bdd5-33b9e1ba2bc9,2025-08-31 05:38:00
2025-08-31 13:31:35+08:00,2025-08-31 13:38:28+08:00,198.0,4454.98,4450.23,-940.5,平多,597f272b-ce3c-45bf-99ee-4abe2f630972,ce3b836f-f3c8-4e27-bdd5-33b9e1ba2bc9,2025-08-31 05:38:00
2025-08-31 14:22:05+08:00,2025-08-31 14:23:54+08:00,275.0,4441.46,4446.28,-1325.49999999992,平空,eafee2f8-8601-47c7-bfe0-2f0a35bd1411,3744b6fa-5971-44d1-885f-7c7f93da8e70,2025-08-31 06:23:00
2025-08-31 14:22:05+08:00,2025-08-31 14:23:54+08:00,100.0,4442.21,4446.28,-406.9999999999709,平空,702cd777-dc0b-4602-8c19-618520cf46f4,3744b6fa-5971-44d1-885f-7c7f93da8e70,2025-08-31 06:23:00
2025-08-31 14:22:05+08:00,2025-08-31 14:23:54+08:00,525.0,4441.46,4446.28,-2530.499999999847,平空,be46bffb-290a-477a-81d9-fd4e7c1d2f3c,3744b6fa-5971-44d1-885f-7c7f93da8e70,2025-08-31 06:23:00
2025-08-31 14:33:49+08:00,2025-08-31 14:39:00+08:00,900.0,4439.81,4444.22,-3968.999999999869,平空,f25e9b2a-1bb7-4bc5-852e-5c953f222f61,2d0c6c6c-070a-498b-ade7-0235a6d3e644,2025-08-31 06:39:00
2025-08-31 14:40:14+08:00,2025-08-31 14:47:51+08:00,411.0,4444.0,4439.28,-1939.9200000001047,平多,46e5c712-8dff-423d-805d-d09da5e43571,9a2c96f9-3c09-4cca-8539-7251e96e99df,2025-08-31 06:47:00
2025-08-31 14:40:14+08:00,2025-08-31 14:47:51+08:00,400.0,4444.0,4439.13,-1947.9999999999563,平多,46e5c712-8dff-423d-805d-d09da5e43571,f92ff1ec-cfa2-4576-bcbb-978910e5200c,2025-08-31 06:47:00
2025-08-31 14:40:14+08:00,2025-08-31 14:47:51+08:00,89.0,4444.0,4439.13,-433.4299999999903,平多,46e5c712-8dff-423d-805d-d09da5e43571,5f572e4d-e1a7-45cf-bc1b-b55ce56f12b4,2025-08-31 06:47:00
2025-08-31 14:51:09+08:00,2025-08-31 14:57:17+08:00,450.0,4436.57,4435.16,634.4999999999345,平空,3d5b8a22-edc9-4076-8d61-23f8ed561202,9c959838-3125-426e-abaf-d09fc309fda2,2025-08-31 06:57:00
2025-08-31 15:30:46+08:00,2025-08-31 15:33:17+08:00,449.0,4450.96,4446.74,-1894.7800000001143,平多,45ada65c-b8e3-4316-9414-5faf1dcad582,57564f53-121e-47ac-8804-e448bb39c82c,2025-08-31 07:33:00
2025-08-31 16:05:31+08:00,2025-08-31 16:08:48+08:00,448.0,4461.21,4457.34,-1733.759999999951,平多,050937e7-f1e4-459e-982a-8d5263e718cb,ad5c9d31-f050-4981-9f51-7852dbf0df37,2025-08-31 08:08:00
2025-08-31 16:20:45+08:00,2025-08-31 16:24:22+08:00,48.0,4463.0,4462.93,-3.35999999998603,平多,e41030f3-095f-4e36-b465-e7f7d20b2972,83b7259d-91f7-485a-92ee-37c94790c7f4,2025-08-31 08:24:00
2025-08-31 16:20:45+08:00,2025-08-31 16:24:22+08:00,400.0,4463.0,4462.93,-27.999999999883585,平多,e41030f3-095f-4e36-b465-e7f7d20b2972,de316218-6bb2-48c0-b540-fc4babf5ce9b,2025-08-31 08:24:00
2025-08-31 17:24:37+08:00,2025-08-31 17:27:28+08:00,447.0,4473.73,4467.56,2757.989999999626,平空,b8d42b12-b7c8-465d-a67b-56085ceae48f,74ed9f75-4d45-47a8-a636-5a1cbe5511ce,2025-08-31 09:27:00
2025-08-31 17:48:57+08:00,2025-08-31 17:52:50+08:00,448.0,4463.45,4470.31,3073.2800000002608,平多,9b9c8688-3c74-48c3-b1bf-6bbc162b3edf,70a47e37-f8fb-440f-9ea6-50ffbf8055f6,2025-08-31 09:52:00
2025-08-31 17:59:19+08:00,2025-08-31 18:00:09+08:00,152.0,4461.24,4465.19,-600.3999999999724,平空,28a00768-c1e1-42d0-b75e-f7b6b8608b60,9263141f-f5ac-4173-b3c2-b8e2f7ba0985,2025-08-31 10:00:00
2025-08-31 17:59:19+08:00,2025-08-31 18:00:09+08:00,520.0,4461.24,4465.19,-2053.9999999999054,平空,28a00768-c1e1-42d0-b75e-f7b6b8608b60,32d89f55-ae9c-49a6-8e2a-e47b5f4167ab,2025-08-31 10:00:00
2025-08-31 18:07:59+08:00,2025-08-31 18:12:30+08:00,672.0,4459.1,4452.94,4139.520000000513,平空,765d6b9a-0683-4dca-b76c-6e9a2ea65cd5,7f047d14-dac5-4fca-94ed-c0fdfec63578,2025-08-31 10:12:00
2025-08-31 18:17:18+08:00,2025-08-31 18:29:14+08:00,673.0,4451.84,4455.42,2409.339999999951,平多,755ad988-d66e-4bc8-9907-b69112e3a11a,775a3323-bbd4-4e5c-ae56-d68e178eb05e,2025-08-31 10:29:00
2025-08-31 22:07:31+08:00,2025-08-31 22:13:15+08:00,1122.0,4453.82,4450.0,4286.0399999996735,平空,c3c54d31-6a99-45ad-8139-546ac61bed34,ef4df9cc-3394-4d53-8fed-7e261a8b0c60,2025-08-31 14:13:00
2025-08-31 22:14:11+08:00,2025-08-31 22:20:53+08:00,500.0,4453.63,4459.25,2809.9999999999454,平多,18042f61-552b-41bb-b228-8d8031ee3c14,ad7b6056-101b-49e4-9b9f-dea68880cd52,2025-08-31 14:20:00
2025-08-31 22:14:11+08:00,2025-08-31 22:20:53+08:00,122.0,4453.63,4459.25,685.6399999999867,平多,208d18b8-941b-4ce3-aa29-2f5fb074cc01,ad7b6056-101b-49e4-9b9f-dea68880cd52,2025-08-31 14:20:00
2025-08-31 22:14:11+08:00,2025-08-31 22:20:53+08:00,500.0,4453.63,4459.25,2809.9999999999454,平多,4e557687-e4c4-4f2d-85b6-364f6e5fd752,ad7b6056-101b-49e4-9b9f-dea68880cd52,2025-08-31 14:20:00
2025-08-31 23:05:00+08:00,2025-08-31 23:09:16+08:00,1117.0,4473.11,4471.27,-2055.2799999991466,平多,41d06c42-ac03-418f-9451-6f5a5fdda71a,5cd65f94-490b-4bb2-bd42-d1a64942d201,2025-08-31 15:09:00
2025-09-01 09:07:41+08:00,2025-09-01 09:11:05+08:00,400.0,4394.0,4383.39,4243.999999999869,平空,092adf53-a461-4de7-8e04-9bfe1de8c387,b3e26049-21f9-495e-9a96-7498f06dcd82,2025-09-01 01:11:00
2025-09-01 09:07:41+08:00,2025-09-01 09:11:05+08:00,55.0,4394.0,4383.39,583.549999999982,平空,092adf53-a461-4de7-8e04-9bfe1de8c387,0614bd80-655c-49d4-b895-798f56f54803,2025-09-01 01:11:00
2025-09-01 09:20:32+08:00,2025-09-01 09:25:17+08:00,454.0,4399.41,4396.45,-1343.8400000000165,平多,ef1554ec-bb75-4b5d-a3fd-03325d8ce248,11fb1482-9f6a-4b3f-aec4-e0e9f46ec4eb,2025-09-01 01:25:00
2025-09-01 09:31:04+08:00,2025-09-01 09:32:03+08:00,453.0,4409.02,4405.26,-1703.2800000000989,平多,8050d64e-1c53-40e1-89e7-68481d09e689,079730bc-d8ce-413a-a77f-a889bed73972,2025-09-01 01:32:00
2025-09-01 09:34:47+08:00,2025-09-01 09:37:04+08:00,453.0,4405.92,4417.68,5327.280000000099,平多,4f3b316a-37b6-43b9-a742-28760ce5267b,18f19970-4048-485b-b95a-00b3e804d0d9,2025-09-01 01:37:00
2025-09-01 10:11:29+08:00,2025-09-01 10:16:05+08:00,400.0,4400.12,4391.86,3304.0000000000873,平空,9b7a45aa-4ed0-4fa2-9c77-ee71e8319ecf,6adc05fa-6727-4961-8ae9-ef7f248ce06f,2025-09-01 02:16:00
2025-09-01 10:11:30+08:00,2025-09-01 10:16:05+08:00,54.0,4400.12,4391.86,446.0400000000118,平空,a2b8e0df-1a70-4cbe-b513-734c169a45e5,6adc05fa-6727-4961-8ae9-ef7f248ce06f,2025-09-01 02:16:00
2025-09-01 10:29:03+08:00,2025-09-01 10:30:26+08:00,683.0,4389.33,4386.21,-2130.9599999999255,平多,9295d00e-a050-472f-b008-426e40eb0f71,73e0f83a-583a-4ae6-8dc3-41c2f37bb58e,2025-09-01 02:30:00
2025-09-01 10:35:00+08:00,2025-09-01 10:36:12+08:00,685.0,4375.45,4379.38,-2692.0500000001994,平空,8e5b463d-f4fe-47f3-b39b-ec3721c79e7a,2f96c834-2272-491f-8bc1-8cbe6c4ea452,2025-09-01 02:36:00
2025-09-01 11:03:26+08:00,2025-09-01 11:05:42+08:00,684.0,4383.62,4391.35,5287.3200000003235,平多,ad2ab2b0-b070-4027-ba77-039ae801c30b,ab66e717-8f29-4ebe-80c7-165f36806e5f,2025-09-01 03:05:00
2025-09-01 11:12:18+08:00,2025-09-01 11:15:56+08:00,184.0,4382.88,4374.85,1477.5199999999531,平空,60e70f9e-3ed0-402a-a33e-0d9104ac17b6,2c200cb7-b183-474a-b78f-bba9e592c8c0,2025-09-01 03:15:00
2025-09-01 11:12:18+08:00,2025-09-01 11:15:56+08:00,500.0,4382.88,4374.85,4014.9999999998727,平空,4f57713c-6a4c-42d4-aa6b-c03bae934835,2c200cb7-b183-474a-b78f-bba9e592c8c0,2025-09-01 03:15:00
2025-09-01 11:34:38+08:00,2025-09-01 11:41:09+08:00,286.0,4370.18,4382.21,3440.579999999927,平多,7716be61-be89-4b30-8939-ff0c2c42b4e2,15dadfe0-75d8-4cc7-838d-931a1d21ccf8,2025-09-01 03:41:00
2025-09-01 11:34:38+08:00,2025-09-01 11:41:09+08:00,400.0,4370.18,4382.21,4811.999999999898,平多,7716be61-be89-4b30-8939-ff0c2c42b4e2,9ae0cd54-0bfb-4a24-8c7a-1a247e078eb8,2025-09-01 03:41:00
2025-09-01 11:54:59+08:00,2025-09-01 11:58:53+08:00,10.0,4396.0,4403.97,79.70000000000255,平多,b0876036-7e56-46cb-bddd-ccabb6519f7c,600628e2-049f-44c8-a905-46ea1135e601,2025-09-01 03:58:00
2025-09-01 11:54:59+08:00,2025-09-01 11:58:53+08:00,145.0,4396.47,4403.97,1087.5,平多,4bc131e8-70e0-4140-a2c8-b054e0507acd,600628e2-049f-44c8-a905-46ea1135e601,2025-09-01 03:58:00
2025-09-01 11:54:59+08:00,2025-09-01 11:58:53+08:00,355.0,4396.47,4403.97,2662.5,平多,4bc131e8-70e0-4140-a2c8-b054e0507acd,9d3eca96-2443-4c6e-b40e-1020bde26895,2025-09-01 03:58:00
2025-09-01 11:54:59+08:00,2025-09-01 11:58:53+08:00,172.0,4396.47,4403.97,1290.0,平多,86ab0723-57a8-4e31-9000-9b73f49ad308,9d3eca96-2443-4c6e-b40e-1020bde26895,2025-09-01 03:58:00
2025-09-01 12:19:34+08:00,2025-09-01 12:23:09+08:00,500.0,4389.68,4388.07,805.000000000291,平空,2aec9027-7a84-45c2-83d3-8c5871d90106,95aa0191-4e59-46b0-b538-e0a3fd31a029,2025-09-01 04:23:00
2025-09-01 12:19:34+08:00,2025-09-01 12:23:09+08:00,87.0,4389.68,4388.0,146.16000000002532,平空,2aec9027-7a84-45c2-83d3-8c5871d90106,861ff638-8ec8-4a6a-bafa-74206b093040,2025-09-01 04:23:00
2025-09-01 12:19:34+08:00,2025-09-01 12:23:09+08:00,52.0,4389.68,4388.07,83.72000000003027,平空,2aec9027-7a84-45c2-83d3-8c5871d90106,6cff4ab5-d999-4dda-87e2-067c9adbd240,2025-09-01 04:23:00
2025-09-01 12:19:34+08:00,2025-09-01 12:23:09+08:00,500.0,4389.68,4388.07,805.000000000291,平空,2aec9027-7a84-45c2-83d3-8c5871d90106,4dc3eeb9-b54d-4820-bc73-2172e8e5fd66,2025-09-01 04:23:00
2025-09-01 12:52:26+08:00,2025-09-01 12:56:26+08:00,1141.0,4381.97,4385.85,4427.0800000001245,平多,a3ef0945-101d-4f17-9cda-711fe44e2cf1,ab314993-0d4e-4632-8bcd-66aaaef57066,2025-09-01 04:56:00
2025-09-01 13:11:24+08:00,2025-09-01 13:12:28+08:00,475.0,4363.3,4368.36,-2403.499999999758,平空,4d1d7cf6-26fe-44f0-be21-d10a9871ae1a,53f10353-21b1-41c1-8554-18c5bac4991a,2025-09-01 05:12:00
2025-09-01 13:11:24+08:00,2025-09-01 13:12:28+08:00,400.0,4363.3,4368.36,-2023.9999999997963,平空,63978423-878f-4bc0-8ac6-7526d1aa3b24,53f10353-21b1-41c1-8554-18c5bac4991a,2025-09-01 05:12:00
2025-09-01 13:11:24+08:00,2025-09-01 13:12:28+08:00,500.0,4363.3,4368.36,-2529.9999999997453,平空,9736d4ed-bfd4-4fb4-a2b9-7a335070a480,53f10353-21b1-41c1-8554-18c5bac4991a,2025-09-01 05:12:00
2025-09-01 13:19:17+08:00,2025-09-01 13:20:04+08:00,1376.0,4357.3,4364.42,-9797.11999999985,平空,9d7b259b-c1ec-4d54-83c5-e1588347d99f,a63b68c2-d467-4b4b-992a-175e562a59cd,2025-09-01 05:20:00
2025-09-01 13:23:06+08:00,2025-09-01 13:33:39+08:00,291.0,4390.89,4384.71,-1798.3800000000847,平多,348b7ba0-df18-4d21-b652-1c54dc5b4635,2a709f71-d330-49c0-9759-3b65a140431c,2025-09-01 05:33:00
2025-09-01 13:23:06+08:00,2025-09-01 13:33:39+08:00,300.0,4390.89,4384.71,-1854.0000000000873,平多,c8c60f9e-a45b-4f5a-b000-a1a436757403,2a709f71-d330-49c0-9759-3b65a140431c,2025-09-01 05:33:00
2025-09-01 13:23:06+08:00,2025-09-01 13:33:39+08:00,300.0,4390.89,4384.71,-1854.0000000000873,平多,970891fc-d2ec-4c54-a196-7a450a88c968,2a709f71-d330-49c0-9759-3b65a140431c,2025-09-01 05:33:00
2025-09-01 13:23:06+08:00,2025-09-01 13:33:39+08:00,20.0,4390.01,4384.71,-106.00000000000364,平多,71cd000e-8c95-4f6f-a32f-1440db6e8c0d,2a709f71-d330-49c0-9759-3b65a140431c,2025-09-01 05:33:00
2025-09-01 13:49:13+08:00,2025-09-01 13:54:15+08:00,287.0,4396.35,4396.21,-40.18000000009397,平多,83a1a14a-a4e3-40f1-86bd-915987501b35,4c298f23-9a76-4a0f-8bc1-f8ed23f12ede,2025-09-01 05:54:00
2025-09-01 13:49:13+08:00,2025-09-01 13:54:15+08:00,200.0,4396.35,4396.21,-28.000000000065484,平多,83a1a14a-a4e3-40f1-86bd-915987501b35,46728c29-6645-408a-bba2-07f01cd5d06d,2025-09-01 05:54:00
2025-09-01 13:49:13+08:00,2025-09-01 13:54:15+08:00,13.0,4396.35,4396.21,-1.8200000000042564,平多,83a1a14a-a4e3-40f1-86bd-915987501b35,c4cb8611-b4dd-41fd-95c2-c9455c1237e6,2025-09-01 05:54:00
2025-09-01 13:49:13+08:00,2025-09-01 13:54:15+08:00,187.0,4396.35,4396.21,-26.180000000061227,平多,47230a4e-8ee9-4d68-aa51-01753afc623b,c4cb8611-b4dd-41fd-95c2-c9455c1237e6,2025-09-01 05:54:00
2025-09-01 13:49:13+08:00,2025-09-01 13:54:15+08:00,213.0,4396.35,4396.13,-46.86000000005424,平多,47230a4e-8ee9-4d68-aa51-01753afc623b,e06fcad9-5742-4c94-82eb-2f34884e3f4a,2025-09-01 05:54:00
2025-09-01 13:49:14+08:00,2025-09-01 13:54:15+08:00,9.0,4396.35,4396.13,-1.980000000002292,平多,1743d43c-c642-434b-940f-b6d33e6718b9,e06fcad9-5742-4c94-82eb-2f34884e3f4a,2025-09-01 05:54:00
2025-09-01 15:34:19+08:00,2025-09-01 15:35:08+08:00,403.0,4429.5,4426.01,-1406.469999999912,平多,e9dad14a-702d-4396-a259-38e6c3b62876,76c3e1c9-aeee-41bd-b8d4-37e8948af1c4,2025-09-01 07:35:00
2025-09-01 15:34:19+08:00,2025-09-01 15:35:08+08:00,500.0,4429.5,4426.01,-1744.9999999998909,平多,431b7e4b-b81e-4626-a6de-f5acd5a7cf20,76c3e1c9-aeee-41bd-b8d4-37e8948af1c4,2025-09-01 07:35:00
2025-09-01 15:36:02+08:00,2025-09-01 15:36:51+08:00,780.0,4424.4,4419.44,-3868.8000000000284,平多,d7ba8670-d0d7-4817-b30f-ed7d2ba4fd3c,74c07207-3acc-4f9c-b98b-ae54e4085d96,2025-09-01 07:36:00
2025-09-01 15:36:02+08:00,2025-09-01 15:36:51+08:00,124.0,4424.4,4420.0,-545.5999999999549,平多,d7ba8670-d0d7-4817-b30f-ed7d2ba4fd3c,a4bea0b9-d2b0-42bf-9e3b-371747ea4fa3,2025-09-01 07:36:00
2025-09-01 15:44:38+08:00,2025-09-01 15:47:21+08:00,676.0,4420.39,4426.94,4427.799999999508,平多,17564d45-1b57-4822-91dd-7bf3a162e7b1,131e056d-1779-4de8-bb12-1663936c3ffe,2025-09-01 07:47:00
2025-09-01 15:44:38+08:00,2025-09-01 15:47:21+08:00,22.0,4420.0,4426.94,152.6799999999912,平多,7e280213-31c8-4848-b164-57ce0f3a30c3,131e056d-1779-4de8-bb12-1663936c3ffe,2025-09-01 07:47:00
2025-09-01 15:44:38+08:00,2025-09-01 15:47:21+08:00,206.0,4420.39,4426.94,1349.2999999998501,平多,37898b4e-9a13-4bc0-a9e6-3fa908bd1e80,131e056d-1779-4de8-bb12-1663936c3ffe,2025-09-01 07:47:00
2025-09-01 15:51:28+08:00,2025-09-01 15:54:46+08:00,387.0,4434.86,4450.54,6068.160000000113,平多,a62d6355-e666-4b24-a9fe-1a8efd802cd4,c5b380bf-78c7-4dfd-a1b8-f212e0562e5d,2025-09-01 07:54:00
2025-09-01 15:51:28+08:00,2025-09-01 15:54:46+08:00,514.0,4434.86,4450.54,8059.52000000015,平多,9383482c-67d4-4a52-9c9a-bf106f8a66ed,c5b380bf-78c7-4dfd-a1b8-f212e0562e5d,2025-09-01 07:54:00
2025-09-01 15:59:35+08:00,2025-09-01 16:02:01+08:00,898.0,4454.21,4472.89,16774.64000000026,平多,b4194b4d-5b4a-4387-879f-b208a173d23e,0b3a10ad-d3bc-49e7-bc76-95d3f3f7b012,2025-09-01 08:02:00
2025-09-01 16:05:00+08:00,2025-09-01 16:05:43+08:00,891.0,4486.3,4479.29,-6245.9100000001945,平多,62035134-6e2c-4e78-a57e-90883d6fd125,e148f8b3-d2b0-49a8-9702-bf0ef6d70a11,2025-09-01 08:05:00
2025-09-01 16:06:22+08:00,2025-09-01 16:13:08+08:00,893.0,4478.53,4480.64,-1884.2300000005198,平空,d901988b-b5b6-4a5e-a03c-83cedbdbbbda,dcc81b54-5253-4a49-a426-f28316341b68,2025-09-01 08:13:00
2025-09-01 16:18:38+08:00,2025-09-01 16:19:03+08:00,895.0,4467.53,4470.68,-2819.2500000004884,平空,2a066536-51d7-425d-ae9e-83613597c612,41ad454f-5790-480c-9f16-80b478841763,2025-09-01 08:19:00
2025-09-01 16:20:05+08:00,2025-09-01 16:22:22+08:00,894.0,4473.83,4478.12,-3835.2599999999675,平空,93df10c4-453d-405e-aa78-3870c5c5f78f,5aeedf17-a10d-4388-b16e-e18251d6e1e5,2025-09-01 08:22:00
2025-09-01 16:23:14+08:00,2025-09-01 16:27:37+08:00,893.0,4475.22,4469.41,5188.330000000357,平空,d9277a5f-844a-4afc-b784-0343d373a87e,7def0a70-6cc3-4880-9da3-16671ec6a296,2025-09-01 08:27:00
2025-09-01 16:33:42+08:00,2025-09-01 16:41:25+08:00,894.0,4470.45,4469.46,885.0599999998049,平空,9e7bf3df-d22c-413b-8b29-024b9c830f6b,3e80d0e3-3466-4e63-b75d-c86b67b6eb0b,2025-09-01 08:41:00
2025-09-01 16:55:38+08:00,2025-09-01 17:04:46+08:00,893.0,4474.93,4476.7,-1580.6099999995777,平空,aca7bfae-9112-4a7a-8a95-7b7661be7d13,20115f47-253a-435a-9b43-1cfcbdc9c12e,2025-09-01 09:04:00
2025-09-01 17:10:25+08:00,2025-09-01 17:15:02+08:00,894.0,4472.69,4480.01,6544.080000000553,平多,44c66b7e-5da3-4773-b5a0-73b1cd1c13b9,d8403012-f909-414d-bb21-a012dc5722c2,2025-09-01 09:15:00
2025-09-01 17:35:29+08:00,2025-09-01 17:38:36+08:00,300.0,4473.01,4460.17,3852.0000000000437,平空,67981b9f-af13-4595-9a36-80db526ac0e4,de9b300a-19de-4cc4-b86e-e5d8ade4eb2f,2025-09-01 09:38:00
2025-09-01 17:35:29+08:00,2025-09-01 17:38:36+08:00,70.0,4473.01,4460.17,898.8000000000102,平空,67981b9f-af13-4595-9a36-80db526ac0e4,f7f5c314-6e7b-498a-99cf-a2c868021b32,2025-09-01 09:38:00
2025-09-01 17:35:29+08:00,2025-09-01 17:38:36+08:00,236.0,4473.01,4460.17,3030.2400000000343,平空,67981b9f-af13-4595-9a36-80db526ac0e4,f34ae213-3bb5-4bc5-96b5-1efb92648427,2025-09-01 09:38:00
2025-09-01 17:35:29+08:00,2025-09-01 17:38:36+08:00,287.0,4473.01,4460.17,3685.0800000000418,平空,da23b541-1bde-4417-8875-4a52000d3183,f34ae213-3bb5-4bc5-96b5-1efb92648427,2025-09-01 09:38:00
1 开仓时间 平仓时间 数量 开仓价 平仓价 盈亏 类型 开仓订单ID 平仓订单ID 时间_x
2 2025-08-28 09:35:18+08:00 2025-08-28 09:44:18+08:00 664.0 4514.69 4507.43 4820.639999999541 平空 e1d3a2da-219e-436f-ac9e-a7ea93de15bd abfa0508-9399-4f1b-90c7-7716c3e7f511 2025-08-28 01:44:00
3 2025-08-28 10:06:42+08:00 2025-08-28 10:10:07+08:00 1106.0 4519.88 4515.64 -4689.439999999759 平多 594bd10c-2120-4692-a8eb-9f5325e26ef0 bd643cab-14d4-414d-912e-e9257ddb96de 2025-08-28 02:10:00
4 2025-08-28 10:45:07+08:00 2025-08-28 10:51:41+08:00 1108.0 4512.13 4516.84 -5218.68000000004 平空 fc0c73ab-9fff-41b5-98c1-ef6f7d300256 206688da-848a-4822-9571-c05302ab7a29 2025-08-28 02:51:00
5 2025-08-28 11:07:30+08:00 2025-08-28 11:13:19+08:00 200.0 4525.0 4529.25 850.0 平多 6197fb5c-6202-422f-9012-5395c5393fb3 59d8859f-2b64-4e8b-aefe-57998b198841 2025-08-28 03:13:00
6 2025-08-28 11:07:30+08:00 2025-08-28 11:13:19+08:00 100.0 4525.0 4529.25 425.0 平多 794c0925-6e48-4b9a-a162-d31d7a3c42cc 59d8859f-2b64-4e8b-aefe-57998b198841 2025-08-28 03:13:00
7 2025-08-28 11:07:31+08:00 2025-08-28 11:13:19+08:00 483.0 4525.0 4529.25 2052.75 平多 65f7d764-ad05-40c7-bce1-6b227ad5f5c0 59d8859f-2b64-4e8b-aefe-57998b198841 2025-08-28 03:13:00
8 2025-08-28 11:07:31+08:00 2025-08-28 11:13:19+08:00 100.0 4525.0 4529.25 425.0 平多 35e1c160-4129-425a-ae46-b8fb45d53ec8 59d8859f-2b64-4e8b-aefe-57998b198841 2025-08-28 03:13:00
9 2025-08-28 11:28:58+08:00 2025-08-28 11:34:21+08:00 400.0 4533.74 4537.34 1440.0000000001455 平多 a983b8f5-70d1-441b-87df-397c6c1ce843 3e161e4e-f367-421a-bc0d-8095f7b79675 2025-08-28 03:34:00
10 2025-08-28 11:28:58+08:00 2025-08-28 11:34:21+08:00 482.0 4533.74 4537.34 1735.2000000001754 平多 a983b8f5-70d1-441b-87df-397c6c1ce843 45ddb145-d637-4985-9c4b-3dee2fd189b5 2025-08-28 03:34:00
11 2025-08-28 12:22:53+08:00 2025-08-28 12:23:33+08:00 478.0 4550.8 4545.04 -2753.2800000001043 平多 37d97b24-c1fd-4a2d-ba0e-75b818062686 fcfe39c7-0bcf-47f6-9b48-a1dd70bd5444 2025-08-28 04:23:00
12 2025-08-28 12:22:53+08:00 2025-08-28 12:23:33+08:00 400.0 4550.8 4545.04 -2304.0000000000873 平多 37d97b24-c1fd-4a2d-ba0e-75b818062686 867b1b2c-0fe5-466b-a89f-ec8dce25bcda 2025-08-28 04:23:00
13 2025-08-28 12:26:39+08:00 2025-08-28 12:34:19+08:00 879.0 4549.6 4555.44 5133.3599999993285 平多 0a3a08a1-61c7-4997-b13c-4da05b2c5dbc ad149e7f-7088-4dd9-9698-9b7bd615478e 2025-08-28 04:34:00
14 2025-08-28 12:46:19+08:00 2025-08-28 12:48:10+08:00 600.0 4561.8 4567.53 -3437.999999999738 平空 18929fa1-2cc7-4e7f-8e76-c3937f16f877 8283a8b1-17f1-4818-843d-33877996af35 2025-08-28 04:48:00
15 2025-08-28 12:46:19+08:00 2025-08-28 12:48:10+08:00 276.0 4561.8 4567.53 -1581.4799999998795 平空 18929fa1-2cc7-4e7f-8e76-c3937f16f877 c0a1d021-0708-476e-a766-722bc73ab740 2025-08-28 04:48:00
16 2025-08-28 12:53:40+08:00 2025-08-28 12:57:03+08:00 873.0 4577.05 4569.51 6582.419999999968 平空 16f8970d-ef44-4026-ba19-9c9ff6dc70e1 e1f9de7d-115e-4289-8acd-bbba16e04ff0 2025-08-28 04:57:00
17 2025-08-28 12:58:03+08:00 2025-08-28 13:01:30+08:00 475.0 4567.45 4572.58 -2436.750000000052 平空 8dbfcfc8-466c-4111-acdf-316a2a8c7428 3e0a22b4-7707-4332-b80d-87d3b07cf3cc 2025-08-28 05:01:00
18 2025-08-28 12:58:03+08:00 2025-08-28 13:01:30+08:00 400.0 4567.45 4572.58 -2052.0000000000437 平空 8dbfcfc8-466c-4111-acdf-316a2a8c7428 29775823-c3fc-4dbc-8afa-f9587f803f2a 2025-08-28 05:01:00
19 2025-08-28 13:32:49+08:00 2025-08-28 13:41:18+08:00 721.0 4564.18 4565.88 1225.6999999998689 平多 6c0a64d8-b890-42bc-ae09-152919931d57 5bba77bd-b49f-4c6d-9a12-fe062c687cae 2025-08-28 05:41:00
20 2025-08-28 13:32:49+08:00 2025-08-28 13:41:18+08:00 155.0 4564.18 4565.88 263.4999999999718 平多 c0e17c5e-6a39-465c-a3b3-347f1af3d772 5bba77bd-b49f-4c6d-9a12-fe062c687cae 2025-08-28 05:41:00
21 2025-08-28 13:52:44+08:00 2025-08-28 13:57:25+08:00 400.0 4555.2 4559.95 -1900.0 平空 8f641745-890a-4b9c-8d83-10163234429d dd5f8c6a-74da-4984-aa24-eebfbceb6d22 2025-08-28 05:57:00
22 2025-08-28 13:52:44+08:00 2025-08-28 13:57:25+08:00 478.0 4555.2 4559.95 -2270.5 平空 66c5bcfb-02ef-4a8c-a314-bd9d672decb5 dd5f8c6a-74da-4984-aa24-eebfbceb6d22 2025-08-28 05:57:00
23 2025-08-28 14:40:01+08:00 2025-08-28 14:41:47+08:00 874.0 4572.59 4578.98 -5584.859999999491 平空 1b1efa90-7dd5-4b5f-a170-eb87df7fb7db 26b0c5e5-f4a4-4f47-9fdc-12c6ecd05704 2025-08-28 06:41:00
24 2025-08-28 15:05:18+08:00 2025-08-28 15:07:11+08:00 60.0 4582.63 4577.98 -279.00000000003274 平多 61f7b24d-18b1-44ee-bc9e-60666e4b2346 e53afe94-f3fa-42c1-9e49-619cd77261ab 2025-08-28 07:07:00
25 2025-08-28 15:05:18+08:00 2025-08-28 15:07:11+08:00 600.0 4582.63 4578.03 -2760.0000000002183 平多 61f7b24d-18b1-44ee-bc9e-60666e4b2346 b9cf7c9c-d909-4dad-ae66-64aa0706566f 2025-08-28 07:07:00
26 2025-08-28 15:05:18+08:00 2025-08-28 15:07:11+08:00 212.0 4582.63 4577.52 -1083.3199999999306 平多 61f7b24d-18b1-44ee-bc9e-60666e4b2346 05d46d57-d923-4d18-8c18-5a49927ac910 2025-08-28 07:07:00
27 2025-08-28 15:22:41+08:00 2025-08-28 15:23:11+08:00 600.0 4572.88 4567.91 -2982.000000000153 平多 184c5b21-ed98-43c2-8003-8cc5f8c1bb0a 10d151ec-2891-44fe-8527-89643b3f3b46 2025-08-28 07:23:00
28 2025-08-28 15:22:41+08:00 2025-08-28 15:23:11+08:00 274.0 4572.88 4567.53 -1465.9000000000997 平多 184c5b21-ed98-43c2-8003-8cc5f8c1bb0a 2a5ef255-f800-4e98-a10c-ca3ed33bb372 2025-08-28 07:23:00
29 2025-08-28 15:57:55+08:00 2025-08-28 16:02:09+08:00 547.0 4589.48 4607.47 9840.530000000377 平多 6fdd3eb9-13a9-4e2a-90b6-78e7d71f3fbc 81bc2d5e-8099-4d48-b968-d695a7f1fee4 2025-08-28 08:02:00
30 2025-08-28 15:57:55+08:00 2025-08-28 16:02:09+08:00 324.0 4589.48 4607.47 5828.760000000224 平多 aec18848-d3b5-4786-8c51-a4fdfc454ee2 81bc2d5e-8099-4d48-b968-d695a7f1fee4 2025-08-28 08:02:00
31 2025-08-28 16:05:54+08:00 2025-08-28 16:09:19+08:00 866.0 4614.86 4624.89 8685.980000000567 平多 8e6d3e81-c813-4759-b608-9ed4e547b24d 25509f73-848d-4620-b662-f7f93d76becc 2025-08-28 08:09:00
32 2025-08-28 16:09:50+08:00 2025-08-28 16:15:00+08:00 865.0 4621.56 4617.66 -3373.500000000472 平多 29739f4f-b289-4a1e-a5e7-f6925dd72b4c 7e4c74ac-902f-47c5-9e0a-b2ef07f31e8e 2025-08-28 08:15:00
33 2025-08-28 16:23:59+08:00 2025-08-28 16:28:31+08:00 867.0 4609.17 4602.01 6207.719999999874 平空 6e8dc270-512a-4826-84c9-cfdf82c6cd59 0df8cd52-9db6-4532-99e1-923fcd9c134d 2025-08-28 08:28:00
34 2025-08-28 16:54:47+08:00 2025-08-28 16:58:41+08:00 870.0 4595.28 4599.69 -3836.6999999998734 平空 35598fc3-567f-4ee2-a9fe-db14aab8228b 9777e233-baa8-4238-8f48-ef3e303ff883 2025-08-28 08:58:00
35 2025-08-28 17:06:53+08:00 2025-08-28 17:15:11+08:00 870.0 4595.19 4592.66 2201.0999999997784 平空 3432672f-ced3-401f-981d-7686ddd396e6 bf9ffdef-56bd-4d35-9eef-f92a668d5829 2025-08-28 09:15:00
36 2025-08-28 17:43:59+08:00 2025-08-28 17:49:12+08:00 258.0 4584.79 4581.95 732.7200000000375 平空 c0b26494-b8c4-434e-bc49-e3b317c1fa88 ffbc0ba2-aa7f-4377-bade-cf31e3697b19 2025-08-28 09:49:00
37 2025-08-28 17:43:59+08:00 2025-08-28 17:49:12+08:00 114.0 4584.79 4581.95 323.7600000000166 平空 6fdb9fc7-e0f4-4033-896b-a13160b4fd18 ffbc0ba2-aa7f-4377-bade-cf31e3697b19 2025-08-28 09:49:00
38 2025-08-28 17:43:59+08:00 2025-08-28 17:49:12+08:00 500.0 4584.79 4581.95 1420.0000000000728 平空 b064c485-653b-4f88-a0d1-86961284dc70 ffbc0ba2-aa7f-4377-bade-cf31e3697b19 2025-08-28 09:49:00
39 2025-08-28 17:49:44+08:00 2025-08-28 17:50:54+08:00 500.0 4579.81 4584.85 -2519.999999999982 平空 1f97429c-1de1-467a-8985-8f9bb17000b5 cf389028-3cfb-4521-bf8c-59c3d9782e85 2025-08-28 09:50:00
40 2025-08-28 17:49:44+08:00 2025-08-28 17:50:54+08:00 139.0 4579.81 4584.85 -700.559999999995 平空 989c44a3-a81f-4939-ab13-d9884d845a65 cf389028-3cfb-4521-bf8c-59c3d9782e85 2025-08-28 09:50:00
41 2025-08-28 17:49:44+08:00 2025-08-28 17:50:54+08:00 234.0 4579.58 4584.85 -1233.1800000001022 平空 0b83f7ef-0985-4168-a211-d009f6c6ff1a cf389028-3cfb-4521-bf8c-59c3d9782e85 2025-08-28 09:50:00
42 2025-08-28 18:36:51+08:00 2025-08-28 18:43:09+08:00 533.0 4609.97 4604.0 -3182.0100000001357 平多 b8391ca4-74b4-41bc-85cd-b4c82cf6e8f3 2926d3da-8a19-4fae-938f-e2556e994376 2025-08-28 10:43:00
43 2025-08-28 18:36:51+08:00 2025-08-28 18:43:09+08:00 84.0 4610.0 4604.0 -504.0 平多 e441f55d-693a-4301-b6c9-10d54ab10357 2926d3da-8a19-4fae-938f-e2556e994376 2025-08-28 10:43:00
44 2025-08-28 18:36:51+08:00 2025-08-28 18:43:09+08:00 33.0 4609.97 4604.0 -197.0100000000084 平多 9dbce008-1d12-422c-80f8-a2c928610074 2926d3da-8a19-4fae-938f-e2556e994376 2025-08-28 10:43:00
45 2025-08-28 19:46:14+08:00 2025-08-28 19:54:40+08:00 654.0 4586.91 4591.36 -2910.299999999881 平空 005b10f4-329d-4d34-8263-b8f63f526ac8 ea07e34c-cd41-4c80-b13f-6b8308257b92 2025-08-28 11:54:00
46 2025-08-28 20:30:04+08:00 2025-08-28 20:30:34+08:00 517.0 4587.25 4588.6 697.9500000001881 平多 26fe1b1b-f4f0-4c49-b6d0-f8445d4e996e 9011ad7e-ef83-4c62-ac90-3e538965ad3f 2025-08-28 12:30:00
47 2025-08-28 20:30:05+08:00 2025-08-28 20:30:34+08:00 354.0 4587.44 4588.6 410.64000000027045 平多 32f1db9d-6a9b-413f-abba-3f698a83ec65 9011ad7e-ef83-4c62-ac90-3e538965ad3f 2025-08-28 12:30:00
48 2025-08-28 20:31:22+08:00 2025-08-28 20:31:28+08:00 400.0 4583.96 4585.9 -775.9999999998399 平空 dd7d8a55-c4bf-4ff8-82b9-ec8591888b0d ca1e611c-1ba6-4418-9f86-8e492a7726c5 2025-08-28 12:31:00
49 2025-08-28 20:31:22+08:00 2025-08-28 20:31:29+08:00 472.0 4583.96 4585.9 -915.6799999998111 平空 dd7d8a55-c4bf-4ff8-82b9-ec8591888b0d 04792496-7da0-4a9b-95cf-293b41d8292a 2025-08-28 12:31:00
50 2025-08-28 20:43:41+08:00 2025-08-28 20:46:26+08:00 92.0 4609.77 4603.6 -567.6400000000067 平多 da034c24-f333-4197-ae9d-7dfa8639be45 9d59670d-a478-4432-8ec0-e3a8c4ec4d8a 2025-08-28 12:46:00
51 2025-08-28 20:43:41+08:00 2025-08-28 20:46:26+08:00 600.0 4609.77 4603.6 -3702.0000000000437 平多 da034c24-f333-4197-ae9d-7dfa8639be45 e83ff9d3-3078-4f5c-8e6a-fa5750c97b55 2025-08-28 12:46:00
52 2025-08-28 20:43:41+08:00 2025-08-28 20:46:27+08:00 175.0 4609.77 4604.08 -995.7500000000891 平多 da034c24-f333-4197-ae9d-7dfa8639be45 433dc03b-8b85-4951-9f21-dfaa5d6a0de5 2025-08-28 12:46:00
53 2025-08-29 09:45:36+08:00 2025-08-29 09:49:22+08:00 447.0 4466.85 4458.15 3888.9000000003252 平空 87d823b2-675d-4501-bb36-b40eef344b7c 28bb7706-f2ce-480e-b606-fc5073ce4153 2025-08-29 01:49:00
54 2025-08-29 10:13:26+08:00 2025-08-29 10:18:05+08:00 2.0 4470.7 4473.08 4.760000000000218 平多 6d7fe294-0553-46ac-9179-e22446e727dc b50fd6a4-865b-4cd4-8b83-015dde307912 2025-08-29 02:18:00
55 2025-08-29 10:13:27+08:00 2025-08-29 10:18:05+08:00 445.0 4470.71 4473.08 1054.6499999999514 平多 3d441a61-f852-4d4d-88d9-a2c4494e3a5f b50fd6a4-865b-4cd4-8b83-015dde307912 2025-08-29 02:18:00
56 2025-08-29 10:21:04+08:00 2025-08-29 10:25:10+08:00 446.0 4479.68 4483.07 1511.9399999997404 平多 9ac71ec9-58a8-43af-83ca-cac772d44dce 7db1d0e0-cdda-45a4-af09-9ec2f6a830a5 2025-08-29 02:25:00
57 2025-08-29 11:08:08+08:00 2025-08-29 11:10:24+08:00 446.0 4477.82 4481.35 1574.380000000292 平多 4c447405-283c-40f7-bc05-42ae2aeaaaeb de3c12d5-ba88-4b3d-8e8a-2158228465cb 2025-08-29 03:10:00
58 2025-08-29 11:25:26+08:00 2025-08-29 11:31:14+08:00 446.0 4478.16 4482.39 1886.580000000211 平多 877eb021-8a47-4d55-8efd-789fde87699c 33addd17-0151-418d-b11e-d68a26c179e6 2025-08-29 03:31:00
59 2025-08-29 11:35:59+08:00 2025-08-29 11:43:49+08:00 446.0 4484.05 4494.74 4767.7399999998215 平多 913408fa-2541-48c8-a8a0-d352b8b74a93 a7fd376e-dd1c-4350-8c58-1913d130902c 2025-08-29 03:43:00
60 2025-08-29 11:55:41+08:00 2025-08-29 12:00:52+08:00 444.0 4498.11 4489.03 4031.5199999999677 平空 6450e48b-f901-4907-b065-18e073f86534 7cfe2e33-9b17-4785-9e45-dd5654c483c2 2025-08-29 04:00:00
61 2025-08-29 12:54:59+08:00 2025-08-29 12:58:10+08:00 670.0 4477.15 4471.43 3832.3999999995613 平空 13bb04ff-529a-48f4-a062-bdbda01abe9a 01a6ebd4-6c63-4e58-9f52-4317a83a6c27 2025-08-29 04:58:00
62 2025-08-29 13:05:31+08:00 2025-08-29 13:06:05+08:00 671.0 4466.57 4472.34 -3871.670000000293 平空 5c439227-9432-48c1-8c70-184e65586599 398e954e-0534-4f4c-bdda-5d14d858afae 2025-08-29 05:06:00
63 2025-08-29 13:17:39+08:00 2025-08-29 13:19:35+08:00 448.0 4461.42 4468.3 -3082.240000000049 平空 d770f2c0-6aed-4bc2-bee2-f98209775454 14ce65ce-8af2-4c07-8441-bdeea724197e 2025-08-29 05:19:00
64 2025-08-29 13:59:25+08:00 2025-08-29 14:01:39+08:00 46.0 4476.01 4484.33 382.7199999999866 平多 1f80cf00-8910-42af-a7ac-dd2199579d04 96e160f6-0a35-4ac4-9f3e-295065a56092 2025-08-29 06:01:00
65 2025-08-29 13:59:25+08:00 2025-08-29 14:01:39+08:00 400.0 4476.01 4484.33 3327.9999999998836 平多 1f80cf00-8910-42af-a7ac-dd2199579d04 db2ea541-8ece-4876-baa0-f803629d4675 2025-08-29 06:01:00
66 2025-08-29 14:15:38+08:00 2025-08-29 14:18:12+08:00 448.0 4457.41 4451.26 2755.199999999837 平空 2616d754-2ae8-43c0-a382-46901e0dba21 913e0886-23e4-467d-932d-79e960df2947 2025-08-29 06:18:00
67 2025-08-29 14:37:31+08:00 2025-08-29 14:39:31+08:00 449.0 4451.44 4451.34 -44.89999999975498 平多 9f225f1e-cdc5-42cc-8c22-6d39f68da6d6 db5c616d-faf7-4183-8e46-b95f09dbad99 2025-08-29 06:39:00
68 2025-08-29 14:41:21+08:00 2025-08-29 14:44:17+08:00 449.0 4451.53 4455.7 1872.3300000000327 平多 5ba24885-5747-405a-8fa9-6a9749dbe6b4 f7e02df2-857b-4e3a-a6aa-c0d7362cb5bb 2025-08-29 06:44:00
69 2025-08-29 15:01:14+08:00 2025-08-29 15:02:16+08:00 449.0 4448.83 4428.34 9200.009999999902 平空 a605bd22-e12e-44a4-9e1c-87c145bc5aa4 365ff72f-891a-4314-a005-d320d2074d5f 2025-08-29 07:02:00
70 2025-08-29 15:12:00+08:00 2025-08-29 15:15:04+08:00 453.0 4412.37 4393.89 8371.439999999802 平空 03169227-80cc-4c41-89e5-7cbc59174c90 7939f969-7566-453d-a718-dfa6b96ee987 2025-08-29 07:15:00
71 2025-08-29 15:44:10+08:00 2025-08-29 15:51:01+08:00 683.0 4387.22 4391.19 -2711.5099999995527 平空 e2151c19-3f56-4239-8368-77af88a0c2c1 f90b5024-cd5b-44d5-a140-4d6253d49d6a 2025-08-29 07:51:00
72 2025-08-29 15:57:12+08:00 2025-08-29 16:00:46+08:00 400.0 4383.78 4387.09 -1324.00000000016 平空 f2affaff-2beb-481f-b346-c9453422f536 70cc7f5d-b472-40a1-b00b-7e4b032722fc 2025-08-29 08:00:00
73 2025-08-29 15:57:12+08:00 2025-08-29 16:00:46+08:00 284.0 4383.78 4387.09 -940.0400000001137 平空 f2affaff-2beb-481f-b346-c9453422f536 676c76cd-7afa-40db-a0a7-89004bb9387b 2025-08-29 08:00:00
74 2025-08-29 16:08:15+08:00 2025-08-29 16:11:24+08:00 383.0 4386.41 4376.76 3695.9499999998607 平空 da4365c6-5bed-4bff-824c-580b3be527bc 0fdf84b4-d9bd-419e-8fd0-037e8631eefd 2025-08-29 08:11:00
75 2025-08-29 16:08:15+08:00 2025-08-29 16:11:24+08:00 300.0 4386.5 4376.76 2921.9999999999345 平空 940d2d22-8103-4bdd-8eaa-ade1277111da 0fdf84b4-d9bd-419e-8fd0-037e8631eefd 2025-08-29 08:11:00
76 2025-08-29 16:17:21+08:00 2025-08-29 16:17:29+08:00 187.0 4364.59 4365.41 -153.33999999994558 平空 89b93201-dfd2-408c-a5de-b6ecd72424cd db922d70-7a90-4cf4-9a17-a598fe213f8b 2025-08-29 08:17:00
77 2025-08-29 16:17:21+08:00 2025-08-29 16:17:29+08:00 400.0 4364.59 4365.41 -327.9999999998836 平空 89b93201-dfd2-408c-a5de-b6ecd72424cd 574a0e60-b26e-46bf-a696-cae5868b7af2 2025-08-29 08:17:00
78 2025-08-29 16:17:21+08:00 2025-08-29 16:17:29+08:00 100.0 4365.0 4365.41 -40.99999999998545 平空 e6be51d9-e746-45dd-8522-877cf7eafd33 574a0e60-b26e-46bf-a696-cae5868b7af2 2025-08-29 08:17:00
79 2025-08-29 16:20:18+08:00 2025-08-29 16:20:36+08:00 688.0 4359.92 4362.29 -1630.559999999925 平空 d302895c-7318-4851-838d-396e7100fc09 719a6eff-a759-4947-8f0a-45f2ac94dfc4 2025-08-29 08:20:00
80 2025-08-29 16:29:12+08:00 2025-08-29 16:33:21+08:00 527.0 4355.55 4362.63 3731.1599999999617 平多 f587dcce-e557-4b34-a55f-bf449234faca e833feb6-8ba7-4fa5-adea-678f690e16b3 2025-08-29 08:33:00
81 2025-08-29 16:29:12+08:00 2025-08-29 16:33:21+08:00 161.0 4355.55 4362.63 1139.8799999999883 平多 22c48502-01b1-4efd-9809-3bc8487b0a9b e833feb6-8ba7-4fa5-adea-678f690e16b3 2025-08-29 08:33:00
82 2025-08-29 16:37:39+08:00 2025-08-29 16:40:08+08:00 688.0 4356.21 4352.88 2291.03999999995 平空 b209c4ae-8c33-4ba5-ad48-7559d1eafc6a f7b8931f-1568-4387-a132-8ac6f7f34891 2025-08-29 08:40:00
83 2025-08-29 16:40:40+08:00 2025-08-29 16:41:12+08:00 140.0 4348.53 4353.19 -652.3999999999796 平空 9f88809c-8f0c-4dd4-b83c-552c6b78da3a b2c3aa90-dcc1-469d-bf31-6c74b8e4099b 2025-08-29 08:41:00
84 2025-08-29 16:40:40+08:00 2025-08-29 16:41:12+08:00 549.0 4348.53 4353.19 -2558.33999999992 平空 3efb68fb-7389-44fd-b48a-d749af57e70f b2c3aa90-dcc1-469d-bf31-6c74b8e4099b 2025-08-29 08:41:00
85 2025-08-29 18:24:56+08:00 2025-08-29 18:28:40+08:00 500.0 4354.11 4357.4 1644.9999999999818 平多 5b3555c7-8c22-45ad-a4b5-ef6b586335d5 88db631a-7f3b-4b85-9887-94f906259583 2025-08-29 10:28:00
86 2025-08-29 18:24:56+08:00 2025-08-29 18:28:40+08:00 189.0 4354.11 4357.4 621.8099999999931 平多 f6c1a4f1-6aa0-4645-b991-503a320913be 6132d1a3-6d55-4517-b5ba-115198948b85 2025-08-29 10:28:00
87 2025-08-29 18:30:45+08:00 2025-08-29 18:49:35+08:00 189.0 4351.51 4343.72 1472.3099999999931 平空 b67b7a3a-cf62-4731-bc9c-1d333f42e639 2d4f2adb-d806-4f37-8ff1-a46eddccc6b1 2025-08-29 10:49:00
88 2025-08-29 18:30:45+08:00 2025-08-29 18:49:35+08:00 500.0 4351.51 4343.72 3894.999999999982 平空 0acabab2-2ab4-4921-82a0-df806d4eb40d 2d4f2adb-d806-4f37-8ff1-a46eddccc6b1 2025-08-29 10:49:00
89 2025-08-29 18:58:56+08:00 2025-08-29 19:02:25+08:00 690.0 4345.89 4340.99 -3381.0000000003765 平多 b525febe-c7eb-4db9-a4f8-4a09406c9f7d 51ddc961-238a-4c9d-b985-e6ad6ef2aac7 2025-08-29 11:02:00
90 2025-08-29 19:14:13+08:00 2025-08-29 19:18:33+08:00 689.0 4351.49 4346.64 -3341.649999999624 平多 da8dccbd-f79c-476b-9471-d28b719da66f cfbfe97f-e085-41db-8679-58574bd165fd 2025-08-29 11:18:00
91 2025-08-29 19:49:41+08:00 2025-08-29 19:51:55+08:00 690.0 4345.68 4340.66 -3463.800000000301 平多 98c03fb1-dca8-43ef-9ca7-0fe6d842946b e0c7b8be-c842-412e-bb4f-e43b51fa53bb 2025-08-29 11:51:00
92 2025-08-29 20:22:08+08:00 2025-08-29 20:30:35+08:00 687.0 4365.85 4411.23 31176.059999999452 平多 7ab49fe4-9bd7-4368-bb45-ffe9970e4999 c3d6e447-288e-48d1-8977-ccceda6a2e41 2025-08-29 12:30:00
93 2025-08-29 20:31:05+08:00 2025-08-29 20:31:21+08:00 16.0 4439.0 4448.35 149.60000000000582 平多 76a58764-fd12-4fb4-8ee9-407aa2213a12 e3f58dbc-6a93-4c16-9dc3-7e351493f00f 2025-08-29 12:31:00
94 2025-08-29 20:31:05+08:00 2025-08-29 20:31:21+08:00 659.0 4439.0 4448.35 6161.65000000024 平多 cdd4a741-4195-4fac-9896-35ee5c09a7b9 e3f58dbc-6a93-4c16-9dc3-7e351493f00f 2025-08-29 12:31:00
95 2025-08-29 20:31:46+08:00 2025-08-29 20:33:05+08:00 180.0 4409.9 4406.3 -647.9999999999018 平多 a47f68a7-9565-4ea7-b3ab-770d376ffcea 46e071a8-871b-4373-92a5-8cd6cd46cc56 2025-08-29 12:33:00
96 2025-08-29 20:31:46+08:00 2025-08-29 20:33:05+08:00 500.0 4409.9 4406.3 -1799.9999999997272 平多 a47f68a7-9565-4ea7-b3ab-770d376ffcea c67209e2-0598-443d-85fa-752bdae6059b 2025-08-29 12:33:00
97 2025-08-29 20:43:25+08:00 2025-08-29 20:44:07+08:00 684.0 4382.62 4386.13 -2400.8400000001493 平空 af3305f0-ec39-48fe-bf71-ac9acb281b25 7556c209-5046-4e8b-8682-99dc36803a62 2025-08-29 12:44:00
98 2025-08-29 20:45:44+08:00 2025-08-29 20:49:11+08:00 102.0 4389.13 4407.06 1828.8600000000297 平多 a19435e4-fbf9-4217-bc5d-d7fc07d9818f cc0577e9-e4b6-45fd-bf5a-47ccf6aec320 2025-08-29 12:49:00
99 2025-08-29 20:45:44+08:00 2025-08-29 20:49:11+08:00 581.0 4389.13 4407.06 10417.33000000017 平多 a19435e4-fbf9-4217-bc5d-d7fc07d9818f 4fa96e6c-6692-426b-beca-c138c8505a82 2025-08-29 12:49:00
100 2025-08-29 20:49:46+08:00 2025-08-29 20:53:14+08:00 500.0 4406.49 4406.02 234.99999999967258 平空 d11f3a55-a1d8-41ff-a979-778c232459c9 b2de5ff9-9281-4c2e-86bd-a071a5e1e864 2025-08-29 12:53:00
101 2025-08-29 20:49:46+08:00 2025-08-29 20:53:14+08:00 180.0 4406.49 4406.02 84.59999999988213 平空 d11f3a55-a1d8-41ff-a979-778c232459c9 a4e3c4e5-4280-417c-8018-8386a63c318a 2025-08-29 12:53:00
102 2025-08-29 21:00:24+08:00 2025-08-29 21:00:33+08:00 680.0 4408.35 4405.11 -2203.20000000047 平多 26e94954-9b31-48a9-9b2b-cb08da0f8e3e 14772435-8e33-4ee5-a87c-81342a7f8449 2025-08-29 13:00:00
103 2025-08-29 21:01:47+08:00 2025-08-29 21:06:54+08:00 39.0 4406.15 4391.41 574.8599999999915 平空 8665f24a-3e13-4d3f-ad28-a702c79c73ed 7addab21-fcf3-4921-97ab-d77462067550 2025-08-29 13:06:00
104 2025-08-29 21:01:47+08:00 2025-08-29 21:06:54+08:00 141.0 4406.15 4391.41 2078.339999999969 平空 0170663d-0cf1-43a4-8595-4511c59b3107 7addab21-fcf3-4921-97ab-d77462067550 2025-08-29 13:06:00
105 2025-08-29 21:01:47+08:00 2025-08-29 21:06:54+08:00 500.0 4406.15 4391.41 7369.999999999891 平空 0170663d-0cf1-43a4-8595-4511c59b3107 3b754022-7c7c-4b14-8251-c2da4478df27 2025-08-29 13:06:00
106 2025-08-29 21:10:41+08:00 2025-08-29 21:11:27+08:00 14.0 4400.55 4392.88 -107.38000000000102 平多 37e79409-f3ed-4e62-811c-6cc437396a41 f3a43d61-4d64-4d82-aada-31b38d441baa 2025-08-29 13:11:00
107 2025-08-29 21:10:41+08:00 2025-08-29 21:11:27+08:00 67.0 4400.55 4392.79 -519.9200000000146 平多 37e79409-f3ed-4e62-811c-6cc437396a41 86bfa728-af41-4e41-9e87-d6ef88b1a063 2025-08-29 13:11:00
108 2025-08-29 21:10:41+08:00 2025-08-29 21:11:27+08:00 600.0 4400.55 4392.88 -4602.000000000044 平多 37e79409-f3ed-4e62-811c-6cc437396a41 af01f0d0-8844-4267-8476-4000d0b2dd8b 2025-08-29 13:11:00
109 2025-08-29 21:30:11+08:00 2025-08-29 21:34:27+08:00 72.0 4386.05 4373.6 896.3999999999869 平空 fecb81e1-3b36-4ae6-91ad-b6a2616ee608 aee7c322-ba5d-4b89-8b93-1c50ce5be75b 2025-08-29 13:34:00
110 2025-08-29 21:30:11+08:00 2025-08-29 21:34:27+08:00 211.0 4386.05 4372.44 2871.710000000123 平空 fecb81e1-3b36-4ae6-91ad-b6a2616ee608 e20951ed-ff4e-4a06-8bb5-8112a72e38bf 2025-08-29 13:34:00
111 2025-08-29 21:30:11+08:00 2025-08-29 21:34:27+08:00 99.0 4386.05 4372.44 1347.3900000000576 平空 fecb81e1-3b36-4ae6-91ad-b6a2616ee608 16329965-69b4-42a4-8145-79d1a0d2e92b 2025-08-29 13:34:00
112 2025-08-29 21:30:11+08:00 2025-08-29 21:34:27+08:00 101.0 4386.29 4372.44 1398.8500000000367 平空 f1e4b54c-d392-4dc4-8f73-40a8733b85fe 16329965-69b4-42a4-8145-79d1a0d2e92b 2025-08-29 13:34:00
113 2025-08-29 21:30:11+08:00 2025-08-29 21:34:27+08:00 200.0 4386.29 4372.44 2770.0000000000728 平空 f1e4b54c-d392-4dc4-8f73-40a8733b85fe 1b66a876-041a-480e-a9d6-428a3e301ec4 2025-08-29 13:34:00
114 2025-08-30 08:15:30+08:00 2025-08-30 08:25:24+08:00 400.0 4343.62 4355.47 4740.0000000001455 平多 fb636839-9fb2-4e2f-bdb0-14bd57ade58a 6b8d4b73-132c-4c86-92f9-2a5df18943fd 2025-08-30 00:25:00
115 2025-08-30 08:15:30+08:00 2025-08-30 08:25:24+08:00 290.0 4343.62 4355.47 3436.5000000001055 平多 fb636839-9fb2-4e2f-bdb0-14bd57ade58a a744bd39-3c81-4cb1-a153-60ed71d6748f 2025-08-30 00:25:00
116 2025-08-30 08:32:12+08:00 2025-08-30 08:35:26+08:00 64.0 4342.48 4337.98 -288.0 平多 e6185c1c-debd-4a9c-928c-edd28b360578 401ccb35-f82c-4df2-9a29-f9cd57481767 2025-08-30 00:35:00
117 2025-08-30 08:32:12+08:00 2025-08-30 08:35:26+08:00 563.0 4342.48 4335.64 -3850.91999999957 平多 e6185c1c-debd-4a9c-928c-edd28b360578 69d6c400-d534-47b6-b2a8-8da09b2986aa 2025-08-30 00:35:00
118 2025-08-30 08:32:12+08:00 2025-08-30 08:35:26+08:00 63.0 4342.48 4335.73 -425.25 平多 e6185c1c-debd-4a9c-928c-edd28b360578 4aa4a001-f8b0-4aea-93c3-546c71b81ee0 2025-08-30 00:35:00
119 2025-08-30 08:37:25+08:00 2025-08-30 08:41:59+08:00 691.0 4336.85 4332.05 3316.8000000001257 平空 5cc6dd95-ec96-4864-a085-95b875673f0f 07f9b455-a026-41df-95c6-f9cf37f23a90 2025-08-30 00:41:00
120 2025-08-30 09:26:28+08:00 2025-08-30 09:29:48+08:00 293.0 4326.54 4324.64 556.6999999998934 平空 ce7db548-7de1-448e-92c9-25139a5f23a4 70062cb1-9074-49a9-8e7f-b5b7bae639d4 2025-08-30 01:29:00
121 2025-08-30 09:26:28+08:00 2025-08-30 09:29:48+08:00 400.0 4326.54 4323.46 1231.999999999971 平空 ce7db548-7de1-448e-92c9-25139a5f23a4 6145a0a3-248c-4822-8e8c-5efb6daf7d24 2025-08-30 01:29:00
122 2025-08-30 09:51:41+08:00 2025-08-30 09:55:09+08:00 177.0 4312.57 4289.19 4138.260000000019 平空 4b786a41-410d-4c93-b1c6-30b118f9e7f2 f78be76a-092e-4e0e-b8c3-26867d78c1de 2025-08-30 01:55:00
123 2025-08-30 09:51:41+08:00 2025-08-30 09:55:09+08:00 518.0 4312.57 4289.19 12110.840000000057 平空 96fbc46a-1dd3-4fc6-9e14-4a032e9464bf f78be76a-092e-4e0e-b8c3-26867d78c1de 2025-08-30 01:55:00
124 2025-08-30 09:55:49+08:00 2025-08-30 09:55:50+08:00 700.0 4282.58 4282.19 -273.0000000002292 平多 201dbee0-8f0d-427d-95d5-ef84e08a8aab 37ff5d0c-e10e-480c-91ca-0506e61330b6 2025-08-30 01:55:00
125 2025-08-30 09:58:19+08:00 2025-08-30 09:58:59+08:00 700.0 4281.59 4280.23 -952.0000000004075 平多 0e651112-db3b-402d-a268-1ea200cf8729 65b07548-3473-4570-be22-0172c49bdb94 2025-08-30 01:58:00
126 2025-08-30 10:00:09+08:00 2025-08-30 10:00:52+08:00 703.0 4264.04 4268.35 -3029.9300000002813 平空 d9703fdd-ea02-410d-8303-d1d13b94748f 17fca37e-fc89-48a9-92ed-671ab0b9088e 2025-08-30 02:00:00
127 2025-08-30 10:01:23+08:00 2025-08-30 10:02:02+08:00 110.0 4268.54 4271.97 -377.300000000032 平空 022ce461-b78f-4127-9157-8c34a5e9272e 89468587-89ce-49cc-a9e3-343e24cb8036 2025-08-30 02:02:00
128 2025-08-30 10:01:23+08:00 2025-08-30 10:02:02+08:00 592.0 4268.54 4271.97 -2030.5600000001723 平空 9bdcfab5-9b8e-447c-b4ac-a82724e2774d 89468587-89ce-49cc-a9e3-343e24cb8036 2025-08-30 02:02:00
129 2025-08-30 10:02:55+08:00 2025-08-30 10:04:26+08:00 400.0 4275.14 4280.56 -2168.000000000029 平空 1b938bf4-dc99-4d2f-9e0b-c2fa5092d19d 4e6c40d8-e7c7-45ac-800e-5f71611479f1 2025-08-30 02:04:00
130 2025-08-30 10:02:55+08:00 2025-08-30 10:04:26+08:00 141.0 4275.14 4280.56 -764.2200000000103 平空 1b938bf4-dc99-4d2f-9e0b-c2fa5092d19d 864390a3-33dd-4a47-a3c2-471b8a0104f1 2025-08-30 02:04:00
131 2025-08-30 10:02:55+08:00 2025-08-30 10:04:26+08:00 160.0 4275.14 4280.56 -867.2000000000116 平空 7eb3eaf4-30fa-495d-a74c-61d725625c42 864390a3-33dd-4a47-a3c2-471b8a0104f1 2025-08-30 02:04:00
132 2025-08-30 10:11:35+08:00 2025-08-30 10:18:43+08:00 232.0 4296.88 4306.91 2326.959999999941 平多 b1a002d6-951f-4912-b8cf-19bfc98f61ba 743a1e0f-48f3-43fe-9b6a-47536fa12ce1 2025-08-30 02:18:00
133 2025-08-30 10:11:35+08:00 2025-08-30 10:18:43+08:00 466.0 4296.91 4306.91 4660.0 平多 94664c85-6be6-42d8-984a-f3293ed9750f 743a1e0f-48f3-43fe-9b6a-47536fa12ce1 2025-08-30 02:18:00
134 2025-08-30 10:21:54+08:00 2025-08-30 10:27:07+08:00 696.0 4307.47 4306.32 800.4000000003798 平空 641e7574-db24-4c78-8782-566b13de1e39 817cbe73-8f5f-4c27-893c-ddfe59e1890d 2025-08-30 02:27:00
135 2025-08-30 10:28:32+08:00 2025-08-30 10:35:18+08:00 500.0 4305.75 4311.46 2855.000000000018 平多 dee31b34-3e7f-4b74-8774-ccd70f3cb124 d37eec35-4b90-42c7-82e7-7a56e909d268 2025-08-30 02:35:00
136 2025-08-30 10:28:32+08:00 2025-08-30 10:35:18+08:00 196.0 4305.75 4311.25 1078.0 平多 dee31b34-3e7f-4b74-8774-ccd70f3cb124 9cbf242a-7e93-4a3c-b798-6e3f7a88025d 2025-08-30 02:35:00
137 2025-08-30 10:48:32+08:00 2025-08-30 10:57:53+08:00 695.0 4313.05 4303.81 6421.799999999848 平空 0efcab97-a0b6-4cd6-ad7e-22911ea32fa2 57fa177a-12c5-4127-91c4-289668a191ae 2025-08-30 02:57:00
138 2025-08-30 11:03:45+08:00 2025-08-30 11:10:25+08:00 296.0 4308.11 4322.99 4404.480000000032 平多 36e3b573-d4be-4d54-9af3-8190731448c9 1e9213a7-3443-4209-a26a-d3e0feeaf325 2025-08-30 03:10:00
139 2025-08-30 11:03:45+08:00 2025-08-30 11:10:25+08:00 400.0 4308.11 4322.99 5952.000000000044 平多 36e3b573-d4be-4d54-9af3-8190731448c9 a344d092-7b22-4230-8ba9-0702dd353041 2025-08-30 03:10:00
140 2025-08-30 11:11:04+08:00 2025-08-30 11:17:45+08:00 693.0 4323.24 4328.87 3901.5900000000756 平多 c2e861bb-6de2-4dc0-aed3-7a385c0f34b8 d786c18b-8199-4335-ad6b-6115f39e089f 2025-08-30 03:17:00
141 2025-08-30 11:18:36+08:00 2025-08-30 11:23:02+08:00 400.0 4333.76 4358.0 9695.999999999913 平多 3c5242f4-5844-46a7-8b84-a6c73fed27c7 d71ce99c-8d8e-4f15-be2e-85d21e853298 2025-08-30 03:23:00
142 2025-08-30 11:18:36+08:00 2025-08-30 11:23:02+08:00 134.0 4333.76 4358.0 3248.1599999999708 平多 3c5242f4-5844-46a7-8b84-a6c73fed27c7 fe3607bd-9257-42ce-a0b3-06d882cb74af 2025-08-30 03:23:00
143 2025-08-30 11:18:36+08:00 2025-08-30 11:23:02+08:00 158.0 4333.76 4358.0 3829.9199999999655 平多 ce9f82f0-70a9-44b1-9175-4ee31dbc8fd6 fe3607bd-9257-42ce-a0b3-06d882cb74af 2025-08-30 03:23:00
144 2025-08-30 11:52:34+08:00 2025-08-30 11:57:42+08:00 69.0 4352.62 4352.32 -20.70000000001255 平多 a7a38452-b2e4-46c1-a14c-d85c0a79b250 078499df-67ff-4bdd-acaf-4e4fcf4457c0 2025-08-30 03:57:00
145 2025-08-30 11:52:34+08:00 2025-08-30 11:57:42+08:00 620.0 4352.62 4352.32 -186.00000000011278 平多 76c6328b-ae56-4313-9b73-3bc43f644ef4 078499df-67ff-4bdd-acaf-4e4fcf4457c0 2025-08-30 03:57:00
146 2025-08-30 12:01:25+08:00 2025-08-30 12:07:56+08:00 500.0 4351.41 4357.44 -3014.9999999998727 平空 2228c2d3-6d7b-4835-8065-42ce6ad3a5af 3544a077-b511-45ef-b088-c380928048ee 2025-08-30 04:07:00
147 2025-08-30 12:01:25+08:00 2025-08-30 12:07:56+08:00 121.0 4351.7 4357.44 -694.5399999999736 平空 e33d8985-328c-4a44-829e-b8ebf6127582 3544a077-b511-45ef-b088-c380928048ee 2025-08-30 04:07:00
148 2025-08-30 12:01:25+08:00 2025-08-30 12:07:56+08:00 527.0 4351.41 4357.44 -3177.809999999866 平空 6f169ccd-3d5a-4e35-9653-7efd0a1580dc 3544a077-b511-45ef-b088-c380928048ee 2025-08-30 04:07:00
149 2025-08-30 13:01:32+08:00 2025-08-30 13:07:24+08:00 577.0 4353.26 4358.47 -3006.170000000021 平空 27412351-b7db-41d2-941e-014723b46c1a f65cc5f5-8a78-4a59-bb58-cf0af4df8448 2025-08-30 05:07:00
150 2025-08-30 13:01:33+08:00 2025-08-30 13:07:24+08:00 298.0 4353.26 4358.47 -1552.5800000000108 平空 cab58243-ce8d-4149-b279-3417eac36fcd f65cc5f5-8a78-4a59-bb58-cf0af4df8448 2025-08-30 05:07:00
151 2025-08-30 13:01:33+08:00 2025-08-30 13:07:24+08:00 273.0 4353.26 4359.1 -1594.3200000000397 平空 cab58243-ce8d-4149-b279-3417eac36fcd c28367f5-fcb9-4345-82f2-c56451e2e462 2025-08-30 05:07:00
152 2025-08-30 13:20:13+08:00 2025-08-30 13:32:38+08:00 1143.0 4373.03 4377.0 -4537.710000000291 平空 0f73205b-a08a-4fad-9e77-f5d2fbbf1aee 6d5e0a1c-53e6-4fac-a76a-77cb3341a976 2025-08-30 05:32:00
153 2025-08-30 13:33:46+08:00 2025-08-30 13:42:14+08:00 1140.0 4385.31 4391.97 7592.399999999834 平多 11f0898c-7cba-49da-91d9-1fc6e9b57ab2 e7744350-f030-4566-bdeb-8a76060f8066 2025-08-30 05:42:00
154 2025-08-30 13:48:01+08:00 2025-08-30 13:56:36+08:00 1137.0 4395.74 4382.93 14564.96999999942 平空 d00ac585-7cde-477d-af47-a5889aa5ef70 e99ef7df-85e7-46b4-bc8a-4a6f2fc811fe 2025-08-30 05:56:00
155 2025-08-30 13:58:04+08:00 2025-08-30 14:03:08+08:00 1141.0 4381.43 4385.01 -4084.779999999917 平空 76216a51-657b-4659-86cb-2295aa642dac 8a9ab27e-38f2-4ec3-bbaf-642afd20a6e5 2025-08-30 06:03:00
156 2025-08-30 14:10:44+08:00 2025-08-30 14:15:13+08:00 601.0 4383.15 4377.63 3317.5199999997158 平空 587020d7-a3eb-4e44-b6c7-5c95b8c5451a 8ecfa693-c528-405b-8db4-0b02ccc7b9b3 2025-08-30 06:15:00
157 2025-08-30 14:10:44+08:00 2025-08-30 14:15:13+08:00 500.0 4383.15 4377.63 2759.9999999997635 平空 587020d7-a3eb-4e44-b6c7-5c95b8c5451a babe1585-607c-4004-9aa9-19e1f5374ac1 2025-08-30 06:15:00
158 2025-08-30 14:10:44+08:00 2025-08-30 14:15:13+08:00 39.0 4383.15 4377.63 215.27999999998156 平空 587020d7-a3eb-4e44-b6c7-5c95b8c5451a ab4e9d81-4133-42b0-9460-9a2efd36ec0b 2025-08-30 06:15:00
159 2025-08-30 14:26:36+08:00 2025-08-30 14:33:14+08:00 1140.0 4384.3 4391.39 8082.600000000166 平多 f703a5cc-3428-4796-a288-bfa6442800cb a4e60efd-9afc-48b1-8850-6054e1330780 2025-08-30 06:33:00
160 2025-08-30 14:45:13+08:00 2025-08-30 14:52:41+08:00 1137.0 4395.22 4390.35 5537.189999999876 平空 b1f16517-7b15-43a4-a3e7-8f0b60f9f732 0445e9e3-c80c-4beb-a121-18b6094f52eb 2025-08-30 06:52:00
161 2025-08-30 15:20:15+08:00 2025-08-30 15:40:40+08:00 52.0 4392.17 4398.92 -351.0 平空 504ad303-3016-470e-9deb-a717d25a761c 9a648f36-ef00-45a4-8e56-868ab74acce6 2025-08-30 07:40:00
162 2025-08-30 15:20:15+08:00 2025-08-30 15:40:40+08:00 500.0 4392.17 4398.92 -3375.0 平空 59f674e3-aff1-4b79-b8b0-c650b299d27d 9a648f36-ef00-45a4-8e56-868ab74acce6 2025-08-30 07:40:00
163 2025-08-30 15:20:15+08:00 2025-08-30 15:40:40+08:00 586.0 4392.17 4398.92 -3955.5 平空 77548f6a-59ae-4ac2-880c-ea1f5679f507 9a648f36-ef00-45a4-8e56-868ab74acce6 2025-08-30 07:40:00
164 2025-08-30 15:46:04+08:00 2025-08-30 15:50:09+08:00 1134.0 4408.51 4402.78 -6497.820000000536 平多 76eb4bce-ff36-4d4c-b97a-cda6d9f7b544 63f7184c-7211-417f-b594-e39436d14940 2025-08-30 07:50:00
165 2025-08-30 16:11:35+08:00 2025-08-30 16:32:13+08:00 400.0 4393.35 4389.12 1692.0000000001892 平空 be9ff2ce-0d9e-4184-8d43-c49b33c71c95 754db465-b458-43a3-b2b5-3fb4f9fc2aaf 2025-08-30 08:32:00
166 2025-08-30 16:11:35+08:00 2025-08-30 16:32:13+08:00 500.0 4393.35 4389.12 2115.0000000002365 平空 cdf388db-68a2-47ea-ba94-431f02dadeac 754db465-b458-43a3-b2b5-3fb4f9fc2aaf 2025-08-30 08:32:00
167 2025-08-30 16:11:35+08:00 2025-08-30 16:32:13+08:00 237.0 4393.35 4389.12 1002.5100000001121 平空 e6f8d379-c20f-4a9d-90a4-7a5904bff1f9 754db465-b458-43a3-b2b5-3fb4f9fc2aaf 2025-08-30 08:32:00
168 2025-08-30 17:05:10+08:00 2025-08-30 17:11:26+08:00 133.0 4390.54 4387.01 469.48999999996613 平空 d4db2208-ba63-42c7-af51-9cec92bfe6f1 46858333-121c-4020-9567-bc44d63dec01 2025-08-30 09:11:00
169 2025-08-30 17:05:10+08:00 2025-08-30 17:11:26+08:00 190.0 4390.54 4387.01 670.6999999999516 平空 d4db2208-ba63-42c7-af51-9cec92bfe6f1 4d19376a-cfb7-4da9-8859-982e073624d1 2025-08-30 09:11:00
170 2025-08-30 17:05:10+08:00 2025-08-30 17:11:26+08:00 310.0 4390.54 4387.01 1094.299999999921 平空 00dda8f5-7156-4d25-9ea0-29e5fb2a4aca 4d19376a-cfb7-4da9-8859-982e073624d1 2025-08-30 09:11:00
171 2025-08-30 17:05:10+08:00 2025-08-30 17:11:26+08:00 505.0 4390.54 4387.01 1782.6499999998714 平空 00dda8f5-7156-4d25-9ea0-29e5fb2a4aca e28b9838-7c48-4c78-a369-8259844cc3f4 2025-08-30 09:11:00
172 2025-08-30 17:18:39+08:00 2025-08-30 17:28:37+08:00 1139.0 4389.73 4385.08 -5296.349999999586 平多 2789c169-8a5d-47da-a6f9-6800e72ec26e cd9481fb-33de-4e75-beb8-119ace92b5f6 2025-08-30 09:28:00
173 2025-08-30 17:31:17+08:00 2025-08-30 17:37:08+08:00 1141.0 4379.77 4384.13 -4974.759999999626 平空 434fc13a-925d-4abd-8677-0cd2b1a412f0 1e63ca1f-7f77-4ed9-a885-159f5dac641e 2025-08-30 09:37:00
174 2025-08-30 17:44:10+08:00 2025-08-30 17:48:40+08:00 1140.0 4384.13 4388.17 -4605.5999999999585 平空 288b4dc7-affd-4b36-897a-e02a024dbae0 70c0e310-219d-45d2-a91d-6b685af4a065 2025-08-30 09:48:00
175 2025-08-30 17:50:34+08:00 2025-08-30 17:54:02+08:00 1138.0 4389.94 4393.0 3482.2800000004554 平多 b78acf6a-d3b3-44c2-b484-ad95dfedd167 9473c228-7657-44cd-9038-38aeb833c3ab 2025-08-30 09:54:00
176 2025-08-30 18:05:09+08:00 2025-08-30 18:07:30+08:00 1138.0 4392.24 4394.52 2594.640000000745 平多 44cd4f02-5250-47d0-8e71-a66f856405ba 81abc1fa-1789-4f69-aaaa-2da1f3f34186 2025-08-30 10:07:00
177 2025-08-31 10:28:55+08:00 2025-08-31 10:34:47+08:00 326.0 4450.3 4446.25 -1320.3000000000593 平多 0fe00795-d7d9-4586-b864-e445017c7f9d 716e265c-d39a-46b3-92e2-99f5d8a6b45f 2025-08-31 02:34:00
178 2025-08-31 10:28:55+08:00 2025-08-31 10:34:47+08:00 572.0 4450.3 4446.25 -2316.600000000104 平多 0fe00795-d7d9-4586-b864-e445017c7f9d e7b360d6-da94-4cb7-b8c7-0b10db53a03b 2025-08-31 02:34:00
179 2025-08-31 11:08:10+08:00 2025-08-31 11:12:01+08:00 897.0 4454.6 4458.68 -3659.7599999999347 平空 c31d66e2-a558-4b86-a520-3a9eb9d55346 f737efdc-5818-4bc5-b3db-1da76e7caf71 2025-08-31 03:12:00
180 2025-08-31 11:24:10+08:00 2025-08-31 11:27:33+08:00 508.0 4457.8 4453.59 -2138.6800000000185 平多 38413547-9d48-43fc-a2be-12d2a8e0cd9f ce5c15c0-d938-4b48-ab08-807531847f2e 2025-08-31 03:27:00
181 2025-08-31 11:24:10+08:00 2025-08-31 11:27:33+08:00 389.0 4457.8 4453.59 -1637.6900000000142 平多 816792ec-d409-4688-b7fd-2ee3e3f4491e ce5c15c0-d938-4b48-ab08-807531847f2e 2025-08-31 03:27:00
182 2025-08-31 11:49:43+08:00 2025-08-31 11:53:50+08:00 500.0 4462.28 4469.74 3730.000000000018 平多 b1e2c3bf-db41-4762-b152-7a6a469c8cdb 52c185f1-3f74-42b6-afe5-6032df9dcb11 2025-08-31 03:53:00
183 2025-08-31 11:49:43+08:00 2025-08-31 11:53:50+08:00 396.0 4462.28 4469.74 2954.1600000000144 平多 b1e2c3bf-db41-4762-b152-7a6a469c8cdb 5fbbe739-8d3c-4aab-8333-7860bdca1d69 2025-08-31 03:53:00
184 2025-08-31 11:54:26+08:00 2025-08-31 12:00:20+08:00 293.0 4475.79 4483.53 2267.819999999936 平多 614c6489-c5a5-451d-a2a0-699e38d5a695 5da7f47f-33e3-45b8-9dfe-8232807978fc 2025-08-31 04:00:00
185 2025-08-31 11:54:26+08:00 2025-08-31 12:00:20+08:00 200.0 4475.79 4483.53 1547.9999999999563 平多 c443995b-f986-4a55-b6d9-59c43fa71fd2 5da7f47f-33e3-45b8-9dfe-8232807978fc 2025-08-31 04:00:00
186 2025-08-31 11:54:26+08:00 2025-08-31 12:00:20+08:00 400.0 4475.79 4483.53 3095.9999999999127 平多 c443995b-f986-4a55-b6d9-59c43fa71fd2 7d96c3c9-b227-48f3-b9fe-9a5c08871cfe 2025-08-31 04:00:00
187 2025-08-31 12:15:25+08:00 2025-08-31 12:25:03+08:00 894.0 4473.35 4467.05 5632.200000000163 平空 d5064049-73a7-4a01-8d14-3d0ba056d572 b4537133-4056-4afc-80c2-7656e28cff88 2025-08-31 04:25:00
188 2025-08-31 12:30:21+08:00 2025-08-31 12:33:51+08:00 500.0 4461.85 4465.99 -2069.999999999709 平空 516d9754-0fe4-4f2e-9289-5827765f7c67 13f52cac-de10-4bba-93d5-8376ba2c5139 2025-08-31 04:33:00
189 2025-08-31 12:30:21+08:00 2025-08-31 12:33:51+08:00 100.0 4461.85 4465.88 -402.99999999997453 平空 516d9754-0fe4-4f2e-9289-5827765f7c67 a77196b2-cc47-482b-8fb0-a140d25da936 2025-08-31 04:33:00
190 2025-08-31 12:30:21+08:00 2025-08-31 12:33:51+08:00 296.0 4461.85 4465.99 -1225.4399999998277 平空 516d9754-0fe4-4f2e-9289-5827765f7c67 c529dbf2-2dd4-46aa-b5b6-dd0ed4f473e2 2025-08-31 04:33:00
191 2025-08-31 12:42:50+08:00 2025-08-31 12:48:13+08:00 661.0 4464.2 4468.3 -2710.1000000002405 平空 0f3ef65f-e754-4229-87e6-e0f102020ce9 bce7cdc5-2c37-4bda-9b2a-05c865dd69ba 2025-08-31 04:48:00
192 2025-08-31 12:42:50+08:00 2025-08-31 12:48:13+08:00 235.0 4464.2 4468.3 -963.5000000000855 平空 10e40e0b-a920-4e80-8d17-ea6f73d645e3 bce7cdc5-2c37-4bda-9b2a-05c865dd69ba 2025-08-31 04:48:00
193 2025-08-31 13:31:35+08:00 2025-08-31 13:38:28+08:00 100.0 4453.99 4450.23 -376.0000000000218 平多 e65553ad-4738-4b5f-af08-c7373301aef8 ce3b836f-f3c8-4e27-bdd5-33b9e1ba2bc9 2025-08-31 05:38:00
194 2025-08-31 13:31:35+08:00 2025-08-31 13:38:28+08:00 600.0 4454.98 4450.23 -2850.0 平多 57f64aba-942f-4563-a3c7-9dfdfeaf98e4 ce3b836f-f3c8-4e27-bdd5-33b9e1ba2bc9 2025-08-31 05:38:00
195 2025-08-31 13:31:35+08:00 2025-08-31 13:38:28+08:00 198.0 4454.98 4450.23 -940.5 平多 597f272b-ce3c-45bf-99ee-4abe2f630972 ce3b836f-f3c8-4e27-bdd5-33b9e1ba2bc9 2025-08-31 05:38:00
196 2025-08-31 14:22:05+08:00 2025-08-31 14:23:54+08:00 275.0 4441.46 4446.28 -1325.49999999992 平空 eafee2f8-8601-47c7-bfe0-2f0a35bd1411 3744b6fa-5971-44d1-885f-7c7f93da8e70 2025-08-31 06:23:00
197 2025-08-31 14:22:05+08:00 2025-08-31 14:23:54+08:00 100.0 4442.21 4446.28 -406.9999999999709 平空 702cd777-dc0b-4602-8c19-618520cf46f4 3744b6fa-5971-44d1-885f-7c7f93da8e70 2025-08-31 06:23:00
198 2025-08-31 14:22:05+08:00 2025-08-31 14:23:54+08:00 525.0 4441.46 4446.28 -2530.499999999847 平空 be46bffb-290a-477a-81d9-fd4e7c1d2f3c 3744b6fa-5971-44d1-885f-7c7f93da8e70 2025-08-31 06:23:00
199 2025-08-31 14:33:49+08:00 2025-08-31 14:39:00+08:00 900.0 4439.81 4444.22 -3968.999999999869 平空 f25e9b2a-1bb7-4bc5-852e-5c953f222f61 2d0c6c6c-070a-498b-ade7-0235a6d3e644 2025-08-31 06:39:00
200 2025-08-31 14:40:14+08:00 2025-08-31 14:47:51+08:00 411.0 4444.0 4439.28 -1939.9200000001047 平多 46e5c712-8dff-423d-805d-d09da5e43571 9a2c96f9-3c09-4cca-8539-7251e96e99df 2025-08-31 06:47:00
201 2025-08-31 14:40:14+08:00 2025-08-31 14:47:51+08:00 400.0 4444.0 4439.13 -1947.9999999999563 平多 46e5c712-8dff-423d-805d-d09da5e43571 f92ff1ec-cfa2-4576-bcbb-978910e5200c 2025-08-31 06:47:00
202 2025-08-31 14:40:14+08:00 2025-08-31 14:47:51+08:00 89.0 4444.0 4439.13 -433.4299999999903 平多 46e5c712-8dff-423d-805d-d09da5e43571 5f572e4d-e1a7-45cf-bc1b-b55ce56f12b4 2025-08-31 06:47:00
203 2025-08-31 14:51:09+08:00 2025-08-31 14:57:17+08:00 450.0 4436.57 4435.16 634.4999999999345 平空 3d5b8a22-edc9-4076-8d61-23f8ed561202 9c959838-3125-426e-abaf-d09fc309fda2 2025-08-31 06:57:00
204 2025-08-31 15:30:46+08:00 2025-08-31 15:33:17+08:00 449.0 4450.96 4446.74 -1894.7800000001143 平多 45ada65c-b8e3-4316-9414-5faf1dcad582 57564f53-121e-47ac-8804-e448bb39c82c 2025-08-31 07:33:00
205 2025-08-31 16:05:31+08:00 2025-08-31 16:08:48+08:00 448.0 4461.21 4457.34 -1733.759999999951 平多 050937e7-f1e4-459e-982a-8d5263e718cb ad5c9d31-f050-4981-9f51-7852dbf0df37 2025-08-31 08:08:00
206 2025-08-31 16:20:45+08:00 2025-08-31 16:24:22+08:00 48.0 4463.0 4462.93 -3.35999999998603 平多 e41030f3-095f-4e36-b465-e7f7d20b2972 83b7259d-91f7-485a-92ee-37c94790c7f4 2025-08-31 08:24:00
207 2025-08-31 16:20:45+08:00 2025-08-31 16:24:22+08:00 400.0 4463.0 4462.93 -27.999999999883585 平多 e41030f3-095f-4e36-b465-e7f7d20b2972 de316218-6bb2-48c0-b540-fc4babf5ce9b 2025-08-31 08:24:00
208 2025-08-31 17:24:37+08:00 2025-08-31 17:27:28+08:00 447.0 4473.73 4467.56 2757.989999999626 平空 b8d42b12-b7c8-465d-a67b-56085ceae48f 74ed9f75-4d45-47a8-a636-5a1cbe5511ce 2025-08-31 09:27:00
209 2025-08-31 17:48:57+08:00 2025-08-31 17:52:50+08:00 448.0 4463.45 4470.31 3073.2800000002608 平多 9b9c8688-3c74-48c3-b1bf-6bbc162b3edf 70a47e37-f8fb-440f-9ea6-50ffbf8055f6 2025-08-31 09:52:00
210 2025-08-31 17:59:19+08:00 2025-08-31 18:00:09+08:00 152.0 4461.24 4465.19 -600.3999999999724 平空 28a00768-c1e1-42d0-b75e-f7b6b8608b60 9263141f-f5ac-4173-b3c2-b8e2f7ba0985 2025-08-31 10:00:00
211 2025-08-31 17:59:19+08:00 2025-08-31 18:00:09+08:00 520.0 4461.24 4465.19 -2053.9999999999054 平空 28a00768-c1e1-42d0-b75e-f7b6b8608b60 32d89f55-ae9c-49a6-8e2a-e47b5f4167ab 2025-08-31 10:00:00
212 2025-08-31 18:07:59+08:00 2025-08-31 18:12:30+08:00 672.0 4459.1 4452.94 4139.520000000513 平空 765d6b9a-0683-4dca-b76c-6e9a2ea65cd5 7f047d14-dac5-4fca-94ed-c0fdfec63578 2025-08-31 10:12:00
213 2025-08-31 18:17:18+08:00 2025-08-31 18:29:14+08:00 673.0 4451.84 4455.42 2409.339999999951 平多 755ad988-d66e-4bc8-9907-b69112e3a11a 775a3323-bbd4-4e5c-ae56-d68e178eb05e 2025-08-31 10:29:00
214 2025-08-31 22:07:31+08:00 2025-08-31 22:13:15+08:00 1122.0 4453.82 4450.0 4286.0399999996735 平空 c3c54d31-6a99-45ad-8139-546ac61bed34 ef4df9cc-3394-4d53-8fed-7e261a8b0c60 2025-08-31 14:13:00
215 2025-08-31 22:14:11+08:00 2025-08-31 22:20:53+08:00 500.0 4453.63 4459.25 2809.9999999999454 平多 18042f61-552b-41bb-b228-8d8031ee3c14 ad7b6056-101b-49e4-9b9f-dea68880cd52 2025-08-31 14:20:00
216 2025-08-31 22:14:11+08:00 2025-08-31 22:20:53+08:00 122.0 4453.63 4459.25 685.6399999999867 平多 208d18b8-941b-4ce3-aa29-2f5fb074cc01 ad7b6056-101b-49e4-9b9f-dea68880cd52 2025-08-31 14:20:00
217 2025-08-31 22:14:11+08:00 2025-08-31 22:20:53+08:00 500.0 4453.63 4459.25 2809.9999999999454 平多 4e557687-e4c4-4f2d-85b6-364f6e5fd752 ad7b6056-101b-49e4-9b9f-dea68880cd52 2025-08-31 14:20:00
218 2025-08-31 23:05:00+08:00 2025-08-31 23:09:16+08:00 1117.0 4473.11 4471.27 -2055.2799999991466 平多 41d06c42-ac03-418f-9451-6f5a5fdda71a 5cd65f94-490b-4bb2-bd42-d1a64942d201 2025-08-31 15:09:00
219 2025-09-01 09:07:41+08:00 2025-09-01 09:11:05+08:00 400.0 4394.0 4383.39 4243.999999999869 平空 092adf53-a461-4de7-8e04-9bfe1de8c387 b3e26049-21f9-495e-9a96-7498f06dcd82 2025-09-01 01:11:00
220 2025-09-01 09:07:41+08:00 2025-09-01 09:11:05+08:00 55.0 4394.0 4383.39 583.549999999982 平空 092adf53-a461-4de7-8e04-9bfe1de8c387 0614bd80-655c-49d4-b895-798f56f54803 2025-09-01 01:11:00
221 2025-09-01 09:20:32+08:00 2025-09-01 09:25:17+08:00 454.0 4399.41 4396.45 -1343.8400000000165 平多 ef1554ec-bb75-4b5d-a3fd-03325d8ce248 11fb1482-9f6a-4b3f-aec4-e0e9f46ec4eb 2025-09-01 01:25:00
222 2025-09-01 09:31:04+08:00 2025-09-01 09:32:03+08:00 453.0 4409.02 4405.26 -1703.2800000000989 平多 8050d64e-1c53-40e1-89e7-68481d09e689 079730bc-d8ce-413a-a77f-a889bed73972 2025-09-01 01:32:00
223 2025-09-01 09:34:47+08:00 2025-09-01 09:37:04+08:00 453.0 4405.92 4417.68 5327.280000000099 平多 4f3b316a-37b6-43b9-a742-28760ce5267b 18f19970-4048-485b-b95a-00b3e804d0d9 2025-09-01 01:37:00
224 2025-09-01 10:11:29+08:00 2025-09-01 10:16:05+08:00 400.0 4400.12 4391.86 3304.0000000000873 平空 9b7a45aa-4ed0-4fa2-9c77-ee71e8319ecf 6adc05fa-6727-4961-8ae9-ef7f248ce06f 2025-09-01 02:16:00
225 2025-09-01 10:11:30+08:00 2025-09-01 10:16:05+08:00 54.0 4400.12 4391.86 446.0400000000118 平空 a2b8e0df-1a70-4cbe-b513-734c169a45e5 6adc05fa-6727-4961-8ae9-ef7f248ce06f 2025-09-01 02:16:00
226 2025-09-01 10:29:03+08:00 2025-09-01 10:30:26+08:00 683.0 4389.33 4386.21 -2130.9599999999255 平多 9295d00e-a050-472f-b008-426e40eb0f71 73e0f83a-583a-4ae6-8dc3-41c2f37bb58e 2025-09-01 02:30:00
227 2025-09-01 10:35:00+08:00 2025-09-01 10:36:12+08:00 685.0 4375.45 4379.38 -2692.0500000001994 平空 8e5b463d-f4fe-47f3-b39b-ec3721c79e7a 2f96c834-2272-491f-8bc1-8cbe6c4ea452 2025-09-01 02:36:00
228 2025-09-01 11:03:26+08:00 2025-09-01 11:05:42+08:00 684.0 4383.62 4391.35 5287.3200000003235 平多 ad2ab2b0-b070-4027-ba77-039ae801c30b ab66e717-8f29-4ebe-80c7-165f36806e5f 2025-09-01 03:05:00
229 2025-09-01 11:12:18+08:00 2025-09-01 11:15:56+08:00 184.0 4382.88 4374.85 1477.5199999999531 平空 60e70f9e-3ed0-402a-a33e-0d9104ac17b6 2c200cb7-b183-474a-b78f-bba9e592c8c0 2025-09-01 03:15:00
230 2025-09-01 11:12:18+08:00 2025-09-01 11:15:56+08:00 500.0 4382.88 4374.85 4014.9999999998727 平空 4f57713c-6a4c-42d4-aa6b-c03bae934835 2c200cb7-b183-474a-b78f-bba9e592c8c0 2025-09-01 03:15:00
231 2025-09-01 11:34:38+08:00 2025-09-01 11:41:09+08:00 286.0 4370.18 4382.21 3440.579999999927 平多 7716be61-be89-4b30-8939-ff0c2c42b4e2 15dadfe0-75d8-4cc7-838d-931a1d21ccf8 2025-09-01 03:41:00
232 2025-09-01 11:34:38+08:00 2025-09-01 11:41:09+08:00 400.0 4370.18 4382.21 4811.999999999898 平多 7716be61-be89-4b30-8939-ff0c2c42b4e2 9ae0cd54-0bfb-4a24-8c7a-1a247e078eb8 2025-09-01 03:41:00
233 2025-09-01 11:54:59+08:00 2025-09-01 11:58:53+08:00 10.0 4396.0 4403.97 79.70000000000255 平多 b0876036-7e56-46cb-bddd-ccabb6519f7c 600628e2-049f-44c8-a905-46ea1135e601 2025-09-01 03:58:00
234 2025-09-01 11:54:59+08:00 2025-09-01 11:58:53+08:00 145.0 4396.47 4403.97 1087.5 平多 4bc131e8-70e0-4140-a2c8-b054e0507acd 600628e2-049f-44c8-a905-46ea1135e601 2025-09-01 03:58:00
235 2025-09-01 11:54:59+08:00 2025-09-01 11:58:53+08:00 355.0 4396.47 4403.97 2662.5 平多 4bc131e8-70e0-4140-a2c8-b054e0507acd 9d3eca96-2443-4c6e-b40e-1020bde26895 2025-09-01 03:58:00
236 2025-09-01 11:54:59+08:00 2025-09-01 11:58:53+08:00 172.0 4396.47 4403.97 1290.0 平多 86ab0723-57a8-4e31-9000-9b73f49ad308 9d3eca96-2443-4c6e-b40e-1020bde26895 2025-09-01 03:58:00
237 2025-09-01 12:19:34+08:00 2025-09-01 12:23:09+08:00 500.0 4389.68 4388.07 805.000000000291 平空 2aec9027-7a84-45c2-83d3-8c5871d90106 95aa0191-4e59-46b0-b538-e0a3fd31a029 2025-09-01 04:23:00
238 2025-09-01 12:19:34+08:00 2025-09-01 12:23:09+08:00 87.0 4389.68 4388.0 146.16000000002532 平空 2aec9027-7a84-45c2-83d3-8c5871d90106 861ff638-8ec8-4a6a-bafa-74206b093040 2025-09-01 04:23:00
239 2025-09-01 12:19:34+08:00 2025-09-01 12:23:09+08:00 52.0 4389.68 4388.07 83.72000000003027 平空 2aec9027-7a84-45c2-83d3-8c5871d90106 6cff4ab5-d999-4dda-87e2-067c9adbd240 2025-09-01 04:23:00
240 2025-09-01 12:19:34+08:00 2025-09-01 12:23:09+08:00 500.0 4389.68 4388.07 805.000000000291 平空 2aec9027-7a84-45c2-83d3-8c5871d90106 4dc3eeb9-b54d-4820-bc73-2172e8e5fd66 2025-09-01 04:23:00
241 2025-09-01 12:52:26+08:00 2025-09-01 12:56:26+08:00 1141.0 4381.97 4385.85 4427.0800000001245 平多 a3ef0945-101d-4f17-9cda-711fe44e2cf1 ab314993-0d4e-4632-8bcd-66aaaef57066 2025-09-01 04:56:00
242 2025-09-01 13:11:24+08:00 2025-09-01 13:12:28+08:00 475.0 4363.3 4368.36 -2403.499999999758 平空 4d1d7cf6-26fe-44f0-be21-d10a9871ae1a 53f10353-21b1-41c1-8554-18c5bac4991a 2025-09-01 05:12:00
243 2025-09-01 13:11:24+08:00 2025-09-01 13:12:28+08:00 400.0 4363.3 4368.36 -2023.9999999997963 平空 63978423-878f-4bc0-8ac6-7526d1aa3b24 53f10353-21b1-41c1-8554-18c5bac4991a 2025-09-01 05:12:00
244 2025-09-01 13:11:24+08:00 2025-09-01 13:12:28+08:00 500.0 4363.3 4368.36 -2529.9999999997453 平空 9736d4ed-bfd4-4fb4-a2b9-7a335070a480 53f10353-21b1-41c1-8554-18c5bac4991a 2025-09-01 05:12:00
245 2025-09-01 13:19:17+08:00 2025-09-01 13:20:04+08:00 1376.0 4357.3 4364.42 -9797.11999999985 平空 9d7b259b-c1ec-4d54-83c5-e1588347d99f a63b68c2-d467-4b4b-992a-175e562a59cd 2025-09-01 05:20:00
246 2025-09-01 13:23:06+08:00 2025-09-01 13:33:39+08:00 291.0 4390.89 4384.71 -1798.3800000000847 平多 348b7ba0-df18-4d21-b652-1c54dc5b4635 2a709f71-d330-49c0-9759-3b65a140431c 2025-09-01 05:33:00
247 2025-09-01 13:23:06+08:00 2025-09-01 13:33:39+08:00 300.0 4390.89 4384.71 -1854.0000000000873 平多 c8c60f9e-a45b-4f5a-b000-a1a436757403 2a709f71-d330-49c0-9759-3b65a140431c 2025-09-01 05:33:00
248 2025-09-01 13:23:06+08:00 2025-09-01 13:33:39+08:00 300.0 4390.89 4384.71 -1854.0000000000873 平多 970891fc-d2ec-4c54-a196-7a450a88c968 2a709f71-d330-49c0-9759-3b65a140431c 2025-09-01 05:33:00
249 2025-09-01 13:23:06+08:00 2025-09-01 13:33:39+08:00 20.0 4390.01 4384.71 -106.00000000000364 平多 71cd000e-8c95-4f6f-a32f-1440db6e8c0d 2a709f71-d330-49c0-9759-3b65a140431c 2025-09-01 05:33:00
250 2025-09-01 13:49:13+08:00 2025-09-01 13:54:15+08:00 287.0 4396.35 4396.21 -40.18000000009397 平多 83a1a14a-a4e3-40f1-86bd-915987501b35 4c298f23-9a76-4a0f-8bc1-f8ed23f12ede 2025-09-01 05:54:00
251 2025-09-01 13:49:13+08:00 2025-09-01 13:54:15+08:00 200.0 4396.35 4396.21 -28.000000000065484 平多 83a1a14a-a4e3-40f1-86bd-915987501b35 46728c29-6645-408a-bba2-07f01cd5d06d 2025-09-01 05:54:00
252 2025-09-01 13:49:13+08:00 2025-09-01 13:54:15+08:00 13.0 4396.35 4396.21 -1.8200000000042564 平多 83a1a14a-a4e3-40f1-86bd-915987501b35 c4cb8611-b4dd-41fd-95c2-c9455c1237e6 2025-09-01 05:54:00
253 2025-09-01 13:49:13+08:00 2025-09-01 13:54:15+08:00 187.0 4396.35 4396.21 -26.180000000061227 平多 47230a4e-8ee9-4d68-aa51-01753afc623b c4cb8611-b4dd-41fd-95c2-c9455c1237e6 2025-09-01 05:54:00
254 2025-09-01 13:49:13+08:00 2025-09-01 13:54:15+08:00 213.0 4396.35 4396.13 -46.86000000005424 平多 47230a4e-8ee9-4d68-aa51-01753afc623b e06fcad9-5742-4c94-82eb-2f34884e3f4a 2025-09-01 05:54:00
255 2025-09-01 13:49:14+08:00 2025-09-01 13:54:15+08:00 9.0 4396.35 4396.13 -1.980000000002292 平多 1743d43c-c642-434b-940f-b6d33e6718b9 e06fcad9-5742-4c94-82eb-2f34884e3f4a 2025-09-01 05:54:00
256 2025-09-01 15:34:19+08:00 2025-09-01 15:35:08+08:00 403.0 4429.5 4426.01 -1406.469999999912 平多 e9dad14a-702d-4396-a259-38e6c3b62876 76c3e1c9-aeee-41bd-b8d4-37e8948af1c4 2025-09-01 07:35:00
257 2025-09-01 15:34:19+08:00 2025-09-01 15:35:08+08:00 500.0 4429.5 4426.01 -1744.9999999998909 平多 431b7e4b-b81e-4626-a6de-f5acd5a7cf20 76c3e1c9-aeee-41bd-b8d4-37e8948af1c4 2025-09-01 07:35:00
258 2025-09-01 15:36:02+08:00 2025-09-01 15:36:51+08:00 780.0 4424.4 4419.44 -3868.8000000000284 平多 d7ba8670-d0d7-4817-b30f-ed7d2ba4fd3c 74c07207-3acc-4f9c-b98b-ae54e4085d96 2025-09-01 07:36:00
259 2025-09-01 15:36:02+08:00 2025-09-01 15:36:51+08:00 124.0 4424.4 4420.0 -545.5999999999549 平多 d7ba8670-d0d7-4817-b30f-ed7d2ba4fd3c a4bea0b9-d2b0-42bf-9e3b-371747ea4fa3 2025-09-01 07:36:00
260 2025-09-01 15:44:38+08:00 2025-09-01 15:47:21+08:00 676.0 4420.39 4426.94 4427.799999999508 平多 17564d45-1b57-4822-91dd-7bf3a162e7b1 131e056d-1779-4de8-bb12-1663936c3ffe 2025-09-01 07:47:00
261 2025-09-01 15:44:38+08:00 2025-09-01 15:47:21+08:00 22.0 4420.0 4426.94 152.6799999999912 平多 7e280213-31c8-4848-b164-57ce0f3a30c3 131e056d-1779-4de8-bb12-1663936c3ffe 2025-09-01 07:47:00
262 2025-09-01 15:44:38+08:00 2025-09-01 15:47:21+08:00 206.0 4420.39 4426.94 1349.2999999998501 平多 37898b4e-9a13-4bc0-a9e6-3fa908bd1e80 131e056d-1779-4de8-bb12-1663936c3ffe 2025-09-01 07:47:00
263 2025-09-01 15:51:28+08:00 2025-09-01 15:54:46+08:00 387.0 4434.86 4450.54 6068.160000000113 平多 a62d6355-e666-4b24-a9fe-1a8efd802cd4 c5b380bf-78c7-4dfd-a1b8-f212e0562e5d 2025-09-01 07:54:00
264 2025-09-01 15:51:28+08:00 2025-09-01 15:54:46+08:00 514.0 4434.86 4450.54 8059.52000000015 平多 9383482c-67d4-4a52-9c9a-bf106f8a66ed c5b380bf-78c7-4dfd-a1b8-f212e0562e5d 2025-09-01 07:54:00
265 2025-09-01 15:59:35+08:00 2025-09-01 16:02:01+08:00 898.0 4454.21 4472.89 16774.64000000026 平多 b4194b4d-5b4a-4387-879f-b208a173d23e 0b3a10ad-d3bc-49e7-bc76-95d3f3f7b012 2025-09-01 08:02:00
266 2025-09-01 16:05:00+08:00 2025-09-01 16:05:43+08:00 891.0 4486.3 4479.29 -6245.9100000001945 平多 62035134-6e2c-4e78-a57e-90883d6fd125 e148f8b3-d2b0-49a8-9702-bf0ef6d70a11 2025-09-01 08:05:00
267 2025-09-01 16:06:22+08:00 2025-09-01 16:13:08+08:00 893.0 4478.53 4480.64 -1884.2300000005198 平空 d901988b-b5b6-4a5e-a03c-83cedbdbbbda dcc81b54-5253-4a49-a426-f28316341b68 2025-09-01 08:13:00
268 2025-09-01 16:18:38+08:00 2025-09-01 16:19:03+08:00 895.0 4467.53 4470.68 -2819.2500000004884 平空 2a066536-51d7-425d-ae9e-83613597c612 41ad454f-5790-480c-9f16-80b478841763 2025-09-01 08:19:00
269 2025-09-01 16:20:05+08:00 2025-09-01 16:22:22+08:00 894.0 4473.83 4478.12 -3835.2599999999675 平空 93df10c4-453d-405e-aa78-3870c5c5f78f 5aeedf17-a10d-4388-b16e-e18251d6e1e5 2025-09-01 08:22:00
270 2025-09-01 16:23:14+08:00 2025-09-01 16:27:37+08:00 893.0 4475.22 4469.41 5188.330000000357 平空 d9277a5f-844a-4afc-b784-0343d373a87e 7def0a70-6cc3-4880-9da3-16671ec6a296 2025-09-01 08:27:00
271 2025-09-01 16:33:42+08:00 2025-09-01 16:41:25+08:00 894.0 4470.45 4469.46 885.0599999998049 平空 9e7bf3df-d22c-413b-8b29-024b9c830f6b 3e80d0e3-3466-4e63-b75d-c86b67b6eb0b 2025-09-01 08:41:00
272 2025-09-01 16:55:38+08:00 2025-09-01 17:04:46+08:00 893.0 4474.93 4476.7 -1580.6099999995777 平空 aca7bfae-9112-4a7a-8a95-7b7661be7d13 20115f47-253a-435a-9b43-1cfcbdc9c12e 2025-09-01 09:04:00
273 2025-09-01 17:10:25+08:00 2025-09-01 17:15:02+08:00 894.0 4472.69 4480.01 6544.080000000553 平多 44c66b7e-5da3-4773-b5a0-73b1cd1c13b9 d8403012-f909-414d-bb21-a012dc5722c2 2025-09-01 09:15:00
274 2025-09-01 17:35:29+08:00 2025-09-01 17:38:36+08:00 300.0 4473.01 4460.17 3852.0000000000437 平空 67981b9f-af13-4595-9a36-80db526ac0e4 de9b300a-19de-4cc4-b86e-e5d8ade4eb2f 2025-09-01 09:38:00
275 2025-09-01 17:35:29+08:00 2025-09-01 17:38:36+08:00 70.0 4473.01 4460.17 898.8000000000102 平空 67981b9f-af13-4595-9a36-80db526ac0e4 f7f5c314-6e7b-498a-99cf-a2c868021b32 2025-09-01 09:38:00
276 2025-09-01 17:35:29+08:00 2025-09-01 17:38:36+08:00 236.0 4473.01 4460.17 3030.2400000000343 平空 67981b9f-af13-4595-9a36-80db526ac0e4 f34ae213-3bb5-4bc5-96b5-1efb92648427 2025-09-01 09:38:00
277 2025-09-01 17:35:29+08:00 2025-09-01 17:38:36+08:00 287.0 4473.01 4460.17 3685.0800000000418 平空 da23b541-1bde-4417-8875-4a52000d3183 f34ae213-3bb5-4bc5-96b5-1efb92648427 2025-09-01 09:38:00

View File

@@ -1,72 +0,0 @@
import requests
import pandas as pd
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh,zh-CN;q=0.9,zh-HK;q=0.8,en;q=0.7',
'cache-control': 'no-cache',
'origin': 'https://www.websea.com',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://www.websea.com/',
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36',
}
if __name__ == '__main__':
datas = []
import datetime
# 定义开始日期和结束日期
start_date = datetime.datetime(2025, 8, 28)
end_date = datetime.datetime(2025, 9, 2)
# 初始化当前日期为开始日期
current_date = start_date
# 循环遍历日期范围
while current_date <= end_date:
# 获取当天开始时刻00:00:00
start_of_day = current_date.replace(hour=0, minute=0, second=0, microsecond=0)
# 获取当天结束时刻23:59:59
end_of_day = current_date.replace(hour=23, minute=59, second=59, microsecond=0)
# 将开始时刻和结束时刻转换为时间戳
start_timestamp = start_of_day.timestamp()
end_timestamp = end_of_day.timestamp()
print(f"日期: {current_date.strftime('%Y.%m.%d')}")
print(f" 开始时刻时间戳: {start_timestamp}")
print(f" 结束时刻时间戳: {end_timestamp}")
params = {
'symbol': 'ETH-USDT',
'period': '1min',
'start': int(start_timestamp),
'end': int(end_timestamp),
}
response = requests.get('https://capi.websea.com/webApi/market/getKline', params=params, headers=headers)
# 提取数据
data = response.json()['result']['data']
print(data)
for i in data:
datas.append(i)
# 日期加一天
current_date += datetime.timedelta(days=1)
# 将数据转换为 DataFrame
df = pd.DataFrame(datas)
# 保存为 Excel 文件
df.to_excel('kline_data.xlsx', index=False)
print("数据已成功保存到 kline_data.xlsx 文件中。")

View File

@@ -1,712 +0,0 @@
import pandas as pd
import numpy as np
import plotly.graph_objects as go
from datetime import datetime, timezone, timedelta
import warnings
import os
import uuid
# ========== 配置 ==========
KLINE_XLSX = "kline_data.xlsx" # K线数据文件名
ORDERS_XLSX = "做市策略.xls" # 订单数据文件名
OUTPUT_HTML = "kline_with_trades.html"
SYMBOL = "ETH-USDT" # 交易对筛选
# 时间与对齐配置
ORDERS_TIME_IS_LOCAL_ASIA_SH = True # 订单时间是否为东八区时间
SNAP_TRADES_TO_NEAREST_CANDLE = True # 对齐交易点到最近的K线时间
SNAP_TOLERANCE_MULTIPLIER = 1.5 # 对齐容忍度倍数
# 图表尺寸配置 - 更宽更扁
CHART_WIDTH = 2200 # 更宽的图表
CHART_HEIGHT = 600 # 更矮的图表
FONT_SIZE = 12 # 字体大小
ANNOTATION_FONT_SIZE = 10 # 标注字体大小
MARKER_SIZE = 10 # 标记大小
LINE_WIDTH = 1.5 # 连接线宽度
# 颜色配置 - 所有文本使用黑色
TEXT_COLOR = "black" # 所有文本使用黑色
TEXT_OFFSET = 10 # 文本偏移量(像素)
# ========== 工具函数 ==========
def parse_numeric(x):
"""高效解析数值类型,支持多种格式"""
if pd.isna(x):
return np.nan
try:
# 尝试直接转换(大多数情况)
return float(x)
except:
# 处理特殊格式
s = str(x).replace(",", "").replace("USDT", "").replace("", "").strip()
if s.endswith("%"):
s = s[:-1]
return float(s) if s else np.nan
def epoch_to_dt(x):
"""将时间戳转换为上海时区时间"""
try:
return pd.to_datetime(int(x), unit="s", utc=True).tz_convert("Asia/Shanghai")
except:
return pd.NaT
def zh_side(row):
"""解析交易方向"""
direction = str(row.get("方向", "")).strip()
if "开多" in direction: return "long_open"
if "平多" in direction: return "long_close"
if "开空" in direction: return "short_open"
if "平空" in direction: return "short_close"
return "unknown"
# ========== 数据加载与预处理 ==========
def load_kline_data():
"""加载并预处理K线数据"""
if not os.path.exists(KLINE_XLSX):
raise FileNotFoundError(f"K线数据文件不存在: {KLINE_XLSX}")
kdf = pd.read_excel(KLINE_XLSX, dtype=str)
kdf.columns = [str(c).strip().lower() for c in kdf.columns]
# 验证必要列
required_cols = {"id", "open", "close", "low", "high"}
missing = required_cols - set(kdf.columns)
if missing:
raise ValueError(f"K线表缺少列: {missing}")
# 时间转换 - 确保id是秒级时间戳
kdf["time"] = kdf["id"].apply(epoch_to_dt)
# 数值转换(向量化操作提升性能)
for col in ["open", "close", "low", "high"]:
kdf[col] = pd.to_numeric(kdf[col].apply(parse_numeric), errors="coerce")
# 清理无效数据
kdf = kdf.dropna(subset=["time", "open", "close", "low", "high"])
kdf = kdf.sort_values("time").reset_index(drop=True)
# 计算K线周期用于交易点对齐
if len(kdf) >= 3:
median_step = kdf["time"].diff().median()
else:
median_step = pd.Timedelta(minutes=1)
return kdf, median_step
def load_order_data():
"""加载并预处理订单数据"""
if not os.path.exists(ORDERS_XLSX):
raise FileNotFoundError(f"订单数据文件不存在: {ORDERS_XLSX}")
odf = pd.read_excel(ORDERS_XLSX, dtype=str)
# 验证必要列
need_order_cols = ["时间", "交易对", "方向", "模式", "数量(张)", "成交价", "交易额", "消耗手续费", "用户盈亏"]
missing = set(need_order_cols) - set(odf.columns)
if missing:
raise ValueError(f"订单表缺少列: {missing}")
# 筛选交易对
if SYMBOL and "交易对" in odf.columns:
odf = odf[odf["交易对"].astype(str).str.strip() == SYMBOL]
# 时间处理 - 确保时间格式正确
with warnings.catch_warnings():
warnings.simplefilter("ignore")
if ORDERS_TIME_IS_LOCAL_ASIA_SH:
# 尝试多种格式解析时间
odf["时间"] = pd.to_datetime(odf["时间"], errors="coerce", format="mixed")
# 本地化为上海时区
odf["时间"] = odf["时间"].dt.tz_localize("Asia/Shanghai", ambiguous="NaT", nonexistent="shift_forward")
else:
# 如果Excel时间已经是UTC
odf["时间"] = pd.to_datetime(odf["时间"], utc=True, errors="coerce").dt.tz_convert("Asia/Shanghai")
# 数值转换
numeric_cols = {
"数量(张)": "数量",
"成交价": "价格",
"交易额": "交易额_num",
"消耗手续费": "手续费",
"用户盈亏": "盈亏"
}
for src, dest in numeric_cols.items():
odf[dest] = pd.to_numeric(odf[src].apply(parse_numeric), errors="coerce")
# 解析交易方向
odf["side"] = odf.apply(zh_side, axis=1)
# 为每个订单生成唯一ID
odf["order_id"] = [str(uuid.uuid4()) for _ in range(len(odf))]
# 计算本金(数量 * 价格)
odf["本金"] = odf["数量"] * odf["价格"]
# 清理无效数据
odf = odf.dropna(subset=["时间", "价格"])
odf = odf.sort_values("时间").reset_index(drop=True)
return odf
def align_trades_to_candles(kdf, odf, median_step):
"""将交易点对齐到最近的K线时间"""
if not SNAP_TRADES_TO_NEAREST_CANDLE or kdf.empty or odf.empty:
return odf.assign(时间_x=odf["时间"])
snap_tolerance = pd.Timedelta(seconds=max(1, int(median_step.total_seconds() * SNAP_TOLERANCE_MULTIPLIER)))
# 使用merge_asof高效对齐
anchor = kdf[["time"]].copy().rename(columns={"time": "k_time"})
odf_sorted = odf.sort_values("时间")
aligned = pd.merge_asof(
odf_sorted,
anchor,
left_on="时间",
right_on="k_time",
direction="nearest",
tolerance=snap_tolerance
)
# 保留原始时间作为参考
aligned["原始时间"] = aligned["时间"]
aligned["时间_x"] = aligned["k_time"].fillna(aligned["时间"])
return aligned
# ========== 持仓跟踪与盈亏计算 ==========
class PositionTracker:
"""FIFO持仓跟踪器支持订单走向可视化"""
def __init__(self):
self.long_lots = [] # (数量, 价格, 时间, 手续费, 订单ID)
self.short_lots = [] # (数量, 价格, 时间, 手续费, 订单ID)
self.realized_pnl = 0.0
self.history = [] # 记录所有交易历史
self.trade_connections = [] # 记录开平仓连接关系
def open_long(self, qty, price, time, fee, order_id):
"""开多仓"""
if qty > 1e-9:
self.long_lots.append((qty, price, time, fee, order_id))
def close_long(self, qty, price, time, fee, order_id):
"""平多仓"""
remaining = qty
local_pnl = 0.0
connections = [] # 本次平仓的连接关系
while remaining > 1e-9 and self.long_lots:
lot_qty, lot_price, lot_time, lot_fee, open_order_id = self.long_lots[0]
take = min(lot_qty, remaining)
pnl = (price - lot_price) * take
local_pnl += pnl
lot_qty -= take
remaining -= take
# 记录开平仓连接
connection = {
"open_time": lot_time,
"close_time": time,
"open_price": lot_price,
"close_price": price,
"qty": take,
"pnl": pnl,
"type": "long",
"open_order_id": open_order_id,
"close_order_id": order_id
}
self.trade_connections.append(connection)
connections.append(connection)
# 记录平仓详情
self.history.append({
"开仓时间": lot_time,
"平仓时间": time,
"数量": take,
"开仓价": lot_price,
"平仓价": price,
"盈亏": pnl,
"类型": "平多",
"开仓订单ID": open_order_id,
"平仓订单ID": order_id
})
if lot_qty <= 1e-9:
self.long_lots.pop(0)
else:
self.long_lots[0] = (lot_qty, lot_price, lot_time, lot_fee, open_order_id)
local_pnl -= fee
self.realized_pnl += local_pnl
return local_pnl, connections
def open_short(self, qty, price, time, fee, order_id):
"""开空仓"""
if qty > 1e-9:
self.short_lots.append((qty, price, time, fee, order_id))
def close_short(self, qty, price, time, fee, order_id):
"""平空仓"""
remaining = qty
local_pnl = 0.0
connections = [] # 本次平仓的连接关系
while remaining > 1e-9 and self.short_lots:
lot_qty, lot_price, lot_time, lot_fee, open_order_id = self.short_lots[0]
take = min(lot_qty, remaining)
pnl = (lot_price - price) * take
local_pnl += pnl
lot_qty -= take
remaining -= take
# 记录开平仓连接
connection = {
"open_time": lot_time,
"close_time": time,
"open_price": lot_price,
"close_price": price,
"qty": take,
"pnl": pnl,
"type": "short",
"open_order_id": open_order_id,
"close_order_id": order_id
}
self.trade_connections.append(connection)
connections.append(connection)
# 记录平仓详情
self.history.append({
"开仓时间": lot_time,
"平仓时间": time,
"数量": take,
"开仓价": lot_price,
"平仓价": price,
"盈亏": pnl,
"类型": "平空",
"开仓订单ID": open_order_id,
"平仓订单ID": order_id
})
if lot_qty <= 1e-9:
self.short_lots.pop(0)
else:
self.short_lots[0] = (lot_qty, lot_price, lot_time, lot_fee, open_order_id)
local_pnl -= fee
self.realized_pnl += local_pnl
return local_pnl, connections
def calculate_pnl(odf):
"""计算持仓盈亏和订单连接关系"""
tracker = PositionTracker()
all_connections = []
for idx, r in odf.iterrows():
qty = r["数量"]
price = r["价格"]
ts = r["时间"]
fee = r["手续费"]
side = r["side"]
order_id = r["order_id"]
if side == "long_open":
tracker.open_long(qty, price, ts, fee, order_id)
elif side == "long_close":
_, connections = tracker.close_long(qty, price, ts, fee, order_id)
all_connections.extend(connections)
elif side == "short_open":
tracker.open_short(qty, price, ts, fee, order_id)
elif side == "short_close":
_, connections = tracker.close_short(qty, price, ts, fee, order_id)
all_connections.extend(connections)
# 创建盈亏DataFrame
if tracker.history:
pnl_df = pd.DataFrame(tracker.history)
# 添加对齐后的时间
pnl_df["时间_x"] = pnl_df["平仓时间"].apply(
lambda x: odf.loc[odf["时间"] == x, "时间_x"].values[0] if not odf.empty else x
)
else:
pnl_df = pd.DataFrame()
# 创建连接关系DataFrame
connections_df = pd.DataFrame(all_connections) if all_connections else pd.DataFrame()
return pnl_df, tracker.realized_pnl, connections_df
# ========== 可视化 ==========
def create_trade_scatter(df, name, color, symbol):
"""创建交易点散点图"""
if df.empty:
return None
# 为不同类型的交易点创建不同的文本标签
if name == "开多":
text = "开多\n" + df["价格"].apply(lambda x: f"{x:.2f}") + "\n" + df["本金"].apply(lambda x: f"{x:.0f}")
elif name == "平多":
text = "平多\n" + df["价格"].apply(lambda x: f"{x:.2f}") + "\n" + df["盈亏"].apply(lambda x: f"{x:.0f}")
elif name == "开空":
text = "开空\n" + df["价格"].apply(lambda x: f"{x:.2f}") + "\n" + df["本金"].apply(lambda x: f"{x:.0f}")
elif name == "平空":
text = "平空\n" + df["价格"].apply(lambda x: f"{x:.2f}") + "\n" + df["盈亏"].apply(lambda x: f"{x:.0f}")
else:
text = name
return go.Scatter(
x=df["时间_x"],
y=df["价格"],
mode="markers+text",
name=name,
text=text,
textposition="middle right", # 文本放在右侧中间位置
textfont=dict(size=ANNOTATION_FONT_SIZE, color=TEXT_COLOR), # 使用黑色文本
marker=dict(
size=MARKER_SIZE,
color=color,
symbol=symbol,
line=dict(width=1.5, color="black")
),
customdata=np.stack([
df["数量"].to_numpy(),
df["价格"].to_numpy(),
df["手续费"].to_numpy(),
df.get("盈亏", np.nan).to_numpy(),
df.get("原始时间", df["时间"]).dt.strftime("%Y-%m-%d %H:%M:%S").to_numpy(),
df["order_id"].to_numpy(),
df["本金"].to_numpy()
], axis=-1),
hovertemplate=(
f"<b>{name}</b><br>"
"数量: %{customdata[0]:.0f}张<br>"
"价格: %{customdata[1]:.2f}<br>"
"手续费: %{customdata[2]:.6f}<br>"
"盈亏: %{customdata[3]:.4f}<br>"
"本金: %{customdata[6]:.0f}<br>"
"时间: %{customdata[4]}<br>"
"订单ID: %{customdata[5]}<extra></extra>"
)
)
def add_trade_connections(fig, connections_df, odf):
"""添加开平仓连接线"""
if connections_df.empty:
return
# 为盈利和亏损的连接线分别创建轨迹
profit_lines = []
loss_lines = []
for _, conn in connections_df.iterrows():
# 获取开仓点和平仓点的坐标
open_point = odf[odf["order_id"] == conn["open_order_id"]].iloc[0]
close_point = odf[odf["order_id"] == conn["close_order_id"]].iloc[0]
line_data = {
"x": [open_point["时间_x"], close_point["时间_x"]],
"y": [open_point["价格"], close_point["价格"]],
"pnl": conn["pnl"],
"type": conn["type"],
"open_order_id": conn["open_order_id"],
"close_order_id": conn["close_order_id"]
}
if conn["pnl"] >= 0:
profit_lines.append(line_data)
else:
loss_lines.append(line_data)
# 添加盈利连接线(绿色)
if profit_lines:
x_profit = []
y_profit = []
customdata_profit = []
for line in profit_lines:
x_profit.extend(line["x"])
y_profit.extend(line["y"])
x_profit.append(None)
y_profit.append(None)
# 为每个点添加自定义数据
customdata_profit.append([
line["open_order_id"],
line["close_order_id"],
line["pnl"],
line["type"]
])
customdata_profit.append([
line["open_order_id"],
line["close_order_id"],
line["pnl"],
line["type"]
])
customdata_profit.append(None)
fig.add_trace(go.Scatter(
x=x_profit,
y=y_profit,
mode="lines",
name="盈利订单",
line=dict(color="rgba(46, 204, 113, 0.7)", width=LINE_WIDTH),
hoverinfo="text",
text=[f"盈利: {d[2]:.2f}" if d else None for d in customdata_profit],
customdata=customdata_profit,
hovertemplate=(
"<b>%{text}</b><br>"
"类型: %{customdata[3]}<br>"
"开仓订单ID: %{customdata[0]}<br>"
"平仓订单ID: %{customdata[1]}<extra></extra>"
)
))
# 添加亏损连接线(红色)
if loss_lines:
x_loss = []
y_loss = []
customdata_loss = []
for line in loss_lines:
x_loss.extend(line["x"])
y_loss.extend(line["y"])
x_loss.append(None)
y_loss.append(None)
# 为每个点添加自定义数据
customdata_loss.append([
line["open_order_id"],
line["close_order_id"],
line["pnl"],
line["type"]
])
customdata_loss.append([
line["open_order_id"],
line["close_order_id"],
line["pnl"],
line["type"]
])
customdata_loss.append(None)
fig.add_trace(go.Scatter(
x=x_loss,
y=y_loss,
mode="lines",
name="亏损订单",
line=dict(color="rgba(231, 76, 60, 0.7)", width=LINE_WIDTH),
hoverinfo="text",
text=[f"亏损: {abs(d[2]):.2f}" if d else None for d in customdata_loss],
customdata=customdata_loss,
hovertemplate=(
"<b>%{text}</b><br>"
"类型: %{customdata[3]}<br>"
"开仓订单ID: %{customdata[0]}<br>"
"平仓订单ID: %{customdata[1]}<extra></extra>"
)
))
def generate_chart(kdf, odf, pnl_df, cum_realized, connections_df):
"""生成K线图与交易标注"""
fig = go.Figure()
# K线主图
fig.add_trace(go.Candlestick(
x=kdf["time"],
open=kdf["open"],
high=kdf["high"],
low=kdf["low"],
close=kdf["close"],
name="K线",
increasing_line_color="#2ecc71",
decreasing_line_color="#e74c3c"
))
# 添加交易点
trade_types = [
(odf[odf["side"] == "long_open"], "开多", "#2ecc71", "triangle-up"),
(odf[odf["side"] == "long_close"], "平多", "#27ae60", "circle"),
(odf[odf["side"] == "short_open"], "开空", "#e74c3c", "triangle-down"),
(odf[odf["side"] == "short_close"], "平空", "#c0392b", "x")
]
for data, name, color, symbol in trade_types:
trace = create_trade_scatter(data, name, color, symbol)
if trace:
fig.add_trace(trace)
# 添加开平仓连接线
add_trade_connections(fig, connections_df, odf)
# 计算时间范围,确保所有点都显示在图表中
all_times = pd.concat([kdf["time"], odf["时间_x"]])
min_time = all_times.min() - pd.Timedelta(minutes=10)
max_time = all_times.max() + pd.Timedelta(minutes=10)
# 计算价格范围,确保所有点都显示在图表中
min_price = min(kdf["low"].min(), odf["价格"].min()) * 0.99
max_price = max(kdf["high"].max(), odf["价格"].max()) * 1.01
# 布局配置 - 更宽更扁的图表
fig.update_layout(
xaxis_title="时间",
yaxis_title="价格 (USDT)",
legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="left",
x=0,
font=dict(size=FONT_SIZE, color=TEXT_COLOR) # 图例文字使用黑色
),
xaxis=dict(
rangeslider=dict(visible=False),
type="date",
gridcolor="rgba(128, 128, 128, 0.2)",
range=[min_time, max_time], # 设置时间范围
title_font=dict(color=TEXT_COLOR), # 坐标轴标题使用黑色
tickfont=dict(color=TEXT_COLOR) # 刻度标签使用黑色
),
yaxis=dict(
gridcolor="rgba(128, 128, 128, 0.2)",
range=[min_price, max_price], # 设置价格范围
title_font=dict(color=TEXT_COLOR), # 坐标轴标题使用黑色
tickfont=dict(color=TEXT_COLOR) # 刻度标签使用黑色
),
hovermode="x unified",
hoverlabel=dict(
namelength=-1,
bgcolor="rgba(255, 255, 255, 0.9)",
font_size=FONT_SIZE,
font_color=TEXT_COLOR # 悬停标签文字使用黑色
),
margin=dict(l=50, r=50, t=80, b=50),
plot_bgcolor="rgba(240, 240, 240, 1)",
width=CHART_WIDTH, # 使用配置的宽度
height=CHART_HEIGHT, # 使用配置的高度
font=dict(size=FONT_SIZE, color=TEXT_COLOR), # 全局字体大小和颜色
# 增强交互性配置
dragmode="pan", # 默认拖拽模式为平移
clickmode="event+select", # 点击模式
selectdirection="h", # 水平选择方向
modebar=dict(
orientation="h", # 水平方向工具栏
bgcolor="rgba(255, 255, 255, 0.7)", # 半透明背景
color="rgba(0, 0, 0, 0.7)", # 图标颜色
activecolor="rgba(0, 0, 0, 0.9)" # 激活图标颜色
)
)
# 添加模式栏按钮
fig.update_layout(
modebar_add=[
"zoom2d",
"pan2d",
"select2d",
"lasso2d",
"zoomIn2d",
"zoomOut2d",
"autoScale2d",
"resetScale2d",
"toImage"
]
)
# 配置缩放行为 - 确保滚轮缩放正常工作
fig.update_xaxes(
autorange=False,
fixedrange=False, # 允许缩放
constrain="domain", # 约束在域内
rangeslider=dict(visible=False) # 禁用范围滑块
)
fig.update_yaxes(
autorange=False,
fixedrange=False, # 允许缩放
scaleanchor="x", # 保持纵横比
scaleratio=1, # 缩放比例
constrain="domain" # 约束在域内
)
# 保存并打开结果 - 启用滚轮缩放
fig.write_html(
OUTPUT_HTML,
include_plotlyjs="cdn",
auto_open=True,
config={
'scrollZoom': True, # 启用滚轮缩放
'displayModeBar': True, # 显示工具栏
'displaylogo': False, # 隐藏Plotly标志
'responsive': True # 响应式布局
}
)
print(f"图表已生成: {OUTPUT_HTML}")
# 返回盈亏详情
if not pnl_df.empty:
pnl_df.to_csv("pnl_details.csv", index=False)
print(f"盈亏详情已保存: pnl_details.csv")
if not connections_df.empty:
connections_df.to_csv("trade_connections.csv", index=False)
print(f"订单连接关系已保存: trade_connections.csv")
return fig
# ========== 主执行流程 ==========
def main():
print("开始处理数据...")
# 加载数据
kdf, median_step = load_kline_data()
odf = load_order_data()
print(f"加载K线数据: {len(kdf)}")
print(f"加载订单数据: {len(odf)}")
# 对齐交易时间
odf = align_trades_to_candles(kdf, odf, median_step)
# 检查时间范围
kline_min_time = kdf["time"].min()
kline_max_time = kdf["time"].max()
order_min_time = odf["时间"].min()
order_max_time = odf["时间"].max()
print(f"K线时间范围: {kline_min_time}{kline_max_time}")
print(f"订单时间范围: {order_min_time}{order_max_time}")
# 检查是否有订单在K线时间范围外
outside_orders = odf[(odf["时间"] < kline_min_time) | (odf["时间"] > kline_max_time)]
if not outside_orders.empty:
print(f"警告: 有 {len(outside_orders)} 个订单在K线时间范围外")
print(outside_orders[["时间", "方向", "价格"]])
# 计算盈亏和订单连接关系
pnl_df, cum_realized, connections_df = calculate_pnl(odf)
print(f"累计已实现盈亏: {cum_realized:.2f} USDT")
print(f"订单连接关系: {len(connections_df)}")
# 生成图表
generate_chart(kdf, odf, pnl_df, cum_realized, connections_df)
print("处理完成")
if __name__ == "__main__":
with warnings.catch_warnings():
warnings.simplefilter("ignore")
main()

View File

@@ -1,713 +0,0 @@
import pandas as pd
import numpy as np
import plotly.graph_objects as go
from datetime import datetime, timezone, timedelta
import warnings
import os
import uuid
# ========== 配置 ==========
KLINE_XLSX = "kline_data.xlsx" # K线数据文件名
ORDERS_XLSX = "做市策略.xls" # 订单数据文件名
OUTPUT_HTML = "kline_with_trades.html"
SYMBOL = "ETH-USDT" # 交易对筛选
# 时间与对齐配置
ORDERS_TIME_IS_LOCAL_ASIA_SH = True # 订单时间是否为东八区时间
SNAP_TRADES_TO_NEAREST_CANDLE = True # 对齐交易点到最近的K线时间
SNAP_TOLERANCE_MULTIPLIER = 1.5 # 对齐容忍度倍数
# 图表尺寸配置 - 更宽更扁
CHART_WIDTH = 2200 # 更宽的图表
CHART_HEIGHT = 600 # 更矮的图表
FONT_SIZE = 12 # 字体大小
ANNOTATION_FONT_SIZE = 10 # 标注字体大小
MARKER_SIZE = 10 # 标记大小
LINE_WIDTH = 1.5 # 连接线宽度
# 颜色配置 - 所有文本使用黑色
TEXT_COLOR = "black" # 所有文本使用黑色
TEXT_OFFSET = 10 # 文本偏移量(像素)
# ========== 工具函数 ==========
def parse_numeric(x):
"""高效解析数值类型,支持多种格式"""
if pd.isna(x):
return np.nan
try:
# 尝试直接转换(大多数情况)
return float(x)
except:
# 处理特殊格式
s = str(x).replace(",", "").replace("USDT", "").replace("", "").strip()
if s.endswith("%"):
s = s[:-1]
return float(s) if s else np.nan
def epoch_to_dt(x):
"""将时间戳转换为上海时区时间"""
try:
return pd.to_datetime(int(x), unit="s", utc=True).tz_convert("Asia/Shanghai")
except:
return pd.NaT
def zh_side(row):
"""解析交易方向"""
direction = str(row.get("方向", "")).strip()
if "开多" in direction: return "long_open"
if "平多" in direction: return "long_close"
if "开空" in direction: return "short_open"
if "平空" in direction: return "short_close"
return "unknown"
# ========== 数据加载与预处理 ==========
def load_kline_data():
"""加载并预处理K线数据"""
if not os.path.exists(KLINE_XLSX):
raise FileNotFoundError(f"K线数据文件不存在: {KLINE_XLSX}")
kdf = pd.read_excel(KLINE_XLSX, dtype=str)
kdf.columns = [str(c).strip().lower() for c in kdf.columns]
# 验证必要列
required_cols = {"id", "open", "close", "low", "high"}
missing = required_cols - set(kdf.columns)
if missing:
raise ValueError(f"K线表缺少列: {missing}")
# 时间转换 - 确保id是秒级时间戳
kdf["time"] = kdf["id"].apply(epoch_to_dt)
# 数值转换(向量化操作提升性能)
for col in ["open", "close", "low", "high"]:
kdf[col] = pd.to_numeric(kdf[col].apply(parse_numeric), errors="coerce")
# 清理无效数据
kdf = kdf.dropna(subset=["time", "open", "close", "low", "high"])
kdf = kdf.sort_values("time").reset_index(drop=True)
# 计算K线周期用于交易点对齐
if len(kdf) >= 3:
median_step = kdf["time"].diff().median()
else:
median_step = pd.Timedelta(minutes=1)
return kdf, median_step
def load_order_data():
"""加载并预处理订单数据"""
if not os.path.exists(ORDERS_XLSX):
raise FileNotFoundError(f"订单数据文件不存在: {ORDERS_XLSX}")
odf = pd.read_excel(ORDERS_XLSX, dtype=str)
# 验证必要列
need_order_cols = ["时间", "交易对", "方向", "模式", "数量(张)", "成交价", "交易额", "消耗手续费", "用户盈亏"]
missing = set(need_order_cols) - set(odf.columns)
if missing:
raise ValueError(f"订单表缺少列: {missing}")
# 筛选交易对
if SYMBOL and "交易对" in odf.columns:
odf = odf[odf["交易对"].astype(str).str.strip() == SYMBOL]
# 时间处理 - 确保时间格式正确
with warnings.catch_warnings():
warnings.simplefilter("ignore")
if ORDERS_TIME_IS_LOCAL_ASIA_SH:
# 尝试多种格式解析时间
odf["时间"] = pd.to_datetime(odf["时间"], errors="coerce", format="mixed")
# 本地化为上海时区
odf["时间"] = odf["时间"].dt.tz_localize("Asia/Shanghai", ambiguous="NaT", nonexistent="shift_forward")
else:
# 如果Excel时间已经是UTC
odf["时间"] = pd.to_datetime(odf["时间"], utc=True, errors="coerce").dt.tz_convert("Asia/Shanghai")
# 数值转换
numeric_cols = {
"数量(张)": "数量",
"成交价": "价格",
"交易额": "交易额_num",
"消耗手续费": "手续费",
"用户盈亏": "盈亏"
}
for src, dest in numeric_cols.items():
odf[dest] = pd.to_numeric(odf[src].apply(parse_numeric), errors="coerce")
# 解析交易方向
odf["side"] = odf.apply(zh_side, axis=1)
# 为每个订单生成唯一ID
odf["order_id"] = [str(uuid.uuid4()) for _ in range(len(odf))]
# 计算本金(数量 * 价格)
odf["本金"] = odf["数量"] * odf["价格"]
# 清理无效数据
odf = odf.dropna(subset=["时间", "价格"])
odf = odf.sort_values("时间").reset_index(drop=True)
return odf
def align_trades_to_candles(kdf, odf, median_step):
"""将交易点对齐到最近的K线时间"""
if not SNAP_TRADES_TO_NEAREST_CANDLE or kdf.empty or odf.empty:
return odf.assign(时间_x=odf["时间"])
snap_tolerance = pd.Timedelta(seconds=max(1, int(median_step.total_seconds() * SNAP_TOLERANCE_MULTIPLIER)))
# 使用merge_asof高效对齐 - 使用方向为'backward'确保交易点对齐到前一个K线
anchor = kdf[["time"]].copy().rename(columns={"time": "k_time"})
odf_sorted = odf.sort_values("时间")
# 关键优化:使用'backward'方向确保交易点对齐到前一个K线
aligned = pd.merge_asof(
odf_sorted,
anchor,
left_on="时间",
right_on="k_time",
direction="backward", # 使用'backward'确保交易点对齐到前一个K线
tolerance=snap_tolerance
)
# 保留原始时间作为参考
aligned["原始时间"] = aligned["时间"]
aligned["时间_x"] = aligned["k_time"].fillna(aligned["时间"])
return aligned
# ========== 持仓跟踪与盈亏计算 ==========
class PositionTracker:
"""FIFO持仓跟踪器支持订单走向可视化"""
def __init__(self):
self.long_lots = [] # (数量, 价格, 时间, 手续费, 订单ID)
self.short_lots = [] # (数量, 价格, 时间, 手续费, 订单ID)
self.realized_pnl = 0.0
self.history = [] # 记录所有交易历史
self.trade_connections = [] # 记录开平仓连接关系
def open_long(self, qty, price, time, fee, order_id):
"""开多仓"""
if qty > 1e-9:
self.long_lots.append((qty, price, time, fee, order_id))
def close_long(self, qty, price, time, fee, order_id):
"""平多仓"""
remaining = qty
local_pnl = 0.0
connections = [] # 本次平仓的连接关系
while remaining > 1e-9 and self.long_lots:
lot_qty, lot_price, lot_time, lot_fee, open_order_id = self.long_lots[0]
take = min(lot_qty, remaining)
pnl = (price - lot_price) * take
local_pnl += pnl
lot_qty -= take
remaining -= take
# 记录开平仓连接
connection = {
"open_time": lot_time,
"close_time": time,
"open_price": lot_price,
"close_price": price,
"qty": take,
"pnl": pnl,
"type": "long",
"open_order_id": open_order_id,
"close_order_id": order_id
}
self.trade_connections.append(connection)
connections.append(connection)
# 记录平仓详情
self.history.append({
"开仓时间": lot_time,
"平仓时间": time,
"数量": take,
"开仓价": lot_price,
"平仓价": price,
"盈亏": pnl,
"类型": "平多",
"开仓订单ID": open_order_id,
"平仓订单ID": order_id
})
if lot_qty <= 1e-9:
self.long_lots.pop(0)
else:
self.long_lots[0] = (lot_qty, lot_price, lot_time, lot_fee, open_order_id)
local_pnl -= fee
self.realized_pnl += local_pnl
return local_pnl, connections
def open_short(self, qty, price, time, fee, order_id):
"""开空仓"""
if qty > 1e-9:
self.short_lots.append((qty, price, time, fee, order_id))
def close_short(self, qty, price, time, fee, order_id):
"""平空仓"""
remaining = qty
local_pnl = 0.0
connections = [] # 本次平仓的连接关系
while remaining > 1e-9 and self.short_lots:
lot_qty, lot_price, lot_time, lot_fee, open_order_id = self.short_lots[0]
take = min(lot_qty, remaining)
pnl = (lot_price - price) * take
local_pnl += pnl
lot_qty -= take
remaining -= take
# 记录开平仓连接
connection = {
"open_time": lot_time,
"close_time": time,
"open_price": lot_price,
"close_price": price,
"q极": take,
"pnl": pnl,
"type": "short",
"open_order_id": open_order_id,
"close_order_id": order_id
}
self.trade_connections.append(connection)
connections.append(connection)
# 记录平仓详情
self.history.append({
"开仓时间": lot_time,
"平仓时间": time,
"数量": take,
"开仓价": lot_price,
"平仓价": price,
"盈亏": pnl,
"类型": "平空",
"开仓订单ID": open_order_id,
"平仓订单ID": order_id
})
if lot_qty <= 1e-9:
self.short_lots.pop(0)
else:
self.short_lots[0] = (lot_qty, lot_price, lot_time, lot_fee, open_order_id)
local_pnl -= fee
self.realized_pnl += local_pnl
return local_pnl, connections
def calculate_pnl(odf):
"""计算持仓盈亏和订单连接关系"""
tracker = PositionTracker()
all_connections = []
for idx, r in odf.iterrows():
qty = r["数量"]
price = r["价格"]
ts = r["时间"]
fee = r["手续费"]
side = r["side"]
order_id = r["order_id"]
if side == "long_open":
tracker.open_long(qty, price, ts, fee, order_id)
elif side == "long_close":
_, connections = tracker.close_long(qty, price, ts, fee, order_id)
all_connections.extend(connections)
elif side == "short_open":
tracker.open_short(qty, price, ts, fee, order_id)
elif side == "short_close":
_, connections = tracker.close_short(qty, price, ts, fee, order_id)
all_connections.extend(connections)
# 创建盈亏DataFrame
if tracker.history:
pnl_df = pd.DataFrame(tracker.history)
# 添加对齐后的时间
pnl_df["时间_x"] = pnl_df["平仓时间"].apply(
lambda x: odf.loc[odf["时间"] == x, "时间_x"].values[0] if not odf.empty else x
)
else:
pnl_df = pd.DataFrame()
# 创建连接关系DataFrame
connections_df = pd.DataFrame(all_connections) if all_connections else pd.DataFrame()
return pnl_df, tracker.realized_pnl, connections_df
# ========== 可视化 ==========
def create_trade_scatter(df, name, color, symbol):
"""创建交易点散点图"""
if df.empty:
return None
# 为不同类型的交易点创建不同的文本标签
if name == "开多":
text = "开多\n" + df["价格"].apply(lambda x: f"{x:.2f}") + "\n" + df["本金"].apply(lambda x: f"{x:.0f}")
elif name == "平多":
text = "平多\n" + df["价格"].apply(lambda x: f"{x:.2f}") + "\n" + df["盈亏"].apply(lambda x: f"{x:.0f}")
elif name == "开空":
text = "开空\n" + df["价格"].apply(lambda x: f"{x:.2f}") + "\n" + df["本金"].apply(lambda x: f"{x:.0f}")
elif name == "平空":
text = "平空\n" + df["价格"].apply(lambda x: f"{x:.2f}") + "\n" + df["盈亏"].apply(lambda x: f"{x:.0f}")
else:
text = name
return go.Scatter(
x=df["时间_x"],
y=df["价格"],
mode="markers+text",
name=name,
text=text,
textposition="middle right", # 文本放在右侧中间位置
textfont=dict(size=ANNOTATION_FONT_SIZE, color=TEXT_COLOR), # 使用黑色文本
marker=dict(
size=MARKER_SIZE,
color=color,
symbol=symbol,
line=dict(width=1.5, color="black")
),
customdata=np.stack([
df["数量"].to_numpy(),
df["价格"].to_numpy(),
df["手续费"].to_numpy(),
df.get("盈亏", np.nan).to_numpy(),
df.get("原始时间", df["时间"]).dt.strftime("%Y-%m-%d %H:%M:%S").to_numpy(),
df["order_id"].to_numpy(),
df["本金"].to_numpy()
], axis=-1),
hovertemplate=(
f"<b>{name}</b><br>"
"数量: %{customdata[0]:.0f}张<br>"
"价格: %{customdata[1]:.2f}<br>"
"手续费: %{customdata[2]:.6f}<br>"
"盈亏: %{customdata[3]:.4f}<br>"
"本金: %{customdata[6]:.0f}<br>"
"时间: %{customdata[4]}<br>"
"订单ID: %{customdata[5]}<extra></extra>"
)
)
def add_trade_connections(fig, connections_df, odf):
"""添加开平仓连接线"""
if connections_df.empty:
return
# 为盈利和亏损的连接线分别创建轨迹
profit_lines = []
loss_lines = []
for _, conn in connections_df.iterrows():
# 获取开仓点和平仓点的坐标
open_point = odf[odf["order_id"] == conn["open_order_id"]].iloc[0]
close_point = odf[odf["order_id"] == conn["close_order_id"]].iloc[0]
line_data = {
"x": [open_point["时间_x"], close_point["时间_x"]],
"y": [open_point["价格"], close_point["价格"]],
"pnl": conn["pnl"],
"type": conn["type"],
"open_order_id": conn["open_order_id"],
"close_order_id": conn["close_order_id"]
}
if conn["pnl"] >= 0:
profit_lines.append(line_data)
else:
loss_lines.append(line_data)
# 添加盈利连接线(绿色)
if profit_lines:
x_profit = []
y_profit = []
customdata_profit = []
for line in profit_lines:
x_profit.extend(line["x"])
y_profit.extend(line["y"])
x_profit.append(None)
y_profit.append(None)
# 为每个点添加自定义数据
customdata_profit.append([
line["open_order_id"],
line["close_order_id"],
line["pnl"],
line["type"]
])
customdata_profit.append([
line["open_order_id"],
line["close_order_id"],
line["pnl"],
line["type"]
])
customdata_profit.append(None)
fig.add_trace(go.Scatter(
x=x_profit,
y=y_profit,
mode="lines",
name="盈利订单",
line=dict(color="rgba(46, 204, 113, 0.7)", width=LINE_WIDTH),
hoverinfo="text",
text=[f"盈利: {d[2]:.2f}" if d else None for d in customdata_profit],
customdata=customdata_profit,
hovertemplate=(
"<b>%{text}</b><br>"
"类型: %{customdata[3]}<br>"
"开仓订单ID: %{customdata[0]}<br>"
"平仓订单ID: %{customdata[1]}<extra></extra>"
)
))
# 添加亏损连接线(红色)
if loss_lines:
x_loss = []
y_loss = []
customdata_loss = []
for line in loss_lines:
x_loss.extend(line["x"])
y_loss.extend(line["y"])
x_loss.append(None)
y_loss.append(None)
# 为每个点添加自定义数据
customdata_loss.append([
line["open_order_id"],
line["close_order_id"],
line["pnl"],
line["type"]
])
customdata_loss.append([
line["open_order_id"],
line["close_order_id"],
line["pnl"],
line["type"]
])
customdata_loss.append(None)
fig.add_trace(go.Scatter(
x=x_loss,
y=y_loss,
mode="lines",
name="亏损订单",
line=dict(color="rgba(231, 76, 60, 0.7)", width=LINE_WIDTH),
hoverinfo="text",
text=[f"亏损: {abs(d[2]):.2f}" if d else None for d in customdata_loss],
customdata=customdata_loss,
hovertemplate=(
"<b>%{text}</b><br>"
"类型: %{customdata[3]}<br>"
"开仓订单ID: %{customdata[0]}<极>"
"平仓订单ID: %{customdata[1]}<extra></extra>"
)
))
def generate_chart(kdf, odf, pnl_df, cum_realized, connections_df):
"""生成K线图与交易标注"""
fig = go.Figure()
# K线主图
fig.add_trace(go.Candlestick(
x=kdf["time"],
open=kdf["open"],
high=kdf["high"],
low=kdf["low"],
close=kdf["close"],
name="K线",
increasing_line_color="#2ecc71",
decreasing_line_color="#e74c3c"
))
# 添加交易点
trade_types = [
(odf[odf["side"] == "long_open"], "开多", "#2ecc71", "triangle-up"),
(odf[odf["side"] == "long_close"], "平多", "#27ae60", "circle"),
(odf[odf["side"] == "short_open"], "开空", "#e74c3c", "triangle-down"),
(odf[odf["side"] == "short_close"], "平空", "#c0392b", "x")
]
for data, name, color, symbol in trade_types:
trace = create_trade_scatter(data, name, color, symbol)
if trace:
fig.add_trace(trace)
# 添加开平仓连接线
add_trade_connections(fig, connections_df, odf)
# 计算时间范围,确保所有点都显示在图表中
all_times = pd.concat([kdf["time"], odf["时间_x"]])
min_time = all_times.min() - pd.Timedelta(minutes=10)
max_time = all_times.max() + pd.Timedelta(minutes=10)
# 计算价格范围,确保所有点都显示在图表中
min_price = min(kdf["low"].min(), odf["价格"].min()) * 0.99
max_price = max(kdf["high"].max(), odf["价格"].max()) * 1.01
# 布局配置 - 更宽更扁的图表
fig.update_layout(
xaxis_title="时间",
yaxis_title="价格 (USDT)",
legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="left",
x=0,
font=dict(size=FONT_SIZE, color=TEXT_COLOR) # 图例文字使用黑色
),
xaxis=dict(
rangeslider=dict(visible=False),
type="date",
gridcolor="rgba(128, 128, 128, 0.2)",
range=[min_time, max_time], # 设置时间范围
title_font=dict(color=TEXT_COLOR), # 坐标轴标题使用黑色
tickfont=dict(color=TEXT_COLOR) # 刻度标签使用黑色
),
yaxis=dict(
gridcolor="rgba(128, 128, 128, 0.2)",
range=[min_price, max_price], # 设置价格范围
title_font=dict(color=TEXT_COLOR), # 坐标轴标题使用黑色
tickfont=dict(color=TEXT_COLOR) # 刻度标签使用黑色
),
hovermode="x unified",
hoverlabel=dict(
namelength=-1,
bgcolor="rgba(255, 255, 255, 0.9)",
font_size=FONT_SIZE,
font_color=TEXT_COLOR # 悬停标签文字使用黑色
),
margin=dict(l=50, r=50, t=80, b=50),
plot_bgcolor="rgba(240, 240, 240, 1)",
width=CHART_WIDTH, # 使用配置的宽度
height=CHART_HEIGHT, # 使用配置的高度
font=dict(size=FONT_SIZE, color=TEXT_COLOR), # 全局字体大小和颜色
# 增强交互性配置
dragmode="pan", # 默认拖拽模式为平移
clickmode="event+select", # 点击模式
selectdirection="h", # 水平选择方向
modebar=dict(
orientation="h", # 水平方向工具栏
bgcolor="rgba(255, 255, 255, 0.7)", # 半透明背景
color="rgba(0, 0, 0, 0.7)", # 图标颜色
activecolor="rgba(0, 0, 0, 0.9)" # 激活图标颜色
)
)
# 添加模式栏按钮
fig.update_layout(
modebar_add=[
"zoom2d",
"pan2d",
"select2d",
"lasso2d",
"zoomIn2d",
"zoomOut2d",
"autoScale2d",
"resetScale2d",
"toImage"
]
)
# 配置缩放行为 - 确保滚轮缩放正常工作
fig.update_xaxes(
autorange=False,
fixedrange=False, # 允许缩放
constrain="domain", # 约束在域内
rangeslider=dict(visible=False) # 禁用范围滑块
)
fig.update_yaxes(
autorange=False,
fixedrange=False, # 允许缩放
scaleanchor="x", # 保持纵横比
scaleratio=1, # 缩放比例
constrain="domain" # 约束在域内
)
# 保存并打开结果 - 启用滚轮缩放
fig.write_html(
OUTPUT_HTML,
include_plotlyjs="cdn",
auto_open=True,
config={
'scrollZoom': True, # 启用滚轮缩放
'displayModeBar': True, # 显示工具栏
'displaylogo': False, # 隐藏Plotly标志
'responsive': True # 响应式布局
}
)
print(f"图表已生成: {OUTPUT_HTML}")
# 返回盈亏详情
if not pnl_df.empty:
pnl_df.to_csv("pnl_details.csv", index=False)
print(f"盈亏详情已保存: pnl_details.csv")
if not connections_df.empty:
connections_df.to_csv("trade_connections.csv", index=False)
print(f"订单连接关系已保存: trade_connections.csv")
return fig
# ========== 主执行流程 ==========
def main():
print("开始处理数据...")
# 加载数据
kdf, median_step = load_kline_data()
odf = load_order_data()
print(f"加载K线数据: {len(kdf)}")
print(f"加载订单数据: {len(odf)}")
# 对齐交易时间
odf = align_trades_to_candles(kdf, odf, median_step)
# 检查时间范围
kline_min_time = kdf["time"].min()
kline_max_time = kdf["time"].max()
order_min_time = odf["时间"].min()
order_max_time = odf["时间"].max()
print(f"K线时间范围: {kline_min_time}{kline_max_time}")
print(f"订单时间范围: {order_min_time}{order_max_time}")
# 检查是否有订单在K线时间范围外
outside_orders = odf[(odf["时间"] < kline_min_time) | (odf["时间"] > kline_max_time)]
if not outside_orders.empty:
print(f"警告: 有 {len(outside_orders)} 个订单在K线时间范围外")
print(outside_orders[["时间", "方向", "价格"]])
# 计算盈亏和订单连接关系
pnl_df, cum_realized, connections_df = calculate_pnl(odf)
print(f"累计已实现盈亏: {cum_realized:.2f} USDT")
print(f"订单连接关系: {len(connections_df)}")
# 生成图表
generate_chart(kdf, odf, pnl_df, cum_realized, connections_df)
print("处理完成")
if __name__ == "__main__":
with warnings.catch_warnings():
warnings.simplefilter("ignore")
main()

View File

@@ -1,713 +0,0 @@
import pandas as pd
import numpy as np
import plotly.graph_objects as go
from datetime import datetime, timezone, timedelta
import warnings
import os
import uuid
# ========== 配置 ==========
KLINE_XLSX = "kline_data.xlsx" # K线数据文件名
ORDERS_XLSX = "做市策略.xls" # 订单数据文件名
OUTPUT_HTML = "kline_with_trades.html"
SYMBOL = "ETH-USDT" # 交易对筛选
# 时间与对齐配置
ORDERS_TIME_IS_LOCAL_ASIA_SH = True # 订单时间是否为东八区时间
SNAP_TRADES_TO_NEAREST_CANDLE = True # 对齐交易点到最近的K线时间
SNAP_TOLERANCE_MULTIPLIER = 1.5 # 对齐容忍度倍数
# 图表尺寸配置 - 更宽更扁
CHART_WIDTH = 2200 # 更宽的图表
CHART_HEIGHT = 600 # 更矮的图表
FONT_SIZE = 12 # 字体大小
ANNOTATION_FONT_SIZE = 10 # 标注字体大小
MARKER_SIZE = 10 # 标记大小
LINE_WIDTH = 1.5 # 连接线宽度
# 颜色配置 - 所有文本使用黑色
TEXT_COLOR = "black" # 所有文本使用黑色
TEXT_OFFSET = 10 # 文本偏移量(像素)
# ========== 工具函数 ==========
def parse_numeric(x):
"""高效解析数值类型,支持多种格式"""
if pd.isna(x):
return np.nan
try:
# 尝试直接转换(大多数情况)
return float(x)
except:
# 处理特殊格式
s = str(x).replace(",", "").replace("USDT", "").replace("", "").strip()
if s.endswith("%"):
s = s[:-1]
return float(s) if s else np.nan
def epoch_to_dt(x):
"""将时间戳转换为上海时区时间"""
try:
return pd.to_datetime(int(x), unit="s", utc=True).tz_convert("Asia/Shanghai")
except:
return pd.NaT
def zh_side(row):
"""解析交易方向"""
direction = str(row.get("方向", "")).strip()
if "开多" in direction: return "long_open"
if "平多" in direction: return "long_close"
if "开空" in direction: return "short_open"
if "平空" in direction: return "short_close"
return "unknown"
# ========== 数据加载与预处理 ==========
def load_kline_data():
"""加载并预处理K线数据"""
if not os.path.exists(KLINE_XLSX):
raise FileNotFoundError(f"K线数据文件不存在: {KLINE_XLSX}")
kdf = pd.read_excel(KLINE_XLSX, dtype=str)
kdf.columns = [str(c).strip().lower() for c in kdf.columns]
# 验证必要列
required_cols = {"id", "open", "close", "low", "high"}
missing = required_cols - set(kdf.columns)
if missing:
raise ValueError(f"K线表缺少列: {missing}")
# 时间转换 - 确保id是秒级时间戳
kdf["time"] = kdf["id"].apply(epoch_to_dt)
# 数值转换(向量化操作提升性能)
for col in ["open", "close", "low", "high"]:
kdf[col] = pd.to_numeric(kdf[col].apply(parse_numeric), errors="coerce")
# 清理无效数据
kdf = kdf.dropna(subset=["time", "open", "close", "low", "high"])
kdf = kdf.sort_values("time").reset_index(drop=True)
# 计算K线周期用于交易点对齐
if len(kdf) >= 3:
median_step = kdf["time"].diff().median()
else:
median_step = pd.Timedelta(minutes=1)
return kdf, median_step
def load_order_data():
"""加载并预处理订单数据"""
if not os.path.exists(ORDERS_XLSX):
raise FileNotFoundError(f"订单数据文件不存在: {ORDERS_XLSX}")
odf = pd.read_excel(ORDERS_XLSX, dtype=str)
# 验证必要列
need_order_cols = ["时间", "交易对", "方向", "模式", "数量(张)", "成交价", "交易额", "消耗手续费", "用户盈亏"]
missing = set(need_order_cols) - set(odf.columns)
if missing:
raise ValueError(f"订单表缺少列: {missing}")
# 筛选交易对
if SYMBOL and "交易对" in odf.columns:
odf = odf[odf["交易对"].astype(str).str.strip() == SYMBOL]
# 时间处理 - 确保时间格式正确
with warnings.catch_warnings():
warnings.simplefilter("ignore")
if ORDERS_TIME_IS_LOCAL_ASIA_SH:
# 尝试多种格式解析时间
odf["时间"] = pd.to_datetime(odf["时间"], errors="coerce", format="mixed")
# 本地化为上海时区
odf["时间"] = odf["时间"].dt.tz_localize("Asia/Shanghai", ambiguous="NaT", nonexistent="shift_forward")
else:
# 如果Excel时间已经是UTC
odf["时间"] = pd.to_datetime(odf["时间"], utc=True, errors="coerce").dt.tz_convert("Asia/Shanghai")
# 数值转换
numeric_cols = {
"数量(张)": "数量",
"成交价": "价格",
"交易额": "交易额_num",
"消耗手续费": "手续费",
"用户盈亏": "盈亏"
}
for src, dest in numeric_cols.items():
odf[dest] = pd.to_numeric(odf[src].apply(parse_numeric), errors="coerce")
# 解析交易方向
odf["side"] = odf.apply(zh_side, axis=1)
# 为每个订单生成唯一ID
odf["order_id"] = [str(uuid.uuid4()) for _ in range(len(odf))]
# 计算本金(数量 * 价格)
odf["本金"] = odf["数量"] * odf["价格"]
# 清理无效数据
odf = odf.dropna(subset=["时间", "价格"])
odf = odf.sort_values("时间").reset_index(drop=True)
return odf
def align_trades_to_candles(kdf, odf, median_step):
"""将交易点对齐到最近的K线时间"""
if not SNAP_TRADES_TO_NEAREST_CANDLE or kdf.empty or odf.empty:
return odf.assign(时间_x=odf["时间"])
snap_tolerance = pd.Timedelta(seconds=max(1, int(median_step.total_seconds() * SNAP_TOLERANCE_MULTIPLIER)))
# 使用merge_asof高效对齐 - 使用方向为'backward'确保交易点对齐到前一个K线
anchor = kdf[["time"]].copy().rename(columns={"time": "k_time"})
odf_sorted = odf.sort_values("时间")
# 关键优化:使用'backward'方向确保交易点对齐到前一个K线
aligned = pd.merge_asof(
odf_sorted,
anchor,
left_on="时间",
right_on="k_time",
direction="backward", # 使用'backward'确保交易点对齐到前一个K线
tolerance=snap_tolerance
)
# 保留原始时间作为参考
aligned["原始时间"] = aligned["时间"]
aligned["时间_x"] = aligned["k_time"].fillna(aligned["时间"])
return aligned
# ========== 持仓跟踪与盈亏计算 ==========
class PositionTracker:
"""FIFO持仓跟踪器支持订单走向可视化"""
def __init__(self):
self.long_lots = [] # (数量, 价格, 时间, 手续费, 订单ID)
self.short_lots = [] # (数量, 价格, 时间, 手续费, 订单ID)
self.realized_pnl = 0.0
self.history = [] # 记录所有交易历史
self.trade_connections = [] # 记录开平仓连接关系
def open_long(self, qty, price, time, fee, order_id):
"""开多仓"""
if qty > 1e-9:
self.long_lots.append((qty, price, time, fee, order_id))
def close_long(self, qty, price, time, fee, order_id):
"""平多仓"""
remaining = qty
local_pnl = 0.0
connections = [] # 本次平仓的连接关系
while remaining > 1e-9 and self.long_lots:
lot_qty, lot_price, lot_time, lot_fee, open_order_id = self.long_lots[0]
take = min(lot_qty, remaining)
pnl = (price - lot_price) * take
local_pnl += pnl
lot_qty -= take
remaining -= take
# 记录开平仓连接
connection = {
"open_time": lot_time,
"close_time": time,
"open_price": lot_price,
"close_price": price,
"qty": take,
"pnl": pnl,
"type": "long",
"open_order_id": open_order_id,
"close_order_id": order_id
}
self.trade_connections.append(connection)
connections.append(connection)
# 记录平仓详情
self.history.append({
"开仓时间": lot_time,
"平仓时间": time,
"数量": take,
"开仓价": lot_price,
"平仓价": price,
"盈亏": pnl,
"类型": "平多",
"开仓订单ID": open_order_id,
"平仓订单ID": order_id
})
if lot_qty <= 1e-9:
self.long_lots.pop(0)
else:
self.long_lots[0] = (lot_qty, lot_price, lot_time, lot_fee, open_order_id)
local_pnl -= fee
self.realized_pnl += local_pnl
return local_pnl, connections
def open_short(self, qty, price, time, fee, order_id):
"""开空仓"""
if qty > 1e-9:
self.short_lots.append((qty, price, time, fee, order_id))
def close_short(self, qty, price, time, fee, order_id):
"""平空仓"""
remaining = qty
local_pnl = 0.0
connections = [] # 本次平仓的连接关系
while remaining > 1e-9 and self.short_lots:
lot_qty, lot_price, lot_time, lot_fee, open_order_id = self.short_lots[0]
take = min(lot_qty, remaining)
pnl = (lot_price - price) * take
local_pnl += pnl
lot_qty -= take
remaining -= take
# 记录开平仓连接
connection = {
"open_time": lot_time,
"close_time": time,
"open_price": lot_price,
"close_price": price,
"q极": take,
"pnl": pnl,
"type": "short",
"open_order_id": open_order_id,
"close_order_id": order_id
}
self.trade_connections.append(connection)
connections.append(connection)
# 记录平仓详情
self.history.append({
"开仓时间": lot_time,
"平仓时间": time,
"数量": take,
"开仓价": lot_price,
"平仓价": price,
"盈亏": pnl,
"类型": "平空",
"开仓订单ID": open_order_id,
"平仓订单ID": order_id
})
if lot_qty <= 1e-9:
self.short_lots.pop(0)
else:
self.short_lots[0] = (lot_qty, lot_price, lot_time, lot_fee, open_order_id)
local_pnl -= fee
self.realized_pnl += local_pnl
return local_pnl, connections
def calculate_pnl(odf):
"""计算持仓盈亏和订单连接关系"""
tracker = PositionTracker()
all_connections = []
for idx, r in odf.iterrows():
qty = r["数量"]
price = r["价格"]
ts = r["时间"]
fee = r["手续费"]
side = r["side"]
order_id = r["order_id"]
if side == "long_open":
tracker.open_long(qty, price, ts, fee, order_id)
elif side == "long_close":
_, connections = tracker.close_long(qty, price, ts, fee, order_id)
all_connections.extend(connections)
elif side == "short_open":
tracker.open_short(qty, price, ts, fee, order_id)
elif side == "short_close":
_, connections = tracker.close_short(qty, price, ts, fee, order_id)
all_connections.extend(connections)
# 创建盈亏DataFrame
if tracker.history:
pnl_df = pd.DataFrame(tracker.history)
# 添加对齐后的时间
pnl_df["时间_x"] = pnl_df["平仓时间"].apply(
lambda x: odf.loc[odf["时间"] == x, "时间_x"].values[0] if not odf.empty else x
)
else:
pnl_df = pd.DataFrame()
# 创建连接关系DataFrame
connections_df = pd.DataFrame(all_connections) if all_connections else pd.DataFrame()
return pnl_df, tracker.realized_pnl, connections_df
# ========== 可视化 ==========
def create_trade_scatter(df, name, color, symbol):
"""创建交易点散点图"""
if df.empty:
return None
# 为不同类型的交易点创建不同的文本标签
if name == "开多":
text = "开多\n" + df["价格"].apply(lambda x: f"{x:.2f}") + "\n" + df["本金"].apply(lambda x: f"{x:.0f}")
elif name == "平多":
text = "平多\n" + df["价格"].apply(lambda x: f"{x:.2f}") + "\n" + df["盈亏"].apply(lambda x: f"{x:.0f}")
elif name == "开空":
text = "开空\n" + df["价格"].apply(lambda x: f"{x:.2f}") + "\n" + df["本金"].apply(lambda x: f"{x:.0f}")
elif name == "平空":
text = "平空\n" + df["价格"].apply(lambda x: f"{x:.2f}") + "\n" + df["盈亏"].apply(lambda x: f"{x:.0f}")
else:
text = name
return go.Scatter(
x=df["时间_x"],
y=df["价格"],
mode="markers+text",
name=name,
text=text,
textposition="middle right", # 文本放在右侧中间位置
textfont=dict(size=ANNOTATION_FONT_SIZE, color=TEXT_COLOR), # 使用黑色文本
marker=dict(
size=MARKER_SIZE,
color=color,
symbol=symbol,
line=dict(width=1.5, color="black")
),
customdata=np.stack([
df["数量"].to_numpy(),
df["价格"].to_numpy(),
df["手续费"].to_numpy(),
df.get("盈亏", np.nan).to_numpy(),
df.get("原始时间", df["时间"]).dt.strftime("%Y-%m-%d %H:%M:%S").to_numpy(),
df["order_id"].to_numpy(),
df["本金"].to_numpy()
], axis=-1),
hovertemplate=(
f"<b>{name}</b><br>"
"数量: %{customdata[0]:.0f}张<br>"
"价格: %{customdata[1]:.2f}<br>"
"手续费: %{customdata[2]:.6f}<br>"
"盈亏: %{customdata[3]:.4f}<br>"
"本金: %{customdata[6]:.0f}<br>"
"时间: %{customdata[4]}<br>"
"订单ID: %{customdata[5]}<extra></extra>"
)
)
def add_trade_connections(fig, connections_df, odf):
"""添加开平仓连接线"""
if connections_df.empty:
return
# 为盈利和亏损的连接线分别创建轨迹
profit_lines = []
loss_lines = []
for _, conn in connections_df.iterrows():
# 获取开仓点和平仓点的坐标
open_point = odf[odf["order_id"] == conn["open_order_id"]].iloc[0]
close_point = odf[odf["order_id"] == conn["close_order_id"]].iloc[0]
line_data = {
"x": [open_point["时间_x"], close_point["时间_x"]],
"y": [open_point["价格"], close_point["价格"]],
"pnl": conn["pnl"],
"type": conn["type"],
"open_order_id": conn["open_order_id"],
"close_order_id": conn["close_order_id"]
}
if conn["pnl"] >= 0:
profit_lines.append(line_data)
else:
loss_lines.append(line_data)
# 添加盈利连接线(绿色)
if profit_lines:
x_profit = []
y_profit = []
customdata_profit = []
for line in profit_lines:
x_profit.extend(line["x"])
y_profit.extend(line["y"])
x_profit.append(None)
y_profit.append(None)
# 为每个点添加自定义数据
customdata_profit.append([
line["open_order_id"],
line["close_order_id"],
line["pnl"],
line["type"]
])
customdata_profit.append([
line["open_order_id"],
line["close_order_id"],
line["pnl"],
line["type"]
])
customdata_profit.append(None)
fig.add_trace(go.Scatter(
x=x_profit,
y=y_profit,
mode="lines",
name="盈利订单",
line=dict(color="rgba(46, 204, 113, 0.7)", width=LINE_WIDTH),
hoverinfo="text",
text=[f"盈利: {d[2]:.2f}" if d else None for d in customdata_profit],
customdata=customdata_profit,
hovertemplate=(
"<b>%{text}</b><br>"
"类型: %{customdata[3]}<br>"
"开仓订单ID: %{customdata[0]}<br>"
"平仓订单ID: %{customdata[1]}<extra></extra>"
)
))
# 添加亏损连接线(红色)
if loss_lines:
x_loss = []
y_loss = []
customdata_loss = []
for line in loss_lines:
x_loss.extend(line["x"])
y_loss.extend(line["y"])
x_loss.append(None)
y_loss.append(None)
# 为每个点添加自定义数据
customdata_loss.append([
line["open_order_id"],
line["close_order_id"],
line["pnl"],
line["type"]
])
customdata_loss.append([
line["open_order_id"],
line["close_order_id"],
line["pnl"],
line["type"]
])
customdata_loss.append(None)
fig.add_trace(go.Scatter(
x=x_loss,
y=y_loss,
mode="lines",
name="亏损订单",
line=dict(color="rgba(231, 76, 60, 0.7)", width=LINE_WIDTH),
hoverinfo="text",
text=[f"亏损: {abs(d[2]):.2f}" if d else None for d in customdata_loss],
customdata=customdata_loss,
hovertemplate=(
"<b>%{text}</b><br>"
"类型: %{customdata[3]}<br>"
"开仓订单ID: %{customdata[0]}<极>"
"平仓订单ID: %{customdata[1]}<extra></extra>"
)
))
def generate_chart(kdf, odf, pnl_df, cum_realized, connections_df):
"""生成K线图与交易标注"""
fig = go.Figure()
# K线主图
fig.add_trace(go.Candlestick(
x=kdf["time"],
open=kdf["open"],
high=kdf["high"],
low=kdf["low"],
close=kdf["close"],
name="K线",
increasing_line_color="#2ecc71",
decreasing_line_color="#e74c3c"
))
# 添加交易点
trade_types = [
(odf[odf["side"] == "long_open"], "开多", "#2ecc71", "triangle-up"),
(odf[odf["side"] == "long_close"], "平多", "#27ae60", "circle"),
(odf[odf["side"] == "short_open"], "开空", "#e74c3c", "triangle-down"),
(odf[odf["side"] == "short_close"], "平空", "#c0392b", "x")
]
for data, name, color, symbol in trade_types:
trace = create_trade_scatter(data, name, color, symbol)
if trace:
fig.add_trace(trace)
# 添加开平仓连接线
add_trade_connections(fig, connections_df, odf)
# 计算时间范围,确保所有点都显示在图表中
all_times = pd.concat([kdf["time"], odf["时间_x"]])
min_time = all_times.min() - pd.Timedelta(minutes=10)
max_time = all_times.max() + pd.Timedelta(minutes=10)
# 计算价格范围,确保所有点都显示在图表中
min_price = min(kdf["low"].min(), odf["价格"].min()) * 0.999
max_price = max(kdf["high"].max(), odf["价格"].max()) * 1.001
# 布局配置 - 更宽更扁的图表
fig.update_layout(
xaxis_title="时间",
yaxis_title="价格 (USDT)",
legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="left",
x=0,
font=dict(size=FONT_SIZE, color=TEXT_COLOR) # 图例文字使用黑色
),
xaxis=dict(
rangeslider=dict(visible=False),
type="date",
gridcolor="rgba(128, 128, 128, 0.2)",
range=[min_time, max_time], # 设置时间范围
title_font=dict(color=TEXT_COLOR), # 坐标轴标题使用黑色
tickfont=dict(color=TEXT_COLOR) # 刻度标签使用黑色
),
yaxis=dict(
gridcolor="rgba(128, 128, 128, 0.2)",
range=[min_price, max_price], # 设置价格范围
title_font=dict(color=TEXT_COLOR), # 坐标轴标题使用黑色
tickfont=dict(color=TEXT_COLOR) # 刻度标签使用黑色
),
hovermode="x unified",
hoverlabel=dict(
namelength=-1,
bgcolor="rgba(255, 255, 255, 0.9)",
font_size=FONT_SIZE,
font_color=TEXT_COLOR # 悬停标签文字使用黑色
),
margin=dict(l=50, r=50, t=80, b=50),
plot_bgcolor="rgba(240, 240, 240, 1)",
width=CHART_WIDTH, # 使用配置的宽度
height=CHART_HEIGHT, # 使用配置的高度
font=dict(size=FONT_SIZE, color=TEXT_COLOR), # 全局字体大小和颜色
# 增强交互性配置
dragmode="pan", # 默认拖拽模式为平移
clickmode="event+select", # 点击模式
selectdirection="h", # 水平选择方向
modebar=dict(
orientation="h", # 水平方向工具栏
bgcolor="rgba(255, 255, 255, 0.7)", # 半透明背景
color="rgba(0, 0, 0, 0.7)", # 图标颜色
activecolor="rgba(0, 0, 0, 0.9)" # 激活图标颜色
)
)
# 添加模式栏按钮
fig.update_layout(
modebar_add=[
"zoom2d",
"pan2d",
"select2d",
"lasso2d",
"zoomIn2d",
"zoomOut2d",
"autoScale2d",
"resetScale2d",
"toImage"
]
)
# 配置缩放行为 - 确保滚轮缩放正常工作
fig.update_xaxes(
autorange=False,
fixedrange=False, # 允许缩放
constrain="domain", # 约束在域内
rangeslider=dict(visible=False) # 禁用范围滑块
)
fig.update_yaxes(
autorange=False,
fixedrange=False, # 允许缩放
scaleanchor="x", # 保持纵横比
scaleratio=1, # 缩放比例
constrain="domain" # 约束在域内
)
# 保存并打开结果 - 启用滚轮缩放
fig.write_html(
OUTPUT_HTML,
include_plotlyjs="cdn",
auto_open=True,
config={
'scrollZoom': True, # 启用滚轮缩放
'displayModeBar': True, # 显示工具栏
'displaylogo': False, # 隐藏Plotly标志
'responsive': True # 响应式布局
}
)
print(f"图表已生成: {OUTPUT_HTML}")
# 返回盈亏详情
if not pnl_df.empty:
pnl_df.to_csv("pnl_details.csv", index=False)
print(f"盈亏详情已保存: pnl_details.csv")
if not connections_df.empty:
connections_df.to_csv("trade_connections.csv", index=False)
print(f"订单连接关系已保存: trade_connections.csv")
return fig
# ========== 主执行流程 ==========
def main():
print("开始处理数据...")
# 加载数据
kdf, median_step = load_kline_data()
odf = load_order_data()
print(f"加载K线数据: {len(kdf)}")
print(f"加载订单数据: {len(odf)}")
# 对齐交易时间
odf = align_trades_to_candles(kdf, odf, median_step)
# 检查时间范围
kline_min_time = kdf["time"].min()
kline_max_time = kdf["time"].max()
order_min_time = odf["时间"].min()
order_max_time = odf["时间"].max()
print(f"K线时间范围: {kline_min_time}{kline_max_time}")
print(f"订单时间范围: {order_min_time}{order_max_time}")
# 检查是否有订单在K线时间范围外
outside_orders = odf[(odf["时间"] < kline_min_time) | (odf["时间"] > kline_max_time)]
if not outside_orders.empty:
print(f"警告: 有 {len(outside_orders)} 个订单在K线时间范围外")
print(outside_orders[["时间", "方向", "价格"]])
# 计算盈亏和订单连接关系
pnl_df, cum_realized, connections_df = calculate_pnl(odf)
print(f"累计已实现盈亏: {cum_realized:.2f} USDT")
print(f"订单连接关系: {len(connections_df)}")
# 生成图表
generate_chart(kdf, odf, pnl_df, cum_realized, connections_df)
print("处理完成")
if __name__ == "__main__":
with warnings.catch_warnings():
warnings.simplefilter("ignore")
main()

View File

@@ -1,277 +0,0 @@
open_time,close_time,open_price,close_price,q极,pnl,type,open_order_id,close_order_id,qty
2025-08-28 09:35:18+08:00,2025-08-28 09:44:18+08:00,4514.69,4507.43,664.0,4820.639999999541,short,e1d3a2da-219e-436f-ac9e-a7ea93de15bd,abfa0508-9399-4f1b-90c7-7716c3e7f511,
2025-08-28 10:06:42+08:00,2025-08-28 10:10:07+08:00,4519.88,4515.64,,-4689.439999999759,long,594bd10c-2120-4692-a8eb-9f5325e26ef0,bd643cab-14d4-414d-912e-e9257ddb96de,1106.0
2025-08-28 10:45:07+08:00,2025-08-28 10:51:41+08:00,4512.13,4516.84,1108.0,-5218.68000000004,short,fc0c73ab-9fff-41b5-98c1-ef6f7d300256,206688da-848a-4822-9571-c05302ab7a29,
2025-08-28 11:07:30+08:00,2025-08-28 11:13:19+08:00,4525.0,4529.25,,850.0,long,6197fb5c-6202-422f-9012-5395c5393fb3,59d8859f-2b64-4e8b-aefe-57998b198841,200.0
2025-08-28 11:07:30+08:00,2025-08-28 11:13:19+08:00,4525.0,4529.25,,425.0,long,794c0925-6e48-4b9a-a162-d31d7a3c42cc,59d8859f-2b64-4e8b-aefe-57998b198841,100.0
2025-08-28 11:07:31+08:00,2025-08-28 11:13:19+08:00,4525.0,4529.25,,2052.75,long,65f7d764-ad05-40c7-bce1-6b227ad5f5c0,59d8859f-2b64-4e8b-aefe-57998b198841,483.0
2025-08-28 11:07:31+08:00,2025-08-28 11:13:19+08:00,4525.0,4529.25,,425.0,long,35e1c160-4129-425a-ae46-b8fb45d53ec8,59d8859f-2b64-4e8b-aefe-57998b198841,100.0
2025-08-28 11:28:58+08:00,2025-08-28 11:34:21+08:00,4533.74,4537.34,,1440.0000000001455,long,a983b8f5-70d1-441b-87df-397c6c1ce843,3e161e4e-f367-421a-bc0d-8095f7b79675,400.0
2025-08-28 11:28:58+08:00,2025-08-28 11:34:21+08:00,4533.74,4537.34,,1735.2000000001754,long,a983b8f5-70d1-441b-87df-397c6c1ce843,45ddb145-d637-4985-9c4b-3dee2fd189b5,482.0
2025-08-28 12:22:53+08:00,2025-08-28 12:23:33+08:00,4550.8,4545.04,,-2753.2800000001043,long,37d97b24-c1fd-4a2d-ba0e-75b818062686,fcfe39c7-0bcf-47f6-9b48-a1dd70bd5444,478.0
2025-08-28 12:22:53+08:00,2025-08-28 12:23:33+08:00,4550.8,4545.04,,-2304.0000000000873,long,37d97b24-c1fd-4a2d-ba0e-75b818062686,867b1b2c-0fe5-466b-a89f-ec8dce25bcda,400.0
2025-08-28 12:26:39+08:00,2025-08-28 12:34:19+08:00,4549.6,4555.44,,5133.3599999993285,long,0a3a08a1-61c7-4997-b13c-4da05b2c5dbc,ad149e7f-7088-4dd9-9698-9b7bd615478e,879.0
2025-08-28 12:46:19+08:00,2025-08-28 12:48:10+08:00,4561.8,4567.53,600.0,-3437.999999999738,short,18929fa1-2cc7-4e7f-8e76-c3937f16f877,8283a8b1-17f1-4818-843d-33877996af35,
2025-08-28 12:46:19+08:00,2025-08-28 12:48:10+08:00,4561.8,4567.53,276.0,-1581.4799999998795,short,18929fa1-2cc7-4e7f-8e76-c3937f16f877,c0a1d021-0708-476e-a766-722bc73ab740,
2025-08-28 12:53:40+08:00,2025-08-28 12:57:03+08:00,4577.05,4569.51,873.0,6582.419999999968,short,16f8970d-ef44-4026-ba19-9c9ff6dc70e1,e1f9de7d-115e-4289-8acd-bbba16e04ff0,
2025-08-28 12:58:03+08:00,2025-08-28 13:01:30+08:00,4567.45,4572.58,475.0,-2436.750000000052,short,8dbfcfc8-466c-4111-acdf-316a2a8c7428,3e0a22b4-7707-4332-b80d-87d3b07cf3cc,
2025-08-28 12:58:03+08:00,2025-08-28 13:01:30+08:00,4567.45,4572.58,400.0,-2052.0000000000437,short,8dbfcfc8-466c-4111-acdf-316a2a8c7428,29775823-c3fc-4dbc-8afa-f9587f803f2a,
2025-08-28 13:32:49+08:00,2025-08-28 13:41:18+08:00,4564.18,4565.88,,1225.6999999998689,long,6c0a64d8-b890-42bc-ae09-152919931d57,5bba77bd-b49f-4c6d-9a12-fe062c687cae,721.0
2025-08-28 13:32:49+08:00,2025-08-28 13:41:18+08:00,4564.18,4565.88,,263.4999999999718,long,c0e17c5e-6a39-465c-a3b3-347f1af3d772,5bba77bd-b49f-4c6d-9a12-fe062c687cae,155.0
2025-08-28 13:52:44+08:00,2025-08-28 13:57:25+08:00,4555.2,4559.95,400.0,-1900.0,short,8f641745-890a-4b9c-8d83-10163234429d,dd5f8c6a-74da-4984-aa24-eebfbceb6d22,
2025-08-28 13:52:44+08:00,2025-08-28 13:57:25+08:00,4555.2,4559.95,478.0,-2270.5,short,66c5bcfb-02ef-4a8c-a314-bd9d672decb5,dd5f8c6a-74da-4984-aa24-eebfbceb6d22,
2025-08-28 14:40:01+08:00,2025-08-28 14:41:47+08:00,4572.59,4578.98,874.0,-5584.859999999491,short,1b1efa90-7dd5-4b5f-a170-eb87df7fb7db,26b0c5e5-f4a4-4f47-9fdc-12c6ecd05704,
2025-08-28 15:05:18+08:00,2025-08-28 15:07:11+08:00,4582.63,4577.98,,-279.00000000003274,long,61f7b24d-18b1-44ee-bc9e-60666e4b2346,e53afe94-f3fa-42c1-9e49-619cd77261ab,60.0
2025-08-28 15:05:18+08:00,2025-08-28 15:07:11+08:00,4582.63,4578.03,,-2760.0000000002183,long,61f7b24d-18b1-44ee-bc9e-60666e4b2346,b9cf7c9c-d909-4dad-ae66-64aa0706566f,600.0
2025-08-28 15:05:18+08:00,2025-08-28 15:07:11+08:00,4582.63,4577.52,,-1083.3199999999306,long,61f7b24d-18b1-44ee-bc9e-60666e4b2346,05d46d57-d923-4d18-8c18-5a49927ac910,212.0
2025-08-28 15:22:41+08:00,2025-08-28 15:23:11+08:00,4572.88,4567.91,,-2982.000000000153,long,184c5b21-ed98-43c2-8003-8cc5f8c1bb0a,10d151ec-2891-44fe-8527-89643b3f3b46,600.0
2025-08-28 15:22:41+08:00,2025-08-28 15:23:11+08:00,4572.88,4567.53,,-1465.9000000000997,long,184c5b21-ed98-43c2-8003-8cc5f8c1bb0a,2a5ef255-f800-4e98-a10c-ca3ed33bb372,274.0
2025-08-28 15:57:55+08:00,2025-08-28 16:02:09+08:00,4589.48,4607.47,,9840.530000000377,long,6fdd3eb9-13a9-4e2a-90b6-78e7d71f3fbc,81bc2d5e-8099-4d48-b968-d695a7f1fee4,547.0
2025-08-28 15:57:55+08:00,2025-08-28 16:02:09+08:00,4589.48,4607.47,,5828.760000000224,long,aec18848-d3b5-4786-8c51-a4fdfc454ee2,81bc2d5e-8099-4d48-b968-d695a7f1fee4,324.0
2025-08-28 16:05:54+08:00,2025-08-28 16:09:19+08:00,4614.86,4624.89,,8685.980000000567,long,8e6d3e81-c813-4759-b608-9ed4e547b24d,25509f73-848d-4620-b662-f7f93d76becc,866.0
2025-08-28 16:09:50+08:00,2025-08-28 16:15:00+08:00,4621.56,4617.66,,-3373.500000000472,long,29739f4f-b289-4a1e-a5e7-f6925dd72b4c,7e4c74ac-902f-47c5-9e0a-b2ef07f31e8e,865.0
2025-08-28 16:23:59+08:00,2025-08-28 16:28:31+08:00,4609.17,4602.01,867.0,6207.719999999874,short,6e8dc270-512a-4826-84c9-cfdf82c6cd59,0df8cd52-9db6-4532-99e1-923fcd9c134d,
2025-08-28 16:54:47+08:00,2025-08-28 16:58:41+08:00,4595.28,4599.69,870.0,-3836.6999999998734,short,35598fc3-567f-4ee2-a9fe-db14aab8228b,9777e233-baa8-4238-8f48-ef3e303ff883,
2025-08-28 17:06:53+08:00,2025-08-28 17:15:11+08:00,4595.19,4592.66,870.0,2201.0999999997784,short,3432672f-ced3-401f-981d-7686ddd396e6,bf9ffdef-56bd-4d35-9eef-f92a668d5829,
2025-08-28 17:43:59+08:00,2025-08-28 17:49:12+08:00,4584.79,4581.95,258.0,732.7200000000375,short,c0b26494-b8c4-434e-bc49-e3b317c1fa88,ffbc0ba2-aa7f-4377-bade-cf31e3697b19,
2025-08-28 17:43:59+08:00,2025-08-28 17:49:12+08:00,4584.79,4581.95,114.0,323.7600000000166,short,6fdb9fc7-e0f4-4033-896b-a13160b4fd18,ffbc0ba2-aa7f-4377-bade-cf31e3697b19,
2025-08-28 17:43:59+08:00,2025-08-28 17:49:12+08:00,4584.79,4581.95,500.0,1420.0000000000728,short,b064c485-653b-4f88-a0d1-86961284dc70,ffbc0ba2-aa7f-4377-bade-cf31e3697b19,
2025-08-28 17:49:44+08:00,2025-08-28 17:50:54+08:00,4579.81,4584.85,500.0,-2519.999999999982,short,1f97429c-1de1-467a-8985-8f9bb17000b5,cf389028-3cfb-4521-bf8c-59c3d9782e85,
2025-08-28 17:49:44+08:00,2025-08-28 17:50:54+08:00,4579.81,4584.85,139.0,-700.559999999995,short,989c44a3-a81f-4939-ab13-d9884d845a65,cf389028-3cfb-4521-bf8c-59c3d9782e85,
2025-08-28 17:49:44+08:00,2025-08-28 17:50:54+08:00,4579.58,4584.85,234.0,-1233.1800000001022,short,0b83f7ef-0985-4168-a211-d009f6c6ff1a,cf389028-3cfb-4521-bf8c-59c3d9782e85,
2025-08-28 18:36:51+08:00,2025-08-28 18:43:09+08:00,4609.97,4604.0,,-3182.0100000001357,long,b8391ca4-74b4-41bc-85cd-b4c82cf6e8f3,2926d3da-8a19-4fae-938f-e2556e994376,533.0
2025-08-28 18:36:51+08:00,2025-08-28 18:43:09+08:00,4610.0,4604.0,,-504.0,long,e441f55d-693a-4301-b6c9-10d54ab10357,2926d3da-8a19-4fae-938f-e2556e994376,84.0
2025-08-28 18:36:51+08:00,2025-08-28 18:43:09+08:00,4609.97,4604.0,,-197.0100000000084,long,9dbce008-1d12-422c-80f8-a2c928610074,2926d3da-8a19-4fae-938f-e2556e994376,33.0
2025-08-28 19:46:14+08:00,2025-08-28 19:54:40+08:00,4586.91,4591.36,654.0,-2910.299999999881,short,005b10f4-329d-4d34-8263-b8f63f526ac8,ea07e34c-cd41-4c80-b13f-6b8308257b92,
2025-08-28 20:30:04+08:00,2025-08-28 20:30:34+08:00,4587.25,4588.6,,697.9500000001881,long,26fe1b1b-f4f0-4c49-b6d0-f8445d4e996e,9011ad7e-ef83-4c62-ac90-3e538965ad3f,517.0
2025-08-28 20:30:05+08:00,2025-08-28 20:30:34+08:00,4587.44,4588.6,,410.64000000027045,long,32f1db9d-6a9b-413f-abba-3f698a83ec65,9011ad7e-ef83-4c62-ac90-3e538965ad3f,354.0
2025-08-28 20:31:22+08:00,2025-08-28 20:31:28+08:00,4583.96,4585.9,400.0,-775.9999999998399,short,dd7d8a55-c4bf-4ff8-82b9-ec8591888b0d,ca1e611c-1ba6-4418-9f86-8e492a7726c5,
2025-08-28 20:31:22+08:00,2025-08-28 20:31:29+08:00,4583.96,4585.9,472.0,-915.6799999998111,short,dd7d8a55-c4bf-4ff8-82b9-ec8591888b0d,04792496-7da0-4a9b-95cf-293b41d8292a,
2025-08-28 20:43:41+08:00,2025-08-28 20:46:26+08:00,4609.77,4603.6,,-567.6400000000067,long,da034c24-f333-4197-ae9d-7dfa8639be45,9d59670d-a478-4432-8ec0-e3a8c4ec4d8a,92.0
2025-08-28 20:43:41+08:00,2025-08-28 20:46:26+08:00,4609.77,4603.6,,-3702.0000000000437,long,da034c24-f333-4197-ae9d-7dfa8639be45,e83ff9d3-3078-4f5c-8e6a-fa5750c97b55,600.0
2025-08-28 20:43:41+08:00,2025-08-28 20:46:27+08:00,4609.77,4604.08,,-995.7500000000891,long,da034c24-f333-4197-ae9d-7dfa8639be45,433dc03b-8b85-4951-9f21-dfaa5d6a0de5,175.0
2025-08-29 09:45:36+08:00,2025-08-29 09:49:22+08:00,4466.85,4458.15,447.0,3888.9000000003252,short,87d823b2-675d-4501-bb36-b40eef344b7c,28bb7706-f2ce-480e-b606-fc5073ce4153,
2025-08-29 10:13:26+08:00,2025-08-29 10:18:05+08:00,4470.7,4473.08,,4.760000000000218,long,6d7fe294-0553-46ac-9179-e22446e727dc,b50fd6a4-865b-4cd4-8b83-015dde307912,2.0
2025-08-29 10:13:27+08:00,2025-08-29 10:18:05+08:00,4470.71,4473.08,,1054.6499999999514,long,3d441a61-f852-4d4d-88d9-a2c4494e3a5f,b50fd6a4-865b-4cd4-8b83-015dde307912,445.0
2025-08-29 10:21:04+08:00,2025-08-29 10:25:10+08:00,4479.68,4483.07,,1511.9399999997404,long,9ac71ec9-58a8-43af-83ca-cac772d44dce,7db1d0e0-cdda-45a4-af09-9ec2f6a830a5,446.0
2025-08-29 11:08:08+08:00,2025-08-29 11:10:24+08:00,4477.82,4481.35,,1574.380000000292,long,4c447405-283c-40f7-bc05-42ae2aeaaaeb,de3c12d5-ba88-4b3d-8e8a-2158228465cb,446.0
2025-08-29 11:25:26+08:00,2025-08-29 11:31:14+08:00,4478.16,4482.39,,1886.580000000211,long,877eb021-8a47-4d55-8efd-789fde87699c,33addd17-0151-418d-b11e-d68a26c179e6,446.0
2025-08-29 11:35:59+08:00,2025-08-29 11:43:49+08:00,4484.05,4494.74,,4767.7399999998215,long,913408fa-2541-48c8-a8a0-d352b8b74a93,a7fd376e-dd1c-4350-8c58-1913d130902c,446.0
2025-08-29 11:55:41+08:00,2025-08-29 12:00:52+08:00,4498.11,4489.03,444.0,4031.5199999999677,short,6450e48b-f901-4907-b065-18e073f86534,7cfe2e33-9b17-4785-9e45-dd5654c483c2,
2025-08-29 12:54:59+08:00,2025-08-29 12:58:10+08:00,4477.15,4471.43,670.0,3832.3999999995613,short,13bb04ff-529a-48f4-a062-bdbda01abe9a,01a6ebd4-6c63-4e58-9f52-4317a83a6c27,
2025-08-29 13:05:31+08:00,2025-08-29 13:06:05+08:00,4466.57,4472.34,671.0,-3871.670000000293,short,5c439227-9432-48c1-8c70-184e65586599,398e954e-0534-4f4c-bdda-5d14d858afae,
2025-08-29 13:17:39+08:00,2025-08-29 13:19:35+08:00,4461.42,4468.3,448.0,-3082.240000000049,short,d770f2c0-6aed-4bc2-bee2-f98209775454,14ce65ce-8af2-4c07-8441-bdeea724197e,
2025-08-29 13:59:25+08:00,2025-08-29 14:01:39+08:00,4476.01,4484.33,,382.7199999999866,long,1f80cf00-8910-42af-a7ac-dd2199579d04,96e160f6-0a35-4ac4-9f3e-295065a56092,46.0
2025-08-29 13:59:25+08:00,2025-08-29 14:01:39+08:00,4476.01,4484.33,,3327.9999999998836,long,1f80cf00-8910-42af-a7ac-dd2199579d04,db2ea541-8ece-4876-baa0-f803629d4675,400.0
2025-08-29 14:15:38+08:00,2025-08-29 14:18:12+08:00,4457.41,4451.26,448.0,2755.199999999837,short,2616d754-2ae8-43c0-a382-46901e0dba21,913e0886-23e4-467d-932d-79e960df2947,
2025-08-29 14:37:31+08:00,2025-08-29 14:39:31+08:00,4451.44,4451.34,,-44.89999999975498,long,9f225f1e-cdc5-42cc-8c22-6d39f68da6d6,db5c616d-faf7-4183-8e46-b95f09dbad99,449.0
2025-08-29 14:41:21+08:00,2025-08-29 14:44:17+08:00,4451.53,4455.7,,1872.3300000000327,long,5ba24885-5747-405a-8fa9-6a9749dbe6b4,f7e02df2-857b-4e3a-a6aa-c0d7362cb5bb,449.0
2025-08-29 15:01:14+08:00,2025-08-29 15:02:16+08:00,4448.83,4428.34,449.0,9200.009999999902,short,a605bd22-e12e-44a4-9e1c-87c145bc5aa4,365ff72f-891a-4314-a005-d320d2074d5f,
2025-08-29 15:12:00+08:00,2025-08-29 15:15:04+08:00,4412.37,4393.89,453.0,8371.439999999802,short,03169227-80cc-4c41-89e5-7cbc59174c90,7939f969-7566-453d-a718-dfa6b96ee987,
2025-08-29 15:44:10+08:00,2025-08-29 15:51:01+08:00,4387.22,4391.19,683.0,-2711.5099999995527,short,e2151c19-3f56-4239-8368-77af88a0c2c1,f90b5024-cd5b-44d5-a140-4d6253d49d6a,
2025-08-29 15:57:12+08:00,2025-08-29 16:00:46+08:00,4383.78,4387.09,400.0,-1324.00000000016,short,f2affaff-2beb-481f-b346-c9453422f536,70cc7f5d-b472-40a1-b00b-7e4b032722fc,
2025-08-29 15:57:12+08:00,2025-08-29 16:00:46+08:00,4383.78,4387.09,284.0,-940.0400000001137,short,f2affaff-2beb-481f-b346-c9453422f536,676c76cd-7afa-40db-a0a7-89004bb9387b,
2025-08-29 16:08:15+08:00,2025-08-29 16:11:24+08:00,4386.41,4376.76,383.0,3695.9499999998607,short,da4365c6-5bed-4bff-824c-580b3be527bc,0fdf84b4-d9bd-419e-8fd0-037e8631eefd,
2025-08-29 16:08:15+08:00,2025-08-29 16:11:24+08:00,4386.5,4376.76,300.0,2921.9999999999345,short,940d2d22-8103-4bdd-8eaa-ade1277111da,0fdf84b4-d9bd-419e-8fd0-037e8631eefd,
2025-08-29 16:17:21+08:00,2025-08-29 16:17:29+08:00,4364.59,4365.41,187.0,-153.33999999994558,short,89b93201-dfd2-408c-a5de-b6ecd72424cd,db922d70-7a90-4cf4-9a17-a598fe213f8b,
2025-08-29 16:17:21+08:00,2025-08-29 16:17:29+08:00,4364.59,4365.41,400.0,-327.9999999998836,short,89b93201-dfd2-408c-a5de-b6ecd72424cd,574a0e60-b26e-46bf-a696-cae5868b7af2,
2025-08-29 16:17:21+08:00,2025-08-29 16:17:29+08:00,4365.0,4365.41,100.0,-40.99999999998545,short,e6be51d9-e746-45dd-8522-877cf7eafd33,574a0e60-b26e-46bf-a696-cae5868b7af2,
2025-08-29 16:20:18+08:00,2025-08-29 16:20:36+08:00,4359.92,4362.29,688.0,-1630.559999999925,short,d302895c-7318-4851-838d-396e7100fc09,719a6eff-a759-4947-8f0a-45f2ac94dfc4,
2025-08-29 16:29:12+08:00,2025-08-29 16:33:21+08:00,4355.55,4362.63,,3731.1599999999617,long,f587dcce-e557-4b34-a55f-bf449234faca,e833feb6-8ba7-4fa5-adea-678f690e16b3,527.0
2025-08-29 16:29:12+08:00,2025-08-29 16:33:21+08:00,4355.55,4362.63,,1139.8799999999883,long,22c48502-01b1-4efd-9809-3bc8487b0a9b,e833feb6-8ba7-4fa5-adea-678f690e16b3,161.0
2025-08-29 16:37:39+08:00,2025-08-29 16:40:08+08:00,4356.21,4352.88,688.0,2291.03999999995,short,b209c4ae-8c33-4ba5-ad48-7559d1eafc6a,f7b8931f-1568-4387-a132-8ac6f7f34891,
2025-08-29 16:40:40+08:00,2025-08-29 16:41:12+08:00,4348.53,4353.19,140.0,-652.3999999999796,short,9f88809c-8f0c-4dd4-b83c-552c6b78da3a,b2c3aa90-dcc1-469d-bf31-6c74b8e4099b,
2025-08-29 16:40:40+08:00,2025-08-29 16:41:12+08:00,4348.53,4353.19,549.0,-2558.33999999992,short,3efb68fb-7389-44fd-b48a-d749af57e70f,b2c3aa90-dcc1-469d-bf31-6c74b8e4099b,
2025-08-29 18:24:56+08:00,2025-08-29 18:28:40+08:00,4354.11,4357.4,,1644.9999999999818,long,5b3555c7-8c22-45ad-a4b5-ef6b586335d5,88db631a-7f3b-4b85-9887-94f906259583,500.0
2025-08-29 18:24:56+08:00,2025-08-29 18:28:40+08:00,4354.11,4357.4,,621.8099999999931,long,f6c1a4f1-6aa0-4645-b991-503a320913be,6132d1a3-6d55-4517-b5ba-115198948b85,189.0
2025-08-29 18:30:45+08:00,2025-08-29 18:49:35+08:00,4351.51,4343.72,189.0,1472.3099999999931,short,b67b7a3a-cf62-4731-bc9c-1d333f42e639,2d4f2adb-d806-4f37-8ff1-a46eddccc6b1,
2025-08-29 18:30:45+08:00,2025-08-29 18:49:35+08:00,4351.51,4343.72,500.0,3894.999999999982,short,0acabab2-2ab4-4921-82a0-df806d4eb40d,2d4f2adb-d806-4f37-8ff1-a46eddccc6b1,
2025-08-29 18:58:56+08:00,2025-08-29 19:02:25+08:00,4345.89,4340.99,,-3381.0000000003765,long,b525febe-c7eb-4db9-a4f8-4a09406c9f7d,51ddc961-238a-4c9d-b985-e6ad6ef2aac7,690.0
2025-08-29 19:14:13+08:00,2025-08-29 19:18:33+08:00,4351.49,4346.64,,-3341.649999999624,long,da8dccbd-f79c-476b-9471-d28b719da66f,cfbfe97f-e085-41db-8679-58574bd165fd,689.0
2025-08-29 19:49:41+08:00,2025-08-29 19:51:55+08:00,4345.68,4340.66,,-3463.800000000301,long,98c03fb1-dca8-43ef-9ca7-0fe6d842946b,e0c7b8be-c842-412e-bb4f-e43b51fa53bb,690.0
2025-08-29 20:22:08+08:00,2025-08-29 20:30:35+08:00,4365.85,4411.23,,31176.059999999452,long,7ab49fe4-9bd7-4368-bb45-ffe9970e4999,c3d6e447-288e-48d1-8977-ccceda6a2e41,687.0
2025-08-29 20:31:05+08:00,2025-08-29 20:31:21+08:00,4439.0,4448.35,,149.60000000000582,long,76a58764-fd12-4fb4-8ee9-407aa2213a12,e3f58dbc-6a93-4c16-9dc3-7e351493f00f,16.0
2025-08-29 20:31:05+08:00,2025-08-29 20:31:21+08:00,4439.0,4448.35,,6161.65000000024,long,cdd4a741-4195-4fac-9896-35ee5c09a7b9,e3f58dbc-6a93-4c16-9dc3-7e351493f00f,659.0
2025-08-29 20:31:46+08:00,2025-08-29 20:33:05+08:00,4409.9,4406.3,,-647.9999999999018,long,a47f68a7-9565-4ea7-b3ab-770d376ffcea,46e071a8-871b-4373-92a5-8cd6cd46cc56,180.0
2025-08-29 20:31:46+08:00,2025-08-29 20:33:05+08:00,4409.9,4406.3,,-1799.9999999997272,long,a47f68a7-9565-4ea7-b3ab-770d376ffcea,c67209e2-0598-443d-85fa-752bdae6059b,500.0
2025-08-29 20:43:25+08:00,2025-08-29 20:44:07+08:00,4382.62,4386.13,684.0,-2400.8400000001493,short,af3305f0-ec39-48fe-bf71-ac9acb281b25,7556c209-5046-4e8b-8682-99dc36803a62,
2025-08-29 20:45:44+08:00,2025-08-29 20:49:11+08:00,4389.13,4407.06,,1828.8600000000297,long,a19435e4-fbf9-4217-bc5d-d7fc07d9818f,cc0577e9-e4b6-45fd-bf5a-47ccf6aec320,102.0
2025-08-29 20:45:44+08:00,2025-08-29 20:49:11+08:00,4389.13,4407.06,,10417.33000000017,long,a19435e4-fbf9-4217-bc5d-d7fc07d9818f,4fa96e6c-6692-426b-beca-c138c8505a82,581.0
2025-08-29 20:49:46+08:00,2025-08-29 20:53:14+08:00,4406.49,4406.02,500.0,234.99999999967258,short,d11f3a55-a1d8-41ff-a979-778c232459c9,b2de5ff9-9281-4c2e-86bd-a071a5e1e864,
2025-08-29 20:49:46+08:00,2025-08-29 20:53:14+08:00,4406.49,4406.02,180.0,84.59999999988213,short,d11f3a55-a1d8-41ff-a979-778c232459c9,a4e3c4e5-4280-417c-8018-8386a63c318a,
2025-08-29 21:00:24+08:00,2025-08-29 21:00:33+08:00,4408.35,4405.11,,-2203.20000000047,long,26e94954-9b31-48a9-9b2b-cb08da0f8e3e,14772435-8e33-4ee5-a87c-81342a7f8449,680.0
2025-08-29 21:01:47+08:00,2025-08-29 21:06:54+08:00,4406.15,4391.41,39.0,574.8599999999915,short,8665f24a-3e13-4d3f-ad28-a702c79c73ed,7addab21-fcf3-4921-97ab-d77462067550,
2025-08-29 21:01:47+08:00,2025-08-29 21:06:54+08:00,4406.15,4391.41,141.0,2078.339999999969,short,0170663d-0cf1-43a4-8595-4511c59b3107,7addab21-fcf3-4921-97ab-d77462067550,
2025-08-29 21:01:47+08:00,2025-08-29 21:06:54+08:00,4406.15,4391.41,500.0,7369.999999999891,short,0170663d-0cf1-43a4-8595-4511c59b3107,3b754022-7c7c-4b14-8251-c2da4478df27,
2025-08-29 21:10:41+08:00,2025-08-29 21:11:27+08:00,4400.55,4392.88,,-107.38000000000102,long,37e79409-f3ed-4e62-811c-6cc437396a41,f3a43d61-4d64-4d82-aada-31b38d441baa,14.0
2025-08-29 21:10:41+08:00,2025-08-29 21:11:27+08:00,4400.55,4392.79,,-519.9200000000146,long,37e79409-f3ed-4e62-811c-6cc437396a41,86bfa728-af41-4e41-9e87-d6ef88b1a063,67.0
2025-08-29 21:10:41+08:00,2025-08-29 21:11:27+08:00,4400.55,4392.88,,-4602.000000000044,long,37e79409-f3ed-4e62-811c-6cc437396a41,af01f0d0-8844-4267-8476-4000d0b2dd8b,600.0
2025-08-29 21:30:11+08:00,2025-08-29 21:34:27+08:00,4386.05,4373.6,72.0,896.3999999999869,short,fecb81e1-3b36-4ae6-91ad-b6a2616ee608,aee7c322-ba5d-4b89-8b93-1c50ce5be75b,
2025-08-29 21:30:11+08:00,2025-08-29 21:34:27+08:00,4386.05,4372.44,211.0,2871.710000000123,short,fecb81e1-3b36-4ae6-91ad-b6a2616ee608,e20951ed-ff4e-4a06-8bb5-8112a72e38bf,
2025-08-29 21:30:11+08:00,2025-08-29 21:34:27+08:00,4386.05,4372.44,99.0,1347.3900000000576,short,fecb81e1-3b36-4ae6-91ad-b6a2616ee608,16329965-69b4-42a4-8145-79d1a0d2e92b,
2025-08-29 21:30:11+08:00,2025-08-29 21:34:27+08:00,4386.29,4372.44,101.0,1398.8500000000367,short,f1e4b54c-d392-4dc4-8f73-40a8733b85fe,16329965-69b4-42a4-8145-79d1a0d2e92b,
2025-08-29 21:30:11+08:00,2025-08-29 21:34:27+08:00,4386.29,4372.44,200.0,2770.0000000000728,short,f1e4b54c-d392-4dc4-8f73-40a8733b85fe,1b66a876-041a-480e-a9d6-428a3e301ec4,
2025-08-30 08:15:30+08:00,2025-08-30 08:25:24+08:00,4343.62,4355.47,,4740.0000000001455,long,fb636839-9fb2-4e2f-bdb0-14bd57ade58a,6b8d4b73-132c-4c86-92f9-2a5df18943fd,400.0
2025-08-30 08:15:30+08:00,2025-08-30 08:25:24+08:00,4343.62,4355.47,,3436.5000000001055,long,fb636839-9fb2-4e2f-bdb0-14bd57ade58a,a744bd39-3c81-4cb1-a153-60ed71d6748f,290.0
2025-08-30 08:32:12+08:00,2025-08-30 08:35:26+08:00,4342.48,4337.98,,-288.0,long,e6185c1c-debd-4a9c-928c-edd28b360578,401ccb35-f82c-4df2-9a29-f9cd57481767,64.0
2025-08-30 08:32:12+08:00,2025-08-30 08:35:26+08:00,4342.48,4335.64,,-3850.91999999957,long,e6185c1c-debd-4a9c-928c-edd28b360578,69d6c400-d534-47b6-b2a8-8da09b2986aa,563.0
2025-08-30 08:32:12+08:00,2025-08-30 08:35:26+08:00,4342.48,4335.73,,-425.25,long,e6185c1c-debd-4a9c-928c-edd28b360578,4aa4a001-f8b0-4aea-93c3-546c71b81ee0,63.0
2025-08-30 08:37:25+08:00,2025-08-30 08:41:59+08:00,4336.85,4332.05,691.0,3316.8000000001257,short,5cc6dd95-ec96-4864-a085-95b875673f0f,07f9b455-a026-41df-95c6-f9cf37f23a90,
2025-08-30 09:26:28+08:00,2025-08-30 09:29:48+08:00,4326.54,4324.64,293.0,556.6999999998934,short,ce7db548-7de1-448e-92c9-25139a5f23a4,70062cb1-9074-49a9-8e7f-b5b7bae639d4,
2025-08-30 09:26:28+08:00,2025-08-30 09:29:48+08:00,4326.54,4323.46,400.0,1231.999999999971,short,ce7db548-7de1-448e-92c9-25139a5f23a4,6145a0a3-248c-4822-8e8c-5efb6daf7d24,
2025-08-30 09:51:41+08:00,2025-08-30 09:55:09+08:00,4312.57,4289.19,177.0,4138.260000000019,short,4b786a41-410d-4c93-b1c6-30b118f9e7f2,f78be76a-092e-4e0e-b8c3-26867d78c1de,
2025-08-30 09:51:41+08:00,2025-08-30 09:55:09+08:00,4312.57,4289.19,518.0,12110.840000000057,short,96fbc46a-1dd3-4fc6-9e14-4a032e9464bf,f78be76a-092e-4e0e-b8c3-26867d78c1de,
2025-08-30 09:55:49+08:00,2025-08-30 09:55:50+08:00,4282.58,4282.19,,-273.0000000002292,long,201dbee0-8f0d-427d-95d5-ef84e08a8aab,37ff5d0c-e10e-480c-91ca-0506e61330b6,700.0
2025-08-30 09:58:19+08:00,2025-08-30 09:58:59+08:00,4281.59,4280.23,,-952.0000000004075,long,0e651112-db3b-402d-a268-1ea200cf8729,65b07548-3473-4570-be22-0172c49bdb94,700.0
2025-08-30 10:00:09+08:00,2025-08-30 10:00:52+08:00,4264.04,4268.35,703.0,-3029.9300000002813,short,d9703fdd-ea02-410d-8303-d1d13b94748f,17fca37e-fc89-48a9-92ed-671ab0b9088e,
2025-08-30 10:01:23+08:00,2025-08-30 10:02:02+08:00,4268.54,4271.97,110.0,-377.300000000032,short,022ce461-b78f-4127-9157-8c34a5e9272e,89468587-89ce-49cc-a9e3-343e24cb8036,
2025-08-30 10:01:23+08:00,2025-08-30 10:02:02+08:00,4268.54,4271.97,592.0,-2030.5600000001723,short,9bdcfab5-9b8e-447c-b4ac-a82724e2774d,89468587-89ce-49cc-a9e3-343e24cb8036,
2025-08-30 10:02:55+08:00,2025-08-30 10:04:26+08:00,4275.14,4280.56,400.0,-2168.000000000029,short,1b938bf4-dc99-4d2f-9e0b-c2fa5092d19d,4e6c40d8-e7c7-45ac-800e-5f71611479f1,
2025-08-30 10:02:55+08:00,2025-08-30 10:04:26+08:00,4275.14,4280.56,141.0,-764.2200000000103,short,1b938bf4-dc99-4d2f-9e0b-c2fa5092d19d,864390a3-33dd-4a47-a3c2-471b8a0104f1,
2025-08-30 10:02:55+08:00,2025-08-30 10:04:26+08:00,4275.14,4280.56,160.0,-867.2000000000116,short,7eb3eaf4-30fa-495d-a74c-61d725625c42,864390a3-33dd-4a47-a3c2-471b8a0104f1,
2025-08-30 10:11:35+08:00,2025-08-30 10:18:43+08:00,4296.88,4306.91,,2326.959999999941,long,b1a002d6-951f-4912-b8cf-19bfc98f61ba,743a1e0f-48f3-43fe-9b6a-47536fa12ce1,232.0
2025-08-30 10:11:35+08:00,2025-08-30 10:18:43+08:00,4296.91,4306.91,,4660.0,long,94664c85-6be6-42d8-984a-f3293ed9750f,743a1e0f-48f3-43fe-9b6a-47536fa12ce1,466.0
2025-08-30 10:21:54+08:00,2025-08-30 10:27:07+08:00,4307.47,4306.32,696.0,800.4000000003798,short,641e7574-db24-4c78-8782-566b13de1e39,817cbe73-8f5f-4c27-893c-ddfe59e1890d,
2025-08-30 10:28:32+08:00,2025-08-30 10:35:18+08:00,4305.75,4311.46,,2855.000000000018,long,dee31b34-3e7f-4b74-8774-ccd70f3cb124,d37eec35-4b90-42c7-82e7-7a56e909d268,500.0
2025-08-30 10:28:32+08:00,2025-08-30 10:35:18+08:00,4305.75,4311.25,,1078.0,long,dee31b34-3e7f-4b74-8774-ccd70f3cb124,9cbf242a-7e93-4a3c-b798-6e3f7a88025d,196.0
2025-08-30 10:48:32+08:00,2025-08-30 10:57:53+08:00,4313.05,4303.81,695.0,6421.799999999848,short,0efcab97-a0b6-4cd6-ad7e-22911ea32fa2,57fa177a-12c5-4127-91c4-289668a191ae,
2025-08-30 11:03:45+08:00,2025-08-30 11:10:25+08:00,4308.11,4322.99,,4404.480000000032,long,36e3b573-d4be-4d54-9af3-8190731448c9,1e9213a7-3443-4209-a26a-d3e0feeaf325,296.0
2025-08-30 11:03:45+08:00,2025-08-30 11:10:25+08:00,4308.11,4322.99,,5952.000000000044,long,36e3b573-d4be-4d54-9af3-8190731448c9,a344d092-7b22-4230-8ba9-0702dd353041,400.0
2025-08-30 11:11:04+08:00,2025-08-30 11:17:45+08:00,4323.24,4328.87,,3901.5900000000756,long,c2e861bb-6de2-4dc0-aed3-7a385c0f34b8,d786c18b-8199-4335-ad6b-6115f39e089f,693.0
2025-08-30 11:18:36+08:00,2025-08-30 11:23:02+08:00,4333.76,4358.0,,9695.999999999913,long,3c5242f4-5844-46a7-8b84-a6c73fed27c7,d71ce99c-8d8e-4f15-be2e-85d21e853298,400.0
2025-08-30 11:18:36+08:00,2025-08-30 11:23:02+08:00,4333.76,4358.0,,3248.1599999999708,long,3c5242f4-5844-46a7-8b84-a6c73fed27c7,fe3607bd-9257-42ce-a0b3-06d882cb74af,134.0
2025-08-30 11:18:36+08:00,2025-08-30 11:23:02+08:00,4333.76,4358.0,,3829.9199999999655,long,ce9f82f0-70a9-44b1-9175-4ee31dbc8fd6,fe3607bd-9257-42ce-a0b3-06d882cb74af,158.0
2025-08-30 11:52:34+08:00,2025-08-30 11:57:42+08:00,4352.62,4352.32,,-20.70000000001255,long,a7a38452-b2e4-46c1-a14c-d85c0a79b250,078499df-67ff-4bdd-acaf-4e4fcf4457c0,69.0
2025-08-30 11:52:34+08:00,2025-08-30 11:57:42+08:00,4352.62,4352.32,,-186.00000000011278,long,76c6328b-ae56-4313-9b73-3bc43f644ef4,078499df-67ff-4bdd-acaf-4e4fcf4457c0,620.0
2025-08-30 12:01:25+08:00,2025-08-30 12:07:56+08:00,4351.41,4357.44,500.0,-3014.9999999998727,short,2228c2d3-6d7b-4835-8065-42ce6ad3a5af,3544a077-b511-45ef-b088-c380928048ee,
2025-08-30 12:01:25+08:00,2025-08-30 12:07:56+08:00,4351.7,4357.44,121.0,-694.5399999999736,short,e33d8985-328c-4a44-829e-b8ebf6127582,3544a077-b511-45ef-b088-c380928048ee,
2025-08-30 12:01:25+08:00,2025-08-30 12:07:56+08:00,4351.41,4357.44,527.0,-3177.809999999866,short,6f169ccd-3d5a-4e35-9653-7efd0a1580dc,3544a077-b511-45ef-b088-c380928048ee,
2025-08-30 13:01:32+08:00,2025-08-30 13:07:24+08:00,4353.26,4358.47,577.0,-3006.170000000021,short,27412351-b7db-41d2-941e-014723b46c1a,f65cc5f5-8a78-4a59-bb58-cf0af4df8448,
2025-08-30 13:01:33+08:00,2025-08-30 13:07:24+08:00,4353.26,4358.47,298.0,-1552.5800000000108,short,cab58243-ce8d-4149-b279-3417eac36fcd,f65cc5f5-8a78-4a59-bb58-cf0af4df8448,
2025-08-30 13:01:33+08:00,2025-08-30 13:07:24+08:00,4353.26,4359.1,273.0,-1594.3200000000397,short,cab58243-ce8d-4149-b279-3417eac36fcd,c28367f5-fcb9-4345-82f2-c56451e2e462,
2025-08-30 13:20:13+08:00,2025-08-30 13:32:38+08:00,4373.03,4377.0,1143.0,-4537.710000000291,short,0f73205b-a08a-4fad-9e77-f5d2fbbf1aee,6d5e0a1c-53e6-4fac-a76a-77cb3341a976,
2025-08-30 13:33:46+08:00,2025-08-30 13:42:14+08:00,4385.31,4391.97,,7592.399999999834,long,11f0898c-7cba-49da-91d9-1fc6e9b57ab2,e7744350-f030-4566-bdeb-8a76060f8066,1140.0
2025-08-30 13:48:01+08:00,2025-08-30 13:56:36+08:00,4395.74,4382.93,1137.0,14564.96999999942,short,d00ac585-7cde-477d-af47-a5889aa5ef70,e99ef7df-85e7-46b4-bc8a-4a6f2fc811fe,
2025-08-30 13:58:04+08:00,2025-08-30 14:03:08+08:00,4381.43,4385.01,1141.0,-4084.779999999917,short,76216a51-657b-4659-86cb-2295aa642dac,8a9ab27e-38f2-4ec3-bbaf-642afd20a6e5,
2025-08-30 14:10:44+08:00,2025-08-30 14:15:13+08:00,4383.15,4377.63,601.0,3317.5199999997158,short,587020d7-a3eb-4e44-b6c7-5c95b8c5451a,8ecfa693-c528-405b-8db4-0b02ccc7b9b3,
2025-08-30 14:10:44+08:00,2025-08-30 14:15:13+08:00,4383.15,4377.63,500.0,2759.9999999997635,short,587020d7-a3eb-4e44-b6c7-5c95b8c5451a,babe1585-607c-4004-9aa9-19e1f5374ac1,
2025-08-30 14:10:44+08:00,2025-08-30 14:15:13+08:00,4383.15,4377.63,39.0,215.27999999998156,short,587020d7-a3eb-4e44-b6c7-5c95b8c5451a,ab4e9d81-4133-42b0-9460-9a2efd36ec0b,
2025-08-30 14:26:36+08:00,2025-08-30 14:33:14+08:00,4384.3,4391.39,,8082.600000000166,long,f703a5cc-3428-4796-a288-bfa6442800cb,a4e60efd-9afc-48b1-8850-6054e1330780,1140.0
2025-08-30 14:45:13+08:00,2025-08-30 14:52:41+08:00,4395.22,4390.35,1137.0,5537.189999999876,short,b1f16517-7b15-43a4-a3e7-8f0b60f9f732,0445e9e3-c80c-4beb-a121-18b6094f52eb,
2025-08-30 15:20:15+08:00,2025-08-30 15:40:40+08:00,4392.17,4398.92,52.0,-351.0,short,504ad303-3016-470e-9deb-a717d25a761c,9a648f36-ef00-45a4-8e56-868ab74acce6,
2025-08-30 15:20:15+08:00,2025-08-30 15:40:40+08:00,4392.17,4398.92,500.0,-3375.0,short,59f674e3-aff1-4b79-b8b0-c650b299d27d,9a648f36-ef00-45a4-8e56-868ab74acce6,
2025-08-30 15:20:15+08:00,2025-08-30 15:40:40+08:00,4392.17,4398.92,586.0,-3955.5,short,77548f6a-59ae-4ac2-880c-ea1f5679f507,9a648f36-ef00-45a4-8e56-868ab74acce6,
2025-08-30 15:46:04+08:00,2025-08-30 15:50:09+08:00,4408.51,4402.78,,-6497.820000000536,long,76eb4bce-ff36-4d4c-b97a-cda6d9f7b544,63f7184c-7211-417f-b594-e39436d14940,1134.0
2025-08-30 16:11:35+08:00,2025-08-30 16:32:13+08:00,4393.35,4389.12,400.0,1692.0000000001892,short,be9ff2ce-0d9e-4184-8d43-c49b33c71c95,754db465-b458-43a3-b2b5-3fb4f9fc2aaf,
2025-08-30 16:11:35+08:00,2025-08-30 16:32:13+08:00,4393.35,4389.12,500.0,2115.0000000002365,short,cdf388db-68a2-47ea-ba94-431f02dadeac,754db465-b458-43a3-b2b5-3fb4f9fc2aaf,
2025-08-30 16:11:35+08:00,2025-08-30 16:32:13+08:00,4393.35,4389.12,237.0,1002.5100000001121,short,e6f8d379-c20f-4a9d-90a4-7a5904bff1f9,754db465-b458-43a3-b2b5-3fb4f9fc2aaf,
2025-08-30 17:05:10+08:00,2025-08-30 17:11:26+08:00,4390.54,4387.01,133.0,469.48999999996613,short,d4db2208-ba63-42c7-af51-9cec92bfe6f1,46858333-121c-4020-9567-bc44d63dec01,
2025-08-30 17:05:10+08:00,2025-08-30 17:11:26+08:00,4390.54,4387.01,190.0,670.6999999999516,short,d4db2208-ba63-42c7-af51-9cec92bfe6f1,4d19376a-cfb7-4da9-8859-982e073624d1,
2025-08-30 17:05:10+08:00,2025-08-30 17:11:26+08:00,4390.54,4387.01,310.0,1094.299999999921,short,00dda8f5-7156-4d25-9ea0-29e5fb2a4aca,4d19376a-cfb7-4da9-8859-982e073624d1,
2025-08-30 17:05:10+08:00,2025-08-30 17:11:26+08:00,4390.54,4387.01,505.0,1782.6499999998714,short,00dda8f5-7156-4d25-9ea0-29e5fb2a4aca,e28b9838-7c48-4c78-a369-8259844cc3f4,
2025-08-30 17:18:39+08:00,2025-08-30 17:28:37+08:00,4389.73,4385.08,,-5296.349999999586,long,2789c169-8a5d-47da-a6f9-6800e72ec26e,cd9481fb-33de-4e75-beb8-119ace92b5f6,1139.0
2025-08-30 17:31:17+08:00,2025-08-30 17:37:08+08:00,4379.77,4384.13,1141.0,-4974.759999999626,short,434fc13a-925d-4abd-8677-0cd2b1a412f0,1e63ca1f-7f77-4ed9-a885-159f5dac641e,
2025-08-30 17:44:10+08:00,2025-08-30 17:48:40+08:00,4384.13,4388.17,1140.0,-4605.5999999999585,short,288b4dc7-affd-4b36-897a-e02a024dbae0,70c0e310-219d-45d2-a91d-6b685af4a065,
2025-08-30 17:50:34+08:00,2025-08-30 17:54:02+08:00,4389.94,4393.0,,3482.2800000004554,long,b78acf6a-d3b3-44c2-b484-ad95dfedd167,9473c228-7657-44cd-9038-38aeb833c3ab,1138.0
2025-08-30 18:05:09+08:00,2025-08-30 18:07:30+08:00,4392.24,4394.52,,2594.640000000745,long,44cd4f02-5250-47d0-8e71-a66f856405ba,81abc1fa-1789-4f69-aaaa-2da1f3f34186,1138.0
2025-08-31 10:28:55+08:00,2025-08-31 10:34:47+08:00,4450.3,4446.25,,-1320.3000000000593,long,0fe00795-d7d9-4586-b864-e445017c7f9d,716e265c-d39a-46b3-92e2-99f5d8a6b45f,326.0
2025-08-31 10:28:55+08:00,2025-08-31 10:34:47+08:00,4450.3,4446.25,,-2316.600000000104,long,0fe00795-d7d9-4586-b864-e445017c7f9d,e7b360d6-da94-4cb7-b8c7-0b10db53a03b,572.0
2025-08-31 11:08:10+08:00,2025-08-31 11:12:01+08:00,4454.6,4458.68,897.0,-3659.7599999999347,short,c31d66e2-a558-4b86-a520-3a9eb9d55346,f737efdc-5818-4bc5-b3db-1da76e7caf71,
2025-08-31 11:24:10+08:00,2025-08-31 11:27:33+08:00,4457.8,4453.59,,-2138.6800000000185,long,38413547-9d48-43fc-a2be-12d2a8e0cd9f,ce5c15c0-d938-4b48-ab08-807531847f2e,508.0
2025-08-31 11:24:10+08:00,2025-08-31 11:27:33+08:00,4457.8,4453.59,,-1637.6900000000142,long,816792ec-d409-4688-b7fd-2ee3e3f4491e,ce5c15c0-d938-4b48-ab08-807531847f2e,389.0
2025-08-31 11:49:43+08:00,2025-08-31 11:53:50+08:00,4462.28,4469.74,,3730.000000000018,long,b1e2c3bf-db41-4762-b152-7a6a469c8cdb,52c185f1-3f74-42b6-afe5-6032df9dcb11,500.0
2025-08-31 11:49:43+08:00,2025-08-31 11:53:50+08:00,4462.28,4469.74,,2954.1600000000144,long,b1e2c3bf-db41-4762-b152-7a6a469c8cdb,5fbbe739-8d3c-4aab-8333-7860bdca1d69,396.0
2025-08-31 11:54:26+08:00,2025-08-31 12:00:20+08:00,4475.79,4483.53,,2267.819999999936,long,614c6489-c5a5-451d-a2a0-699e38d5a695,5da7f47f-33e3-45b8-9dfe-8232807978fc,293.0
2025-08-31 11:54:26+08:00,2025-08-31 12:00:20+08:00,4475.79,4483.53,,1547.9999999999563,long,c443995b-f986-4a55-b6d9-59c43fa71fd2,5da7f47f-33e3-45b8-9dfe-8232807978fc,200.0
2025-08-31 11:54:26+08:00,2025-08-31 12:00:20+08:00,4475.79,4483.53,,3095.9999999999127,long,c443995b-f986-4a55-b6d9-59c43fa71fd2,7d96c3c9-b227-48f3-b9fe-9a5c08871cfe,400.0
2025-08-31 12:15:25+08:00,2025-08-31 12:25:03+08:00,4473.35,4467.05,894.0,5632.200000000163,short,d5064049-73a7-4a01-8d14-3d0ba056d572,b4537133-4056-4afc-80c2-7656e28cff88,
2025-08-31 12:30:21+08:00,2025-08-31 12:33:51+08:00,4461.85,4465.99,500.0,-2069.999999999709,short,516d9754-0fe4-4f2e-9289-5827765f7c67,13f52cac-de10-4bba-93d5-8376ba2c5139,
2025-08-31 12:30:21+08:00,2025-08-31 12:33:51+08:00,4461.85,4465.88,100.0,-402.99999999997453,short,516d9754-0fe4-4f2e-9289-5827765f7c67,a77196b2-cc47-482b-8fb0-a140d25da936,
2025-08-31 12:30:21+08:00,2025-08-31 12:33:51+08:00,4461.85,4465.99,296.0,-1225.4399999998277,short,516d9754-0fe4-4f2e-9289-5827765f7c67,c529dbf2-2dd4-46aa-b5b6-dd0ed4f473e2,
2025-08-31 12:42:50+08:00,2025-08-31 12:48:13+08:00,4464.2,4468.3,661.0,-2710.1000000002405,short,0f3ef65f-e754-4229-87e6-e0f102020ce9,bce7cdc5-2c37-4bda-9b2a-05c865dd69ba,
2025-08-31 12:42:50+08:00,2025-08-31 12:48:13+08:00,4464.2,4468.3,235.0,-963.5000000000855,short,10e40e0b-a920-4e80-8d17-ea6f73d645e3,bce7cdc5-2c37-4bda-9b2a-05c865dd69ba,
2025-08-31 13:31:35+08:00,2025-08-31 13:38:28+08:00,4453.99,4450.23,,-376.0000000000218,long,e65553ad-4738-4b5f-af08-c7373301aef8,ce3b836f-f3c8-4e27-bdd5-33b9e1ba2bc9,100.0
2025-08-31 13:31:35+08:00,2025-08-31 13:38:28+08:00,4454.98,4450.23,,-2850.0,long,57f64aba-942f-4563-a3c7-9dfdfeaf98e4,ce3b836f-f3c8-4e27-bdd5-33b9e1ba2bc9,600.0
2025-08-31 13:31:35+08:00,2025-08-31 13:38:28+08:00,4454.98,4450.23,,-940.5,long,597f272b-ce3c-45bf-99ee-4abe2f630972,ce3b836f-f3c8-4e27-bdd5-33b9e1ba2bc9,198.0
2025-08-31 14:22:05+08:00,2025-08-31 14:23:54+08:00,4441.46,4446.28,275.0,-1325.49999999992,short,eafee2f8-8601-47c7-bfe0-2f0a35bd1411,3744b6fa-5971-44d1-885f-7c7f93da8e70,
2025-08-31 14:22:05+08:00,2025-08-31 14:23:54+08:00,4442.21,4446.28,100.0,-406.9999999999709,short,702cd777-dc0b-4602-8c19-618520cf46f4,3744b6fa-5971-44d1-885f-7c7f93da8e70,
2025-08-31 14:22:05+08:00,2025-08-31 14:23:54+08:00,4441.46,4446.28,525.0,-2530.499999999847,short,be46bffb-290a-477a-81d9-fd4e7c1d2f3c,3744b6fa-5971-44d1-885f-7c7f93da8e70,
2025-08-31 14:33:49+08:00,2025-08-31 14:39:00+08:00,4439.81,4444.22,900.0,-3968.999999999869,short,f25e9b2a-1bb7-4bc5-852e-5c953f222f61,2d0c6c6c-070a-498b-ade7-0235a6d3e644,
2025-08-31 14:40:14+08:00,2025-08-31 14:47:51+08:00,4444.0,4439.28,,-1939.9200000001047,long,46e5c712-8dff-423d-805d-d09da5e43571,9a2c96f9-3c09-4cca-8539-7251e96e99df,411.0
2025-08-31 14:40:14+08:00,2025-08-31 14:47:51+08:00,4444.0,4439.13,,-1947.9999999999563,long,46e5c712-8dff-423d-805d-d09da5e43571,f92ff1ec-cfa2-4576-bcbb-978910e5200c,400.0
2025-08-31 14:40:14+08:00,2025-08-31 14:47:51+08:00,4444.0,4439.13,,-433.4299999999903,long,46e5c712-8dff-423d-805d-d09da5e43571,5f572e4d-e1a7-45cf-bc1b-b55ce56f12b4,89.0
2025-08-31 14:51:09+08:00,2025-08-31 14:57:17+08:00,4436.57,4435.16,450.0,634.4999999999345,short,3d5b8a22-edc9-4076-8d61-23f8ed561202,9c959838-3125-426e-abaf-d09fc309fda2,
2025-08-31 15:30:46+08:00,2025-08-31 15:33:17+08:00,4450.96,4446.74,,-1894.7800000001143,long,45ada65c-b8e3-4316-9414-5faf1dcad582,57564f53-121e-47ac-8804-e448bb39c82c,449.0
2025-08-31 16:05:31+08:00,2025-08-31 16:08:48+08:00,4461.21,4457.34,,-1733.759999999951,long,050937e7-f1e4-459e-982a-8d5263e718cb,ad5c9d31-f050-4981-9f51-7852dbf0df37,448.0
2025-08-31 16:20:45+08:00,2025-08-31 16:24:22+08:00,4463.0,4462.93,,-3.35999999998603,long,e41030f3-095f-4e36-b465-e7f7d20b2972,83b7259d-91f7-485a-92ee-37c94790c7f4,48.0
2025-08-31 16:20:45+08:00,2025-08-31 16:24:22+08:00,4463.0,4462.93,,-27.999999999883585,long,e41030f3-095f-4e36-b465-e7f7d20b2972,de316218-6bb2-48c0-b540-fc4babf5ce9b,400.0
2025-08-31 17:24:37+08:00,2025-08-31 17:27:28+08:00,4473.73,4467.56,447.0,2757.989999999626,short,b8d42b12-b7c8-465d-a67b-56085ceae48f,74ed9f75-4d45-47a8-a636-5a1cbe5511ce,
2025-08-31 17:48:57+08:00,2025-08-31 17:52:50+08:00,4463.45,4470.31,,3073.2800000002608,long,9b9c8688-3c74-48c3-b1bf-6bbc162b3edf,70a47e37-f8fb-440f-9ea6-50ffbf8055f6,448.0
2025-08-31 17:59:19+08:00,2025-08-31 18:00:09+08:00,4461.24,4465.19,152.0,-600.3999999999724,short,28a00768-c1e1-42d0-b75e-f7b6b8608b60,9263141f-f5ac-4173-b3c2-b8e2f7ba0985,
2025-08-31 17:59:19+08:00,2025-08-31 18:00:09+08:00,4461.24,4465.19,520.0,-2053.9999999999054,short,28a00768-c1e1-42d0-b75e-f7b6b8608b60,32d89f55-ae9c-49a6-8e2a-e47b5f4167ab,
2025-08-31 18:07:59+08:00,2025-08-31 18:12:30+08:00,4459.1,4452.94,672.0,4139.520000000513,short,765d6b9a-0683-4dca-b76c-6e9a2ea65cd5,7f047d14-dac5-4fca-94ed-c0fdfec63578,
2025-08-31 18:17:18+08:00,2025-08-31 18:29:14+08:00,4451.84,4455.42,,2409.339999999951,long,755ad988-d66e-4bc8-9907-b69112e3a11a,775a3323-bbd4-4e5c-ae56-d68e178eb05e,673.0
2025-08-31 22:07:31+08:00,2025-08-31 22:13:15+08:00,4453.82,4450.0,1122.0,4286.0399999996735,short,c3c54d31-6a99-45ad-8139-546ac61bed34,ef4df9cc-3394-4d53-8fed-7e261a8b0c60,
2025-08-31 22:14:11+08:00,2025-08-31 22:20:53+08:00,4453.63,4459.25,,2809.9999999999454,long,18042f61-552b-41bb-b228-8d8031ee3c14,ad7b6056-101b-49e4-9b9f-dea68880cd52,500.0
2025-08-31 22:14:11+08:00,2025-08-31 22:20:53+08:00,4453.63,4459.25,,685.6399999999867,long,208d18b8-941b-4ce3-aa29-2f5fb074cc01,ad7b6056-101b-49e4-9b9f-dea68880cd52,122.0
2025-08-31 22:14:11+08:00,2025-08-31 22:20:53+08:00,4453.63,4459.25,,2809.9999999999454,long,4e557687-e4c4-4f2d-85b6-364f6e5fd752,ad7b6056-101b-49e4-9b9f-dea68880cd52,500.0
2025-08-31 23:05:00+08:00,2025-08-31 23:09:16+08:00,4473.11,4471.27,,-2055.2799999991466,long,41d06c42-ac03-418f-9451-6f5a5fdda71a,5cd65f94-490b-4bb2-bd42-d1a64942d201,1117.0
2025-09-01 09:07:41+08:00,2025-09-01 09:11:05+08:00,4394.0,4383.39,400.0,4243.999999999869,short,092adf53-a461-4de7-8e04-9bfe1de8c387,b3e26049-21f9-495e-9a96-7498f06dcd82,
2025-09-01 09:07:41+08:00,2025-09-01 09:11:05+08:00,4394.0,4383.39,55.0,583.549999999982,short,092adf53-a461-4de7-8e04-9bfe1de8c387,0614bd80-655c-49d4-b895-798f56f54803,
2025-09-01 09:20:32+08:00,2025-09-01 09:25:17+08:00,4399.41,4396.45,,-1343.8400000000165,long,ef1554ec-bb75-4b5d-a3fd-03325d8ce248,11fb1482-9f6a-4b3f-aec4-e0e9f46ec4eb,454.0
2025-09-01 09:31:04+08:00,2025-09-01 09:32:03+08:00,4409.02,4405.26,,-1703.2800000000989,long,8050d64e-1c53-40e1-89e7-68481d09e689,079730bc-d8ce-413a-a77f-a889bed73972,453.0
2025-09-01 09:34:47+08:00,2025-09-01 09:37:04+08:00,4405.92,4417.68,,5327.280000000099,long,4f3b316a-37b6-43b9-a742-28760ce5267b,18f19970-4048-485b-b95a-00b3e804d0d9,453.0
2025-09-01 10:11:29+08:00,2025-09-01 10:16:05+08:00,4400.12,4391.86,400.0,3304.0000000000873,short,9b7a45aa-4ed0-4fa2-9c77-ee71e8319ecf,6adc05fa-6727-4961-8ae9-ef7f248ce06f,
2025-09-01 10:11:30+08:00,2025-09-01 10:16:05+08:00,4400.12,4391.86,54.0,446.0400000000118,short,a2b8e0df-1a70-4cbe-b513-734c169a45e5,6adc05fa-6727-4961-8ae9-ef7f248ce06f,
2025-09-01 10:29:03+08:00,2025-09-01 10:30:26+08:00,4389.33,4386.21,,-2130.9599999999255,long,9295d00e-a050-472f-b008-426e40eb0f71,73e0f83a-583a-4ae6-8dc3-41c2f37bb58e,683.0
2025-09-01 10:35:00+08:00,2025-09-01 10:36:12+08:00,4375.45,4379.38,685.0,-2692.0500000001994,short,8e5b463d-f4fe-47f3-b39b-ec3721c79e7a,2f96c834-2272-491f-8bc1-8cbe6c4ea452,
2025-09-01 11:03:26+08:00,2025-09-01 11:05:42+08:00,4383.62,4391.35,,5287.3200000003235,long,ad2ab2b0-b070-4027-ba77-039ae801c30b,ab66e717-8f29-4ebe-80c7-165f36806e5f,684.0
2025-09-01 11:12:18+08:00,2025-09-01 11:15:56+08:00,4382.88,4374.85,184.0,1477.5199999999531,short,60e70f9e-3ed0-402a-a33e-0d9104ac17b6,2c200cb7-b183-474a-b78f-bba9e592c8c0,
2025-09-01 11:12:18+08:00,2025-09-01 11:15:56+08:00,4382.88,4374.85,500.0,4014.9999999998727,short,4f57713c-6a4c-42d4-aa6b-c03bae934835,2c200cb7-b183-474a-b78f-bba9e592c8c0,
2025-09-01 11:34:38+08:00,2025-09-01 11:41:09+08:00,4370.18,4382.21,,3440.579999999927,long,7716be61-be89-4b30-8939-ff0c2c42b4e2,15dadfe0-75d8-4cc7-838d-931a1d21ccf8,286.0
2025-09-01 11:34:38+08:00,2025-09-01 11:41:09+08:00,4370.18,4382.21,,4811.999999999898,long,7716be61-be89-4b30-8939-ff0c2c42b4e2,9ae0cd54-0bfb-4a24-8c7a-1a247e078eb8,400.0
2025-09-01 11:54:59+08:00,2025-09-01 11:58:53+08:00,4396.0,4403.97,,79.70000000000255,long,b0876036-7e56-46cb-bddd-ccabb6519f7c,600628e2-049f-44c8-a905-46ea1135e601,10.0
2025-09-01 11:54:59+08:00,2025-09-01 11:58:53+08:00,4396.47,4403.97,,1087.5,long,4bc131e8-70e0-4140-a2c8-b054e0507acd,600628e2-049f-44c8-a905-46ea1135e601,145.0
2025-09-01 11:54:59+08:00,2025-09-01 11:58:53+08:00,4396.47,4403.97,,2662.5,long,4bc131e8-70e0-4140-a2c8-b054e0507acd,9d3eca96-2443-4c6e-b40e-1020bde26895,355.0
2025-09-01 11:54:59+08:00,2025-09-01 11:58:53+08:00,4396.47,4403.97,,1290.0,long,86ab0723-57a8-4e31-9000-9b73f49ad308,9d3eca96-2443-4c6e-b40e-1020bde26895,172.0
2025-09-01 12:19:34+08:00,2025-09-01 12:23:09+08:00,4389.68,4388.07,500.0,805.000000000291,short,2aec9027-7a84-45c2-83d3-8c5871d90106,95aa0191-4e59-46b0-b538-e0a3fd31a029,
2025-09-01 12:19:34+08:00,2025-09-01 12:23:09+08:00,4389.68,4388.0,87.0,146.16000000002532,short,2aec9027-7a84-45c2-83d3-8c5871d90106,861ff638-8ec8-4a6a-bafa-74206b093040,
2025-09-01 12:19:34+08:00,2025-09-01 12:23:09+08:00,4389.68,4388.07,52.0,83.72000000003027,short,2aec9027-7a84-45c2-83d3-8c5871d90106,6cff4ab5-d999-4dda-87e2-067c9adbd240,
2025-09-01 12:19:34+08:00,2025-09-01 12:23:09+08:00,4389.68,4388.07,500.0,805.000000000291,short,2aec9027-7a84-45c2-83d3-8c5871d90106,4dc3eeb9-b54d-4820-bc73-2172e8e5fd66,
2025-09-01 12:52:26+08:00,2025-09-01 12:56:26+08:00,4381.97,4385.85,,4427.0800000001245,long,a3ef0945-101d-4f17-9cda-711fe44e2cf1,ab314993-0d4e-4632-8bcd-66aaaef57066,1141.0
2025-09-01 13:11:24+08:00,2025-09-01 13:12:28+08:00,4363.3,4368.36,475.0,-2403.499999999758,short,4d1d7cf6-26fe-44f0-be21-d10a9871ae1a,53f10353-21b1-41c1-8554-18c5bac4991a,
2025-09-01 13:11:24+08:00,2025-09-01 13:12:28+08:00,4363.3,4368.36,400.0,-2023.9999999997963,short,63978423-878f-4bc0-8ac6-7526d1aa3b24,53f10353-21b1-41c1-8554-18c5bac4991a,
2025-09-01 13:11:24+08:00,2025-09-01 13:12:28+08:00,4363.3,4368.36,500.0,-2529.9999999997453,short,9736d4ed-bfd4-4fb4-a2b9-7a335070a480,53f10353-21b1-41c1-8554-18c5bac4991a,
2025-09-01 13:19:17+08:00,2025-09-01 13:20:04+08:00,4357.3,4364.42,1376.0,-9797.11999999985,short,9d7b259b-c1ec-4d54-83c5-e1588347d99f,a63b68c2-d467-4b4b-992a-175e562a59cd,
2025-09-01 13:23:06+08:00,2025-09-01 13:33:39+08:00,4390.89,4384.71,,-1798.3800000000847,long,348b7ba0-df18-4d21-b652-1c54dc5b4635,2a709f71-d330-49c0-9759-3b65a140431c,291.0
2025-09-01 13:23:06+08:00,2025-09-01 13:33:39+08:00,4390.89,4384.71,,-1854.0000000000873,long,c8c60f9e-a45b-4f5a-b000-a1a436757403,2a709f71-d330-49c0-9759-3b65a140431c,300.0
2025-09-01 13:23:06+08:00,2025-09-01 13:33:39+08:00,4390.89,4384.71,,-1854.0000000000873,long,970891fc-d2ec-4c54-a196-7a450a88c968,2a709f71-d330-49c0-9759-3b65a140431c,300.0
2025-09-01 13:23:06+08:00,2025-09-01 13:33:39+08:00,4390.01,4384.71,,-106.00000000000364,long,71cd000e-8c95-4f6f-a32f-1440db6e8c0d,2a709f71-d330-49c0-9759-3b65a140431c,20.0
2025-09-01 13:49:13+08:00,2025-09-01 13:54:15+08:00,4396.35,4396.21,,-40.18000000009397,long,83a1a14a-a4e3-40f1-86bd-915987501b35,4c298f23-9a76-4a0f-8bc1-f8ed23f12ede,287.0
2025-09-01 13:49:13+08:00,2025-09-01 13:54:15+08:00,4396.35,4396.21,,-28.000000000065484,long,83a1a14a-a4e3-40f1-86bd-915987501b35,46728c29-6645-408a-bba2-07f01cd5d06d,200.0
2025-09-01 13:49:13+08:00,2025-09-01 13:54:15+08:00,4396.35,4396.21,,-1.8200000000042564,long,83a1a14a-a4e3-40f1-86bd-915987501b35,c4cb8611-b4dd-41fd-95c2-c9455c1237e6,13.0
2025-09-01 13:49:13+08:00,2025-09-01 13:54:15+08:00,4396.35,4396.21,,-26.180000000061227,long,47230a4e-8ee9-4d68-aa51-01753afc623b,c4cb8611-b4dd-41fd-95c2-c9455c1237e6,187.0
2025-09-01 13:49:13+08:00,2025-09-01 13:54:15+08:00,4396.35,4396.13,,-46.86000000005424,long,47230a4e-8ee9-4d68-aa51-01753afc623b,e06fcad9-5742-4c94-82eb-2f34884e3f4a,213.0
2025-09-01 13:49:14+08:00,2025-09-01 13:54:15+08:00,4396.35,4396.13,,-1.980000000002292,long,1743d43c-c642-434b-940f-b6d33e6718b9,e06fcad9-5742-4c94-82eb-2f34884e3f4a,9.0
2025-09-01 15:34:19+08:00,2025-09-01 15:35:08+08:00,4429.5,4426.01,,-1406.469999999912,long,e9dad14a-702d-4396-a259-38e6c3b62876,76c3e1c9-aeee-41bd-b8d4-37e8948af1c4,403.0
2025-09-01 15:34:19+08:00,2025-09-01 15:35:08+08:00,4429.5,4426.01,,-1744.9999999998909,long,431b7e4b-b81e-4626-a6de-f5acd5a7cf20,76c3e1c9-aeee-41bd-b8d4-37e8948af1c4,500.0
2025-09-01 15:36:02+08:00,2025-09-01 15:36:51+08:00,4424.4,4419.44,,-3868.8000000000284,long,d7ba8670-d0d7-4817-b30f-ed7d2ba4fd3c,74c07207-3acc-4f9c-b98b-ae54e4085d96,780.0
2025-09-01 15:36:02+08:00,2025-09-01 15:36:51+08:00,4424.4,4420.0,,-545.5999999999549,long,d7ba8670-d0d7-4817-b30f-ed7d2ba4fd3c,a4bea0b9-d2b0-42bf-9e3b-371747ea4fa3,124.0
2025-09-01 15:44:38+08:00,2025-09-01 15:47:21+08:00,4420.39,4426.94,,4427.799999999508,long,17564d45-1b57-4822-91dd-7bf3a162e7b1,131e056d-1779-4de8-bb12-1663936c3ffe,676.0
2025-09-01 15:44:38+08:00,2025-09-01 15:47:21+08:00,4420.0,4426.94,,152.6799999999912,long,7e280213-31c8-4848-b164-57ce0f3a30c3,131e056d-1779-4de8-bb12-1663936c3ffe,22.0
2025-09-01 15:44:38+08:00,2025-09-01 15:47:21+08:00,4420.39,4426.94,,1349.2999999998501,long,37898b4e-9a13-4bc0-a9e6-3fa908bd1e80,131e056d-1779-4de8-bb12-1663936c3ffe,206.0
2025-09-01 15:51:28+08:00,2025-09-01 15:54:46+08:00,4434.86,4450.54,,6068.160000000113,long,a62d6355-e666-4b24-a9fe-1a8efd802cd4,c5b380bf-78c7-4dfd-a1b8-f212e0562e5d,387.0
2025-09-01 15:51:28+08:00,2025-09-01 15:54:46+08:00,4434.86,4450.54,,8059.52000000015,long,9383482c-67d4-4a52-9c9a-bf106f8a66ed,c5b380bf-78c7-4dfd-a1b8-f212e0562e5d,514.0
2025-09-01 15:59:35+08:00,2025-09-01 16:02:01+08:00,4454.21,4472.89,,16774.64000000026,long,b4194b4d-5b4a-4387-879f-b208a173d23e,0b3a10ad-d3bc-49e7-bc76-95d3f3f7b012,898.0
2025-09-01 16:05:00+08:00,2025-09-01 16:05:43+08:00,4486.3,4479.29,,-6245.9100000001945,long,62035134-6e2c-4e78-a57e-90883d6fd125,e148f8b3-d2b0-49a8-9702-bf0ef6d70a11,891.0
2025-09-01 16:06:22+08:00,2025-09-01 16:13:08+08:00,4478.53,4480.64,893.0,-1884.2300000005198,short,d901988b-b5b6-4a5e-a03c-83cedbdbbbda,dcc81b54-5253-4a49-a426-f28316341b68,
2025-09-01 16:18:38+08:00,2025-09-01 16:19:03+08:00,4467.53,4470.68,895.0,-2819.2500000004884,short,2a066536-51d7-425d-ae9e-83613597c612,41ad454f-5790-480c-9f16-80b478841763,
2025-09-01 16:20:05+08:00,2025-09-01 16:22:22+08:00,4473.83,4478.12,894.0,-3835.2599999999675,short,93df10c4-453d-405e-aa78-3870c5c5f78f,5aeedf17-a10d-4388-b16e-e18251d6e1e5,
2025-09-01 16:23:14+08:00,2025-09-01 16:27:37+08:00,4475.22,4469.41,893.0,5188.330000000357,short,d9277a5f-844a-4afc-b784-0343d373a87e,7def0a70-6cc3-4880-9da3-16671ec6a296,
2025-09-01 16:33:42+08:00,2025-09-01 16:41:25+08:00,4470.45,4469.46,894.0,885.0599999998049,short,9e7bf3df-d22c-413b-8b29-024b9c830f6b,3e80d0e3-3466-4e63-b75d-c86b67b6eb0b,
2025-09-01 16:55:38+08:00,2025-09-01 17:04:46+08:00,4474.93,4476.7,893.0,-1580.6099999995777,short,aca7bfae-9112-4a7a-8a95-7b7661be7d13,20115f47-253a-435a-9b43-1cfcbdc9c12e,
2025-09-01 17:10:25+08:00,2025-09-01 17:15:02+08:00,4472.69,4480.01,,6544.080000000553,long,44c66b7e-5da3-4773-b5a0-73b1cd1c13b9,d8403012-f909-414d-bb21-a012dc5722c2,894.0
2025-09-01 17:35:29+08:00,2025-09-01 17:38:36+08:00,4473.01,4460.17,300.0,3852.0000000000437,short,67981b9f-af13-4595-9a36-80db526ac0e4,de9b300a-19de-4cc4-b86e-e5d8ade4eb2f,
2025-09-01 17:35:29+08:00,2025-09-01 17:38:36+08:00,4473.01,4460.17,70.0,898.8000000000102,short,67981b9f-af13-4595-9a36-80db526ac0e4,f7f5c314-6e7b-498a-99cf-a2c868021b32,
2025-09-01 17:35:29+08:00,2025-09-01 17:38:36+08:00,4473.01,4460.17,236.0,3030.2400000000343,short,67981b9f-af13-4595-9a36-80db526ac0e4,f34ae213-3bb5-4bc5-96b5-1efb92648427,
2025-09-01 17:35:29+08:00,2025-09-01 17:38:36+08:00,4473.01,4460.17,287.0,3685.0800000000418,short,da23b541-1bde-4417-8875-4a52000d3183,f34ae213-3bb5-4bc5-96b5-1efb92648427,
1 open_time close_time open_price close_price q极 pnl type open_order_id close_order_id qty
2 2025-08-28 09:35:18+08:00 2025-08-28 09:44:18+08:00 4514.69 4507.43 664.0 4820.639999999541 short e1d3a2da-219e-436f-ac9e-a7ea93de15bd abfa0508-9399-4f1b-90c7-7716c3e7f511
3 2025-08-28 10:06:42+08:00 2025-08-28 10:10:07+08:00 4519.88 4515.64 -4689.439999999759 long 594bd10c-2120-4692-a8eb-9f5325e26ef0 bd643cab-14d4-414d-912e-e9257ddb96de 1106.0
4 2025-08-28 10:45:07+08:00 2025-08-28 10:51:41+08:00 4512.13 4516.84 1108.0 -5218.68000000004 short fc0c73ab-9fff-41b5-98c1-ef6f7d300256 206688da-848a-4822-9571-c05302ab7a29
5 2025-08-28 11:07:30+08:00 2025-08-28 11:13:19+08:00 4525.0 4529.25 850.0 long 6197fb5c-6202-422f-9012-5395c5393fb3 59d8859f-2b64-4e8b-aefe-57998b198841 200.0
6 2025-08-28 11:07:30+08:00 2025-08-28 11:13:19+08:00 4525.0 4529.25 425.0 long 794c0925-6e48-4b9a-a162-d31d7a3c42cc 59d8859f-2b64-4e8b-aefe-57998b198841 100.0
7 2025-08-28 11:07:31+08:00 2025-08-28 11:13:19+08:00 4525.0 4529.25 2052.75 long 65f7d764-ad05-40c7-bce1-6b227ad5f5c0 59d8859f-2b64-4e8b-aefe-57998b198841 483.0
8 2025-08-28 11:07:31+08:00 2025-08-28 11:13:19+08:00 4525.0 4529.25 425.0 long 35e1c160-4129-425a-ae46-b8fb45d53ec8 59d8859f-2b64-4e8b-aefe-57998b198841 100.0
9 2025-08-28 11:28:58+08:00 2025-08-28 11:34:21+08:00 4533.74 4537.34 1440.0000000001455 long a983b8f5-70d1-441b-87df-397c6c1ce843 3e161e4e-f367-421a-bc0d-8095f7b79675 400.0
10 2025-08-28 11:28:58+08:00 2025-08-28 11:34:21+08:00 4533.74 4537.34 1735.2000000001754 long a983b8f5-70d1-441b-87df-397c6c1ce843 45ddb145-d637-4985-9c4b-3dee2fd189b5 482.0
11 2025-08-28 12:22:53+08:00 2025-08-28 12:23:33+08:00 4550.8 4545.04 -2753.2800000001043 long 37d97b24-c1fd-4a2d-ba0e-75b818062686 fcfe39c7-0bcf-47f6-9b48-a1dd70bd5444 478.0
12 2025-08-28 12:22:53+08:00 2025-08-28 12:23:33+08:00 4550.8 4545.04 -2304.0000000000873 long 37d97b24-c1fd-4a2d-ba0e-75b818062686 867b1b2c-0fe5-466b-a89f-ec8dce25bcda 400.0
13 2025-08-28 12:26:39+08:00 2025-08-28 12:34:19+08:00 4549.6 4555.44 5133.3599999993285 long 0a3a08a1-61c7-4997-b13c-4da05b2c5dbc ad149e7f-7088-4dd9-9698-9b7bd615478e 879.0
14 2025-08-28 12:46:19+08:00 2025-08-28 12:48:10+08:00 4561.8 4567.53 600.0 -3437.999999999738 short 18929fa1-2cc7-4e7f-8e76-c3937f16f877 8283a8b1-17f1-4818-843d-33877996af35
15 2025-08-28 12:46:19+08:00 2025-08-28 12:48:10+08:00 4561.8 4567.53 276.0 -1581.4799999998795 short 18929fa1-2cc7-4e7f-8e76-c3937f16f877 c0a1d021-0708-476e-a766-722bc73ab740
16 2025-08-28 12:53:40+08:00 2025-08-28 12:57:03+08:00 4577.05 4569.51 873.0 6582.419999999968 short 16f8970d-ef44-4026-ba19-9c9ff6dc70e1 e1f9de7d-115e-4289-8acd-bbba16e04ff0
17 2025-08-28 12:58:03+08:00 2025-08-28 13:01:30+08:00 4567.45 4572.58 475.0 -2436.750000000052 short 8dbfcfc8-466c-4111-acdf-316a2a8c7428 3e0a22b4-7707-4332-b80d-87d3b07cf3cc
18 2025-08-28 12:58:03+08:00 2025-08-28 13:01:30+08:00 4567.45 4572.58 400.0 -2052.0000000000437 short 8dbfcfc8-466c-4111-acdf-316a2a8c7428 29775823-c3fc-4dbc-8afa-f9587f803f2a
19 2025-08-28 13:32:49+08:00 2025-08-28 13:41:18+08:00 4564.18 4565.88 1225.6999999998689 long 6c0a64d8-b890-42bc-ae09-152919931d57 5bba77bd-b49f-4c6d-9a12-fe062c687cae 721.0
20 2025-08-28 13:32:49+08:00 2025-08-28 13:41:18+08:00 4564.18 4565.88 263.4999999999718 long c0e17c5e-6a39-465c-a3b3-347f1af3d772 5bba77bd-b49f-4c6d-9a12-fe062c687cae 155.0
21 2025-08-28 13:52:44+08:00 2025-08-28 13:57:25+08:00 4555.2 4559.95 400.0 -1900.0 short 8f641745-890a-4b9c-8d83-10163234429d dd5f8c6a-74da-4984-aa24-eebfbceb6d22
22 2025-08-28 13:52:44+08:00 2025-08-28 13:57:25+08:00 4555.2 4559.95 478.0 -2270.5 short 66c5bcfb-02ef-4a8c-a314-bd9d672decb5 dd5f8c6a-74da-4984-aa24-eebfbceb6d22
23 2025-08-28 14:40:01+08:00 2025-08-28 14:41:47+08:00 4572.59 4578.98 874.0 -5584.859999999491 short 1b1efa90-7dd5-4b5f-a170-eb87df7fb7db 26b0c5e5-f4a4-4f47-9fdc-12c6ecd05704
24 2025-08-28 15:05:18+08:00 2025-08-28 15:07:11+08:00 4582.63 4577.98 -279.00000000003274 long 61f7b24d-18b1-44ee-bc9e-60666e4b2346 e53afe94-f3fa-42c1-9e49-619cd77261ab 60.0
25 2025-08-28 15:05:18+08:00 2025-08-28 15:07:11+08:00 4582.63 4578.03 -2760.0000000002183 long 61f7b24d-18b1-44ee-bc9e-60666e4b2346 b9cf7c9c-d909-4dad-ae66-64aa0706566f 600.0
26 2025-08-28 15:05:18+08:00 2025-08-28 15:07:11+08:00 4582.63 4577.52 -1083.3199999999306 long 61f7b24d-18b1-44ee-bc9e-60666e4b2346 05d46d57-d923-4d18-8c18-5a49927ac910 212.0
27 2025-08-28 15:22:41+08:00 2025-08-28 15:23:11+08:00 4572.88 4567.91 -2982.000000000153 long 184c5b21-ed98-43c2-8003-8cc5f8c1bb0a 10d151ec-2891-44fe-8527-89643b3f3b46 600.0
28 2025-08-28 15:22:41+08:00 2025-08-28 15:23:11+08:00 4572.88 4567.53 -1465.9000000000997 long 184c5b21-ed98-43c2-8003-8cc5f8c1bb0a 2a5ef255-f800-4e98-a10c-ca3ed33bb372 274.0
29 2025-08-28 15:57:55+08:00 2025-08-28 16:02:09+08:00 4589.48 4607.47 9840.530000000377 long 6fdd3eb9-13a9-4e2a-90b6-78e7d71f3fbc 81bc2d5e-8099-4d48-b968-d695a7f1fee4 547.0
30 2025-08-28 15:57:55+08:00 2025-08-28 16:02:09+08:00 4589.48 4607.47 5828.760000000224 long aec18848-d3b5-4786-8c51-a4fdfc454ee2 81bc2d5e-8099-4d48-b968-d695a7f1fee4 324.0
31 2025-08-28 16:05:54+08:00 2025-08-28 16:09:19+08:00 4614.86 4624.89 8685.980000000567 long 8e6d3e81-c813-4759-b608-9ed4e547b24d 25509f73-848d-4620-b662-f7f93d76becc 866.0
32 2025-08-28 16:09:50+08:00 2025-08-28 16:15:00+08:00 4621.56 4617.66 -3373.500000000472 long 29739f4f-b289-4a1e-a5e7-f6925dd72b4c 7e4c74ac-902f-47c5-9e0a-b2ef07f31e8e 865.0
33 2025-08-28 16:23:59+08:00 2025-08-28 16:28:31+08:00 4609.17 4602.01 867.0 6207.719999999874 short 6e8dc270-512a-4826-84c9-cfdf82c6cd59 0df8cd52-9db6-4532-99e1-923fcd9c134d
34 2025-08-28 16:54:47+08:00 2025-08-28 16:58:41+08:00 4595.28 4599.69 870.0 -3836.6999999998734 short 35598fc3-567f-4ee2-a9fe-db14aab8228b 9777e233-baa8-4238-8f48-ef3e303ff883
35 2025-08-28 17:06:53+08:00 2025-08-28 17:15:11+08:00 4595.19 4592.66 870.0 2201.0999999997784 short 3432672f-ced3-401f-981d-7686ddd396e6 bf9ffdef-56bd-4d35-9eef-f92a668d5829
36 2025-08-28 17:43:59+08:00 2025-08-28 17:49:12+08:00 4584.79 4581.95 258.0 732.7200000000375 short c0b26494-b8c4-434e-bc49-e3b317c1fa88 ffbc0ba2-aa7f-4377-bade-cf31e3697b19
37 2025-08-28 17:43:59+08:00 2025-08-28 17:49:12+08:00 4584.79 4581.95 114.0 323.7600000000166 short 6fdb9fc7-e0f4-4033-896b-a13160b4fd18 ffbc0ba2-aa7f-4377-bade-cf31e3697b19
38 2025-08-28 17:43:59+08:00 2025-08-28 17:49:12+08:00 4584.79 4581.95 500.0 1420.0000000000728 short b064c485-653b-4f88-a0d1-86961284dc70 ffbc0ba2-aa7f-4377-bade-cf31e3697b19
39 2025-08-28 17:49:44+08:00 2025-08-28 17:50:54+08:00 4579.81 4584.85 500.0 -2519.999999999982 short 1f97429c-1de1-467a-8985-8f9bb17000b5 cf389028-3cfb-4521-bf8c-59c3d9782e85
40 2025-08-28 17:49:44+08:00 2025-08-28 17:50:54+08:00 4579.81 4584.85 139.0 -700.559999999995 short 989c44a3-a81f-4939-ab13-d9884d845a65 cf389028-3cfb-4521-bf8c-59c3d9782e85
41 2025-08-28 17:49:44+08:00 2025-08-28 17:50:54+08:00 4579.58 4584.85 234.0 -1233.1800000001022 short 0b83f7ef-0985-4168-a211-d009f6c6ff1a cf389028-3cfb-4521-bf8c-59c3d9782e85
42 2025-08-28 18:36:51+08:00 2025-08-28 18:43:09+08:00 4609.97 4604.0 -3182.0100000001357 long b8391ca4-74b4-41bc-85cd-b4c82cf6e8f3 2926d3da-8a19-4fae-938f-e2556e994376 533.0
43 2025-08-28 18:36:51+08:00 2025-08-28 18:43:09+08:00 4610.0 4604.0 -504.0 long e441f55d-693a-4301-b6c9-10d54ab10357 2926d3da-8a19-4fae-938f-e2556e994376 84.0
44 2025-08-28 18:36:51+08:00 2025-08-28 18:43:09+08:00 4609.97 4604.0 -197.0100000000084 long 9dbce008-1d12-422c-80f8-a2c928610074 2926d3da-8a19-4fae-938f-e2556e994376 33.0
45 2025-08-28 19:46:14+08:00 2025-08-28 19:54:40+08:00 4586.91 4591.36 654.0 -2910.299999999881 short 005b10f4-329d-4d34-8263-b8f63f526ac8 ea07e34c-cd41-4c80-b13f-6b8308257b92
46 2025-08-28 20:30:04+08:00 2025-08-28 20:30:34+08:00 4587.25 4588.6 697.9500000001881 long 26fe1b1b-f4f0-4c49-b6d0-f8445d4e996e 9011ad7e-ef83-4c62-ac90-3e538965ad3f 517.0
47 2025-08-28 20:30:05+08:00 2025-08-28 20:30:34+08:00 4587.44 4588.6 410.64000000027045 long 32f1db9d-6a9b-413f-abba-3f698a83ec65 9011ad7e-ef83-4c62-ac90-3e538965ad3f 354.0
48 2025-08-28 20:31:22+08:00 2025-08-28 20:31:28+08:00 4583.96 4585.9 400.0 -775.9999999998399 short dd7d8a55-c4bf-4ff8-82b9-ec8591888b0d ca1e611c-1ba6-4418-9f86-8e492a7726c5
49 2025-08-28 20:31:22+08:00 2025-08-28 20:31:29+08:00 4583.96 4585.9 472.0 -915.6799999998111 short dd7d8a55-c4bf-4ff8-82b9-ec8591888b0d 04792496-7da0-4a9b-95cf-293b41d8292a
50 2025-08-28 20:43:41+08:00 2025-08-28 20:46:26+08:00 4609.77 4603.6 -567.6400000000067 long da034c24-f333-4197-ae9d-7dfa8639be45 9d59670d-a478-4432-8ec0-e3a8c4ec4d8a 92.0
51 2025-08-28 20:43:41+08:00 2025-08-28 20:46:26+08:00 4609.77 4603.6 -3702.0000000000437 long da034c24-f333-4197-ae9d-7dfa8639be45 e83ff9d3-3078-4f5c-8e6a-fa5750c97b55 600.0
52 2025-08-28 20:43:41+08:00 2025-08-28 20:46:27+08:00 4609.77 4604.08 -995.7500000000891 long da034c24-f333-4197-ae9d-7dfa8639be45 433dc03b-8b85-4951-9f21-dfaa5d6a0de5 175.0
53 2025-08-29 09:45:36+08:00 2025-08-29 09:49:22+08:00 4466.85 4458.15 447.0 3888.9000000003252 short 87d823b2-675d-4501-bb36-b40eef344b7c 28bb7706-f2ce-480e-b606-fc5073ce4153
54 2025-08-29 10:13:26+08:00 2025-08-29 10:18:05+08:00 4470.7 4473.08 4.760000000000218 long 6d7fe294-0553-46ac-9179-e22446e727dc b50fd6a4-865b-4cd4-8b83-015dde307912 2.0
55 2025-08-29 10:13:27+08:00 2025-08-29 10:18:05+08:00 4470.71 4473.08 1054.6499999999514 long 3d441a61-f852-4d4d-88d9-a2c4494e3a5f b50fd6a4-865b-4cd4-8b83-015dde307912 445.0
56 2025-08-29 10:21:04+08:00 2025-08-29 10:25:10+08:00 4479.68 4483.07 1511.9399999997404 long 9ac71ec9-58a8-43af-83ca-cac772d44dce 7db1d0e0-cdda-45a4-af09-9ec2f6a830a5 446.0
57 2025-08-29 11:08:08+08:00 2025-08-29 11:10:24+08:00 4477.82 4481.35 1574.380000000292 long 4c447405-283c-40f7-bc05-42ae2aeaaaeb de3c12d5-ba88-4b3d-8e8a-2158228465cb 446.0
58 2025-08-29 11:25:26+08:00 2025-08-29 11:31:14+08:00 4478.16 4482.39 1886.580000000211 long 877eb021-8a47-4d55-8efd-789fde87699c 33addd17-0151-418d-b11e-d68a26c179e6 446.0
59 2025-08-29 11:35:59+08:00 2025-08-29 11:43:49+08:00 4484.05 4494.74 4767.7399999998215 long 913408fa-2541-48c8-a8a0-d352b8b74a93 a7fd376e-dd1c-4350-8c58-1913d130902c 446.0
60 2025-08-29 11:55:41+08:00 2025-08-29 12:00:52+08:00 4498.11 4489.03 444.0 4031.5199999999677 short 6450e48b-f901-4907-b065-18e073f86534 7cfe2e33-9b17-4785-9e45-dd5654c483c2
61 2025-08-29 12:54:59+08:00 2025-08-29 12:58:10+08:00 4477.15 4471.43 670.0 3832.3999999995613 short 13bb04ff-529a-48f4-a062-bdbda01abe9a 01a6ebd4-6c63-4e58-9f52-4317a83a6c27
62 2025-08-29 13:05:31+08:00 2025-08-29 13:06:05+08:00 4466.57 4472.34 671.0 -3871.670000000293 short 5c439227-9432-48c1-8c70-184e65586599 398e954e-0534-4f4c-bdda-5d14d858afae
63 2025-08-29 13:17:39+08:00 2025-08-29 13:19:35+08:00 4461.42 4468.3 448.0 -3082.240000000049 short d770f2c0-6aed-4bc2-bee2-f98209775454 14ce65ce-8af2-4c07-8441-bdeea724197e
64 2025-08-29 13:59:25+08:00 2025-08-29 14:01:39+08:00 4476.01 4484.33 382.7199999999866 long 1f80cf00-8910-42af-a7ac-dd2199579d04 96e160f6-0a35-4ac4-9f3e-295065a56092 46.0
65 2025-08-29 13:59:25+08:00 2025-08-29 14:01:39+08:00 4476.01 4484.33 3327.9999999998836 long 1f80cf00-8910-42af-a7ac-dd2199579d04 db2ea541-8ece-4876-baa0-f803629d4675 400.0
66 2025-08-29 14:15:38+08:00 2025-08-29 14:18:12+08:00 4457.41 4451.26 448.0 2755.199999999837 short 2616d754-2ae8-43c0-a382-46901e0dba21 913e0886-23e4-467d-932d-79e960df2947
67 2025-08-29 14:37:31+08:00 2025-08-29 14:39:31+08:00 4451.44 4451.34 -44.89999999975498 long 9f225f1e-cdc5-42cc-8c22-6d39f68da6d6 db5c616d-faf7-4183-8e46-b95f09dbad99 449.0
68 2025-08-29 14:41:21+08:00 2025-08-29 14:44:17+08:00 4451.53 4455.7 1872.3300000000327 long 5ba24885-5747-405a-8fa9-6a9749dbe6b4 f7e02df2-857b-4e3a-a6aa-c0d7362cb5bb 449.0
69 2025-08-29 15:01:14+08:00 2025-08-29 15:02:16+08:00 4448.83 4428.34 449.0 9200.009999999902 short a605bd22-e12e-44a4-9e1c-87c145bc5aa4 365ff72f-891a-4314-a005-d320d2074d5f
70 2025-08-29 15:12:00+08:00 2025-08-29 15:15:04+08:00 4412.37 4393.89 453.0 8371.439999999802 short 03169227-80cc-4c41-89e5-7cbc59174c90 7939f969-7566-453d-a718-dfa6b96ee987
71 2025-08-29 15:44:10+08:00 2025-08-29 15:51:01+08:00 4387.22 4391.19 683.0 -2711.5099999995527 short e2151c19-3f56-4239-8368-77af88a0c2c1 f90b5024-cd5b-44d5-a140-4d6253d49d6a
72 2025-08-29 15:57:12+08:00 2025-08-29 16:00:46+08:00 4383.78 4387.09 400.0 -1324.00000000016 short f2affaff-2beb-481f-b346-c9453422f536 70cc7f5d-b472-40a1-b00b-7e4b032722fc
73 2025-08-29 15:57:12+08:00 2025-08-29 16:00:46+08:00 4383.78 4387.09 284.0 -940.0400000001137 short f2affaff-2beb-481f-b346-c9453422f536 676c76cd-7afa-40db-a0a7-89004bb9387b
74 2025-08-29 16:08:15+08:00 2025-08-29 16:11:24+08:00 4386.41 4376.76 383.0 3695.9499999998607 short da4365c6-5bed-4bff-824c-580b3be527bc 0fdf84b4-d9bd-419e-8fd0-037e8631eefd
75 2025-08-29 16:08:15+08:00 2025-08-29 16:11:24+08:00 4386.5 4376.76 300.0 2921.9999999999345 short 940d2d22-8103-4bdd-8eaa-ade1277111da 0fdf84b4-d9bd-419e-8fd0-037e8631eefd
76 2025-08-29 16:17:21+08:00 2025-08-29 16:17:29+08:00 4364.59 4365.41 187.0 -153.33999999994558 short 89b93201-dfd2-408c-a5de-b6ecd72424cd db922d70-7a90-4cf4-9a17-a598fe213f8b
77 2025-08-29 16:17:21+08:00 2025-08-29 16:17:29+08:00 4364.59 4365.41 400.0 -327.9999999998836 short 89b93201-dfd2-408c-a5de-b6ecd72424cd 574a0e60-b26e-46bf-a696-cae5868b7af2
78 2025-08-29 16:17:21+08:00 2025-08-29 16:17:29+08:00 4365.0 4365.41 100.0 -40.99999999998545 short e6be51d9-e746-45dd-8522-877cf7eafd33 574a0e60-b26e-46bf-a696-cae5868b7af2
79 2025-08-29 16:20:18+08:00 2025-08-29 16:20:36+08:00 4359.92 4362.29 688.0 -1630.559999999925 short d302895c-7318-4851-838d-396e7100fc09 719a6eff-a759-4947-8f0a-45f2ac94dfc4
80 2025-08-29 16:29:12+08:00 2025-08-29 16:33:21+08:00 4355.55 4362.63 3731.1599999999617 long f587dcce-e557-4b34-a55f-bf449234faca e833feb6-8ba7-4fa5-adea-678f690e16b3 527.0
81 2025-08-29 16:29:12+08:00 2025-08-29 16:33:21+08:00 4355.55 4362.63 1139.8799999999883 long 22c48502-01b1-4efd-9809-3bc8487b0a9b e833feb6-8ba7-4fa5-adea-678f690e16b3 161.0
82 2025-08-29 16:37:39+08:00 2025-08-29 16:40:08+08:00 4356.21 4352.88 688.0 2291.03999999995 short b209c4ae-8c33-4ba5-ad48-7559d1eafc6a f7b8931f-1568-4387-a132-8ac6f7f34891
83 2025-08-29 16:40:40+08:00 2025-08-29 16:41:12+08:00 4348.53 4353.19 140.0 -652.3999999999796 short 9f88809c-8f0c-4dd4-b83c-552c6b78da3a b2c3aa90-dcc1-469d-bf31-6c74b8e4099b
84 2025-08-29 16:40:40+08:00 2025-08-29 16:41:12+08:00 4348.53 4353.19 549.0 -2558.33999999992 short 3efb68fb-7389-44fd-b48a-d749af57e70f b2c3aa90-dcc1-469d-bf31-6c74b8e4099b
85 2025-08-29 18:24:56+08:00 2025-08-29 18:28:40+08:00 4354.11 4357.4 1644.9999999999818 long 5b3555c7-8c22-45ad-a4b5-ef6b586335d5 88db631a-7f3b-4b85-9887-94f906259583 500.0
86 2025-08-29 18:24:56+08:00 2025-08-29 18:28:40+08:00 4354.11 4357.4 621.8099999999931 long f6c1a4f1-6aa0-4645-b991-503a320913be 6132d1a3-6d55-4517-b5ba-115198948b85 189.0
87 2025-08-29 18:30:45+08:00 2025-08-29 18:49:35+08:00 4351.51 4343.72 189.0 1472.3099999999931 short b67b7a3a-cf62-4731-bc9c-1d333f42e639 2d4f2adb-d806-4f37-8ff1-a46eddccc6b1
88 2025-08-29 18:30:45+08:00 2025-08-29 18:49:35+08:00 4351.51 4343.72 500.0 3894.999999999982 short 0acabab2-2ab4-4921-82a0-df806d4eb40d 2d4f2adb-d806-4f37-8ff1-a46eddccc6b1
89 2025-08-29 18:58:56+08:00 2025-08-29 19:02:25+08:00 4345.89 4340.99 -3381.0000000003765 long b525febe-c7eb-4db9-a4f8-4a09406c9f7d 51ddc961-238a-4c9d-b985-e6ad6ef2aac7 690.0
90 2025-08-29 19:14:13+08:00 2025-08-29 19:18:33+08:00 4351.49 4346.64 -3341.649999999624 long da8dccbd-f79c-476b-9471-d28b719da66f cfbfe97f-e085-41db-8679-58574bd165fd 689.0
91 2025-08-29 19:49:41+08:00 2025-08-29 19:51:55+08:00 4345.68 4340.66 -3463.800000000301 long 98c03fb1-dca8-43ef-9ca7-0fe6d842946b e0c7b8be-c842-412e-bb4f-e43b51fa53bb 690.0
92 2025-08-29 20:22:08+08:00 2025-08-29 20:30:35+08:00 4365.85 4411.23 31176.059999999452 long 7ab49fe4-9bd7-4368-bb45-ffe9970e4999 c3d6e447-288e-48d1-8977-ccceda6a2e41 687.0
93 2025-08-29 20:31:05+08:00 2025-08-29 20:31:21+08:00 4439.0 4448.35 149.60000000000582 long 76a58764-fd12-4fb4-8ee9-407aa2213a12 e3f58dbc-6a93-4c16-9dc3-7e351493f00f 16.0
94 2025-08-29 20:31:05+08:00 2025-08-29 20:31:21+08:00 4439.0 4448.35 6161.65000000024 long cdd4a741-4195-4fac-9896-35ee5c09a7b9 e3f58dbc-6a93-4c16-9dc3-7e351493f00f 659.0
95 2025-08-29 20:31:46+08:00 2025-08-29 20:33:05+08:00 4409.9 4406.3 -647.9999999999018 long a47f68a7-9565-4ea7-b3ab-770d376ffcea 46e071a8-871b-4373-92a5-8cd6cd46cc56 180.0
96 2025-08-29 20:31:46+08:00 2025-08-29 20:33:05+08:00 4409.9 4406.3 -1799.9999999997272 long a47f68a7-9565-4ea7-b3ab-770d376ffcea c67209e2-0598-443d-85fa-752bdae6059b 500.0
97 2025-08-29 20:43:25+08:00 2025-08-29 20:44:07+08:00 4382.62 4386.13 684.0 -2400.8400000001493 short af3305f0-ec39-48fe-bf71-ac9acb281b25 7556c209-5046-4e8b-8682-99dc36803a62
98 2025-08-29 20:45:44+08:00 2025-08-29 20:49:11+08:00 4389.13 4407.06 1828.8600000000297 long a19435e4-fbf9-4217-bc5d-d7fc07d9818f cc0577e9-e4b6-45fd-bf5a-47ccf6aec320 102.0
99 2025-08-29 20:45:44+08:00 2025-08-29 20:49:11+08:00 4389.13 4407.06 10417.33000000017 long a19435e4-fbf9-4217-bc5d-d7fc07d9818f 4fa96e6c-6692-426b-beca-c138c8505a82 581.0
100 2025-08-29 20:49:46+08:00 2025-08-29 20:53:14+08:00 4406.49 4406.02 500.0 234.99999999967258 short d11f3a55-a1d8-41ff-a979-778c232459c9 b2de5ff9-9281-4c2e-86bd-a071a5e1e864
101 2025-08-29 20:49:46+08:00 2025-08-29 20:53:14+08:00 4406.49 4406.02 180.0 84.59999999988213 short d11f3a55-a1d8-41ff-a979-778c232459c9 a4e3c4e5-4280-417c-8018-8386a63c318a
102 2025-08-29 21:00:24+08:00 2025-08-29 21:00:33+08:00 4408.35 4405.11 -2203.20000000047 long 26e94954-9b31-48a9-9b2b-cb08da0f8e3e 14772435-8e33-4ee5-a87c-81342a7f8449 680.0
103 2025-08-29 21:01:47+08:00 2025-08-29 21:06:54+08:00 4406.15 4391.41 39.0 574.8599999999915 short 8665f24a-3e13-4d3f-ad28-a702c79c73ed 7addab21-fcf3-4921-97ab-d77462067550
104 2025-08-29 21:01:47+08:00 2025-08-29 21:06:54+08:00 4406.15 4391.41 141.0 2078.339999999969 short 0170663d-0cf1-43a4-8595-4511c59b3107 7addab21-fcf3-4921-97ab-d77462067550
105 2025-08-29 21:01:47+08:00 2025-08-29 21:06:54+08:00 4406.15 4391.41 500.0 7369.999999999891 short 0170663d-0cf1-43a4-8595-4511c59b3107 3b754022-7c7c-4b14-8251-c2da4478df27
106 2025-08-29 21:10:41+08:00 2025-08-29 21:11:27+08:00 4400.55 4392.88 -107.38000000000102 long 37e79409-f3ed-4e62-811c-6cc437396a41 f3a43d61-4d64-4d82-aada-31b38d441baa 14.0
107 2025-08-29 21:10:41+08:00 2025-08-29 21:11:27+08:00 4400.55 4392.79 -519.9200000000146 long 37e79409-f3ed-4e62-811c-6cc437396a41 86bfa728-af41-4e41-9e87-d6ef88b1a063 67.0
108 2025-08-29 21:10:41+08:00 2025-08-29 21:11:27+08:00 4400.55 4392.88 -4602.000000000044 long 37e79409-f3ed-4e62-811c-6cc437396a41 af01f0d0-8844-4267-8476-4000d0b2dd8b 600.0
109 2025-08-29 21:30:11+08:00 2025-08-29 21:34:27+08:00 4386.05 4373.6 72.0 896.3999999999869 short fecb81e1-3b36-4ae6-91ad-b6a2616ee608 aee7c322-ba5d-4b89-8b93-1c50ce5be75b
110 2025-08-29 21:30:11+08:00 2025-08-29 21:34:27+08:00 4386.05 4372.44 211.0 2871.710000000123 short fecb81e1-3b36-4ae6-91ad-b6a2616ee608 e20951ed-ff4e-4a06-8bb5-8112a72e38bf
111 2025-08-29 21:30:11+08:00 2025-08-29 21:34:27+08:00 4386.05 4372.44 99.0 1347.3900000000576 short fecb81e1-3b36-4ae6-91ad-b6a2616ee608 16329965-69b4-42a4-8145-79d1a0d2e92b
112 2025-08-29 21:30:11+08:00 2025-08-29 21:34:27+08:00 4386.29 4372.44 101.0 1398.8500000000367 short f1e4b54c-d392-4dc4-8f73-40a8733b85fe 16329965-69b4-42a4-8145-79d1a0d2e92b
113 2025-08-29 21:30:11+08:00 2025-08-29 21:34:27+08:00 4386.29 4372.44 200.0 2770.0000000000728 short f1e4b54c-d392-4dc4-8f73-40a8733b85fe 1b66a876-041a-480e-a9d6-428a3e301ec4
114 2025-08-30 08:15:30+08:00 2025-08-30 08:25:24+08:00 4343.62 4355.47 4740.0000000001455 long fb636839-9fb2-4e2f-bdb0-14bd57ade58a 6b8d4b73-132c-4c86-92f9-2a5df18943fd 400.0
115 2025-08-30 08:15:30+08:00 2025-08-30 08:25:24+08:00 4343.62 4355.47 3436.5000000001055 long fb636839-9fb2-4e2f-bdb0-14bd57ade58a a744bd39-3c81-4cb1-a153-60ed71d6748f 290.0
116 2025-08-30 08:32:12+08:00 2025-08-30 08:35:26+08:00 4342.48 4337.98 -288.0 long e6185c1c-debd-4a9c-928c-edd28b360578 401ccb35-f82c-4df2-9a29-f9cd57481767 64.0
117 2025-08-30 08:32:12+08:00 2025-08-30 08:35:26+08:00 4342.48 4335.64 -3850.91999999957 long e6185c1c-debd-4a9c-928c-edd28b360578 69d6c400-d534-47b6-b2a8-8da09b2986aa 563.0
118 2025-08-30 08:32:12+08:00 2025-08-30 08:35:26+08:00 4342.48 4335.73 -425.25 long e6185c1c-debd-4a9c-928c-edd28b360578 4aa4a001-f8b0-4aea-93c3-546c71b81ee0 63.0
119 2025-08-30 08:37:25+08:00 2025-08-30 08:41:59+08:00 4336.85 4332.05 691.0 3316.8000000001257 short 5cc6dd95-ec96-4864-a085-95b875673f0f 07f9b455-a026-41df-95c6-f9cf37f23a90
120 2025-08-30 09:26:28+08:00 2025-08-30 09:29:48+08:00 4326.54 4324.64 293.0 556.6999999998934 short ce7db548-7de1-448e-92c9-25139a5f23a4 70062cb1-9074-49a9-8e7f-b5b7bae639d4
121 2025-08-30 09:26:28+08:00 2025-08-30 09:29:48+08:00 4326.54 4323.46 400.0 1231.999999999971 short ce7db548-7de1-448e-92c9-25139a5f23a4 6145a0a3-248c-4822-8e8c-5efb6daf7d24
122 2025-08-30 09:51:41+08:00 2025-08-30 09:55:09+08:00 4312.57 4289.19 177.0 4138.260000000019 short 4b786a41-410d-4c93-b1c6-30b118f9e7f2 f78be76a-092e-4e0e-b8c3-26867d78c1de
123 2025-08-30 09:51:41+08:00 2025-08-30 09:55:09+08:00 4312.57 4289.19 518.0 12110.840000000057 short 96fbc46a-1dd3-4fc6-9e14-4a032e9464bf f78be76a-092e-4e0e-b8c3-26867d78c1de
124 2025-08-30 09:55:49+08:00 2025-08-30 09:55:50+08:00 4282.58 4282.19 -273.0000000002292 long 201dbee0-8f0d-427d-95d5-ef84e08a8aab 37ff5d0c-e10e-480c-91ca-0506e61330b6 700.0
125 2025-08-30 09:58:19+08:00 2025-08-30 09:58:59+08:00 4281.59 4280.23 -952.0000000004075 long 0e651112-db3b-402d-a268-1ea200cf8729 65b07548-3473-4570-be22-0172c49bdb94 700.0
126 2025-08-30 10:00:09+08:00 2025-08-30 10:00:52+08:00 4264.04 4268.35 703.0 -3029.9300000002813 short d9703fdd-ea02-410d-8303-d1d13b94748f 17fca37e-fc89-48a9-92ed-671ab0b9088e
127 2025-08-30 10:01:23+08:00 2025-08-30 10:02:02+08:00 4268.54 4271.97 110.0 -377.300000000032 short 022ce461-b78f-4127-9157-8c34a5e9272e 89468587-89ce-49cc-a9e3-343e24cb8036
128 2025-08-30 10:01:23+08:00 2025-08-30 10:02:02+08:00 4268.54 4271.97 592.0 -2030.5600000001723 short 9bdcfab5-9b8e-447c-b4ac-a82724e2774d 89468587-89ce-49cc-a9e3-343e24cb8036
129 2025-08-30 10:02:55+08:00 2025-08-30 10:04:26+08:00 4275.14 4280.56 400.0 -2168.000000000029 short 1b938bf4-dc99-4d2f-9e0b-c2fa5092d19d 4e6c40d8-e7c7-45ac-800e-5f71611479f1
130 2025-08-30 10:02:55+08:00 2025-08-30 10:04:26+08:00 4275.14 4280.56 141.0 -764.2200000000103 short 1b938bf4-dc99-4d2f-9e0b-c2fa5092d19d 864390a3-33dd-4a47-a3c2-471b8a0104f1
131 2025-08-30 10:02:55+08:00 2025-08-30 10:04:26+08:00 4275.14 4280.56 160.0 -867.2000000000116 short 7eb3eaf4-30fa-495d-a74c-61d725625c42 864390a3-33dd-4a47-a3c2-471b8a0104f1
132 2025-08-30 10:11:35+08:00 2025-08-30 10:18:43+08:00 4296.88 4306.91 2326.959999999941 long b1a002d6-951f-4912-b8cf-19bfc98f61ba 743a1e0f-48f3-43fe-9b6a-47536fa12ce1 232.0
133 2025-08-30 10:11:35+08:00 2025-08-30 10:18:43+08:00 4296.91 4306.91 4660.0 long 94664c85-6be6-42d8-984a-f3293ed9750f 743a1e0f-48f3-43fe-9b6a-47536fa12ce1 466.0
134 2025-08-30 10:21:54+08:00 2025-08-30 10:27:07+08:00 4307.47 4306.32 696.0 800.4000000003798 short 641e7574-db24-4c78-8782-566b13de1e39 817cbe73-8f5f-4c27-893c-ddfe59e1890d
135 2025-08-30 10:28:32+08:00 2025-08-30 10:35:18+08:00 4305.75 4311.46 2855.000000000018 long dee31b34-3e7f-4b74-8774-ccd70f3cb124 d37eec35-4b90-42c7-82e7-7a56e909d268 500.0
136 2025-08-30 10:28:32+08:00 2025-08-30 10:35:18+08:00 4305.75 4311.25 1078.0 long dee31b34-3e7f-4b74-8774-ccd70f3cb124 9cbf242a-7e93-4a3c-b798-6e3f7a88025d 196.0
137 2025-08-30 10:48:32+08:00 2025-08-30 10:57:53+08:00 4313.05 4303.81 695.0 6421.799999999848 short 0efcab97-a0b6-4cd6-ad7e-22911ea32fa2 57fa177a-12c5-4127-91c4-289668a191ae
138 2025-08-30 11:03:45+08:00 2025-08-30 11:10:25+08:00 4308.11 4322.99 4404.480000000032 long 36e3b573-d4be-4d54-9af3-8190731448c9 1e9213a7-3443-4209-a26a-d3e0feeaf325 296.0
139 2025-08-30 11:03:45+08:00 2025-08-30 11:10:25+08:00 4308.11 4322.99 5952.000000000044 long 36e3b573-d4be-4d54-9af3-8190731448c9 a344d092-7b22-4230-8ba9-0702dd353041 400.0
140 2025-08-30 11:11:04+08:00 2025-08-30 11:17:45+08:00 4323.24 4328.87 3901.5900000000756 long c2e861bb-6de2-4dc0-aed3-7a385c0f34b8 d786c18b-8199-4335-ad6b-6115f39e089f 693.0
141 2025-08-30 11:18:36+08:00 2025-08-30 11:23:02+08:00 4333.76 4358.0 9695.999999999913 long 3c5242f4-5844-46a7-8b84-a6c73fed27c7 d71ce99c-8d8e-4f15-be2e-85d21e853298 400.0
142 2025-08-30 11:18:36+08:00 2025-08-30 11:23:02+08:00 4333.76 4358.0 3248.1599999999708 long 3c5242f4-5844-46a7-8b84-a6c73fed27c7 fe3607bd-9257-42ce-a0b3-06d882cb74af 134.0
143 2025-08-30 11:18:36+08:00 2025-08-30 11:23:02+08:00 4333.76 4358.0 3829.9199999999655 long ce9f82f0-70a9-44b1-9175-4ee31dbc8fd6 fe3607bd-9257-42ce-a0b3-06d882cb74af 158.0
144 2025-08-30 11:52:34+08:00 2025-08-30 11:57:42+08:00 4352.62 4352.32 -20.70000000001255 long a7a38452-b2e4-46c1-a14c-d85c0a79b250 078499df-67ff-4bdd-acaf-4e4fcf4457c0 69.0
145 2025-08-30 11:52:34+08:00 2025-08-30 11:57:42+08:00 4352.62 4352.32 -186.00000000011278 long 76c6328b-ae56-4313-9b73-3bc43f644ef4 078499df-67ff-4bdd-acaf-4e4fcf4457c0 620.0
146 2025-08-30 12:01:25+08:00 2025-08-30 12:07:56+08:00 4351.41 4357.44 500.0 -3014.9999999998727 short 2228c2d3-6d7b-4835-8065-42ce6ad3a5af 3544a077-b511-45ef-b088-c380928048ee
147 2025-08-30 12:01:25+08:00 2025-08-30 12:07:56+08:00 4351.7 4357.44 121.0 -694.5399999999736 short e33d8985-328c-4a44-829e-b8ebf6127582 3544a077-b511-45ef-b088-c380928048ee
148 2025-08-30 12:01:25+08:00 2025-08-30 12:07:56+08:00 4351.41 4357.44 527.0 -3177.809999999866 short 6f169ccd-3d5a-4e35-9653-7efd0a1580dc 3544a077-b511-45ef-b088-c380928048ee
149 2025-08-30 13:01:32+08:00 2025-08-30 13:07:24+08:00 4353.26 4358.47 577.0 -3006.170000000021 short 27412351-b7db-41d2-941e-014723b46c1a f65cc5f5-8a78-4a59-bb58-cf0af4df8448
150 2025-08-30 13:01:33+08:00 2025-08-30 13:07:24+08:00 4353.26 4358.47 298.0 -1552.5800000000108 short cab58243-ce8d-4149-b279-3417eac36fcd f65cc5f5-8a78-4a59-bb58-cf0af4df8448
151 2025-08-30 13:01:33+08:00 2025-08-30 13:07:24+08:00 4353.26 4359.1 273.0 -1594.3200000000397 short cab58243-ce8d-4149-b279-3417eac36fcd c28367f5-fcb9-4345-82f2-c56451e2e462
152 2025-08-30 13:20:13+08:00 2025-08-30 13:32:38+08:00 4373.03 4377.0 1143.0 -4537.710000000291 short 0f73205b-a08a-4fad-9e77-f5d2fbbf1aee 6d5e0a1c-53e6-4fac-a76a-77cb3341a976
153 2025-08-30 13:33:46+08:00 2025-08-30 13:42:14+08:00 4385.31 4391.97 7592.399999999834 long 11f0898c-7cba-49da-91d9-1fc6e9b57ab2 e7744350-f030-4566-bdeb-8a76060f8066 1140.0
154 2025-08-30 13:48:01+08:00 2025-08-30 13:56:36+08:00 4395.74 4382.93 1137.0 14564.96999999942 short d00ac585-7cde-477d-af47-a5889aa5ef70 e99ef7df-85e7-46b4-bc8a-4a6f2fc811fe
155 2025-08-30 13:58:04+08:00 2025-08-30 14:03:08+08:00 4381.43 4385.01 1141.0 -4084.779999999917 short 76216a51-657b-4659-86cb-2295aa642dac 8a9ab27e-38f2-4ec3-bbaf-642afd20a6e5
156 2025-08-30 14:10:44+08:00 2025-08-30 14:15:13+08:00 4383.15 4377.63 601.0 3317.5199999997158 short 587020d7-a3eb-4e44-b6c7-5c95b8c5451a 8ecfa693-c528-405b-8db4-0b02ccc7b9b3
157 2025-08-30 14:10:44+08:00 2025-08-30 14:15:13+08:00 4383.15 4377.63 500.0 2759.9999999997635 short 587020d7-a3eb-4e44-b6c7-5c95b8c5451a babe1585-607c-4004-9aa9-19e1f5374ac1
158 2025-08-30 14:10:44+08:00 2025-08-30 14:15:13+08:00 4383.15 4377.63 39.0 215.27999999998156 short 587020d7-a3eb-4e44-b6c7-5c95b8c5451a ab4e9d81-4133-42b0-9460-9a2efd36ec0b
159 2025-08-30 14:26:36+08:00 2025-08-30 14:33:14+08:00 4384.3 4391.39 8082.600000000166 long f703a5cc-3428-4796-a288-bfa6442800cb a4e60efd-9afc-48b1-8850-6054e1330780 1140.0
160 2025-08-30 14:45:13+08:00 2025-08-30 14:52:41+08:00 4395.22 4390.35 1137.0 5537.189999999876 short b1f16517-7b15-43a4-a3e7-8f0b60f9f732 0445e9e3-c80c-4beb-a121-18b6094f52eb
161 2025-08-30 15:20:15+08:00 2025-08-30 15:40:40+08:00 4392.17 4398.92 52.0 -351.0 short 504ad303-3016-470e-9deb-a717d25a761c 9a648f36-ef00-45a4-8e56-868ab74acce6
162 2025-08-30 15:20:15+08:00 2025-08-30 15:40:40+08:00 4392.17 4398.92 500.0 -3375.0 short 59f674e3-aff1-4b79-b8b0-c650b299d27d 9a648f36-ef00-45a4-8e56-868ab74acce6
163 2025-08-30 15:20:15+08:00 2025-08-30 15:40:40+08:00 4392.17 4398.92 586.0 -3955.5 short 77548f6a-59ae-4ac2-880c-ea1f5679f507 9a648f36-ef00-45a4-8e56-868ab74acce6
164 2025-08-30 15:46:04+08:00 2025-08-30 15:50:09+08:00 4408.51 4402.78 -6497.820000000536 long 76eb4bce-ff36-4d4c-b97a-cda6d9f7b544 63f7184c-7211-417f-b594-e39436d14940 1134.0
165 2025-08-30 16:11:35+08:00 2025-08-30 16:32:13+08:00 4393.35 4389.12 400.0 1692.0000000001892 short be9ff2ce-0d9e-4184-8d43-c49b33c71c95 754db465-b458-43a3-b2b5-3fb4f9fc2aaf
166 2025-08-30 16:11:35+08:00 2025-08-30 16:32:13+08:00 4393.35 4389.12 500.0 2115.0000000002365 short cdf388db-68a2-47ea-ba94-431f02dadeac 754db465-b458-43a3-b2b5-3fb4f9fc2aaf
167 2025-08-30 16:11:35+08:00 2025-08-30 16:32:13+08:00 4393.35 4389.12 237.0 1002.5100000001121 short e6f8d379-c20f-4a9d-90a4-7a5904bff1f9 754db465-b458-43a3-b2b5-3fb4f9fc2aaf
168 2025-08-30 17:05:10+08:00 2025-08-30 17:11:26+08:00 4390.54 4387.01 133.0 469.48999999996613 short d4db2208-ba63-42c7-af51-9cec92bfe6f1 46858333-121c-4020-9567-bc44d63dec01
169 2025-08-30 17:05:10+08:00 2025-08-30 17:11:26+08:00 4390.54 4387.01 190.0 670.6999999999516 short d4db2208-ba63-42c7-af51-9cec92bfe6f1 4d19376a-cfb7-4da9-8859-982e073624d1
170 2025-08-30 17:05:10+08:00 2025-08-30 17:11:26+08:00 4390.54 4387.01 310.0 1094.299999999921 short 00dda8f5-7156-4d25-9ea0-29e5fb2a4aca 4d19376a-cfb7-4da9-8859-982e073624d1
171 2025-08-30 17:05:10+08:00 2025-08-30 17:11:26+08:00 4390.54 4387.01 505.0 1782.6499999998714 short 00dda8f5-7156-4d25-9ea0-29e5fb2a4aca e28b9838-7c48-4c78-a369-8259844cc3f4
172 2025-08-30 17:18:39+08:00 2025-08-30 17:28:37+08:00 4389.73 4385.08 -5296.349999999586 long 2789c169-8a5d-47da-a6f9-6800e72ec26e cd9481fb-33de-4e75-beb8-119ace92b5f6 1139.0
173 2025-08-30 17:31:17+08:00 2025-08-30 17:37:08+08:00 4379.77 4384.13 1141.0 -4974.759999999626 short 434fc13a-925d-4abd-8677-0cd2b1a412f0 1e63ca1f-7f77-4ed9-a885-159f5dac641e
174 2025-08-30 17:44:10+08:00 2025-08-30 17:48:40+08:00 4384.13 4388.17 1140.0 -4605.5999999999585 short 288b4dc7-affd-4b36-897a-e02a024dbae0 70c0e310-219d-45d2-a91d-6b685af4a065
175 2025-08-30 17:50:34+08:00 2025-08-30 17:54:02+08:00 4389.94 4393.0 3482.2800000004554 long b78acf6a-d3b3-44c2-b484-ad95dfedd167 9473c228-7657-44cd-9038-38aeb833c3ab 1138.0
176 2025-08-30 18:05:09+08:00 2025-08-30 18:07:30+08:00 4392.24 4394.52 2594.640000000745 long 44cd4f02-5250-47d0-8e71-a66f856405ba 81abc1fa-1789-4f69-aaaa-2da1f3f34186 1138.0
177 2025-08-31 10:28:55+08:00 2025-08-31 10:34:47+08:00 4450.3 4446.25 -1320.3000000000593 long 0fe00795-d7d9-4586-b864-e445017c7f9d 716e265c-d39a-46b3-92e2-99f5d8a6b45f 326.0
178 2025-08-31 10:28:55+08:00 2025-08-31 10:34:47+08:00 4450.3 4446.25 -2316.600000000104 long 0fe00795-d7d9-4586-b864-e445017c7f9d e7b360d6-da94-4cb7-b8c7-0b10db53a03b 572.0
179 2025-08-31 11:08:10+08:00 2025-08-31 11:12:01+08:00 4454.6 4458.68 897.0 -3659.7599999999347 short c31d66e2-a558-4b86-a520-3a9eb9d55346 f737efdc-5818-4bc5-b3db-1da76e7caf71
180 2025-08-31 11:24:10+08:00 2025-08-31 11:27:33+08:00 4457.8 4453.59 -2138.6800000000185 long 38413547-9d48-43fc-a2be-12d2a8e0cd9f ce5c15c0-d938-4b48-ab08-807531847f2e 508.0
181 2025-08-31 11:24:10+08:00 2025-08-31 11:27:33+08:00 4457.8 4453.59 -1637.6900000000142 long 816792ec-d409-4688-b7fd-2ee3e3f4491e ce5c15c0-d938-4b48-ab08-807531847f2e 389.0
182 2025-08-31 11:49:43+08:00 2025-08-31 11:53:50+08:00 4462.28 4469.74 3730.000000000018 long b1e2c3bf-db41-4762-b152-7a6a469c8cdb 52c185f1-3f74-42b6-afe5-6032df9dcb11 500.0
183 2025-08-31 11:49:43+08:00 2025-08-31 11:53:50+08:00 4462.28 4469.74 2954.1600000000144 long b1e2c3bf-db41-4762-b152-7a6a469c8cdb 5fbbe739-8d3c-4aab-8333-7860bdca1d69 396.0
184 2025-08-31 11:54:26+08:00 2025-08-31 12:00:20+08:00 4475.79 4483.53 2267.819999999936 long 614c6489-c5a5-451d-a2a0-699e38d5a695 5da7f47f-33e3-45b8-9dfe-8232807978fc 293.0
185 2025-08-31 11:54:26+08:00 2025-08-31 12:00:20+08:00 4475.79 4483.53 1547.9999999999563 long c443995b-f986-4a55-b6d9-59c43fa71fd2 5da7f47f-33e3-45b8-9dfe-8232807978fc 200.0
186 2025-08-31 11:54:26+08:00 2025-08-31 12:00:20+08:00 4475.79 4483.53 3095.9999999999127 long c443995b-f986-4a55-b6d9-59c43fa71fd2 7d96c3c9-b227-48f3-b9fe-9a5c08871cfe 400.0
187 2025-08-31 12:15:25+08:00 2025-08-31 12:25:03+08:00 4473.35 4467.05 894.0 5632.200000000163 short d5064049-73a7-4a01-8d14-3d0ba056d572 b4537133-4056-4afc-80c2-7656e28cff88
188 2025-08-31 12:30:21+08:00 2025-08-31 12:33:51+08:00 4461.85 4465.99 500.0 -2069.999999999709 short 516d9754-0fe4-4f2e-9289-5827765f7c67 13f52cac-de10-4bba-93d5-8376ba2c5139
189 2025-08-31 12:30:21+08:00 2025-08-31 12:33:51+08:00 4461.85 4465.88 100.0 -402.99999999997453 short 516d9754-0fe4-4f2e-9289-5827765f7c67 a77196b2-cc47-482b-8fb0-a140d25da936
190 2025-08-31 12:30:21+08:00 2025-08-31 12:33:51+08:00 4461.85 4465.99 296.0 -1225.4399999998277 short 516d9754-0fe4-4f2e-9289-5827765f7c67 c529dbf2-2dd4-46aa-b5b6-dd0ed4f473e2
191 2025-08-31 12:42:50+08:00 2025-08-31 12:48:13+08:00 4464.2 4468.3 661.0 -2710.1000000002405 short 0f3ef65f-e754-4229-87e6-e0f102020ce9 bce7cdc5-2c37-4bda-9b2a-05c865dd69ba
192 2025-08-31 12:42:50+08:00 2025-08-31 12:48:13+08:00 4464.2 4468.3 235.0 -963.5000000000855 short 10e40e0b-a920-4e80-8d17-ea6f73d645e3 bce7cdc5-2c37-4bda-9b2a-05c865dd69ba
193 2025-08-31 13:31:35+08:00 2025-08-31 13:38:28+08:00 4453.99 4450.23 -376.0000000000218 long e65553ad-4738-4b5f-af08-c7373301aef8 ce3b836f-f3c8-4e27-bdd5-33b9e1ba2bc9 100.0
194 2025-08-31 13:31:35+08:00 2025-08-31 13:38:28+08:00 4454.98 4450.23 -2850.0 long 57f64aba-942f-4563-a3c7-9dfdfeaf98e4 ce3b836f-f3c8-4e27-bdd5-33b9e1ba2bc9 600.0
195 2025-08-31 13:31:35+08:00 2025-08-31 13:38:28+08:00 4454.98 4450.23 -940.5 long 597f272b-ce3c-45bf-99ee-4abe2f630972 ce3b836f-f3c8-4e27-bdd5-33b9e1ba2bc9 198.0
196 2025-08-31 14:22:05+08:00 2025-08-31 14:23:54+08:00 4441.46 4446.28 275.0 -1325.49999999992 short eafee2f8-8601-47c7-bfe0-2f0a35bd1411 3744b6fa-5971-44d1-885f-7c7f93da8e70
197 2025-08-31 14:22:05+08:00 2025-08-31 14:23:54+08:00 4442.21 4446.28 100.0 -406.9999999999709 short 702cd777-dc0b-4602-8c19-618520cf46f4 3744b6fa-5971-44d1-885f-7c7f93da8e70
198 2025-08-31 14:22:05+08:00 2025-08-31 14:23:54+08:00 4441.46 4446.28 525.0 -2530.499999999847 short be46bffb-290a-477a-81d9-fd4e7c1d2f3c 3744b6fa-5971-44d1-885f-7c7f93da8e70
199 2025-08-31 14:33:49+08:00 2025-08-31 14:39:00+08:00 4439.81 4444.22 900.0 -3968.999999999869 short f25e9b2a-1bb7-4bc5-852e-5c953f222f61 2d0c6c6c-070a-498b-ade7-0235a6d3e644
200 2025-08-31 14:40:14+08:00 2025-08-31 14:47:51+08:00 4444.0 4439.28 -1939.9200000001047 long 46e5c712-8dff-423d-805d-d09da5e43571 9a2c96f9-3c09-4cca-8539-7251e96e99df 411.0
201 2025-08-31 14:40:14+08:00 2025-08-31 14:47:51+08:00 4444.0 4439.13 -1947.9999999999563 long 46e5c712-8dff-423d-805d-d09da5e43571 f92ff1ec-cfa2-4576-bcbb-978910e5200c 400.0
202 2025-08-31 14:40:14+08:00 2025-08-31 14:47:51+08:00 4444.0 4439.13 -433.4299999999903 long 46e5c712-8dff-423d-805d-d09da5e43571 5f572e4d-e1a7-45cf-bc1b-b55ce56f12b4 89.0
203 2025-08-31 14:51:09+08:00 2025-08-31 14:57:17+08:00 4436.57 4435.16 450.0 634.4999999999345 short 3d5b8a22-edc9-4076-8d61-23f8ed561202 9c959838-3125-426e-abaf-d09fc309fda2
204 2025-08-31 15:30:46+08:00 2025-08-31 15:33:17+08:00 4450.96 4446.74 -1894.7800000001143 long 45ada65c-b8e3-4316-9414-5faf1dcad582 57564f53-121e-47ac-8804-e448bb39c82c 449.0
205 2025-08-31 16:05:31+08:00 2025-08-31 16:08:48+08:00 4461.21 4457.34 -1733.759999999951 long 050937e7-f1e4-459e-982a-8d5263e718cb ad5c9d31-f050-4981-9f51-7852dbf0df37 448.0
206 2025-08-31 16:20:45+08:00 2025-08-31 16:24:22+08:00 4463.0 4462.93 -3.35999999998603 long e41030f3-095f-4e36-b465-e7f7d20b2972 83b7259d-91f7-485a-92ee-37c94790c7f4 48.0
207 2025-08-31 16:20:45+08:00 2025-08-31 16:24:22+08:00 4463.0 4462.93 -27.999999999883585 long e41030f3-095f-4e36-b465-e7f7d20b2972 de316218-6bb2-48c0-b540-fc4babf5ce9b 400.0
208 2025-08-31 17:24:37+08:00 2025-08-31 17:27:28+08:00 4473.73 4467.56 447.0 2757.989999999626 short b8d42b12-b7c8-465d-a67b-56085ceae48f 74ed9f75-4d45-47a8-a636-5a1cbe5511ce
209 2025-08-31 17:48:57+08:00 2025-08-31 17:52:50+08:00 4463.45 4470.31 3073.2800000002608 long 9b9c8688-3c74-48c3-b1bf-6bbc162b3edf 70a47e37-f8fb-440f-9ea6-50ffbf8055f6 448.0
210 2025-08-31 17:59:19+08:00 2025-08-31 18:00:09+08:00 4461.24 4465.19 152.0 -600.3999999999724 short 28a00768-c1e1-42d0-b75e-f7b6b8608b60 9263141f-f5ac-4173-b3c2-b8e2f7ba0985
211 2025-08-31 17:59:19+08:00 2025-08-31 18:00:09+08:00 4461.24 4465.19 520.0 -2053.9999999999054 short 28a00768-c1e1-42d0-b75e-f7b6b8608b60 32d89f55-ae9c-49a6-8e2a-e47b5f4167ab
212 2025-08-31 18:07:59+08:00 2025-08-31 18:12:30+08:00 4459.1 4452.94 672.0 4139.520000000513 short 765d6b9a-0683-4dca-b76c-6e9a2ea65cd5 7f047d14-dac5-4fca-94ed-c0fdfec63578
213 2025-08-31 18:17:18+08:00 2025-08-31 18:29:14+08:00 4451.84 4455.42 2409.339999999951 long 755ad988-d66e-4bc8-9907-b69112e3a11a 775a3323-bbd4-4e5c-ae56-d68e178eb05e 673.0
214 2025-08-31 22:07:31+08:00 2025-08-31 22:13:15+08:00 4453.82 4450.0 1122.0 4286.0399999996735 short c3c54d31-6a99-45ad-8139-546ac61bed34 ef4df9cc-3394-4d53-8fed-7e261a8b0c60
215 2025-08-31 22:14:11+08:00 2025-08-31 22:20:53+08:00 4453.63 4459.25 2809.9999999999454 long 18042f61-552b-41bb-b228-8d8031ee3c14 ad7b6056-101b-49e4-9b9f-dea68880cd52 500.0
216 2025-08-31 22:14:11+08:00 2025-08-31 22:20:53+08:00 4453.63 4459.25 685.6399999999867 long 208d18b8-941b-4ce3-aa29-2f5fb074cc01 ad7b6056-101b-49e4-9b9f-dea68880cd52 122.0
217 2025-08-31 22:14:11+08:00 2025-08-31 22:20:53+08:00 4453.63 4459.25 2809.9999999999454 long 4e557687-e4c4-4f2d-85b6-364f6e5fd752 ad7b6056-101b-49e4-9b9f-dea68880cd52 500.0
218 2025-08-31 23:05:00+08:00 2025-08-31 23:09:16+08:00 4473.11 4471.27 -2055.2799999991466 long 41d06c42-ac03-418f-9451-6f5a5fdda71a 5cd65f94-490b-4bb2-bd42-d1a64942d201 1117.0
219 2025-09-01 09:07:41+08:00 2025-09-01 09:11:05+08:00 4394.0 4383.39 400.0 4243.999999999869 short 092adf53-a461-4de7-8e04-9bfe1de8c387 b3e26049-21f9-495e-9a96-7498f06dcd82
220 2025-09-01 09:07:41+08:00 2025-09-01 09:11:05+08:00 4394.0 4383.39 55.0 583.549999999982 short 092adf53-a461-4de7-8e04-9bfe1de8c387 0614bd80-655c-49d4-b895-798f56f54803
221 2025-09-01 09:20:32+08:00 2025-09-01 09:25:17+08:00 4399.41 4396.45 -1343.8400000000165 long ef1554ec-bb75-4b5d-a3fd-03325d8ce248 11fb1482-9f6a-4b3f-aec4-e0e9f46ec4eb 454.0
222 2025-09-01 09:31:04+08:00 2025-09-01 09:32:03+08:00 4409.02 4405.26 -1703.2800000000989 long 8050d64e-1c53-40e1-89e7-68481d09e689 079730bc-d8ce-413a-a77f-a889bed73972 453.0
223 2025-09-01 09:34:47+08:00 2025-09-01 09:37:04+08:00 4405.92 4417.68 5327.280000000099 long 4f3b316a-37b6-43b9-a742-28760ce5267b 18f19970-4048-485b-b95a-00b3e804d0d9 453.0
224 2025-09-01 10:11:29+08:00 2025-09-01 10:16:05+08:00 4400.12 4391.86 400.0 3304.0000000000873 short 9b7a45aa-4ed0-4fa2-9c77-ee71e8319ecf 6adc05fa-6727-4961-8ae9-ef7f248ce06f
225 2025-09-01 10:11:30+08:00 2025-09-01 10:16:05+08:00 4400.12 4391.86 54.0 446.0400000000118 short a2b8e0df-1a70-4cbe-b513-734c169a45e5 6adc05fa-6727-4961-8ae9-ef7f248ce06f
226 2025-09-01 10:29:03+08:00 2025-09-01 10:30:26+08:00 4389.33 4386.21 -2130.9599999999255 long 9295d00e-a050-472f-b008-426e40eb0f71 73e0f83a-583a-4ae6-8dc3-41c2f37bb58e 683.0
227 2025-09-01 10:35:00+08:00 2025-09-01 10:36:12+08:00 4375.45 4379.38 685.0 -2692.0500000001994 short 8e5b463d-f4fe-47f3-b39b-ec3721c79e7a 2f96c834-2272-491f-8bc1-8cbe6c4ea452
228 2025-09-01 11:03:26+08:00 2025-09-01 11:05:42+08:00 4383.62 4391.35 5287.3200000003235 long ad2ab2b0-b070-4027-ba77-039ae801c30b ab66e717-8f29-4ebe-80c7-165f36806e5f 684.0
229 2025-09-01 11:12:18+08:00 2025-09-01 11:15:56+08:00 4382.88 4374.85 184.0 1477.5199999999531 short 60e70f9e-3ed0-402a-a33e-0d9104ac17b6 2c200cb7-b183-474a-b78f-bba9e592c8c0
230 2025-09-01 11:12:18+08:00 2025-09-01 11:15:56+08:00 4382.88 4374.85 500.0 4014.9999999998727 short 4f57713c-6a4c-42d4-aa6b-c03bae934835 2c200cb7-b183-474a-b78f-bba9e592c8c0
231 2025-09-01 11:34:38+08:00 2025-09-01 11:41:09+08:00 4370.18 4382.21 3440.579999999927 long 7716be61-be89-4b30-8939-ff0c2c42b4e2 15dadfe0-75d8-4cc7-838d-931a1d21ccf8 286.0
232 2025-09-01 11:34:38+08:00 2025-09-01 11:41:09+08:00 4370.18 4382.21 4811.999999999898 long 7716be61-be89-4b30-8939-ff0c2c42b4e2 9ae0cd54-0bfb-4a24-8c7a-1a247e078eb8 400.0
233 2025-09-01 11:54:59+08:00 2025-09-01 11:58:53+08:00 4396.0 4403.97 79.70000000000255 long b0876036-7e56-46cb-bddd-ccabb6519f7c 600628e2-049f-44c8-a905-46ea1135e601 10.0
234 2025-09-01 11:54:59+08:00 2025-09-01 11:58:53+08:00 4396.47 4403.97 1087.5 long 4bc131e8-70e0-4140-a2c8-b054e0507acd 600628e2-049f-44c8-a905-46ea1135e601 145.0
235 2025-09-01 11:54:59+08:00 2025-09-01 11:58:53+08:00 4396.47 4403.97 2662.5 long 4bc131e8-70e0-4140-a2c8-b054e0507acd 9d3eca96-2443-4c6e-b40e-1020bde26895 355.0
236 2025-09-01 11:54:59+08:00 2025-09-01 11:58:53+08:00 4396.47 4403.97 1290.0 long 86ab0723-57a8-4e31-9000-9b73f49ad308 9d3eca96-2443-4c6e-b40e-1020bde26895 172.0
237 2025-09-01 12:19:34+08:00 2025-09-01 12:23:09+08:00 4389.68 4388.07 500.0 805.000000000291 short 2aec9027-7a84-45c2-83d3-8c5871d90106 95aa0191-4e59-46b0-b538-e0a3fd31a029
238 2025-09-01 12:19:34+08:00 2025-09-01 12:23:09+08:00 4389.68 4388.0 87.0 146.16000000002532 short 2aec9027-7a84-45c2-83d3-8c5871d90106 861ff638-8ec8-4a6a-bafa-74206b093040
239 2025-09-01 12:19:34+08:00 2025-09-01 12:23:09+08:00 4389.68 4388.07 52.0 83.72000000003027 short 2aec9027-7a84-45c2-83d3-8c5871d90106 6cff4ab5-d999-4dda-87e2-067c9adbd240
240 2025-09-01 12:19:34+08:00 2025-09-01 12:23:09+08:00 4389.68 4388.07 500.0 805.000000000291 short 2aec9027-7a84-45c2-83d3-8c5871d90106 4dc3eeb9-b54d-4820-bc73-2172e8e5fd66
241 2025-09-01 12:52:26+08:00 2025-09-01 12:56:26+08:00 4381.97 4385.85 4427.0800000001245 long a3ef0945-101d-4f17-9cda-711fe44e2cf1 ab314993-0d4e-4632-8bcd-66aaaef57066 1141.0
242 2025-09-01 13:11:24+08:00 2025-09-01 13:12:28+08:00 4363.3 4368.36 475.0 -2403.499999999758 short 4d1d7cf6-26fe-44f0-be21-d10a9871ae1a 53f10353-21b1-41c1-8554-18c5bac4991a
243 2025-09-01 13:11:24+08:00 2025-09-01 13:12:28+08:00 4363.3 4368.36 400.0 -2023.9999999997963 short 63978423-878f-4bc0-8ac6-7526d1aa3b24 53f10353-21b1-41c1-8554-18c5bac4991a
244 2025-09-01 13:11:24+08:00 2025-09-01 13:12:28+08:00 4363.3 4368.36 500.0 -2529.9999999997453 short 9736d4ed-bfd4-4fb4-a2b9-7a335070a480 53f10353-21b1-41c1-8554-18c5bac4991a
245 2025-09-01 13:19:17+08:00 2025-09-01 13:20:04+08:00 4357.3 4364.42 1376.0 -9797.11999999985 short 9d7b259b-c1ec-4d54-83c5-e1588347d99f a63b68c2-d467-4b4b-992a-175e562a59cd
246 2025-09-01 13:23:06+08:00 2025-09-01 13:33:39+08:00 4390.89 4384.71 -1798.3800000000847 long 348b7ba0-df18-4d21-b652-1c54dc5b4635 2a709f71-d330-49c0-9759-3b65a140431c 291.0
247 2025-09-01 13:23:06+08:00 2025-09-01 13:33:39+08:00 4390.89 4384.71 -1854.0000000000873 long c8c60f9e-a45b-4f5a-b000-a1a436757403 2a709f71-d330-49c0-9759-3b65a140431c 300.0
248 2025-09-01 13:23:06+08:00 2025-09-01 13:33:39+08:00 4390.89 4384.71 -1854.0000000000873 long 970891fc-d2ec-4c54-a196-7a450a88c968 2a709f71-d330-49c0-9759-3b65a140431c 300.0
249 2025-09-01 13:23:06+08:00 2025-09-01 13:33:39+08:00 4390.01 4384.71 -106.00000000000364 long 71cd000e-8c95-4f6f-a32f-1440db6e8c0d 2a709f71-d330-49c0-9759-3b65a140431c 20.0
250 2025-09-01 13:49:13+08:00 2025-09-01 13:54:15+08:00 4396.35 4396.21 -40.18000000009397 long 83a1a14a-a4e3-40f1-86bd-915987501b35 4c298f23-9a76-4a0f-8bc1-f8ed23f12ede 287.0
251 2025-09-01 13:49:13+08:00 2025-09-01 13:54:15+08:00 4396.35 4396.21 -28.000000000065484 long 83a1a14a-a4e3-40f1-86bd-915987501b35 46728c29-6645-408a-bba2-07f01cd5d06d 200.0
252 2025-09-01 13:49:13+08:00 2025-09-01 13:54:15+08:00 4396.35 4396.21 -1.8200000000042564 long 83a1a14a-a4e3-40f1-86bd-915987501b35 c4cb8611-b4dd-41fd-95c2-c9455c1237e6 13.0
253 2025-09-01 13:49:13+08:00 2025-09-01 13:54:15+08:00 4396.35 4396.21 -26.180000000061227 long 47230a4e-8ee9-4d68-aa51-01753afc623b c4cb8611-b4dd-41fd-95c2-c9455c1237e6 187.0
254 2025-09-01 13:49:13+08:00 2025-09-01 13:54:15+08:00 4396.35 4396.13 -46.86000000005424 long 47230a4e-8ee9-4d68-aa51-01753afc623b e06fcad9-5742-4c94-82eb-2f34884e3f4a 213.0
255 2025-09-01 13:49:14+08:00 2025-09-01 13:54:15+08:00 4396.35 4396.13 -1.980000000002292 long 1743d43c-c642-434b-940f-b6d33e6718b9 e06fcad9-5742-4c94-82eb-2f34884e3f4a 9.0
256 2025-09-01 15:34:19+08:00 2025-09-01 15:35:08+08:00 4429.5 4426.01 -1406.469999999912 long e9dad14a-702d-4396-a259-38e6c3b62876 76c3e1c9-aeee-41bd-b8d4-37e8948af1c4 403.0
257 2025-09-01 15:34:19+08:00 2025-09-01 15:35:08+08:00 4429.5 4426.01 -1744.9999999998909 long 431b7e4b-b81e-4626-a6de-f5acd5a7cf20 76c3e1c9-aeee-41bd-b8d4-37e8948af1c4 500.0
258 2025-09-01 15:36:02+08:00 2025-09-01 15:36:51+08:00 4424.4 4419.44 -3868.8000000000284 long d7ba8670-d0d7-4817-b30f-ed7d2ba4fd3c 74c07207-3acc-4f9c-b98b-ae54e4085d96 780.0
259 2025-09-01 15:36:02+08:00 2025-09-01 15:36:51+08:00 4424.4 4420.0 -545.5999999999549 long d7ba8670-d0d7-4817-b30f-ed7d2ba4fd3c a4bea0b9-d2b0-42bf-9e3b-371747ea4fa3 124.0
260 2025-09-01 15:44:38+08:00 2025-09-01 15:47:21+08:00 4420.39 4426.94 4427.799999999508 long 17564d45-1b57-4822-91dd-7bf3a162e7b1 131e056d-1779-4de8-bb12-1663936c3ffe 676.0
261 2025-09-01 15:44:38+08:00 2025-09-01 15:47:21+08:00 4420.0 4426.94 152.6799999999912 long 7e280213-31c8-4848-b164-57ce0f3a30c3 131e056d-1779-4de8-bb12-1663936c3ffe 22.0
262 2025-09-01 15:44:38+08:00 2025-09-01 15:47:21+08:00 4420.39 4426.94 1349.2999999998501 long 37898b4e-9a13-4bc0-a9e6-3fa908bd1e80 131e056d-1779-4de8-bb12-1663936c3ffe 206.0
263 2025-09-01 15:51:28+08:00 2025-09-01 15:54:46+08:00 4434.86 4450.54 6068.160000000113 long a62d6355-e666-4b24-a9fe-1a8efd802cd4 c5b380bf-78c7-4dfd-a1b8-f212e0562e5d 387.0
264 2025-09-01 15:51:28+08:00 2025-09-01 15:54:46+08:00 4434.86 4450.54 8059.52000000015 long 9383482c-67d4-4a52-9c9a-bf106f8a66ed c5b380bf-78c7-4dfd-a1b8-f212e0562e5d 514.0
265 2025-09-01 15:59:35+08:00 2025-09-01 16:02:01+08:00 4454.21 4472.89 16774.64000000026 long b4194b4d-5b4a-4387-879f-b208a173d23e 0b3a10ad-d3bc-49e7-bc76-95d3f3f7b012 898.0
266 2025-09-01 16:05:00+08:00 2025-09-01 16:05:43+08:00 4486.3 4479.29 -6245.9100000001945 long 62035134-6e2c-4e78-a57e-90883d6fd125 e148f8b3-d2b0-49a8-9702-bf0ef6d70a11 891.0
267 2025-09-01 16:06:22+08:00 2025-09-01 16:13:08+08:00 4478.53 4480.64 893.0 -1884.2300000005198 short d901988b-b5b6-4a5e-a03c-83cedbdbbbda dcc81b54-5253-4a49-a426-f28316341b68
268 2025-09-01 16:18:38+08:00 2025-09-01 16:19:03+08:00 4467.53 4470.68 895.0 -2819.2500000004884 short 2a066536-51d7-425d-ae9e-83613597c612 41ad454f-5790-480c-9f16-80b478841763
269 2025-09-01 16:20:05+08:00 2025-09-01 16:22:22+08:00 4473.83 4478.12 894.0 -3835.2599999999675 short 93df10c4-453d-405e-aa78-3870c5c5f78f 5aeedf17-a10d-4388-b16e-e18251d6e1e5
270 2025-09-01 16:23:14+08:00 2025-09-01 16:27:37+08:00 4475.22 4469.41 893.0 5188.330000000357 short d9277a5f-844a-4afc-b784-0343d373a87e 7def0a70-6cc3-4880-9da3-16671ec6a296
271 2025-09-01 16:33:42+08:00 2025-09-01 16:41:25+08:00 4470.45 4469.46 894.0 885.0599999998049 short 9e7bf3df-d22c-413b-8b29-024b9c830f6b 3e80d0e3-3466-4e63-b75d-c86b67b6eb0b
272 2025-09-01 16:55:38+08:00 2025-09-01 17:04:46+08:00 4474.93 4476.7 893.0 -1580.6099999995777 short aca7bfae-9112-4a7a-8a95-7b7661be7d13 20115f47-253a-435a-9b43-1cfcbdc9c12e
273 2025-09-01 17:10:25+08:00 2025-09-01 17:15:02+08:00 4472.69 4480.01 6544.080000000553 long 44c66b7e-5da3-4773-b5a0-73b1cd1c13b9 d8403012-f909-414d-bb21-a012dc5722c2 894.0
274 2025-09-01 17:35:29+08:00 2025-09-01 17:38:36+08:00 4473.01 4460.17 300.0 3852.0000000000437 short 67981b9f-af13-4595-9a36-80db526ac0e4 de9b300a-19de-4cc4-b86e-e5d8ade4eb2f
275 2025-09-01 17:35:29+08:00 2025-09-01 17:38:36+08:00 4473.01 4460.17 70.0 898.8000000000102 short 67981b9f-af13-4595-9a36-80db526ac0e4 f7f5c314-6e7b-498a-99cf-a2c868021b32
276 2025-09-01 17:35:29+08:00 2025-09-01 17:38:36+08:00 4473.01 4460.17 236.0 3030.2400000000343 short 67981b9f-af13-4595-9a36-80db526ac0e4 f34ae213-3bb5-4bc5-96b5-1efb92648427
277 2025-09-01 17:35:29+08:00 2025-09-01 17:38:36+08:00 4473.01 4460.17 287.0 3685.0800000000418 short da23b541-1bde-4417-8875-4a52000d3183 f34ae213-3bb5-4bc5-96b5-1efb92648427

Binary file not shown.

View File

@@ -1,177 +0,0 @@
import datetime
import requests
from loguru import logger
# 请求头,用于伪装成浏览器访问接口
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh,zh-CN;q=0.9,zh-HK;q=0.8,en;q=0.7',
'cache-control': 'no-cache',
'origin': 'https://www.websea.com',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://www.websea.com/',
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36',
}
def fetch_kline(day: int):
"""获取某一天的分钟级 K线数据"""
# 构造该日的起止时间戳
time_ser = datetime.datetime(2025, 6, day)
start_of_day = time_ser.replace(hour=0, minute=0, second=0, microsecond=0)
end_of_day = time_ser.replace(hour=23, minute=59, second=59, microsecond=0)
params = {
'symbol': 'ETH-USDT', # 交易对
'period': '1min', # 分钟级K线
'start': int(start_of_day.timestamp()), # 开始时间
'end': int(end_of_day.timestamp()), # 结束时间
}
# 请求 API 获取数据
response = requests.get('https://capi.websea.com/webApi/market/getKline', params=params, headers=headers)
data = response.json()['result']['data']
# 按 id 排序(保证时间顺序)
return sorted(data, key=lambda x: x['id'])
# ================= 辅助函数 =================
def is_bullish(candle):
"""判断是否是阳线(收盘价 > 开盘价)"""
return float(candle['close']) > float(candle['open'])
def is_bearish(candle):
"""判断是否是阴线(收盘价 < 开盘价)"""
return float(candle['close']) < float(candle['open'])
def check_signal(prev, curr):
"""
判断是否出现反包形态:
1. 前一根阴线,后一根阳线,并且阳线包住前一根阴线 -> 做多信号
2. 前一根阳线,后一根阴线,并且阴线包住前一根阳线 -> 做空信号
"""
p_open, p_close = float(prev['open']), float(prev['close'])
c_open, c_close = float(curr['open']), float(curr['close'])
# 情况1前阴后阳且阳线包住前阴
if is_bullish(curr) and is_bearish(prev):
if c_open < p_close and c_close > p_open:
return "long"
# 情况2前阳后阴且阴线包住前阳
if is_bearish(curr) and is_bullish(prev):
if c_open > p_close and c_close < p_open:
return "short"
return None
def simulate_trade(direction, entry_price, future_candles, capital=10000, take_profit_ratio=5,
stop_loss_ratio=-2):
"""
模拟交易逐根K线回测
使用资金金额来控制止盈止损:
- 盈利达到 capital * take_profit_ratio 就止盈
- 亏损达到 capital * stop_loss_ratio 就止损
"""
for candle in future_candles:
high, low, close = float(candle['high']), float(candle['low']), float(candle['close'])
if direction == "long":
if high - entry_price >= take_profit_ratio:
return high, take_profit_ratio, candle['id'] # 止盈
if low - entry_price <= stop_loss_ratio:
return low, stop_loss_ratio, candle['id'] # 止损
elif direction == "short":
if entry_price - low >= take_profit_ratio:
return high, take_profit_ratio, candle['id'] # 止盈
if entry_price - low <= stop_loss_ratio:
return low, stop_loss_ratio, candle['id'] # 止损
# 如果未来都没触发,最后一根收盘平仓
final_price = float(future_candles[-1]['close'])
if direction == "long":
diff_money = (final_price - entry_price) / entry_price * capital
else:
diff_money = (entry_price - final_price) / entry_price * capital
return final_price, diff_money, future_candles[-1]['id']
# ================= 主程序 =================
if __name__ == '__main__':
if __name__ == '__main__':
zh_project = 0 # 累计盈亏
all_trades = [] # 保存所有交易明细
# 遍历 9月1日 ~ 9月27日
for i in range(1, 30):
sorted_data = fetch_kline(i) # 获取数据
signals = wins = 0
lig_price = low_price = 0 # 分别记录多/空的净收益
# 遍历每根K线寻找信号
for idx in range(1, len(sorted_data) - 2): # 留出未来K线
prev, curr = sorted_data[idx - 1], sorted_data[idx] # 前一笔,当前一笔
entry_candle = sorted_data[idx + 1] # 下一根开盘价作为入场价
future_candles = sorted_data[idx + 2:] # 未来行情
entry_open = float(entry_candle['open']) # 开仓价格
direction = check_signal(prev, curr) # 判断开仓方向
if direction:
signals += 1 # 总共信号数
exit_price, diff, exit_time = simulate_trade(direction, entry_open, future_candles)
# 统计多单/空单盈亏情况
if direction == "long":
lig_price += diff
if diff > 0: wins += 1
else:
low_price += diff
if diff > 0: wins += 1
# 保存交易详情
all_trades.append((f"{i}", entry_candle["id"], "做多" if direction == "long" else "做空",
entry_open, exit_price, diff, exit_time))
# 输出每日统计结果
if signals > 0:
logger.info(
f"日期:{i}号,信号数={signals}, 胜率={wins / signals * 100:.2f}%"
f"上涨方向={lig_price:.2f},下跌方向={low_price:.2f},综合={lig_price + low_price:.2f}"
)
else:
logger.info(f"日期:{i}号,没有信号")
# 累计盈亏
zh_project += (lig_price + low_price)
logger.success(f"综合价格:{zh_project:.2f}")
# ===== 输出每笔交易详情 =====
logger.info("===== 每笔交易详情 =====")
n = n1 = 0 # n = 总盈利n1 = 总手续费
for date, time_str, direction, entry, exit, diff, end_time in all_trades:
logger.info(
f"{date} {time_str} {direction} 入场={entry:.2f} 出场={exit:.2f} 出场时间={end_time} "
f"差价={diff:.2f} 盈利={diff / entry * 10000:.2f} "
f"开仓手续费=5u 平仓手续费={10000 / entry * exit * 0.0005:.2f}"
)
n1 += 5 + (10000 / entry * exit * 0.0005)
n += (diff / entry) * 10000
print(f'一共笔数:{len(all_trades)}')
print(f"一共盈利:{n:.2f}")
print(f'一共手续费:{n1:.2f}')

View File

@@ -1,214 +0,0 @@
import datetime
import requests
from loguru import logger
# 请求头,用于伪装成浏览器访问接口
headers = {
'accept': 'application/json, text/plain, */*',
'accept-language': 'zh,zh-CN;q=0.9,zh-HK;q=0.8,en;q=0.7',
'cache-control': 'no-cache',
'origin': 'https://www.websea.com',
'pragma': 'no-cache',
'priority': 'u=1, i',
'referer': 'https://www.websea.com/',
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36',
}
def fetch_kline(day: int, year: int = 2025, month: int = 9, period=1):
"""获取某一天的分钟级 K线数据"""
# 构造该日的起止时间戳
time_ser = datetime.datetime(year, month, day) # 修正为2024年9月
start_of_day = time_ser.replace(hour=0, minute=0, second=0, microsecond=0)
end_of_day = time_ser.replace(hour=23, minute=59, second=59, microsecond=0)
params = {
'symbol': 'ETH-USDT', # 交易对
'period': f'{period}min', # 分钟级K线
'start': int(start_of_day.timestamp()), # 开始时间
'end': int(end_of_day.timestamp()), # 结束时间
}
# 请求 API 获取数据
response = requests.get('https://capi.websea.com/webApi/market/getKline', params=params, headers=headers)
data = response.json()['result']['data']
# 按 id 排序(保证时间顺序)
return sorted(data, key=lambda x: x['id'])
# ================= 辅助函数 =================
def is_bullish(candle):
"""判断是否是阳线(开盘价 < 收盘价,即涨)"""
return float(candle['open']) < float(candle['close'])
def is_bearish(candle):
"""判断是否是阴线(开盘价 > 收盘价,即跌)"""
return float(candle['open']) > float(candle['close'])
def check_signal(prev, curr):
"""
判断是否出现包住形态,返回信号类型和方向:
1. 前跌后涨包住 -> 做多信号 (bear_bull_engulf)
2. 前涨后跌包住 -> 做空信号 (bull_bear_engulf)
3. 前涨后涨包住 -> 做多信号 (bull_bull_engulf)
4. 前跌后跌包住 -> 做空信号 (bear_bear_engulf)
"""
p_open, p_close = float(prev['open']), float(prev['close']) # 前一笔
c_open, c_close = float(curr['open']), float(curr['close']) # 当前一笔
# 情况1前跌后涨且涨线包住前跌线 -> 做多信号
if is_bullish(curr) and is_bearish(prev):
if c_open < p_close and c_close > p_open:
return "long", "bear_bull_engulf"
# 情况2前涨后跌且跌线包住前涨线 -> 做空信号
if is_bearish(curr) and is_bullish(prev):
if c_open > p_close and c_close < p_open:
return "short", "bull_bear_engulf"
# # 情况3前涨后涨且后涨线包住前涨线 -> 做多信号
# if is_bullish(curr) and is_bullish(prev):
# if c_open < p_open and c_close > p_close:
# return "long", "bull_bull_engulf"
# # 情况4前跌后跌且后跌线包住前跌线 -> 做空信号
# if is_bearish(curr) and is_bearish(prev):
# if c_open > p_open and c_close < p_close:
# return "short", "bear_bear_engulf"
return None, None
def simulate_trade(direction, entry_price, future_candles, take_profit_diff=30, stop_loss_diff=-10):
"""
模拟交易逐根K线回测
使用价差来控制止盈止损:
- 盈利达到 take_profit_diff 就止盈
- 亏损达到 stop_loss_diff 就止损
direction信号类型
entry_price开盘价格
future_candles未来的行情数据
"""
for candle in future_candles:
high, low, close = float(candle['high']), float(candle['low']), float(candle['close'])
if direction == "long":
# 做多:检查最高价是否达到止盈,最低价是否触及止损
if high >= entry_price + take_profit_diff:
return entry_price + take_profit_diff, take_profit_diff, candle['id'] # 止盈
if low <= entry_price + stop_loss_diff:
return entry_price + stop_loss_diff, stop_loss_diff, candle['id'] # 止损
elif direction == "short":
# 做空:检查最低价是否达到止盈,最高价是否触及止损
if low <= entry_price - take_profit_diff:
return entry_price - take_profit_diff, take_profit_diff, candle['id'] # 止盈
if high >= entry_price - stop_loss_diff:
return entry_price - stop_loss_diff, stop_loss_diff, candle['id'] # 止损
# 如果未来都没触发,最后一根收盘平仓
final_price = float(future_candles[-1]['close'])
if direction == "long":
diff_money = final_price - entry_price
else:
diff_money = entry_price - final_price
return final_price, diff_money, future_candles[-1]['id']
# ================= 主程序 =================
if __name__ == '__main__':
zh_project = 0 # 累计盈亏
all_trades = [] # 保存所有交易明细
# 四种信号类型的统计
signal_stats = {
"bear_bull_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "涨包跌"},
"bull_bear_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "跌包涨"},
# "bull_bull_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "涨包涨"},
# "bear_bear_engulf": {"count": 0, "wins": 0, "total_profit": 0, "name": "跌包跌"}
}
datas = []
# 遍历 9月1日 ~ 9月27日
for i in range(1, 31):
logger.info(i)
sorted_data = fetch_kline(year=2025, month=9, day=i, period=15) # 获取数据
datas.extend(sorted_data)
datas = sorted(datas, key=lambda x: x["id"])
print(datas)
daily_signals = 0 # 信号总数
daily_wins = 0
daily_profit = 0 # 价差总和
# 遍历每根K线寻找信号
for idx in range(1, len(datas) - 2): # 留出未来K线
prev, curr = datas[idx - 1], datas[idx] # 前一笔,当前一笔
entry_candle = datas[idx + 1] # 下一根开盘价作为入场价
future_candles = datas[idx + 2:] # 未来行情
entry_open = float(entry_candle['open']) # 开仓价格
direction, signal_type = check_signal(prev, curr) # 判断开仓方向和信号类型
if direction and signal_type:
daily_signals += 1
exit_price, diff, exit_time = simulate_trade(direction, entry_open, future_candles, take_profit_diff=30,
stop_loss_diff=-2)
# 统计该信号类型的表现
signal_stats[signal_type]["count"] += 1
signal_stats[signal_type]["total_profit"] += diff
if diff > 0:
signal_stats[signal_type]["wins"] += 1
daily_wins += 1
daily_profit += diff
# 将时间戳转换为本地时间
local_time = datetime.datetime.fromtimestamp(entry_candle['id'])
formatted_time = local_time.strftime("%Y-%m-%d %H:%M:%S")
# 保存交易详情
all_trades.append(
(
f"{formatted_time}",
"做多" if direction == "long" else "做空",
signal_stats[signal_type]["name"],
entry_open,
exit_price,
diff,
exit_time
)
)
# ===== 输出每笔交易详情 =====
logger.info("===== 每笔交易详情 =====")
n = n1 = 0 # n = 总盈利n1 = 总手续费
for date, direction, signal_name, entry, exit, diff, end_time in all_trades:
profit_amount = diff / entry * 10000 # 计算盈利金额
close_fee = 10000 / entry * exit * 0.0005 # 平仓手续费
logger.info(
f"{date} {direction}({signal_name}) 入场={entry:.2f} 出场={exit:.2f} 出场时间={end_time} "
f"差价={diff:.2f} 盈利={profit_amount:.2f} "
f"开仓手续费=5u 平仓手续费={close_fee:.2f}"
)
n1 += 5 + close_fee
n += profit_amount
print(f'一共笔数:{len(all_trades)}')
print(f"一共盈利:{n:.2f}")
print(f'一共手续费:{n1:.2f}')