408 Commits

Author SHA1 Message Date
dekun 890659f173 Add key monitor and live trade toggles to instance nav display prefs.
Defaults stay on; users can hide them like other top-bar tabs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 00:55:31 +08:00
dekun ca499c6104 Send WeChat alerts on OKX options open and close.
Cover manual, target, and exchange/expiry sync with idempotent sent flags.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 00:48:15 +08:00
dekun 54f1857fa2 Sync OKX options closed trades into hub archive with a separate tab.
Mirror perpetual archive flow into archive_options_trade_cache for offline calendar and review.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 00:39:59 +08:00
dekun 6f1ae14b3d Add display toggles to hide monitor cards and strategy tabs.
Keep unused exchanges/docs out of the UI without disabling accounts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 00:24:00 +08:00
dekun 29d59d6a53 Add playbook v2 without hedge as the primary strategy guide.
Wire hub strategy tabs and coach brief to 1H→space→structure→risk/reward→options/perp only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 00:09:40 +08:00
dekun 58a4dafe9a Document snapshot/20260723-2 after strategy compare work.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 15:20:00 +08:00
dekun 9e0591c676 Increase strategy compare card padding so content is not flush.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 14:59:37 +08:00
dekun ed3033d793 Add hub strategy compare page for perp vs options vs 7:3 hedge.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 14:39:59 +08:00
dekun b6156e0049 Apply account-PnL display pref to dashboard KPI and position tables.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 12:44:36 +08:00
dekun 8e3c00641f Hide options PnL/ROI and daily float when account-PnL pref is off.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 12:39:43 +08:00
dekun f11f89e760 Show options funding, trading, and float PnL in monitor account stats.
EOF

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 12:34:23 +08:00
dekun 0096467d14 Keep Cursor project rules local-only.
Ignore .cursor/ and stop tracking rules so habits stay on this machine.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 12:05:52 +08:00
dekun 8a9dee267f Add open-trade three-check behavior guidelines.
Document signal/process/emotion firewall, expose it in hub strategy tabs, and brief the AI coach.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 09:15:47 +08:00
dekun 910c938d0a Throttle OKX amp-stats candle pagination and retry on 429.
Add page pauses, exponential backoff, and cooldown before swap fallback to avoid rate limits.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 02:57:24 +08:00
dekun 0a9e3aa95c Fix amp-stats long-range candles via OKX history endpoints.
Recent candles cap near 60d; continue with history-index/history candles and color profit green/red.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 02:53:36 +08:00
dekun b64c742fc9 Add weekend filter, take-profit, and profit column to amp stats.
Long-straddle effective move uses TP on path hit (>=) else abs change; mark Sat/Sun on settlement days.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 02:47:20 +08:00
dekun 789ab43dbe Add long-straddle premium overlay to hub amp stats.
Configurable bilateral premium with exceed counts/ratios and settlement PnL for buying volatility.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 02:33:23 +08:00
dekun 61e8da1e8b Add hub-only OKX amp stats for ETH/BTC session windows.
Read-only 1H index candles, point amplitude metrics, history save and CSV export; no order-path changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 02:06:21 +08:00
dekun 40be3a5ab7 Fix snapshot tag commit hash in docs table.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 02:01:22 +08:00
dekun 4ccfb838f6 Record pre-amp-stats snapshot and freeze amp-stats plan.
Tag baseline before hub-only amplitude statistics feature work.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 02:01:21 +08:00
dekun 58e9c8f85e Feed options positions and playbook brief into trading coach.
Coach context previously omitted options_snapshot details; also inject a short 执行手册 summary each turn.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-22 23:28:16 +08:00
dekun eb0eddbc9d Tighten mobile monitor stats to two lines and hide ops fold.
Desktop refresh/emergency-close and expanded stats layout stay unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-22 22:17:14 +08:00
dekun c5f40cba2b Align snapshot/20260721-2 hash with tag target.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 22:24:02 +08:00
dekun a7216428ab Fix snapshot tag commit hash in docs table.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 22:22:29 +08:00
dekun 77f66bf200 Fill snapshot/20260721-2 commit hash placeholder.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 22:22:29 +08:00
dekun 488b931959 Fix snapshot tag commit hash in docs table.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 22:22:05 +08:00
dekun b89cba3b6e Record evening git snapshot snapshot/20260721-2.
Document playbook hub tab, daily loss freeze, and trading handbook state on main.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 22:22:04 +08:00
dekun e7f8e9201e Show trading playbook in hub strategy docs.
Add an 执行手册 tab that renders docs/交易执行手册-期权与Gate.md as the default strategy view.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 22:16:54 +08:00
dekun 301a464f29 Add daily loss-count freeze for account risk cooldown.
RISK_DAILY_LOSS_LIMIT (default 2, 0 disables) freezes new opens after N losing closes in the trading day.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 22:13:38 +08:00
dekun a4be294c06 Add personal options-and-Gate trading playbook doc.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 22:04:46 +08:00
dekun 1a163c0a43 Fix snapshot tag commit hash in docs table.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 10:52:59 +08:00
dekun 2a60d47b2d Document git snapshot tags including snapshot/20260721.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 10:52:35 +08:00
dekun 64b24fd6a6 Add repository code statistics snapshot doc.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 10:48:10 +08:00
dekun 60ff45f098 Fix hedge option PnL match by parsing opened_at as Asia/Shanghai.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 10:21:52 +08:00
dekun 67a09b1de8 Fix options review light theme dark card/filter styles.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 10:14:26 +08:00
dekun 7e7666adfb Align hedge plan option leg PnL with OKX exchange history.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 10:09:44 +08:00
dekun 6876515160 Align options review PnL with OKX positions-history realizedPnl.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 10:05:27 +08:00
dekun 1bc12a32c6 Sync exchange PnL when hub loads trade records API.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-21 09:40:42 +08:00
dekun 6def61fae3 Fix option day splits to daily Beijing 16:00 lines.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 16:18:46 +08:00
dekun 10ee7614b5 Hub market: add option expiry Friday yellow dashed splits.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 16:16:38 +08:00
dekun 221e8c3cad Desktop calculator: stretch left/right cards to equal height.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 12:56:59 +08:00
dekun 29c080f8e0 Desktop calculator: top tabs with input/result dual cards.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 12:54:13 +08:00
dekun 7a01535802 Enlarge dashboard KPI summary bar for readability.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 12:48:38 +08:00
dekun f467f94fe9 Replace dashboard perp profit column with stop-loss and take-profit.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 12:47:16 +08:00
dekun 913c7d5be6 Show hedge plan id in options type column; drop group box UI.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 12:43:51 +08:00
dekun 0f5fe801e2 Fix dashboard TP profit display; add options ROI column.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 12:41:32 +08:00
dekun 977d62bddf Group hedge option legs on dashboard; show long/short direction colors.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 12:38:11 +08:00
dekun 3ed8dabc76 Align dashboard PnL columns with monitor; add back-to-dashboard button.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 12:34:09 +08:00
dekun eb2afb3c55 Restore position type badges; hide empty perp/options sections.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 12:30:05 +08:00
dekun ee3c1bcdca Unify hub dashboard positions into one card with exchange links.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 12:27:19 +08:00
dekun d2028ed0ee Show options budget buffer ratio in open-order rule tip.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 10:37:20 +08:00
dekun 3ae7def999 Show live hedge budget buffer ratio in options-options rule tips.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 10:32:06 +08:00
dekun c9229d64bf Move hedge rule tips into left parameter cards as inline collapses.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 10:25:31 +08:00
dekun 3923818508 Add collapsible rule tips for perp-options and options-options hedge tabs.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 10:22:04 +08:00
dekun 4a3e6a2a1d Add global autofill guard for hub, env, and transfer inputs.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 10:18:56 +08:00
dekun 00d76ba20f Stop browser autofill stuffing login username into transfer amount fields.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 10:14:14 +08:00
dekun 5b346a5760 Hedge start: re-quote ask and resize OO sheets; add HEDGE_PLAN_BUDGET_BUFFER.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 10:09:32 +08:00
dekun a43cb35d9a Add end-plan action; never show unfilled option legs as open.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 09:36:46 +08:00
dekun 8597e47596 Hedge options open: require full fill (IOC + wait) before success.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 09:14:03 +08:00
dekun 88d460d484 Options: collapse open rules; move open-guard tip into risk policy.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 08:46:02 +08:00
dekun ed1ec6f14a Options: default nearest expiry and env ask-liquidity chain filter.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 08:37:39 +08:00
dekun 7eb098def6 Options: merge duplicate order dialog head CSS.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 08:16:23 +08:00
dekun 972ef4f910 Options: loosen order dialog spacing and stack mode/note rows.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 08:15:55 +08:00
dekun 4e614eb9ed Options: frame target and size-mode chips like cancel buttons.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 08:11:23 +08:00
dekun 547eedeec4 Options: show order form as viewport modal on select.
Stop inserting the panel under the strike row; mount backdrop on body with cancel/Esc close.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 08:06:07 +08:00
dekun 19b46d19fd Options: eth-amount dialog, stop note autofill, pending tab in positions.
Selecting 指定币数量 opens an order dialog; pending orders move into a 当前委托 tab after 当前持仓; harden remark autofill that showed dekun.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 08:00:39 +08:00
dekun debfb116fd Expand options review table columns and color result tags.
Show direction, hold time, and entry logic; paint 盈利 green and 亏损 red.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 16:49:35 +08:00
dekun 3c21680763 Bump hedge_plan.js cache for Chinese close-reason labels.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 16:45:27 +08:00
dekun bc08a5852d Show hedge close reasons in Chinese on options review.
Map plan/leg close_reason codes like target_down_win_leg and expiry to Chinese labels in detail, form, and stats.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 16:44:45 +08:00
dekun a2d4507028 Move options review tabs and filters above content cards.
Keep the category tabs and search toolbar page-level so they sit above the numbered trade/review/stats sections.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 16:39:34 +08:00
dekun 17cd835e5d Clarify options review layout with numbered sections and KPI tiles.
Separate trade/review/stats blocks, tuck filters into a toolbar, and hide empty stat groups so the page scans more easily.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 16:32:34 +08:00
dekun ac018cb618 Show options review image zoom above the detail modal.
Add a dedicated lightbox above the review dialog and raise global imgModal z-index so enlargements are no longer hidden behind it.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 16:27:42 +08:00
dekun 220aab9b63 Keep reviewed trades in options list and stop search autofill.
Top trade list no longer hides reviewed rows; search box resists browser username autofill (dekun).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 16:26:02 +08:00
dekun 72dddc5106 Fix options review screenshots missing after journal upload hijack.
Stop journal_upload_slots from binding options slots; resolve journal_* files from static/images root so existing reviews display again.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 16:23:37 +08:00
dekun 12574ae88a Fix options review empty lists when search box has symbol text.
Treat the filter as fuzzy q over underlying/inst/strategy (BTCUSDT->BTC) instead of exact strategy_tag, which always wiped pending rows.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 16:17:45 +08:00
dekun 426afb8dbe Make options review detail a modal and fix screenshot display.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 16:11:45 +08:00
dekun 38ac258497 Color 期期 preview PnL and show RR vs full premium loss.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 15:43:01 +08:00
dekun 7938628485 Fix 期期 sheets bias: split total 2n from same-sheets, not n.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 15:33:00 +08:00
dekun e3cd2a75de Replace 期期 equal-split with long/short bias sizing and env ratio controls.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 15:25:10 +08:00
dekun bc797cb1db Split options review open/close times into separate columns.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 15:08:23 +08:00
dekun 0ed2eabf0d Expand system guide with live trade, strategy, and key monitor chapters.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 09:29:56 +08:00
dekun 5e0ce43415 Add instance system guide nav (default off) with overview/options/hedge manual.
EOF

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 09:23:30 +08:00
dekun eea4d4ff8f Show auto-close as off when partial manual-complete is enabled.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 09:11:00 +08:00
dekun d74d0aeae0 Park partial hedge plans for manual leg complete instead of auto-close.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 09:06:22 +08:00
dekun e11c13747a Add mutual-exclusion gate between hedge plans and standalone options.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 08:51:46 +08:00
dekun 899a2de931 Show options position source (纯期权/永期/期期) on holdings cards.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 08:45:17 +08:00
dekun fa2127d66c Make 永期 hedge UI clearer with dir segments and field grid.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 08:34:45 +08:00
dekun d5f3f315dc Show hedge-plan scenario preview in a modal with start/cancel.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 08:28:54 +08:00
dekun 1c155328b4 Move 期期 USDC transfer into T-quote card to free left panel.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 08:20:55 +08:00
dekun 3093d07167 期期: green index after lower target, USDC transfer, clearer selected state.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 08:16:44 +08:00
dekun 79420904f4 Tighten 期期 parameter UI: compact controls, less copy.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 08:10:12 +08:00
dekun 3119486105 Add 期期 close mode (全平/到期平) with scheme-C env toggle.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 08:06:27 +08:00
dekun b3548240cc Auto-fill 期期 sheets from trading balance with same-sheets default.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 00:56:35 +08:00
dekun f21e4d1166 Add env toggles to show/hide perp and options hedge plan tabs.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-19 00:43:04 +08:00
dekun 9e1343981d Give strategy doc body more inner padding from card edges.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 17:44:28 +08:00
dekun 2f7e6355a1 Add section badges to strategy TOC/headings and fill cards to viewport height.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 17:41:04 +08:00
dekun 023bf6a814 Simplify strategy TOC to h2-only one level.
Drop nested h3 entries from the sidebar directory so the outline stays flat and easier to scan.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 17:37:39 +08:00
dekun 9198aa0dcd Fix strategy checklist hidden class so tabs do not stack.
Generic .hidden was missing display:none, so 执行清单 stayed visible beside 策略正文.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 17:32:04 +08:00
dekun 82c910fbf8 Add blog-style TOC to strategy doc; checklist as separate tab.
Strategy page uses 策略正文 (MD + sticky h2/h3 TOC) and 执行清单 tabs so full playbook detail stays readable with jump navigation.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 17:29:18 +08:00
dekun 778a215ad7 Fix strategy checklist print closing too early.
Stop auto-closing the print tab on afterprint (short checklist pages were especially fragile), load print HTML via fetch into a blank window, and use CSS checkboxes instead of Unicode ballot boxes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 16:16:34 +08:00
dekun faf21da955 Show trade record prices at exchange tick precision.
API enriches entry/SL/TP with price_to_precision display strings; OKX formatter now uses the same path as Gate/Binance.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 15:41:49 +08:00
dekun 0a14fe73c1 Add key auto-order toggle to instance env config UI.
Expose KEY_AUTO_ORDER_ENABLED and KEY_AUTO_MIN_PLANNED_RR under 交易执行 so the frontend matches the settings readout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 15:31:39 +08:00
dekun 27c116f872 Stop embed form interceptor from blanking trade records after journal save.
Exclude journal-form from InstanceEmbed submit reload, stopImmediatePropagation on AJAX save, and force-reload trades when the table is stuck on loading.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 15:28:52 +08:00
dekun a244850b25 Fix journal AJAX save in embed so trades stay loaded.
Delegate submit handling for late-mounted #journal-form across OKX/Binance/Gate, avoid full reload fallback, and soft-refresh trade rows after save.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 15:23:48 +08:00
dekun 8f4ae8ad31 Speed up journal save with AJAX and async K-line charts.
Defer exchange chart generation to a background thread and save via XHR so fill-from-trade no longer blocks on full page reload.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 15:15:24 +08:00
dekun 813ecdd4ac Lighten hub options snapshot by skipping history stats.
Monitor board only needs positions, balances, and targets; drop the OKX positions-history pull each poll, and surface timeout errors via msg.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 15:00:55 +08:00
dekun 217e752ee6 Shrink instance dashboard header type and show options net PnL.
Header copy is smaller; options column uses bid-recycle net PnL like the options card.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 22:04:21 +08:00
dekun 173f09300b Align instance dashboard with hub snapshot+SSE pattern.
Background poll builds a memory snapshot; the page reads snapshot and refreshes on SSE instead of hitting heavy exchange APIs on each load.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 22:00:30 +08:00
dekun aabbbef0a9 Turn position/margin/sizing/direction env fields into dropdown selects.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 19:41:47 +08:00
dekun 53e55aa4b4 Redirect Gate and Binance page routes into the embed shell like OKX.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 19:36:39 +08:00
dekun 041692a763 Retry pip installs during deploy to tolerate flaky mirrors.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 16:02:51 +08:00
dekun 572239f69c Fix pip --progress-bar for pip 26+ so instance deploy can install deps.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 15:47:33 +08:00
dekun 0f12e0a8ea Add single-exchange instance-only deploy menu options.
Manage menu 4/5/6 install OKX/Binance/Gate Flask only without hub or agents; reuse setup_env --only and narrowed PM2 verify.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 15:40:25 +08:00
dekun 2269bc51ff Deduct round-trip taker fees from estimated perp PnL.
Unify hub/instance TP profit, calc_pnl, and push/accounting to net of 0.05% per side; leave exchange floating PnL unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 15:12:52 +08:00
dekun d5e6132b13 Spread dashboard KPI items evenly across the card.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 14:55:15 +08:00
dekun 89148bb119 Merge dashboard KPIs into one compact card.
Put status badge and expand on one row; drop funds footnote, win/loss, and separate options float KPI.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 14:52:05 +08:00
dekun 549d8a015c Show pure-option source and net PnL on dashboard.
Restore 纯期权 label for non-hedge option rows and use close-preview net PnL instead of exchange upl.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 14:32:43 +08:00
dekun c4c8ad172a Label dashboard positions from monitor sources with priority.
Match hedge/roll/trend/order/key monitors for source badges, show option target monitors in green, and refresh the dashboard with the board 5s cycle.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 14:25:36 +08:00
dekun 0bda44248f Show only positioned accounts on the dashboard.
Drop per-exchange fund metrics and render open positions as labeled tables while keeping closed-trade details.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 14:13:44 +08:00
dekun 33b3e5f54b Keep calendar day trades inline and hide K-line by default.
Show selected-day trades under the calendar without tab jumps, put trades first, and open the chart only via toolbar or row actions.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 14:05:59 +08:00
dekun e70e6c7b13 Split archive into four content tabs.
Move chart overview and calendar into their own tabs so trades and quotes stay focused.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 13:59:44 +08:00
dekun b7f3a5c289 Add top-nav Quotes blog feed page.
Surface recent review quotes grouped by trading day with expand, day PnL summary, and AI review jump.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 13:54:24 +08:00
dekun 7a0d015416 Add archive tabs for trades vs review quotes.
Switch hub 内照明心 to a single-column tab layout and auto-show that day's closed trades under the quote form for AI review context.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 13:41:13 +08:00
dekun afb771fef1 Shrink hub archive panels to content height instead of filling the viewport.
Remove 100vh min-heights and flex-grow on quotes/trades so idle space below 5-row lists collapses.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 13:30:15 +08:00
dekun e5e1d5edcc Paginate hub archive trade records at 5 per page.
Match the instance records pager so 内照明心 lists stay compact with prev/next controls.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 13:27:42 +08:00
dekun c2a40e3cc5 Fix empty AI review content from gemma reasoning token use.
Parse alternate reasoning fields, retry with a larger max_tokens budget, cap review images, and fall back to text-only when vision returns empty.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 13:21:06 +08:00
dekun 4126784056 Make env config panel full width like the funds header strip.
Match settings/risk-policy: span the page grid so the card aligns with account stats.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 13:16:06 +08:00
dekun af7fb44650 Raise Nginx proxy timeouts so AI daily/weekly review is not cut at 60s.
POST /ai_daily_review was returning 504 while the model was still running; patch BT reverse-proxy read/send timeouts to 360s on deploy.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 13:12:32 +08:00
dekun 5bd3f3250a Restore vertical gaps between cards on the records/review panel.
The pagination wrap stacked cards without inheriting the page grid gap.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 13:05:54 +08:00
dekun f27b4bc1ec Fix OKX header trade stats stuck at zero after settings shell load.
Always SSR records summary on embed shell (including settings/risk/env), and refresh total/win-rate/PL ratio via account_snapshot so soft-nav cannot leave the strip blank.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 13:03:04 +08:00
dekun 3a20546782 Make risk policy and settings panels full width.
Match the funds header span by spanning the two-column content grid.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 12:55:40 +08:00
dekun 35117ba84e Polish dashboard tables: hub-style orders, options source/expiry, hedge status.
Show 进行中 in green for active hedges; options columns include source/target/expiry; merge live mark/contracts/pnl from price snapshot.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 12:23:25 +08:00
dekun cd2dfac2ba Hide empty dashboard sections and render data as tables.
Orders/keys/strategy/options/hedge only appear when they have rows, shown in table layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 12:14:03 +08:00
dekun c7aae67881 Add instance data dashboard (default off).
Read-only overview of live orders, key monitors, and strategy; show options/hedge only when present. Toggle via system settings nav prefs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 12:09:29 +08:00
dekun f7ba7c2f7d Auto-fill journal direction from trade records.
Add a required direction field on the review form, persist it, and set long/short when clicking 填入复盘.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 12:00:09 +08:00
dekun f435e9dfaa Render saved journals as a table like trade records.
Desktop journal list now uses columns for coin, direction, PnL, times, and actions instead of stacked entry cards.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 11:55:18 +08:00
dekun d9b8069906 Add shared records review pagination for all three exchanges.
Paginate trade records, journals, and AI history at 5 per page with soft in-card flips; hide the journal form until 填入复盘.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 11:52:02 +08:00
dekun 57f8d6761c Keep options review paging in-card without layout jump.
Soft-load table rows on prev/next so height stays stable and the page below does not flash.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 11:40:23 +08:00
dekun 77ab7503a1 Show total pages and card-local AJAX paging on options review.
Trades and reviewed lists now report page X / Y and flip without full-page sync refresh.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 11:34:21 +08:00
dekun 06ffb6ee0f Keep page scrollbars at the window right edge across hub pages.
Move funds scrolling to body, keep monitor/market on a full-width shell, and stretch other desktop shells so page scroll is never inset.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 11:27:29 +08:00
dekun 78c44fdeab Fix funds overview clipping on 1920x1080.
Make the funds stage scrollable, give the equity chart a fixed height so date labels fit, and stop truncating account cards without a scrollbar.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 11:24:41 +08:00
dekun cb2fcd283a Give funds equity curve more room on 1920x1080.
Drop the 42vh chart cap, let the curve fill remaining height, and scroll account cards so the curve is not clipped.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 11:19:58 +08:00
dekun 3f6e4329d9 Fix market chart collapse while keeping edge scrollbar.
Restore app-shell to full-viewport height for flex charts, and stretch the shell full width so the scrollbar stays at the window edge.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 11:15:23 +08:00
dekun 353c09ea0d Put hub page scroll on body so the scrollbar sits at the window edge.
Revert the host-status chevron move; the inset scrollbar came from scrolling the centered app-shell.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 11:10:15 +08:00
dekun ee9608dc80 Move monitor host-status chevron to the right edge.
Align the server-status disclosure arrow with the common right-side fold pattern.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 11:07:41 +08:00
dekun 8842f0b869 Restructure options review into pending trades, form, and reviewed detail.
Show five pending trades per page, reveal the upload form only after clicking 复盘, and list saved reviews with image detail above stats.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 10:50:12 +08:00
dekun 01ca035c2a Add typed options review form presets by source.
Pure options and hedge plans use separate strategy/entry selects, with auto-filled direction and PnL result including breakeven.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 10:27:23 +08:00
dekun d7272c9722 Persist options review deletes across local resync.
Hide deleted rows by history key and contract/close fingerprint so local options_trades imports no longer resurrect them.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 10:03:00 +08:00
dekun 48afc8ebe3 Load options review from local records with compact journal UI.
Drop exchange sync for the review page, auto-import closed local options and hedge plans, and match contract-style multi-timeframe upload styling with smaller fonts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 09:54:35 +08:00
dekun c6142dc246 Show options review upload form always on page.
Keep the multi-timeframe journal card visible like contract review instead of hiding it until a row is selected.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 09:49:14 +08:00
dekun edcc04e88c Improve options review tabs and multi-timeframe uploads.
Add source-type tabs, open an inline journal form from list rows, and match contract-style 5m/15m/1h/4h screenshot slots.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 09:45:44 +08:00
dekun 10128d18bc Add OKX options review module with hedge plan entries.
Import closed OKX option history and closed hedge plans into one list for journaling, images, and stats without mixing contract reviews.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 09:35:19 +08:00
dekun eb5c6a658b Show hedge targets in control center
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 07:29:45 +08:00
dekun 8f71dbe874 Show hedge targets in options monitoring
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 07:15:00 +08:00
dekun 6e6cb7caac Add active hedge plan tab
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-17 07:04:51 +08:00
dekun e280220951 Move desktop calculator tabs left.
Compress wide-screen calculator inputs into three rows while preserving mobile layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 14:50:42 +08:00
dekun c9d40e5e52 Add desktop calculator tabs.
Show one strategy calculator at a time while preserving the existing mobile tab experience.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 14:44:36 +08:00
dekun b30129f83f Remove duplicate funds PnL banner.
Keep cumulative PnL in summary cards and free toolbar space after snapshot sync.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 14:36:37 +08:00
dekun 4e86595f2a Collapse daily stats by default.
Show only total floating PnL until expanded; enlarge details and lower exchange headers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 14:31:00 +08:00
dekun 35b23836e3 Restore strategy chips and 1080p side margins.
Stick expand hint to card bottom; drop mistaken key-monitor slot; keep ultrawide content width.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 14:11:29 +08:00
dekun 0540b585c7 Refine monitor 2x2 slots and drop tablet CSS.
Add options target column, reserve pos/monitor rows, equal columns, and remove hub-tablet densify path.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 14:03:59 +08:00
dekun 018b4d5601 Split OKX monitor into perp and options cards.
Align four exchange cards in a 2x2 grid so 1080p layout stays balanced.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 13:47:21 +08:00
dekun bde8c517e0 Tighten empty monitor cards on 1080p.
Size no-position blocks to content and give remaining height to options/positions.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 13:42:26 +08:00
dekun 480f6d78e8 Fix desktop blur from false tablet layout.
Stop classifying short desktop viewports as tablets so densify fonts do not apply.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 13:35:41 +08:00
dekun 57dad1ffdf Fit tablet hub to one screen with denser type.
Keep full card content readable; shrink fonts/spacing and use in-table scroll only when positions overflow.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 13:22:57 +08:00
dekun 7d6f0ac55b Fix tablet hub cards clipping content.
Prefer visible card content over forced one-screen crop; auto row heights and page scroll on hub-tablet.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 13:13:17 +08:00
dekun 2777419a10 Add tablet viewport fit for hub one-screen layout.
Hi-DPI tablets like 2560x1600 map to ~1280x800 CSS; broaden fit breakpoints and densify for hub-tablet.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 13:09:29 +08:00
dekun 836b37cc7e Fit hub monitor, market, and funds to one 1080p screen.
Constrain desktop shell to 100dvh with flex fill so OKX perp+option plus peer cards, chart, and equity overview avoid page scroll.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 13:01:17 +08:00
dekun 4686cf049a Require real ask depth for options and hedge opens.
Block mark-as-ask opens, show reference mark when no depth, cap sheets to ask size; leave close paths unchanged. Document in docs/更新文档.md.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 12:48:53 +08:00
dekun 195eeae295 Fix options select UI and false contract-missing quotes.
Keep the order host out of tbody wipes, sync pick-button labels, and retry/fallback OKX meta under rate limits so live contracts are not reported as missing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 12:18:41 +08:00
dekun 1f767f16e4 Fix Gate key_focus 500 from invalid Jinja startswith filter.
Use (value|upper).startswith(...) so symbol whitelist select works when default is BTC/USDT.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 12:12:48 +08:00
dekun b057122d71 Fix options order panel vanishing after select.
Park the panel before strike-table rebuilds so soft chain refresh no longer destroys #opt-order-panel with innerHTML.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 12:10:45 +08:00
dekun 95e46ab803 Restyle options target-monitor banner for light mode.
Use a light panel with dark text instead of keeping the dark-theme black bar.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 12:06:01 +08:00
dekun 12c4e55f24 Fix intermittent empty options expiry dropdown after coin select.
Retry instrument fetch, reject empty chains instead of caching them, and ignore stale loadChain races.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 12:04:08 +08:00
dekun b50eebe37c Boost light-mode contrast on options position cards.
Darken labels, hints, and badges so call/put chips and metric text stay readable on white.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 12:00:30 +08:00
dekun 4c7197ad99 Fix options chain headers mixing list and T-view columns.
Thead rows used a .hidden class with no CSS rule on instance pages, so both header sets stayed visible.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 11:57:07 +08:00
dekun f0d5b47f50 Fix options add-on premium to sum all open legs for the contract.
Display, close gate, alerts, and full-close accounting no longer use only the latest fill row.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 11:11:32 +08:00
dekun 4a0b0def1d Center instance login form by fixing broken theme-bar layout.
Move the theme toggle inside body and stack it above the form so flex no longer pushes the card to the right.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 08:49:23 +08:00
dekun 19a4a5194d Use per-exchange PWA names and logos for instance app installs.
Show Binance/OKX/Gate 交易系统 with distinct exchange icons in manifests, apple titles, and login branding.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 08:44:07 +08:00
dekun 717a3d5694 Add cumulative P&L banner to fund overview for at-a-glance profit/loss.
Expose period delta from equity curve start and surface it in the toolbar and summary cards with green/red cues.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 00:19:43 +08:00
dekun 83a7465996 Remove default login credentials from hub login UI.
Stop showing admin/admin123 on the login page and clear the hardcoded username placeholder in settings.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 22:59:14 +08:00
dekun 8838f1f221 Phone hub folds: emergency ops, market toolbar, calc tabs, OKX options.
Collapse bulky monitor/market controls by default on phone, show OKX options on tiles, add calculator tab switch, and request landscape on market fullscreen.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 22:56:02 +08:00
dekun f16dcac202 Tighten phone hub layout: single-column monitor and chart-first market.
Hide duplicate page titles on phone, compact toolbars, and denser calculator forms without changing desktop/tablet shells.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 22:47:09 +08:00
dekun bfb5e22be9 Add phone-only hub shell with four bottom tabs.
Keep desktop/tablet top nav unchanged; at max-width 720px use monitor/market/calculator/AI plus a More sheet for secondary pages.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 22:40:50 +08:00
dekun 0939274113 Fix roll docs page by resolving markdown from repo root.
The /strategy/roll/docs link looked under lib/strategy/ while 顺势加仓滚仓说明.md lives at the repository root.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 22:29:14 +08:00
dekun a21b962bf1 Fix options mark price float junk and target index input rollback.
Skip full card redraw while the monitor target field is focused, and format mark/avg without relying on dusty server strings.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 22:24:52 +08:00
dekun 6f934ecbbf Clarify 2x recycle is a target-close gate, not auto-close.
Rename UI copy from auto-close to target gate so 2x alone is not read as a close trigger.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 22:16:06 +08:00
dekun cbb7f954f5 Auto-cancel stale option close limits after pending TTL.
Default 10m via OKX_OPTIONS_PENDING_TTL_SECONDS; show age/countdown in pending panel; monitor loop cancels sell closes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 22:06:24 +08:00
dekun ee7be3e7f3 Align options realtime PnL with bid-net and show totals in stats.
Header float PnL now uses bid recycle minus premium like position cards. Stats adds realized/open/total net PnL.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 22:00:45 +08:00
dekun 60f3437c73 Rename options close wording to bid1 in hub help.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 21:55:07 +08:00
dekun 1909eea654 Use bid1-only option closes with hard-disabled market exits.
Manual close checks liquidity only; target auto still requires 2x recycle hold once, then reuses the shared bid1 executor. Add /options/guide doc and update hedge-plan refs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 21:49:06 +08:00
dekun ab8b2a74e2 Show cancellable pending option orders beside the order form.
Fetch live OKX option hangs on the right after submit, with refresh and one-click cancel.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 21:22:29 +08:00
dekun c2a0cea3f4 Gate option closes behind 2x recycle sustained for 2 minutes.
Require bid-side recoverable premium at least 2x cost continuously before target auto-close or depth close can fire.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 21:13:43 +08:00
dekun c025c06fac Block option auto-close on stub bids far below mark.
Reject target and depth closes when bid is a residual tick, and show invalid-bid UI instead of recycling at junk prices.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 21:05:54 +08:00
dekun e15eca76f3 Show option net P/L from bid recycle minus premium.
Rename floating P/L to net P/L, align ROI, and display bid depth as price/liquidity for only the levels needed to close.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 20:54:15 +08:00
dekun da3975e42e Fix BTC option prices losing trailing zeros in display.
Integer tick formatting was stripping zeros (1370 -> 137), so hedge-plan quotes looked wrong versus the options list.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 17:12:33 +08:00
dekun 142b6de0f6 Stop repeat WeChat alerts on option target closes.
Commit monitor status before notify, and use a closing state so unfilled limits retry silently instead of re-alerting.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 16:45:43 +08:00
dekun ec30a3999c Fix exchange display names polluted by shared PM2 env.
Require EXCHANGE_DISPLAY_NAME in each instance .env.example and restart with --update-env so Binance/Gate no longer inherit OKX.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 16:30:44 +08:00
dekun 944a211e4a Keep draft target input across position refresh until set.
Polling was re-rendering cards and wiping the field before 设定; drafts and focus are now restored.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 16:10:09 +08:00
dekun 0bedb2e972 Clear target input after set and show estimated value/profit.
Position委托 row keeps the field empty for new entry and displays target value plus estimated PnL after arming.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 16:05:54 +08:00
dekun 61f63c456b Use bid-only limit closes when option index targets hit.
Target price is only for monitoring; auto flat waits for 买一 instead of falling back to mark.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 15:53:08 +08:00
dekun 280e59eb25 Cancel pending option sells before target auto-close.
Prevents duplicate sells from stacking into short opens when the bid book is empty and mark fallback retries.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 15:45:36 +08:00
dekun bcb229fc9d Fix option close reduceOnly flag and use position mark when quote has no bid.
OKX expects reduceOnly as the string true; target auto-close also falls back to the live position mark price on empty books.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 15:43:19 +08:00
dekun cfc1d42c09 Fall back to mark price when option target close has no bid depth.
Keeps auto limit-close workable on thin books instead of stalling after the index target is hit.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 15:37:55 +08:00
dekun d6823a2903 Add options index target monitors that auto limit-close on hit.
Position and order forms can arm a target; right-side and hub panels show active monitors; expiry remains the stop with no separate SL.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 15:27:46 +08:00
dekun 8d2da921ee Stop deploy from overwriting manual FORCE_CLOSE settings.
Apply force-close defaults only when keys are missing so system-settings toggles survive pull_and_restart.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 11:54:31 +08:00
dekun 1e765f4b2b Silence Flask access logs and retain PM2 logs for 3 days.
Stop werkzeug request spam into PM2 error files, truncate oversized logs, and install daily logrotate with 3-day retention.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-15 07:53:19 +08:00
dekun 8ecc70a61c Support dual breakout targets for options-options hedges.
Replace single S* with up/down targets across UI, preview, persist, monitor, and alerts so ranging breakouts can close the winner either way.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 14:32:06 +08:00
dekun f6ef06f659 Add hedge history delete/detail modal and typed stats cards.
History shows contract names with clickable fill details; stats split perp vs options plans for win rate, profit factor, max win/loss, and drawdown.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 14:04:48 +08:00
dekun e6907dfbbe Add hedge-plan WeChat start/end alerts and expiry settlement.
Wire idempotent notify on open/close/partial fail, settle OO at expiry, and close orphaned TP option legs without rewriting plan totals.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 13:23:32 +08:00
dekun 982497d65a Enable hedge-plan live opens with path validation, DB, and monitor.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 13:15:10 +08:00
dekun 5fcf649c79 Move hedge-plan calc actions to second card and add spacing above preview.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 13:05:56 +08:00
dekun 8afaea1ea6 Allow entering sheet counts for each options-options hedge leg.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 12:59:24 +08:00
dekun 9e0d89bd01 Align hedge-plan perp contract precision with exchange and show TP/SL USDT PnL.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 12:49:03 +08:00
dekun 036501b70c Fix hedge-plan option list to 5-row scroll viewport and add auto-deploy rule.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 12:43:23 +08:00
dekun 27f4f5e2ee Make hedge-plan dual cards equal width and height.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 12:38:19 +08:00
dekun 8d37b2cba3 Compact hedge-plan option list to 5 rows with overflow select.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 12:33:30 +08:00
dekun 09cd680e4a Improve hedge-plan option board: moneyness, px/sz, accounts, and denser UI.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 12:27:09 +08:00
dekun 4df2cb4253 Switch hedge-plan modes to high-contrast tabs with history/stats placeholders.
EOF

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 11:29:50 +08:00
dekun 9e17814e37 Prevent env autofill from overwriting OKX API keys when saving hedge settings.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 11:22:28 +08:00
dekun 1fa98425e7 Add OKX hedge-plan P0: env group, preview page, and PnL scenario math.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-14 11:00:15 +08:00
dekun d27ccbea8f Add OKX options hedge strategy guide for manual perp and options pairing.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-13 11:20:03 +08:00
dekun 1bda78ceb2 Fix env save-and-restart by deferring PM2 restart until after HTTP response.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-13 10:54:48 +08:00
dekun c4753ffb89 Fix swap-all balance by reading OKX funding via asset/balances API.
Swap-all targets funding account but ccxt free was often empty; fall back to trading USDT for unified accounts and show balances in errors.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-13 09:01:37 +08:00
dekun c4bac23c48 Parse OKX spot swap errors into friendly Chinese instead of raw JSON.
Map sCode 51008 to a clear insufficient-balance message for the currency exchange UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-13 08:54:53 +08:00
dekun 8e492987ec Stop uninstall from killing unrelated PM2 processes on the server.
Only stop and delete crypto_monitor app names (plus legacy aliases) instead of pm2 stop/delete all.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-12 12:56:08 +08:00
dekun 337a6bc54f Show pip progress bars during deploy instead of silent installs.
Replace -q with --progress-bar so dependency installation visibly continues in setup_env and update flows.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-12 12:42:31 +08:00
dekun 96b5096284 Pull latest deploy scripts when repo exists before showing curl-pipe menu.
Avoids sourcing stale lib/common.sh from an older clone after curl | bash.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-12 12:37:15 +08:00
dekun acb61a413b Fix curl-pipe menu exiting immediately by reading from /dev/tty.
Re-exec manage.sh with terminal stdin after clone or when repo exists, and route all prompts through cm_read.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-12 12:36:34 +08:00
dekun 95895d53b6 Fix manage.sh crash when piped from curl without BASH_SOURCE.
Defer set -u until after safe script-path detection so stdin bootstrap works on fresh servers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-12 12:33:09 +08:00
dekun 58c9f36a75 Add interactive deploy manager with install, uninstall, and update menus.
Provides curl-friendly manage.sh so production servers can bootstrap without a prior clone, then configure API and risk settings in the browser.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-12 12:23:29 +08:00
dekun 44657e0484 Add confirm dialogs and busy states for swap/transfer all actions.
Use available (free) balances for full-amount ops, support sub-account scope, and show clear success/failure feedback.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-12 09:10:29 +08:00
dekun 5eb9b9f5c5 Force-refresh header balances after transfers and balance SSE events.
Invalidate balance caches on mutation, push SSE balance tick, and bypass 60s cache when refreshing funds.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-12 09:03:15 +08:00
dekun bb53beb22d Hide zero USDT in options balance labels and add swap/transfer all buttons.
Skip 0 balances in header display; fill max funding/trading amount on 全部兑换/全部划转.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-12 08:55:30 +08:00
dekun 551c86264a Fix OKX spot swap tgtCcy and show options trading USDT in header.
OKX requires quote_ccy/base_ccy for market orders; include trading_usdt in balance display and total funds.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-12 08:42:33 +08:00
dekun 04fd84757c Improve light theme contrast on options positions panel.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 15:09:02 +08:00
dekun 6f6545ce52 Add T-shaped options chain view with straddle metrics (phase A).
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 15:00:50 +08:00
dekun c9c8388250 Improve options order estimates and chain filter defaults.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 14:37:53 +08:00
dekun 9f0a30a040 Add hub usage help page with settings nav toggle.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 10:02:07 +08:00
dekun 843d87422d Show hub fullscreen options positions as cards matching instance data.
Enrich hub options snapshot with close preview and render read-only option position cards in exchange fullscreen view.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 09:40:35 +08:00
dekun baf94b4feb Compute option stats from exchange history instead of local DB.
Share history loading between history and stats APIs so average profit/loss matches the option history tab.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 09:34:49 +08:00
dekun 68733eb4f9 Show average profit and loss in option stats panel.
Expose avg_win and avg_loss from stats API and update chart labels and values to match the average-based P/L ratio.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 09:29:26 +08:00
dekun bf2d668d3c Fix option history to full closes only, 2-decimal USDC, restore hide-delete.
Filter OKX positions-history to type 2/3/6, format premium and bid recovery to 2 decimals, and allow locally hiding rows via delete button.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 09:24:24 +08:00
dekun fdea5bb610 Align option display precision with OKX and use exchange position history.
Format prices by tickSz, move bid depth/recovery to card end with plain styling, and load option history from OKX positions-history instead of local DB.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 09:14:43 +08:00
dekun 1b31c61aac Simplify option close depth display.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 09:04:17 +08:00
dekun e8a55a0f85 Polish option close depth display.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 08:57:19 +08:00
dekun 6e45604d93 Add depth-based option close flow.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-11 08:46:07 +08:00
dekun 02472f19cb Fix breakeven badge still showing after roll lowers stop loss.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 16:52:29 +08:00
dekun edfe935fb4 Register instance_stats.js static route so period tabs work on all exchanges.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 14:02:24 +08:00
dekun c97cc2823c Fix corrupted embed stats fragment causing 500 and broken period tabs.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 13:57:09 +08:00
dekun 40dbafe851 Fix instance stats week/month tabs not responding after embed preload.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 13:50:25 +08:00
dekun 6aaa328a24 Add tabbed period stats with lightweight charts on instance pages.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 13:27:02 +08:00
dekun 0ce14c8822 Add missing last_alert_message column migration for key_monitors.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 12:54:07 +08:00
dekun dbd8764b0d Fix light-mode system logs readability and add calendar day card frames.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 12:42:51 +08:00
dekun 944673cac1 Improve hub and instance navigation contrast for light and dark themes.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 12:33:54 +08:00
dekun 66d0721c12 Fix archive chart visibility and contrast in light theme.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 12:19:03 +08:00
dekun e4893a6306 Refine archive cumulative PnL chart proportions and axis layout.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 12:14:17 +08:00
dekun 8714bb6fd3 Fix archive.js syntax error that broke the entire archive page.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 12:04:31 +08:00
dekun daf023b403 Improve archive stats chart layout and fix invisible bar colors.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 11:58:27 +08:00
dekun f3af6e2a53 Add collapsible archive stats charts and calendar sections.
Show win rate ring, PnL and sick bars, exchange breakdown, hold-time comparison, and cumulative curve below the stats table; wrap the trading calendar in a foldable panel.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 11:49:09 +08:00
dekun d1ab2d5172 Add options stats holding time metrics and lightweight charts.
Show average hold duration for wins and losses, open positions, and CSS ring/bar visualizations in the stats tab.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 11:32:45 +08:00
dekun 9f255f13dd Add ITM and OTM filter toggles to options chain.
Default to in-the-money view with at-the-money contracts included; update expiry counts and empty states for the active filter.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 11:25:24 +08:00
dekun b70ce510ef Add tabbed layout for options positions card.
Split current positions, stats, and history into tabs to save vertical space and improve readability.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 11:19:33 +08:00
dekun b6d116ec7a Fix options positions API 500 from sync throttle UnboundLocalError.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 18:19:45 +08:00
dekun f99900ac40 Fix intermittent loss of options positions and realtime PnL on refresh.
Use stale-while-revalidate for positions API and UI, throttle sync calls, and avoid overwriting displayed PnL with null on transient failures.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 18:09:58 +08:00
dekun 5a97e14f3e Fix false options close sync, restore bar layout, and show open premium in history.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 17:51:07 +08:00
dekun 08a61fd4ae Tighten options position bar grouping and compact history table status layout.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 17:43:24 +08:00
dekun af7a397816 Fix options position bar layout so Put badge and contract id display on one line.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 17:37:24 +08:00
dekun 3d11b91869 Expand options position card inline below the clicked bar.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 17:06:22 +08:00
dekun ff83f6eebc Refine options position accordion: default collapsed, 2dp PnL, card outside scroll.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 17:00:06 +08:00
dekun f41af0bf1c Improve OKX options sizing, expiry sync, and multi-position accordion UI.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 16:51:48 +08:00
dekun d092f213a7 Fix hub system logs by resolving PM2 log paths from jlist and glob fallback.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 10:38:24 +08:00
dekun 5214794f95 Add hub system logs page with PM2 stdout/stderr tabs for all exchanges.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 10:33:14 +08:00
dekun 9eb10ba771 Align risk policy cards per row with equal-height stretch in 2x2 grid.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 10:21:25 +08:00
dekun db8a9296a7 Fix risk policy layout to 2x2 grid with content-based card heights.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 10:17:15 +08:00
dekun f4361e3eeb Make risk policy cards responsive with auto-fit grid layout.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 10:09:49 +08:00
dekun 23ba725c89 Fix intraday profit amount and hide TP/SL cancel for day trades.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 09:55:09 +08:00
dekun 44546d1a96 chore: enforce LF line endings for docs/
Prevents spurious CRLF diffs when editing documentation on Windows.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 09:34:21 +08:00
dekun d3a44b23db Split journal order type from entry reason and fix review edit toggle in embed shell.
Adds order_type to journal uploads, removes legacy swing/trend labels from entry reason options, and ensures review-edit buttons sync when the records tab loads dynamically.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 09:27:03 +08:00
dekun 4abe8a6ca9 Fix instance settings prefs JS 404 on static route.
Register instance_settings_prefs.js (and options_panel.js) in install_instance_theme_static; add delegated click handlers for embed lazy tabs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 00:07:30 +08:00
dekun f5bdaee886 Fix instance nav display prefs save in embed shell.
Re-bind save button when settings tab loads lazily; scope form lookup to settings pane.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 23:58:06 +08:00
dekun bb0f328f2f Fix hub AI save PM2 restart NameError in hub_env_lib.
Import restart_instances_then_hub_pm2 so background restart after AI env sync actually runs on the server.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 23:48:40 +08:00
dekun b733e551a0 Normalize fullwidth punctuation to ASCII across codebase.
Add scripts/normalize_ambiguous_unicode.py; fix corrupted patch_instance_theme_templates.py. Preserves curly quotes in string literals; removes Git homoglyph warnings on .env.example.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 23:42:26 +08:00
dekun aaa72c7961 Fix hub AI save: background PM2 restart after JSON response.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 23:06:31 +08:00
dekun 823aeda42a Add hub AI config tab with sync to instances and deploy secret bootstrap.
Wire bootstrap_deploy_secrets into setup_env.sh (one-time HUB_BRIDGE_TOKEN, FLASK_SECRET_KEY, HUB_SESSION_SECRET). Remove AI section from instance env UI; hub saves OPENAI settings to all four .env files. SSO unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 22:50:58 +08:00
dekun 886f7740f2 Remove redundant reload toolbar from hub settings page.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 22:17:06 +08:00
dekun 79962d2cf3 Remove redundant Save All button from hub settings page.
Each settings tab already has its own save action; keep reload only.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 22:07:41 +08:00
dekun 88f7f0cfca Add hub settings tabs and account password change UI.
Restructure manual-trading-hub settings with CSS tabs matching instance layout; add password API writing HUB_USERNAME/HUB_PASSWORD to hub .env.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 22:01:26 +08:00
dekun d339971c26 Fix env config UI to show runtime defaults when keys are missing from .env.
Account risk fields now match the risk policy page; uncomment RISK_* defaults in .env.example.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 21:54:47 +08:00
dekun 2e0bde9cc2 Fix settings 500: pop display before building instance settings view.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 21:50:31 +08:00
dekun 1ee9eb02c3 Add settings page tabs and show env API keys with last four digits.
System settings now use the same CSS tab layout as env config; sensitive env fields display masked values from .env while keeping save-on-empty behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 21:31:14 +08:00
dekun 12e44ab26d Fix env config tabs with CSS radio labels, no JS required
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 21:19:23 +08:00
dekun 4b3373a68d Fix env config tab clicks via document event delegation
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 21:14:42 +08:00
dekun 576f6fbcfc Redesign env config UI: tabs, 2-col form, remove per-field badges
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 21:10:54 +08:00
dekun 0d2ce9c126 Add curated env config UI with Chinese labels and deploy secret bootstrap
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 21:03:00 +08:00
dekun 0b91d26f71 Fix Jinja conflict: rename display meta items to entries
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 20:38:52 +08:00
dekun 68e03ccd97 Fix settings tab 500 and env config grouping in UI
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 20:33:31 +08:00
dekun aa966114b1 Fix settings and env config stuck on loading via SSR form render
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 20:24:15 +08:00
dekun 6975da8575 Fix settings loading and use 2-column card layout.
Merge Flask GET/POST routes, refresh prefs on tab revisit after preload, and reorganize system settings into separate cards.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 20:12:22 +08:00
dekun ef4b2f17ca Add instance nav prefs, env config UI, and PM2 restart.
P1-P4: configurable nav/section visibility in system settings, full .env editor with restart badges, password change, runtime hot overrides, and single-instance pm2 restart. Works in hub embed iframe.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 20:07:06 +08:00
dekun d84a265b67 Split risk policy into its own navigation tab.
Move read-only risk control docs to /risk_policy before settings; keep transfers and exports on the settings page.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 19:42:29 +08:00
dekun fd6391b734 Remove manual refresh funds button from header.
Account snapshot already refreshes automatically on load, interval, and tab switch.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 19:18:44 +08:00
dekun 0d27e13275 Fix header funds flicker and unify settings page top bar.
Preserve SSR fund values when account_snapshot returns null, retry on failure, and show the same instance header panel on system settings.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 19:08:08 +08:00
dekun 279648de56 Add hub TP profit field, 2-decimal options PnL, and exchange mark price display.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 17:22:26 +08:00
dekun e3e53ff7f5 Fix roll position display: live contracts, TP profit, and 2-decimal qty precision.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 17:06:33 +08:00
dekun 5ef6affabf Show initial and current roll position size plus rolling status on active roll groups table.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 16:45:32 +08:00
dekun f5f302b97e Add month/quarter/half-year/all list window presets with this month as default.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 11:22:29 +08:00
dekun 189b27e076 Add live expiry countdown for options positions on instance page and trading hub.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 11:14:30 +08:00
dekun f68197b775 Include options unrealized PnL in OKX instance header realtime PnL total.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 11:05:52 +08:00
dekun 75a64c5d24 Show premium paid on options position card and parse strike/type from instId when OKX omits them.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 10:40:07 +08:00
dekun 43fa1ad1f3 Show OTM options in chain even when ticker has no quotes.
Stop skipping contracts with empty ask, bid, and mark so out-of-the-money strikes remain visible in the list.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 07:28:11 +08:00
dekun 7f225c7407 Estimate missing option ask from mark or intrinsic on chain list.
Deep ITM contracts often have no ask on the book; show mark-based estimates with a tilde and restore breakeven calculations.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 17:50:25 +08:00
dekun 25879dd007 Show equivalent contract leverage on options order panel.
Display notional-over-premium leverage at current index and at the user target price for quick sizing comparison.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 16:58:25 +08:00
dekun 27921213b0 Add expiry profit estimate and remove chain quick-buy button.
Let users enter a target index in the order panel for estimated expiry P&L, and remove the redundant buy button from the options chain row.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 16:46:21 +08:00
dekun 2cfc1a490f Show bid/ask liquidity as price per sheet in options chain.
Display OKX askSz and bidSz beside top-of-book prices in the chain table and order panel using price/sheets format.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 16:28:08 +08:00
dekun 99f13817f8 Add pre-buy expiry breakeven columns to options chain table.
Show estimated expiry balance and distance from index in the chain list and order panel using ask price before opening a position.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 16:21:22 +08:00
dekun 3570a6900e Add OKX options expiry and close breakeven to hub monitor and dashboard.
Expose bePx-based expiry balance and mark-to-close breakeven on positions so monitor and dashboard can show both labels per contract.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 16:10:03 +08:00
dekun 7bbb5663c9 Dashboard OKX card: 3-column perpetual/options split when options enabled.
Show perpetual and options funding metrics separately, total funds row, then positions; other exchanges keep the 2-column layout.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 15:22:11 +08:00
dekun 9027708a61 Fix monitor stats bar: full-width strip with centered cell text.
Revert whole-card centering; keep compact height and text-align center inside each stat mini-card.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 13:42:45 +08:00
dekun 299b20acc5 Hub monitor: compact centered today stats bar in options split layout.
Reduce stats card height and center the horizontal bar above the OKX / Binance-Gate columns.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 13:36:48 +08:00
dekun dda022d3c3 Hub monitor: OKX left column with dual inner cards when options enabled.
Use a stats bar plus left OKX / right Binance+Gate split layout with equal-height inner perpetual and options cards and no in-card scrolling.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 13:33:13 +08:00
dekun 5e66600727 Hub monitor card: split perpetual and options blocks when options enabled.
Show matching stat rows and position sections for each account type; keep the standard single-block layout for exchanges without options.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 13:17:48 +08:00
dekun 4a3afdfb48 Fix monitor board crash: avoid shadowing options_open_position_count helper.
Rename the imported counter function so aggregate_monitor_board_totals no longer overwrites it with an int accumulator.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 13:09:39 +08:00
dekun 3163912266 Hub funds and dashboard: include OKX options balances in USDT totals.
Merge options USDC/USDT at 1:1 into fund overview snapshots, dashboard aggregation, and monitor board totals while keeping a separate options breakdown in the UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 13:06:01 +08:00
dekun 6cc3382526 Hub monitor: read-only OKX options positions aggregation (Phase B).
Expose /api/hub/options/snapshot from OKX instance and render options summary on hub monitor cards when the options capability is enabled.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 12:55:35 +08:00
dekun 11a50c02cd fix(theme): improve light mode contrast across instance and options pages
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 12:23:22 +08:00
dekun afb191f90a fix(theme): show toggle on standalone embed shell, not only hub iframe
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 12:18:18 +08:00
dekun b29c54f126 fix(settings): restore theme toggle on OKX settings page
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 12:14:46 +08:00
dekun 68d8a97db5 fix(settings): equal columns, form-style option transfers, compact export
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 12:09:12 +08:00
dekun 27a00f026a fix(settings): OKX side panel shell, compact option transfers without selects
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 11:43:56 +08:00
dekun 6c26d4739e fix(settings): horizontal export links and strict OKX side column height
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 11:35:36 +08:00
dekun 5680ab515e fix: stretch settings side cards to match left column height
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 11:29:14 +08:00
dekun 6571fc9029 fix: enable threaded Flask on binance/gate for SSE embed live push
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 11:24:17 +08:00
dekun 2ad9e049f3 fix(okx): cache options balances and stop SSE from hammering exchange API
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 11:15:06 +08:00
dekun 799a4d6b8b fix: enable threaded Flask for SSE and make embed tab switch instant
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 11:09:34 +08:00
dekun 3db84d07e3 feat: instance embed SSE live push and lighter tab revisit
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 11:01:10 +08:00
dekun 444088baf3 fix: reduce embed tab flash with persistent pane show/hide
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:53:42 +08:00
dekun 86188e6611 fix: import urlencode from urllib.parse in embed redirect
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:48:38 +08:00
dekun 30e40dc34c perf: embed shell soft nav, tab cache, and lighter options page boot
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:42:01 +08:00
dekun 8913138dc3 style: tighten options page typography and spacing
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:35:00 +08:00
dekun 2d52bfac80 feat: options stats profit/loss totals and history delete
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:31:09 +08:00
dekun 5fdfc67438 fix: use isolated margin for OKX option buys (error 51019)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:24:33 +08:00
dekun 2a3f36d34f feat: split options settings into compact swap and transfer cards with aligned columns
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:18:41 +08:00
dekun 75aa4b1391 feat: single-row funds strip on header and system settings page
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:09:51 +08:00
dekun e82fd15bb7 feat: options UI scroll layout, stats card, funding balance, and cross-account transfer
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 09:57:13 +08:00
dekun 090b9c6215 feat: restructure OKX options UI with header funds, settings card, and dual-column layout
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 09:36:00 +08:00
dekun 38f6bc240e fix: inline options order panel below selected row with clear active states
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 09:16:04 +08:00
dekun c1647822fb feat: options sheet sizing, ITM/OTM labels, and 14-day chain view
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 09:06:45 +08:00
dekun d6d1ac5818 fix: import _safe_float at module level for options close route
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 09:00:26 +08:00
dekun e1c14977e6 fix: OKX option quote requires instFamily with instId
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 08:58:31 +08:00
dekun 05586242f0 fix: OKX options buy/close orders with tick alignment and reduceOnly
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 08:52:18 +08:00
dekun ae0c44e20d fix: always show OKX options nav tab and allow options page without redirect
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 08:33:23 +08:00
dekun 806bb074ab feat: add OKX options module with dual API, USDT/USDC convert, and docs
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 08:17:27 +08:00
dekun 814fe67a21 feat: expand header stats with total funds and profit-loss ratio
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 02:14:18 +08:00
dekun 659c0969fe fix: show header realtime PnL from exchange positions and order metrics
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 02:04:40 +08:00
dekun 3b494932c7 feat: settings risk sections as 2x2 nested subcards
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 01:58:06 +08:00
dekun fc6f85e76c fix: taller centered stats strip with larger exchange and trade count
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 01:52:50 +08:00
dekun 65594c28bd fix: move status badges to right with theme and add nav spacing
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 01:49:18 +08:00
dekun a1096155b8 fix: unify instance header panel layout for toolbar and stats
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 01:44:45 +08:00
dekun 6547029a89 feat: compact instance toolbar, stats strip and settings two-column layout
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 01:37:19 +08:00
dekun d87081205d feat: instance system settings page with risk docs, export and transfer
顶栏新增系统设置;风控说明读取 .env;数据导出与资金划转迁入三张卡片;顶栏移除导出条与手动划转。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 01:26:38 +08:00
dekun d7fa596e68 feat: auto sick tag in archive from journal mood issues
内照明心同步时匹配实例复盘情绪标签,自动标注犯病并锁定标签;中控不再手动选犯病。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 01:12:47 +08:00
dekun 2a3d264c8f fix: allow force-close in trade review and hide strategy nav for intraday
统计核对结果允许强制清仓;日内户顶栏隐藏策略交易与策略交易记录。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 01:01:57 +08:00
dekun 6745262412 fix: intraday journal entry type limited to four options
日内复盘开仓类型仅保留假破、结构突破、回调触价、突破触价;移除旧趋势长句与策略项。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 00:55:35 +08:00
dekun 5a0d18cf99 feat: add force-close exit trigger and round journal real RR to 2dp
复盘离场触发增加强制清仓;填入复盘与自动计算实际盈亏比保留两位小数。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 00:40:55 +08:00
dekun 1092816359 feat: review entry reason picker uses dropdown instead of prompt
Add modal select for trade record review, expand options to two-level labels (反转/启动A), and accept legacy short labels on save.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 00:38:16 +08:00
dekun f580e4542d feat: show entry type as category/subtype (反转/启动A)
Format持仓与交易记录开仓类型为两级展示;新平仓写入与旧短标签自动展开。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 00:27:53 +08:00
dekun 99eb16dbd8 fix: Gate force-close badge and classify midnight closes correctly
Narrow executing window to 15 minutes after the hour, show countdown when flat, run force_close before reconcile, and map 00:00 synced closes to 强制清仓 instead of 手动平仓.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 00:23:40 +08:00
dekun d520ba6904 fix: OKX manual orders save entry_model for trade record 开仓类型
OKX add_order omitted entry_model on insert; align with Binance/Gate and add trade_style fallback when resolving entry_reason for close and display.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 00:15:22 +08:00
dekun d3753f1aee Fix Gate price_snapshot 500: define FUNDS_DECIMALS
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 22:27:58 +08:00
dekun 8e1492e4f0 Fix mark/PnL display fallback and intraday entry labels
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 22:19:42 +08:00
dekun d4a76f05d2 Fix Gate mark/PnL/TP-SL snapshot and intraday order UI
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 22:04:19 +08:00
dekun 5e4f885f80 fix: loosen divergence scan list layout with card-style rows
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 20:08:51 +08:00
dekun e62a3f3351 feat: market divergence scan tabs (4h/1d/1w) with Top20 MACD confluence colors
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 19:58:30 +08:00
dekun 81f7a7c451 fix: entry model sub-select linkage via DOM options and event delegation
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 19:08:11 +08:00
dekun ff1bcd69d2 feat: two-level entry model UI for trend accounts (reversal/trend/swing)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 19:02:18 +08:00
dekun eb6788091d docs: OKX reversal launch A/B strategy v0.4 with short mirror
Align OKX strategy MD and checklist with binance v0.4; document long reversal and mirrored short rules.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 18:50:04 +08:00
dekun 96ab7e997c docs: binance reversal launch A/B strategy v0.4 draft
Document MACD divergence, reference-high two-touch rules, launch A (A1/A2) and B; update hub checklist. UI implementation still pending.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 18:44:17 +08:00
dekun 43cd98f2d5 feat: add EMA144 as separate market chart indicator
Optional EMA144 line on hub K-line main chart, independent from EMA 21/55 cross.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 03:32:26 +08:00
dekun 22b2db34fc feat: MD-style popup print for strategy doc and checklist
Open clean white document in new tab with auto print dialog instead of printing the dark hub page.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 03:28:44 +08:00
dekun 0d5b20c0db feat: strategy page scroll layout, OKX standalone docs, split print
Right checklist drives card height with left doc scroll; rewrite OKX strategy MD and checklist as standalone; add per-column print buttons.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 03:25:56 +08:00
dekun a4cd966370 fix: align strategy page card heights and inner padding
Equal-height two-column cards with flex layout; add card padding and spacing so content is not flush to edges.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 03:17:12 +08:00
dekun 7223b54ec4 feat: add hub strategy docs page with MD and checklists
Central /strategy page shows per-exchange strategy markdown and read-only entry checklists; nav toggle in settings, print and HTML export per tab.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 03:12:09 +08:00
dekun 8b069294b7 refactor: unify three-exchange instance UI with shared templates
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 02:43:24 +08:00
dekun df99eb5fb5 chore: gate-only force-close policy and deploy pull script
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 02:32:35 +08:00
dekun 3c0c62997f chore: align binance/okx env examples with gate and add sync script
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 02:31:06 +08:00
dekun 4904a86e03 fix: hide hub close/entrust controls for intraday discipline profile
Expose intraday_discipline via hub meta and block manual close/tpsl APIs; Gate instance card no longer shows 全平/平仓/委托.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 02:26:22 +08:00
dekun a268a93027 feat: show force-close badge and countdown when FORCE_CLOSE is enabled
Add shared lib/UI for midnight force-close indicator on instance and hub pages, and document Gate intraday 0-point exit alignment.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 02:17:47 +08:00
dekun 7fb87d6030 fix: improve journal form layout for tablet with proportional field widths
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 00:59:45 +08:00
dekun fa9e6be36d feat: show entry type in trade records, remove journal custom entry reason
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 00:49:21 +08:00
dekun 5137d5ed17 fix: remove inline estimated TP preview from fixed RR order form
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 00:40:16 +08:00
dekun e526d6af76 fix: 注册 order_entry_model.js 静态路由,embed 内联联动逻辑
中控 iframe 下 JS 404 导致小分歧/杠杆不更新;boot 脚本内联兜底。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 00:34:26 +08:00
dekun e81343ae91 fix: 小分歧联动波段单显示,杠杆改为按币种默认只读
option 增加 data-trade-style;修复 JS 初始化顺序。杠杆隐藏输入,显示 BTC/ETH 10x 其它 5x。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 00:28:10 +08:00
dekun ea429b2694 feat: 趋势户开仓类型大分歧A/B/小分歧,自动联动趋势波段与复盘
下单监控增加 entry_model 下拉;平仓写入短标签并预填复盘。Binance/OKX 用趋势 profile,Gate 日内仍用手选 trade_style。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 00:18:38 +08:00
dekun 21894334f8 feat: KEY_AUTO_ORDER_ENABLED 三所统一开关,联动关键位自动单与开仓类型
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 23:39:06 +08:00
dekun f688a504e1 ui: 复盘表单紧凑布局、即时上传截图并移除占用时新开仓
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 22:46:05 +08:00
dekun 7bb6ee1154 remove: 全面移除「错过机会」功能与文案
删除手动记录表单与 /add_miss;停止自动生成错过类交易记录;列表/统计/顶栏不再展示;复盘卡片改为整行。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 22:21:30 +08:00
dekun 88fe4bbe56 feat: 复盘四周期手动上传,移除 AI 识别预填
固定 5m/15m/1h/4h 四槽截图上传与详情四宫格展示;自动 K 线默认关闭且与手动上传互斥。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 21:57:41 +08:00
dekun eec57610dc fix: 注册 symbol_live_price.js 静态路由(现价不显示)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 00:46:23 +08:00
dekun 3a740235ac feat: 币种输入旁实时显示交易所现价
Shared SymbolLivePrice polls /api/order_defaults on input with debounce; wired to trade, key monitor, trend, and key focus forms.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 00:42:44 +08:00
dekun efe7a57e60 fix: trade_policy 宏使用 with context 修复 500
Jinja imported macros did not receive trade_policy from render context, causing Internal Server Error on all instance pages.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 00:36:06 +08:00
dekun c0ad50a7b5 feat: 账户方向与币种白名单 env 开关(三所)
Per-instance TRADE_DIRECTION / TRADE_SYMBOL_WHITELIST restricts UI and API for manual orders, key monitors, and strategies; includes sync script for deployment profiles.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-05 00:30:49 +08:00
dekun 65b911994c fix: 今日统计数字改用常规字体,去掉发光效果
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-04 23:16:22 +08:00
dekun 9deb58a38a feat: 监控区 2x2 布局与左上今日统计卡
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-04 23:10:32 +08:00
dekun eb975b0133 fix: 交易安全审计修复 — 补偿平仓、中控同步、滚仓/趋势防护
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-04 22:44:16 +08:00
dekun df28e6dfb8 fix: ccxt Gate 类名 gateio 改为兼容 gate
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-04 22:21:33 +08:00
dekun 4923b32bbe feat: 新增 Plan B 整目录重装脚本,不影响 setup_env 一键安装
添加 deploy/reinstall.sh 备份 env、克隆、调 setup_env、恢复配置并 PM2 启动;
附带 pm2_start_all.sh 与 hub_settings 清理工具。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-04 22:07:59 +08:00
dekun 9f67de3677 refactor: 移除 gate_bot,统一为三所架构并更新文档
删除 crypto_monitor_gate_bot 目录,中控与子代理改为 binance/okx/gate 三账户;
文档与 UI 文案「四所」改为「三所」;新增清库前一次性配置备份脚本。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-04 22:00:08 +08:00
620 changed files with 137118 additions and 92271 deletions
+2
View File
@@ -1,5 +1,7 @@
# Shell 脚本在仓库内统一 LF,避免 Linux 上 bash: pipefail: invalid option nameCRLF
*.sh text eol=lf
deploy/** text eol=lf
# 文档统一 LF,避免 Windows 编辑后产生 CRLF 脏 diff
docs/** text eol=lf
# .env 模板统一 LF,避免 Linux PM2 source 报 $'\r': command not found
**/.env.example text eol=lf
+6
View File
@@ -15,14 +15,20 @@
**/.env.backup*
**/.env.bak
**/.env.local
# Cursor 本机规则/配置(勿提交;只留本地)
.cursor/
manual_trading_hub/hub_settings.json
manual_trading_hub/hub_backup_state.json
manual_trading_hub/hub_fund_history.json
manual_trading_hub/hub_supervisor_state.json
manual_trading_hub/hub_ai_summaries.json
manual_trading_hub/hub_ai_chat.json
manual_trading_hub/amp_stats_history.json
manual_trading_hub/hub_ai_fund_history.json
manual_trading_hub/data/
backups/
# 数据库与上传(运行时生成)
**/*.sqlite
+23 -23
View File
@@ -1,66 +1,66 @@
# AI 复盘与模型配置说明
`crypto_monitor_*` 实例共用仓库根目录 **`ai_client.py`**通过 `PYTHONPATH=..` 导入)。用于 **交易记录与复盘** 页的 AI 点评短评建议以及从复盘截图提取结构化 JSON
`crypto_monitor_*` 实例共用仓库根目录 **`ai_client.py`**(通过 `PYTHONPATH=..` 导入).用于 **交易记录与复盘** 页的 AI 点评,短评建议,以及从复盘截图提取结构化 JSON.
---
## 一二选一`AI_PROVIDER`
## 一,二选一:`AI_PROVIDER`
| 值 | 说明 |
|----|------|
| **`openai`**默认 | OpenAI 兼容 **Chat Completions** 接口 |
| **`ollama`** | 本机 Ollama **`/api/generate`**流式 NDJSON |
| **`openai`**(默认) | OpenAI 兼容 **Chat Completions** 接口 |
| **`ollama`** | 本机 Ollama **`/api/generate`**(流式 NDJSON) |
在对应子目录 **`.env`** 中设置各所 `.env.example` 已含模板):
在对应子目录 **`.env`** 中设置(各所 `.env.example` 已含模板):
```bash
AI_PROVIDER=openai
AI_TIMEOUT_SECONDS=120
# OpenAI 兼容网关默认
# OpenAI 兼容网关(默认)
OPENAI_API_BASE=https://op.bz121.com/v1
OPENAI_API_KEY=你的密钥
OPENAI_MODEL=gemma4:e4b
# 本机 Ollama仅当 AI_PROVIDER=ollama
# 本机 Ollama(仅当 AI_PROVIDER=ollama)
OLLAMA_API=http://127.0.0.1:11434/api/generate
AI_MODEL=huihui_ai/deepseek-r1-abliterated:latest
```
### OpenAI 兼容网关
- **Base URL**`https://op.bz121.com/v1`请求路径为 `{base}/chat/completions`)。
- **API Key**在 [op.bz121.com](https://op.bz121.com/) 登录后**`gateway.json`** 页面复制与网关账号一致)。
- **默认模型**`gemma4:e4b`可通过 `OPENAI_MODEL` 覆盖)。
- **Base URL**:`https://op.bz121.com/v1`(请求路径为 `{base}/chat/completions`).
- **API Key**:在 [op.bz121.com](https://op.bz121.com/) 登录后,**`gateway.json`** 页面复制(与网关账号一致).
- **默认模型**:`gemma4:e4b`(可通过 `OPENAI_MODEL` 覆盖).
### Ollama
- 需本机已安装并拉取对应模型`AI_PROVIDER=ollama` 时使用 `OLLAMA_API``AI_MODEL`
- `app.py` **不再** 直连 Ollama统一走 `ai_client.ai_generate` / `ai_review` / `ai_short_advice`
- 需本机已安装并拉取对应模型;`AI_PROVIDER=ollama` 时使用 `OLLAMA_API``AI_MODEL`.
- `app.py` **不再** 直连 Ollama;统一走 `ai_client.ai_generate` / `ai_review` / `ai_short_advice`.
---
## 二部署注意
## 二,部署注意
1. **PM2 / 手工启动**`ecosystem.config.cjs`**`PYTHONPATH=..`** 必须包含仓库根否则无法 `from ai_client import ...`
2. 修改 `.env` 后重启对应实例例如`pm2 restart crypto_binance`名称以你机器为准)。
3. **`git pull`** 不会改 `.env``.env.example` 新增 AI 变量请手动补进本机 `.env`
4. **勿** 将含真实 `OPENAI_API_KEY``.env` 提交 Git
1. **PM2 / 手工启动**:`ecosystem.config.cjs`**`PYTHONPATH=..`** 必须包含仓库根,否则无法 `from ai_client import ...`.
2. 修改 `.env` 后重启对应实例,例如:`pm2 restart crypto_binance`(名称以你机器为准).
3. **`git pull`** 不会改 `.env`;`.env.example` 新增 AI 变量,请手动补进本机 `.env`.
4. **勿** 将含真实 `OPENAI_API_KEY``.env` 提交 Git.
---
## 三功能入口网页
## 三,功能入口(网页)
登录后进入 **「交易记录与复盘」**
登录后进入 **「交易记录与复盘」**:
- 单条记录 **AI 复盘** / **短评**依赖上述配置)。
- 上传复盘图后 **从图片提取** 字段内部调用 `ai_generate`与所选 provider 一致)。
- 单条记录 **AI 复盘** / **短评**(依赖上述配置).
- 上传复盘图后 **从图片提取** 字段(内部调用 `ai_generate`,与所选 provider 一致).
若请求超时或返回错误请检查密钥是否有效网关是否可达`AI_TIMEOUT_SECONDS` 是否过短Ollama 是否已启动仅 ollama 模式)。
若请求超时或返回错误,请检查:密钥是否有效,网关是否可达,`AI_TIMEOUT_SECONDS` 是否过短,Ollama 是否已启动(仅 ollama 模式).
---
## 四相关文件
## 四,相关文件
| 路径 | 说明 |
|------|------|
+91 -88
View File
@@ -1,88 +1,91 @@
# 复盘交易系统crypto_monitor
多交易所 **USDT 永续** 的下单监控**关键位****策略交易****止盈止损 / 移动保本** 与 **AI 复盘**,四所独立部署 + 可选 **中控** 聚合监控
**远程仓库**[https://git.bz121.com/dekun/crypto_monitor.git](https://git.bz121.com/dekun/crypto_monitor.git)
---
## 部署环境必读
| 项 | 约定 |
|----|------|
| 系统 | **Ubuntu 22.04 / 24.04** |
| 用户 | **root** |
| 路径 | **`/opt/crypto_monitor`** |
| 进程 | **PM2**唯一推荐的常驻方式 |
**环境详解**Python 3.10+NodePM2 安装与启动顺序):**[docs/ubuntu-server.md](./docs/ubuntu-server.md)**
**一键 venv**`bash deploy/setup_env.sh`**[deploy/README.md](./deploy/README.md)**
```bash
cd /opt
git clone https://git.bz121.com/dekun/crypto_monitor.git crypto_monitor
cd /opt/crypto_monitor
bash deploy/setup_env.sh --install-system-deps
```
配置与运维脚本: **[docs/env-sync-scripts.md](./docs/env-sync-scripts.md)** · **[备份与恢复.md](./备份与恢复.md)**
---
## 功能导航
| 功能 | 说明 | 文档 |
|------|------|------|
| **关键位监控** | 箱体/收敛自动开仓、阻力支撑提醒、斐波限价;止盈止损方案与 **移动保本** 开关 | 各所 [关键位自动下单说明.md](./crypto_monitor_binance/关键位自动下单说明.md)(Gate/OKX 目录内同名);方案细则 **[关键位止盈止损与移动保本更新说明.md](./关键位止盈止损与移动保本更新说明.md)** |
| **实盘下单 / 下单监控** | 首仓、以损定仓;监控内 **止盈 / 止损**、**移动保本**(步进 R、偏移%) | 各所 [使用说明.md](./crypto_monitor_binance/使用说明.md) · 顶栏「实盘下单」`/trade` |
| **策略交易** | **趋势回调** + **顺势加仓**`/strategy` 双栏) | **[策略交易说明.md](./策略交易说明.md)** · 趋势细则 [crypto_monitor_gate_bot/趋势回调策略说明.md](./crypto_monitor_gate_bot/趋势回调策略说明.md) |
| **策略交易记录** | 已结束计划快照(最近 100 条)、筛选与展开详情 | [策略交易说明.md §五](./策略交易说明.md) · 顶栏 `/strategy/records` |
| **交易复盘** | 平仓记录、错过机会、图表;**AI 点评** | **[AI复盘与模型配置说明.md](./AI复盘与模型配置说明.md)** · 顶栏「交易记录与复盘」`/records` |
| **中控** | 多账户持仓/委托聚合、行情 K 线、紧急全平(**不在中控网页下单**) | [manual_trading_hub/使用说明.md](./manual_trading_hub/使用说明.md) · [部署文档.md](./manual_trading_hub/部署文档.md) |
其它专题:[计仓模式](./docs/position-sizing-mode.md) · [每日自动划转](./docs/auto-transfer-daily.md) · [Chrome 快捷方式图标](./docs/shortcut-icon.md)
---
## 仓库目录
| 目录 | 交易所 / 角色 | 部署文档 |
|------|----------------|----------|
| `crypto_monitor_binance/` | Binance U 本位永续 | [部署文档.md](./crypto_monitor_binance/部署文档.md) |
| `crypto_monitor_gate/` | Gate 主号 | [部署文档.md](./crypto_monitor_gate/部署文档.md) |
| `crypto_monitor_gate_bot/` | Gate 机器人 / 趋势户 | [部署文档.md](./crypto_monitor_gate_bot/部署文档.md) |
| `crypto_monitor_okx/` | OKX 永续 | [部署文档.md](./crypto_monitor_okx/部署文档.md) |
| `manual_trading_hub/` | 中控 + 子代理 | [部署文档.md](./manual_trading_hub/部署文档.md) |
| `lib/` | **共用模块**(策略、关键位、交易、中控库、AI、静态与模板) | **[docs/lib-structure.md](./docs/lib-structure.md)** |
| `brand/` | 各所共用图标与 manifest | — |
| `docs/``deploy/``scripts/``tests/` | 文档、环境、脚本、单元测试 | — |
共用代码 import 示例:`from lib.strategy.strategy_db import init_strategy_tables`(各所启动时仍将仓库根加入 `PYTHONPATH`)。详见 **[docs/lib-structure.md](./docs/lib-structure.md)**。
---
## 技术要点
- **Python 3.10+**、Flask、ccxt、SQLite`crypto.db`
- 四所 `.env` 前缀不同(`BINANCE_*` / `GATE_*` / `OKX_*`),**不可混用**
- 实盘须 `LIVE_TRADING_ENABLED=true` 且理解 API 权限与 IP 白名单风险
- **SOCKS** 访问交易所时配置各所 `*_SOCKS_PROXY` 并安装 PySocks
---
## 推荐阅读顺序
1. [docs/ubuntu-server.md](./docs/ubuntu-server.md) — 装 Python / Node / PM2PM2 启动四所 + 中控
2. 各所 **`.env`**(从 `.env.example` 复制)
3. 所用功能对应上表 **功能导航** 文档
4. [备份与恢复.md](./备份与恢复.md) — 生产机备份习惯
---
## 安全
- **勿** 将 `.env`、API Secret、`.pem` 提交 Git
- 公网暴露中控须配置登录、`HUB_BRIDGE_TOKEN`、HTTPS Cookie
- 实盘风险由使用者自行承担
若子目录 README 与本文冲突,以 **子目录《部署文档》与当前代码** 为准。
# 复盘交易系统(crypto_monitor)
多交易所 **USDT 永续** 的下单监控,**关键位**,**策略交易**,**止盈止损 / 移动保本** 与 **AI 复盘**,三所独立部署 + 可选 **中控** 聚合监控.
**远程仓库**:[https://git.bz121.com/dekun/crypto_monitor.git](https://git.bz121.com/dekun/crypto_monitor.git)
---
## 部署环境(必读)
| 项 | 约定 |
|----|------|
| 系统 | **Ubuntu 22.04 / 24.04** |
| 用户 | **root** |
| 路径 | **`/opt/crypto_monitor`** |
| 进程 | **PM2**(唯一推荐的常驻方式) |
**环境详解**(Python 3.10+,Node,PM2 安装与启动顺序):**[docs/ubuntu-server.md](./docs/ubuntu-server.md)**
**一键部署管理器**:`curl -fsSL .../deploy/manage.sh | bash`**[deploy/README.md](./deploy/README.md)**
```bash
# 新服务器(推荐)
curl -fsSL https://git.bz121.com/dekun/crypto_monitor/raw/branch/main/deploy/manage.sh | bash
# 或手动 clone
cd /opt
git clone https://git.bz121.com/dekun/crypto_monitor.git crypto_monitor
cd /opt/crypto_monitor
bash deploy/manage.sh
```
配置与运维脚本: **[docs/env-sync-scripts.md](./docs/env-sync-scripts.md)** · **[备份与恢复.md](./备份与恢复.md)**
---
## 功能导航
| 功能 | 说明 | 文档 |
|------|------|------|
| **关键位监控** | 箱体/收敛自动开仓,阻力支撑提醒,斐波限价;止盈止损方案与 **移动保本** 开关 | 各所 [关键位自动下单说明.md](./crypto_monitor_binance/关键位自动下单说明.md)(Gate/OKX 目录内同名);方案细则 **[关键位止盈止损与移动保本更新说明.md](./关键位止盈止损与移动保本更新说明.md)** |
| **实盘下单 / 下单监控** | 首仓,以损定仓;监控内 **止盈 / 止损**,**移动保本**(步进 R,偏移%) | 各所 [使用说明.md](./crypto_monitor_binance/使用说明.md) · 顶栏「实盘下单」`/trade` |
| **策略交易** | **趋势回调** + **顺势加仓**(`/strategy` 双栏) | **[策略交易说明.md](./策略交易说明.md)** · 趋势细则 [docs/trend-pullback-strategy.md](./docs/trend-pullback-strategy.md) |
| **策略交易记录** | 已结束计划快照(最近 100 条),筛选与展开详情 | [策略交易说明.md §五](./策略交易说明.md) · 顶栏 `/strategy/records` |
| **交易复盘** | 平仓记录,错过机会,图表;**AI 点评** | **[AI复盘与模型配置说明.md](./AI复盘与模型配置说明.md)** · 顶栏「交易记录与复盘」`/records` |
| **中控** | 多账户持仓/委托聚合,行情 K 线,紧急全平(**不在中控网页下单**) | [manual_trading_hub/使用说明.md](./manual_trading_hub/使用说明.md) · [部署文档.md](./manual_trading_hub/部署文档.md) |
其它专题:[计仓模式](./docs/position-sizing-mode.md) · [每日自动划转](./docs/auto-transfer-daily.md) · [Chrome 快捷方式图标](./docs/shortcut-icon.md)
---
## 仓库目录
| 目录 | 交易所 / 角色 | 部署文档 |
|------|----------------|----------|
| `crypto_monitor_binance/` | Binance U 本位永续 | [部署文档.md](./crypto_monitor_binance/部署文档.md) |
| `crypto_monitor_gate/` | Gate | [部署文档.md](./crypto_monitor_gate/部署文档.md) |
| `crypto_monitor_okx/` | OKX 永续 | [部署文档.md](./crypto_monitor_okx/部署文档.md) |
| `manual_trading_hub/` | 中控 + 子代理 | [部署文档.md](./manual_trading_hub/部署文档.md) |
| `lib/` | **共用模块**(策略,关键位,交易,中控库,AI,静态与模板) | **[docs/lib-structure.md](./docs/lib-structure.md)** |
| `brand/` | 各所共用图标与 manifest | — |
| `docs/`,`deploy/`,`scripts/`,`tests/` | 文档,环境,脚本,单元测试 | — |
共用代码 import 示例:`from lib.strategy.strategy_db import init_strategy_tables`(各所启动时仍将仓库根加入 `PYTHONPATH`).详见 **[docs/lib-structure.md](./docs/lib-structure.md)**.
---
## 技术要点
- **Python 3.10+**,Flask,ccxt,SQLite(`crypto.db`)
- 三所 `.env` 前缀不同(`BINANCE_*` / `GATE_*` / `OKX_*`),**不可混用**
- 实盘须 `LIVE_TRADING_ENABLED=true` 且理解 API 权限与 IP 白名单风险
-**SOCKS** 访问交易所时配置各所 `*_SOCKS_PROXY` 并安装 PySocks
---
## 推荐阅读顺序
1. [docs/ubuntu-server.md](./docs/ubuntu-server.md) — 装 Python / Node / PM2,PM2 启动三所 + 中控
2. 各所 **`.env`**(从 `.env.example` 复制)
3. 所用功能对应上表 **功能导航** 文档
4. [备份与恢复.md](./备份与恢复.md) — 生产机备份习惯
---
## 安全
- **勿** 将 `.env`,API Secret,`.pem` 提交 Git
- 公网暴露中控须配置登录,`HUB_BRIDGE_TOKEN`,HTTPS Cookie
- 实盘风险由使用者自行承担
若子目录 README 与本文冲突,以 **子目录《部署文档》与当前代码** 为准.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

+6
View File
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<rect width="512" height="512" rx="108" fill="#0c1019"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="#141b2d"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="none" stroke="#F0B90B" stroke-width="12"/>
<polygon points="256,150 362,256 256,362 150,256" fill="#F0B90B"/><polygon points="256,210 302,256 256,302 210,256" fill="#1a160a"/>
</svg>

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

+6
View File
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<rect width="512" height="512" rx="108" fill="#0c1019"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="#141b2d"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="none" stroke="#17E6A1" stroke-width="12"/>
<text x="256" y="310" text-anchor="middle" font-family="Arial, Helvetica, sans-serif" font-size="220" font-weight="700" fill="#17E6A1">G</text>
</svg>

After

Width:  |  Height:  |  Size: 451 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

+6
View File
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<rect width="512" height="512" rx="108" fill="#0c1019"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="#141b2d"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="none" stroke="#FFFFFF" stroke-width="12"/>
<rect x="168" y="168" width="72" height="72" rx="10" fill="#FFFFFF"/><rect x="272" y="168" width="72" height="72" rx="10" fill="#FFFFFF"/><rect x="168" y="272" width="72" height="72" rx="10" fill="#FFFFFF"/>
</svg>

After

Width:  |  Height:  |  Size: 515 B

+23
View File
@@ -0,0 +1,23 @@
{
"name": "Binance 交易系统",
"short_name": "Binance 交易系统",
"description": "Binance 永续交易监控与复盘",
"start_url": "/",
"display": "standalone",
"background_color": "#0b0d14",
"theme_color": "#F0B90B",
"icons": [
{
"src": "__ICON_PREFIX__/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "__ICON_PREFIX__/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "交易监控复盘",
"short_name": "监控",
"description": "加密货币永续交易监控与复盘",
"name": "交易系统",
"short_name": "交易系统",
"description": "加密货币永续交易监控与复盘(请使用各所独立 manifest)",
"start_url": "/",
"display": "standalone",
"background_color": "#0b0d14",
+23
View File
@@ -0,0 +1,23 @@
{
"name": "Gate 交易系统",
"short_name": "Gate 交易系统",
"description": "Gate 永续交易监控与复盘",
"start_url": "/",
"display": "standalone",
"background_color": "#0b0d14",
"theme_color": "#17E6A1",
"icons": [
{
"src": "__ICON_PREFIX__/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "__ICON_PREFIX__/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}
@@ -1,20 +1,20 @@
{
"name": "交易监控复盘",
"short_name": "监控",
"description": "加密货币永续交易监控与复盘",
"name": "OKX 交易系统",
"short_name": "OKX 交易系统",
"description": "OKX 永续交易监控与复盘",
"start_url": "/",
"display": "standalone",
"background_color": "#0b0d14",
"theme_color": "#0b0d14",
"theme_color": "#FFFFFF",
"icons": [
{
"src": "/static/icons/icon-192.png",
"src": "__ICON_PREFIX__/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "/static/icons/icon-512.png",
"src": "__ICON_PREFIX__/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
+23 -23
View File
@@ -1,23 +1,23 @@
{
"name": "复盘系统中控",
"short_name": "中控",
"description": "所交易监控与行情中控",
"start_url": "/monitor",
"display": "standalone",
"background_color": "#0b0e18",
"theme_color": "#0b0e18",
"icons": [
{
"src": "__ICON_PREFIX__/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "__ICON_PREFIX__/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}
{
"name": "复盘系统中控",
"short_name": "中控",
"description": "所交易监控与行情中控",
"start_url": "/monitor",
"display": "standalone",
"background_color": "#0b0e18",
"theme_color": "#0b0e18",
"icons": [
{
"src": "__ICON_PREFIX__/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "__ICON_PREFIX__/icon-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any maskable"
}
]
}
+106 -77
View File
@@ -1,206 +1,235 @@
# =============================================================================
# 环境配置模板可提交 Git)。程序运行时只读取同目录下的 .env
# 环境配置模板(可提交 Git).程序运行时只读取同目录下的 .env.
#
# 首次部署 / 新机
# 首次部署 / 新机:
# cp .env.example .env
# nano .env # 填入真实密钥端口代理等
# nano .env # 填入真实密钥,端口,代理等
#
# 升级代码git pull前建议备份.env 不在 Git 中pull 不会覆盖):
# 升级代码(git pull)前建议备份(.env 不在 Git 中,pull 不会覆盖):
# cp .env .env.backup.$(date +%Y%m%d)
#
# 从备份恢复
# 从备份恢复:
# cp .env.backup.YYYYMMDD .env
# =============================================================================
APP_ENV=production
# 服务监听地址云服务器通常用 0.0.0.0
# 服务监听地址(云服务器通常用 0.0.0.0)
APP_HOST=0.0.0.0
# 服务端口
APP_PORT=5001
# 是否开启调试模式生产建议 false
# 是否开启调试模式(生产建议 false)
APP_DEBUG=false
# 登录账号
APP_USERNAME=admin
# 登录密码请改成你自己的强密码
# 登录密码(请改成你自己的强密码)
APP_PASSWORD=admin123
# 是否关闭登录校验局域网可设 true公网务必 false
# 是否关闭登录校验(局域网可设 true;公网务必 false)
APP_AUTH_DISABLED=true
# --- 多账户交易中控 manual_trading_hub ---
# 中控请求本实例 /api/hub/* 时携带请求头 X-Hub-Token须与中控启动环境变量 HUB_BRIDGE_TOKEN 一致
# 未设置且 APP_AUTH_DISABLED=false 时仅网页登录后可访问本机联调可保持 APP_AUTH_DISABLED=true
# 中控请求本实例 /api/hub/* 时携带请求头 X-Hub-Token,须与中控启动环境变量 HUB_BRIDGE_TOKEN 一致
# 未设置且 APP_AUTH_DISABLED=false 时,仅网页登录后可访问;本机联调可保持 APP_AUTH_DISABLED=true
# HUB_BRIDGE_TOKEN=your-long-random-token
# Flask 会话密钥必须替换为长随机字符串
# Flask 会话密钥(必须替换为长随机字符串)
FLASK_SECRET_KEY=CHANGE_TO_LONG_RANDOM_SECRET
# 企业微信机器人 Webhook用于行情/风控推送
# 企业微信机器人 Webhook(用于行情/风控推送)
WECHAT_WEBHOOK=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=REPLACE_WITH_REAL_KEY
# 数据库文件路径相对路径会自动按项目目录解析
# 数据库文件路径(相对路径会自动按项目目录解析)
DB_PATH=crypto.db
# 交易截图上传目录
UPLOAD_DIR=static/images
# 自动备份scripts/backup_data.sh + cron可选默认即可
# 自动备份(scripts/backup_data.sh + cron,可选;默认即可)
# BACKUP_ROOT=/root/backups
# BACKUP_RETENTION_DAYS=30
# BACKUP_INSTANCE=crypto_monitor_binance
# 已废弃资金账户仅显示交易所 funding 余额不再读取此变量
# 已废弃:资金账户仅显示交易所 funding 余额,不再读取此变量
# TOTAL_CAPITAL=100
# 页顶「资金账户」默认仅 Binance Funding 钱包若 USDT 主要在现货可改为 true 合并 Spot
# 页顶「资金账户」默认仅 Binance Funding 钱包;若 USDT 主要在现货,可改为 true 合并 Spot
# BINANCE_FUNDING_INCLUDE_SPOT=false
# 计仓risk=以损定仓默认);full_margin=合约可用×FULL_MARGIN_BUFFER_RATIO 全仓杠杆须无仓后重启
# 计仓:risk=以损定仓(默认);full_margin=合约可用×FULL_MARGIN_BUFFER_RATIO 全仓杠杆(须无仓后重启)
POSITION_SIZING_MODE=risk
# 每天起始基数(U
# 方向限制(默认 false=双向均可;true 时按 TRADE_DIRECTION 限制,修改后须重启)
# TRADE_DIRECTION=long_only | short_only | both(或 多/空/双向)
TRADE_DIRECTION_RESTRICT_ENABLED=false
TRADE_DIRECTION=both
# 币种白名单(默认 false=全币种可手输;true 时关键位/下单/策略仅下拉选择)
TRADE_SYMBOL_RESTRICT_ENABLED=false
TRADE_SYMBOL_WHITELIST=BTC,ETH
# 每天起始基数(U)
DAILY_START_CAPITAL=30
# 日内回撤后基数U
# 日内回撤后基数(U)
DAILY_LOSS_CAPITAL=20
# 日内盈利后基数U
# 日内盈利后基数(U)
DAILY_PROFIT_CAPITAL=50
# BTC 默认杠杆倍数
BTC_LEVERAGE=10
# 山寨币默认杠杆倍数
ALT_LEVERAGE=5
# 交易日重置小时北京时间
# 交易日重置小时(北京时间)
TRADING_DAY_RESET_HOUR=8
# 整点前禁止新开仓true=启用默认),false=关闭仍可保留 8 点作为交易日划分
# 整点前禁止新开仓:true=启用(默认),false=关闭(仍可保留 8 点作为交易日划分)
TRADING_DAY_RESET_OPEN_GUARD_ENABLED=true
# 是否开启 Binance 实盘下单false=只做本地流程true=真实下单
# 是否开启 Binance 实盘下单(false=只做本地流程,true=真实下单)
LIVE_TRADING_ENABLED=true
# Binance API Key需开通合约万向划转等权限
# Binance API Key(需开通合约,万向划转等权限)
BINANCE_API_KEY=REPLACE_WITH_BINANCE_API_KEY
# Binance API Secret
BINANCE_API_SECRET=REPLACE_WITH_BINANCE_API_SECRET
# 保证金模式cross=全仓isolated=逐仓
# 保证金模式:cross=全仓,isolated=逐仓
BINANCE_MARGIN_MODE=cross
# 持仓模式hedge=双向需账户开启双向持仓下单带 positionSide);oneway=单向
# 持仓模式:hedge=双向(需账户开启双向持仓,下单带 positionSide);oneway=单向
BINANCE_POSITION_MODE=hedge
# 条件单触发参考价CONTRACT_PRICE=最新成交价 MARK_PRICE=标记价更易触发时用标记价
# 条件单触发参考价:CONTRACT_PRICE=最新成交价 MARK_PRICE=标记价(更易触发时用标记价)
BINANCE_TRIGGER_WORKING_TYPE=CONTRACT_PRICE
# 页面与浏览器标签展示的交易所名称多环境区分时可改成例如 Binance·测试网
# EXCHANGE_DISPLAY_NAME=Binance
# 页面与浏览器标签展示的交易所名称(多环境区分时可改成例如 Binance·测试网)
EXCHANGE_DISPLAY_NAME=Binance
# 企业微信推送里展示的账户备注
# BINANCE_ACCOUNT_LABEL=binance实盘账户
# 平仓盈亏估算false=按仓位历史口径已实现盈亏+手续费不含资金费);true=含资金费
# 平仓盈亏估算:false=按仓位历史口径(已实现盈亏+手续费,不含资金费);true=含资金费
# BINANCE_PNL_INCLUDE_FUNDING=false
# =============================================================================
# 关键位门控(页面「关键位监控」规则条与 _key_hard_checks 共用)
# 关键位程序自动下单(与 POSITION_SIZING_MODE 联动,修改后须重启 PM2)
# =============================================================================
# 【周期】门控 K 线周期,如 5m、15m;仅影响关键位硬条件,不改变顶栏分区
# 默认 false = 关闭所有关键位程序自动单(箱体/收敛/斐波/假突破/触价)
#
# POSITION_SIZING_MODE=risk(以损定仓)
# false → 不执行任何关键位自动单;支撑/阻力提醒,人工下单,顺势加仓不受影响
# true → 允许关键位全套自动(含触价)
#
# POSITION_SIZING_MODE=full_margin(全仓杠杆,须无仓切换)
# false → 不执行触价自动单
# true → 仅回调/突破触价可程序自动开仓;箱体/斐波等仍禁止
#
# 顺势加仓,趋势回调不受本开关控制;全仓模式下策略自动仍禁止.
KEY_AUTO_ORDER_ENABLED=false
# =============================================================================
# 关键位门控(页面「关键位监控」规则条与 _key_hard_checks 共用)
# =============================================================================
# 【周期】门控 K 线周期,如 5m,15m;仅影响关键位硬条件,不改变顶栏分区
KLINE_TIMEFRAME=5m
# 【确认K】闭合 K 序列中的棒偏移突破棒默认 -2倒数第2根),确认棒默认 -1倒数第1根
# 【确认K】闭合 K 序列中的棒偏移:突破棒默认 -2(倒数第2根),确认棒默认 -1(倒数第1根)
KEY_CONFIRM_BREAKOUT_BAR=-2
KEY_CONFIRM_BAR=-1
# 【量能】突破棒成交量 > 前 N 根均量 × 倍数默认 N=20倍数=1.3 即放大 30%
# 【量能】突破棒成交量 > 前 N 根均量 × 倍数(默认 N=20,倍数=1.3 即放大 30%)
KEY_VOLUME_MA_BARS=20
KEY_VOLUME_RATIO_MIN=1.3
# 【箱体/收敛】突破K收盘越过关键位占该侧价格%的下限无上限过猛由计划RR过滤
# 【箱体/收敛】突破K收盘越过关键位(占该侧价格%)的下限;无上限(过猛由计划RR过滤)
KEY_BREAKOUT_AMP_MIN_PCT=0.03
# 已不参与门控可保留配置项兼容旧环境
# 已不参与门控,可保留配置项兼容旧环境
KEY_BREAKOUT_AMP_MAX_PCT=0.5
# 【阻力/支撑】突破后微信提醒次数与间隔分钟
# 【阻力/支撑】突破后微信提醒次数与间隔(分钟)
KEY_ALERT_MAX_TIMES=3
KEY_ALERT_INTERVAL_MINUTES=5
# 【日成交量排名】品种须在该排名前 N 名添加关键位与运行时门控均校验
# 【日成交量排名】品种须在该排名前 N 名(添加关键位与运行时门控均校验)
KEY_DAILY_VOLUME_RANK_MAX=30
# 【关键位自动开仓盈亏比】按确认K收盘 E 计算严格大于该值才市价开仓如 1.5 表示须 >1.5:1
# 【关键位自动开仓盈亏比】按确认K收盘 E 计算,严格大于该值才市价开仓(如 1.5 表示须 >1.5:1)
KEY_AUTO_MIN_PLANNED_RR=1.5
# 止损突破 K 极值向外缓冲的百分比默认 0.5 即 0.5%
# 止损:突破 K 极值向外缓冲的百分比(默认 0.5 即 0.5%)
KEY_STOP_OUTSIDE_BREAKOUT_PCT=0.5
# 趋势单方案止损在突破 K 极值外侧的百分比默认 1 即 1%
# 趋势单方案:止损在突破 K 极值外侧的百分比(默认 1 即 1%)
KEY_TREND_STOP_OUTSIDE_PCT=1
# =============================================================================
# 交易执行 / 人工风控页面「实盘下单」
# 交易执行 / 人工风控(页面「实盘下单」)
# =============================================================================
# 【最大同时持仓】active 订单数达到该值后禁止人工与关键位自动再加仓默认 1=单仓
# 【最大同时持仓】active 订单数达到该值后禁止人工与关键位自动再加仓(默认 1=单仓)
MAX_ACTIVE_POSITIONS=1
# 【人工下单最低盈亏比】按当前价与 SL/TP 计算低于该值前后端均拒绝默认 1.4即须 >=1.4:1
# 【人工下单最低盈亏比】按当前价与 SL/TP 计算,低于该值前后端均拒绝(默认 1.4,即须 >=1.4:1)
MANUAL_MIN_PLANNED_RR=1.4
# 【关键位连开计仓】true=已有持仓时关键位自动单仍按「无仓时」资金快照算保证金基数
KEY_SIZING_USE_ZERO_POSITION_SNAPSHOT=true
# 【单日开仓 AI 提醒】本交易日开仓达到该次数时推送企业微信 AI 克制提醒不拦单
# 【单日开仓 AI 提醒】本交易日开仓达到该次数时推送企业微信 AI 克制提醒(不拦单)
DAILY_OPEN_ALERT_THRESHOLD=5
# 【单日开仓硬上限】本交易日开仓次数>=该值后禁止一切新开仓直至下一交易日北京时间 TRADING_DAY_RESET_HOUR 切日);0=不启用
# 【单日开仓硬上限】本交易日开仓次数>=该值后禁止一切新开仓直至下一交易日(北京时间 TRADING_DAY_RESET_HOUR 切日);0=不启用
DAILY_OPEN_HARD_LIMIT=0
# =============================================================================
# 账户冷静期 / 日冻结风控手动平仓外部平仓复盘情绪标签
# 账户冷静期 / 日冻结风控(手动平仓,外部平仓,复盘情绪标签)
# 详见 docs/account-risk-cooldown.md
# =============================================================================
# RISK_CONTROL_ENABLED=true
# RISK_COOLING_HOURS_MANUAL=4
# RISK_COOLING_HOURS_MANUAL_JOURNAL=1
# RISK_MANUAL_CLOSE_DAILY_LIMIT=2
# RISK_MOOD_ISSUES_DAILY_FREEZE=true
RISK_CONTROL_ENABLED=true
RISK_COOLING_HOURS_MANUAL=4
RISK_COOLING_HOURS_MANUAL_JOURNAL=1
RISK_MANUAL_CLOSE_DAILY_LIMIT=2
# 日亏损次数上限:平仓盈亏<0 计1次;达限当日冻结开仓;0=不启用
RISK_DAILY_LOSS_LIMIT=2
RISK_MOOD_ISSUES_DAILY_FREEZE=true
# 资金与仓位刷新周期(秒)
# 资金与仓位刷新周期(秒)
BALANCE_REFRESH_SECONDS=60
# 前端价格快照轮询(秒)
# 前端价格快照轮询(秒)
PRICE_REFRESH_SECONDS=5
# 后台监控轮询周期(秒)
# 后台监控轮询周期(秒)
MONITOR_POLL_SECONDS=3
# 使用可用资金时的缓冲比例(如0.98代表用98%)
# 重启后多少秒内不做「外部平仓」同步(避免 API 未就绪误判)
RECONCILE_STARTUP_GRACE_SEC=90
# 连续多少次轮询确认交易所空仓后,才记为外部平仓(默认 3 次 ≈ 9 秒)
RECONCILE_FLAT_CONFIRM_POLLS=3
# 使用可用资金时的缓冲比例(如0.98代表用98%)
FULL_MARGIN_BUFFER_RATIO=0.98
# =============================================================================
# 自动划转页顶「将 swap 补足到 XU」与 DAILY_START_CAPITAL 独立需一致时请设为相同值
# 自动划转(页顶「将 swap 补足到 XU」;与 DAILY_START_CAPITAL 独立,需一致时请设为相同值)
# =============================================================================
AUTO_TRANSFER_ENABLED=false
# 交易账户(swap)目标余额 U每日 8 点(北京)自动划入或划出至 funding持仓中不划转
# 交易账户(swap)目标余额 U:每日 8 点(北京)自动划入或划出至 funding;持仓中不划转
AUTO_TRANSFER_AMOUNT=30
AUTO_TRANSFER_FROM=funding
AUTO_TRANSFER_TO=swap
TRANSFER_CCY=USDT
# 北京时间该整点小时内尝试账簿按 UTC 自然日去重
# 北京时间该整点小时内尝试;账簿按 UTC 自然日去重
AUTO_TRANSFER_BJ_HOUR=8
# 强制清仓整点北京时间默认 0=凌晨00点
# 强制清仓整点(北京时间,默认 0=凌晨00点)
FORCE_CLOSE_BJ_HOUR=0
# 是否启用强制清仓默认关闭true 才会在整点执行
# 是否启用强制清仓(默认关闭,true 才会在整点执行)
FORCE_CLOSE_ENABLED=false
# 推送与AI超时(秒)
# 推送与AI超时(秒)
WECHAT_TIMEOUT_SECONDS=10
AI_TIMEOUT_SECONDS=120
# AI 提供方openai默认OpenAI 兼容网关| ollama本机 Ollama
# AI 提供方:openai(默认,OpenAI 兼容网关)| ollama(本机 Ollama)
AI_PROVIDER=openai
# OpenAI 兼容接口示例https://op.bz121.com/v1 账号见 gateway.json
# OpenAI 兼容接口(示例:https://op.bz121.com/v1 ,账号见 gateway.json)
OPENAI_API_BASE=https://op.bz121.com/v1
OPENAI_API_KEY=你的密钥
OPENAI_MODEL=gemma4:e4b
# 本机 OllamaAI_PROVIDER=ollama 时使用
# 本机 Ollama(AI_PROVIDER=ollama 时使用)
OLLAMA_API=http://127.0.0.1:11434/api/generate
AI_MODEL=huihui_ai/deepseek-r1-abliterated:latest
# Binance 代理可选):本机网络不稳定时通过 SSH 动态转发 SOCKS5 出口
# 1) 先在本机建立隧道示例):
# Binance 代理(可选):本机网络不稳定时通过 SSH 动态转发 SOCKS5 出口
# 1) 先在本机建立隧道(示例):
# ssh -N -D 127.0.0.1:1080 user@vps -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes
# 2) 再启用下面这一行推荐 socks5h让远端解析域名):
# 2) 再启用下面这一行(推荐 socks5h,让远端解析域名):
# BINANCE_SOCKS_PROXY=socks5h://127.0.0.1:1080
#
# 如你更偏向 HTTP 代理VPS 上跑 tinyproxy 之类),可用
# 如你更偏向 HTTP 代理(VPS 上跑 tinyproxy 之类),可用:
# BINANCE_HTTP_PROXY=http://127.0.0.1:3128
# BINANCE_HTTPS_PROXY=http://127.0.0.1:3128
# 开仓多周期K线图可选
# 开仓多周期K线图(可选)
# ORDER_CHART_ENABLED=true
# ORDER_CHART_TFS=4h,1h,15m,5m
# ORDER_CHART_LIMIT=100
# ORDER_CHART_DIR=static/images/order_charts
# 详见上文 DAILY_OPEN_ALERT_THRESHOLD / DAILY_OPEN_HARD_LIMIT说明文档 docs/daily-open-limit.md
# 以损定仓按交易账户资金的百分比
# 详见上文 DAILY_OPEN_ALERT_THRESHOLD / DAILY_OPEN_HARD_LIMIT;说明文档 docs/daily-open-limit.md
# 以损定仓(按交易账户资金的百分比)
# RISK_PERCENT=2
# 移动保本触发达到多少R触发与偏移百分比
# 移动保本触发(达到多少R触发)与偏移(百分比)
# BREAKEVEN_RR_TRIGGER=1.0
# 移动保本阶梯每多少R继续上移一次默认1R
# 移动保本阶梯(每多少R继续上移一次,默认1R)
# BREAKEVEN_STEP_R=1.0
# BREAKEVEN_OFFSET_PCT=0.02
# 开单风格默认值trend / swing
# 开单风格默认值:trend / swing
# DEFAULT_TRADE_STYLE=trend
APP_TIMEZONE=Asia/Shanghai
# TRADING_DAY_RESET_HOUR 现在表示「北京时间」整点默认 8 点起算新交易日开仓整点限制见 TRADING_DAY_RESET_OPEN_GUARD_ENABLED
# TRADING_DAY_RESET_HOUR 现在表示「北京时间」整点,默认 8 点起算新交易日;开仓整点限制见 TRADING_DAY_RESET_OPEN_GUARD_ENABLED
+31 -31
View File
@@ -1,22 +1,22 @@
# crypto_monitor_binance
基于 **Flask** 的加密货币 **下单监控 / 关键位监控 / 交易复盘** 小系统行情与实盘接口统一走 **BinanceUSDT-M 永续**通过 **ccxt** 访问
基于 **Flask** 的加密货币 **下单监控 / 关键位监控 / 交易复盘** 小系统,行情与实盘接口统一走 **Binance(USDT-M 永续)**,通过 **ccxt** 访问.
## 功能概要
- **关键位监控**价格与硬条件校验企业微信推送可选
- **下单监控**本地风控含移动保本逻辑)、触达止盈/止损后尝试市价平仓并记账
- **策略交易**顶栏 `/strategy`趋势回调 + 顺势加仓),见仓库根 [策略交易说明.md](../策略交易说明.md)
- **AI 复盘**OpenAI 兼容网关默认或 Ollama见 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)
- **实盘可选**`LIVE_TRADING_ENABLED=true` 且配置 `BINANCE_API_KEY` / `BINANCE_API_SECRET`支持合约开仓平仓余额读取与内部划转依赖 API 权限
- **止盈止损Binance**市价成交后挂 **`STOP_MARKET`**止损)、**`TAKE_PROFIT_MARKET`**止盈);双向持仓带 `positionSide`不显式传 `reduceOnly`避免 API `-1106`)。触发参考价由 `BINANCE_TRIGGER_WORKING_TYPE` 控制最新价 / 标记价
- **关键位监控**:价格与硬条件校验,企业微信推送(可选)
- **下单监控**:本地风控(含移动保本逻辑),触达止盈/止损后尝试市价平仓并记账
- **策略交易**:顶栏 `/strategy`(趋势回调 + 顺势加仓),见仓库根 [策略交易说明.md](../策略交易说明.md)
- **AI 复盘**:OpenAI 兼容网关(默认)或 Ollama,见 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)
- **实盘(可选)**:`LIVE_TRADING_ENABLED=true` 且配置 `BINANCE_API_KEY` / `BINANCE_API_SECRET`,支持合约开仓,平仓,余额读取与内部划转(依赖 API 权限)
- **止盈止损(Binance)**:市价成交后挂 **`STOP_MARKET`**(止损),**`TAKE_PROFIT_MARKET`**(止盈);双向持仓带 `positionSide`;不显式传 `reduceOnly`(避免 API `-1106`).触发参考价由 `BINANCE_TRIGGER_WORKING_TYPE` 控制(最新价 / 标记价)
## 环境要求
- Python 3.10+建议
- 依赖`flask``requests``ccxt``werkzeug``Pillow`K 线图可选);经 SOCKS 代理时需 **`PySocks`**
- Python 3.10+(建议)
- 依赖:`flask`,`requests`,`ccxt`,`werkzeug`,`Pillow`(K 线图可选);经 SOCKS 代理时需 **`PySocks`**
安装示例
安装示例:
```bash
# 推荐在 /opt/crypto_monitor 执行仓库根目录 deploy/setup_env.sh
@@ -25,31 +25,31 @@ source .venv/bin/activate
pip install -r ../requirements.txt
```
页面上的 **「当日资金(交易账户)」** 与 **「可开仓」可用 U** 仅统计 **Binance U 本位永续合约账户**`fetch_balance``swap` / FAPI `assets` 中的 USDT),**不会**再用现货余额顶替
页面上的 **「当日资金(交易账户)」** 与 **「可开仓」可用 U** 仅统计 **Binance U 本位永续合约账户**(`fetch_balance``swap` / FAPI `assets` 中的 USDT),**不会**再用现货余额顶替.
## 配置说明`.env.example` → `.env`
## 配置说明(`.env.example` → `.env`)
- **`.env.example`**模板可提交 Git);首次`cp .env.example .env` 后编辑
- **`.env`**本机真实配置勿提交);`app.py` 只读此文件`git pull` 不覆盖 `.env`升级前可 `cp .env .env.backup.$(date +%Y%m%d)`
- **`.env.example`**:模板(可提交 Git);首次:`cp .env.example .env` 后编辑.
- **`.env`**:本机真实配置(勿提交);`app.py` 只读此文件.`git pull` 不覆盖 `.env`;升级前可 `cp .env .env.backup.$(date +%Y%m%d)`.
与 Binance 相关的常用变量
与 Binance 相关的常用变量:
| 变量 | 说明 |
|------|------|
| `BINANCE_API_KEY` / `BINANCE_API_SECRET` | 币安 API需合约等权限 |
| `LIVE_TRADING_ENABLED` | `true` 时允许真实下单`false` 仅本地逻辑 |
| `BINANCE_API_KEY` / `BINANCE_API_SECRET` | 币安 API(需合约等权限) |
| `LIVE_TRADING_ENABLED` | `true` 时允许真实下单;`false` 仅本地逻辑 |
| `BINANCE_MARGIN_MODE` | `cross` 全仓 / `isolated` 逐仓 |
| `BINANCE_POSITION_MODE` | `hedge` 双向需账户开启双向持仓/ `oneway` 单向 |
| `BINANCE_TRIGGER_WORKING_TYPE` | `CONTRACT_PRICE``MARK_PRICE`条件单触发参考 |
| `BINANCE_SOCKS_PROXY` / `BINANCE_HTTP_PROXY` | 可选代理与部署文档一致 |
| `EXCHANGE_DISPLAY_NAME` | 页面展示的交易所名称默认 `Binance` |
| `BINANCE_POSITION_MODE` | `hedge` 双向(需账户开启双向持仓)/ `oneway` 单向 |
| `BINANCE_TRIGGER_WORKING_TYPE` | `CONTRACT_PRICE``MARK_PRICE`(条件单触发参考) |
| `BINANCE_SOCKS_PROXY` / `BINANCE_HTTP_PROXY` | 可选代理(与部署文档一致) |
| `EXCHANGE_DISPLAY_NAME` | 页面展示的交易所名称,默认 `Binance` |
| `BINANCE_ACCOUNT_LABEL` | 推送文案中的账户备注 |
其余变量登录企业微信风控参数**`AI_PROVIDER` / `OPENAI_*` / `OLLAMA_*`**数据库路径等**`.env.example` 内注释** 或 `app.py` 顶部默认值
其余变量(登录,企业微信,风控参数,**`AI_PROVIDER` / `OPENAI_*` / `OLLAMA_*`**,数据库路径等)**`.env.example` 内注释** 或 `app.py` 顶部默认值.
## 运行
生产环境使用 **PM2**`ecosystem.config.cjs`)。临时调试
生产环境使用 **PM2**(`ecosystem.config.cjs`).临时调试:
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
@@ -57,13 +57,13 @@ source .venv/bin/activate
python app.py
```
环境说明见 [docs/ubuntu-server.md](../docs/ubuntu-server.md)
环境说明见 [docs/ubuntu-server.md](../docs/ubuntu-server.md).
默认监听端口由 `.env``APP_PORT` 决定未设置时多为 `5000`)。
默认监听端口由 `.env``APP_PORT` 决定(未设置时多为 `5000`).
## 部署Linux / PM2 / SSH SOCKS
## 部署(Linux / PM2 / SSH SOCKS)
详见 **[部署文档.md](./部署文档.md)**Ubuntu + PM2 + 可选 SOCKS 访问 Binance)。
详见 **[部署文档.md](./部署文档.md)**(Ubuntu + PM2 + 可选 SOCKS 访问 Binance).
## 自检脚本
@@ -71,13 +71,13 @@ python app.py
python scripts/verify_binance_funding.py
```
用于核对 Key 前缀不含 Secret并尝试读取资金钱包 / 合约钱包 USDT需网络与 API 权限)。
用于核对 Key 前缀(不含 Secret)并尝试读取资金钱包 / 合约钱包 USDT(需网络与 API 权限).
## 数据与脚本
- 默认 SQLite`crypto.db`路径由 `DB_PATH` 指定
- `scripts/fix_breakeven_labels.py`批量修正「止损」但盈亏为正的记录标签见部署文档附录
- 默认 SQLite:`crypto.db`(路径由 `DB_PATH` 指定)
- `scripts/fix_breakeven_labels.py`:批量修正「止损」但盈亏为正的记录标签(见部署文档附录)
## 风险与合规
实盘交易有亏损风险请自行确认 API 权限IP 白名单杠杆与保证金模式与币安账户设置一致并遵守当地法律法规与 Binance 用户协议
实盘交易有亏损风险.请自行确认 API 权限,IP 白名单,杠杆与保证金模式与币安账户设置一致,并遵守当地法律法规与 Binance 用户协议.
+10124 -9710
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -1,14 +1,14 @@
/**
* PM2 进程定义Ubuntu / Linux)。
* PM2 进程定义(Ubuntu / Linux).
*
* 仅托管 Flask 应用**SSH SOCKS 隧道**用 `ssh -D` 常驻可用 tmux / autossh),勿交给 PM2
* 与 `.env` 里 `BINANCE_SOCKS_PROXY` 端口一致即可不必交给 PM2
* 仅托管 Flask 应用.**SSH SOCKS 隧道**用 `ssh -D` 常驻(可用 tmux / autossh),勿交给 PM2.
* 与 `.env` 里 `BINANCE_SOCKS_PROXY` 端口一致即可;不必交给 PM2.
*
* 使用前项目根目录存在 `.venv`且已安装依赖走 SOCKS 时需 PySocks)。
* 使用前:项目根目录存在 `.venv`,且已安装依赖(走 SOCKS 时需 PySocks).
*
* 启动
* 启动:
* pm2 start ecosystem.config.cjs
* 保存开机列表
* 保存开机列表:
* pm2 save && pm2 startup
*/
const path = require("path");
@@ -1,18 +1,18 @@
#!/usr/bin/env python3
"""
一次性修复历史交易记录标签
将 trade_records 里“止损但实际盈利”的记录改为“保本止盈”
一次性修复历史交易记录标签:
将 trade_records 里“止损但实际盈利”的记录改为“保本止盈”.
默认条件可通过参数修改):
默认条件(可通过参数修改):
- monitor_type = 下单监控
- result = 止损
- pnl_amount > 0
用法示例
1) 仅预览不落库):
用法示例:
1) 仅预览(不落库):
python scripts/fix_breakeven_labels.py --db ./crypto.db --dry-run
2) 执行修复
2) 执行修复:
python scripts/fix_breakeven_labels.py --db ./crypto.db --apply
"""
@@ -115,15 +115,15 @@ def build_section(order_loop: str) -> str:
{{% endif %}}
</{t}>
<{t} class="rule-tip" id="order-rule-tip">
规则最多 {{{{ max_active_positions }}}}BTC {{{{ btc_leverage }}}}x / 山寨 {{{{ alt_leverage }}}}x
{{% if can_trade %}}可开仓{{% else %}}不可开仓持仓已满或未到北京时间 {{{{ reset_hour }}}}:00{{% endif %}}
规则:最多 {{{{ max_active_positions }}}};BTC {{{{ btc_leverage }}}}x / 山寨 {{{{ alt_leverage }}}}x;
{{% if can_trade %}}可开仓{{% else %}}不可开仓(持仓已满或未到北京时间 {{{{ reset_hour }}}}:00){{% endif %}};
人工开仓盈亏比不得低于 {{{{ manual_min_planned_rr }}}}:1
</{t}>
<{t} class="rule-tip">
以损定仓风险 {{{{ risk_percent }}}}% |移动保本下单可勾选关闭开启时 {{{{ breakeven_rr_trigger }}}}R 触发每 1R 阶梯上移),偏移 {{{{ breakeven_offset_pct }}}}%
以损定仓:风险 {{{{ risk_percent }}}}% |移动保本:下单可勾选关闭;开启时 {{{{ breakeven_rr_trigger }}}}R 触发(每 1R 阶梯上移),偏移 {{{{ breakeven_offset_pct }}}}%
</{t}>
<{t} class="rule-tip">
划转自动划转 {{{{ '开启' if auto_transfer_enabled else '关闭' }}}}每天<strong>北京时间 {{{{ auto_transfer_bj_hour }}}}:00</strong>起该整点小时内尝试账簿按 <strong>UTC 自然日</strong>去重界面时间为北京{{{{ auto_transfer_to }}}} 补足到 {{{{ auto_transfer_amount }}}}U来自 {{{{ auto_transfer_from }}}}
划转:自动划转 {{{{ '开启' if auto_transfer_enabled else '关闭' }}}}(每天<strong>北京时间 {{{{ auto_transfer_bj_hour }}}}:00</strong>起该整点小时内尝试;账簿按 <strong>UTC 自然日</strong>去重;界面时间为北京;{{{{ auto_transfer_to }}}} 补足到 {{{{ auto_transfer_amount }}}}U,来自 {{{{ auto_transfer_from }}}})
</{t}>
<form action="/manual_transfer" method="post" class="form-row">
<input name="amount" type="number" min="0.01" step="0.01" placeholder="手动划转金额U" required>
@@ -145,8 +145,8 @@ def build_section(order_loop: str) -> str:
<option value="">方向</option><option value="long">做多</option><option value="short">做空</option>
</select>
<select id="sltp-mode" name="sltp_mode">
<option value="price">止盈止损价格模式</option>
<option value="pct">止盈止损百分比模式</option>
<option value="price">止盈止损:价格模式</option>
<option value="pct">止盈止损:百分比模式</option>
</select>
<select name="trade_style" required>
<option value="trend">趋势单</option>
@@ -154,17 +154,17 @@ def build_section(order_loop: str) -> str:
</select>
<input id="order-leverage" name="leverage" type="number" min="1" step="1" placeholder="杠杆(可选)">
<label style="display:flex;align-items:center;gap:4px;font-size:.82rem;color:#cfd3ef">
<input type="checkbox" name="breakeven_enabled" value="1" checked> 启用移动保本关闭则仅保留初始止损与交易所挂单
<input type="checkbox" name="breakeven_enabled" value="1" checked> 启用移动保本(关闭则仅保留初始止损与交易所挂单)
</label>
<label style="display:flex;align-items:center;gap:4px;font-size:.82rem;color:#cfd3ef">
<input type="checkbox" name="order_chart" value="true"> 开仓后生成多周期K线图各周期100根含开平仓标记
<input type="checkbox" name="order_chart" value="true"> 开仓后生成多周期K线图(各周期100根,含开平仓标记)
</label>
<span style="display:flex;align-items:center;padding:0 10px;font-size:.8rem;color:#8fc8ff">成交价自动取交易所实时+成交回报</span>
<input id="order-sl" name="sl" step="any" placeholder="止损价格" required>
<input id="order-tp" name="tgt" step="any" placeholder="止盈价格" required>
<input id="order-sl-pct" name="sl_pct" type="number" min="0.01" step="0.01" placeholder="止损%" style="display:none">
<input id="order-tp-pct" name="tp_pct" type="number" min="0.01" step="0.01" placeholder="止盈%" style="display:none">
<button type="submit">开仓以损定仓</button>
<button type="submit">开仓(以损定仓)</button>
</form>
</{t}>
<{t} class="card">
@@ -218,7 +218,7 @@ if(addOrderForm){
const mode = (document.getElementById("sltp-mode")||{}).value || "price";
let sl, tp, entry;
if(mode === "pct"){
alert("百分比模式请确认盈亏比后再提交建议使用价格模式以便校验");
alert("百分比模式请确认盈亏比后再提交;建议使用价格模式以便校验.");
return;
}
sl = Number((document.getElementById("order-sl")||{}).value);
@@ -231,12 +231,12 @@ if(addOrderForm){
if(px) entry = Number(px);
const rr = calcClientRr(direction, entry, sl, tp);
if(rr === null || rr < MANUAL_MIN_PLANNED_RR){
alert(`计划盈亏比 ${rr === null ? '无效' : rr.toFixed(2)}:1 低于最低要求 ${MANUAL_MIN_PLANNED_RR}:1已阻止人工下单`);
alert(`计划盈亏比 ${rr === null ? '无效' : rr.toFixed(2)}:1 低于最低要求 ${MANUAL_MIN_PLANNED_RR}:1,已阻止人工下单.`);
return;
}
addOrderForm.submit();
})
.catch(()=>{ ev.preventDefault(); alert("无法校验盈亏比请稍后重试"); });
.catch(()=>{ ev.preventDefault(); alert("无法校验盈亏比,请稍后重试"); });
ev.preventDefault();
});
}
@@ -244,27 +244,27 @@ if(addOrderForm){
text = text.replace("refreshOrderDefaults();", hook + "\nrefreshOrderDefaults();")
if "max_active_positions" not in text and "order-rule-tip" in text:
text = text.replace(
"规则单仓",
"规则最多 {{ max_active_positions }} 仓",
"规则:单仓;",
"规则:最多 {{ max_active_positions }} 仓;",
)
# account snapshot tip
old_tip = '`规则单仓BTC {{ btc_leverage }}x'
old_tip = '`规则:单仓;BTC {{ btc_leverage }}x'
if old_tip in text:
text = text.replace(
old_tip,
"`规则最多 ${data.max_active_positions || {{ max_active_positions }}} 仓BTC {{ btc_leverage }}x",
"`规则:最多 ${data.max_active_positions || {{ max_active_positions }}} 仓;BTC {{ btc_leverage }}x",
)
text = text.replace(
'const canTradeText = data.can_trade ? "可开仓" : "不可开仓有持仓或未到北京时间 {{ reset_hour }}:00";',
'const canTradeText = data.can_trade ? "可开仓" : `不可开仓持仓 ${data.active_count||0}/${data.max_active_positions||{{ max_active_positions }}} 或未到北京时间 {{ reset_hour }}:00`;',
'const canTradeText = data.can_trade ? "可开仓" : "不可开仓(有持仓或未到北京时间 {{ reset_hour }}:00)";',
'const canTradeText = data.can_trade ? "可开仓" : `不可开仓(持仓 ${data.active_count||0}/${data.max_active_positions||{{ max_active_positions }}} 或未到北京时间 {{ reset_hour }}:00)`;',
)
text = text.replace(
"if(!data.in_top30){",
"const rankMax = data.rank_max || 30;\n if(!data.in_top30){",
)
text = text.replace(
"不在前30已拦截",
"不在前${rankMax}已拦截",
"不在前30,已拦截",
"不在前${rankMax},已拦截",
)
# conditional price refresh
if "data-page" in text and "refreshPriceSnapshotConditional" not in text:
@@ -68,8 +68,8 @@ if "key_monitor_page" not in g:
" can_trade = trading_day_reset_allows_new_open(now) and active_count == 0\n conn.close()\n return render_template(",
""" can_trade = trading_day_reset_allows_new_open(now) and active_count < MAX_ACTIVE_POSITIONS
key_gate_rule_text = (
f"周期 {KLINE_TIMEFRAME}|确认K突破棒偏移 {KEY_CONFIRM_BREAKOUT_BAR}确认棒偏移 {KEY_CONFIRM_BAR}"
f"量能突破量 > 前{KEY_VOLUME_MA_BARS}均量×{KEY_VOLUME_RATIO_MIN}"
f"周期 {KLINE_TIMEFRAME}|确认K:突破棒偏移 {KEY_CONFIRM_BREAKOUT_BAR},确认棒偏移 {KEY_CONFIRM_BAR}"
f"量能:突破量 > 前{KEY_VOLUME_MA_BARS}均量×{KEY_VOLUME_RATIO_MIN}"
f"自动开仓盈亏比 > {KEY_AUTO_MIN_PLANNED_RR}:1|日成交量排名前 {KEY_DAILY_VOLUME_RANK_MAX}"
)
conn.close()
@@ -2,8 +2,8 @@
"""
python scripts/verify_binance_funding.py
打印 BINANCE_API_KEY 8 位便于与 Binance 控制台核对不含 Secret用于服务器自检
对比 App资产 资金账户(Funding) / 现货账户(Spot) / U本位合约
打印 BINANCE_API_KEY 8 位便于与 Binance 控制台核对(不含 Secret).用于服务器自检.
对比 App:资产 资金账户(Funding) / 现货账户(Spot) / U本位合约.
"""
import os
import sys
@@ -30,9 +30,9 @@ def main():
k = (os.getenv("BINANCE_API_KEY") or "").strip()
s = (os.getenv("BINANCE_API_SECRET") or "").strip()
if not k or "REPLACE" in k.upper():
print("WARN: BINANCE_API_KEY 为空或仍像占位符请核对 .env")
print("WARN: BINANCE_API_KEY 为空或仍像占位符,请核对 .env")
if not s or "REPLACE" in s.upper():
print("WARN: BINANCE_API_SECRET 为空或仍像占位符请核对 .env")
print("WARN: BINANCE_API_SECRET 为空或仍像占位符,请核对 .env")
print("BINANCE_API_KEY prefix (8 chars):", (k[:8] + "") if len(k) > 8 else "(short)")
print("BINANCE_FUNDING_INCLUDE_SPOT:", os.getenv("BINANCE_FUNDING_INCLUDE_SPOT", "false"))
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 B

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 B

After

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 497 B

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

+2 -13
View File
@@ -1,17 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<defs>
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#22d3ee"/>
<stop offset="100%" stop-color="#34d399"/>
</linearGradient>
</defs>
<rect width="512" height="512" rx="108" fill="#0c1019"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="#141b2d"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="none" stroke="url(#g)" stroke-width="12"/>
<path d="M120 320 L200 248 L280 272 L392 168" fill="none" stroke="url(#g)" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="392" cy="168" r="18" fill="#34d399"/>
<rect x="168" y="268" width="28" height="64" rx="6" fill="#f87171"/>
<line x1="182" y1="248" x2="182" y2="340" stroke="#f87171" stroke-width="10" stroke-linecap="round"/>
<rect x="268" y="220" width="28" height="96" rx="6" fill="#34d399"/>
<line x1="282" y1="200" x2="282" y2="340" stroke="#34d399" stroke-width="10" stroke-linecap="round"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="none" stroke="#F0B90B" stroke-width="12"/>
<polygon points="256,150 362,256 256,362 150,256" fill="#F0B90B"/><polygon points="256,210 302,256 256,302 210,256" fill="#1a160a"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 440 B

@@ -1,11 +1,11 @@
{
"name": "交易监控复盘",
"short_name": "监控",
"description": "加密货币永续交易监控与复盘",
"name": "Binance 交易系统",
"short_name": "Binance 交易系统",
"description": "Binance 永续交易监控与复盘",
"start_url": "/",
"display": "standalone",
"background_color": "#0b0d14",
"theme_color": "#0b0d14",
"theme_color": "#F0B90B",
"icons": [
{
"src": "/static/icons/icon-192.png",
File diff suppressed because it is too large Load Diff
@@ -29,9 +29,9 @@
<div class="row" style="justify-content:space-between">
<div class="row">
<a class="btn" href="/">返回首页</a>
<strong style="color:#dbe4ff">实盘下单放大100根K线</strong>
<strong style="color:#dbe4ff">实盘下单放大(100根K线)</strong>
</div>
<div class="status">最近刷新<span id="updated-at">--</span></div>
<div class="status">最近刷新:<span id="updated-at">--</span></div>
</div>
{% if orders %}
<div class="row" style="margin-top:10px">
@@ -53,7 +53,7 @@
<span id="load-status" class="status"></span>
</div>
{% else %}
<div class="empty">当前没有激活订单无法展示放大K线</div>
<div class="empty">当前没有激活订单,无法展示放大K线.</div>
{% endif %}
</div>
+139 -139
View File
@@ -1,139 +1,139 @@
# 使用说明
**本文件对应仓库`crypto_monitor_binance`Binance U 本位永续)。**
功能界面与 **Gate.io USDT 永续版**目录 `crypto_monitor_gate`基本一致差异主要在 **`.env` 里交易所密钥与部分参数名**`BINANCE_*` / `GATE_*`),文末有对照
**部署代理PM2 等**请参考本仓库说明或 **`crypto_monitor_gate`** 下的 **`部署文档.md`**该文以 Gate + SSH SOCKS 为例Binance 侧将 API 与密钥改为 `BINANCE_*` 即可类比)。
**关键位自动开仓的规则RR结案原因**见本目录 **`关键位自动下单说明.md`**
---
## 1. 它能做什么
面向个人盘面的 **Web 控制台**主要能力包括
| 模块 | 说明 |
|------|------|
| **关键位监控** | 录入上/下沿与类型**5m 收线** 做硬条件过滤符合条件后 **企业微信** 提醒部分类型可 **自动市价开仓**见第 4 节与专门文档)。 |
| **实盘下单监控** | 手工填止损/止盈**以损定仓** 市价开单挂上条件止盈止损并在页面跟踪浮盈亏保本逻辑等 |
| **交易记录 / 复盘** | 平仓结果盈亏错过的单等归档与导出可选 **AI 复盘**见仓库根 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md))。 |
| **策略交易** | 顶栏 `/strategy`**趋势回调**(左)**顺势加仓**(右)左右并列细则见 [策略交易说明.md](../策略交易说明.md) |
| **策略交易记录** | 顶栏 `/strategy/records`趋势/顺势分两栏可筛选库内保留最近 100 条结束快照 |
后台按 **`MONITOR_POLL_SECONDS`**默认几秒轮询行情与监控逻辑**切勿**在未理解规则时同时运行两套程序共用一个实盘账户
---
## 2. 运行前必须配置`.env`
首次在本目录执行 **`cp .env.example .env`**再编辑 `.env``.env` 勿提交 Git`git pull` 不会改你的 `.env`升级前建议 `cp .env .env.backup.$(date +%Y%m%d)`)。
至少检查以下项具体键名以 **`.env.example`** 为准):
| 类别 | 说明 |
|------|------|
| **登录网页** | `APP_PASSWORD`打开站点后的登录口令`FLASK_SECRET_KEY`Session 密钥请勿使用默认值 |
| **企业微信** | `WECHAT_WEBHOOK`告警与关键位推送机器人的 Webhook |
| **是否真下单** | `LIVE_TRADING_ENABLED=false`**不会**向交易所发送开仓指令适合测试流程)。改为 `true` 且密钥正确才会实盘 |
| **交易所 API** | **本仓库** `BINANCE_API_KEY``BINANCE_API_SECRET`永续相关见 `BINANCE_MARGIN_MODE``BINANCE_POSITION_MODE``BINANCE_TRIGGER_WORKING_TYPE`**勿**把 `.env` 提交到 Git |
| **关键位 RR / 止损外扩** | `KEY_AUTO_MIN_PLANNED_RR``KEY_STOP_OUTSIDE_BREAKOUT_PCT`详见 `关键位自动下单说明.md`)。 |
| **AI 复盘** | 默认 `AI_PROVIDER=openai``OPENAI_API_BASE=https://op.bz121.com/v1``OPENAI_API_KEY``OPENAI_MODEL=gemma4:e4b``AI_PROVIDER=ollama` + `OLLAMA_API` / `AI_MODEL`详见 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md) |
网络需要代理时可配置 **`BINANCE_SOCKS_PROXY` / `BINANCE_HTTP_PROXY`**与 Gate 版 `GATE_*_PROXY` 用法类似)。
---
## 3. 如何启动与登录
1. 准备 Python 虚拟环境并安装依赖`flask``requests``ccxt`按需 `Pillow``PySocks`),配置好 `.env`
2. 启动 Flask 应用可用 **`ecosystem.config.cjs`** 交给 PM2或本地 `python app.py` / `flask run`以你当前脚本为准)。
3. 浏览器访问站点打开 **`/login`**使用 **`.env` 里的 `APP_PASSWORD`** 登录
登录后顶栏**关键位监控** | **实盘下单**默认首页| **策略交易**`/strategy`趋势回调 + 顺势加仓双栏| **策略交易记录**`/strategy/records`最近 100 条结束快照| **交易记录与复盘** | **统计分析**
---
## 4. 关键位监控顶栏「关键位监控」→ `/key_monitor`
### 4.1 添加一条关键位
1. **币种**`BTC``BTC/USDT`会规范成内部符号)。
2. **类型**必选其一):
| 类型 | 行为摘要 |
|------|----------|
| **箱体突破** | 通过门控且计划 RR 达标 → **自动市价开仓**`LIVE_TRADING_ENABLED=true` 且无其他持仓占位)。结案后本条从列表消失并记入历史 |
| **收敛突破** | 同上自动开仓类)。 |
| **关键阻力位** | **不自动开仓**触发后 **发 1 次微信**然后本条 **结案进历史** |
| **关键支撑位** | 同上仅提醒)。 |
| **回调触价开仓** | **不挂交易所限价**标记价回调触达 E 后 **下一轮询市价开仓**RR 门槛同 `KEY_AUTO_MIN_PLANNED_RR`);有效期 **24h** |
| **突破触价开仓** | **不挂交易所限价**标记价 **穿越 E 立即市价开仓**先触 SL/TP 侧失效有效期 **24h** |
3. **方向**做多 / 做空回调/突破触价箱体 / 收敛 / 斐波必选阻力/支撑不选)。
4. **价位**箱体/收敛/阻力/支撑填 **上沿 / 下沿**触价填 **入场 E / 止损 SL / 止盈 TP**
**限制**
活跃持仓数达到 **`MAX_ACTIVE_POSITIONS`**默认 1)时,**不允许**再添加「**箱体突破** / **收敛突破**仍可添加「**关键阻力位 / 支撑位**」
**4h EMA55** 与你的方向逆势页面会 **额外 Flash 提示****不阻挡**提交
### 4.2 触发后会发生什么简版
- **箱体 / 收敛**门控通过后算计划 SL/TP 与 RR不达标 → 微信说明 + **`rr_insufficient`** 结案达标 → **市价开仓**成功 **`auto_opened`** / 失败 **`exchange_failed`**均不重试同一关键位
- **阻力 / 支撑****单次推送****`key_level_alert_only`** 结案
详细公式与字段见 **`关键位自动下单说明.md`**
### 4.3 列表与历史
当前条目与历史记录的用法与 Gate 版相同结案后可在历史区查阅 **`close_reason`**
---
## 5. 实盘下单顶栏「实盘下单」→ `/trade`
- 持仓上限由 **`MAX_ACTIVE_POSITIONS`** 控制默认 1)。
- **人工开仓**计划盈亏比不得低于 **`MANUAL_MIN_PLANNED_RR`**默认 1.4:1)。
- 填写币种方向杠杆可选)、止损/止盈价格或百分比按表单)。
- 移动保本等选项按页面与 `.env` 默认
开仓成功后卡片 **「来源」**手工一般为 **下单监控**关键位自动为 **关键位监控**
---
## 6. 企业微信
推送逻辑与 Gate 版一致未配置 **`WECHAT_WEBHOOK`** 时可能没有消息请以 **交易所端** 核对持仓与挂单
---
## 7. 强烈建议的风险与运维习惯
1. **先用 `LIVE_TRADING_ENABLED=false`** 熟悉流程再实盘
2. **API 权限**最小化密钥勿泄露
3. **同一账户避免多程序重复开仓**
4. **自动备份**服务器上执行 `bash scripts/install_backup_cron.sh`每天北京时间 0:00 → `/root/backups`保留 30 天);升级前也可 `bash scripts/backup_data.sh` 手动跑一次
5. 升级代码后留意 **首轮启动**有无数据库迁移报错
---
## 8. 常见问题简要
| 现象 | 可自查 |
|------|--------|
| 关键位永远不触发 | 门控五项日成交量排名`KLINE_TIMEFRAME` |
| 有信号但不自动开仓 | `LIVE_TRADING_ENABLED`RR 阈值是否已有持仓API/保证金错误信息 |
| 加不了箱体/收敛 | 是否已有持仓 |
| 推送收不到 | Webhook网络 |
---
## 9. Gate 版`crypto_monitor_gate`差异速查
| 项目 | Binance 本仓库 | Gate 版 |
|------|----------------|--------|
| API 变量 | `BINANCE_API_KEY``BINANCE_API_SECRET``BINANCE_*` | `GATE_API_KEY``GATE_API_SECRET``GATE_*` |
| 代理示例 | `BINANCE_SOCKS_PROXY` | `GATE_SOCKS_PROXY` |
| TP/SL 实现 | `_binance_place_tp_sl_orders` | `_gate_place_tp_sl_orders``GATE_TPSL_*` |
| 资金舍入口径 | **`FUNDS_DECIMALS`**与记账一致 | 以 Gate 仓库实现为准 |
业务流程登录四种关键位手工单单仓两份程序对齐仅需更换目录与 `.env`
# 使用说明
**本文件对应仓库:`crypto_monitor_binance`(Binance U 本位永续).**
功能,界面与 **Gate.io USDT 永续版**(目录 `crypto_monitor_gate`)基本一致,差异主要在 **`.env` 里交易所密钥与部分参数名**(`BINANCE_*` / `GATE_*`),文末有对照.
**部署,代理,PM2 等**请参考本仓库说明或 **`crypto_monitor_gate`** 下的 **`部署文档.md`**(该文以 Gate + SSH SOCKS 为例;Binance 侧将 API 与密钥改为 `BINANCE_*` 即可类比).
**关键位自动开仓的规则,RR,结案原因**见本目录 **`关键位自动下单说明.md`**.
---
## 1. 它能做什么
面向个人盘面的 **Web 控制台**,主要能力包括:
| 模块 | 说明 |
|------|------|
| **关键位监控** | 录入上/下沿与类型,**5m 收线** 做硬条件过滤;符合条件后 **企业微信** 提醒,部分类型可 **自动市价开仓**(见第 4 节与专门文档). |
| **实盘下单监控** | 手工填止损/止盈,**以损定仓** 市价开单,挂上条件止盈止损,并在页面跟踪浮盈亏,保本逻辑等. |
| **交易记录 / 复盘** | 平仓结果,盈亏,错过的单等归档与导出;可选 **AI 复盘**(见仓库根 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)). |
| **策略交易** | 顶栏 `/strategy`:**趋势回调**(左)**顺势加仓**(右)左右并列;细则见 [策略交易说明.md](../策略交易说明.md). |
| **策略交易记录** | 顶栏 `/strategy/records`:趋势/顺势分两栏,可筛选,库内保留最近 100 条结束快照. |
后台按 **`MONITOR_POLL_SECONDS`**(默认几秒)轮询行情与监控逻辑.**切勿**在未理解规则时同时运行两套程序共用一个实盘账户.
---
## 2. 运行前必须配置(`.env`)
首次在本目录执行 **`cp .env.example .env`**,再编辑 `.env`(`.env` 勿提交 Git;`git pull` 不会改你的 `.env`,升级前建议 `cp .env .env.backup.$(date +%Y%m%d)`).
至少检查以下项(具体键名以 **`.env.example`** 为准):
| 类别 | 说明 |
|------|------|
| **登录网页** | `APP_PASSWORD`:打开站点后的登录口令.`FLASK_SECRET_KEY`:Session 密钥,请勿使用默认值. |
| **企业微信** | `WECHAT_WEBHOOK`:告警与关键位推送机器人的 Webhook. |
| **是否真下单** | `LIVE_TRADING_ENABLED=false`:**不会**向交易所发送开仓指令(适合测试流程).改为 `true` 且密钥正确才会实盘. |
| **交易所 API** | **本仓库:** `BINANCE_API_KEY`,`BINANCE_API_SECRET`;永续相关见 `BINANCE_MARGIN_MODE`,`BINANCE_POSITION_MODE`,`BINANCE_TRIGGER_WORKING_TYPE`.**勿**把 `.env` 提交到 Git. |
| **关键位 RR / 止损外扩** | `KEY_AUTO_MIN_PLANNED_RR`,`KEY_STOP_OUTSIDE_BREAKOUT_PCT`(详见 `关键位自动下单说明.md`). |
| **AI 复盘** | 默认 `AI_PROVIDER=openai`,`OPENAI_API_BASE=https://op.bz121.com/v1`,`OPENAI_API_KEY`,`OPENAI_MODEL=gemma4:e4b`;`AI_PROVIDER=ollama` + `OLLAMA_API` / `AI_MODEL`.详见 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md). |
网络需要代理时可配置 **`BINANCE_SOCKS_PROXY` / `BINANCE_HTTP_PROXY`**(与 Gate 版 `GATE_*_PROXY` 用法类似).
---
## 3. 如何启动与登录
1. 准备 Python 虚拟环境并安装依赖(`flask`,`requests`,`ccxt`,按需 `Pillow`,`PySocks`),配置好 `.env`.
2. 启动 Flask 应用(可用 **`ecosystem.config.cjs`** 交给 PM2,或本地 `python app.py` / `flask run`,以你当前脚本为准).
3. 浏览器访问站点,打开 **`/login`**,使用 **`.env` 里的 `APP_PASSWORD`** 登录.
登录后顶栏:**关键位监控** | **实盘下单**(默认首页)| **策略交易**(`/strategy`,趋势回调 + 顺势加仓双栏)| **策略交易记录**(`/strategy/records`,最近 100 条结束快照)| **交易记录与复盘** | **统计分析**.
---
## 4. 关键位监控(顶栏「关键位监控」→ `/key_monitor`)
### 4.1 添加一条关键位
1. **币种**:`BTC``BTC/USDT`(会规范成内部符号).
2. **类型**(必选其一):
| 类型 | 行为摘要 |
|------|----------|
| **箱体突破** | 通过门控且计划 RR 达标 → **自动市价开仓**(`LIVE_TRADING_ENABLED=true` 且无其他持仓占位).结案后本条从列表消失并记入历史. |
| **收敛突破** | 同上(自动开仓类). |
| **关键阻力位** | **不自动开仓**;触发后 **发 1 次微信**,然后本条 **结案进历史**. |
| **关键支撑位** | 同上(仅提醒). |
| **回调触价开仓** | **不挂交易所限价**;标记价回调触达 E 后 **下一轮询市价开仓**(RR 门槛同 `KEY_AUTO_MIN_PLANNED_RR`);有效期 **24h** |
| **突破触价开仓** | **不挂交易所限价**;标记价 **穿越 E 立即市价开仓**;先触 SL/TP 侧失效;有效期 **24h** |
3. **方向**:做多 / 做空(回调/突破触价,箱体 / 收敛 / 斐波必选;阻力/支撑不选).
4. **价位**:箱体/收敛/阻力/支撑填 **上沿 / 下沿**;触价填 **入场 E / 止损 SL / 止盈 TP**.
**限制:**
活跃持仓数达到 **`MAX_ACTIVE_POSITIONS`**(默认 1)时,**不允许**再添加「**箱体突破** / **收敛突破**;仍可添加「**关键阻力位 / 支撑位**」.
**4h EMA55** 与你的方向逆势,页面会 **额外 Flash 提示**,**不阻挡**提交.
### 4.2 触发后会发生什么(简版)
- **箱体 / 收敛**:门控通过后算计划 SL/TP 与 RR;不达标 → 微信说明 + **`rr_insufficient`** 结案;达标 → **市价开仓**,成功 **`auto_opened`** / 失败 **`exchange_failed`**,均不重试同一关键位.
- **阻力 / 支撑**:**单次推送****`key_level_alert_only`** 结案.
详细公式与字段见 **`关键位自动下单说明.md`**.
### 4.3 列表与历史
当前条目与历史记录的用法与 Gate 版相同;结案后可在历史区查阅 **`close_reason`**.
---
## 5. 实盘下单(顶栏「实盘下单」→ `/trade`)
- 持仓上限由 **`MAX_ACTIVE_POSITIONS`** 控制(默认 1).
- **人工开仓**计划盈亏比不得低于 **`MANUAL_MIN_PLANNED_RR`**(默认 1.4:1).
- 填写币种,方向,杠杆(可选),止损/止盈(价格或百分比按表单).
- 移动保本等选项按页面与 `.env` 默认.
开仓成功后卡片 **「来源」**:手工一般为 **下单监控**;关键位自动为 **关键位监控**.
---
## 6. 企业微信
推送逻辑与 Gate 版一致;未配置 **`WECHAT_WEBHOOK`** 时可能没有消息,请以 **交易所端** 核对持仓与挂单.
---
## 7. 强烈建议的风险与运维习惯
1. **先用 `LIVE_TRADING_ENABLED=false`** 熟悉流程再实盘.
2. **API 权限**最小化,密钥勿泄露.
3. **同一账户避免多程序重复开仓**.
4. **自动备份**:服务器上执行 `bash scripts/install_backup_cron.sh`(每天北京时间 0:00 → `/root/backups`,保留 30 天);升级前也可 `bash scripts/backup_data.sh` 手动跑一次.
5. 升级代码后留意 **首轮启动**有无数据库迁移报错.
---
## 8. 常见问题(简要)
| 现象 | 可自查 |
|------|--------|
| 关键位永远不触发 | 门控五项,日成交量排名,`KLINE_TIMEFRAME`. |
| 有信号但不自动开仓 | `LIVE_TRADING_ENABLED`,RR 阈值,是否已有持仓,API/保证金错误信息. |
| 加不了箱体/收敛 | 是否已有持仓. |
| 推送收不到 | Webhook,网络. |
---
## 9. Gate 版(`crypto_monitor_gate`)差异速查
| 项目 | Binance 本仓库 | Gate 版 |
|------|----------------|--------|
| API 变量 | `BINANCE_API_KEY`,`BINANCE_API_SECRET`,`BINANCE_*` | `GATE_API_KEY`,`GATE_API_SECRET`,`GATE_*` |
| 代理示例 | `BINANCE_SOCKS_PROXY` | `GATE_SOCKS_PROXY` |
| TP/SL 实现 | `_binance_place_tp_sl_orders` | `_gate_place_tp_sl_orders`,`GATE_TPSL_*` |
| 资金舍入口径 | **`FUNDS_DECIMALS`**(与记账一致) | 以 Gate 仓库实现为准 |
业务流程(登录,四种关键位,手工单,单仓)两份程序对齐;仅需更换目录与 `.env`.
@@ -1,175 +1,192 @@
# 关键位监控说明自动开仓 + 人工盯盘
**适用`crypto_monitor_gate`Gate U 本位永续)**
Binance / OKX 见各自目录下同名文档;共享逻辑在仓库根目录 `key_monitor_lib.py`
本文档与 `.env``check_key_monitors``add_key``_key_hard_checks``_process_key_rs_level_alert` 一致。
---
## 一、监控类型总览
| 录入类型 | 录入时选方向 | 自动市价开仓 | 触发与结案 |
|----------|--------------|--------------|------------|
| **箱体突破** | **必选** 多/空 | **是**(门控 + RR) | 条件满足 → 开仓或 `rr_insufficient` / `exchange_failed`**一次性删除** |
| **收敛突破** | **必选** 多/空 | **是**(同上) | 同上 |
| **关键阻力位** | **不选**`direction=watch` | **否** | 5m 收盘突破上/下沿 → 微信 **3 次**`key_level_alert_done` |
| **关键支撑位** | **不选** | **否** | 同上(与阻力位**相同规则**:填上沿+下沿,程序双向监控) |
| 斐波回调 0.618 / 0.786 | 必选 | 限价挂单逻辑 | 见斐波说明(**不在下文展开**) |
| **回调触价开仓** | **必选** 多/空 | **程序盯价 → 回调触 E 后市价** | 见下文 **§四** |
| **突破触价开仓** | **必选** 多/空 | **程序盯价 → 穿越 E 立即市价** | 见下文 **§四** |
**添加时(箱体/收敛/斐波/触价):** 品种须 **日成交量排名前 `KEY_DAILY_VOLUME_RANK_MAX`(默认 30**;上沿 **>** 下沿(触价开仓填 E/SL/TP,上下沿仅作展示占位)。
---
## 二、关键阻力位 / 关键支撑位(人工盯盘)
### 2.1 录入
- 填写 **上沿 `upper`****下沿 `lower`**(程序同时监控两侧,**无法预先判定**做多还是做空)。
- 页面 **不显示、不要求** 方向;库中 `direction` 初始为 `watch`**首次突破后** 写入 `long`(向上突破上沿)或 `short`(向下突破下沿)。
### 2.2 触发(极简)
- 周期:**`KLINE_TIMEFRAME`(默认 5m)最近一根已闭合 K** 的 **收盘价**(非影线)。
- **向上突破上沿:** `收盘 > upper` → 推断方向 **多 / 向上**,本次监控任务开始按节奏提醒。
- **向下突破下沿:** `收盘 < lower` → 推断方向 **空 / 向下**,本次任务同样开始提醒。
- **任一侧突破即结束本条监控周期**(不会在突破后再等待另一侧;上沿、下沿谁先满足用谁,同根 K 仅可能满足一侧)。
**不参与:** 量能、二确 K、越过幅度下限、日成交排名(运行时)、计划 RR、自动开仓。
### 2.3 微信提醒次数
| 配置 | 默认 | 含义 |
|------|------|------|
| `KEY_ALERT_MAX_TIMES` | `3` | 突破后最多推送 3 次 |
| `KEY_ALERT_INTERVAL_MINUTES` | `5` | 相邻两次推送至少间隔 5 分钟 |
- 第 1 次:首次检测到突破的当次轮询(若已闭合 5m 满足条件)。
- 第 2、3 次:仅按间隔推送(**不要求**价格仍在箱外)。
- 第 3 次推送后:写入 `key_monitor_history``close_reason=**key_level_alert_done**`,从 `key_monitors` **删除**
### 2.4 与箱体/收敛的区别
| 项目 | 阻力/支撑 | 箱体/收敛 |
|------|-----------|-----------|
| 方向 | 程序推断 | 人工选择 |
| K 线根数 | 1 根闭合 5m | 2 根(突破 K + 确认 K |
| 提醒次数 | 3 次后结案 | 自动单:触发后 1 次业务推送并结案 |
---
## 三、箱体突破 / 收敛突破(自动开仓)
### 3.1 K 线结构(默认索引)
| 角色 | 环境变量 | 默认 | 含义 |
|------|----------|------|------|
| 突破 K | `KEY_CONFIRM_BREAKOUT_BAR` | `-2` | 倒数第 2 根闭合 K |
| 确认 K | `KEY_CONFIRM_BAR` | `-1` | 倒数第 1 根闭合 K |
### 3.2 硬门控(须全部通过)
1. **有效突破(收盘越界)**
- 多:`突破 K 收盘 > upper`
- 空:`突破 K 收盘 < lower`
2. **突破越过幅度(仅下限)**
- 多:`(突破 K 收盘 upper) / upper × 100 > KEY_BREAKOUT_AMP_MIN_PCT`(默认 **0.03%**
- 空:`(lower 突破 K盘) / lower × 100 >` 同上
- **无上限**;突破过猛由 **计划 RR** 过滤。
- **不再**使用 K 线实体占开盘价比例;`KEY_BREAKOUT_AMP_MAX_PCT` **已不参与门控**
3. **确认 K 不进箱体**
- 多:确认 K 收盘 **`> upper`**(不得在 `[lower, upper]` 内)
- 空:确认 K 收盘 **`< lower`**
4. **量能:** 突破 K 成交量 > 前 `KEY_VOLUME_MA_BARS`(默认 20)根均量 × `KEY_VOLUME_RATIO_MIN`(默认 1.3
5. **日成交量排名:** 运行时仍须前 `KEY_DAILY_VOLUME_RANK_MAX`(默认 30
6. **计划 RR(最后经济门控):** 按确认 K 收盘 **E** 计算 SL/TP 后,`RR` **严格大于** `KEY_AUTO_MIN_PLANNED_RR`(默认 1.5)才市价开仓
### 3.3 止损 / 止盈(确认 K 收盘为 E)
箱体高 **H = |upper lower|**。止损锚在 **突破 K 极值** 外侧:
| 方向 | 止损(标准/趋势方案) |
|------|------------------------|
| 多 | 突破 K **最低价** × (1 `KEY_STOP_OUTSIDE_BREAKOUT_PCT`%) |
| 空 | 突破 K **最高价** × (1 + `KEY_STOP_OUTSIDE_BREAKOUT_PCT`%) |
止盈方案见下表(与改版前一致):
| 方案 | `sl_tp_mode` | 多:SL / TP | 空:SL / TP |
|------|--------------|-------------|-------------|
| 标准突破 | `standard` | 突破 K 低外侧% / **E+H** | 突破 K 高外侧% / **EH** |
| 箱体 1R·止盈 1.5H | `box_1p5` | **EH** / **E+1.5×H** | **E+H** / **E1.5×H** |
| 趋势单·自填止盈 | `trend_manual` | 突破 K 低 × (1`KEY_TREND_STOP_OUTSIDE_PCT`%) / **录入止盈** | 突破 K 高外侧% / **录入止盈** |
### 3.4 一次性结案(`close_reason`
| `close_reason` | 含义 |
|----------------|------|
| `box_opposite_break` | 标记价先突破反向边界(多:≤下沿;空:≥上沿) |
| `rr_insufficient` | 门控通过但 RR 不达标或 SL/TP 几何无效 |
| `exchange_failed` | RR 达标但实盘/交易所等原因未开仓 |
| `auto_opened` | RR 达标且市价开仓成功 |
| `key_level_alert_done` | 阻力/支撑 **3 次提醒** 完成 |
---
## 四、回调 / 突破触价开仓(程序触价,无交易所挂单)
### 4.1 录入
- **回调触价开仓**:方向必选多/空;填写 **计划入场价 E**、**止损 SL**、**止盈 TP**(做多须 `SL < E < TP`)。
- **突破触价开仓**:同上;添加时当前价须在突破方向一侧(做多:价低于 E;做空:价高于 E)。
- 计划 RR 以 **E** 为基准,须 **严格大于** `KEY_AUTO_MIN_PLANNED_RR`(默认 1.5)。
- 可选移动保本、时间平仓;**全仓杠杆模式**下可用。
### 4.2 触发与结案
| 类型 | 触发条件(标记价) |
|------|-------------------|
| **回调触价** | 做多 `≤ E`;做空 `≥ E` → 下一轮询市价开仓 |
| **突破触价** | 做多**向上穿越** E;做空**向下穿越** E → **立即**市价开仓 |
- 未成交前标记价先触 **TP 侧**`trigger_tp_invalidate`
- **突破触价**另:未穿越 E 先触 **SL 侧**`trigger_sl_invalidate`
- **24h** 未触发 → `trigger_entry_expired`
- 成功 → `trigger_entry_filled`;触发后开仓失败 → `trigger_exchange_failed`
### 4.3 计仓与占位
- **以损定仓**:按 E、SL 反推保证金,触发时重算;**全仓杠杆**:可用×缓冲比例,BTC/ETH 10x、其它 5x。
- **占当日开仓意图**(已开 + 待触发),未成交不占持仓;同币仅 1 条触价监控(含回调/突破)。
共享逻辑:`trigger_entry_key_monitor_lib.py`;轮询:`check_trigger_entry_key_monitors`
---
## 五、环境与参数(`.env` 摘要)
| 变量 | 箱体/收敛 | 阻力/支撑 |
|------|-----------|-----------|
| `KEY_BREAKOUT_AMP_MIN_PCT` | 突破越过下限(默认 0.03) | 不用 |
| `KEY_BREAKOUT_AMP_MAX_PCT` | **已废弃门控** | 不用 |
| `KEY_VOLUME_*` / `KEY_CONFIRM_*` | 用 | 不用 |
| `KEY_AUTO_MIN_PLANNED_RR` | 用 | 不用 |
| `KEY_ALERT_MAX_TIMES` / `KEY_ALERT_INTERVAL_MINUTES` | 不用 | 用(默认 3 次 / 5 分钟) |
| `KEY_DAILY_VOLUME_RANK_MAX` | 添加时 + 运行时 | **仅添加时** |
---
## 六、相关代码
| 说明 | 位置 |
|------|------|
| 共享判定 | `key_monitor_lib.py` |
| 主循环 | `check_key_monitors` |
| 自动门控 | `_key_hard_checks` |
| 阻力/支撑提醒 | `_process_key_rs_level_alert` |
| 录入 | `add_key` |
| 开仓 | `_market_open_for_key_monitor` |
# 关键位监控说明(自动开仓 + 人工盯盘)
**适用:Gate / Binance / OKX 三所实例(共用 `lib/key_monitor/key_auto_order_lib.py`)**
## 环境开关 `KEY_AUTO_ORDER_ENABLED`(默认 `false`)
| 计仓模式 | 开关 | 关键位程序自动单 |
|----------|------|------------------|
| `risk`(以损定仓) | `false` | **全部关闭**(含触价);支撑/阻力微信提醒仍可用 |
| `risk` | `true` | 箱体/收敛/斐波/假突破/触价均可自动(旧行为) |
| `full_margin`(全仓) | `false` | 全部关闭(含触价) |
| `full_margin` | `true` | **仅触价**自动;箱体/斐波等仍禁止 |
**不受本开关影响:** 人工实盘下单,关键支撑/阻力提醒,**顺势加仓**(`risk` 下),趋势回调(`risk` 下).全仓模式下策略自动仍禁止.
修改 `.env` 后须 **重启 PM2**.复盘「开仓类型」与统计分段会随开关联动隐藏关键位选项.
---
**适用:`crypto_monitor_binance`(Binance U 本位)**
Gate / OKX 见各自目录下同名文档;共享逻辑在 `lib/key_monitor/`.
本文档与 `.env`,`check_key_monitors`,`add_key`,`_key_hard_checks`,`_process_key_rs_level_alert` 一致.
---
## 一,监控类型总览
| 录入类型 | 录入时选方向 | 自动市价开仓 | 触发与结案 |
|----------|--------------|--------------|------------|
| **箱体突破** | **必选** 多/空 | **是**(门控 + RR) | 条件满足 → 开仓或 `rr_insufficient` / `exchange_failed`**一次性删除** |
| **收敛突破** | **必选** 多/空 | **是**(同上) | 同上 |
| **关键阻力位** | **不选**(`direction=watch`) | **否** | 5m 收盘突破上/下沿 → 微信 **3 次**`key_level_alert_done` |
| **关键支撑位** | **不选** | **否** | 同上(与阻力位**相同规则**:填上沿+下沿,程序双向监控) |
| 斐波回调 0.618 / 0.786 | 必选 | 限价挂单逻辑 | 见斐波说明(**不在下文展开**) |
| **回调触价开仓** | **必选** 多/空 | **程序盯价 → 回调触 E 后市价** | 见下文 **§四** |
| **突破触价开仓** | **必选** 多/空 | **程序盯价 → 穿越 E 立即市价** | 见下文 **§四** |
**添加时(箱体/收敛/斐波/触价):** 品种须 **日成交量排名前 `KEY_DAILY_VOLUME_RANK_MAX`(默认 30)**;上沿 **>** 下沿(触价开仓填 E/SL/TP,上下沿仅作展示占位).
---
## 二,关键阻力位 / 关键支撑位(人工盯盘)
### 2.1 录入
- 填写 **上沿 `upper`****下沿 `lower`**(程序同时监控两侧,**无法预先判定**做多还是做空).
- 页面 **不显示,不要求** 方向;库中 `direction` 初始为 `watch`,**首次突破后** 写入 `long`(向上突破上沿)或 `short`(向下突破下沿).
### 2.2 触发(极简)
- 周期:**`KLINE_TIMEFRAME`(默认 5m)最近一根已闭合 K** 的 **收盘价**(非影线).
- **向上突破上沿:** `收盘 > upper` → 推断方向 **多 / 向上**,本次监控任务开始按节奏提醒.
- **向下突破下沿:** `收盘 < lower` → 推断方向 **空 / 向下**,本次任务同样开始提醒.
- **任一侧突破即结束本条监控周期**(不会在突破后再等待另一侧;上沿,下沿谁先满足用谁,同根 K 仅可能满足一侧).
**不参与:** 量能,二确 K,越过幅度下限,日成交排名(运行时),计划 RR,自动开仓.
### 2.3 微信提醒次数
| 配置 | 默认 | 含义 |
|------|------|------|
| `KEY_ALERT_MAX_TIMES` | `3` | 突破后最多推送 3 次 |
| `KEY_ALERT_INTERVAL_MINUTES` | `5` | 相邻两次推送至少间隔 5 分钟 |
- 第 1 次:首次检测到突破的当次轮询(若已闭合 5m 满足条件).
- 第 2,3 次:仅按间隔推送(**不要求**价格仍在箱外).
- 第 3 次推送后:写入 `key_monitor_history`,`close_reason=**key_level_alert_done**`,从 `key_monitors` **删除**.
### 2.4 与箱体/收敛的区别
| 项目 | 阻力/支撑 | 箱体/收敛 |
|------|-----------|-----------|
| 方向 | 程序推断 | 人工选择 |
| K 线根数 | 1 根闭合 5m | 2 根(突破 K + 确认 K) |
| 提醒次数 | 3 次后结案 | 自动单:触发后 1 次业务推送并结案 |
---
## 三,箱体突破 /敛突破(自动开仓)
### 3.1 K 线结构(默认索引)
| 角色 | 环境变量 | 默认 | 含义 |
|------|----------|------|------|
| 突破 K | `KEY_CONFIRM_BREAKOUT_BAR` | `-2` | 倒数第 2 根闭合 K |
| 确认 K | `KEY_CONFIRM_BAR` | `-1` | 倒数第 1 根闭合 K |
### 3.2 硬门控(须全部通过)
1. **有效突破(收盘越界)**
- 多:`突破 K 收盘 > upper`
- 空:`突破 K 收盘 < lower`
2. **突破越过幅度(仅下限)**
- 多:`(突破 K 收盘 upper) / upper × 100 > KEY_BREAKOUT_AMP_MIN_PCT`(默认 **0.03%**)
- 空:`(lower 突破 K 收盘) / lower × 100 >` 同上
- **无上限**;突破过猛由 **计划 RR** 过滤.
- **不再**使用 K 线实体占开盘价比例;`KEY_BREAKOUT_AMP_MAX_PCT` **已不参与门控**.
3. **确认 K 不进箱体**
- 多:确认 K 收盘 **`> upper`**(不得在 `[lower, upper]` 内)
- 空:确认 K 收盘 **`< lower`**
4. **量能:** 突破 K 成交量 > 前 `KEY_VOLUME_MA_BARS`(默认 20)根均量 × `KEY_VOLUME_RATIO_MIN`(默认 1.3)
5. **日成交量排名:** 运行时仍须前 `KEY_DAILY_VOLUME_RANK_MAX`(默认 30)
6. **计划 RR(最后经济门控):** 按确认 K 收盘 **E** 计算 SL/TP 后,`RR` **严格大于** `KEY_AUTO_MIN_PLANNED_RR`(默认 1.5)才市价开仓
### 3.3 止损 / 止盈(确认 K 收盘为 E)
箱体高 **H = |upper lower|**.止损锚在 **突破 K 极值** 外侧:
| 方向 | 止损(标准/趋势方案) |
|------|------------------------|
| 多 | 突破 K **最低价** × (1 `KEY_STOP_OUTSIDE_BREAKOUT_PCT`%) |
| 空 | 突破 K **最高价** × (1 + `KEY_STOP_OUTSIDE_BREAKOUT_PCT`%) |
止盈方案见下表(与改版前一致):
| 方案 | `sl_tp_mode` | 多:SL / TP | 空:SL / TP |
|------|--------------|-------------|-------------|
| 标准突破 | `standard` | 突破 K 低外侧% / **E+H** | 突破 K 高外侧% / **EH** |
| 箱体 1R·止盈 1.5H | `box_1p5` | **EH** / **E+1.5×H** | **E+H** / **E1.5×H** |
| 趋势单·自填止盈 | `trend_manual` | 突破 K 低 × (1`KEY_TREND_STOP_OUTSIDE_PCT`%) / **录入止盈** | 突破 K 高外侧% / **录入止盈** |
### 3.4 一次性结案(`close_reason`)
| `close_reason` | 含义 |
|----------------|------|
| `box_opposite_break` | 标记价先突破反向边界(多:≤下沿;空:≥上沿) |
| `rr_insufficient` | 门控通过但 RR 不达标或 SL/TP 几何无效 |
| `exchange_failed` | RR 达标但实盘/交易所等原因未开仓 |
| `auto_opened` | RR 达标且市价开仓成功 |
| `key_level_alert_done` | 阻力/支撑 **3 次提醒** 完成 |
---
## 四,回调 / 突破触价开仓(程序触价,无交易所挂单)
### 4.1 录入
- **回调触价开仓**:方向必选多/空;填写 **计划入场价 E**,**止损 SL**,**止盈 TP**(做多须 `SL < E < TP`).
- **突破触价开仓**:同上;添加时当前价须在突破方向一侧(做多:价低于 E;做空:价高于 E).
- 计划 RR 以 **E** 为基准,须 **严格大于** `KEY_AUTO_MIN_PLANNED_RR`(默认 1.5).
- 可选移动保本,时间平仓;**全仓杠杆模式**下可用.
### 4.2 触发与结案
| 类型 | 触发条件(标记价) |
|------|-------------------|
| **回调触价** | 做多 `≤ E`;做空 `≥ E` → 下一轮询市价开仓 |
| **突破触价** | 做多**向上穿越** E;做空**向下穿越** E → **立即**市价开仓 |
- 未成交前标记价先触 **TP 侧**`trigger_tp_invalidate`.
- **突破触价**另:未穿越 E 先触 **SL 侧**`trigger_sl_invalidate`.
- **24h** 未触发 → `trigger_entry_expired`.
- 成功 → `trigger_entry_filled`;触发后开仓失败 → `trigger_exchange_failed`.
### 4.3 计仓与占位
- **以损定仓**:按 E,SL 反推保证金,触发时重算;**全仓杠杆**:可用×缓冲比例,BTC/ETH 10x,其它 5x.
- **占当日开仓意图**(已开 + 待触发),未成交不占持仓;同币仅 1 条触价监控(含回调/突破).
共享逻辑:`trigger_entry_key_monitor_lib.py`;轮询:`check_trigger_entry_key_monitors`.
---
## 五,环境与参数(`.env` 摘要)
| 变量 | 箱体/收敛 | 阻力/支撑 |
|------|-----------|-----------|
| `KEY_BREAKOUT_AMP_MIN_PCT` | 突破越过下限(默认 0.03) | 不用 |
| `KEY_BREAKOUT_AMP_MAX_PCT` | **已废弃门控** | 不用 |
| `KEY_VOLUME_*` / `KEY_CONFIRM_*` | 用 | 不用 |
| `KEY_AUTO_MIN_PLANNED_RR` | 用 | 不用 |
| `KEY_ALERT_MAX_TIMES` / `KEY_ALERT_INTERVAL_MINUTES` | 不用 | 用(默认 3 次 / 5 分钟) |
| `KEY_DAILY_VOLUME_RANK_MAX` | 添加时 + 运行时 | **仅添加时** |
---
## 六,相关代码
| 说明 | 位置 |
|------|------|
| 共享判定 | `key_monitor_lib.py` |
| 主循环 | `check_key_monitors` |
| 自动门控 | `_key_hard_checks` |
| 阻力/支撑提醒 | `_process_key_rs_level_alert` |
| 录入 | `add_key` |
| 开仓 | `_market_open_for_key_monitor` |
+147 -147
View File
@@ -1,147 +1,147 @@
# 界面与风控更新说明Binance 实例
## 顶栏导航4 项
| 顺序 | 名称 | 路由 | 说明 |
|------|------|------|------|
| 1 | 关键位监控 | `/key_monitor` | 关键位添加实时门控历史 |
| 2 | 实盘下单 | `/trade` | 人工开仓划转实时持仓**默认首页** `/``/trade` |
| 3 | 交易记录与复盘 | `/records` | 交易记录复盘表单AI 历史受顶栏 UTC 时间窗筛选 |
| 4 | 统计分析 | `/stats` | 按北京时间交易日切日 + 分品类统计块 |
## 关键位监控页
- 标题去掉「5m」规则条从 `.env` 读取周期确认K量能自动开仓盈亏比日成交量排名)。
- 左列活跃关键位**pos-card** 样式展示现价/距上沿/距下沿/门控
- 右列关键位历史失效/结案),与左列等高滚动**受顶栏 UTC 列表时间窗筛选**默认 UTC 当日)。
- 监控类型新增**斐波回调0.618****斐波回调0.786**与 Gate 主站同一套规则计算逻辑见仓库根目录 `fib_key_monitor_lib.py`)。
### 斐波关键位监控方案 A交易所限价
| 项 | 说明 |
|----|------|
| 同币互斥 | 每个币种只能有一条斐波监控0.618 与 0.786 不可并存 |
| 上下沿 | 上沿 **H**下沿 **L**须 H > L |
| 挂单价 E | **做多** `E = H ratio × (H L)`自 H 向下回撤);**做空** `E = L + ratio × (H L)`自 L 向上反弹 |
| 做多 | 限价 @ E止损 L止盈 H |
| 做空 | 限价 @ E止损 H止盈 L |
| 添加后 | **立即**在 Binance U 本位挂限价单卡片显示 **挂E**限价单 ID |
| 失效 | 以**标记价**判断做多且标记价 ≥ H做空且标记价 ≤ L且限价**未成交** → 撤销该限价单并结案 |
| 成交后 | 挂交易所 TP/SL含 Algo 通道条件单→ 写入 **实盘下单监控**`monitor_type=关键位监控``key_signal_type=斐波回调…`→ 从关键位列表移除 |
| 撤单 | 仅撤本条斐波的订单 ID**不会**对该合约 `cancel_all_orders` / 全撤 Algo避免误伤其他委托 |
| 盈亏比 | 计划 RR 须 > `KEY_AUTO_MIN_PLANNED_RR`0.618 理论约 1.6:10.786 约 3.7:1 |
| 日成交量 | 与箱体/收敛相同须在前 `KEY_DAILY_VOLUME_RANK_MAX` 名内方可添加 |
后台轮询`check_fib_key_monitors()`箱体/收敛仍走 `check_key_monitors()`
手动删除关键位时未成交斐波会先撤限价再删库
### 箱体 / 收敛自动开仓来源标注
- 自动开仓写入 `order_monitors.key_signal_type``箱体突破``收敛突破`
- 持仓与交易记录展示「来源 · 信号类型」
## 列表时间窗UTC全站顶栏
共用模块仓库根目录 `history_window_lib.py`Gate / Binance 主站一致)。
| 项 | 说明 |
|----|------|
| 默认 | **UTC 当日**`win_preset=utc_today`从 UTC 0:00 至当前时刻 |
| 可选 | 近 24 小时近 7 天自定义起止UTC`datetime-local` |
| 作用范围 | 关键位历史交易记录列表复盘记录 APIAI 历史 API导出「交易记录」「关键位历史」 |
| 与统计的关系 | **仅影响列表/导出****统计分析页仍按北京时间 `TRADING_DAY_RESET_HOUR`默认 8:00切交易日** |
| 库内时间 | DB 存北京时间字符串后端用 `utc_window_to_bj_sql_strings()` 换算后再 SQL 比较 |
| 切换方式 | 顶栏「列表筛选UTC」→ 选预设 → **应用**保留当前路由`/records?win_preset=…` |
查询参数示例
- `?win_preset=utc_today`
- `?win_preset=utc_last24h` / `utc_last7d`
- `?win_preset=custom&from_utc=2026-05-18 00:00:00&to_utc=2026-05-19 12:00:00`
## 交易记录与复盘
- 交易记录盈亏以**本地估算**为准平仓时按成交/计划价计算);盈亏列可标注 **估**
- 与币安 App 不一致时请在「核对修改」或复盘中 **手工填写** `reviewed_pnl_amount` 覆盖展示不再提供批量「同步交易所盈亏」)。
- **列表默认只显示当前 UTC 时间窗内**的记录见上节);导出 CSV 同步该时间窗
- 表头 **「止损(开仓)」**展示开仓快照 `initial_stop_loss`无则回退 `stop_loss`);核对/复盘仍可用有效止损字段
- 平仓写入 `trade_records``stop_loss``initial_stop_loss` 均写入**开仓时止损快照**`key_signal_type` 保留箱体/收敛/斐波来源`fib_key_monitor_lib.key_signal_type_for_trade_record`)。
- **开仓类型**`entry_reason`):机器单平仓入库时若未手填`key_signal_type` 自动映射见下表);列表/导出「开仓类型」列 = 复盘核对值优先否则入库值否则按信号映射
| `key_signal_type` | 自动写入的 `entry_reason` |
|-------------------|---------------------------|
| 箱体突破 | 关键位箱体突破 |
| 收敛突破 | 关键位收敛突破 |
| 斐波回调0.618 | 关键位斐波0.618 |
| 斐波回调0.786 | 关键位斐波0.786 |
- 复盘表单 **开仓类型** 下拉新增上述四条固定文案与趋势/波段类并列)。
- 复盘 **离场触发** 新增 **「止盈」**从交易记录「填入复盘」时若结果为「止盈/保本止盈/移动止盈/止损/手动平仓」会自动选中对应触发项并按 `key_signal_type` 预填开仓类型
- 勾选「保存时自动生成多周期 K 线图」时**平仓时间** 为锚点各周期向前约 `ORDER_CHART_LIMIT`默认 100根 K 线`_fetch_ohlcv_ending_at`),不再固定拉「最近 100 根」
- `/api/journals``/api/reviews` 支持同一时间窗 query与列表一致
### 导出交易记录 v3
- 文件名`trade_records_v3_YYYYMMDD.csv`
- 相对 v2 增加`key_signal_type``initial_stop_loss`及开仓快照列)、`planned_rr``actual_rr``risk_amount`交易所盈亏与时间字段等末列「开仓类型」为有效展示文案
- 「关键位历史」导出同样受 UTC 时间窗限制
## 实盘下单页
- 左列实盘下单监控表单划转规则)。
- 右列实时持仓独立模块)。
- **人工开仓门控**计划盈亏比 &lt; `MANUAL_MIN_PLANNED_RR`默认 **1.4**时前端弹窗 + 后端拒绝
- **移动保本**勾选启用):监控轮询达到触发 RR 后止损阶梯上移时**同步交易所**——**先撤**该合约全部 TP/SL含 Algo 条件单**再挂**新止损 + 原止盈`replace_active_monitor_tpsl_on_exchange`)。仅交易所成功后才写库失败发企业微信告警未配置实盘 API 时仍只更新本地
## 统计分析页`/stats`
| 项 | 说明 |
|----|------|
| 切日 | **北京时间**交易日边界 = 每日 `TRADING_DAY_RESET_HOUR:00``.env` 默认 **8** |
| 品类下拉 | 页顶 **「统计品类」** 下拉切换默认「全部交易」):全部交易下单监控关键位箱体突破关键位收敛结构关键位斐波0.618关键位斐波0.786一次只显示所选品类的日/周/月 |
| URL | 切换后写入 `stats_segment=``all``manual``key_box``key_conv``key_fib618``key_fib786`),刷新 `/stats` 可保持选项 |
| 每块指标 | 日 / 周 / 月开单次数平仓笔数胜率净盈亏回撤连续亏损等与原口径一致 |
| 开单次数 | 人工块`monitor_type=下单监控` 且无 `key_signal_type`关键位块`order_monitors.key_signal_type` 计数 |
| 不受 UTC 窗影响 | 统计始终基于库内全部已平仓记录按北京交易日归类**不**随顶栏 UTC 列表窗切换 |
## 持仓与计仓
- `MAX_ACTIVE_POSITIONS` 默认 **1**可在 `.env` 调大)。
- 关键位自动开仓在已有持仓时`KEY_SIZING_USE_ZERO_POSITION_SNAPSHOT=true`按**首笔开仓前**交易账户资金快照计仓字段 `trading_sessions.key_sizing_capital_snapshot`)。
## 配置
详见 `.env.example` 中「关键位门控」「交易执行 / 人工风控」注释段
## 自动备份服务器
- 脚本`scripts/backup_data.sh``crypto.db` + `static/images`
- 定时`scripts/install_backup_cron.sh` → 每天 **北京时间 0:00**目录 **`/root/backups/<实例名>/YYYY-MM-DD/`**保留 **30**
- 详见 `部署文档.md` 第 5.4 节自动备份
## 数据库启动时自动迁移
`key_monitors` 斐波字段`fib_limit_order_id``fib_entry_price``fib_stop_loss``fib_take_profit``fib_order_amount``fib_margin_capital``fib_leverage`
`trade_records` / `order_monitors``key_signal_type``exchange_realized_pnl``exchange_opened_at``exchange_closed_at``exchange_sync_key``entry_reason``reviewed_entry_reason``initial_stop_loss`
**历史数据**本次**不做**旧记录的批量回填`entry_reason` / `initial_stop_loss` / `key_signal_type`);仅**新产生**的平仓与复盘按新逻辑写入旧行展示可回退已有字段
## 涉及文件便于排查
| 路径 | 说明 |
|------|------|
| `history_window_lib.py` | UTC 时间窗解析与转北京时间 SQL 字符串 |
| `fib_key_monitor_lib.py` | 斐波计算`KEY_ENTRY_REASON_BY_SIGNAL``entry_reason_from_key_signal` |
| `crypto_monitor_binance/app.py` | 列表筛选统计分块导出 v3复盘 K 线锚点入库逻辑 |
| `crypto_monitor_binance/templates/index.html` | 顶栏时间窗统计分块 UI止损(开仓)列复盘预填 |
## 升级步骤
1. `git pull` 后对比 `.env.example`把新增变量合并进本地 `.env`
2. 在 VPS 上为 Binance / Gate / Gate Bot **各执行一次** `bash scripts/install_backup_cron.sh`若尚未安装)。
3. 重启 Binance 实例`pm2 restart crypto_binance`);SQLite 会自动 `ALTER` 缺列斐波交易所盈亏`entry_reason`)。
4. 浏览器强刷Ctrl+F5避免旧版 `index.html` 缓存
5. 打开任意页确认顶栏出现 **「列表筛选UTC」**`/stats` 可见分品类统计与「北京 8:00 切日」说明
6. 建议先用测试币验证斐波限价挂出标记价失效撤单成交后 TP/SL 与订单监控是否正常平仓后检查交易记录止损(开仓)与开仓类型
# 界面与风控更新说明(Binance 实例)
## 顶栏导航(4 项)
| 顺序 | 名称 | 路由 | 说明 |
|------|------|------|------|
| 1 | 关键位监控 | `/key_monitor` | 关键位添加,实时门控,历史 |
| 2 | 实盘下单 | `/trade` | 人工开仓,划转,实时持仓(**默认首页** `/``/trade`) |
| 3 | 交易记录与复盘 | `/records` | 交易记录,复盘表单,AI 历史(受顶栏 UTC 时间窗筛选) |
| 4 | 统计分析 | `/stats` | 按北京时间交易日切日 + 分品类统计块 |
## 关键位监控页
- 标题去掉「5m」;规则条从 `.env` 读取(周期,确认K,量能,自动开仓盈亏比,日成交量排名).
- 左列:活跃关键位,**pos-card** 样式展示现价/距上沿/距下沿/门控.
- 右列:关键位历史(失效/结案),与左列等高滚动;**受顶栏 UTC 列表时间窗筛选**(默认 UTC 当日).
- 监控类型新增:**斐波回调0.618**,**斐波回调0.786**(与 Gate 主站同一套规则,计算逻辑见仓库根目录 `fib_key_monitor_lib.py`).
### 斐波关键位监控(方案 A:交易所限价)
| 项 | 说明 |
|----|------|
| 同币互斥 | 每个币种只能有一条斐波监控(0.618 与 0.786 不可并存) |
| 上下沿 | 上沿 **H**,下沿 **L**(须 H > L) |
| 挂单价 E | **做多** `E = H ratio × (H L)`(自 H 向下回撤);**做空** `E = L + ratio × (H L)`(自 L 向上反弹) |
| 做多 | 限价 @ E,止损 L,止盈 H |
| 做空 | 限价 @ E,止损 H,止盈 L |
| 添加后 | **立即**在 Binance U 本位挂限价单;卡片显示 **挂E**,限价单 ID |
| 失效 | 以**标记价**判断:做多且标记价 ≥ H,做空且标记价 ≤ L,且限价**未成交** → 撤销该限价单并结案 |
| 成交后 | 挂交易所 TP/SL(含 Algo 通道条件单)→ 写入 **实盘下单监控**(`monitor_type=关键位监控`,`key_signal_type=斐波回调…`)→ 从关键位列表移除 |
| 撤单 | 仅撤本条斐波的订单 ID,**不会**对该合约 `cancel_all_orders` / 全撤 Algo,避免误伤其他委托 |
| 盈亏比 | 计划 RR 须 > `KEY_AUTO_MIN_PLANNED_RR`;0.618 理论约 1.6:1,0.786 约 3.7:1 |
| 日成交量 | 与箱体/收敛相同,须在前 `KEY_DAILY_VOLUME_RANK_MAX` 名内方可添加 |
后台轮询:`check_fib_key_monitors()`;箱体/收敛仍走 `check_key_monitors()`.
手动删除关键位时,未成交斐波会先撤限价再删库.
### 箱体 / 收敛自动开仓(来源标注)
- 自动开仓写入 `order_monitors.key_signal_type`:`箱体突破``收敛突破`.
- 持仓与交易记录展示「来源 · 信号类型」.
## 列表时间窗(UTC,全站顶栏)
共用模块:仓库根目录 `history_window_lib.py`(Gate / Binance 主站一致).
| 项 | 说明 |
|----|------|
| 默认 | **UTC 当日**(`win_preset=utc_today`,从 UTC 0:00 至当前时刻) |
| 可选 | 近 24 小时,近 7 天,自定义起止(UTC,`datetime-local`) |
| 作用范围 | 关键位历史,交易记录列表,复盘记录 API,AI 历史 API,导出「交易记录」「关键位历史」 |
| 与统计的关系 | **仅影响列表/导出**;**统计分析页仍按北京时间 `TRADING_DAY_RESET_HOUR`(默认 8:00)切交易日** |
| 库内时间 | DB 存北京时间字符串;后端用 `utc_window_to_bj_sql_strings()` 换算后再 SQL 比较 |
| 切换方式 | 顶栏「列表筛选(UTC)」→ 选预设 → **应用**(保留当前路由,`/records?win_preset=…`) |
查询参数示例:
- `?win_preset=utc_today`
- `?win_preset=utc_last24h` / `utc_last7d`
- `?win_preset=custom&from_utc=2026-05-18 00:00:00&to_utc=2026-05-19 12:00:00`
## 交易记录与复盘
- 交易记录盈亏以**本地估算**为准(平仓时按成交/计划价计算);盈亏列可标注 **估**.
- 与币安 App 不一致时,请在「核对修改」或复盘中 **手工填写** `reviewed_pnl_amount` 覆盖展示(不再提供批量「同步交易所盈亏」).
- **列表默认只显示当前 UTC 时间窗内**的记录(见上节);导出 CSV 同步该时间窗.
- 表头 **「止损(开仓)」**:展示开仓快照 `initial_stop_loss`(无则回退 `stop_loss`);核对/复盘仍可用有效止损字段.
- 平仓写入 `trade_records`:`stop_loss``initial_stop_loss` 均写入**开仓时止损快照**;`key_signal_type` 保留箱体/收敛/斐波来源(`fib_key_monitor_lib.key_signal_type_for_trade_record`).
- **开仓类型**(`entry_reason`):机器单平仓入库时,若未手填,`key_signal_type` 自动映射(见下表);列表/导出「开仓类型」列 = 复盘核对值优先,否则入库值,否则按信号映射.
| `key_signal_type` | 自动写入的 `entry_reason` |
|-------------------|---------------------------|
| 箱体突破 | 关键位箱体突破 |
| 收敛突破 | 关键位收敛突破 |
| 斐波回调0.618 | 关键位斐波0.618 |
| 斐波回调0.786 | 关键位斐波0.786 |
- 复盘表单 **开仓类型** 下拉新增上述四条固定文案(与趋势/波段类并列).
- 复盘 **离场触发** 新增 **「止盈」**;从交易记录「填入复盘」时,若结果为「止盈/保本止盈/移动止盈/止损/手动平仓」会自动选中对应触发项,并按 `key_signal_type` 预填开仓类型.
- 勾选「保存时自动生成多周期 K 线图」时:**平仓时间** 为锚点,各周期向前约 `ORDER_CHART_LIMIT`(默认 100)根 K 线(`_fetch_ohlcv_ending_at`),不再固定拉「最近 100 根」.
- `/api/journals`,`/api/reviews` 支持同一时间窗 query,与列表一致.
### 导出(交易记录 v3)
- 文件名:`trade_records_v3_YYYYMMDD.csv`
- 相对 v2 增加:`key_signal_type`,`initial_stop_loss`(及开仓快照列),`planned_rr`,`actual_rr`,`risk_amount`,交易所盈亏与时间字段等;末列「开仓类型」为有效展示文案.
- 「关键位历史」导出同样受 UTC 时间窗限制.
## 实盘下单页
- 左列:实盘下单监控(表单,划转,规则).
- 右列:实时持仓(独立模块).
- **人工开仓门控**:计划盈亏比 &lt; `MANUAL_MIN_PLANNED_RR`(默认 **1.4**)时前端弹窗 + 后端拒绝.
- **移动保本**(勾选启用):监控轮询达到触发 RR 后,止损阶梯上移时**同步交易所**——**先撤**该合约全部 TP/SL(含 Algo 条件单)**再挂**新止损 + 原止盈(`replace_active_monitor_tpsl_on_exchange`).仅交易所成功后才写库;失败发企业微信告警.未配置实盘 API 时仍只更新本地.
## 统计分析页(`/stats`)
| 项 | 说明 |
|----|------|
| 切日 | **北京时间**;交易日边界 = 每日 `TRADING_DAY_RESET_HOUR:00`(`.env` 默认 **8**) |
| 品类下拉 | 页顶 **「统计品类」** 下拉切换(默认「全部交易」):全部交易,下单监控,关键位箱体突破,关键位收敛结构,关键位斐波0.618,关键位斐波0.786;一次只显示所选品类的日/周/月 |
| URL | 切换后写入 `stats_segment=`(`all`,`manual`,`key_box`,`key_conv`,`key_fib618`,`key_fib786`),刷新 `/stats` 可保持选项 |
| 每块指标 | 日 / 周 / 月:开单次数,平仓笔数,胜率,净盈亏,回撤,连续亏损等(与原口径一致) |
| 开单次数 | 人工块:`monitor_type=下单监控` 且无 `key_signal_type`;关键位块:`order_monitors.key_signal_type` 计数 |
| 不受 UTC 窗影响 | 统计始终基于库内全部已平仓记录,按北京交易日归类,**不**随顶栏 UTC 列表窗切换 |
## 持仓与计仓
- `MAX_ACTIVE_POSITIONS` 默认 **1**(可在 `.env` 调大).
- 关键位自动开仓:在已有持仓时,`KEY_SIZING_USE_ZERO_POSITION_SNAPSHOT=true`,按**首笔开仓前**交易账户资金快照计仓(字段 `trading_sessions.key_sizing_capital_snapshot`).
## 配置
详见 `.env.example` 中「关键位门控」「交易执行 / 人工风控」注释段.
## 自动备份(服务器)
- 脚本:`scripts/backup_data.sh`(`crypto.db` + `static/images`)
- 定时:`scripts/install_backup_cron.sh` → 每天 **北京时间 0:00**,目录 **`/root/backups/<实例名>/YYYY-MM-DD/`**,保留 **30**
- 详见 `部署文档.md` 第 5.4 节(自动备份)
## 数据库(启动时自动迁移)
`key_monitors` 斐波字段:`fib_limit_order_id`,`fib_entry_price`,`fib_stop_loss`,`fib_take_profit`,`fib_order_amount`,`fib_margin_capital`,`fib_leverage`.
`trade_records` / `order_monitors`:`key_signal_type`,`exchange_realized_pnl`,`exchange_opened_at`,`exchange_closed_at`,`exchange_sync_key`,`entry_reason`,`reviewed_entry_reason`,`initial_stop_loss`.
**历史数据**:本次**不做**旧记录的批量回填(`entry_reason` / `initial_stop_loss` / `key_signal_type`);仅**新产生**的平仓与复盘按新逻辑写入.旧行展示可回退已有字段.
## 涉及文件(便于排查)
| 路径 | 说明 |
|------|------|
| `history_window_lib.py` | UTC 时间窗解析与转北京时间 SQL 字符串 |
| `fib_key_monitor_lib.py` | 斐波计算,`KEY_ENTRY_REASON_BY_SIGNAL`,`entry_reason_from_key_signal` |
| `crypto_monitor_binance/app.py` | 列表筛选,统计分块,导出 v3,复盘 K 线锚点,入库逻辑 |
| `crypto_monitor_binance/templates/index.html` | 顶栏时间窗,统计分块 UI,止损(开仓)列,复盘预填 |
## 升级步骤
1. `git pull` 后对比 `.env.example`,把新增变量合并进本地 `.env`.
2. 在 VPS 上为 Binance / Gate / **各执行一次** `bash scripts/install_backup_cron.sh`(若尚未安装).
3. 重启 Binance 实例(`pm2 restart crypto_binance`);SQLite 会自动 `ALTER` 缺列(斐波,交易所盈亏,`entry_reason`).
4. 浏览器强刷(Ctrl+F5)避免旧版 `index.html` 缓存.
5. 打开任意页确认顶栏出现 **「列表筛选(UTC)」**;`/stats` 可见分品类统计与「北京 8:00 切日」说明.
6. 建议先用测试币验证斐波:限价挂出,标记价失效撤单,成交后 TP/SL 与订单监控是否正常;平仓后检查交易记录止损(开仓)与开仓类型.
+389 -389
View File
@@ -1,389 +1,389 @@
# `crypto_monitor_binance` 部署指南SSH SOCKS + Binance + PM2Ubuntu
项目功能环境变量总览见 **[README.md](./README.md)**Ubuntu 环境Python / Node / PM2**[docs/ubuntu-server.md](../docs/ubuntu-server.md)**
本文面向**在本机或 VPS 上运行本项目****直连 Binance API 不稳定超时或被网络策略拦截** 的场景思路是
- 本机用 `ssh -D` 做动态转发把 **SOCKS5 出口**放到能稳定访问 Binance 的机器常见为一台境外 VPS
- 项目在 `.env` 中设置 **`BINANCE_SOCKS_PROXY=socks5h://127.0.0.1:1080`**或你实际端口),`ccxt` 经 SOCKS 访问交易所
- **SSH 隧道**`ssh -D` 在本机常驻可用 **tmux****autossh** 保持连接),**不要** 把 `ssh` 交给 PM2
- 使用 **PM2** 仅托管 **Flask 应用**仓库根目录 **`ecosystem.config.cjs`** 默认进程名为 **`crypto-monitor-binance`**
> 安全提醒不要把 `.env`私钥 `.pem`Binance API Key / Secret 提交到 Git下文只用占位符
---
## 0. 你需要准备的东西
- 一台 **Ubuntu**或同类 Linux运行项目的机器下文称「本机」
- 一台可 SSH 登录**能正常访问 Binance API** 的 VPS示例`HostName` 填你的服务器 IP用户如 `root`
- SSH**私钥登录**推荐便于隧道脚本无人值守
- 本机已安装`python3``python3-venv``pip``curl``ssh``git`可选)、`node` + `npm`安装 PM2
- Binance 账户已开通 **USDT-M 永续合约**API Key 勾选 **合约****万向划转**若使用资金↔合约划转等所需权限并配置 **IP 白名单**若启用
---
## 1. 获取代码与目录
将包含 `app.py` 的项目放到固定目录例如
```bash
mkdir -p /opt/crypto_monitor
cd /opt/crypto_monitor
git clone https://git.bz121.com/dekun/crypto_monitor.git
cd crypto_monitor/crypto_monitor_binance
```
下文用 **`/opt/crypto_monitor/crypto_monitor_binance`** 仅为示例请换成你的实际绝对路径
拉取代码后若目录下尚无 `.env`先从模板生成**勿**把填好密钥的 `.env` 提交 Git):
```bash
cp -n .env.example .env # -n已存在 .env 时不覆盖
```
---
## 2. 配置 SSH 私钥与 `~/.ssh/config`
```bash
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 私钥示例~/.ssh/vps1.pem
chmod 600 ~/.ssh/vps1.pem
```
编辑 `~/.ssh/config`示例别名 **`bn-vps`**与你手工启动 `ssh -D ... bn-vps` 一致即可):
```sshconfig
Host bn-vps
HostName 你的_VPS_IP
User root
IdentityFile ~/.ssh/vps1.pem
IdentitiesOnly yes
ServerAliveInterval 30
ServerAliveCountMax 3
ExitOnForwardFailure yes
BatchMode yes
```
测试
```bash
ssh bn-vps true
```
> 若尚未完全改为密钥登录可暂时注释 `BatchMode yes`调试完成后再打开
---
## 3. 手工验证SSH SOCKS + Binance API
### 3.1 本地 SOCKS示例端口 1080
```bash
ssh -N -D 127.0.0.1:1080 bn-vps
```
保持运行另开终端继续
### 3.2 验证经 SOCKS 可访问 Binance公开接口
```bash
curl -4 -sS --max-time 15 --proxy socks5h://127.0.0.1:1080 https://api.binance.com/api/v3/time
```
应返回 JSON`serverTime` 字段)。若此处失败**不要先启动应用**先修隧道或 VPS 出站
---
## 4. Python 虚拟环境
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
pip install flask requests ccxt werkzeug PySocks Pillow
```
走 SOCKS 时 **必须** 安装 **`PySocks`**否则易出现代理相关报错
可选
```bash
export PYTHONDONTWRITEBYTECODE=1
```
---
## 5. 配置环境变量`.env.example``.env`
| 文件 | 是否进 Git | 说明 |
|------|------------|------|
| **`.env.example`** | ✅ 是 | 变量模板与注释可随 `git pull` 更新 |
| **`.env`** | ❌ 否 | 本机真实配置`app.py` **只读此文件** |
### 5.1 首次配置
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
cp -n .env.example .env # 已存在 .env 时不覆盖
nano .env # 填入 API登录密码端口代理等
```
### 5.2 备份与 `git pull`
- **`.env` 已被仓库根目录 `.gitignore` 忽略**`git pull` **不会**覆盖或删除你本地的 `.env`
- 若远端更新了 **`.env.example`**新增变量名),pull 后请对照模板**手动把新行补进你的 `.env`**不会自动合并进 `.env`)。
- **建议在每次 `git pull` 或大批量改配置前备份**
```bash
cp .env .env.backup.$(date +%Y%m%d)
# 恢复示例cp .env.backup.20260516 .env
```
- **换机 / 迁移**`scp` 复制整份 `.env` 到新机器对应目录或在新机重新 `cp .env.example .env` 后填写
### 5.3 AI 复盘与模型可选
所共用仓库根目录 **`ai_client.py`**PM2 的 **`PYTHONPATH=..`** 须包含仓库根)。`.env` 中配置 **`AI_PROVIDER`**
| 模式 | 主要变量 |
|------|----------|
| **`openai`**默认 | `OPENAI_API_BASE=https://op.bz121.com/v1``OPENAI_API_KEY``OPENAI_MODEL=gemma4:e4b` |
| **`ollama`** | `OLLAMA_API``AI_MODEL`本机 Ollama |
密钥在 [op.bz121.com](https://op.bz121.com/) 的 **`gateway.json`** 页面获取`.env` 后需 **`pm2 restart`** 对应进程详见根目录 **[AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)**
### 5.4 自动备份数据库 + 复盘图片
默认每天 **北京时间 0:00** 备份到 **`/root/backups`**保留 **30 天** 后自动删除更早的目录
备份内容路径来自 `.env``DB_PATH``UPLOAD_DIR`):
- `crypto.db`优先 `sqlite3 .backup` 热备
- `static/images` 打包为 `static_images.tar.gz`
目录结构示例
```text
/root/backups/crypto_monitor_binance/2026-05-17/
crypto.db
static_images.tar.gz
manifest.txt
```
**一次性安装定时任务**在对应项目目录执行Binance / Gate 各执行一次):
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
chmod +x scripts/backup_data.sh scripts/install_backup_cron.sh
bash scripts/install_backup_cron.sh
```
Gate 实例
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
bash scripts/install_backup_cron.sh
```
Gate Bot 实例趋势回调等):
```bash
cd /opt/crypto_monitor/crypto_monitor_gate_bot
bash scripts/install_backup_cron.sh
```
**立即试跑**不写 cron):
```bash
bash scripts/backup_data.sh
```
日志默认`/var/log/crypto-monitor-backup-<项目目录名>.log`可选在 `.env` 中覆盖`BACKUP_ROOT``BACKUP_RETENTION_DAYS``BACKUP_INSTANCE`
**恢复示例**先停 PM2再覆盖文件):
```bash
pm2 stop crypto-monitor-binance
cp /root/backups/crypto_monitor_binance/2026-05-16/crypto.db ./crypto.db
tar -xzf /root/backups/crypto_monitor_binance/2026-05-16/static_images.tar.gz -C .
pm2 start ecosystem.config.cjs
```
建议安装`apt install -y sqlite3`热备更稳)。
### 5.5 必填项检查Binance + 代理
与交易所相关的变量使用 **`BINANCE_`** 前缀与代码一致)。至少确认
```env
APP_HOST=127.0.0.1
APP_PORT=5000
# 实盘按需
LIVE_TRADING_ENABLED=false
BINANCE_API_KEY=你的_Key
BINANCE_API_SECRET=你的_Secret
# 保证金cross=全仓 isolated=逐仓与币安账户/习惯一致
BINANCE_MARGIN_MODE=cross
# 持仓模式hedge=双向需在币安开启双向持仓);oneway=单向
BINANCE_POSITION_MODE=hedge
# 条件单触发参考CONTRACT_PRICE=最新成交价 MARK_PRICE=标记价
BINANCE_TRIGGER_WORKING_TYPE=CONTRACT_PRICE
# 经本机 SSH 动态转发访问 Binance端口与隧道一致
BINANCE_SOCKS_PROXY=socks5h://127.0.0.1:1080
# 若不用 SOCKS可改用 HTTP 代理一般二选一
# BINANCE_HTTP_PROXY=http://127.0.0.1:7890
# BINANCE_HTTPS_PROXY=http://127.0.0.1:7890
```
说明**推荐 `socks5h://`**由 SOCKS 端解析域名`curl --proxy socks5h://...` 行为一致
**止盈止损说明应用逻辑**实盘开仓后程序会在 Binance USDT-M 永续上挂 **`STOP_MARKET`止损** 与 **`TAKE_PROFIT_MARKET`止盈**`BINANCE_POSITION_MODE=hedge` 时会自动带 **`positionSide`**须与币安合约「双向持仓」开关一致不显式传 **`reduceOnly`**否则易触发 API **`-1106`**`Parameter 'reduceOnly' sent when not required`)。
---
## 6. 自检脚本可选
在已配置 `.env` 且网络可达的前提下
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
source .venv/bin/activate
python scripts/verify_binance_funding.py
```
用于粗测资金钱包与合约钱包 USDT 读取需有效 API 与权限)。
---
## 7. 手工启动 Flask验证
1. SOCKS 已监听 `127.0.0.1:1080`若使用代理
2. 已 `source .venv/bin/activate`
3. `.env` 已按需配置 `BINANCE_SOCKS_PROXY`
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
source .venv/bin/activate
python app.py
```
浏览器访问`http://127.0.0.1:5000`或你在 `.env` 中的端口)。
---
## 8. 安装 PM2
```bash
sudo npm i -g pm2
pm2 -v
```
---
## 9. PM2使用仓库内 `ecosystem.config.cjs`推荐
在项目根目录
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
pm2 start ecosystem.config.cjs
pm2 status
pm2 logs --lines 200
```
默认只启动 **`crypto-monitor-binance`**`.venv/bin/python app.py`)。
### 本机已可直连 Binance不需要隧道时
`.env` 里应 **去掉或留空** `BINANCE_SOCKS_PROXY`除非仍要走别的代理),`pm2 start ecosystem.config.cjs`
### 开机自启
```bash
pm2 save
pm2 startup
# 按屏幕提示执行一条 sudo 命令
```
---
## 10. 等价手工命令不使用 ecosystem 文件时
### 10.1 SSH SOCKS自行后台常驻不推荐用 PM2
示例前台调试生产请用 **PM2**见本文 §6 与 [docs/ubuntu-server.md](../docs/ubuntu-server.md)):
```bash
ssh -N -D 127.0.0.1:1080 bn-vps \
-o ServerAliveInterval=30 -o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes
```
### 10.2 Flask
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
pm2 start /opt/crypto_monitor/crypto_monitor_binance/.venv/bin/python --name crypto-monitor-binance -- \
/opt/crypto_monitor/crypto_monitor_binance/app.py
```
---
## 11. 交易所「连接不上」排查清单
1. **`.env` 是否为 Binance 变量**`BINANCE_SOCKS_PROXY` / `BINANCE_HTTP_PROXY` / `BINANCE_API_KEY` / `BINANCE_API_SECRET` 等前缀需与代码一致
2. **隧道是否在本机端口监听**若配置了 `BINANCE_SOCKS_PROXY`):
```bash
ss -lntp | grep 1080 || true
```
3. **curl 复测 Binance**与第 3.2 节相同);curl 不通则应用也不会通
4. **PySocks**`pip show PySocks`缺失则 `pip install PySocks`
5. **SSH 隧道连不上**检查私钥权限`~/.ssh/config`VPS 出站与端口是否与 `.env` 一致
6. **API 权限与 IP 白名单**Secret 错误权限不足未放行当前出口 IP 时私有接口会失败
7. **启动顺序**若走代理先保证 SOCKS 已监听`pm2 start` 应用或重启应用)。
---
## 12. 推荐启动顺序习惯
1. 若走代理先启动并确认 SSH SOCKS 已监听`curl --proxy socks5h://127.0.0.1:1080 https://api.binance.com/api/v3/time` 成功
2. `pm2 start ecosystem.config.cjs`
3. 再确认页面与余额等接口正常
---
## 13. 免责声明
交易所有合规与地区政策要求请确保使用方式符合当地法律法规与交易所条款本文仅描述网络与工程部署路径
---
## 附录数据库标签修复脚本 `scripts/fix_breakeven_labels.py`
在 Ubuntu 上
1预览不写库):
```bash
python scripts/fix_breakeven_labels.py --db ./crypto.db --dry-run
```
2确认后执行
```bash
python scripts/fix_breakeven_labels.py --db ./crypto.db --apply
```
默认修复条件`monitor_type='下单监控'``result='止损'``pnl_amount > 0` → 改为 `result='保本止盈'`
# `crypto_monitor_binance` 部署指南:SSH SOCKS + Binance + PM2(Ubuntu)
项目功能,环境变量总览见 **[README.md](./README.md)**.Ubuntu 环境(Python / Node / PM2)**[docs/ubuntu-server.md](../docs/ubuntu-server.md)**.
本文面向:**在本机或 VPS 上运行本项目**,**直连 Binance API 不稳定,超时或被网络策略拦截** 的场景.思路是:
- 本机用 `ssh -D` 做动态转发,把 **SOCKS5 出口**放到能稳定访问 Binance 的机器(常见为一台境外 VPS)
- 项目在 `.env` 中设置 **`BINANCE_SOCKS_PROXY=socks5h://127.0.0.1:1080`**(或你实际端口),`ccxt` 经 SOCKS 访问交易所
- **SSH 隧道**:`ssh -D` 在本机常驻(可用 **tmux****autossh** 保持连接),**不要** 把 `ssh` 交给 PM2
- 使用 **PM2** 仅托管 **Flask 应用**;仓库根目录 **`ecosystem.config.cjs`** 默认进程名为 **`crypto-monitor-binance`**
> 安全提醒:不要把 `.env`,私钥 `.pem`,Binance API Key / Secret 提交到 Git;下文只用占位符.
---
## 0. 你需要准备的东西
- 一台 **Ubuntu**(或同类 Linux)运行项目的机器(下文称「本机」)
- 一台可 SSH 登录,**能正常访问 Binance API** 的 VPS(示例:`HostName` 填你的服务器 IP,用户如 `root`)
- SSH:**私钥登录**(推荐,便于隧道脚本无人值守)
- 本机已安装:`python3`,`python3-venv`,`pip`,`curl`,`ssh`,`git`(可选),`node` + `npm`(安装 PM2)
- Binance 账户:已开通 **USDT-M 永续合约**;API Key 勾选 **合约**,**万向划转**(若使用资金↔合约划转)等所需权限,并配置 **IP 白名单**(若启用)
---
## 1. 获取代码与目录
将包含 `app.py` 的项目放到固定目录,例如:
```bash
mkdir -p /opt/crypto_monitor
cd /opt/crypto_monitor
git clone https://git.bz121.com/dekun/crypto_monitor.git
cd crypto_monitor/crypto_monitor_binance
```
下文用 **`/opt/crypto_monitor/crypto_monitor_binance`** 仅为示例,请换成你的实际绝对路径.
拉取代码后,若目录下尚无 `.env`,先从模板生成(**勿**把填好密钥的 `.env` 提交 Git):
```bash
cp -n .env.example .env # -n:已存在 .env 时不覆盖
```
---
## 2. 配置 SSH 私钥与 `~/.ssh/config`
```bash
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 私钥示例:~/.ssh/vps1.pem
chmod 600 ~/.ssh/vps1.pem
```
编辑 `~/.ssh/config`(示例别名 **`bn-vps`**,与你手工启动 `ssh -D ... bn-vps` 一致即可):
```sshconfig
Host bn-vps
HostName 你的_VPS_IP
User root
IdentityFile ~/.ssh/vps1.pem
IdentitiesOnly yes
ServerAliveInterval 30
ServerAliveCountMax 3
ExitOnForwardFailure yes
BatchMode yes
```
测试:
```bash
ssh bn-vps true
```
> 若尚未完全改为密钥登录,可暂时注释 `BatchMode yes`,调试完成后再打开.
---
## 3. 手工验证:SSH SOCKS + Binance API
### 3.1 本地 SOCKS(示例端口 1080)
```bash
ssh -N -D 127.0.0.1:1080 bn-vps
```
保持运行,另开终端继续.
### 3.2 验证经 SOCKS 可访问 Binance(公开接口)
```bash
curl -4 -sS --max-time 15 --proxy socks5h://127.0.0.1:1080 https://api.binance.com/api/v3/time
```
应返回 JSON(`serverTime` 字段).若此处失败,**不要先启动应用**:先修隧道或 VPS 出站.
---
## 4. Python 虚拟环境
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
pip install flask requests ccxt werkzeug PySocks Pillow
```
走 SOCKS 时 **必须** 安装 **`PySocks`**,否则易出现代理相关报错.
可选:
```bash
export PYTHONDONTWRITEBYTECODE=1
```
---
## 5. 配置环境变量(`.env.example``.env`)
| 文件 | 是否进 Git | 说明 |
|------|------------|------|
| **`.env.example`** | ✅ 是 | 变量模板与注释,可随 `git pull` 更新 |
| **`.env`** | ❌ 否 | 本机真实配置;`app.py` **只读此文件** |
### 5.1 首次配置
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
cp -n .env.example .env # 已存在 .env 时不覆盖
nano .env # 填入 API,登录密码,端口,代理等
```
### 5.2 备份与 `git pull`
- **`.env` 已被仓库根目录 `.gitignore` 忽略**:`git pull` **不会**覆盖或删除你本地的 `.env`.
- 若远端更新了 **`.env.example`**(新增变量名),pull 后请对照模板,**手动把新行补进你的 `.env`**(不会自动合并进 `.env`).
- **建议在每次 `git pull` 或大批量改配置前备份**:
```bash
cp .env .env.backup.$(date +%Y%m%d)
# 恢复示例:cp .env.backup.20260516 .env
```
- **换机 / 迁移**:`scp` 复制整份 `.env` 到新机器对应目录;或在新机重新 `cp .env.example .env` 后填写.
### 5.3 AI 复盘与模型(可选)
所共用仓库根目录 **`ai_client.py`**(PM2 的 **`PYTHONPATH=..`** 须包含仓库根).`.env` 中配置 **`AI_PROVIDER`**:
| 模式 | 主要变量 |
|------|----------|
| **`openai`**(默认) | `OPENAI_API_BASE=https://op.bz121.com/v1`,`OPENAI_API_KEY`,`OPENAI_MODEL=gemma4:e4b` |
| **`ollama`** | `OLLAMA_API`,`AI_MODEL`(本机 Ollama) |
密钥在 [op.bz121.com](https://op.bz121.com/) 的 **`gateway.json`** 页面获取.`.env` 后需 **`pm2 restart`** 对应进程.详见根目录 **[AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)**.
### 5.4 自动备份(数据库 + 复盘图片)
默认每天 **北京时间 0:00** 备份到 **`/root/backups`**,保留 **30 天** 后自动删除更早的目录.
备份内容(路径来自 `.env``DB_PATH`,`UPLOAD_DIR`):
- `crypto.db`(优先 `sqlite3 .backup` 热备)
- `static/images` 打包为 `static_images.tar.gz`
目录结构示例:
```text
/root/backups/crypto_monitor_binance/2026-05-17/
crypto.db
static_images.tar.gz
manifest.txt
```
**一次性安装定时任务**(在对应项目目录执行,Binance / Gate 各执行一次):
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
chmod +x scripts/backup_data.sh scripts/install_backup_cron.sh
bash scripts/install_backup_cron.sh
```
Gate 实例:
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
bash scripts/install_backup_cron.sh
```
实例(趋势回调等):
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
bash scripts/install_backup_cron.sh
```
**立即试跑**(不写 cron):
```bash
bash scripts/backup_data.sh
```
日志默认:`/var/log/crypto-monitor-backup-<项目目录名>.log`.可选在 `.env` 中覆盖:`BACKUP_ROOT`,`BACKUP_RETENTION_DAYS`,`BACKUP_INSTANCE`.
**恢复示例**(先停 PM2,再覆盖文件):
```bash
pm2 stop crypto-monitor-binance
cp /root/backups/crypto_monitor_binance/2026-05-16/crypto.db ./crypto.db
tar -xzf /root/backups/crypto_monitor_binance/2026-05-16/static_images.tar.gz -C .
pm2 start ecosystem.config.cjs
```
建议安装:`apt install -y sqlite3`(热备更稳).
### 5.5 必填项检查(Binance + 代理)
与交易所相关的变量使用 **`BINANCE_`** 前缀(与代码一致).至少确认:
```env
APP_HOST=127.0.0.1
APP_PORT=5000
# 实盘(按需)
LIVE_TRADING_ENABLED=false
BINANCE_API_KEY=你的_Key
BINANCE_API_SECRET=你的_Secret
# 保证金:cross=全仓 isolated=逐仓(与币安账户/习惯一致)
BINANCE_MARGIN_MODE=cross
# 持仓模式:hedge=双向(需在币安开启双向持仓);oneway=单向
BINANCE_POSITION_MODE=hedge
# 条件单触发参考:CONTRACT_PRICE=最新成交价 MARK_PRICE=标记价
BINANCE_TRIGGER_WORKING_TYPE=CONTRACT_PRICE
# 经本机 SSH 动态转发访问 Binance(端口与隧道一致)
BINANCE_SOCKS_PROXY=socks5h://127.0.0.1:1080
# 若不用 SOCKS,可改用 HTTP 代理(一般二选一)
# BINANCE_HTTP_PROXY=http://127.0.0.1:7890
# BINANCE_HTTPS_PROXY=http://127.0.0.1:7890
```
说明:**推荐 `socks5h://`**,由 SOCKS 端解析域名,`curl --proxy socks5h://...` 行为一致.
**止盈止损说明(应用逻辑)**:实盘开仓后,程序会在 Binance USDT-M 永续上挂 **`STOP_MARKET`(止损)** 与 **`TAKE_PROFIT_MARKET`(止盈)**;`BINANCE_POSITION_MODE=hedge` 时会自动带 **`positionSide`**,须与币安合约「双向持仓」开关一致.不显式传 **`reduceOnly`**(否则易触发 API **`-1106`**:`Parameter 'reduceOnly' sent when not required`).
---
## 6. 自检脚本(可选)
在已配置 `.env` 且网络可达的前提下:
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
source .venv/bin/activate
python scripts/verify_binance_funding.py
```
用于粗测资金钱包与合约钱包 USDT 读取(需有效 API 与权限).
---
## 7. 手工启动 Flask(验证)
1. SOCKS 已监听 `127.0.0.1:1080`(若使用代理)
2. 已 `source .venv/bin/activate`
3. `.env` 已按需配置 `BINANCE_SOCKS_PROXY`
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
source .venv/bin/activate
python app.py
```
浏览器访问:`http://127.0.0.1:5000`(或你在 `.env` 中的端口).
---
## 8. 安装 PM2
```bash
sudo npm i -g pm2
pm2 -v
```
---
## 9. PM2:使用仓库内 `ecosystem.config.cjs`(推荐)
在项目根目录:
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
pm2 start ecosystem.config.cjs
pm2 status
pm2 logs --lines 200
```
默认只启动 **`crypto-monitor-binance`**(`.venv/bin/python app.py`).
### 本机已可直连 Binance,不需要隧道时
`.env` 里应 **去掉或留空** `BINANCE_SOCKS_PROXY`(除非仍要走别的代理),`pm2 start ecosystem.config.cjs`.
### 开机自启
```bash
pm2 save
pm2 startup
# 按屏幕提示执行一条 sudo 命令
```
---
## 10. 等价手工命令(不使用 ecosystem 文件时)
### 10.1 SSH SOCKS(自行后台常驻,不推荐用 PM2)
示例(前台调试;生产请用 **PM2**,见本文 §6 与 [docs/ubuntu-server.md](../docs/ubuntu-server.md)):
```bash
ssh -N -D 127.0.0.1:1080 bn-vps \
-o ServerAliveInterval=30 -o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes
```
### 10.2 Flask
```bash
cd /opt/crypto_monitor/crypto_monitor_binance
pm2 start /opt/crypto_monitor/crypto_monitor_binance/.venv/bin/python --name crypto-monitor-binance -- \
/opt/crypto_monitor/crypto_monitor_binance/app.py
```
---
## 11. 交易所「连接不上」排查清单
1. **`.env` 是否为 Binance 变量**:`BINANCE_SOCKS_PROXY` / `BINANCE_HTTP_PROXY` / `BINANCE_API_KEY` / `BINANCE_API_SECRET` 等前缀需与代码一致.
2. **隧道是否在本机端口监听**(若配置了 `BINANCE_SOCKS_PROXY`):
```bash
ss -lntp | grep 1080 || true
```
3. **curl 复测 Binance**(与第 3.2 节相同);curl 不通则应用也不会通.
4. **PySocks**:`pip show PySocks`,缺失则 `pip install PySocks`.
5. **SSH 隧道连不上**:检查私钥权限,`~/.ssh/config`,VPS 出站与端口是否与 `.env` 一致.
6. **API 权限与 IP 白名单**:Secret 错误,权限不足,未放行当前出口 IP 时,私有接口会失败.
7. **启动顺序**:若走代理,先保证 SOCKS 已监听,`pm2 start` 应用(或重启应用).
---
## 12. 推荐启动顺序(习惯)
1. 若走代理:先启动并确认 SSH SOCKS 已监听,`curl --proxy socks5h://127.0.0.1:1080 https://api.binance.com/api/v3/time` 成功
2. `pm2 start ecosystem.config.cjs`
3. 再确认页面与余额等接口正常
---
## 13. 免责声明
交易所有合规与地区政策要求.请确保使用方式符合当地法律法规与交易所条款.本文仅描述网络与工程部署路径.
---
## 附录:数据库标签修复脚本 `scripts/fix_breakeven_labels.py`
在 Ubuntu 上:
1)预览(不写库):
```bash
python scripts/fix_breakeven_labels.py --db ./crypto.db --dry-run
```
2)确认后执行:
```bash
python scripts/fix_breakeven_labels.py --db ./crypto.db --apply
```
默认修复条件:`monitor_type='下单监控'``result='止损'``pnl_amount > 0` → 改为 `result='保本止盈'`.
+98 -73
View File
@@ -1,104 +1,127 @@
# =============================================================================
# 环境配置模板可提交 Git)。程序运行时只读取同目录下的 .env
# 环境配置模板(可提交 Git).程序运行时只读取同目录下的 .env.
#
# 首次部署 / 新机
# 首次部署 / 新机:
# cp .env.example .env
# nano .env # 填入真实密钥端口代理等
# nano .env # 填入真实密钥,端口,代理等
#
# 升级代码git pull前建议备份.env 不在 Git 中pull 不会覆盖):
# 升级代码(git pull)前建议备份(.env 不在 Git 中,pull 不会覆盖):
# cp .env .env.backup.$(date +%Y%m%d)
#
# 从备份恢复
# 从备份恢复:
# cp .env.backup.YYYYMMDD .env
# =============================================================================
APP_ENV=production
# 服务监听地址云服务器通常用 0.0.0.0
# 服务监听地址(云服务器通常用 0.0.0.0)
APP_HOST=0.0.0.0
# 服务端口
APP_PORT=5000
# 是否开启调试模式生产建议 false
# 是否开启调试模式(生产建议 false)
APP_DEBUG=false
# 登录账号
APP_USERNAME=admin
# 登录密码请改成你自己的强密码
# 登录密码(请改成你自己的强密码)
APP_PASSWORD=admin123
# 是否关闭登录校验局域网可设 true公网务必 false
# 是否关闭登录校验(局域网可设 true;公网务必 false)
APP_AUTH_DISABLED=true
# --- 多账户交易中控 manual_trading_hub ---
# 中控请求本实例 /api/hub/* 时携带请求头 X-Hub-Token须与中控启动环境变量 HUB_BRIDGE_TOKEN 一致
# 未设置且 APP_AUTH_DISABLED=false 时仅网页登录后可访问本机联调可保持 APP_AUTH_DISABLED=true
# 中控请求本实例 /api/hub/* 时携带请求头 X-Hub-Token,须与中控启动环境变量 HUB_BRIDGE_TOKEN 一致
# 未设置且 APP_AUTH_DISABLED=false 时,仅网页登录后可访问;本机联调可保持 APP_AUTH_DISABLED=true
# HUB_BRIDGE_TOKEN=your-long-random-token
# Flask 会话密钥必须替换为长随机字符串
# Flask 会话密钥(必须替换为长随机字符串)
FLASK_SECRET_KEY=CHANGE_TO_LONG_RANDOM_SECRET
# 企业微信机器人 Webhook用于行情/风控推送
# 企业微信机器人 Webhook(用于行情/风控推送)
WECHAT_WEBHOOK=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=REPLACE_WITH_REAL_KEY
# 数据库文件路径相对路径会自动按项目目录解析
# 数据库文件路径(相对路径会自动按项目目录解析)
DB_PATH=crypto.db
# 交易截图上传目录
UPLOAD_DIR=static/images
# 自动备份scripts/backup_data.sh + cron可选默认即可
# 自动备份(scripts/backup_data.sh + cron,可选;默认即可)
# BACKUP_ROOT=/root/backups
# BACKUP_RETENTION_DAYS=30
# BACKUP_INSTANCE=crypto_monitor_gate
# 已废弃资金账户仅显示交易所 funding 余额不再读取此变量
# 已废弃:资金账户仅显示交易所 funding 余额,不再读取此变量
# TOTAL_CAPITAL=100
# 计仓risk=以损定仓默认);full_margin=合约可用×FULL_MARGIN_BUFFER_RATIO 全仓杠杆须无仓后重启
# 计仓:risk=以损定仓(默认);full_margin=合约可用×FULL_MARGIN_BUFFER_RATIO 全仓杠杆(须无仓后重启)
POSITION_SIZING_MODE=risk
# 每天起始基数(U
# 方向限制(默认 false=双向均可;true 时按 TRADE_DIRECTION 限制,修改后须重启)
# TRADE_DIRECTION=long_only | short_only | both(或 多/空/双向)
TRADE_DIRECTION_RESTRICT_ENABLED=false
TRADE_DIRECTION=both
# 币种白名单(默认 false=全币种可手输;true 时关键位/下单/策略仅下拉选择)
TRADE_SYMBOL_RESTRICT_ENABLED=false
TRADE_SYMBOL_WHITELIST=BTC,ETH
# 每天起始基数(U)
DAILY_START_CAPITAL=30
# 日内回撤后基数U
# 日内回撤后基数(U)
DAILY_LOSS_CAPITAL=20
# 日内盈利后基数U
# 日内盈利后基数(U)
DAILY_PROFIT_CAPITAL=50
# BTC 默认杠杆倍数
BTC_LEVERAGE=10
# 山寨币默认杠杆倍数
ALT_LEVERAGE=5
# 交易日重置小时北京时间
# 交易日重置小时(北京时间)
TRADING_DAY_RESET_HOUR=8
# 整点前禁止新开仓true=启用默认),false=关闭仍可保留 8 点作为交易日划分
# 整点前禁止新开仓:true=启用(默认),false=关闭(仍可保留 8 点作为交易日划分)
TRADING_DAY_RESET_OPEN_GUARD_ENABLED=true
# 是否开启 Gate 实盘下单false=只做本地流程true=真实下单
# 是否开启 Gate 实盘下单(false=只做本地流程,true=真实下单)
LIVE_TRADING_ENABLED=true
# Gate API Key实盘
# Gate API Key(实盘)
GATE_API_KEY=REPLACE_WITH_GATE_API_KEY
# Gate API Secret实盘
# Gate API Secret(实盘)
GATE_API_SECRET=REPLACE_WITH_GATE_API_SECRET
# 保证金模式cross=全仓isolated=逐仓
# 保证金模式:cross=全仓,isolated=逐仓
GATE_TD_MODE=cross
# 持仓筛选hedge=双向持仓下按多空腿过滤其它值如 single不按腿过滤
# 持仓筛选:hedge=双向持仓下按多空腿过滤;其它值(如 single)不按腿过滤
GATE_POS_MODE=hedge
# 永续止盈止损是否优先用官方仓位类触发单POST price_ordersclose-*-position);false=仅用旧版两张 ccxt 条件单
# 永续止盈止损:是否优先用官方仓位类触发单(POST price_orders,close-*-position);false=仅用旧版两张 ccxt 条件单
GATE_TPSL_USE_POSITION_ORDER=true
# 触发单超时(秒),默认 604800=7 天设为 0 或负数则不向 API 传 expiration
# 触发单超时(秒),默认 604800=7 天;设为 0 或负数则不向 API 传 expiration
GATE_TPSL_TRIGGER_EXPIRATION=604800
# 触发参考价0=最新成交 1=标记价 2=指数价非法值按 0
# 触发参考价:0=最新成交 1=标记价 2=指数价(非法值按 0)
GATE_TPSL_PRICE_TYPE=0
# 仓位类 TP/SL 相对现价的最小间距%),避免 Gate 1026「触发价须高于/低于现价」
# 仓位类 TP/SL 相对现价的最小间距(%),避免 Gate 1026「触发价须高于/低于现价」
GATE_TPSL_LAST_PRICE_GAP_PCT=0.05
# 页面与浏览器标签展示的交易所名称多环境区分时可改成例如 Gate·模拟
# EXCHANGE_DISPLAY_NAME=Gate.io
# 页面与浏览器标签展示的交易所名称(多环境区分时可改成例如 Gate·模拟)
EXCHANGE_DISPLAY_NAME=Gate.io
# =============================================================================
# 关键位门控(页面「关键位监控」规则条与 _key_hard_checks 共用)
# 关键位程序自动下单(与 POSITION_SIZING_MODE 联动,修改后须重启 PM2)
# =============================================================================
# 【周期】门控 K 线周期,如 5m、15m
# 默认 false = 关闭所有关键位程序自动单(箱体/收敛/斐波/假突破/触价)
#
# POSITION_SIZING_MODE=risk(以损定仓)
# false → 不执行任何关键位自动单;支撑/阻力提醒,人工下单,顺势加仓不受影响
# true → 允许关键位全套自动(含触价)
#
# POSITION_SIZING_MODE=full_margin(全仓杠杆,须无仓切换)
# false → 不执行触价自动单
# true → 仅回调/突破触价可程序自动开仓;箱体/斐波等仍禁止
#
# 顺势加仓,趋势回调不受本开关控制;全仓模式下策略自动仍禁止.
KEY_AUTO_ORDER_ENABLED=false
# =============================================================================
# 关键位门控(页面「关键位监控」规则条与 _key_hard_checks 共用)
# =============================================================================
# 【周期】门控 K 线周期,如 5m,15m
KLINE_TIMEFRAME=5m
# 【确认K】闭合 K 序列中的棒偏移突破棒默认 -2确认棒默认 -1
# 【确认K】闭合 K 序列中的棒偏移:突破棒默认 -2,确认棒默认 -1
KEY_CONFIRM_BREAKOUT_BAR=-2
KEY_CONFIRM_BAR=-1
# 【量能】突破棒成交量 > 前 N 根均量 × 倍数
KEY_VOLUME_MA_BARS=20
KEY_VOLUME_RATIO_MIN=1.3
# 【突破K实体幅度】占开盘价百分比区间
# 【箱体/收敛】突破K收盘越过关键位下限%无上限过猛由计划RR过滤
# 【箱体/收敛】突破K收盘越过关键位下限%;无上限(过猛由计划RR过滤)
KEY_BREAKOUT_AMP_MIN_PCT=0.03
KEY_BREAKOUT_AMP_MAX_PCT=0.5
# 【阻力/支撑】突破后微信提醒
@@ -108,71 +131,73 @@ KEY_ALERT_INTERVAL_MINUTES=5
KEY_DAILY_VOLUME_RANK_MAX=30
# 【关键位自动开仓盈亏比】严格大于该值才市价开仓
KEY_AUTO_MIN_PLANNED_RR=1.5
# 止损突破 K 极值向外缓冲的百分比默认 0.5 即 0.5%
# 止损:突破 K 极值向外缓冲的百分比(默认 0.5 即 0.5%)
KEY_STOP_OUTSIDE_BREAKOUT_PCT=0.5
# 趋势单方案止损在突破 K 极值外侧的百分比默认 1 即 1%
# 趋势单方案:止损在突破 K 极值外侧的百分比(默认 1 即 1%)
KEY_TREND_STOP_OUTSIDE_PCT=1
KEY_ALERT_MAX_TIMES=3
KEY_ALERT_INTERVAL_MINUTES=5
# =============================================================================
# 交易执行 / 人工风控页面「实盘下单」
# 交易执行 / 人工风控(页面「实盘下单」)
# =============================================================================
# 【最大同时持仓】默认 1=单仓
MAX_ACTIVE_POSITIONS=1
# 【人工下单最低盈亏比】低于该值前后端均拒绝默认 1.4即须 >=1.4:1
# 【人工下单最低盈亏比】低于该值前后端均拒绝(默认 1.4,即须 >=1.4:1)
MANUAL_MIN_PLANNED_RR=1.4
# 【关键位连开计仓】已有持仓时按无仓时资金快照算基数
KEY_SIZING_USE_ZERO_POSITION_SNAPSHOT=true
# 【单日开仓 AI 提醒】本交易日开仓达到该次数时推送企业微信 AI 克制提醒不拦单
# 【单日开仓 AI 提醒】本交易日开仓达到该次数时推送企业微信 AI 克制提醒(不拦单)
DAILY_OPEN_ALERT_THRESHOLD=5
# 【单日开仓硬上限】本交易日开仓次数>=该值后禁止一切新开仓直至下一交易日北京时间 TRADING_DAY_RESET_HOUR 切日);0=不启用
# 【单日开仓硬上限】本交易日开仓次数>=该值后禁止一切新开仓直至下一交易日(北京时间 TRADING_DAY_RESET_HOUR 切日);0=不启用
DAILY_OPEN_HARD_LIMIT=0
# =============================================================================
# 账户冷静期 / 日冻结风控手动平仓外部平仓复盘情绪标签
# 账户冷静期 / 日冻结风控(手动平仓,外部平仓,复盘情绪标签)
# 详见 docs/account-risk-cooldown.md
# =============================================================================
# RISK_CONTROL_ENABLED=true
# RISK_COOLING_HOURS_MANUAL=4
# RISK_COOLING_HOURS_MANUAL_JOURNAL=1
# RISK_MANUAL_CLOSE_DAILY_LIMIT=2
# RISK_MOOD_ISSUES_DAILY_FREEZE=true
RISK_CONTROL_ENABLED=true
RISK_COOLING_HOURS_MANUAL=4
RISK_COOLING_HOURS_MANUAL_JOURNAL=1
RISK_MANUAL_CLOSE_DAILY_LIMIT=2
# 日亏损次数上限:平仓盈亏<0 计1次;达限当日冻结开仓;0=不启用
RISK_DAILY_LOSS_LIMIT=2
RISK_MOOD_ISSUES_DAILY_FREEZE=true
# 资金与仓位刷新周期(秒)
# 资金与仓位刷新周期(秒)
BALANCE_REFRESH_SECONDS=60
# 前端价格快照轮询(秒)
# 前端价格快照轮询(秒)
PRICE_REFRESH_SECONDS=5
# 后台监控轮询周期(秒)
# 后台监控轮询周期(秒)
MONITOR_POLL_SECONDS=3
# 重启后多少秒内不做「外部平仓」同步避免 API 未就绪误判
# 重启后多少秒内不做「外部平仓」同步(避免 API 未就绪误判)
RECONCILE_STARTUP_GRACE_SEC=90
# 连续多少次轮询确认交易所空仓后才记为外部平仓默认 3 次 ≈ 9 秒
# 连续多少次轮询确认交易所空仓后,才记为外部平仓(默认 3 次 ≈ 9 秒)
RECONCILE_FLAT_CONFIRM_POLLS=3
# 使用可用资金时的缓冲比例如0.98代表用98%
# 使用可用资金时的缓冲比例(如0.98代表用98%)
FULL_MARGIN_BUFFER_RATIO=0.98
# =============================================================================
# 自动划转页顶「将 swap 补足到 XU」与 DAILY_START_CAPITAL 独立需一致时请设为相同值
# 自动划转(页顶「将 swap 补足到 XU」;与 DAILY_START_CAPITAL 独立,需一致时请设为相同值)
# =============================================================================
AUTO_TRANSFER_ENABLED=false
# 交易账户(swap)目标余额 U每日 8 点(北京)自动划入或划出至 funding持仓中不划转
# 交易账户(swap)目标余额 U:每日 8 点(北京)自动划入或划出至 funding;持仓中不划转
AUTO_TRANSFER_AMOUNT=30
AUTO_TRANSFER_FROM=funding
AUTO_TRANSFER_TO=swap
TRANSFER_CCY=USDT
# 北京时间该整点小时内尝试账簿按 UTC 自然日去重
# 北京时间该整点小时内尝试;账簿按 UTC 自然日去重
AUTO_TRANSFER_BJ_HOUR=8
# 强制清仓整点北京时间默认 0=凌晨00点
# 强制清仓整点(北京时间,默认 0=凌晨00点)
FORCE_CLOSE_BJ_HOUR=0
# 是否启用强制清仓默认关闭true 才会在整点执行
# 是否启用强制清仓(默认关闭,true 才会在整点执行)
FORCE_CLOSE_ENABLED=false
# 推送与AI超时(秒)
# 推送与AI超时(秒)
WECHAT_TIMEOUT_SECONDS=10
AI_TIMEOUT_SECONDS=120
# AI 提供方openai默认| ollama
# AI 提供方:openai(默认)| ollama
AI_PROVIDER=openai
OPENAI_API_BASE=https://op.bz121.com/v1
OPENAI_API_KEY=你的密钥
@@ -180,31 +205,31 @@ OPENAI_MODEL=gemma4:e4b
OLLAMA_API=http://127.0.0.1:11434/api/generate
AI_MODEL=huihui_ai/deepseek-r1-abliterated:latest
# Gate 代理可选):本机网络不稳定时通过 SSH 动态转发 SOCKS5 出口
# 1) 先在本机建立隧道示例):
# Gate 代理(可选):本机网络不稳定时通过 SSH 动态转发 SOCKS5 出口
# 1) 先在本机建立隧道(示例):
# ssh -N -D 127.0.0.1:1080 root@你的VPS_IP -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes
# 2) 再启用下面这一行推荐 socks5h让远端解析域名):
# 2) 再启用下面这一行(推荐 socks5h,让远端解析域名):
# GATE_SOCKS_PROXY=socks5h://127.0.0.1:1080
#
# 如你更偏向 HTTP 代理VPS 上跑 tinyproxy 之类),可用
# 如你更偏向 HTTP 代理(VPS 上跑 tinyproxy 之类),可用:
# GATE_HTTP_PROXY=http://127.0.0.1:3128
# GATE_HTTPS_PROXY=http://127.0.0.1:3128
# 开仓多周期K线图可选
# 开仓多周期K线图(可选)
# ORDER_CHART_ENABLED=true
# ORDER_CHART_TFS=4h,1h,15m,5m
# ORDER_CHART_LIMIT=100
# ORDER_CHART_DIR=static/images/order_charts
# 详见 DAILY_OPEN_ALERT_THRESHOLD / DAILY_OPEN_HARD_LIMIT说明文档 docs/daily-open-limit.md
# 以损定仓按交易账户资金的百分比
# 详见 DAILY_OPEN_ALERT_THRESHOLD / DAILY_OPEN_HARD_LIMIT;说明文档 docs/daily-open-limit.md
# 以损定仓(按交易账户资金的百分比)
# RISK_PERCENT=2
# 移动保本触发达到多少R触发与偏移百分比
# 移动保本触发(达到多少R触发)与偏移(百分比)
# BREAKEVEN_RR_TRIGGER=1.0
# 移动保本阶梯每多少R继续上移一次默认1R
# 移动保本阶梯(每多少R继续上移一次,默认1R)
# BREAKEVEN_STEP_R=1.0
# BREAKEVEN_OFFSET_PCT=0.02
# 开单风格默认值trend / swing
# 开单风格默认值:trend / swing
# DEFAULT_TRADE_STYLE=trend
APP_TIMEZONE=Asia/Shanghai
# TRADING_DAY_RESET_HOUR 现在表示「北京时间」整点默认 8 点起算新交易日开仓整点限制见 TRADING_DAY_RESET_OPEN_GUARD_ENABLED
# TRADING_DAY_RESET_HOUR 现在表示「北京时间」整点,默认 8 点起算新交易日;开仓整点限制见 TRADING_DAY_RESET_OPEN_GUARD_ENABLED
+29 -29
View File
@@ -1,34 +1,34 @@
# crypto_monitor_gate
基于 **Flask** 的加密货币 **下单监控 / 关键位监控 / 交易复盘** 小系统行情与实盘接口统一走 **Gate.io USDT 永续**通过 **ccxt** 访问
基于 **Flask** 的加密货币 **下单监控 / 关键位监控 / 交易复盘** 小系统,行情与实盘接口统一走 **Gate.io USDT 永续**,通过 **ccxt** 访问.
## 文档导航
| 文档 | 说明 |
|------|------|
| **[使用说明.md](./使用说明.md)** | 日常怎么用登录关键位四类手工开仓单仓与微信等 |
| **[关键位自动下单说明.md](./关键位自动下单说明.md)** | 关键位自动开仓的 RR止盈止损结案原因与 `.env` |
| **[部署文档.md](./部署文档.md)** | UbuntuPM2**SSH SOCKS** 访问 Gate API 等 |
| **[使用说明.md](./使用说明.md)** | 日常怎么用:登录,关键位四类,手工开仓,单仓与微信等 |
| **[关键位自动下单说明.md](./关键位自动下单说明.md)** | 关键位自动开仓的 RR,止盈止损,结案原因与 `.env` |
| **[部署文档.md](./部署文档.md)** | Ubuntu,PM2,**SSH SOCKS** 访问 Gate API 等 |
**Binance U 本位** 对等实现见同级的 **`crypto_monitor_binance`** 仓库
:**Binance U 本位** 对等实现见同级的 **`crypto_monitor_binance`** 仓库.
---
## 功能概要
- **关键位监控**5m 收线硬条件企业微信推送**箱体 / 收敛** 在 RR 达标时可 **自动市价开仓**见专门文档);**阻力 / 支撑** 仅单次提醒结案
- **下单监控**本地风控含移动保本)、止盈/止损触达后轮询尝试平仓并记账
- **实盘可选**`LIVE_TRADING_ENABLED=true` 且配置 **`GATE_API_KEY` / `GATE_API_SECRET`** 时支持开仓挂单 TP/SL余额与划转权限依账户而定
- **止盈止损Gate**市价成交后经 **`_gate_place_tp_sl_orders`** 挂单优先 **仓位类 `price_orders`**`GATE_TPSL_USE_POSITION_ORDER``GATE_TPSL_PRICE_TYPE``GATE_POS_MODE` 等影响
- **关键位监控**:5m 收线硬条件,企业微信推送;**箱体 / 收敛** 在 RR 达标时可 **自动市价开仓**(见专门文档);**阻力 / 支撑** 仅单次提醒结案
- **下单监控**:本地风控(含移动保本),止盈/止损触达后轮询尝试平仓并记账
- **实盘(可选)**:`LIVE_TRADING_ENABLED=true` 且配置 **`GATE_API_KEY` / `GATE_API_SECRET`** 时,支持开仓,挂单 TP/SL,余额与划转(权限依账户而定)
- **止盈止损(Gate)**:市价成交后经 **`_gate_place_tp_sl_orders`** 挂单;优先 **仓位类 `price_orders`**(`GATE_TPSL_USE_POSITION_ORDER`,`GATE_TPSL_PRICE_TYPE`,`GATE_POS_MODE` 等影响)
---
## 环境要求
- Python 3.10+建议
- 依赖`flask``requests``ccxt``werkzeug``PySocks`经 SOCKS 代理时);`Pillow`K 线导出等可选用
- Python 3.10+(建议)
- 依赖:`flask`,`requests`,`ccxt`,`werkzeug`,`PySocks`(经 SOCKS 代理时);`Pillow`(K 线导出等可选用)
安装示例
安装示例:
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
@@ -36,41 +36,41 @@ source .venv/bin/activate
pip install -r ../requirements.txt
```
## 配置`.env.example``.env`
## 配置(`.env.example``.env`)
- **`.env.example`**模板可提交 Git);首次`cp .env.example .env` 后编辑
- **`.env`**本机真实配置勿提交);`git pull` 不覆盖升级前建议备份见《部署文档》§5.2)。
- **`.env.example`**:模板(可提交 Git);首次:`cp .env.example .env` 后编辑.
- **`.env`**:本机真实配置(勿提交);`git pull` 不覆盖;升级前建议备份(见《部署文档》§5.2).
项目启动时加载**仓库根目录**下的 `.env`常用项
项目启动时加载**仓库根目录**下的 `.env`.常用项:
| 变量 | 说明 |
|------|------|
| `GATE_API_KEY` / `GATE_API_SECRET` | Gate API需合约与对应权限 |
| `LIVE_TRADING_ENABLED` | `true` 允许真实下单`false` 仅本地与推送逻辑 |
| `GATE_API_KEY` / `GATE_API_SECRET` | Gate API(需合约与对应权限) |
| `LIVE_TRADING_ENABLED` | `true` 允许真实下单;`false` 仅本地与推送逻辑 |
| `GATE_MARGIN_MODE` / `GATE_POS_MODE` | 保证金与持仓模式 |
| `GATE_TPSL_USE_POSITION_ORDER` / `GATE_TPSL_PRICE_TYPE` 等 | 条件止盈止损行为 |
| `GATE_SOCKS_PROXY` | 可选直连不稳时 SSH 动态转发详见部署文档 |
| `GATE_SOCKS_PROXY` | 可选;直连不稳时 SSH 动态转发(详见部署文档) |
| `APP_PASSWORD` / `FLASK_SECRET_KEY` | Web 登录与 Session |
| `WECHAT_WEBHOOK` | 企业微信机器人 |
| `EXCHANGE_DISPLAY_NAME` / `GATE_ACCOUNT_LABEL` | 页面与推送展示的账户文案 |
其余见 **`.env.example` 内注释** 或 **`app.py` 顶部默认值**
其余见 **`.env.example` 内注释** 或 **`app.py` 顶部默认值**.
## 运行
生产使用 **PM2**`ecosystem.config.cjs`)。调试
生产使用 **PM2**(`ecosystem.config.cjs`).调试:
```bash
source .venv/bin/activate && python app.py
```
见 [docs/ubuntu-server.md](../docs/ubuntu-server.md)
见 [docs/ubuntu-server.md](../docs/ubuntu-server.md).
端口由 **`APP_PORT`** 控制未设置默认 **5000**)。浏览器登录 **`/login`**口令为 **`APP_PASSWORD`**
端口由 **`APP_PORT`** 控制(未设置默认 **5000**).浏览器登录 **`/login`**,口令为 **`APP_PASSWORD`**.
## 部署Linux / PM2 / SSH SOCKS
## 部署(Linux / PM2 / SSH SOCKS)
**[部署文档.md](./部署文档.md)**
**[部署文档.md](./部署文档.md)**.
## 自检脚本
@@ -78,13 +78,13 @@ source .venv/bin/activate && python app.py
python scripts/verify_gate_funding.py
```
用于核对密钥前缀不落 Secret)、资金/合约可读性等需网络与权限)。
用于核对密钥前缀(不落 Secret),资金/合约可读性等(需网络与权限).
## 数据与脚本
- 默认 SQLite**`DB_PATH`** 指定常见为项目下 `crypto.db`
- `scripts/fix_breakeven_labels.py`修正「止损」但盈亏为正的记录标签参见部署文档说明
- 默认 SQLite:**`DB_PATH`** 指定(常见为项目下 `crypto.db`)
- `scripts/fix_breakeven_labels.py`:修正「止损」但盈亏为正的记录标签(参见部署文档说明)
## 风险与合规
实盘有亏损风险请确认 API 权限IP 白名单杠杆与保证金模式与 **Gate.io** 后台一致并遵守当地法律法规与交易所用户协议
实盘有亏损风险.请确认 API 权限,IP 白名单,杠杆与保证金模式与 **Gate.io** 后台一致,并遵守当地法律法规与交易所用户协议.
+9981 -9631
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -1,14 +1,14 @@
/**
* PM2 进程定义Ubuntu / Linux
* PM2 进程定义(Ubuntu / Linux).
*
* 仅托管 Flask 应用**SSH SOCKS 隧道** `ssh -D` 常驻可用 tmux / autossh勿交给 PM2
* `.env` `GATE_SOCKS_PROXY` 端口一致即可不必交给 PM2
* 仅托管 Flask 应用.**SSH SOCKS 隧道** `ssh -D` 常驻(可用 tmux / autossh),勿交给 PM2.
* `.env` `GATE_SOCKS_PROXY` 端口一致即可;不必交给 PM2.
*
* 使用前项目根目录存在 `.venv`且已安装依赖 SOCKS 时需 PySocks
* 使用前:项目根目录存在 `.venv`,且已安装依赖( SOCKS 时需 PySocks).
*
* 启动
* 启动:
* pm2 start ecosystem.config.cjs
* 保存开机列表
* 保存开机列表:
* pm2 save && pm2 startup
*/
const path = require("path");
@@ -1,18 +1,18 @@
#!/usr/bin/env python3
"""
一次性修复历史交易记录标签
trade_records 止损但实际盈利的记录改为保本止盈
一次性修复历史交易记录标签:
trade_records 止损但实际盈利的记录改为保本止盈.
默认条件可通过参数修改
默认条件(可通过参数修改):
- monitor_type = 下单监控
- result = 止损
- pnl_amount > 0
用法示例
1) 仅预览不落库
用法示例:
1) 仅预览(不落库):
python scripts/fix_breakeven_labels.py --db ./crypto.db --dry-run
2) 执行修复
2) 执行修复:
python scripts/fix_breakeven_labels.py --db ./crypto.db --apply
"""
@@ -1,9 +1,9 @@
"""
在项目根目录执行会加载根目录 .env
在项目根目录执行(会加载根目录 .env):
python scripts/verify_gate_funding.py
依次探测[0] swap 余额 App交易账户同源[1][3] 现货 / 统一账户资金路径
打印 GATE_API_KEY 8 位便于与 Gate 控制台核对不含 Secret用于服务器自检
依次探测:[0] swap 余额( App交易账户同源);[1][3] 现货 / 统一账户资金路径.
打印 GATE_API_KEY 8 位便于与 Gate 控制台核对(不含 Secret).用于服务器自检.
"""
from __future__ import annotations
@@ -39,12 +39,12 @@ def main():
k = (os.getenv("GATE_API_KEY") or "").strip()
s = (os.getenv("GATE_API_SECRET") or "").strip()
if not k or "REPLACE" in k.upper():
print("WARN: GATE_API_KEY 为空或仍像占位符请核对 .env")
print("WARN: GATE_API_KEY 为空或仍像占位符,请核对 .env")
if not s or "REPLACE" in s.upper():
print("WARN: GATE_API_SECRET 为空或仍像占位符请核对 .env")
print("WARN: GATE_API_SECRET 为空或仍像占位符,请核对 .env")
print("GATE_API_KEY prefix (8 chars):", (k[:8] + "") if len(k) > 8 else "(short)")
# 0) swap — 与 App「交易账户」余额同源优先看此项是否与网页一致
# 0) swap — 与 App「交易账户」余额同源(优先看此项是否与网页一致)
try:
bal = mod.exchange.fetch_balance({"type": "swap"})
v0 = mod._extract_usdt_total(bal)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 B

After

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 B

After

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 497 B

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

+2 -13
View File
@@ -1,17 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<defs>
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#22d3ee"/>
<stop offset="100%" stop-color="#34d399"/>
</linearGradient>
</defs>
<rect width="512" height="512" rx="108" fill="#0c1019"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="#141b2d"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="none" stroke="url(#g)" stroke-width="12"/>
<path d="M120 320 L200 248 L280 272 L392 168" fill="none" stroke="url(#g)" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="392" cy="168" r="18" fill="#34d399"/>
<rect x="168" y="268" width="28" height="64" rx="6" fill="#f87171"/>
<line x1="182" y1="248" x2="182" y2="340" stroke="#f87171" stroke-width="10" stroke-linecap="round"/>
<rect x="268" y="220" width="28" height="96" rx="6" fill="#34d399"/>
<line x1="282" y1="200" x2="282" y2="340" stroke="#34d399" stroke-width="10" stroke-linecap="round"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="none" stroke="#17E6A1" stroke-width="12"/>
<text x="256" y="310" text-anchor="middle" font-family="Arial, Helvetica, sans-serif" font-size="220" font-weight="700" fill="#17E6A1">G</text>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 451 B

@@ -1,11 +1,11 @@
{
"name": "交易监控复盘",
"short_name": "监控",
"description": "加密货币永续交易监控与复盘",
"name": "Gate 交易系统",
"short_name": "Gate 交易系统",
"description": "Gate 永续交易监控与复盘",
"start_url": "/",
"display": "standalone",
"background_color": "#0b0d14",
"theme_color": "#0b0d14",
"theme_color": "#17E6A1",
"icons": [
{
"src": "/static/icons/icon-192.png",
File diff suppressed because it is too large Load Diff
-136
View File
@@ -1,136 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN" data-theme="dark">
<head>
<meta charset="UTF-8">
<script src="/static/instance_theme.js?v=4"></script>
<title>登录 · {{ exchange_display }}</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #0a0a10;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
color: #fff;
}
.login-box {
background: #12121a;
padding: 2.5rem;
border-radius: 16px;
width: 100%;
max-width: 400px;
border: 1px solid #242435;
box-shadow: 0 8px 24px rgba(0,0,0,0.3);
}
.login-box h2 {
margin-bottom: 2rem;
text-align: center;
font-size: 1.5rem;
background: linear-gradient(90deg, #4cc2ff, #7b42ff);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.form-group {
margin-bottom: 1.25rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-size: 0.9rem;
color: #a9a9ff;
}
.form-group input {
width: 100%;
padding: 0.85rem 1rem;
border-radius: 10px;
border: 1px solid #2e2e45;
background: #1a1a29;
color: #fff;
font-size: 0.95rem;
outline: none;
}
.form-group input:focus {
border-color: #4cc2ff;
}
button {
width: 100%;
padding: 0.9rem;
border-radius: 10px;
border: none;
background: linear-gradient(90deg, #4285f4, #7b42ff);
color: #fff;
font-size: 1rem;
font-weight: 500;
cursor: pointer;
transition: 0.2s;
}
button:hover {
opacity: 0.9;
}
.flash {
padding: 0.8rem;
margin-bottom: 1rem;
background: #331e24;
color: #ff6666;
border-radius: 8px;
text-align: center;
font-size: 0.85rem;
}
.exchange-line {
text-align: center;
font-size: 0.82rem;
color: #8892b0;
margin: -0.5rem 0 1.25rem;
}
.exchange-line strong {
color: #b8f5d0;
font-weight: 600;
}
</style>
<link rel="stylesheet" href="/static/instance_theme.css?v=4">
</head>
<div class="login-theme-bar">
<div class="theme-toggle instance-theme-toggle" role="group" aria-label="界面主题">
<button type="button" class="theme-toggle-btn is-active" data-theme-value="dark" aria-pressed="true" title="暗色主题">
<svg class="theme-icon" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
<path fill="currentColor" d="M12.1 3a9 9 0 1 0 8.9 11 6.5 6.5 0 1 1-8.9-11z"/>
</svg>
</button>
<button type="button" class="theme-toggle-btn" data-theme-value="light" aria-pressed="false" title="亮色主题">
<svg class="theme-icon" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/>
</svg>
</button>
</div>
</div>
<body>
<div class="login-box">
<h2>交易监控系统登录</h2>
<p class="exchange-line">交易所:<strong>{{ exchange_display }}</strong></p>
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="flash">{{ messages[0] }}</div>
{% endif %}
{% endwith %}
<form method="POST" autocomplete="off">
<div class="form-group">
<label>账号</label>
<input type="text" name="username" required placeholder="请输入账号" autocomplete="off" autocapitalize="off" spellcheck="false">
</div>
<div class="form-group">
<label>密码</label>
<input type="password" name="password" required placeholder="请输入密码" autocomplete="new-password">
</div>
<button type="submit">登录</button>
</form>
</div>
</body>
</html>
@@ -29,9 +29,9 @@
<div class="row" style="justify-content:space-between">
<div class="row">
<a class="btn" href="/">返回首页</a>
<strong style="color:#dbe4ff">实盘下单放大100根K线</strong>
<strong style="color:#dbe4ff">实盘下单放大(100根K线)</strong>
</div>
<div class="status">最近刷新<span id="updated-at">--</span></div>
<div class="status">最近刷新:<span id="updated-at">--</span></div>
</div>
{% if orders %}
<div class="row" style="margin-top:10px">
@@ -53,7 +53,7 @@
<span id="load-status" class="status"></span>
</div>
{% else %}
<div class="empty">当前没有激活订单无法展示放大K线</div>
<div class="empty">当前没有激活订单,无法展示放大K线.</div>
{% endif %}
</div>
+147 -147
View File
@@ -1,147 +1,147 @@
# 使用说明
**本文件对应仓库`crypto_monitor_gate`Gate.io USDT 永续)。**
功能界面与 **Binance U 本位版**目录 `crypto_monitor_binance`基本一致差异主要在 **`.env` 里交易所密钥与部分参数名**`GATE_*` / `BINANCE_*`),文末有对照
**更细的部署SSH 代理PM2依赖安装** 见同目录 **`部署文档.md`**
**关键位自动开仓的规则RR结案原因** 见 **`关键位自动下单说明.md`**
---
## 1. 它能做什么
面向个人盘面的 **Web 控制台**主要能力包括
| 模块 | 说明 |
|------|------|
| **关键位监控** | 录入上/下沿与类型**5m 收线** 做硬条件过滤符合条件后 **企业微信** 提醒部分类型可 **自动市价开仓**见第 4 节与专门文档)。 |
| **实盘下单监控** | 手工填止损/止盈**以损定仓** 市价开单挂上条件止盈止损并在页面跟踪浮盈亏保本逻辑等 |
| **交易记录 / 复盘** | 平仓结果盈亏错过的单等归档与导出可选 **AI 复盘**见 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md))。 |
| **策略交易** | 顶栏 `/strategy`趋势回调 + 顺势加仓双栏见 [策略交易说明.md](../策略交易说明.md) |
后台按 **`MONITOR_POLL_SECONDS`**默认几秒轮询行情与监控逻辑**切勿**在未理解规则时同时运行两套程序共用一个实盘账户
---
## 2. 运行前必须配置`.env`
首次在本目录执行 **`cp .env.example .env`**再编辑 `.env``.env` 勿提交 Git`git pull` 不会改你的 `.env`升级前建议 `cp .env .env.backup.$(date +%Y%m%d)`)。
至少检查以下项具体键名以 **`.env.example`** 为准):
| 类别 | 说明 |
|------|------|
| **登录网页** | `APP_PASSWORD`打开站点后的登录口令`FLASK_SECRET_KEY`Session 密钥请勿使用默认值 |
| **企业微信** | `WECHAT_WEBHOOK`告警与关键位推送机器人的 Webhook |
| **是否真下单** | `LIVE_TRADING_ENABLED=false`**不会**向交易所发送开仓指令适合测试流程)。改为 `true` 且密钥正确才会实盘 |
| **交易所 API** | **本仓库** `GATE_API_KEY``GATE_API_SECRET`合约相关见 `GATE_MARGIN_MODE``GATE_POS_MODE``GATE_TPSL_*`**勿**把 `.env` 提交到 Git |
| **关键位 RR / 止损外扩** | `KEY_AUTO_MIN_PLANNED_RR``KEY_STOP_OUTSIDE_BREAKOUT_PCT`详见 `关键位自动下单说明.md`)。 |
| **AI 复盘** | `AI_PROVIDER=openai`默认`ollama`变量见 `.env.example` 与 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md) |
网络不稳定时可为 Gate 配置 **`GATE_SOCKS_PROXY`** 等**`部署文档.md`**)。
---
## 3. 如何启动与登录
1. 按 **`部署文档.md`** 建好虚拟环境安装依赖`flask``requests``ccxt`按需 `Pillow``PySocks`),配置好 `.env`
2. 启动 Flask 应用本仓库可用 **`ecosystem.config.cjs`** 交给 PM2或本地 `python app.py` / `flask run`以你当前脚本为准)。
3. 浏览器访问站点打开 **`/login`**使用 **`.env` 里的 `APP_PASSWORD`** 登录
登录后顶栏**关键位监控** | **实盘下单** | **策略交易**`/strategy`| **策略交易记录**`/strategy/records`| **交易记录与复盘** | **统计分析**
---
## 4. 关键位监控顶栏「关键位监控」→ `/key_monitor`
### 4.1 添加一条关键位
1. **币种**`BTC``BTC/USDT`会规范成内部符号)。
2. **类型**必选其一):
| 类型 | 行为摘要 |
|------|----------|
| **箱体突破** | 通过门控且计划 RR 达标 → **自动市价开仓**`LIVE_TRADING_ENABLED=true` 且无其他持仓占位)。结案后本条从列表消失并记入历史 |
| **收敛突破** | 同上自动开仓类)。 |
| **关键阻力位** | **不自动开仓**触发后 **发 1 次微信**然后本条 **结案进历史** |
| **关键支撑位** | 同上仅提醒)。 |
| **回调触价开仓** | **不挂交易所限价**标记价回调触达 E 后 **下一轮询市价开仓**RR 门槛同 `KEY_AUTO_MIN_PLANNED_RR`);有效期 **24h** |
| **突破触价开仓** | **不挂交易所限价**标记价 **穿越 E 立即市价开仓**先触 SL/TP 侧失效有效期 **24h** |
3. **方向**做多 / 做空触价开仓 / 箱体 / 收敛 / 斐波必选阻力/支撑不选)。
4. **价位**箱体/收敛/阻力/支撑填 **上沿 / 下沿**触价开仓填 **入场 E / 止损 SL / 止盈 TP**
**限制**
活跃持仓数达到 **`MAX_ACTIVE_POSITIONS`**默认 1)时,**不允许**再添加「**箱体突破** / **收敛突破**仍可添加「**关键阻力位 / 支撑位**」
**4h EMA55** 与你的方向逆势页面会 **额外 Flash 提示****不阻挡**提交
### 4.2 触发后会发生什么简版
- **箱体 / 收敛**门控通过后计算计划 SL/TP 与 RR不达标则 **微信说明 + `rr_insufficient` 结案**达标则尝试 **市价开仓**成功 **`auto_opened`**失败 **`exchange_failed`**——均 **不重试同一关键位**
- **阻力 / 支撑****单次推送****`key_level_alert_only`** 结案
详细公式结案字段与企业微信文案口径见 **`关键位自动下单说明.md`**
### 4.3 列表与历史
- 当前条目可 **删除**会按规则记入历史的情形见页面说明)。
- **关键位历史**已结案记录可配合导出链接若有做备份
---
## 5. 实盘下单顶栏「实盘下单」→ `/trade`
用于 **自己点按钮** 开单
- 持仓上限由 **`MAX_ACTIVE_POSITIONS`** 控制默认 1与关键位自动单共用)。
- **人工开仓**时计划盈亏比不得低于 **`MANUAL_MIN_PLANNED_RR`**默认 1.4:1),否则页面弹窗且后端拒绝
- 填写币种方向杠杆可选)、止损/止盈价格或百分比按表单说明)。
- 勾选是否启用 **移动保本** 等行为以 `.env`/页面默认值为准
平仓通过页面 **平仓**或等价入口),会从交易所市价处理并更新记录**删除/误操作可能造成真实盈亏**请先确认环境与方向
开仓成功后持仓卡片上会显示 **「来源」**手工单一般为 **下单监控**来自关键位自动单的为 **关键位监控**
---
## 6. 企业微信会看到什么
- 关键位按类型与结案结果推送RR 不足下单失败自动开仓成功仅阻力支撑提醒等),**每条关键位结案路径原则上一条主推送**详见 `关键位自动下单说明.md`)。
- 手工开仓平仓部分异常也会在规则满足时推送以代码与配置为准)。
若未配置 **`WECHAT_WEBHOOK`** 或网络失败可能只是看不到推送不代表逻辑未执行要紧操作请以 **交易所端持仓与挂单** 为准核对
---
## 7. 强烈建议的风险与运维习惯
1. **先用 `LIVE_TRADING_ENABLED=false`** 验证页面录入推送再开小资金开实盘
2. **API 权限**仅开所需合约权限勿泄露密钥定期轮换
3. **单进程控盘**同一账户避免本程序与其他机器人 **重复开仓**
4. **自动备份**服务器上执行 `bash scripts/install_backup_cron.sh`每天北京时间 0:00 → `/root/backups`保留 30 天);升级前也可 `bash scripts/backup_data.sh` 手动跑一次
5. **升级代码后**启动时会跑 **数据库迁移**如新列 `order_monitors.monitor_type`);首次启动关注一下日志或无报错页面
---
## 8. 常见问题简要
| 现象 | 可自查 |
|------|--------|
| 关键位永远不触发 | 5m 门控是否全通过页面门控摘要)、币种日成交量是否在规则内`KLINE_TIMEFRAME` |
| 有信号但不自动开仓 | `LIVE_TRADING_ENABLED``KEY_AUTO_MIN_PLANNED_RR`计划 RR是否已有持仓API/余额报错微信或日志)。 |
| 加不了箱体/收敛 | 是否已有活跃持仓先平仓或改用「阻力/支撑位」仅提醒 |
| 推送收不到 | `WECHAT_WEBHOOK`企业微信机器人配额与网络 |
---
## 9. Binance 版`crypto_monitor_binance`差异速查
| 项目 | Gate 本仓库 | Binance 版 |
|------|-------------|------------|
| API 变量 | `GATE_API_KEY``GATE_API_SECRET``GATE_*` | `BINANCE_API_KEY``BINANCE_API_SECRET``BINANCE_*` |
| 实盘开关 | `LIVE_TRADING_ENABLED`通用 | 同上 |
| 止盈止损挂载路径 | `_gate_place_tp_sl_orders``GATE_TPSL_*` | `_binance_place_tp_sl_orders`U 本位条件单 |
| 资金显示舍入 | 以本仓库为准 | 与 **`FUNDS_DECIMALS`** 等一致 |
| 专门文档 | **`关键位自动下单说明.md`**各仓库有一份开头标明交易所 | 同左 |
操作流程登录关键位四类手工单单仓**两份程序一致**换目录`.env` 即可对照使用
# 使用说明
**本文件对应仓库:`crypto_monitor_gate`(Gate.io USDT 永续).**
功能,界面与 **Binance U 本位版**(目录 `crypto_monitor_binance`)基本一致,差异主要在 **`.env` 里交易所密钥与部分参数名**(`GATE_*` / `BINANCE_*`),文末有对照.
**更细的部署(SSH 代理,PM2,依赖安装)** 见同目录 **`部署文档.md`**.
**关键位自动开仓的规则,RR,结案原因** 见 **`关键位自动下单说明.md`**.
---
## 1. 它能做什么
面向个人盘面的 **Web 控制台**,主要能力包括:
| 模块 | 说明 |
|------|------|
| **关键位监控** | 录入上/下沿与类型,**5m 收线** 做硬条件过滤;符合条件后 **企业微信** 提醒,部分类型可 **自动市价开仓**(见第 4 节与专门文档). |
| **实盘下单监控** | 手工填止损/止盈,**以损定仓** 市价开单,挂上条件止盈止损,并在页面跟踪浮盈亏,保本逻辑等. |
| **交易记录 / 复盘** | 平仓结果,盈亏,错过的单等归档与导出;可选 **AI 复盘**(见 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)). |
| **策略交易** | 顶栏 `/strategy`:趋势回调 + 顺势加仓双栏;见 [策略交易说明.md](../策略交易说明.md). |
后台按 **`MONITOR_POLL_SECONDS`**(默认几秒)轮询行情与监控逻辑.**切勿**在未理解规则时同时运行两套程序共用一个实盘账户.
---
## 2. 运行前必须配置(`.env`)
首次在本目录执行 **`cp .env.example .env`**,再编辑 `.env`(`.env` 勿提交 Git;`git pull` 不会改你的 `.env`,升级前建议 `cp .env .env.backup.$(date +%Y%m%d)`).
至少检查以下项(具体键名以 **`.env.example`** 为准):
| 类别 | 说明 |
|------|------|
| **登录网页** | `APP_PASSWORD`:打开站点后的登录口令.`FLASK_SECRET_KEY`:Session 密钥,请勿使用默认值. |
| **企业微信** | `WECHAT_WEBHOOK`:告警与关键位推送机器人的 Webhook. |
| **是否真下单** | `LIVE_TRADING_ENABLED=false`:**不会**向交易所发送开仓指令(适合测试流程).改为 `true` 且密钥正确才会实盘. |
| **交易所 API** | **本仓库:** `GATE_API_KEY`,`GATE_API_SECRET`;合约相关见 `GATE_MARGIN_MODE`,`GATE_POS_MODE`,`GATE_TPSL_*`.**勿**把 `.env` 提交到 Git. |
| **关键位 RR / 止损外扩** | `KEY_AUTO_MIN_PLANNED_RR`,`KEY_STOP_OUTSIDE_BREAKOUT_PCT`(详见 `关键位自动下单说明.md`). |
| **AI 复盘** | `AI_PROVIDER=openai`(默认)`ollama`;变量见 `.env.example` 与 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md). |
网络不稳定时可为 Gate 配置 **`GATE_SOCKS_PROXY`** 等(**`部署文档.md`**).
---
## 3. 如何启动与登录
1. 按 **`部署文档.md`** 建好虚拟环境,安装依赖(`flask`,`requests`,`ccxt`,按需 `Pillow`,`PySocks`),配置好 `.env`.
2. 启动 Flask 应用(本仓库可用 **`ecosystem.config.cjs`** 交给 PM2,或本地 `python app.py` / `flask run`,以你当前脚本为准).
3. 浏览器访问站点,打开 **`/login`**,使用 **`.env` 里的 `APP_PASSWORD`** 登录.
登录后顶栏:**关键位监控** | **实盘下单** | **策略交易**(`/strategy`)| **策略交易记录**(`/strategy/records`)| **交易记录与复盘** | **统计分析**.
---
## 4. 关键位监控(顶栏「关键位监控」→ `/key_monitor`)
### 4.1 添加一条关键位
1. **币种**:`BTC``BTC/USDT`(会规范成内部符号).
2. **类型**(必选其一):
| 类型 | 行为摘要 |
|------|----------|
| **箱体突破** | 通过门控且计划 RR 达标 → **自动市价开仓**(`LIVE_TRADING_ENABLED=true` 且无其他持仓占位).结案后本条从列表消失并记入历史. |
| **收敛突破** | 同上(自动开仓类). |
| **关键阻力位** | **不自动开仓**;触发后 **发 1 次微信**,然后本条 **结案进历史**. |
| **关键支撑位** | 同上(仅提醒). |
| **回调触价开仓** | **不挂交易所限价**;标记价回调触达 E 后 **下一轮询市价开仓**(RR 门槛同 `KEY_AUTO_MIN_PLANNED_RR`);有效期 **24h** |
| **突破触价开仓** | **不挂交易所限价**;标记价 **穿越 E 立即市价开仓**;先触 SL/TP 侧失效;有效期 **24h** |
3. **方向**:做多 / 做空(触价开仓 / 箱体 / 收敛 / 斐波必选;阻力/支撑不选).
4. **价位**:箱体/收敛/阻力/支撑填 **上沿 / 下沿**;触价开仓填 **入场 E / 止损 SL / 止盈 TP**.
**限制:**
活跃持仓数达到 **`MAX_ACTIVE_POSITIONS`**(默认 1)时,**不允许**再添加「**箱体突破** / **收敛突破**;仍可添加「**关键阻力位 / 支撑位**」.
**4h EMA55** 与你的方向逆势,页面会 **额外 Flash 提示**,**不阻挡**提交.
### 4.2 触发后会发生什么(简版)
- **箱体 / 收敛**:门控通过后计算计划 SL/TP 与 RR;不达标则 **微信说明 + `rr_insufficient` 结案**;达标则尝试 **市价开仓**,成功 **`auto_opened`**,失败 **`exchange_failed`**——均 **不重试同一关键位**.
- **阻力 / 支撑**:**单次推送****`key_level_alert_only`** 结案.
详细公式,结案字段,与企业微信文案口径见 **`关键位自动下单说明.md`**.
### 4.3 列表与历史
- 当前条目可 **删除**(会按规则记入历史的情形见页面说明).
- **关键位历史**:已结案记录;可配合导出链接(若有)做备份.
---
## 5. 实盘下单(顶栏「实盘下单」→ `/trade`)
用于 **自己点按钮** 开单:
- 持仓上限由 **`MAX_ACTIVE_POSITIONS`** 控制(默认 1,与关键位自动单共用).
- **人工开仓**时计划盈亏比不得低于 **`MANUAL_MIN_PLANNED_RR`**(默认 1.4:1),否则页面弹窗且后端拒绝.
- 填写币种,方向,杠杆(可选),止损/止盈(价格或百分比按表单说明).
- 勾选是否启用 **移动保本** 等行为以 `.env`/页面默认值为准.
平仓通过页面 **平仓**(或等价入口),会从交易所市价处理并更新记录.**删除/误操作可能造成真实盈亏**,请先确认环境与方向.
开仓成功后持仓卡片上会显示 **「来源」**:手工单一般为 **下单监控**;来自关键位自动单的为 **关键位监控**.
---
## 6. 企业微信会看到什么
- 关键位:按类型与结案结果推送(RR 不足,下单失败,自动开仓成功,仅阻力支撑提醒等),**每条关键位结案路径原则上一条主推送**(详见 `关键位自动下单说明.md`).
- 手工开仓,平仓,部分异常也会在规则满足时推送(以代码与配置为准).
若未配置 **`WECHAT_WEBHOOK`** 或网络失败,可能只是看不到推送,不代表逻辑未执行;要紧操作请以 **交易所端持仓与挂单** 为准核对.
---
## 7. 强烈建议的风险与运维习惯
1. **先用 `LIVE_TRADING_ENABLED=false`** 验证页面,录入,推送,再开小资金开实盘.
2. **API 权限**:仅开所需合约权限;勿泄露密钥;定期轮换.
3. **单进程控盘**:同一账户避免本程序与其他机器人 **重复开仓**.
4. **自动备份**:服务器上执行 `bash scripts/install_backup_cron.sh`(每天北京时间 0:00 → `/root/backups`,保留 30 天);升级前也可 `bash scripts/backup_data.sh` 手动跑一次.
5. **升级代码后**:启动时会跑 **数据库迁移**(如新列 `order_monitors.monitor_type`);首次启动关注一下日志或无报错页面.
---
## 8. 常见问题(简要)
| 现象 | 可自查 |
|------|--------|
| 关键位永远不触发 | 5m 门控是否全通过(页面门控摘要),币种日成交量是否在规则内,`KLINE_TIMEFRAME`. |
| 有信号但不自动开仓 | `LIVE_TRADING_ENABLED`,`KEY_AUTO_MIN_PLANNED_RR`,计划 RR,是否已有持仓,API/余额报错(微信或日志). |
| 加不了箱体/收敛 | 是否已有活跃持仓;先平仓或改用「阻力/支撑位」仅提醒. |
| 推送收不到 | `WECHAT_WEBHOOK`,企业微信机器人配额与网络. |
---
## 9. Binance 版(`crypto_monitor_binance`)差异速查
| 项目 | Gate 本仓库 | Binance 版 |
|------|-------------|------------|
| API 变量 | `GATE_API_KEY`,`GATE_API_SECRET`,`GATE_*` | `BINANCE_API_KEY`,`BINANCE_API_SECRET`,`BINANCE_*` |
| 实盘开关 | `LIVE_TRADING_ENABLED`(通用) | 同上 |
| 止盈止损挂载路径 | `_gate_place_tp_sl_orders``GATE_TPSL_*` | `_binance_place_tp_sl_orders`(U 本位条件单) |
| 资金显示舍入 | 以本仓库为准 | 与 **`FUNDS_DECIMALS`** 等一致 |
| 专门文档 | **`关键位自动下单说明.md`**(各仓库有一份,开头标明交易所) | 同左 |
操作流程(登录,关键位四类,手工单,单仓)**两份程序一致**:换目录,`.env` 即可对照使用.
+192 -175
View File
@@ -1,175 +1,192 @@
# 关键位监控说明自动开仓 + 人工盯盘
**适用`crypto_monitor_gate`Gate U 本位永续)**
Binance / OKX 见各自目录下同名文档;共享逻辑在仓库根目录 `key_monitor_lib.py`
本文档与 `.env``check_key_monitors``add_key``_key_hard_checks``_process_key_rs_level_alert` 一致。
---
## 一、监控类型总览
| 录入类型 | 录入时选方向 | 自动市价开仓 | 触发与结案 |
|----------|--------------|--------------|------------|
| **箱体突破** | **必选** 多/空 | **是**(门控 + RR) | 条件满足 → 开仓或 `rr_insufficient` / `exchange_failed`**一次性删除** |
| **收敛突破** | **必选** 多/空 | **是**(同上) | 同上 |
| **关键阻力位** | **不选**`direction=watch` | **否** | 5m 收盘突破上/下沿 → 微信 **3 次**`key_level_alert_done` |
| **关键支撑位** | **不选** | **否** | 同上(与阻力位**相同规则**:填上沿+下沿,程序双向监控) |
| 斐波回调 0.618 / 0.786 | 必选 | 限价挂单逻辑 | 见斐波说明(**不在下文展开**) |
| **回调触价开仓** | **必选** 多/空 | **程序盯价 → 回调触 E 后市价** | 见下文 **§四** |
| **突破触价开仓** | **必选** 多/空 | **程序盯价 → 穿越 E 立即市价** | 见下文 **§四** |
**添加时(箱体/收敛/斐波/触价):** 品种须 **日成交量排名前 `KEY_DAILY_VOLUME_RANK_MAX`(默认 30**;上沿 **>** 下沿(触价开仓填 E/SL/TP,上下沿仅作展示占位)。
---
## 二、关键阻力位 / 关键支撑位(人工盯盘)
### 2.1 录入
- 填写 **上沿 `upper`****下沿 `lower`**(程序同时监控两侧,**无法预先判定**做多还是做空)。
- 页面 **不显示、不要求** 方向;库中 `direction` 初始为 `watch`**首次突破后** 写入 `long`(向上突破上沿)或 `short`(向下突破下沿)。
### 2.2 触发(极简)
- 周期:**`KLINE_TIMEFRAME`(默认 5m)最近一根已闭合 K** 的 **收盘价**(非影线)。
- **向上突破上沿:** `收盘 > upper` → 推断方向 **多 / 向上**,本次监控任务开始按节奏提醒。
- **向下突破下沿:** `收盘 < lower` → 推断方向 **空 / 向下**,本次任务同样开始提醒。
- **任一侧突破即结束本条监控周期**(不会在突破后再等待另一侧;上沿、下沿谁先满足用谁,同根 K 仅可能满足一侧)。
**不参与:** 量能、二确 K、越过幅度下限、日成交排名(运行时)、计划 RR、自动开仓。
### 2.3 微信提醒次数
| 配置 | 默认 | 含义 |
|------|------|------|
| `KEY_ALERT_MAX_TIMES` | `3` | 突破后最多推送 3 次 |
| `KEY_ALERT_INTERVAL_MINUTES` | `5` | 相邻两次推送至少间隔 5 分钟 |
- 第 1 次:首次检测到突破的当次轮询(若已闭合 5m 满足条件)。
- 第 2、3 次:仅按间隔推送(**不要求**价格仍在箱外)。
- 第 3 次推送后:写入 `key_monitor_history``close_reason=**key_level_alert_done**`,从 `key_monitors` **删除**
### 2.4 与箱体/收敛的区别
| 项目 | 阻力/支撑 | 箱体/收敛 |
|------|-----------|-----------|
| 方向 | 程序推断 | 人工选择 |
| K 线根数 | 1 根闭合 5m | 2 根(突破 K + 确认 K |
| 提醒次数 | 3 次后结案 | 自动单:触发后 1 次业务推送并结案 |
---
## 三、箱体突破 / 收敛突破(自动开仓)
### 3.1 K 线结构(默认索引)
| 角色 | 环境变量 | 默认 | 含义 |
|------|----------|------|------|
| 突破 K | `KEY_CONFIRM_BREAKOUT_BAR` | `-2` | 倒数第 2 根闭合 K |
| 确认 K | `KEY_CONFIRM_BAR` | `-1` | 倒数第 1 根闭合 K |
### 3.2 硬门控(须全部通过)
1. **有效突破(收盘越界)**
- 多:`突破 K 收盘 > upper`
- 空:`突破 K 收盘 < lower`
2. **突破越过幅度(仅下限)**
- 多:`(突破 K 收盘 upper) / upper × 100 > KEY_BREAKOUT_AMP_MIN_PCT`(默认 **0.03%**
- 空:`(lower 突破 K盘) / lower × 100 >` 同上
- **无上限**;突破过猛由 **计划 RR** 过滤。
- **不再**使用 K 线实体占开盘价比例;`KEY_BREAKOUT_AMP_MAX_PCT` **已不参与门控**
3. **确认 K 不进箱体**
- 多:确认 K 收盘 **`> upper`**(不得在 `[lower, upper]` 内)
- 空:确认 K 收盘 **`< lower`**
4. **量能:** 突破 K 成交量 > 前 `KEY_VOLUME_MA_BARS`(默认 20)根均量 × `KEY_VOLUME_RATIO_MIN`(默认 1.3
5. **日成交量排名:** 运行时仍须前 `KEY_DAILY_VOLUME_RANK_MAX`(默认 30
6. **计划 RR(最后经济门控):** 按确认 K 收盘 **E** 计算 SL/TP 后,`RR` **严格大于** `KEY_AUTO_MIN_PLANNED_RR`(默认 1.5)才市价开仓
### 3.3 止损 / 止盈(确认 K 收盘为 E)
箱体高 **H = |upper lower|**。止损锚在 **突破 K 极值** 外侧:
| 方向 | 止损(标准/趋势方案) |
|------|------------------------|
| 多 | 突破 K **最低价** × (1 `KEY_STOP_OUTSIDE_BREAKOUT_PCT`%) |
| 空 | 突破 K **最高价** × (1 + `KEY_STOP_OUTSIDE_BREAKOUT_PCT`%) |
止盈方案见下表(与改版前一致):
| 方案 | `sl_tp_mode` | 多:SL / TP | 空:SL / TP |
|------|--------------|-------------|-------------|
| 标准突破 | `standard` | 突破 K 低外侧% / **E+H** | 突破 K 高外侧% / **EH** |
| 箱体 1R·止盈 1.5H | `box_1p5` | **EH** / **E+1.5×H** | **E+H** / **E1.5×H** |
| 趋势单·自填止盈 | `trend_manual` | 突破 K 低 × (1`KEY_TREND_STOP_OUTSIDE_PCT`%) / **录入止盈** | 突破 K 高外侧% / **录入止盈** |
### 3.4 一次性结案(`close_reason`
| `close_reason` | 含义 |
|----------------|------|
| `box_opposite_break` | 标记价先突破反向边界(多:≤下沿;空:≥上沿) |
| `rr_insufficient` | 门控通过但 RR 不达标或 SL/TP 几何无效 |
| `exchange_failed` | RR 达标但实盘/交易所等原因未开仓 |
| `auto_opened` | RR 达标且市价开仓成功 |
| `key_level_alert_done` | 阻力/支撑 **3 次提醒** 完成 |
---
## 四、回调 / 突破触价开仓(程序触价,无交易所挂单)
### 4.1 录入
- **回调触价开仓**:方向必选多/空;填写 **计划入场价 E**、**止损 SL**、**止盈 TP**(做多须 `SL < E < TP`)。
- **突破触价开仓**:同上;添加时当前价须在突破方向一侧(做多:价低于 E;做空:价高于 E)。
- 计划 RR 以 **E** 为基准,须 **严格大于** `KEY_AUTO_MIN_PLANNED_RR`(默认 1.5)。
- 可选移动保本、时间平仓;**全仓杠杆模式**下可用。
### 4.2 触发与结案
| 类型 | 触发条件(标记价) |
|------|-------------------|
| **回调触价** | 做多 `≤ E`;做空 `≥ E` → 下一轮询市价开仓 |
| **突破触价** | 做多**向上穿越** E;做空**向下穿越** E → **立即**市价开仓 |
- 未成交前标记价先触 **TP 侧**`trigger_tp_invalidate`
- **突破触价**另:未穿越 E 先触 **SL 侧**`trigger_sl_invalidate`
- **24h** 未触发 → `trigger_entry_expired`
- 成功 → `trigger_entry_filled`;触发后开仓失败 → `trigger_exchange_failed`
### 4.3 计仓与占位
- **以损定仓**:按 E、SL 反推保证金,触发时重算;**全仓杠杆**:可用×缓冲比例,BTC/ETH 10x、其它 5x。
- **占当日开仓意图**(已开 + 待触发),未成交不占持仓;同币仅 1 条触价监控(含回调/突破)。
共享逻辑:`trigger_entry_key_monitor_lib.py`;轮询:`check_trigger_entry_key_monitors`
---
## 五、环境与参数(`.env` 摘要)
| 变量 | 箱体/收敛 | 阻力/支撑 |
|------|-----------|-----------|
| `KEY_BREAKOUT_AMP_MIN_PCT` | 突破越过下限(默认 0.03) | 不用 |
| `KEY_BREAKOUT_AMP_MAX_PCT` | **已废弃门控** | 不用 |
| `KEY_VOLUME_*` / `KEY_CONFIRM_*` | 用 | 不用 |
| `KEY_AUTO_MIN_PLANNED_RR` | 用 | 不用 |
| `KEY_ALERT_MAX_TIMES` / `KEY_ALERT_INTERVAL_MINUTES` | 不用 | 用(默认 3 次 / 5 分钟) |
| `KEY_DAILY_VOLUME_RANK_MAX` | 添加时 + 运行时 | **仅添加时** |
---
## 六、相关代码
| 说明 | 位置 |
|------|------|
| 共享判定 | `key_monitor_lib.py` |
| 主循环 | `check_key_monitors` |
| 自动门控 | `_key_hard_checks` |
| 阻力/支撑提醒 | `_process_key_rs_level_alert` |
| 录入 | `add_key` |
| 开仓 | `_market_open_for_key_monitor` |
# 关键位监控说明(自动开仓 + 人工盯盘)
**适用:Gate / Binance / OKX 三所实例(共用 `lib/key_monitor/key_auto_order_lib.py`)**
## 环境开关 `KEY_AUTO_ORDER_ENABLED`(默认 `false`)
| 计仓模式 | 开关 | 关键位程序自动单 |
|----------|------|------------------|
| `risk`(以损定仓) | `false` | **全部关闭**(含触价);支撑/阻力微信提醒仍可用 |
| `risk` | `true` | 箱体/收敛/斐波/假突破/触价均可自动(旧行为) |
| `full_margin`(全仓) | `false` | 全部关闭(含触价) |
| `full_margin` | `true` | **仅触价**自动;箱体/斐波等仍禁止 |
**不受本开关影响:** 人工实盘下单,关键支撑/阻力提醒,**顺势加仓**(`risk` 下),趋势回调(`risk` 下).全仓模式下策略自动仍禁止.
修改 `.env` 后须 **重启 PM2**.复盘「开仓类型」与统计分段会随开关联动隐藏关键位选项.
---
**适用:`crypto_monitor_gate`(Gate U 本位永续)**
Binance / OKX 见各自目录下同名文档;共享逻辑在 `lib/key_monitor/`.
本文档与 `.env`,`check_key_monitors`,`add_key`,`_key_hard_checks`,`_process_key_rs_level_alert` 一致.
---
## 一,监控类型总览
| 录入类型 | 录入时选方向 | 自动市价开仓 | 触发与结案 |
|----------|--------------|--------------|------------|
| **箱体突破** | **必选** 多/空 | **是**(门控 + RR) | 条件满足 → 开仓或 `rr_insufficient` / `exchange_failed`**一次性删除** |
| **收敛突破** | **必选** 多/空 | **是**(同上) | 同上 |
| **关键阻力位** | **不选**(`direction=watch`) | **否** | 5m 收盘突破上/下沿 → 微信 **3 次**`key_level_alert_done` |
| **关键支撑位** | **不选** | **否** | 同上(与阻力位**相同规则**:填上沿+下沿,程序双向监控) |
| 斐波回调 0.618 / 0.786 | 必选 | 限价挂单逻辑 | 见斐波说明(**不在下文展开**) |
| **回调触价开仓** | **必选** 多/空 | **程序盯价 → 回调触 E 后市价** | 见下文 **§四** |
| **突破触价开仓** | **必选** 多/空 | **程序盯价 → 穿越 E 立即市价** | 见下文 **§四** |
**添加时(箱体/收敛/斐波/触价):** 品种须 **日成交量排名前 `KEY_DAILY_VOLUME_RANK_MAX`(默认 30)**;上沿 **>** 下沿(触价开仓填 E/SL/TP,上下沿仅作展示占位).
---
## 二,关键阻力位 / 关键支撑位(人工盯盘)
### 2.1 录入
- 填写 **上沿 `upper`****下沿 `lower`**(程序同时监控两侧,**无法预先判定**做多还是做空).
- 页面 **不显示,不要求** 方向;库中 `direction` 初始为 `watch`,**首次突破后** 写入 `long`(向上突破上沿)或 `short`(向下突破下沿).
### 2.2 触发(极简)
- 周期:**`KLINE_TIMEFRAME`(默认 5m)最近一根已闭合 K** 的 **收盘价**(非影线).
- **向上突破上沿:** `收盘 > upper` → 推断方向 **多 / 向上**,本次监控任务开始按节奏提醒.
- **向下突破下沿:** `收盘 < lower` → 推断方向 **空 / 向下**,本次任务同样开始提醒.
- **任一侧突破即结束本条监控周期**(不会在突破后再等待另一侧;上沿,下沿谁先满足用谁,同根 K 仅可能满足一侧).
**不参与:** 量能,二确 K,越过幅度下限,日成交排名(运行时),计划 RR,自动开仓.
### 2.3 微信提醒次数
| 配置 | 默认 | 含义 |
|------|------|------|
| `KEY_ALERT_MAX_TIMES` | `3` | 突破后最多推送 3 次 |
| `KEY_ALERT_INTERVAL_MINUTES` | `5` | 相邻两次推送至少间隔 5 分钟 |
- 第 1 次:首次检测到突破的当次轮询(若已闭合 5m 满足条件).
- 第 2,3 次:仅按间隔推送(**不要求**价格仍在箱外).
- 第 3 次推送后:写入 `key_monitor_history`,`close_reason=**key_level_alert_done**`,从 `key_monitors` **删除**.
### 2.4 与箱体/收敛的区别
| 项目 | 阻力/支撑 | 箱体/收敛 |
|------|-----------|-----------|
| 方向 | 程序推断 | 人工选择 |
| K 线根数 | 1 根闭合 5m | 2 根(突破 K + 确认 K) |
| 提醒次数 | 3 次后结案 | 自动单:触发后 1 次业务推送并结案 |
---
## 三,箱体突破 /敛突破(自动开仓)
### 3.1 K 线结构(默认索引)
| 角色 | 环境变量 | 默认 | 含义 |
|------|----------|------|------|
| 突破 K | `KEY_CONFIRM_BREAKOUT_BAR` | `-2` | 倒数第 2 根闭合 K |
| 确认 K | `KEY_CONFIRM_BAR` | `-1` | 倒数第 1 根闭合 K |
### 3.2 硬门控(须全部通过)
1. **有效突破(收盘越界)**
- 多:`突破 K 收盘 > upper`
- 空:`突破 K 收盘 < lower`
2. **突破越过幅度(仅下限)**
- 多:`(突破 K 收盘 upper) / upper × 100 > KEY_BREAKOUT_AMP_MIN_PCT`(默认 **0.03%**)
- 空:`(lower 突破 K 收盘) / lower × 100 >` 同上
- **无上限**;突破过猛由 **计划 RR** 过滤.
- **不再**使用 K 线实体占开盘价比例;`KEY_BREAKOUT_AMP_MAX_PCT` **已不参与门控**.
3. **确认 K 不进箱体**
- 多:确认 K 收盘 **`> upper`**(不得在 `[lower, upper]` 内)
- 空:确认 K 收盘 **`< lower`**
4. **量能:** 突破 K 成交量 > 前 `KEY_VOLUME_MA_BARS`(默认 20)根均量 × `KEY_VOLUME_RATIO_MIN`(默认 1.3)
5. **日成交量排名:** 运行时仍须前 `KEY_DAILY_VOLUME_RANK_MAX`(默认 30)
6. **计划 RR(最后经济门控):** 按确认 K 收盘 **E** 计算 SL/TP 后,`RR` **严格大于** `KEY_AUTO_MIN_PLANNED_RR`(默认 1.5)才市价开仓
### 3.3 止损 / 止盈(确认 K 收盘为 E)
箱体高 **H = |upper lower|**.止损锚在 **突破 K 极值** 外侧:
| 方向 | 止损(标准/趋势方案) |
|------|------------------------|
| 多 | 突破 K **最低价** × (1 `KEY_STOP_OUTSIDE_BREAKOUT_PCT`%) |
| 空 | 突破 K **最高价** × (1 + `KEY_STOP_OUTSIDE_BREAKOUT_PCT`%) |
止盈方案见下表(与改版前一致):
| 方案 | `sl_tp_mode` | 多:SL / TP | 空:SL / TP |
|------|--------------|-------------|-------------|
| 标准突破 | `standard` | 突破 K 低外侧% / **E+H** | 突破 K 高外侧% / **EH** |
| 箱体 1R·止盈 1.5H | `box_1p5` | **EH** / **E+1.5×H** | **E+H** / **E1.5×H** |
| 趋势单·自填止盈 | `trend_manual` | 突破 K 低 × (1`KEY_TREND_STOP_OUTSIDE_PCT`%) / **录入止盈** | 突破 K 高外侧% / **录入止盈** |
### 3.4 一次性结案(`close_reason`)
| `close_reason` | 含义 |
|----------------|------|
| `box_opposite_break` | 标记价先突破反向边界(多:≤下沿;空:≥上沿) |
| `rr_insufficient` | 门控通过但 RR 不达标或 SL/TP 几何无效 |
| `exchange_failed` | RR 达标但实盘/交易所等原因未开仓 |
| `auto_opened` | RR 达标且市价开仓成功 |
| `key_level_alert_done` | 阻力/支撑 **3 次提醒** 完成 |
---
## 四,回调 / 突破触价开仓(程序触价,无交易所挂单)
### 4.1 录入
- **回调触价开仓**:方向必选多/空;填写 **计划入场价 E**,**止损 SL**,**止盈 TP**(做多须 `SL < E < TP`).
- **突破触价开仓**:同上;添加时当前价须在突破方向一侧(做多:价低于 E;做空:价高于 E).
- 计划 RR 以 **E** 为基准,须 **严格大于** `KEY_AUTO_MIN_PLANNED_RR`(默认 1.5).
- 可选移动保本,时间平仓;**全仓杠杆模式**下可用.
### 4.2 触发与结案
| 类型 | 触发条件(标记价) |
|------|-------------------|
| **回调触价** | 做多 `≤ E`;做空 `≥ E` → 下一轮询市价开仓 |
| **突破触价** | 做多**向上穿越** E;做空**向下穿越** E → **立即**市价开仓 |
- 未成交前标记价先触 **TP 侧**`trigger_tp_invalidate`.
- **突破触价**另:未穿越 E 先触 **SL 侧**`trigger_sl_invalidate`.
- **24h** 未触发 → `trigger_entry_expired`.
- 成功 → `trigger_entry_filled`;触发后开仓失败 → `trigger_exchange_failed`.
### 4.3 计仓与占位
- **以损定仓**:按 E,SL 反推保证金,触发时重算;**全仓杠杆**:可用×缓冲比例,BTC/ETH 10x,其它 5x.
- **占当日开仓意图**(已开 + 待触发),未成交不占持仓;同币仅 1 条触价监控(含回调/突破).
共享逻辑:`trigger_entry_key_monitor_lib.py`;轮询:`check_trigger_entry_key_monitors`.
---
## 五,环境与参数(`.env` 摘要)
| 变量 | 箱体/收敛 | 阻力/支撑 |
|------|-----------|-----------|
| `KEY_BREAKOUT_AMP_MIN_PCT` | 突破越过下限(默认 0.03) | 不用 |
| `KEY_BREAKOUT_AMP_MAX_PCT` | **已废弃门控** | 不用 |
| `KEY_VOLUME_*` / `KEY_CONFIRM_*` | 用 | 不用 |
| `KEY_AUTO_MIN_PLANNED_RR` | 用 | 不用 |
| `KEY_ALERT_MAX_TIMES` / `KEY_ALERT_INTERVAL_MINUTES` | 不用 | 用(默认 3 次 / 5 分钟) |
| `KEY_DAILY_VOLUME_RANK_MAX` | 添加时 + 运行时 | **仅添加时** |
---
## 六,相关代码
| 说明 | 位置 |
|------|------|
| 共享判定 | `key_monitor_lib.py` |
| 主循环 | `check_key_monitors` |
| 自动门控 | `_key_hard_checks` |
| 阻力/支撑提醒 | `_process_key_rs_level_alert` |
| 录入 | `add_key` |
| 开仓 | `_market_open_for_key_monitor` |
+148 -148
View File
@@ -1,148 +1,148 @@
# 界面与风控更新说明Gate 实例
## 顶栏导航4 项
| 顺序 | 名称 | 路由 | 说明 |
|------|------|------|------|
| 1 | 关键位监控 | `/key_monitor` | 关键位添加实时门控历史 |
| 2 | 实盘下单 | `/trade` | 人工开仓划转实时持仓**默认首页** `/``/trade` |
| 3 | 交易记录与复盘 | `/records` | 交易记录复盘表单AI 历史受顶栏 UTC 时间窗筛选 |
| 4 | 统计分析 | `/stats` | 按北京时间交易日切日 + 分品类统计块 |
## 关键位监控页
- 标题去掉「5m」规则条从 `.env` 读取周期确认K量能自动开仓盈亏比日成交量排名)。
- 左列活跃关键位**pos-card** 样式展示现价/距上沿/距下沿/门控
- 右列关键位历史失效/结案),与左列等高滚动**受顶栏 UTC 列表时间窗筛选**默认 UTC 当日)。
- 监控类型新增**斐波回调0.618****斐波回调0.786**与 Binance 主站同一套规则计算逻辑见仓库根目录 `fib_key_monitor_lib.py`)。
### 斐波关键位监控方案 A交易所限价
| 项 | 说明 |
|----|------|
| 同币互斥 | 每个币种只能有一条斐波监控0.618 与 0.786 不可并存 |
| 上下沿 | 上沿 **H**下沿 **L**须 H > L |
| 挂单价 E | **做多** `E = H ratio × (H L)`自 H 向下回撤);**做空** `E = L + ratio × (H L)`自 L 向上反弹 |
| 做多 | 限价 @ E止损 L止盈 H |
| 做空 | 限价 @ E止损 H止盈 L |
| 添加后 | **立即**在 Gate 挂限价单卡片显示 **挂E**限价单 ID |
| 失效 | 以**标记价**判断做多且标记价 ≥ H做空且标记价 ≤ L且限价**未成交** → 撤销该限价单并结案不写历史开仓 |
| 成交后 | 按仓位挂交易所 TP/SL → 写入 **实盘下单监控**`monitor_type=关键位监控``key_signal_type=斐波回调0.618/0.786`→ 从关键位列表移除 |
| 撤单 | 仅撤本条斐波的 `fib_limit_order_id`**不会** `cancel_all`避免误伤其他委托 |
| 盈亏比 | 计划 RR 须 > `KEY_AUTO_MIN_PLANNED_RR`与箱体/收敛一致);0.618 理论约 1.6:10.786 约 3.7:1 |
| 日成交量 | 与箱体/收敛相同须在前 `KEY_DAILY_VOLUME_RANK_MAX` 名内方可添加 |
后台轮询`check_fib_key_monitors()`标记价失效 / 成交检测);箱体/收敛仍走 `check_key_monitors()`互不干扰
手动删除关键位时若斐波限价尚未成交会先撤交易所限价再删库记录
### 箱体 / 收敛自动开仓来源标注
- 自动开仓写入 `order_monitors.key_signal_type``箱体突破``收敛突破`
- 持仓卡片交易记录列表会显示「来源 · 信号类型」
## 列表时间窗UTC全站顶栏
共用模块仓库根目录 `history_window_lib.py`Gate / Binance 主站一致)。
| 项 | 说明 |
|----|------|
| 默认 | **UTC 当日**`win_preset=utc_today`从 UTC 0:00 至当前时刻 |
| 可选 | 近 24 小时近 7 天自定义起止UTC`datetime-local` |
| 作用范围 | 关键位历史交易记录列表复盘记录 APIAI 历史 API导出「交易记录」「关键位历史」 |
| 与统计的关系 | **仅影响列表/导出****统计分析页仍按北京时间 `TRADING_DAY_RESET_HOUR`默认 8:00切交易日** |
| 库内时间 | DB 存北京时间字符串后端用 `utc_window_to_bj_sql_strings()` 换算后再 SQL 比较 |
| 切换方式 | 顶栏「列表筛选UTC」→ 选预设 → **应用**保留当前路由`/records?win_preset=…` |
查询参数示例
- `?win_preset=utc_today`
- `?win_preset=utc_last24h` / `utc_last7d`
- `?win_preset=custom&from_utc=2026-05-18 00:00:00&to_utc=2026-05-19 12:00:00`
## 交易记录与复盘
- 平仓记录可同步交易所已实现盈亏Gate 仓位历史等);列表盈亏列优先显示交易所数据标注 **所** / **估**
- 记录页提供 **立即同步**`POST /api/sync_exchange_pnl`),用于补全或刷新 `exchange_realized_pnl` 等字段
- 未做人工复盘时展示以交易所盈亏为准有同步数据时)。
- **列表默认只显示当前 UTC 时间窗内**的记录见上节);导出 CSV 同步该时间窗
- 表头 **「止损(开仓)」**展示开仓快照 `initial_stop_loss`无则回退 `stop_loss`);核对/复盘仍可用有效止损字段
- 平仓写入 `trade_records``stop_loss``initial_stop_loss` 均写入**开仓时止损快照**`key_signal_type` 保留箱体/收敛/斐波来源`fib_key_monitor_lib.key_signal_type_for_trade_record`)。
- **开仓类型**`entry_reason`):机器单平仓入库时若未手填`key_signal_type` 自动映射见下表);列表/导出「开仓类型」列 = 复盘核对值优先否则入库值否则按信号映射
| `key_signal_type` | 自动写入的 `entry_reason` |
|-------------------|---------------------------|
| 箱体突破 | 关键位箱体突破 |
| 收敛突破 | 关键位收敛突破 |
| 斐波回调0.618 | 关键位斐波0.618 |
| 斐波回调0.786 | 关键位斐波0.786 |
- 复盘表单 **开仓类型** 下拉新增上述四条固定文案与趋势/波段类并列)。
- 复盘 **离场触发** 新增 **「止盈」**从交易记录「填入复盘」时若结果为「止盈/保本止盈/移动止盈/止损/手动平仓」会自动选中对应触发项并按 `key_signal_type` 预填开仓类型
- 勾选「保存时自动生成多周期 K 线图」时**平仓时间** 为锚点各周期向前约 `ORDER_CHART_LIMIT`默认 100根 K 线`_fetch_ohlcv_ending_at`),不再固定拉「最近 100 根」
- `/api/journals``/api/reviews` 支持同一时间窗 query与列表一致
### 导出交易记录 v3
- 文件名`trade_records_v3_YYYYMMDD.csv`
- 相对 v2 增加`key_signal_type``initial_stop_loss`及开仓快照列)、`planned_rr``actual_rr``risk_amount`交易所盈亏与时间字段等末列「开仓类型」为有效展示文案
- 「关键位历史」导出同样受 UTC 时间窗限制
## 实盘下单页
- 左列实盘下单监控表单划转规则)。
- 右列实时持仓独立模块)。
- **人工开仓门控**计划盈亏比 &lt; `MANUAL_MIN_PLANNED_RR`默认 **1.4**时前端弹窗 + 后端拒绝
- **移动保本**勾选启用):监控轮询达到触发 RR 后止损阶梯上移时**同步交易所**——调用与页面「挂止盈止损」相同的 **先撤后挂**`replace_active_monitor_tpsl_on_exchange`撤该合约全部 TP/SL 条件单 → 按新止损 + 原止盈重挂)。仅交易所成功后才写库失败发企业微信告警本地止损不变未配置实盘 API 时仍只更新本地与旧行为一致)。
## 统计分析页`/stats`
| 项 | 说明 |
|----|------|
| 切日 | **北京时间**交易日边界 = 每日 `TRADING_DAY_RESET_HOUR:00``.env` 默认 **8** |
| 品类下拉 | 页顶 **「统计品类」** 下拉切换默认「全部交易」):全部交易下单监控关键位箱体突破关键位收敛结构关键位斐波0.618关键位斐波0.786一次只显示所选品类的日/周/月 |
| URL | 切换后写入 `stats_segment=``all``manual``key_box``key_conv``key_fib618``key_fib786`),刷新 `/stats` 可保持选项 |
| 每块指标 | 日 / 周 / 月开单次数平仓笔数胜率净盈亏回撤连续亏损等与原口径一致 |
| 开单次数 | 人工块`monitor_type=下单监控` 且无 `key_signal_type`关键位块`order_monitors.key_signal_type` 计数 |
| 不受 UTC 窗影响 | 统计始终基于库内全部已平仓记录按北京交易日归类**不**随顶栏 UTC 列表窗切换 |
## 持仓与计仓
- `MAX_ACTIVE_POSITIONS` 默认 **1**可在 `.env` 调大)。
- 关键位自动开仓在已有持仓时`KEY_SIZING_USE_ZERO_POSITION_SNAPSHOT=true`按**首笔开仓前**交易账户资金快照计仓`trading_sessions.key_sizing_capital_snapshot`)。
## 配置
详见 `.env.example` 中「关键位门控」「交易执行 / 人工风控」注释段Gate 专用项`GATE_*`止盈止损触发等保持原有段落不变
## 自动备份服务器
- 脚本`scripts/backup_data.sh``crypto.db` + `static/images`
- 定时`scripts/install_backup_cron.sh` → 每天 **北京时间 0:00**目录 **`/root/backups/<实例名>/YYYY-MM-DD/`**保留 **30**
- 详见 `部署文档.md` 第 5.4 节自动备份
## 数据库启动时自动迁移
`key_monitors` 新增斐波字段示例):`fib_limit_order_id``fib_entry_price``fib_stop_loss``fib_take_profit``fib_order_amount``fib_margin_capital``fib_leverage`
`trade_records` / `order_monitors` 新增或沿用`key_signal_type``exchange_realized_pnl``exchange_opened_at``exchange_closed_at``exchange_sync_key``entry_reason``reviewed_entry_reason``initial_stop_loss`
**历史数据**本次**不做**旧记录的批量回填`entry_reason` / `initial_stop_loss` / `key_signal_type`);仅**新产生**的平仓与复盘按新逻辑写入旧行展示可回退已有字段
## 涉及文件便于排查
| 路径 | 说明 |
|------|------|
| `history_window_lib.py` | UTC 时间窗解析与转北京时间 SQL 字符串 |
| `fib_key_monitor_lib.py` | 斐波计算`KEY_ENTRY_REASON_BY_SIGNAL``entry_reason_from_key_signal` |
| `crypto_monitor_gate/app.py` | 列表筛选统计分块导出 v3复盘 K 线锚点入库逻辑 |
| `crypto_monitor_gate/templates/index.html` | 顶栏时间窗统计分块 UI止损(开仓)列复盘预填 |
## 升级步骤
1. `git pull` 后对比 `.env.example`把新增变量合并进本地 `.env`
2. 在 VPS 上为 Binance / Gate / Gate Bot **各执行一次** `bash scripts/install_backup_cron.sh`若尚未安装)。
3. 重启 Gate 实例服务`pm2 restart crypto_gate`);首次启动会自动 `ALTER TABLE` 缺列斐波交易所盈亏`entry_reason`)。
4. 浏览器强刷Ctrl+F5避免旧版 `index.html` 缓存
5. 打开任意页确认顶栏出现 **「列表筛选UTC」**`/stats` 可见分品类统计与「北京 8:00 切日」说明
6. 建议在测试币上先添加一条斐波监控确认限价已挂出标记价失效会撤单成交后出现持仓监控且 TP/SL 已挂上平仓后交易记录止损(开仓)与开仓类型是否正确
# 界面与风控更新说明(Gate 实例)
## 顶栏导航(4 项)
| 顺序 | 名称 | 路由 | 说明 |
|------|------|------|------|
| 1 | 关键位监控 | `/key_monitor` | 关键位添加,实时门控,历史 |
| 2 | 实盘下单 | `/trade` | 人工开仓,划转,实时持仓(**默认首页** `/``/trade`) |
| 3 | 交易记录与复盘 | `/records` | 交易记录,复盘表单,AI 历史(受顶栏 UTC 时间窗筛选) |
| 4 | 统计分析 | `/stats` | 按北京时间交易日切日 + 分品类统计块 |
## 关键位监控页
- 标题去掉「5m」;规则条从 `.env` 读取(周期,确认K,量能,自动开仓盈亏比,日成交量排名).
- 左列:活跃关键位,**pos-card** 样式展示现价/距上沿/距下沿/门控.
- 右列:关键位历史(失效/结案),与左列等高滚动;**受顶栏 UTC 列表时间窗筛选**(默认 UTC 当日).
- 监控类型新增:**斐波回调0.618**,**斐波回调0.786**(与 Binance 主站同一套规则,计算逻辑见仓库根目录 `fib_key_monitor_lib.py`).
### 斐波关键位监控(方案 A:交易所限价)
| 项 | 说明 |
|----|------|
| 同币互斥 | 每个币种只能有一条斐波监控(0.618 与 0.786 不可并存) |
| 上下沿 | 上沿 **H**,下沿 **L**(须 H > L) |
| 挂单价 E | **做多** `E = H ratio × (H L)`(自 H 向下回撤);**做空** `E = L + ratio × (H L)`(自 L 向上反弹) |
| 做多 | 限价 @ E,止损 L,止盈 H |
| 做空 | 限价 @ E,止损 H,止盈 L |
| 添加后 | **立即**在 Gate 挂限价单;卡片显示 **挂E**,限价单 ID |
| 失效 | 以**标记价**判断:做多且标记价 ≥ H,做空且标记价 ≤ L,且限价**未成交** → 撤销该限价单并结案(不写历史开仓) |
| 成交后 | 按仓位挂交易所 TP/SL → 写入 **实盘下单监控**(`monitor_type=关键位监控`,`key_signal_type=斐波回调0.618/0.786`)→ 从关键位列表移除 |
| 撤单 | 仅撤本条斐波的 `fib_limit_order_id`,**不会** `cancel_all`,避免误伤其他委托 |
| 盈亏比 | 计划 RR 须 > `KEY_AUTO_MIN_PLANNED_RR`(与箱体/收敛一致);0.618 理论约 1.6:1,0.786 约 3.7:1 |
| 日成交量 | 与箱体/收敛相同,须在前 `KEY_DAILY_VOLUME_RANK_MAX` 名内方可添加 |
后台轮询:`check_fib_key_monitors()`(标记价失效 / 成交检测);箱体/收敛仍走 `check_key_monitors()`,互不干扰.
手动删除关键位时,若斐波限价尚未成交,会先撤交易所限价再删库记录.
### 箱体 / 收敛自动开仓(来源标注)
- 自动开仓写入 `order_monitors.key_signal_type`:`箱体突破``收敛突破`.
- 持仓卡片,交易记录列表会显示「来源 · 信号类型」.
## 列表时间窗(UTC,全站顶栏)
共用模块:仓库根目录 `history_window_lib.py`(Gate / Binance 主站一致).
| 项 | 说明 |
|----|------|
| 默认 | **UTC 当日**(`win_preset=utc_today`,从 UTC 0:00 至当前时刻) |
| 可选 | 近 24 小时,近 7 天,自定义起止(UTC,`datetime-local`) |
| 作用范围 | 关键位历史,交易记录列表,复盘记录 API,AI 历史 API,导出「交易记录」「关键位历史」 |
| 与统计的关系 | **仅影响列表/导出**;**统计分析页仍按北京时间 `TRADING_DAY_RESET_HOUR`(默认 8:00)切交易日** |
| 库内时间 | DB 存北京时间字符串;后端用 `utc_window_to_bj_sql_strings()` 换算后再 SQL 比较 |
| 切换方式 | 顶栏「列表筛选(UTC)」→ 选预设 → **应用**(保留当前路由,`/records?win_preset=…`) |
查询参数示例:
- `?win_preset=utc_today`
- `?win_preset=utc_last24h` / `utc_last7d`
- `?win_preset=custom&from_utc=2026-05-18 00:00:00&to_utc=2026-05-19 12:00:00`
## 交易记录与复盘
- 平仓记录可同步交易所已实现盈亏(Gate 仓位历史等);列表盈亏列优先显示交易所数据,标注 **所** / **估**.
- 记录页提供 **立即同步**(`POST /api/sync_exchange_pnl`),用于补全或刷新 `exchange_realized_pnl` 等字段.
- 未做人工复盘时,展示以交易所盈亏为准(有同步数据时).
- **列表默认只显示当前 UTC 时间窗内**的记录(见上节);导出 CSV 同步该时间窗.
- 表头 **「止损(开仓)」**:展示开仓快照 `initial_stop_loss`(无则回退 `stop_loss`);核对/复盘仍可用有效止损字段.
- 平仓写入 `trade_records`:`stop_loss``initial_stop_loss` 均写入**开仓时止损快照**;`key_signal_type` 保留箱体/收敛/斐波来源(`fib_key_monitor_lib.key_signal_type_for_trade_record`).
- **开仓类型**(`entry_reason`):机器单平仓入库时,若未手填,`key_signal_type` 自动映射(见下表);列表/导出「开仓类型」列 = 复盘核对值优先,否则入库值,否则按信号映射.
| `key_signal_type` | 自动写入的 `entry_reason` |
|-------------------|---------------------------|
| 箱体突破 | 关键位箱体突破 |
| 收敛突破 | 关键位收敛突破 |
| 斐波回调0.618 | 关键位斐波0.618 |
| 斐波回调0.786 | 关键位斐波0.786 |
- 复盘表单 **开仓类型** 下拉新增上述四条固定文案(与趋势/波段类并列).
- 复盘 **离场触发** 新增 **「止盈」**;从交易记录「填入复盘」时,若结果为「止盈/保本止盈/移动止盈/止损/手动平仓」会自动选中对应触发项,并按 `key_signal_type` 预填开仓类型.
- 勾选「保存时自动生成多周期 K 线图」时:**平仓时间** 为锚点,各周期向前约 `ORDER_CHART_LIMIT`(默认 100)根 K 线(`_fetch_ohlcv_ending_at`),不再固定拉「最近 100 根」.
- `/api/journals`,`/api/reviews` 支持同一时间窗 query,与列表一致.
### 导出(交易记录 v3)
- 文件名:`trade_records_v3_YYYYMMDD.csv`
- 相对 v2 增加:`key_signal_type`,`initial_stop_loss`(及开仓快照列),`planned_rr`,`actual_rr`,`risk_amount`,交易所盈亏与时间字段等;末列「开仓类型」为有效展示文案.
- 「关键位历史」导出同样受 UTC 时间窗限制.
## 实盘下单页
- 左列:实盘下单监控(表单,划转,规则).
- 右列:实时持仓(独立模块).
- **人工开仓门控**:计划盈亏比 &lt; `MANUAL_MIN_PLANNED_RR`(默认 **1.4**)时前端弹窗 + 后端拒绝.
- **移动保本**(勾选启用):监控轮询达到触发 RR 后,止损阶梯上移时**同步交易所**——调用与页面「挂止盈止损」相同的 **先撤后挂**(`replace_active_monitor_tpsl_on_exchange`:撤该合约全部 TP/SL 条件单 → 按新止损 + 原止盈重挂).仅交易所成功后才写库;失败发企业微信告警,本地止损不变.未配置实盘 API 时仍只更新本地(与旧行为一致).
## 统计分析页(`/stats`)
| 项 | 说明 |
|----|------|
| 切日 | **北京时间**;交易日边界 = 每日 `TRADING_DAY_RESET_HOUR:00`(`.env` 默认 **8**) |
| 品类下拉 | 页顶 **「统计品类」** 下拉切换(默认「全部交易」):全部交易,下单监控,关键位箱体突破,关键位收敛结构,关键位斐波0.618,关键位斐波0.786;一次只显示所选品类的日/周/月 |
| URL | 切换后写入 `stats_segment=`(`all`,`manual`,`key_box`,`key_conv`,`key_fib618`,`key_fib786`),刷新 `/stats` 可保持选项 |
| 每块指标 | 日 / 周 / 月:开单次数,平仓笔数,胜率,净盈亏,回撤,连续亏损等(与原口径一致) |
| 开单次数 | 人工块:`monitor_type=下单监控` 且无 `key_signal_type`;关键位块:`order_monitors.key_signal_type` 计数 |
| 不受 UTC 窗影响 | 统计始终基于库内全部已平仓记录,按北京交易日归类,**不**随顶栏 UTC 列表窗切换 |
## 持仓与计仓
- `MAX_ACTIVE_POSITIONS` 默认 **1**(可在 `.env` 调大).
- 关键位自动开仓:在已有持仓时,`KEY_SIZING_USE_ZERO_POSITION_SNAPSHOT=true`,按**首笔开仓前**交易账户资金快照计仓(`trading_sessions.key_sizing_capital_snapshot`).
## 配置
详见 `.env.example` 中「关键位门控」「交易执行 / 人工风控」注释段.Gate 专用项(`GATE_*`,止盈止损触发等)保持原有段落不变.
## 自动备份(服务器)
- 脚本:`scripts/backup_data.sh`(`crypto.db` + `static/images`)
- 定时:`scripts/install_backup_cron.sh` → 每天 **北京时间 0:00**,目录 **`/root/backups/<实例名>/YYYY-MM-DD/`**,保留 **30**
- 详见 `部署文档.md` 第 5.4 节(自动备份)
## 数据库(启动时自动迁移)
`key_monitors` 新增斐波字段(示例):`fib_limit_order_id`,`fib_entry_price`,`fib_stop_loss`,`fib_take_profit`,`fib_order_amount`,`fib_margin_capital`,`fib_leverage`.
`trade_records` / `order_monitors` 新增或沿用:`key_signal_type`,`exchange_realized_pnl`,`exchange_opened_at`,`exchange_closed_at`,`exchange_sync_key`,`entry_reason`,`reviewed_entry_reason`,`initial_stop_loss`.
**历史数据**:本次**不做**旧记录的批量回填(`entry_reason` / `initial_stop_loss` / `key_signal_type`);仅**新产生**的平仓与复盘按新逻辑写入.旧行展示可回退已有字段.
## 涉及文件(便于排查)
| 路径 | 说明 |
|------|------|
| `history_window_lib.py` | UTC 时间窗解析与转北京时间 SQL 字符串 |
| `fib_key_monitor_lib.py` | 斐波计算,`KEY_ENTRY_REASON_BY_SIGNAL`,`entry_reason_from_key_signal` |
| `crypto_monitor_gate/app.py` | 列表筛选,统计分块,导出 v3,复盘 K 线锚点,入库逻辑 |
| `crypto_monitor_gate/templates/index.html` | 顶栏时间窗,统计分块 UI,止损(开仓)列,复盘预填 |
## 升级步骤
1. `git pull` 后对比 `.env.example`,把新增变量合并进本地 `.env`.
2. 在 VPS 上为 Binance / Gate / **各执行一次** `bash scripts/install_backup_cron.sh`(若尚未安装).
3. 重启 Gate 实例服务(`pm2 restart crypto_gate`);首次启动会自动 `ALTER TABLE` 缺列(斐波,交易所盈亏,`entry_reason`).
4. 浏览器强刷(Ctrl+F5)避免旧版 `index.html` 缓存.
5. 打开任意页确认顶栏出现 **「列表筛选(UTC)」**;`/stats` 可见分品类统计与「北京 8:00 切日」说明.
6. 建议在测试币上先添加一条斐波监控,确认:限价已挂出,标记价失效会撤单,成交后出现持仓监控且 TP/SL 已挂上;平仓后交易记录止损(开仓)与开仓类型是否正确.
+305 -305
View File
@@ -1,305 +1,305 @@
# `crypto_monitor_gate` 部署指南SSH SOCKS + Gate.io + PM2Ubuntu
Ubuntu 环境Python / Node / PM2/opt 路径**[docs/ubuntu-server.md](../docs/ubuntu-server.md)**
本文面向**在本机运行本项目****直连 Gate.io API 不稳定或被重置** 的场景思路是
- 本机用 `ssh -D` 做动态转发把 **SOCKS5 出口**放到能正常访问 Gate 的机器常见为一台境外 VPS
- 项目在 `.env` 中设置 **`GATE_SOCKS_PROXY=socks5h://127.0.0.1:1080`**或你实际端口),`ccxt` 经 SOCKS 访问交易所
- **SSH 隧道**`ssh -D` 在本机常驻可用 **tmux****autossh** 保持连接),**不要** 把 `ssh` 交给 PM2
- 使用 **PM2** 仅托管 **Flask 应用**仓库根目录 **`ecosystem.config.cjs`** 只定义 `crypto-monitor-gate`
> 安全提醒不要把 `.env`私钥 `.pem`Gate API Key 提交到 Git下文只用占位符
---
## 0. 你需要准备的东西
- 一台 **Ubuntu**或同类 Linux运行项目的机器下文称「本机」
- 一台可 SSH 登录**能正常访问 Gate.io API** 的 VPS示例`HostName` 填你的服务器 IP用户如 `root`
- SSH**私钥登录**推荐便于隧道脚本无人值守
- 本机已安装`python3``python3-venv``pip``curl``ssh``git`可选)、`node` + `npm`安装 PM2
---
## 1. 获取代码与目录
将包含 `app.py` 的项目放到固定目录例如
```bash
mkdir -p /opt/crypto_monitor
cd /opt/crypto_monitor
git clone https://git.bz121.com/dekun/crypto_monitor.git
cd crypto_monitor/crypto_monitor_gate
```
下文用 **`/opt/crypto_monitor/crypto_monitor_gate`** 仅为示例请换成你的实际绝对路径
拉取代码后若目录下尚无 `.env`
```bash
cp -n .env.example .env
```
---
## 2. 配置 SSH 私钥与 `~/.ssh/config`
```bash
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 私钥示例~/.ssh/vps1.pem
chmod 600 ~/.ssh/vps1.pem
```
编辑 `~/.ssh/config`示例别名 **`gate-vps`**与你手工启动 `ssh -D ... gate-vps` 一致即可):
```sshconfig
Host gate-vps
HostName 你的_VPS_IP
User root
IdentityFile ~/.ssh/vps1.pem
IdentitiesOnly yes
ServerAliveInterval 30
ServerAliveCountMax 3
ExitOnForwardFailure yes
BatchMode yes
```
测试
```bash
ssh gate-vps true
```
> 若尚未完全改为密钥登录可暂时注释 `BatchMode yes`调试完成后再打开
---
## 3. 手工验证SSH SOCKS + Gate API
### 3.1 本地 SOCKS示例端口 1080
```bash
ssh -N -D 127.0.0.1:1080 gate-vps
```
保持运行另开终端继续
### 3.2 验证经 SOCKS 可访问 Gate
```bash
curl -4 -sS --max-time 15 --proxy socks5h://127.0.0.1:1080 https://api.gateio.ws/api/v4/spot/time
```
应返回 JSON含服务器时间字段)。若此处失败**不要先启动应用**先修隧道或 VPS 出站
---
## 4. Python 虚拟环境
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
pip install flask requests ccxt werkzeug PySocks Pillow
```
走 SOCKS 时 **必须** 安装 **`PySocks`**否则易出现代理相关报错
可选
```bash
export PYTHONDONTWRITEBYTECODE=1
```
---
## 5. 配置环境变量`.env.example``.env`
| 文件 | 是否进 Git | 说明 |
|------|------------|------|
| **`.env.example`** | ✅ 是 | 变量模板与注释可随 `git pull` 更新 |
| **`.env`** | ❌ 否 | 本机真实配置`app.py` **只读此文件** |
### 5.1 首次配置
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
cp -n .env.example .env
nano .env
```
### 5.2 备份与 `git pull`
- **`.env` 不在 Git 中**`git pull` **不会**覆盖本地 `.env`
- 远端若更新 **`.env.example`**pull 后请**手动**把新增变量补进你的 `.env`
- **升级前备份**`cp .env .env.backup.$(date +%Y%m%d)`恢复`cp .env.backup.YYYYMMDD .env`
- **换机**`scp` 复制 `.env`或新机 `cp .env.example .env` 后重填
### 5.3 AI 复盘与模型可选
共用根目录 **`ai_client.py`**`PYTHONPATH=..`)。`.env`**`AI_PROVIDER=openai`**默认时使用 `OPENAI_API_BASE=https://op.bz121.com/v1``OPENAI_API_KEY``OPENAI_MODEL=gemma4:e4b`**`ollama`** 则用 `OLLAMA_API` + `AI_MODEL`详见 **[AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)**
### 5.4 自动备份数据库 + 复盘图片
与 Binance 实例相同每天 **北京时间 0:00****`/root/backups`**保留 **30 天**
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
chmod +x scripts/backup_data.sh scripts/install_backup_cron.sh
bash scripts/install_backup_cron.sh
bash scripts/backup_data.sh # 试跑
```
备份目录`/root/backups/crypto_monitor_gate/YYYY-MM-DD/`详见 Binance 项目 `部署文档.md` 第 5.4 节恢复步骤可选 `.env` 变量相同)。
若还部署了 **`crypto_monitor_gate_bot`**请在该目录同样执行 `bash scripts/install_backup_cron.sh`
### 5.5 必填项检查Gate + 代理
与交易所相关的变量必须是 **Gate** 前缀**不要**再写 OKX 变量否则代理不会生效密钥也不会被识别)。至少确认
```env
APP_HOST=127.0.0.1
APP_PORT=5000
# 实盘按需
LIVE_TRADING_ENABLED=false
GATE_API_KEY=你的_Key
GATE_API_SECRET=你的_Secret
# 经本机 SSH 动态转发访问 Gate端口与隧道一致
GATE_SOCKS_PROXY=socks5h://127.0.0.1:1080
# 若不用 SOCKS可改用 HTTP 代理一般二选一
# GATE_HTTP_PROXY=http://127.0.0.1:7890
# GATE_HTTPS_PROXY=http://127.0.0.1:7890
```
说明**推荐 `socks5h://`**由 SOCKS 端解析域名`curl --proxy socks5h://...` 行为一致
---
## 6. 手工启动 Flask验证
1. SOCKS 已监听 `127.0.0.1:1080`
2. 已 `source .venv/bin/activate`
3. `.env` 已含 `GATE_SOCKS_PROXY`
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
source .venv/bin/activate
python app.py
```
浏览器访问`http://127.0.0.1:5000`或你在 `.env` 中的端口)。
---
## 7. 安装 PM2
```bash
sudo npm i -g pm2
pm2 -v
```
---
## 8. PM2使用仓库内 `ecosystem.config.cjs`推荐
在项目根目录
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
pm2 start ecosystem.config.cjs
pm2 status
pm2 logs --lines 200
```
默认只启动 **`crypto-monitor-gate`**`.venv/bin/python app.py`)。
### 本机已可直连 Gate不需要隧道时
`.env` 里应 **去掉或留空** `GATE_SOCKS_PROXY`除非仍要走别的代理),`pm2 start ecosystem.config.cjs`
### 开机自启
```bash
pm2 save
pm2 startup
# 按屏幕提示执行一条 sudo 命令
```
---
## 9. 等价手工命令不使用 ecosystem 文件时
### 9.1 SSH SOCKS自行后台常驻不推荐用 PM2
示例前台调试生产请用 **PM2**见本文与 [docs/ubuntu-server.md](../docs/ubuntu-server.md)):
```bash
ssh -N -D 127.0.0.1:1080 gate-vps \
-o ServerAliveInterval=30 -o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes
```
### 9.2 Flask
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
pm2 start /opt/crypto_monitor/crypto_monitor_gate/.venv/bin/python --name crypto-monitor-gate -- \
/opt/crypto_monitor/crypto_monitor_gate/app.py
```
---
## 10. 交易所「连接不上」排查清单
1. **`.env` 是否为 Gate 变量**必须是 `GATE_SOCKS_PROXY` / `GATE_API_KEY` / `GATE_API_SECRET`不是 OKX
2. **隧道是否在本机端口监听**若配置了 `GATE_SOCKS_PROXY`):
```bash
ss -lntp | grep 1080 || true
```
3. **curl 复测 Gate**与第 3.2 节相同);curl 不通则应用也不会通
4. **PySocks**`pip show PySocks`缺失则 `pip install PySocks`
5. **SSH 隧道连不上**检查私钥权限`~/.ssh/config`VPS 出站与端口是否与 `.env` 一致
6. **启动顺序**先保证 SOCKS 已监听`pm2 start` 应用或重启应用)。
---
## 11. 推荐启动顺序习惯
1. 若走代理先启动并确认 SSH SOCKS 已监听`curl --proxy socks5h://127.0.0.1:1080 https://api.gateio.ws/api/v4/spot/time` 成功
2. `pm2 start ecosystem.config.cjs`
3. 再确认页面与余额等接口正常
---
## 12. 免责声明
交易所有合规与地区政策要求请确保使用方式符合当地法律法规与交易所条款本文仅描述网络与工程部署路径
---
## 附录数据库标签修复脚本 `scripts/fix_breakeven_labels.py`
在 Ubuntu 上
1预览不写库):
```bash
python scripts/fix_breakeven_labels.py --db ./crypto.db --dry-run
```
2确认后执行
```bash
python scripts/fix_breakeven_labels.py --db ./crypto.db --apply
```
默认修复条件`monitor_type='下单监控'``result='止损'``pnl_amount > 0` → 改为 `result='保本止盈'`
# `crypto_monitor_gate` 部署指南:SSH SOCKS + Gate.io + PM2(Ubuntu)
Ubuntu 环境(Python / Node / PM2,/opt 路径)**[docs/ubuntu-server.md](../docs/ubuntu-server.md)**.
本文面向:**在本机运行本项目**,**直连 Gate.io API 不稳定或被重置** 的场景.思路是:
- 本机用 `ssh -D` 做动态转发,把 **SOCKS5 出口**放到能正常访问 Gate 的机器(常见为一台境外 VPS)
- 项目在 `.env` 中设置 **`GATE_SOCKS_PROXY=socks5h://127.0.0.1:1080`**(或你实际端口),`ccxt` 经 SOCKS 访问交易所
- **SSH 隧道**:`ssh -D` 在本机常驻(可用 **tmux****autossh** 保持连接),**不要** 把 `ssh` 交给 PM2
- 使用 **PM2** 仅托管 **Flask 应用**;仓库根目录 **`ecosystem.config.cjs`** 只定义 `crypto-monitor-gate`
> 安全提醒:不要把 `.env`,私钥 `.pem`,Gate API Key 提交到 Git;下文只用占位符.
---
## 0. 你需要准备的东西
- 一台 **Ubuntu**(或同类 Linux)运行项目的机器(下文称「本机」)
- 一台可 SSH 登录,**能正常访问 Gate.io API** 的 VPS(示例:`HostName` 填你的服务器 IP,用户如 `root`)
- SSH:**私钥登录**(推荐,便于隧道脚本无人值守)
- 本机已安装:`python3`,`python3-venv`,`pip`,`curl`,`ssh`,`git`(可选),`node` + `npm`(安装 PM2)
---
## 1. 获取代码与目录
将包含 `app.py` 的项目放到固定目录,例如:
```bash
mkdir -p /opt/crypto_monitor
cd /opt/crypto_monitor
git clone https://git.bz121.com/dekun/crypto_monitor.git
cd crypto_monitor/crypto_monitor_gate
```
下文用 **`/opt/crypto_monitor/crypto_monitor_gate`** 仅为示例,请换成你的实际绝对路径.
拉取代码后,若目录下尚无 `.env`:
```bash
cp -n .env.example .env
```
---
## 2. 配置 SSH 私钥与 `~/.ssh/config`
```bash
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 私钥示例:~/.ssh/vps1.pem
chmod 600 ~/.ssh/vps1.pem
```
编辑 `~/.ssh/config`(示例别名 **`gate-vps`**,与你手工启动 `ssh -D ... gate-vps` 一致即可):
```sshconfig
Host gate-vps
HostName 你的_VPS_IP
User root
IdentityFile ~/.ssh/vps1.pem
IdentitiesOnly yes
ServerAliveInterval 30
ServerAliveCountMax 3
ExitOnForwardFailure yes
BatchMode yes
```
测试:
```bash
ssh gate-vps true
```
> 若尚未完全改为密钥登录,可暂时注释 `BatchMode yes`,调试完成后再打开.
---
## 3. 手工验证:SSH SOCKS + Gate API
### 3.1 本地 SOCKS(示例端口 1080)
```bash
ssh -N -D 127.0.0.1:1080 gate-vps
```
保持运行,另开终端继续.
### 3.2 验证经 SOCKS 可访问 Gate
```bash
curl -4 -sS --max-time 15 --proxy socks5h://127.0.0.1:1080 https://api.gateio.ws/api/v4/spot/time
```
应返回 JSON(含服务器时间字段).若此处失败,**不要先启动应用**:先修隧道或 VPS 出站.
---
## 4. Python 虚拟环境
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
pip install flask requests ccxt werkzeug PySocks Pillow
```
走 SOCKS 时 **必须** 安装 **`PySocks`**,否则易出现代理相关报错.
可选:
```bash
export PYTHONDONTWRITEBYTECODE=1
```
---
## 5. 配置环境变量(`.env.example``.env`)
| 文件 | 是否进 Git | 说明 |
|------|------------|------|
| **`.env.example`** | ✅ 是 | 变量模板与注释,可随 `git pull` 更新 |
| **`.env`** | ❌ 否 | 本机真实配置;`app.py` **只读此文件** |
### 5.1 首次配置
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
cp -n .env.example .env
nano .env
```
### 5.2 备份与 `git pull`
- **`.env` 不在 Git 中**:`git pull` **不会**覆盖本地 `.env`.
- 远端若更新 **`.env.example`**,pull 后请**手动**把新增变量补进你的 `.env`.
- **升级前备份**:`cp .env .env.backup.$(date +%Y%m%d)`;恢复:`cp .env.backup.YYYYMMDD .env`.
- **换机**:`scp` 复制 `.env`,或新机 `cp .env.example .env` 后重填.
### 5.3 AI 复盘与模型(可选)
共用根目录 **`ai_client.py`**(`PYTHONPATH=..`).`.env`**`AI_PROVIDER=openai`**(默认)时使用 `OPENAI_API_BASE=https://op.bz121.com/v1`,`OPENAI_API_KEY`,`OPENAI_MODEL=gemma4:e4b`;**`ollama`** 则用 `OLLAMA_API` + `AI_MODEL`.详见 **[AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)**.
### 5.4 自动备份(数据库 + 复盘图片)
与 Binance 实例相同:每天 **北京时间 0:00****`/root/backups`**,保留 **30 天**.
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
chmod +x scripts/backup_data.sh scripts/install_backup_cron.sh
bash scripts/install_backup_cron.sh
bash scripts/backup_data.sh # 试跑
```
备份目录:`/root/backups/crypto_monitor_gate/YYYY-MM-DD/`.详见 Binance 项目 `部署文档.md` 第 5.4 节(恢复步骤,可选 `.env` 变量相同).
若还部署了 **`crypto_monitor_okx`**,请在该目录同样执行 `bash scripts/install_backup_cron.sh`.
### 5.5 必填项检查(Gate + 代理)
与交易所相关的变量必须是 **Gate** 前缀(**不要**再写 OKX 变量,否则代理不会生效,密钥也不会被识别).至少确认:
```env
APP_HOST=127.0.0.1
APP_PORT=5000
# 实盘(按需)
LIVE_TRADING_ENABLED=false
GATE_API_KEY=你的_Key
GATE_API_SECRET=你的_Secret
# 经本机 SSH 动态转发访问 Gate(端口与隧道一致)
GATE_SOCKS_PROXY=socks5h://127.0.0.1:1080
# 若不用 SOCKS,可改用 HTTP 代理(一般二选一)
# GATE_HTTP_PROXY=http://127.0.0.1:7890
# GATE_HTTPS_PROXY=http://127.0.0.1:7890
```
说明:**推荐 `socks5h://`**,由 SOCKS 端解析域名,`curl --proxy socks5h://...` 行为一致.
---
## 6. 手工启动 Flask(验证)
1. SOCKS 已监听 `127.0.0.1:1080`
2. 已 `source .venv/bin/activate`
3. `.env` 已含 `GATE_SOCKS_PROXY`
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
source .venv/bin/activate
python app.py
```
浏览器访问:`http://127.0.0.1:5000`(或你在 `.env` 中的端口).
---
## 7. 安装 PM2
```bash
sudo npm i -g pm2
pm2 -v
```
---
## 8. PM2:使用仓库内 `ecosystem.config.cjs`(推荐)
在项目根目录:
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
pm2 start ecosystem.config.cjs
pm2 status
pm2 logs --lines 200
```
默认只启动 **`crypto-monitor-gate`**(`.venv/bin/python app.py`).
### 本机已可直连 Gate,不需要隧道时
`.env` 里应 **去掉或留空** `GATE_SOCKS_PROXY`(除非仍要走别的代理),`pm2 start ecosystem.config.cjs`.
### 开机自启
```bash
pm2 save
pm2 startup
# 按屏幕提示执行一条 sudo 命令
```
---
## 9. 等价手工命令(不使用 ecosystem 文件时)
### 9.1 SSH SOCKS(自行后台常驻,不推荐用 PM2)
示例(前台调试;生产请用 **PM2**,见本文与 [docs/ubuntu-server.md](../docs/ubuntu-server.md)):
```bash
ssh -N -D 127.0.0.1:1080 gate-vps \
-o ServerAliveInterval=30 -o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes
```
### 9.2 Flask
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
pm2 start /opt/crypto_monitor/crypto_monitor_gate/.venv/bin/python --name crypto-monitor-gate -- \
/opt/crypto_monitor/crypto_monitor_gate/app.py
```
---
## 10. 交易所「连接不上」排查清单
1. **`.env` 是否为 Gate 变量**:必须是 `GATE_SOCKS_PROXY` / `GATE_API_KEY` / `GATE_API_SECRET`,不是 OKX.
2. **隧道是否在本机端口监听**(若配置了 `GATE_SOCKS_PROXY`):
```bash
ss -lntp | grep 1080 || true
```
3. **curl 复测 Gate**(与第 3.2 节相同);curl 不通则应用也不会通.
4. **PySocks**:`pip show PySocks`,缺失则 `pip install PySocks`.
5. **SSH 隧道连不上**:检查私钥权限,`~/.ssh/config`,VPS 出站与端口是否与 `.env` 一致.
6. **启动顺序**:先保证 SOCKS 已监听,`pm2 start` 应用(或重启应用).
---
## 11. 推荐启动顺序(习惯)
1. 若走代理:先启动并确认 SSH SOCKS 已监听,`curl --proxy socks5h://127.0.0.1:1080 https://api.gateio.ws/api/v4/spot/time` 成功
2. `pm2 start ecosystem.config.cjs`
3. 再确认页面与余额等接口正常
---
## 12. 免责声明
交易所有合规与地区政策要求.请确保使用方式符合当地法律法规与交易所条款.本文仅描述网络与工程部署路径.
---
## 附录:数据库标签修复脚本 `scripts/fix_breakeven_labels.py`
在 Ubuntu 上:
1)预览(不写库):
```bash
python scripts/fix_breakeven_labels.py --db ./crypto.db --dry-run
```
2)确认后执行:
```bash
python scripts/fix_breakeven_labels.py --db ./crypto.db --apply
```
默认修复条件:`monitor_type='下单监控'``result='止损'``pnl_amount > 0` → 改为 `result='保本止盈'`.
-210
View File
@@ -1,210 +0,0 @@
# =============================================================================
# 环境配置模板(可提交 Git)。程序运行时只读取同目录下的 .env。
#
# 首次部署 / 新机:
# cp .env.example .env
# nano .env # 填入真实密钥、端口、代理等
#
# 升级代码(git pull)前建议备份(.env 不在 Git 中,pull 不会覆盖):
# cp .env .env.backup.$(date +%Y%m%d)
#
# 从备份恢复:
# cp .env.backup.YYYYMMDD .env
# =============================================================================
APP_ENV=production
# 服务监听地址(云服务器通常用 0.0.0.0)
APP_HOST=0.0.0.0
# 服务端口
APP_PORT=5002
# 是否开启调试模式(生产建议 false)
APP_DEBUG=false
# 登录账号
APP_USERNAME=admin
# 登录密码(请改成你自己的强密码)
APP_PASSWORD=admin123
# 是否关闭登录校验(局域网可设 true;公网务必 false)
APP_AUTH_DISABLED=true
# --- 多账户交易中控 manual_trading_hub ---
# 中控请求本实例 /api/hub/* 时携带请求头 X-Hub-Token,须与中控启动环境变量 HUB_BRIDGE_TOKEN 一致
# 未设置且 APP_AUTH_DISABLED=false 时,仅网页登录后可访问;本机联调可保持 APP_AUTH_DISABLED=true
# HUB_BRIDGE_TOKEN=your-long-random-token
# Flask 会话密钥(必须替换为长随机字符串)
FLASK_SECRET_KEY=CHANGE_TO_LONG_RANDOM_SECRET
# 企业微信机器人 Webhook(用于行情/风控推送)
WECHAT_WEBHOOK=https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=REPLACE_WITH_REAL_KEY
# 数据库文件路径(相对路径会自动按项目目录解析)
DB_PATH=crypto.db
# 交易截图上传目录
UPLOAD_DIR=static/images
# 自动备份(scripts/backup_data.sh + cron,可选;默认即可)
# BACKUP_ROOT=/root/backups
# BACKUP_RETENTION_DAYS=30
# BACKUP_INSTANCE=crypto_monitor_gate_bot
# 已废弃:资金账户仅显示交易所 funding 余额,不再读取此变量
# TOTAL_CAPITAL=100
# 计仓:risk=以损定仓(默认);full_margin=合约可用×FULL_MARGIN_BUFFER_RATIO 全仓杠杆(须无仓后重启)
POSITION_SIZING_MODE=risk
# 每天起始基数(U
DAILY_START_CAPITAL=30
# 日内回撤后基数(U
DAILY_LOSS_CAPITAL=20
# 日内盈利后基数(U
DAILY_PROFIT_CAPITAL=50
# BTC 默认杠杆倍数
BTC_LEVERAGE=10
# 山寨币默认杠杆倍数
ALT_LEVERAGE=5
# 交易日重置小时(北京时间)
TRADING_DAY_RESET_HOUR=8
# 整点前禁止新开仓:true=启用(默认),false=关闭(仍可保留 8 点作为交易日划分)
TRADING_DAY_RESET_OPEN_GUARD_ENABLED=true
# 是否开启 Gate 实盘下单(false=只做本地流程,true=真实下单)
LIVE_TRADING_ENABLED=true
# Gate API Key(实盘)
GATE_API_KEY=REPLACE_WITH_GATE_API_KEY
# Gate API Secret(实盘)
GATE_API_SECRET=REPLACE_WITH_GATE_API_SECRET
# 保证金模式:cross=全仓,isolated=逐仓
GATE_TD_MODE=cross
# 持仓筛选:hedge=双向持仓下按多空腿过滤;其它值(如 single)不按腿过滤
GATE_POS_MODE=hedge
# 永续止盈止损:是否优先用官方仓位类触发单(POST price_ordersclose-*-position);false=仅用旧版两张 ccxt 条件单
GATE_TPSL_USE_POSITION_ORDER=true
# 触发单超时(秒),默认 604800=7 天;设为 0 或负数则不向 API 传 expiration
GATE_TPSL_TRIGGER_EXPIRATION=604800
# 触发参考价:0=最新成交 1=标记价 2=指数价(非法值按 0)
GATE_TPSL_PRICE_TYPE=0
# 仓位类 TP/SL 相对现价的最小间距(%),避免 Gate 1026「触发价须高于/低于现价」
GATE_TPSL_LAST_PRICE_GAP_PCT=0.05
# 页面与浏览器标签展示的交易所名称(多环境区分时可改成例如 Gate·模拟)
# EXCHANGE_DISPLAY_NAME=Gate.io
# =============================================================================
# 关键位门控(页面「关键位监控」规则条与 _key_hard_checks 共用)
# =============================================================================
# 【周期】门控 K 线周期,如 5m、15m
KLINE_TIMEFRAME=5m
# 【确认K】闭合 K 序列中的棒偏移:突破棒默认 -2,确认棒默认 -1
KEY_CONFIRM_BREAKOUT_BAR=-2
KEY_CONFIRM_BAR=-1
# 【量能】突破棒成交量 > 前 N 根均量 × 倍数
KEY_VOLUME_MA_BARS=20
KEY_VOLUME_RATIO_MIN=1.3
# 【突破K实体幅度】占开盘价百分比区间
# 【箱体/收敛】突破K收盘越过关键位下限%;无上限(过猛由计划RR过滤)
KEY_BREAKOUT_AMP_MIN_PCT=0.03
KEY_BREAKOUT_AMP_MAX_PCT=0.5
# 【阻力/支撑】突破后微信提醒
KEY_ALERT_MAX_TIMES=3
KEY_ALERT_INTERVAL_MINUTES=5
# 【日成交量排名】品种须在该排名前 N 名
KEY_DAILY_VOLUME_RANK_MAX=30
# 【关键位自动开仓盈亏比】严格大于该值才市价开仓
KEY_AUTO_MIN_PLANNED_RR=1.5
# 止损:突破 K 极值向外缓冲的百分比(默认 0.5 即 0.5%)
KEY_STOP_OUTSIDE_BREAKOUT_PCT=0.5
# 趋势单方案:止损在突破 K 极值外侧的百分比(默认 1 即 1%)
KEY_TREND_STOP_OUTSIDE_PCT=1
KEY_ALERT_MAX_TIMES=3
KEY_ALERT_INTERVAL_MINUTES=5
# =============================================================================
# 交易执行 / 人工风控(页面「实盘下单」)
# =============================================================================
# 【最大同时持仓】默认 1=单仓
MAX_ACTIVE_POSITIONS=1
# 【人工下单最低盈亏比】低于该值前后端均拒绝(默认 1.4,即须 >=1.4:1
MANUAL_MIN_PLANNED_RR=1.4
# 【关键位连开计仓】已有持仓时按无仓时资金快照算基数
KEY_SIZING_USE_ZERO_POSITION_SNAPSHOT=true
# 【单日开仓 AI 提醒】本交易日开仓达到该次数时推送企业微信 AI 克制提醒(不拦单)
DAILY_OPEN_ALERT_THRESHOLD=5
# 【单日开仓硬上限】本交易日开仓次数>=该值后禁止一切新开仓直至下一交易日(北京时间 TRADING_DAY_RESET_HOUR 切日);0=不启用
DAILY_OPEN_HARD_LIMIT=0
# =============================================================================
# 账户冷静期 / 日冻结风控(手动平仓、外部平仓、复盘情绪标签)
# 详见 docs/account-risk-cooldown.md
# =============================================================================
# RISK_CONTROL_ENABLED=true
# RISK_COOLING_HOURS_MANUAL=4
# RISK_COOLING_HOURS_MANUAL_JOURNAL=1
# RISK_MANUAL_CLOSE_DAILY_LIMIT=2
# RISK_MOOD_ISSUES_DAILY_FREEZE=true
# 资金与仓位刷新周期(秒)
BALANCE_REFRESH_SECONDS=60
# 前端价格快照轮询(秒)
PRICE_REFRESH_SECONDS=5
# 后台监控轮询周期(秒)
MONITOR_POLL_SECONDS=3
# 重启后多少秒内不做「外部平仓」同步(避免 API 未就绪误判)
RECONCILE_STARTUP_GRACE_SEC=90
# 连续多少次轮询确认交易所空仓后,才记为外部平仓(默认 3 次 ≈ 9 秒)
RECONCILE_FLAT_CONFIRM_POLLS=3
# 使用可用资金时的缓冲比例(如0.98代表用98%)
FULL_MARGIN_BUFFER_RATIO=0.98
# =============================================================================
# 自动划转(页顶「将 swap 补足到 XU」;与 DAILY_START_CAPITAL 独立,需一致时请设为相同值)
# =============================================================================
AUTO_TRANSFER_ENABLED=false
# 交易账户(swap)目标余额 U:每日 8 点(北京)自动划入或划出至 funding;持仓中不划转
AUTO_TRANSFER_AMOUNT=30
AUTO_TRANSFER_FROM=funding
AUTO_TRANSFER_TO=swap
TRANSFER_CCY=USDT
# 北京时间该整点小时内尝试;账簿按 UTC 自然日去重
AUTO_TRANSFER_BJ_HOUR=8
# 强制清仓整点(北京时间,默认 0=凌晨00点)
FORCE_CLOSE_BJ_HOUR=0
# 是否启用强制清仓(默认关闭,true 才会在整点执行)
FORCE_CLOSE_ENABLED=false
# 推送与AI超时(秒)
WECHAT_TIMEOUT_SECONDS=10
AI_TIMEOUT_SECONDS=120
# AI 提供方:openai(默认)| ollama
AI_PROVIDER=openai
OPENAI_API_BASE=https://op.bz121.com/v1
OPENAI_API_KEY=你的密钥
OPENAI_MODEL=gemma4:e4b
OLLAMA_API=http://127.0.0.1:11434/api/generate
AI_MODEL=huihui_ai/deepseek-r1-abliterated:latest
# Gate 代理(可选):本机网络不稳定时通过 SSH 动态转发 SOCKS5 出口
# 1) 先在本机建立隧道(示例):
# ssh -N -D 127.0.0.1:1080 root@你的VPS_IP -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes
# 2) 再启用下面这一行(推荐 socks5h,让远端解析域名):
# GATE_SOCKS_PROXY=socks5h://127.0.0.1:1080
#
# 如你更偏向 HTTP 代理(VPS 上跑 tinyproxy 之类),可用:
# GATE_HTTP_PROXY=http://127.0.0.1:3128
# GATE_HTTPS_PROXY=http://127.0.0.1:3128
# 开仓多周期K线图(可选)
# ORDER_CHART_ENABLED=true
# ORDER_CHART_TFS=4h,1h,15m,5m
# ORDER_CHART_LIMIT=100
# ORDER_CHART_DIR=static/images/order_charts
# 详见 DAILY_OPEN_ALERT_THRESHOLD / DAILY_OPEN_HARD_LIMIT;说明文档 docs/daily-open-limit.md
# 以损定仓(按交易账户资金的百分比)
# RISK_PERCENT=2
# 移动保本触发(达到多少R触发)与偏移(百分比)
# BREAKEVEN_RR_TRIGGER=1.0
# 移动保本阶梯(每多少R继续上移一次,默认1R)
# BREAKEVEN_STEP_R=1.0
# BREAKEVEN_OFFSET_PCT=0.02
# 开单风格默认值:trend / swing
# DEFAULT_TRADE_STYLE=trend
APP_TIMEZONE=Asia/Shanghai
# TRADING_DAY_RESET_HOUR 现在表示「北京时间」整点,默认 8 点起算新交易日;开仓整点限制见 TRADING_DAY_RESET_OPEN_GUARD_ENABLED
-90
View File
@@ -1,90 +0,0 @@
# crypto_monitor_gate
基于 **Flask** 的加密货币 **下单监控 / 关键位监控 / 交易复盘** 小系统,行情与实盘接口统一走 **Gate.io USDT 永续**,通过 **ccxt** 访问。
## 文档导航
| 文档 | 说明 |
|------|------|
| **[使用说明.md](./使用说明.md)** | 日常怎么用:登录、关键位四类、手工开仓、单仓与微信等 |
| **[关键位自动下单说明.md](./关键位自动下单说明.md)** | 关键位自动开仓的 RR、止盈止损、结案原因与 `.env` |
| **[部署文档.md](./部署文档.md)** | Ubuntu、PM2、**SSH SOCKS** 访问 Gate API 等 |
另:**Binance U 本位** 对等实现见同级的 **`crypto_monitor_binance`** 仓库。
---
## 功能概要
- **关键位监控**:5m 收线硬条件、企业微信推送;**箱体 / 收敛** 在 RR 达标时可 **自动市价开仓**(见专门文档);**阻力 / 支撑** 仅单次提醒结案
- **下单监控**:本地风控(含移动保本)、止盈/止损触达后轮询尝试平仓并记账
- **实盘(可选)**`LIVE_TRADING_ENABLED=true` 且配置 **`GATE_API_KEY` / `GATE_API_SECRET`** 时,支持开仓、挂单 TP/SL、余额与划转(权限依账户而定)
- **止盈止损(Gate**:市价成交后经 **`_gate_place_tp_sl_orders`** 挂单;优先 **仓位类 `price_orders`**(受 `GATE_TPSL_USE_POSITION_ORDER``GATE_TPSL_PRICE_TYPE``GATE_POS_MODE` 等影响)
---
## 环境要求
- Python 3.10+(建议)
- 依赖:`flask``requests``ccxt``werkzeug``PySocks`(经 SOCKS 代理时);`Pillow`K 线导出等可选用)
安装示例:
```bash
cd /opt/crypto_monitor/crypto_monitor_gate
source .venv/bin/activate
pip install -r ../requirements.txt
```
## 配置(`.env.example``.env`
- **`.env.example`**:模板(可提交 Git);首次:`cp .env.example .env` 后编辑。
- **`.env`**:本机真实配置(勿提交);`git pull` 不覆盖;升级前建议备份(见《部署文档》§5.2)。
项目启动时加载**仓库根目录**下的 `.env`。常用项:
| 变量 | 说明 |
|------|------|
| `GATE_API_KEY` / `GATE_API_SECRET` | Gate API(需合约与对应权限) |
| `LIVE_TRADING_ENABLED` | `true` 允许真实下单;`false` 仅本地与推送逻辑 |
| `GATE_MARGIN_MODE` / `GATE_POS_MODE` | 保证金与持仓模式 |
| `GATE_TPSL_USE_POSITION_ORDER` / `GATE_TPSL_PRICE_TYPE` 等 | 条件止盈止损行为 |
| `GATE_SOCKS_PROXY` | 可选;直连不稳时 SSH 动态转发(详见部署文档) |
| `APP_PASSWORD` / `FLASK_SECRET_KEY` | Web 登录与 Session |
| `WECHAT_WEBHOOK` | 企业微信机器人 |
| `EXCHANGE_DISPLAY_NAME` / `GATE_ACCOUNT_LABEL` | 页面与推送展示的账户文案 |
其余见 **`.env.example` 内注释** 或 **`app.py` 顶部默认值**。
## 运行
生产使用 **PM2**`ecosystem.config.cjs`)。调试:
```bash
source .venv/bin/activate && python app.py
```
见 [docs/ubuntu-server.md](../docs/ubuntu-server.md)。
端口由 **`APP_PORT`** 控制(未设置默认 **5000**)。浏览器登录 **`/login`**,口令为 **`APP_PASSWORD`**。
## 部署(Linux / PM2 / SSH SOCKS
**[部署文档.md](./部署文档.md)**。
## 自检脚本
```bash
python scripts/verify_gate_funding.py
```
用于核对密钥前缀(不落 Secret)、资金/合约可读性等(需网络与权限)。
## 数据与脚本
- 默认 SQLite:由 **`DB_PATH`** 指定(常见为项目下 `crypto.db`
- `scripts/fix_breakeven_labels.py`:修正「止损」但盈亏为正的记录标签(参见部署文档说明)
## 风险与合规
实盘有亏损风险。请确认 API 权限、IP 白名单、杠杆与保证金模式与 **Gate.io** 后台一致,并遵守当地法律法规与交易所用户协议。
File diff suppressed because it is too large Load Diff
@@ -1,34 +0,0 @@
/**
* PM2 进程定义Ubuntu / Linux
*
* 仅托管 Flask 应用**SSH SOCKS 隧道** `ssh -D` 常驻可用 tmux / autossh勿交给 PM2
* `.env` `GATE_SOCKS_PROXY` 端口一致即可不必交给 PM2
*
* 使用前项目根目录存在 `.venv`且已安装依赖 SOCKS 时需 PySocks
*
* 启动
* pm2 start ecosystem.config.cjs
* 保存开机列表
* pm2 save && pm2 startup
*/
const path = require("path");
const ROOT = __dirname;
const REPO_ROOT = path.join(ROOT, "..");
const PY = path.join(ROOT, ".venv", "bin", "python");
module.exports = {
apps: [
{
name: "crypto_gate_bot",
cwd: ROOT,
script: path.join(ROOT, "app.py"),
interpreter: PY,
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: "800M",
env: { PYTHONPATH: REPO_ROOT },
},
],
};
@@ -1,109 +0,0 @@
#!/usr/bin/env bash
# Daily backup: SQLite DB + static/images → /root/backups/<instance>/<YYYY-MM-DD>/
# Prune backup folders older than RETENTION_DAYS (default 30).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
cd "$PROJECT_DIR"
BACKUP_ROOT="${BACKUP_ROOT:-/root/backups}"
RETENTION_DAYS="${RETENTION_DAYS:-30}"
INSTANCE_NAME="${BACKUP_INSTANCE:-$(basename "$PROJECT_DIR")}"
TZ_NAME="${BACKUP_TZ:-Asia/Shanghai}"
log() {
printf '[%s] %s\n' "$(TZ="$TZ_NAME" date '+%Y-%m-%d %H:%M:%S %Z')" "$*"
}
read_env_var() {
local key="$1"
local default="$2"
local line
if [[ ! -f .env ]]; then
printf '%s' "$default"
return
fi
line="$(grep -E "^${key}=" .env 2>/dev/null | tail -1 || true)"
if [[ -z "$line" ]]; then
printf '%s' "$default"
return
fi
printf '%s' "${line#*=}" | tr -d '\r'
}
resolve_project_path() {
local p="$1"
if [[ "$p" == /* ]]; then
printf '%s' "$p"
else
printf '%s' "$PROJECT_DIR/$p"
fi
}
prune_old_backups() {
local base="$BACKUP_ROOT/$INSTANCE_NAME"
[[ -d "$base" ]] || return 0
local cutoff
cutoff="$(TZ="$TZ_NAME" date -d "-${RETENTION_DAYS} days" +%Y-%m-%d 2>/dev/null || true)"
if [[ -z "$cutoff" ]]; then
find "$base" -mindepth 1 -maxdepth 1 -type d -mtime +"$RETENTION_DAYS" -print0 |
xargs -r -0 rm -rf
return 0
fi
local dir name
for dir in "$base"/*/; do
[[ -d "$dir" ]] || continue
name="$(basename "$dir")"
[[ "$name" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]] || continue
if [[ "$name" < "$cutoff" ]]; then
log "prune: remove $dir (older than ${RETENTION_DAYS} days)"
rm -rf "$dir"
fi
done
}
DB_REL="$(read_env_var DB_PATH crypto.db)"
UPLOAD_REL="$(read_env_var UPLOAD_DIR static/images)"
BACKUP_ROOT="$(read_env_var BACKUP_ROOT "$BACKUP_ROOT")"
RETENTION_DAYS="$(read_env_var BACKUP_RETENTION_DAYS "$RETENTION_DAYS")"
INSTANCE_NAME="$(read_env_var BACKUP_INSTANCE "$INSTANCE_NAME")"
DB_PATH="$(resolve_project_path "$DB_REL")"
UPLOAD_DIR="$(resolve_project_path "$UPLOAD_REL")"
DATE_TAG="$(TZ="$TZ_NAME" date +%Y-%m-%d)"
DEST="$BACKUP_ROOT/$INSTANCE_NAME/$DATE_TAG"
if [[ ! -f "$DB_PATH" ]]; then
log "error: database not found: $DB_PATH"
exit 1
fi
mkdir -p "$DEST"
log "start backup instance=$INSTANCE_NAME dest=$DEST"
if command -v sqlite3 >/dev/null 2>&1; then
sqlite3 "$DB_PATH" ".backup '$DEST/crypto.db'"
log "db: sqlite3 backup -> $DEST/crypto.db"
else
cp -a "$DB_PATH" "$DEST/crypto.db"
log "db: cp -> $DEST/crypto.db (sqlite3 not installed)"
fi
if [[ -d "$UPLOAD_DIR" ]]; then
tar -czf "$DEST/static_images.tar.gz" -C "$(dirname "$UPLOAD_DIR")" "$(basename "$UPLOAD_DIR")"
log "images: $UPLOAD_DIR -> $DEST/static_images.tar.gz"
else
log "warn: upload dir missing, skip images: $UPLOAD_DIR"
fi
{
echo "instance=$INSTANCE_NAME"
echo "project_dir=$PROJECT_DIR"
echo "backup_date=$DATE_TAG"
echo "db_path=$DB_PATH"
echo "upload_dir=$UPLOAD_DIR"
} >"$DEST/manifest.txt"
prune_old_backups
log "done"
@@ -1,69 +0,0 @@
#!/usr/bin/env python3
"""One-shot SQLite backup before code deploy. Reads DB_PATH from .env (default crypto.db)."""
from __future__ import annotations
import os
import shutil
import sqlite3
from datetime import datetime
from pathlib import Path
PROJECT_DIR = Path(__file__).resolve().parent.parent
def _read_env_db_path() -> Path:
env_file = PROJECT_DIR / ".env"
default = PROJECT_DIR / "crypto.db"
if not env_file.is_file():
return default
for line in env_file.read_text(encoding="utf-8", errors="replace").splitlines():
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, val = line.split("=", 1)
if key.strip() != "DB_PATH":
continue
val = val.strip().strip('"').strip("'")
p = Path(val)
return p if p.is_absolute() else PROJECT_DIR / p
return default
def main() -> int:
db_path = _read_env_db_path()
if not db_path.is_file():
print(f"error: database not found: {db_path}")
return 1
stamp = datetime.now().strftime("%Y%m%d_%H%M%S")
dest_dir = PROJECT_DIR / "backups" / stamp
dest_dir.mkdir(parents=True, exist_ok=True)
dest = dest_dir / db_path.name
try:
src = sqlite3.connect(str(db_path))
dst = sqlite3.connect(str(dest))
src.backup(dst)
dst.close()
src.close()
method = "sqlite3 backup"
except Exception:
shutil.copy2(db_path, dest)
method = "file copy"
manifest = dest_dir / "manifest.txt"
manifest.write_text(
"\n".join(
[
f"project_dir={PROJECT_DIR}",
f"source_db={db_path}",
f"backup_file={dest}",
f"method={method}",
f"created_at={stamp}",
]
),
encoding="utf-8",
)
print(f"ok: {dest} ({method})")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,108 +0,0 @@
#!/usr/bin/env python3
"""
一次性修复历史交易记录标签
trade_records 止损但实际盈利的记录改为保本止盈
默认条件可通过参数修改
- monitor_type = 下单监控
- result = 止损
- pnl_amount > 0
用法示例
1) 仅预览不落库
python scripts/fix_breakeven_labels.py --db ./crypto.db --dry-run
2) 执行修复
python scripts/fix_breakeven_labels.py --db ./crypto.db --apply
"""
from __future__ import annotations
import argparse
import sqlite3
import sys
from pathlib import Path
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Fix historical stop-loss records with positive pnl.")
parser.add_argument("--db", required=True, help="Path to sqlite db file, e.g. ./crypto.db")
parser.add_argument("--monitor-type", default="下单监控", help="Filter by monitor_type (default: 下单监控)")
parser.add_argument("--from-result", default="止损", help="Source result label (default: 止损)")
parser.add_argument("--to-result", default="保本止盈", help="Target result label (default: 保本止盈)")
parser.add_argument("--dry-run", action="store_true", help="Preview only, no write")
parser.add_argument("--apply", action="store_true", help="Execute update")
return parser.parse_args()
def main() -> int:
args = parse_args()
db_path = Path(args.db).expanduser().resolve()
if not db_path.exists():
print(f"[ERR] DB not found: {db_path}")
return 1
if args.dry_run and args.apply:
print("[ERR] --dry-run and --apply are mutually exclusive.")
return 1
if not args.dry_run and not args.apply:
print("[INFO] No mode provided, defaulting to --dry-run.")
args.dry_run = True
conn = sqlite3.connect(str(db_path))
conn.row_factory = sqlite3.Row
cur = conn.cursor()
where_sql = """
monitor_type = ?
AND result = ?
AND CAST(COALESCE(pnl_amount, 0) AS REAL) > 0
"""
params = (args.monitor_type, args.from_result)
cur.execute(f"SELECT COUNT(*) AS c FROM trade_records WHERE {where_sql}", params)
will_change = int(cur.fetchone()["c"])
print(f"[INFO] Candidate rows: {will_change}")
if will_change == 0:
print("[INFO] Nothing to update.")
conn.close()
return 0
cur.execute(
f"""
SELECT id, symbol, result, pnl_amount, closed_at
FROM trade_records
WHERE {where_sql}
ORDER BY id DESC
LIMIT 10
""",
params,
)
sample = cur.fetchall()
print("[INFO] Sample (latest 10):")
for r in sample:
print(
f" id={r['id']} symbol={r['symbol']} result={r['result']} "
f"pnl={r['pnl_amount']} closed_at={r['closed_at']}"
)
if args.dry_run:
print("[DRY-RUN] No write executed.")
conn.close()
return 0
cur.execute(
f"UPDATE trade_records SET result=? WHERE {where_sql}",
(args.to_result, *params),
)
changed = int(cur.rowcount)
conn.commit()
conn.close()
print(f"[DONE] Updated rows: {changed}")
return 0
if __name__ == "__main__":
sys.exit(main())
@@ -1,38 +0,0 @@
#!/usr/bin/env bash
# Install daily backup cron: Beijing 00:00 (CRON_TZ=Asia/Shanghai).
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
BACKUP_SCRIPT="$SCRIPT_DIR/backup_data.sh"
INSTANCE_NAME="${BACKUP_INSTANCE:-$(basename "$PROJECT_DIR")}"
LOG_FILE="${BACKUP_CRON_LOG:-/var/log/crypto-monitor-backup-${INSTANCE_NAME}.log}"
if [[ ! -x "$BACKUP_SCRIPT" ]]; then
chmod +x "$BACKUP_SCRIPT"
fi
TMP="$(mktemp)"
trap 'rm -f "$TMP"' EXIT
{
crontab -l 2>/dev/null | grep -vF "$BACKUP_SCRIPT" || true
echo "CRON_TZ=Asia/Shanghai"
echo "0 0 * * * $BACKUP_SCRIPT >> $LOG_FILE 2>&1"
} >"$TMP"
awk '
BEGIN { tz = 0 }
/^CRON_TZ=Asia\/Shanghai$/ {
if (tz++) next
}
{ print }
' "$TMP" >"${TMP}.2"
mv "${TMP}.2" "$TMP"
crontab "$TMP"
echo "Installed cron for $INSTANCE_NAME"
echo " Schedule : daily 00:00 Asia/Shanghai"
echo " Script : $BACKUP_SCRIPT"
echo " Log : $LOG_FILE"
crontab -l | grep -F "$BACKUP_SCRIPT" || true
@@ -1,93 +0,0 @@
"""
在项目根目录执行会加载根目录 .env
python scripts/verify_gate_funding.py
依次探测[0] swap 余额 App交易账户同源[1][3] 现货 / 统一账户资金路径
打印 GATE_API_KEY 8 位便于与 Gate 控制台核对不含 Secret用于服务器自检
"""
from __future__ import annotations
import importlib.util
import os
import sys
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if ROOT not in sys.path:
sys.path.insert(0, ROOT)
def _load_app():
path = os.path.join(ROOT, "app.py")
spec = importlib.util.spec_from_file_location("crypto_app", path)
mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(mod)
return mod
def main():
os.chdir(ROOT)
mod = _load_app()
print("LIVE_TRADING_ENABLED =", os.getenv("LIVE_TRADING_ENABLED"))
ok, reason = mod.ensure_exchange_live_ready()
print("ensure_exchange_live_ready =", ok, repr(reason))
if not ok:
print("跳过私有接口探测")
return 1
mod.ensure_markets_loaded()
k = (os.getenv("GATE_API_KEY") or "").strip()
s = (os.getenv("GATE_API_SECRET") or "").strip()
if not k or "REPLACE" in k.upper():
print("WARN: GATE_API_KEY 为空或仍像占位符,请核对 .env")
if not s or "REPLACE" in s.upper():
print("WARN: GATE_API_SECRET 为空或仍像占位符,请核对 .env")
print("GATE_API_KEY prefix (8 chars):", (k[:8] + "") if len(k) > 8 else "(short)")
# 0) swap — 与 App「交易账户」余额同源(优先看此项是否与网页一致)
try:
bal = mod.exchange.fetch_balance({"type": "swap"})
v0 = mod._extract_usdt_total(bal)
print("[0] fetch_balance(swap) USDT total =", v0)
except Exception as e:
print("[0] fetch_balance(swap) FAILED:", type(e).__name__, e)
# 1) fetch_balance spot + marginMode spot
try:
bal = mod.exchange.fetch_balance({"type": "spot", "marginMode": "spot"})
v = mod._extract_usdt_total(bal)
print("[1] fetch_balance(spot,marginMode=spot) USDT total =", v)
except Exception as e:
print("[1] fetch_balance(spot) FAILED:", type(e).__name__, e)
# 2) raw spot accounts
try:
resp = mod.exchange.privateSpotGetAccounts({})
v2 = mod._parse_gate_spot_accounts_response_usdt(resp)
print("[2] privateSpotGetAccounts USDT =", v2)
except Exception as e:
print("[2] privateSpotGetAccounts FAILED:", type(e).__name__, e)
# 3) unified accounts raw
try:
raw = mod.exchange.privateUnifiedGetAccounts({})
body = raw
if isinstance(body, dict) and isinstance(body.get("result"), dict):
body = body["result"]
if isinstance(body, dict):
keys = sorted(body.keys())
print("[3] unified top-level keys (sample):", keys[:25], "..." if len(keys) > 25 else "")
v3 = mod._parse_usdt_from_gate_unified_accounts_body(body) if isinstance(body, dict) else None
print("[3] parsed unified USDT =", v3)
except Exception as e:
print("[3] privateUnifiedGetAccounts FAILED:", type(e).__name__, e)
fu = mod._fetch_gate_funding_usdt()
print(">>> _fetch_gate_funding_usdt() =", fu)
f, t = mod.get_exchange_capitals(force=True)
print(">>> get_exchange_capitals(force=True) funding, trading =", f, t)
return 0
if __name__ == "__main__":
raise SystemExit(main())
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

@@ -1,17 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<defs>
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#22d3ee"/>
<stop offset="100%" stop-color="#34d399"/>
</linearGradient>
</defs>
<rect width="512" height="512" rx="108" fill="#0c1019"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="#141b2d"/>
<rect x="36" y="36" width="440" height="440" rx="88" fill="none" stroke="url(#g)" stroke-width="12"/>
<path d="M120 320 L200 248 L280 272 L392 168" fill="none" stroke="url(#g)" stroke-width="20" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="392" cy="168" r="18" fill="#34d399"/>
<rect x="168" y="268" width="28" height="64" rx="6" fill="#f87171"/>
<line x1="182" y1="248" x2="182" y2="340" stroke="#f87171" stroke-width="10" stroke-linecap="round"/>
<rect x="268" y="220" width="28" height="96" rx="6" fill="#34d399"/>
<line x1="282" y1="200" x2="282" y2="340" stroke="#34d399" stroke-width="10" stroke-linecap="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

@@ -1 +0,0 @@
ok2
@@ -1,136 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN" data-theme="dark">
<head>
<meta charset="UTF-8">
<script src="/static/instance_theme.js?v=4"></script>
<title>登录 · {{ exchange_display }}</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #0a0a10;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
color: #fff;
}
.login-box {
background: #12121a;
padding: 2.5rem;
border-radius: 16px;
width: 100%;
max-width: 400px;
border: 1px solid #242435;
box-shadow: 0 8px 24px rgba(0,0,0,0.3);
}
.login-box h2 {
margin-bottom: 2rem;
text-align: center;
font-size: 1.5rem;
background: linear-gradient(90deg, #4cc2ff, #7b42ff);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.form-group {
margin-bottom: 1.25rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-size: 0.9rem;
color: #a9a9ff;
}
.form-group input {
width: 100%;
padding: 0.85rem 1rem;
border-radius: 10px;
border: 1px solid #2e2e45;
background: #1a1a29;
color: #fff;
font-size: 0.95rem;
outline: none;
}
.form-group input:focus {
border-color: #4cc2ff;
}
button {
width: 100%;
padding: 0.9rem;
border-radius: 10px;
border: none;
background: linear-gradient(90deg, #4285f4, #7b42ff);
color: #fff;
font-size: 1rem;
font-weight: 500;
cursor: pointer;
transition: 0.2s;
}
button:hover {
opacity: 0.9;
}
.flash {
padding: 0.8rem;
margin-bottom: 1rem;
background: #331e24;
color: #ff6666;
border-radius: 8px;
text-align: center;
font-size: 0.85rem;
}
.exchange-line {
text-align: center;
font-size: 0.82rem;
color: #8892b0;
margin: -0.5rem 0 1.25rem;
}
.exchange-line strong {
color: #b8f5d0;
font-weight: 600;
}
</style>
<link rel="stylesheet" href="/static/instance_theme.css?v=4">
</head>
<div class="login-theme-bar">
<div class="theme-toggle instance-theme-toggle" role="group" aria-label="界面主题">
<button type="button" class="theme-toggle-btn is-active" data-theme-value="dark" aria-pressed="true" title="暗色主题">
<svg class="theme-icon" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true">
<path fill="currentColor" d="M12.1 3a9 9 0 1 0 8.9 11 6.5 6.5 0 1 1-8.9-11z"/>
</svg>
</button>
<button type="button" class="theme-toggle-btn" data-theme-value="light" aria-pressed="false" title="亮色主题">
<svg class="theme-icon" viewBox="0 0 24 24" width="18" height="18" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
<circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/>
</svg>
</button>
</div>
</div>
<body>
<div class="login-box">
<h2>交易监控系统登录</h2>
<p class="exchange-line">交易所:<strong>{{ exchange_display }}</strong></p>
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="flash">{{ messages[0] }}</div>
{% endif %}
{% endwith %}
<form method="POST" autocomplete="off">
<div class="form-group">
<label>账号</label>
<input type="text" name="username" required placeholder="请输入账号" autocomplete="off" autocapitalize="off" spellcheck="false">
</div>
<div class="form-group">
<label>密码</label>
<input type="password" name="password" required placeholder="请输入密码" autocomplete="new-password">
</div>
<button type="submit">登录</button>
</form>
</div>
</body>
</html>
@@ -1,194 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>实盘下单放大 | 100根K线</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;background:#0b0d14;color:#eaeaea;padding:14px}
.container{width:min(98vw,1900px);margin:0 auto}
.card{background:#121726;border-radius:10px;padding:12px;border:1px solid #2a3150;margin-bottom:12px}
.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.btn{padding:7px 10px;border-radius:8px;text-decoration:none;border:1px solid #304164;background:#151a2a;color:#8fc8ff;cursor:pointer}
.btn:hover{background:#1f2740}
select,button{padding:8px 10px;border-radius:8px;border:1px solid #2e2e45;background:#1a1a29;color:#fff}
.meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:8px;margin-top:10px}
.meta-item{background:#141b2f;border:1px solid #27324e;border-radius:8px;padding:8px}
.meta-item .k{font-size:.76rem;color:#9fb0d8}
.meta-item .v{font-size:1rem;margin-top:4px;word-break:break-all}
.status{font-size:.84rem;color:#95a2c2}
.status.err{color:#ff8080}
#chart-wrap{height:560px;background:#0f1320;border:1px solid #2a3150;border-radius:10px;padding:8px}
#chart{width:100%;height:100%}
.empty{padding:18px;color:#95a2c2}
</style>
</head>
<body>
<div class="container">
<div class="card">
<div class="row" style="justify-content:space-between">
<div class="row">
<a class="btn" href="/">返回首页</a>
<strong style="color:#dbe4ff">实盘下单放大(100根K线)</strong>
</div>
<div class="status">最近刷新:<span id="updated-at">--</span></div>
</div>
{% if orders %}
<div class="row" style="margin-top:10px">
<label>订单</label>
<select id="order-id">
{% for o in orders %}
<option value="{{ o.id }}" {% if selected_order and o.id == selected_order.id %}selected{% endif %}>
#{{ o.id }} {{ o.symbol }} {{ '做多' if o.direction == 'long' else '做空' }}
</option>
{% endfor %}
</select>
<label>周期</label>
<select id="timeframe">
{% for tf in ['1m','3m','5m','15m','30m','1h','4h','1d'] %}
<option value="{{ tf }}" {% if tf == default_timeframe %}selected{% endif %}>{{ tf }}</option>
{% endfor %}
</select>
<button id="manual-refresh" type="button">刷新</button>
<span id="load-status" class="status"></span>
</div>
{% else %}
<div class="empty">当前没有激活订单,无法展示放大K线。</div>
{% endif %}
</div>
{% if orders %}
<div class="card">
<div class="meta">
<div class="meta-item"><div class="k">交易对</div><div class="v" id="m-symbol">-</div></div>
<div class="meta-item"><div class="k">方向</div><div class="v" id="m-direction">-</div></div>
<div class="meta-item"><div class="k">成交价</div><div class="v" id="m-entry">-</div></div>
<div class="meta-item"><div class="k">止损</div><div class="v" id="m-sl">-</div></div>
<div class="meta-item"><div class="k">止盈</div><div class="v" id="m-tp">-</div></div>
<div class="meta-item"><div class="k">盈亏比</div><div class="v" id="m-rr">-</div></div>
<div class="meta-item"><div class="k">现价</div><div class="v" id="m-price">-</div></div>
<div class="meta-item"><div class="k">浮盈亏</div><div class="v" id="m-pnl">-</div></div>
</div>
</div>
<div class="card">
<div id="chart-wrap"><div id="chart"></div></div>
</div>
{% endif %}
</div>
{% if orders %}
<script src="https://unpkg.com/lightweight-charts/dist/lightweight-charts.standalone.production.js"></script>
<script>
const refreshMs = Math.max({{ price_refresh_seconds * 1000 }}, 5000);
const orderSelect = document.getElementById("order-id");
const tfSelect = document.getElementById("timeframe");
const statusEl = document.getElementById("load-status");
const updatedAtEl = document.getElementById("updated-at");
const chartHost = document.getElementById("chart");
const fmt = (v, d=6) => (v === null || typeof v === "undefined" || Number.isNaN(Number(v))) ? "-" : Number(v).toFixed(d);
let chart = null;
let candleSeries = null;
let priceLines = [];
function ensureChart(){
if(chart){ return true; }
if(!window.LightweightCharts){
statusEl.className = "status err";
statusEl.innerText = "图表库加载失败";
return false;
}
chart = LightweightCharts.createChart(chartHost, {
layout: { background: { color: "#0f1320" }, textColor: "#d6deff" },
grid: { vertLines: { color: "#1e263d" }, horzLines: { color: "#1e263d" } },
rightPriceScale: { borderColor: "#2a3150" },
timeScale: { borderColor: "#2a3150", timeVisible: true, secondsVisible: false },
crosshair: { mode: 0 }
});
candleSeries = chart.addCandlestickSeries({
upColor: "#4cd97f",
downColor: "#ff6666",
borderVisible: false,
wickUpColor: "#4cd97f",
wickDownColor: "#ff6666"
});
window.addEventListener("resize", () => {
chart.applyOptions({ width: chartHost.clientWidth, height: chartHost.clientHeight });
});
chart.applyOptions({ width: chartHost.clientWidth, height: chartHost.clientHeight });
return true;
}
function resetPriceLines(){
if(!candleSeries){ return; }
priceLines.forEach(line => {
try { candleSeries.removePriceLine(line); } catch (_) {}
});
priceLines = [];
}
function addLine(price, title, color){
if(!candleSeries || typeof price === "undefined" || price === null){ return; }
const p = Number(price);
if(Number.isNaN(p) || p <= 0){ return; }
priceLines.push(candleSeries.createPriceLine({
price: p, color, lineWidth: 1, lineStyle: 0, axisLabelVisible: true, title
}));
}
function paintOrder(order){
document.getElementById("m-symbol").innerText = order.symbol || "-";
document.getElementById("m-direction").innerText = (order.direction === "short") ? "做空" : "做多";
document.getElementById("m-entry").innerText = order.trigger_price_display || fmt(order.trigger_price, 8);
document.getElementById("m-sl").innerText = order.stop_loss_display || fmt(order.stop_loss, 8);
document.getElementById("m-tp").innerText = order.take_profit_display || fmt(order.take_profit, 8);
document.getElementById("m-rr").innerText = (order.rr_ratio === null || typeof order.rr_ratio === "undefined") ? "-" : `1:${Number(order.rr_ratio).toFixed(2)}`;
document.getElementById("m-price").innerText = order.current_price_display || fmt(order.current_price, 8);
const pnlEl = document.getElementById("m-pnl");
pnlEl.innerText = `${fmt(order.float_pnl, 2)}U (${fmt(order.float_pct, 2)}%)`;
pnlEl.style.color = Number(order.float_pnl || 0) > 0 ? "#4cd97f" : (Number(order.float_pnl || 0) < 0 ? "#ff6666" : "#d6deff");
}
async function loadOrderKline(){
if(!ensureChart()){ return; }
const orderId = orderSelect.value;
const timeframe = tfSelect.value;
if(!orderId){ return; }
statusEl.className = "status";
statusEl.innerText = "加载中...";
try{
const resp = await fetch(`/api/order_kline?order_id=${encodeURIComponent(orderId)}&timeframe=${encodeURIComponent(timeframe)}`);
const data = await resp.json();
if(!resp.ok || !data.ok){ throw new Error(data.msg || "请求失败"); }
const candles = Array.isArray(data.candles) ? data.candles : [];
if(!candles.length){
statusEl.className = "status err";
statusEl.innerText = "暂无K线数据";
return;
}
candleSeries.setData(candles);
resetPriceLines();
addLine(data.order.trigger_price, "成交价", "#42a5f5");
addLine(data.order.stop_loss, "止损", "#ff6666");
addLine(data.order.take_profit, "止盈", "#4cd97f");
chart.timeScale().fitContent();
paintOrder(data.order || {});
updatedAtEl.innerText = data.updated_at || "--";
statusEl.className = "status";
statusEl.innerText = `已加载 ${candles.length} 根K线`;
}catch(err){
statusEl.className = "status err";
statusEl.innerText = err && err.message ? err.message : "加载失败";
}
}
document.getElementById("manual-refresh").addEventListener("click", loadOrderKline);
orderSelect.addEventListener("change", loadOrderKline);
tfSelect.addEventListener("change", loadOrderKline);
loadOrderKline();
setInterval(loadOrderKline, refreshMs);
</script>
{% endif %}
</body>
</html>
-147
View File
@@ -1,147 +0,0 @@
# 使用说明
**本文件对应仓库:`crypto_monitor_gate`Gate.io USDT 永续)。**
功能、界面与 **Binance U 本位版**(目录 `crypto_monitor_binance`)基本一致,差异主要在 **`.env` 里交易所密钥与部分参数名**`GATE_*` / `BINANCE_*`),文末有对照。
**更细的部署(SSH 代理、PM2、依赖安装)** 见同目录 **`部署文档.md`**。
**关键位自动开仓的规则、RR、结案原因** 见 **`关键位自动下单说明.md`**。
---
## 1. 它能做什么
面向个人盘面的 **Web 控制台**,主要能力包括:
| 模块 | 说明 |
|------|------|
| **关键位监控** | 录入上/下沿与类型,按 **5m 收线** 做硬条件过滤;符合条件后 **企业微信** 提醒,部分类型可 **自动市价开仓**(见第 4 节与专门文档)。 |
| **实盘下单监控** | 手工填止损/止盈,**以损定仓** 市价开单,挂上条件止盈止损,并在页面跟踪浮盈亏、保本逻辑等。 |
| **交易记录 / 复盘** | 平仓结果、盈亏、错过的单等归档与导出;可选 **AI 复盘**(见 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md))。 |
| **策略交易** | 顶栏 `/strategy`:趋势回调 + 顺势加仓双栏;见 [策略交易说明.md](../策略交易说明.md)。 |
后台按 **`MONITOR_POLL_SECONDS`**(默认几秒)轮询行情与监控逻辑。**切勿**在未理解规则时同时运行两套程序共用一个实盘账户。
---
## 2. 运行前必须配置(`.env`
首次在本目录执行 **`cp .env.example .env`**,再编辑 `.env``.env` 勿提交 Git`git pull` 不会改你的 `.env`,升级前建议 `cp .env .env.backup.$(date +%Y%m%d)`)。
至少检查以下项(具体键名以 **`.env.example`** 为准):
| 类别 | 说明 |
|------|------|
| **登录网页** | `APP_PASSWORD`:打开站点后的登录口令。`FLASK_SECRET_KEY`:Session 密钥,请勿使用默认值。 |
| **企业微信** | `WECHAT_WEBHOOK`:告警与关键位推送机器人的 Webhook。 |
| **是否真下单** | `LIVE_TRADING_ENABLED=false`:**不会**向交易所发送开仓指令(适合测试流程)。改为 `true` 且密钥正确才会实盘。 |
| **交易所 API** | **本仓库:** `GATE_API_KEY``GATE_API_SECRET`;合约相关见 `GATE_MARGIN_MODE``GATE_POS_MODE``GATE_TPSL_*` 等。**勿**把 `.env` 提交到 Git。 |
| **关键位 RR / 止损外扩** | `KEY_AUTO_MIN_PLANNED_RR``KEY_STOP_OUTSIDE_BREAKOUT_PCT`(详见 `关键位自动下单说明.md`)。 |
| **AI 复盘** | `AI_PROVIDER=openai`(默认)或 `ollama`;变量见 `.env.example` 与 [AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)。 |
网络不稳定时可为 Gate 配置 **`GATE_SOCKS_PROXY`** 等(见 **`部署文档.md`**)。
---
## 3. 如何启动与登录
1. 按 **`部署文档.md`** 建好虚拟环境、安装依赖(如 `flask``requests``ccxt`、按需 `Pillow``PySocks` 等),配置好 `.env`
2. 启动 Flask 应用(本仓库可用 **`ecosystem.config.cjs`** 交给 PM2,或本地 `python app.py` / `flask run`,以你当前脚本为准)。
3. 浏览器访问站点,打开 **`/login`**,使用 **`.env` 里的 `APP_PASSWORD`** 登录。
登录后顶栏:**关键位监控** | **实盘下单** | **策略交易**`/strategy`| **策略交易记录**`/strategy/records`| **交易记录与复盘** | **统计分析**
---
## 4. 关键位监控(顶栏「关键位监控」→ `/key_monitor`
### 4.1 添加一条关键位
1. **币种**:如 `BTC``BTC/USDT`(会规范成内部符号)。
2. **类型**(必选其一):
| 类型 | 行为摘要 |
|------|----------|
| **箱体突破** | 通过门控且计划 RR 达标 → **自动市价开仓**(需 `LIVE_TRADING_ENABLED=true` 且无其他持仓占位)。结案后本条从列表消失并记入历史。 |
| **收敛突破** | 同上(自动开仓类)。 |
| **关键阻力位** | **不自动开仓**;触发后 **发 1 次微信**,然后本条 **结案进历史**。 |
| **关键支撑位** | 同上(仅提醒)。 |
| **回调触价开仓** | **不挂交易所限价**;标记价回调触达 E 后 **下一轮询市价开仓**RR 门槛同 `KEY_AUTO_MIN_PLANNED_RR`);有效期 **24h** |
| **突破触价开仓** | **不挂交易所限价**;标记价 **穿越 E 立即市价开仓**;先触 SL/TP 侧失效;有效期 **24h** |
3. **方向**:做多 / 做空(触价开仓 / 箱体 / 收敛 / 斐波必选;阻力/支撑不选)。
4. **价位**:箱体/收敛/阻力/支撑填 **上沿 / 下沿**;触价开仓填 **入场 E / 止损 SL / 止盈 TP**
**限制:**
活跃持仓数达到 **`MAX_ACTIVE_POSITIONS`**(默认 1)时,**不允许**再添加「**箱体突破** / **收敛突破**」;仍可添加「**关键阻力位 / 支撑位**」。
**4h EMA55** 与你的方向逆势,页面会 **额外 Flash 提示****不阻挡**提交。
### 4.2 触发后会发生什么(简版)
- **箱体 / 收敛**:门控通过后计算计划 SL/TP 与 RR;不达标则 **微信说明 + `rr_insufficient` 结案**;达标则尝试 **市价开仓**,成功 **`auto_opened`**,失败 **`exchange_failed`**——均 **不重试同一关键位**
- **阻力 / 支撑**:仅 **单次推送****`key_level_alert_only`** 结案。
详细公式、结案字段、与企业微信文案口径见 **`关键位自动下单说明.md`**。
### 4.3 列表与历史
- 当前条目可 **删除**(会按规则记入历史的情形见页面说明)。
- **关键位历史**:已结案记录;可配合导出链接(若有)做备份。
---
## 5. 实盘下单(顶栏「实盘下单」→ `/trade`
用于 **自己点按钮** 开单:
- 持仓上限由 **`MAX_ACTIVE_POSITIONS`** 控制(默认 1,与关键位自动单共用)。
- **人工开仓**时计划盈亏比不得低于 **`MANUAL_MIN_PLANNED_RR`**(默认 1.4:1),否则页面弹窗且后端拒绝。
- 填写币种、方向、杠杆(可选)、止损/止盈(价格或百分比按表单说明)。
- 勾选是否启用 **移动保本** 等行为以 `.env`/页面默认值为准。
平仓通过页面 **平仓**(或等价入口),会从交易所市价处理并更新记录。**删除/误操作可能造成真实盈亏**,请先确认环境与方向。
开仓成功后持仓卡片上会显示 **「来源」**:手工单一般为 **下单监控**;来自关键位自动单的为 **关键位监控**
---
## 6. 企业微信会看到什么
- 关键位:按类型与结案结果推送(RR 不足、下单失败、自动开仓成功、仅阻力支撑提醒等),**每条关键位结案路径原则上一条主推送**(详见 `关键位自动下单说明.md`)。
- 手工开仓、平仓、部分异常也会在规则满足时推送(以代码与配置为准)。
若未配置 **`WECHAT_WEBHOOK`** 或网络失败,可能只是看不到推送,不代表逻辑未执行;要紧操作请以 **交易所端持仓与挂单** 为准核对。
---
## 7. 强烈建议的风险与运维习惯
1. **先用 `LIVE_TRADING_ENABLED=false`** 验证页面、录入、推送,再开小资金开实盘。
2. **API 权限**:仅开所需合约权限;勿泄露密钥;定期轮换。
3. **单进程控盘**:同一账户避免本程序与其他机器人 **重复开仓**
4. **自动备份**:服务器上执行 `bash scripts/install_backup_cron.sh`(每天北京时间 0:00 → `/root/backups`,保留 30 天);升级前也可 `bash scripts/backup_data.sh` 手动跑一次。
5. **升级代码后**:启动时会跑 **数据库迁移**(如新列 `order_monitors.monitor_type`);首次启动关注一下日志或无报错页面。
---
## 8. 常见问题(简要)
| 现象 | 可自查 |
|------|--------|
| 关键位永远不触发 | 5m 门控是否全通过(页面门控摘要)、币种日成交量是否在规则内、`KLINE_TIMEFRAME`。 |
| 有信号但不自动开仓 | `LIVE_TRADING_ENABLED``KEY_AUTO_MIN_PLANNED_RR`、计划 RR、是否已有持仓、API/余额报错(微信或日志)。 |
| 加不了箱体/收敛 | 是否已有活跃持仓;先平仓或改用「阻力/支撑位」仅提醒。 |
| 推送收不到 | `WECHAT_WEBHOOK`、企业微信机器人配额与网络。 |
---
## 9. Binance 版(`crypto_monitor_binance`)差异速查
| 项目 | Gate 本仓库 | Binance 版 |
|------|-------------|------------|
| API 变量 | `GATE_API_KEY``GATE_API_SECRET``GATE_*` | `BINANCE_API_KEY``BINANCE_API_SECRET``BINANCE_*` |
| 实盘开关 | `LIVE_TRADING_ENABLED`(通用) | 同上 |
| 止盈止损挂载路径 | `_gate_place_tp_sl_orders``GATE_TPSL_*` | `_binance_place_tp_sl_orders`U 本位条件单) |
| 资金显示舍入 | 以本仓库为准 | 与 **`FUNDS_DECIMALS`** 等一致 |
| 专门文档 | **`关键位自动下单说明.md`**(各仓库有一份,开头标明交易所) | 同左 |
操作流程(登录、关键位四类、手工单、单仓)**两份程序一致**:换目录、换 `.env` 即可对照使用。
@@ -1,143 +0,0 @@
# 关键位监控说明(自动开仓 + 人工盯盘)
**适用:`crypto_monitor_gate`Gate U 本位永续)**
Binance / OKX 见各自目录下同名文档;共享逻辑在仓库根目录 `key_monitor_lib.py`
本文档与 `.env``check_key_monitors``add_key``_key_hard_checks``_process_key_rs_level_alert` 一致。
---
## 一、监控类型总览
| 录入类型 | 录入时选方向 | 自动市价开仓 | 触发与结案 |
|----------|--------------|--------------|------------|
| **箱体突破** | **必选** 多/空 | **是**(门控 + RR) | 条件满足 → 开仓或 `rr_insufficient` / `exchange_failed`**一次性删除** |
| **收敛突破** | **必选** 多/空 | **是**(同上) | 同上 |
| **关键阻力位** | **不选**`direction=watch` | **否** | 5m 收盘突破上/下沿 → 微信 **3 次**`key_level_alert_done` |
| **关键支撑位** | **不选** | **否** | 同上(与阻力位**相同规则**:填上沿+下沿,程序双向监控) |
| 斐波回调 0.618 / 0.786 | 必选 | 限价挂单逻辑 | 见斐波说明(**不在下文展开**) |
**添加时(所有类型):** 品种须 **日成交量排名前 `KEY_DAILY_VOLUME_RANK_MAX`(默认 30**;上沿 **>** 下沿。
---
## 二、关键阻力位 / 关键支撑位(人工盯盘)
### 2.1 录入
- 填写 **上沿 `upper`****下沿 `lower`**(程序同时监控两侧,**无法预先判定**做多还是做空)。
- 页面 **不显示、不要求** 方向;库中 `direction` 初始为 `watch`**首次突破后** 写入 `long`(向上突破上沿)或 `short`(向下突破下沿)。
### 2.2 触发(极简)
- 周期:**`KLINE_TIMEFRAME`(默认 5m)最近一根已闭合 K** 的 **收盘价**(非影线)。
- **向上突破上沿:** `收盘 > upper` → 推断方向 **多 / 向上**,本次监控任务开始按节奏提醒。
- **向下突破下沿:** `收盘 < lower` → 推断方向 **空 / 向下**,本次任务同样开始提醒。
- **任一侧突破即结束本条监控周期**(不会在突破后再等待另一侧;上沿、下沿谁先满足用谁,同根 K 仅可能满足一侧)。
**不参与:** 量能、二确 K、越过幅度下限、日成交排名(运行时)、计划 RR、自动开仓。
### 2.3 微信提醒次数
| 配置 | 默认 | 含义 |
|------|------|------|
| `KEY_ALERT_MAX_TIMES` | `3` | 突破后最多推送 3 次 |
| `KEY_ALERT_INTERVAL_MINUTES` | `5` | 相邻两次推送至少间隔 5 分钟 |
- 第 1 次:首次检测到突破的当次轮询(若已闭合 5m 满足条件)。
- 第 2、3 次:仅按间隔推送(**不要求**价格仍在箱外)。
- 第 3 次推送后:写入 `key_monitor_history``close_reason=**key_level_alert_done**`,从 `key_monitors` **删除**
### 2.4 与箱体/收敛的区别
| 项目 | 阻力/支撑 | 箱体/收敛 |
|------|-----------|-----------|
| 方向 | 程序推断 | 人工选择 |
| K 线根数 | 1 根闭合 5m | 2 根(突破 K + 确认 K |
| 提醒次数 | 3 次后结案 | 自动单:触发后 1 次业务推送并结案 |
---
## 三、箱体突破 / 收敛突破(自动开仓)
### 3.1 K 线结构(默认索引)
| 角色 | 环境变量 | 默认 | 含义 |
|------|----------|------|------|
| 突破 K | `KEY_CONFIRM_BREAKOUT_BAR` | `-2` | 倒数第 2 根闭合 K |
| 确认 K | `KEY_CONFIRM_BAR` | `-1` | 倒数第 1 根闭合 K |
### 3.2 硬门控(须全部通过)
1. **有效突破(收盘越界)**
- 多:`突破 K 收盘 > upper`
- 空:`突破 K 收盘 < lower`
2. **突破越过幅度(仅下限)**
- 多:`(突破 K 收盘 upper) / upper × 100 > KEY_BREAKOUT_AMP_MIN_PCT`(默认 **0.03%**
- 空:`(lower 突破 K 收盘) / lower × 100 >` 同上
- **无上限**;突破过猛由 **计划 RR** 过滤。
- **不再**使用 K 线实体占开盘价比例;`KEY_BREAKOUT_AMP_MAX_PCT` **已不参与门控**
3. **确认 K 不进箱体**
- 多:确认 K 收盘 **`> upper`**(不得在 `[lower, upper]` 内)
- 空:确认 K 收盘 **`< lower`**
4. **量能:** 突破 K 成交量 > 前 `KEY_VOLUME_MA_BARS`(默认 20)根均量 × `KEY_VOLUME_RATIO_MIN`(默认 1.3
5. **日成交量排名:** 运行时仍须前 `KEY_DAILY_VOLUME_RANK_MAX`(默认 30
6. **计划 RR(最后经济门控):** 按确认 K 收盘 **E** 计算 SL/TP 后,`RR` **严格大于** `KEY_AUTO_MIN_PLANNED_RR`(默认 1.5)才市价开仓
### 3.3 止损 / 止盈(确认 K 收盘为 E)
箱体高 **H = |upper lower|**。止损锚在 **突破 K 极值** 外侧:
| 方向 | 止损(标准/趋势方案) |
|------|------------------------|
| 多 | 突破 K **最低价** × (1 `KEY_STOP_OUTSIDE_BREAKOUT_PCT`%) |
| 空 | 突破 K **最高价** × (1 + `KEY_STOP_OUTSIDE_BREAKOUT_PCT`%) |
止盈方案见下表(与改版前一致):
| 方案 | `sl_tp_mode` | 多:SL / TP | 空:SL / TP |
|------|--------------|-------------|-------------|
| 标准突破 | `standard` | 突破 K 低外侧% / **E+H** | 突破 K 高外侧% / **EH** |
| 箱体 1R·止盈 1.5H | `box_1p5` | **EH** / **E+1.5×H** | **E+H** / **E1.5×H** |
| 趋势单·自填止盈 | `trend_manual` | 突破 K 低 × (1`KEY_TREND_STOP_OUTSIDE_PCT`%) / **录入止盈** | 突破 K 高外侧% / **录入止盈** |
### 3.4 一次性结案(`close_reason`
| `close_reason` | 含义 |
|----------------|------|
| `box_opposite_break` | 标记价先突破反向边界(多:≤下沿;空:≥上沿) |
| `rr_insufficient` | 门控通过但 RR 不达标或 SL/TP 几何无效 |
| `exchange_failed` | RR 达标但实盘/交易所等原因未开仓 |
| `auto_opened` | RR 达标且市价开仓成功 |
| `key_level_alert_done` | 阻力/支撑 **3 次提醒** 完成 |
---
## 四、环境与参数(`.env` 摘要)
| 变量 | 箱体/收敛 | 阻力/支撑 |
|------|-----------|-----------|
| `KEY_BREAKOUT_AMP_MIN_PCT` | 突破越过下限(默认 0.03) | 不用 |
| `KEY_BREAKOUT_AMP_MAX_PCT` | **已废弃门控** | 不用 |
| `KEY_VOLUME_*` / `KEY_CONFIRM_*` | 用 | 不用 |
| `KEY_AUTO_MIN_PLANNED_RR` | 用 | 不用 |
| `KEY_ALERT_MAX_TIMES` / `KEY_ALERT_INTERVAL_MINUTES` | 不用 | 用(默认 3 次 / 5 分钟) |
| `KEY_DAILY_VOLUME_RANK_MAX` | 添加时 + 运行时 | **仅添加时** |
---
## 五、相关代码
| 说明 | 位置 |
|------|------|
| 共享判定 | `key_monitor_lib.py` |
| 主循环 | `check_key_monitors` |
| 自动门控 | `_key_hard_checks` |
| 阻力/支撑提醒 | `_process_key_rs_level_alert` |
| 录入 | `add_key` |
| 开仓 | `_market_open_for_key_monitor` |
-148
View File
@@ -1,148 +0,0 @@
# 界面与风控更新说明(Gate 实例)
## 顶栏导航(4 项)
| 顺序 | 名称 | 路由 | 说明 |
|------|------|------|------|
| 1 | 关键位监控 | `/key_monitor` | 关键位添加、实时门控、历史 |
| 2 | 实盘下单 | `/trade` | 人工开仓、划转、实时持仓(**默认首页** `/``/trade` |
| 3 | 交易记录与复盘 | `/records` | 交易记录、复盘表单、AI 历史(受顶栏 UTC 时间窗筛选) |
| 4 | 统计分析 | `/stats` | 按北京时间交易日切日 + 分品类统计块 |
## 关键位监控页
- 标题去掉「5m」;规则条从 `.env` 读取(周期、确认K、量能、自动开仓盈亏比、日成交量排名)。
- 左列:活跃关键位,**pos-card** 样式展示现价/距上沿/距下沿/门控。
- 右列:关键位历史(失效/结案),与左列等高滚动;**受顶栏 UTC 列表时间窗筛选**(默认 UTC 当日)。
- 监控类型新增:**斐波回调0.618**、**斐波回调0.786**(与 Binance 主站同一套规则,计算逻辑见仓库根目录 `fib_key_monitor_lib.py`)。
### 斐波关键位监控(方案 A:交易所限价)
| 项 | 说明 |
|----|------|
| 同币互斥 | 每个币种只能有一条斐波监控(0.618 与 0.786 不可并存) |
| 上下沿 | 上沿 **H**、下沿 **L**(须 H > L |
| 挂单价 E | **做多** `E = H ratio × (H L)`(自 H 向下回撤);**做空** `E = L + ratio × (H L)`(自 L 向上反弹) |
| 做多 | 限价 @ E,止损 L,止盈 H |
| 做空 | 限价 @ E,止损 H,止盈 L |
| 添加后 | **立即**在 Gate 挂限价单;卡片显示 **挂E**、限价单 ID |
| 失效 | 以**标记价**判断:做多且标记价 ≥ H、做空且标记价 ≤ L,且限价**未成交** → 撤销该限价单并结案(不写历史开仓) |
| 成交后 | 按仓位挂交易所 TP/SL → 写入 **实盘下单监控**`monitor_type=关键位监控``key_signal_type=斐波回调0.618/0.786`)→ 从关键位列表移除 |
| 撤单 | 仅撤本条斐波的 `fib_limit_order_id`**不会** `cancel_all`,避免误伤其他委托 |
| 盈亏比 | 计划 RR 须 > `KEY_AUTO_MIN_PLANNED_RR`(与箱体/收敛一致);0.618 理论约 1.6:10.786 约 3.7:1 |
| 日成交量 | 与箱体/收敛相同,须在前 `KEY_DAILY_VOLUME_RANK_MAX` 名内方可添加 |
后台轮询:`check_fib_key_monitors()`(标记价失效 / 成交检测);箱体/收敛仍走 `check_key_monitors()`,互不干扰。
手动删除关键位时,若斐波限价尚未成交,会先撤交易所限价再删库记录。
### 箱体 / 收敛自动开仓(来源标注)
- 自动开仓写入 `order_monitors.key_signal_type``箱体突破``收敛突破`
- 持仓卡片、交易记录列表会显示「来源 · 信号类型」。
## 列表时间窗(UTC,全站顶栏)
共用模块:仓库根目录 `history_window_lib.py`Gate / Binance 主站一致)。
| 项 | 说明 |
|----|------|
| 默认 | **UTC 当日**`win_preset=utc_today`,从 UTC 0:00 至当前时刻) |
| 可选 | 近 24 小时、近 7 天、自定义起止(UTC,`datetime-local` |
| 作用范围 | 关键位历史、交易记录列表、复盘记录 API、AI 历史 API、导出「交易记录」「关键位历史」 |
| 与统计的关系 | **仅影响列表/导出****统计分析页仍按北京时间 `TRADING_DAY_RESET_HOUR`(默认 8:00)切交易日** |
| 库内时间 | DB 存北京时间字符串;后端用 `utc_window_to_bj_sql_strings()` 换算后再 SQL 比较 |
| 切换方式 | 顶栏「列表筛选(UTC)」→ 选预设 → **应用**(保留当前路由,如 `/records?win_preset=…` |
查询参数示例:
- `?win_preset=utc_today`
- `?win_preset=utc_last24h` / `utc_last7d`
- `?win_preset=custom&from_utc=2026-05-18 00:00:00&to_utc=2026-05-19 12:00:00`
## 交易记录与复盘
- 平仓记录可同步交易所已实现盈亏(Gate 仓位历史等);列表盈亏列优先显示交易所数据,标注 **所** / **估**
- 记录页提供 **立即同步**`POST /api/sync_exchange_pnl`),用于补全或刷新 `exchange_realized_pnl` 等字段。
- 未做人工复盘时,展示以交易所盈亏为准(有同步数据时)。
- **列表默认只显示当前 UTC 时间窗内**的记录(见上节);导出 CSV 同步该时间窗。
- 表头 **「止损(开仓)」**:展示开仓快照 `initial_stop_loss`(无则回退 `stop_loss`);核对/复盘仍可用有效止损字段。
- 平仓写入 `trade_records` 时:`stop_loss``initial_stop_loss` 均写入**开仓时止损快照**`key_signal_type` 保留箱体/收敛/斐波来源(`fib_key_monitor_lib.key_signal_type_for_trade_record`)。
- **开仓类型**`entry_reason`):机器单平仓入库时,若未手填,按 `key_signal_type` 自动映射(见下表);列表/导出「开仓类型」列 = 复盘核对值优先,否则入库值,否则按信号映射。
| `key_signal_type` | 自动写入的 `entry_reason` |
|-------------------|---------------------------|
| 箱体突破 | 关键位箱体突破 |
| 收敛突破 | 关键位收敛突破 |
| 斐波回调0.618 | 关键位斐波0.618 |
| 斐波回调0.786 | 关键位斐波0.786 |
- 复盘表单 **开仓类型** 下拉新增上述四条固定文案(与趋势/波段类并列)。
- 复盘 **离场触发** 新增 **「止盈」**;从交易记录「填入复盘」时,若结果为「止盈/保本止盈/移动止盈/止损/手动平仓」会自动选中对应触发项,并按 `key_signal_type` 预填开仓类型。
- 勾选「保存时自动生成多周期 K 线图」时:以 **平仓时间** 为锚点,各周期向前约 `ORDER_CHART_LIMIT`(默认 100)根 K 线(`_fetch_ohlcv_ending_at`),不再固定拉「最近 100 根」。
- `/api/journals``/api/reviews` 支持同一时间窗 query,与列表一致。
### 导出(交易记录 v3
- 文件名:`trade_records_v3_YYYYMMDD.csv`
- 相对 v2 增加:`key_signal_type``initial_stop_loss`(及开仓快照列)、`planned_rr``actual_rr``risk_amount`、交易所盈亏与时间字段等;末列「开仓类型」为有效展示文案。
- 「关键位历史」导出同样受 UTC 时间窗限制。
## 实盘下单页
- 左列:实盘下单监控(表单、划转、规则)。
- 右列:实时持仓(独立模块)。
- **人工开仓门控**:计划盈亏比 &lt; `MANUAL_MIN_PLANNED_RR`(默认 **1.4**)时前端弹窗 + 后端拒绝。
- **移动保本**(勾选启用):监控轮询达到触发 RR 后,止损阶梯上移时**同步交易所**——调用与页面「挂止盈止损」相同的 **先撤后挂**`replace_active_monitor_tpsl_on_exchange`:撤该合约全部 TP/SL 条件单 → 按新止损 + 原止盈重挂)。仅交易所成功后才写库;失败发企业微信告警,本地止损不变。未配置实盘 API 时仍只更新本地(与旧行为一致)。
## 统计分析页(`/stats`
| 项 | 说明 |
|----|------|
| 切日 | **北京时间**;交易日边界 = 每日 `TRADING_DAY_RESET_HOUR:00``.env` 默认 **8** |
| 品类下拉 | 页顶 **「统计品类」** 下拉切换(默认「全部交易」):全部交易、下单监控、关键位箱体突破、关键位收敛结构、关键位斐波0.618、关键位斐波0.786;一次只显示所选品类的日/周/月 |
| URL | 切换后写入 `stats_segment=`(如 `all``manual``key_box``key_conv``key_fib618``key_fib786`),刷新 `/stats` 可保持选项 |
| 每块指标 | 日 / 周 / 月:开单次数、平仓笔数、胜率、净盈亏、回撤、连续亏损等(与原口径一致) |
| 开单次数 | 人工块:`monitor_type=下单监控` 且无 `key_signal_type`;关键位块:按 `order_monitors.key_signal_type` 计数 |
| 不受 UTC 窗影响 | 统计始终基于库内全部已平仓记录,按北京交易日归类,**不**随顶栏 UTC 列表窗切换 |
## 持仓与计仓
- `MAX_ACTIVE_POSITIONS` 默认 **1**(可在 `.env` 调大)。
- 关键位自动开仓:在已有持仓时,若 `KEY_SIZING_USE_ZERO_POSITION_SNAPSHOT=true`,按**首笔开仓前**交易账户资金快照计仓(`trading_sessions.key_sizing_capital_snapshot`)。
## 配置
详见 `.env.example` 中「关键位门控」「交易执行 / 人工风控」注释段。Gate 专用项(`GATE_*`、止盈止损触发等)保持原有段落不变。
## 自动备份(服务器)
- 脚本:`scripts/backup_data.sh``crypto.db` + `static/images`
- 定时:`scripts/install_backup_cron.sh` → 每天 **北京时间 0:00**,目录 **`/root/backups/<实例名>/YYYY-MM-DD/`**,保留 **30**
- 详见 `部署文档.md` 第 5.4 节(自动备份)
## 数据库(启动时自动迁移)
`key_monitors` 新增斐波字段(示例):`fib_limit_order_id``fib_entry_price``fib_stop_loss``fib_take_profit``fib_order_amount``fib_margin_capital``fib_leverage`
`trade_records` / `order_monitors` 新增或沿用:`key_signal_type``exchange_realized_pnl``exchange_opened_at``exchange_closed_at``exchange_sync_key``entry_reason``reviewed_entry_reason``initial_stop_loss`
**历史数据**:本次**不做**旧记录的批量回填(`entry_reason` / `initial_stop_loss` / `key_signal_type` 等);仅**新产生**的平仓与复盘按新逻辑写入。旧行展示可回退已有字段。
## 涉及文件(便于排查)
| 路径 | 说明 |
|------|------|
| `history_window_lib.py` | UTC 时间窗解析与转北京时间 SQL 字符串 |
| `fib_key_monitor_lib.py` | 斐波计算、`KEY_ENTRY_REASON_BY_SIGNAL``entry_reason_from_key_signal` |
| `crypto_monitor_gate/app.py` | 列表筛选、统计分块、导出 v3、复盘 K 线锚点、入库逻辑 |
| `crypto_monitor_gate/templates/index.html` | 顶栏时间窗、统计分块 UI、止损(开仓)列、复盘预填 |
## 升级步骤
1. `git pull` 后对比 `.env.example`,把新增变量合并进本地 `.env`
2. 在 VPS 上为 Binance / Gate / Gate Bot **各执行一次** `bash scripts/install_backup_cron.sh`(若尚未安装)。
3. 重启 Gate 实例服务(如 `pm2 restart crypto_gate`);首次启动会自动 `ALTER TABLE` 缺列(斐波、交易所盈亏、`entry_reason` 等)。
4. 浏览器强刷(Ctrl+F5)避免旧版 `index.html` 缓存。
5. 打开任意页确认顶栏出现 **「列表筛选(UTC)」**`/stats` 可见分品类统计与「北京 8:00 切日」说明。
6. 建议在测试币上先添加一条斐波监控,确认:限价已挂出、标记价失效会撤单、成交后出现持仓监控且 TP/SL 已挂上;平仓后交易记录止损(开仓)与开仓类型是否正确。
@@ -1,129 +0,0 @@
# 趋势回调策略(机器人)说明
本文描述 **「趋势回调」** 自动交易计划的业务规则与实现口径。
**四所主站**Binance / Gate / OKX / 本目录 `crypto_monitor_gate_bot`)均在顶栏 **策略交易 → `/strategy`** 左栏提供同一套逻辑(共用 `strategy_trend_register.py`);本目录侧重 **Gate 子账户 / 机器人** 实例,可与主 Gate 账户隔离部署。
**检阅备忘**(中控平仓、交易记录、补仓展示、漏记补录):[docs/trend-hub-close-and-trade-records.md](../docs/trend-hub-close-and-trade-records.md)
---
## 1. 适用场景
- 单独用于跑策略的 **Gate.io USDT 永续** 子账户(建议与主资金隔离);其它交易所实例同理,使用各自 API 与 `crypto.db`
- 你已明确:**方向、止损价、补仓区间边界价、止盈价、杠杆**,并接受程序按风险预算拆分 **首仓 50% + 多档补仓 50%**
---
## 2. 名词与参数
| 名称 | 含义 |
|------|------|
| **合约 USDT 可用余额** | **生成预览**时通过 API 读取的 **swap 账户 USDT `free`** 快照;**确认执行**时再次读取并与快照比对偏差。 |
| **风险比例** | 默认 **5%**:指「若整笔计划在 **补仓区间远侧边界**(做多=上沿、做空=下沿)这一侧的最坏价格结构下触及止损」,目标亏损上限约为 **可用余额快照 × 风险比例**(实现上用 `calc_risk_fraction``prepare_order_amount` 反推总张数,受交易所最小张数与精度约束)。 |
| **止损价** | 用户填写;开仓后挂 **交易所仓位类止损触发单**(全平)。 |
| **补仓区间边界**(库字段 `add_upper`) | 用户填写;**仅在该价位与止损价构成的区间内** 才允许程序触发剩余 50% 的市价补仓。**界面文案**:做多显示「补仓上沿」,做空显示「补仓下沿」。校验:做多 `止损 < 边界价`;做空 `止损 > 边界价`。 |
| **止盈价** | 用户填写的 **固定价格**;**不由交易所条件止盈单触发**,由应用后台 **按标记价/行情价轮询**,达到后 **市价全平**。 |
| **杠杆** | 计划内固定写入;用于 `set_leverage` 与名义换算。 |
| **补仓档位数** | 默认 **5** 档(环境变量 `TREND_PULLBACK_DCA_LEGS` 可调);程序在满足最小张数前提下可能 **自动减少档数**。 |
---
## 3. 执行流程(时间顺序)
### 3.0 列表时间窗(交易记录 / 计划历史)
- **交易记录**、**计划历史**(含预览快照)列表与 **交易记录 CSV 导出** 支持 **UTC** 时间筛选(默认 UTC 当日;可选近 24h、近 7d、自定义起止)。
- 查询参数:`win_preset``utc_today` / `utc_last24h` / `utc_last7d` / `custom`)、自定义时另传 `from_utc``to_utc`
- **统计分析**页仍按北京时间 `TRADING_DAY_RESET_HOUR` 切日,不受列表窗影响。
### 3.1 预览阶段(不下单)
1. **风控**:与「机器人下单监控」**互斥**——存在活跃机器人持仓或运行中趋势计划时,不可生成预览。
2. **读取可用余额快照** `get_available_trading_usdt()`,失败则拒绝。
3. **计算**(写入表 `trend_pullback_previews`,并跳转带 `preview_id`):
- 在 **补仓区间边界 ↔ 止损** 区间内生成 `N` 个补仓触发价(做多从上沿向止损、做空从下沿向止损);
- 将 **剩余 50% 计划张数** 拆成 `N` 份写入 `leg_amounts_json`
4. **预览有效期**:默认 **120 秒**`TREND_PULLBACK_PREVIEW_TTL_SECONDS`),超时须重新点「生成预览」。
### 3.2 确认执行(实盘)
5. 再次校验:预览未过期;**当前可用余额**与预览快照相对偏差 ≤ `TREND_PREVIEW_MAX_BALANCE_DRIFT_PCT`(默认 **5%**),否则拒绝执行并要求重新预览。
6. **首仓****立即市价** 开立 **总计划张数 × 50%**(不附带交易所止盈单)。
7. **止损**:撤销旧条件单后,挂 **仅止损** 的仓位触发单;之后每次补仓成交会 **刷新** 止损挂单。
7b. **保本移交下单监控**(可选):首仓完成且交易所有持仓后,可点击「保本移交下单监控」——将止损移至 **持仓均价 ± 偏移%**(默认 **+0.3%** 多 / **0.3%** 空),仅当新止损 **优于** 当前止损时生效;**本次趋势计划随即结束**,持仓写入 **下单监控**(备注 **趋势回调计划**),交易所在 **同一时刻挂保本止损 + 计划止盈**;后续无论中控平仓或交易所手动平仓,均经下单监控轮询 **`reconcile_external_closes` / `check_order_monitors`** 写入 **交易记录**(含 `trend_plan_id`、开仓类型「趋势回调」),供人工核对。
8. **补仓**:当价格 **穿越** 下一档触发价(做多为自上向下穿越,做空为自下向上穿越)时,按该档张数 **市价加仓**;直至 `N` 档执行完毕或计划结束。
9. **止盈监控**:后台线程若发现价格触及止盈,则 **市价全平**
10. **止损触发**:若仓位被交易所止损打光,本地检测到 **持仓为 0** 后记账为 **止损** 并结束计划。
11. **计划结束**:任一结束路径(止盈 / 止损 / 用户手动结束)均会 **撤单**(条件单 + 普通挂单,尽力而为)。
### 3.3 取消预览
用户可「取消预览」删除 `trend_pullback_previews` 中对应记录;过期记录会在新预览或页面加载时清理。
### 3.4 界面:计划历史与运行中浮动盈亏
- **计划历史(页顶卡片)**
- 仅展示 **`trend_pullback_plans` 中已结束的计划**`status != 'active'`,如止盈结束、止损结束、手动结束)。
- **不包含**仅存在于 `trend_pullback_previews`、从未「确认执行」的预览。
- 每行提供 **删除**:删除该计划行,并删除 `trade_records`**`trend_plan_id` 与之相同** 且类型为「趋势回调」的记录(用于与计划一一对应的新数据;历史旧行若无 `trend_plan_id` 则不会随删)。
- **运行中的计划(交易执行页)**
- 在计划摘要下方展示 **浮盈亏(交易所)**:来自 Gate 当前持仓接口的 **未实现盈亏**(及标记价,若可得);与本地按均价估算可能略有差异,以交易所为准便于对照。
- **补仓边界**按方向显示「补仓上沿」或「补仓下沿」(数值仍为 `add_upper` 字段)。
- **手动保本**:表单可改偏移 %(默认见 `TREND_PULLBACK_MANUAL_BREAKEVEN_OFFSET_PCT`);成功后显示「已保本」时间与原止损(若与当前不同)。
### 3.5 交易记录与交易所「已实现盈亏」对齐
- 平仓时仍会写入一条 **`trade_records`**`monitor_type=趋势回调`),其中的 **`pnl_amount` 等为本地估算**`calc_pnl`,不含手续费、资金费等完整账单口径)。
- 打开 **「交易执行」或「交易记录」** 页面时,若已配置 **`GATE_API_KEY` / `GATE_API_SECRET`**(不要求 `LIVE_TRADING_ENABLED=true`,只读即可),应用会按节流策略(同进程约 **25 秒**内最多一次)调用 Gate **`fetch_positions_history`(平仓历史)**,为尚未写入 `exchange_sync_key` 的趋势回调记录 **匹配一条平仓记录**,并回填:
- **`exchange_realized_pnl`**:交易所口径已实现盈亏(与 App「历史仓位」更接近);
- **`exchange_opened_at` / `exchange_closed_at`**:换算为应用时区(默认北京)下的开、平时间字符串。
- **交易记录表**展示列「开仓(展示) / 平仓(展示) / 盈亏U(展示)」:对「趋势回调」行,若已同步则优先显示交易所字段(界面小字 **「所」**);未同步前仍显示本地复盘字段(小字 **「估」**)。
- 匹配规则概要:同品种、同方向、平仓时间与本地 `closed_at` 接近,并结合 **`trend_plan_id`** 对应计划的 `opened_at` 收窄时间窗;极端情况下若短时间多笔同向同品种,仍存在错配可能,可对照 `exchange_sync_key` 与交易所记录。
---
## 4. 与「机器人下单监控」的差异
| 项目 | 机器人下单监控 | 趋势回调 |
|------|------------------|----------|
| 开仓 | 单次市价 + 条件止盈+止损 | 首仓 50% 市价 + 多档补仓 + **仅止损在交易所** |
| 止盈 | 条件单 + 本地监控 | **仅本地监控市价止盈** |
| 仓位基数 | 以损定仓(表单/会话基数) | **可用余额快照 × 风险比例** 推导 |
| 移动保本 | 支持(按 R 自动上移) | **保本移交**(结束计划→下单监控;交易所 TP+SL;**无**自动 R 保本) |
---
## 5. 风险声明(必读)
- 市价单存在 **滑点**;极端行情下实际亏损可能 **大于** 理论 5%。
- 补仓触发依赖应用 **轮询间隔**`MONITOR_POLL_SECONDS`),非毫秒级高频。
- 交易所 **最小张数 / 精度** 可能导致计划张数被截断,实际风险略低于或偏离纸面计算。
- 请使用 **单独 API Key / 子账户**,并先在 `LIVE_TRADING_ENABLED=false` 环境验证流程(若需沙盒请自行对接测试网,本仓库默认实盘接口)。
---
## 6. 相关环境变量
| 变量 | 说明 | 默认 |
|------|------|------|
| `TREND_PULLBACK_MANUAL_BREAKEVEN_OFFSET_PCT` | 手动保本默认偏移(相对持仓均价,%) | `0.3` |
| `TREND_PULLBACK_DCA_LEGS` | 剩余 50% 拆档数量上限 | `5` |
| `TREND_PULLBACK_PREVIEW_TTL_SECONDS` | 预览有效时间(秒) | `120` |
| `TREND_PREVIEW_MAX_BALANCE_DRIFT_PCT` | 确认执行时允许「当前可用 / 预览快照」最大相对偏差(%) | `5` |
| `MONITOR_POLL_SECONDS` | 监控轮询间隔(秒) | `3` |
| `LIVE_TRADING_ENABLED` | 是否允许真实下单 | `false` |
| `FULL_MARGIN_BUFFER_RATIO` | 计划保证金相对可用余额上限比例 | `0.98` |
| `APP_TIMEZONE` | 应用墙钟与「北京日期」同步起点时区(如 `Asia/Shanghai` | `Asia/Shanghai` |
| `EXCHANGE_POSITION_SYNC_FROM_BJ` | 拉取 Gate **平仓历史** 的最早日期(`YYYY-MM-DD`,按 `APP_TIMEZONE` 当日 **00:00** 起算)。**留空**则从近 **90 天** 起拉取 | 空 |
| `EXCHANGE_POSITION_HISTORY_LIMIT` | 单次拉取平仓历史条数上限(50–1000) | `200` |
---
## 7. 数据库
- **`trend_pullback_previews`**:未执行的预览行(含 `expires_at_ms`),执行成功或取消后删除;过期可被清理。
- **`trend_pullback_plans`**:趋势回调计划。执行后写入一行,`status='active'` 表示运行中;止盈 / 止损 / 手动结束后变为 **`stopped_tp` / `stopped_sl` / `stopped_manual`** 等非 `active` 状态,并出现在页顶 **计划历史**。字段含快照可用余额、计划保证金、总张数、首仓张数、补仓 JSON、网格价 JSON、已补仓档数、均价、`opened_at``message`(结束说明)等;**`add_upper`** 存补仓区间远侧边界价(做多=上沿、做空=下沿)。
- **`trade_records`**`monitor_type=趋势回调`):每次计划结束插入一行;含本地估算盈亏等。新写入行带 **`trend_plan_id`** 指向 `trend_pullback_plans.id`。另含 **`exchange_realized_pnl``exchange_opened_at``exchange_closed_at``exchange_sync_key`**,由页面触发的交易所平仓历史同步填充(见 3.5)。
**CSV 导出**:交易记录导出为 **v3**,包含上述交易所对齐字段及 `trend_plan_id`
-339
View File
@@ -1,339 +0,0 @@
# `crypto_monitor_gate_bot` 部署指南:SSH SOCKS + Gate.io + PM2Ubuntu
Ubuntu 环境总览见 **[docs/ubuntu-server.md](../docs/ubuntu-server.md)**。
本文面向:**在本机运行本项目**,但 **直连 Gate.io API 不稳定或被重置** 的场景。思路是:
- 本机用 `ssh -D` 做动态转发,把 **SOCKS5 出口**放到能正常访问 Gate 的机器(常见为一台境外 VPS)
- 项目在 `.env` 中设置 **`GATE_SOCKS_PROXY=socks5h://127.0.0.1:1080`**(或你实际端口),`ccxt` 经 SOCKS 访问交易所
- **SSH 隧道**:用 `ssh -D` 在本机常驻(可用 **tmux****autossh** 保持连接),**不要** 把 `ssh` 交给 PM2
- 使用 **PM2** 仅托管 **Flask 应用**;仓库根目录 **`ecosystem.config.cjs`** 只定义 `crypto-monitor-gate`
> 安全提醒:不要把 `.env`、私钥 `.pem`、Gate API Key 提交到 Git;下文只用占位符。
---
## 0. 你需要准备的东西
- 一台 **Ubuntu**(或同类 Linux)运行项目的机器(下文称「本机」)
- 一台可 SSH 登录、且 **能正常访问 Gate.io API** 的 VPS(示例:`HostName` 填你的服务器 IP,用户如 `root`
- SSH:**私钥登录**(推荐,便于隧道脚本无人值守)
- 本机已安装:`python3``python3-venv``pip``curl``ssh``git`(可选)、`node` + `npm`(安装 PM2
---
## 1. 获取代码与目录
将包含 `app.py` 的项目放到固定目录,例如:
```bash
mkdir -p /opt/crypto_monitor
cd /opt/crypto_monitor
git clone https://git.bz121.com/dekun/crypto_monitor.git
cd crypto_monitor/crypto_monitor_gate_bot
```
下文用 **`/opt/crypto_monitor/crypto_monitor_gate_bot`** 仅为示例,请换成你的实际绝对路径。
拉取代码后,若目录下尚无 `.env`
```bash
cp -n .env.example .env
```
---
## 2. 配置 SSH 私钥与 `~/.ssh/config`
```bash
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# 私钥示例:~/.ssh/vps1.pem
chmod 600 ~/.ssh/vps1.pem
```
编辑 `~/.ssh/config`(示例别名 **`gate-vps`**,与你手工启动 `ssh -D ... gate-vps` 一致即可):
```sshconfig
Host gate-vps
HostName 你的_VPS_IP
User root
IdentityFile ~/.ssh/vps1.pem
IdentitiesOnly yes
ServerAliveInterval 30
ServerAliveCountMax 3
ExitOnForwardFailure yes
BatchMode yes
```
测试:
```bash
ssh gate-vps true
```
> 若尚未完全改为密钥登录,可暂时注释 `BatchMode yes`,调试完成后再打开。
---
## 3. 手工验证:SSH SOCKS + Gate API
### 3.1 本地 SOCKS(示例端口 1080
```bash
ssh -N -D 127.0.0.1:1080 gate-vps
```
保持运行,另开终端继续。
### 3.2 验证经 SOCKS 可访问 Gate
```bash
curl -4 -sS --max-time 15 --proxy socks5h://127.0.0.1:1080 https://api.gateio.ws/api/v4/spot/time
```
应返回 JSON(含服务器时间字段)。若此处失败,**不要先启动应用**:先修隧道或 VPS 出站。
---
## 4. Python 虚拟环境
```bash
cd /opt/crypto_monitor/crypto_monitor_gate_bot
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -U pip
pip install flask requests ccxt werkzeug PySocks Pillow
```
走 SOCKS 时 **必须** 安装 **`PySocks`**,否则易出现代理相关报错。
可选:
```bash
export PYTHONDONTWRITEBYTECODE=1
```
---
## 5. 配置环境变量(`.env.example``.env`
| 文件 | 是否进 Git | 说明 |
|------|------------|------|
| **`.env.example`** | ✅ 是 | 变量模板与注释,可随 `git pull` 更新 |
| **`.env`** | ❌ 否 | 本机真实配置;`app.py` **只读此文件** |
### 5.1 首次配置
```bash
cd /opt/crypto_monitor/crypto_monitor_gate_bot
cp -n .env.example .env
nano .env
```
### 5.2 备份与 `git pull`
- **`.env` 不在 Git 中**`git pull` **不会**覆盖本地 `.env`
- 远端若更新 **`.env.example`**,pull 后请**手动**把新增变量补进你的 `.env`
- **升级前备份**`cp .env .env.backup.$(date +%Y%m%d)`;恢复:`cp .env.backup.YYYYMMDD .env`
- **换机**`scp` 复制 `.env`,或新机 `cp .env.example .env` 后重填。
### 5.3 AI 复盘与模型(可选)
共用根目录 **`ai_client.py`**`PYTHONPATH=..`)。`.env` 默认 **`AI_PROVIDER=openai`** + `OPENAI_API_BASE` / `OPENAI_API_KEY` / `OPENAI_MODEL`;或 **`ollama`** + `OLLAMA_API` / `AI_MODEL`。详见 **[AI复盘与模型配置说明.md](../AI复盘与模型配置说明.md)**。
### 5.4 自动备份(数据库 + 复盘图片)
每天 **北京时间 0:00** 备份到 **`/root/backups`**,保留 **30 天**`crypto.db` + `static/images`)。
```bash
cd /opt/crypto_monitor/crypto_monitor_gate_bot
chmod +x scripts/backup_data.sh scripts/install_backup_cron.sh
bash scripts/install_backup_cron.sh
bash scripts/backup_data.sh # 试跑
```
备份目录:`/root/backups/crypto_monitor_gate_bot/YYYY-MM-DD/`。与 Binance / Gate 实例规则相同,详见 `crypto_monitor_binance/部署文档.md` 第 5.4 节(恢复步骤、可选 `.env` 变量)。
若服务器同时跑 **binance、gate、gate_bot** 三个实例,请在**各自项目目录**各执行一次 `install_backup_cron.sh`
### 5.4 必填项检查(Gate + 代理)
与交易所相关的变量必须是 **Gate** 前缀(**不要**再写 OKX 变量,否则代理不会生效、密钥也不会被识别)。至少确认:
```env
APP_HOST=127.0.0.1
APP_PORT=5000
# 实盘(按需)
LIVE_TRADING_ENABLED=false
GATE_API_KEY=你的_Key
GATE_API_SECRET=你的_Secret
# 经本机 SSH 动态转发访问 Gate(端口与隧道一致)
GATE_SOCKS_PROXY=socks5h://127.0.0.1:1080
# 若不用 SOCKS,可改用 HTTP 代理(一般二选一)
# GATE_HTTP_PROXY=http://127.0.0.1:7890
# GATE_HTTPS_PROXY=http://127.0.0.1:7890
```
说明:**推荐 `socks5h://`**,由 SOCKS 端解析域名,与 `curl --proxy socks5h://...` 行为一致。
### 5.4 趋势回调策略(可选)
若使用「交易执行」页的 **趋势回调** 计划:
- 详细规则见项目根目录 **`趋势回调策略说明.md`**。
- **两阶段**:先「生成预览」(默认 **120 秒**内有效),再「确认执行」;执行时若可用余额与预览快照偏差超过 **5%** 会拒绝(可调 `.env`)。
- 补仓档位数默认 **5**,预览有效期与余额偏差阈值可在 `.env` 覆盖:
```env
TREND_PULLBACK_DCA_LEGS=5
TREND_PULLBACK_PREVIEW_TTL_SECONDS=120
TREND_PREVIEW_MAX_BALANCE_DRIFT_PCT=5
```
- **生成预览**与**确认执行**时都会读取 **Gate 永续账户 USDT 可用余额**;请尽量使用 **单独子账户** 承载策略资金。
**界面与对账(与策略说明 3.4–3.5 节一致)**
- 页顶 **计划历史**:仅 **已结束** 的趋势计划(不含未执行预览);可 **删除** 计划行,并删除 `trend_plan_id` 关联的「趋势回调」`trade_records`(新数据;旧行无 `trend_plan_id` 不级联)。
- **运行中计划**展示交易所 **未实现盈亏**(浮盈亏)。
- **交易记录**:趋势单在配置 API Key 后,打开「交易执行 / 交易记录」页会按节流(约 **25 秒**内同进程最多一次)拉取 Gate **平仓历史**,回填 **`exchange_realized_pnl`** 等;列表展示优先用交易所口径(见策略说明)。
**与交易所对齐的可选环境变量**
```env
# 平仓历史同步起点:北京日期 YYYY-MM-DD 的 0 点(与 APP_TIMEZONE 一致);留空则从近 90 天拉取
# EXCHANGE_POSITION_SYNC_FROM_BJ=2026-05-14
# EXCHANGE_POSITION_HISTORY_LIMIT=200
```
说明:同步 **只读** 交易所接口,**不要求** `LIVE_TRADING_ENABLED=true`;无 Key 时不拉取,界面仍可用(浮盈亏可能为「—」、交易记录仍为本地「估」)。
**交易记录 CSV**:导出为 **v3**,含 `trend_plan_id` 与交易所对齐列(详见策略说明数据库一节)。
---
## 6. 手工启动 Flask(验证)
1. SOCKS 已监听 `127.0.0.1:1080`
2. 已 `source .venv/bin/activate`
3. `.env` 已含 `GATE_SOCKS_PROXY`
```bash
cd /opt/crypto_monitor/crypto_monitor_gate_bot
source .venv/bin/activate
python app.py
```
浏览器访问:`http://127.0.0.1:5000`(或你在 `.env` 中的端口)。
---
## 7. 安装 PM2
```bash
sudo npm i -g pm2
pm2 -v
```
---
## 8. PM2:使用仓库内 `ecosystem.config.cjs`(推荐)
在项目根目录:
```bash
cd /opt/crypto_monitor/crypto_monitor_gate_bot
pm2 start ecosystem.config.cjs
pm2 status
pm2 logs --lines 200
```
默认只启动 **`crypto-monitor-gate`**`.venv/bin/python app.py`)。
### 本机已可直连 Gate、不需要隧道时
`.env` 里应 **去掉或留空** `GATE_SOCKS_PROXY`(除非仍要走别的代理),再 `pm2 start ecosystem.config.cjs`
### 开机自启
```bash
pm2 save
pm2 startup
# 按屏幕提示执行一条 sudo 命令
```
---
## 9. 等价手工命令(不使用 ecosystem 文件时)
### 9.1 SSH SOCKS(自行后台常驻,不推荐用 PM2)
示例(前台调试;生产请用 **PM2**,见本文与 [docs/ubuntu-server.md](../docs/ubuntu-server.md)):
```bash
ssh -N -D 127.0.0.1:1080 gate-vps \
-o ServerAliveInterval=30 -o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes
```
### 9.2 Flask
```bash
cd /opt/crypto_monitor/crypto_monitor_gate_bot
pm2 start /opt/crypto_monitor/crypto_monitor_gate_bot/.venv/bin/python --name crypto-monitor-gate -- \
/opt/crypto_monitor/crypto_monitor_gate_bot/app.py
```
---
## 10. 交易所「连接不上」排查清单
1. **`.env` 是否为 Gate 变量**:必须是 `GATE_SOCKS_PROXY` / `GATE_API_KEY` / `GATE_API_SECRET`,不是 OKX。
2. **隧道是否在本机端口监听**(若配置了 `GATE_SOCKS_PROXY`):
```bash
ss -lntp | grep 1080 || true
```
3. **curl 复测 Gate**(与第 3.2 节相同);curl 不通则应用也不会通。
4. **PySocks**`pip show PySocks`,缺失则 `pip install PySocks`
5. **SSH 隧道连不上**:检查私钥权限、`~/.ssh/config`、VPS 出站与端口是否与 `.env` 一致。
6. **启动顺序**:先保证 SOCKS 已监听,再 `pm2 start` 应用(或重启应用)。
---
## 11. 推荐启动顺序(习惯)
1. 若走代理:先启动并确认 SSH SOCKS 已监听,再 `curl --proxy socks5h://127.0.0.1:1080 https://api.gateio.ws/api/v4/spot/time` 成功
2. `pm2 start ecosystem.config.cjs`
3. 再确认页面与余额等接口正常
---
## 12. 免责声明
交易所有合规与地区政策要求。请确保使用方式符合当地法律法规与交易所条款。本文仅描述网络与工程部署路径。
---
## 附录:数据库标签修复脚本 `scripts/fix_breakeven_labels.py`
在 Ubuntu 上:
1)预览(不写库):
```bash
python scripts/fix_breakeven_labels.py --db ./crypto.db --dry-run
```
2)确认后执行:
```bash
python scripts/fix_breakeven_labels.py --db ./crypto.db --apply
```
默认修复条件:`monitor_type='下单监控'``result='止损'``pnl_amount > 0` → 改为 `result='保本止盈'`

Some files were not shown because too many files have changed in this diff Show More