一個自稱「礦工」、實為分散式量化策略回測客戶端的 Windows 程式之完整靜態拆解。全程未執行 .exe,所有結論均來自 PyInstaller 解包、bytecode 反組譯與可複用模組實測。
SheepNodeMiner 不是加密貨幣礦工。它是一個分散式量化交易策略回測客戶端:使用者貢獻 CPU 核心,幫中央伺服器 sheepnode.com 大規模回測交易策略參數組合(幣種 × 週期 × 多空 × 指標策略族),把通過績效門檻的策略上傳回伺服器。本質是群眾外包的 alpha 挖掘(crowd-sourced alpha mining)。
data.sheepnode.com 下載 BitMart 3 年 K 線(sha256 校驗)→ 用 seed 決定性產 N 組參數 → 逐一回測(強制 1 分鐘 intrabar 撮合,切 IS/OOS)→ 通過 gate 門檻就上傳 → 每 ~20 秒心跳 → 重複。.pyc 已實測在乾淨 Python 3.13 直接 import 執行成功。f30d0d0a)大檔來自一整套科學運算依賴:numba / llvmlite(JIT)、pandas / numpy / polars、pywebview、requests / aiohttp、plotly、以及連帶打包但未使用的 boto3 / google.auth / GitPython / pythonnet / pefile。
pyinstxtractor(以 Python 3.13 執行,確保 PYZ 正確 unmarshal)→ 取出 4,965 個模組與資源(含 miner_ui.html、挖掘範圍.json)。pycdc(Decompyle++)對 Python 3.13 的新 opcode CALL_KW 不完全支援,僅能還原 import 與 docstring。pycdas 產出 7 個自訂模組共約 78,000 行完整反組譯(含所有常數、名稱、控制流)。marshal 遞迴抽取器,列出每個模組的字串常數、函式簽名、全域名稱。.pyc 放入乾淨 Python 3.13.12 環境直接 import 並呼叫,驗證可用性(見第 11 節)。全程未執行任何 .exe。所有結論基於靜態反組譯與可獨立執行的純函式模組實測,不含動態行為觀測。
除函式庫外,共 7 個自訂核心模組,分工如下:
| 模組 | 角色 | 職責 |
|---|---|---|
miner_gui | 進入點 | pywebview API bridge、開機自啟、看門狗、單一視窗鎖、自動更新、心跳、狀態快照 |
miner_client | 客戶端 | 伺服器通訊協定、主迴圈、資料管理(DataMgr)、設定載入 |
mining_core | 計算核心 | seed 決定性參數生成、單筆回測封裝、IS/OOS 指標切分(礦工端與伺服器防作弊端共用) |
backtest_runtime_core | 回測引擎 | 約 40 指標、訊號生成、1m 撮合模擬、KPI、BitMart 抓取、Numba/GPU 加速 |
backtest_costs | 成本模型 | 手續費 / 滑點唯一真實來源 |
sheep_backtest_policy | 政策 | canonical 回測政策常數、Walk-Forward 窗、可重現雜湊 |
sheep_runtime_paths | 路徑 | 檔案落地路徑解析;揭露另有一套「實盤交易 GUI」 |
# 資料流(高層)
sheepnode.com ──claim──▶ miner_client.run()
▲ │ work_unit{symbol,tf,direction,family,n_samples,seed,gate}
│ ▼
submit ◀── passed ── mining_core.gen_param_samples(family,seed,n) ──每組──▶ backtest_runtime_core.run_backtest()
▲ │ (1m intrabar 撮合)
│ ▼
miner_gui (pywebview UI) ◀── get_state/heartbeat ── IS/OOS metrics ── gate 過濾
│
data.sheepnode.com ──gz+sha256──▶ DataMgr.ensure() (BitMart 3y K線快取)
| 方法 | 行為 |
|---|---|
ui_ready() | 印 UI_BRIDGE_OK 確認橋接,回 {ok:true} |
get_state() | 回傳完整狀態快照(見下) |
connect(token) | strip token、寫入狀態、_save_config() 持久化、補一拍心跳 |
start() / stop() | start 清暫停閘門續跑;stop 是「暫停」(保留進度、不殺進程) |
set_workers(n) | clamp 至 [1, MAX_WORKERS]、持久化、即時增減 worker 進程 |
set_autostart(on) | 寫/刪 HKCU Run 鍵(見持久化) |
set_recover(on) | 建/刪 schtasks 排程(見持久化) |
open_url(url) | webbrowser.open() 用系統瀏覽器開連結 |
| 行為 | 位置 / 內容 | 控制 |
|---|---|---|
| 開機自啟 | HKCU\Software\Microsoft\Windows\CurrentVersion\Run 值 SheepNodeMiner → "<EXE>" --autostart | UI set_autostart,DeleteValue 移除 |
| 當機自復 | 工作排程 SheepNodeMinerRecover,每 5 分鐘 "<EXE>" --watchdog | UI set_recover,schtasks /delete 移除 |
| 單一視窗鎖 | %LOCALAPPDATA%\SheepNodeMiner\instance.lock(寫 PID)、stopped.flag | 啟動時自動 |
| 設定檔 | miner_config.json(EXE 同層)— token 明文 | 連線時 |
| 日誌 | miner_error.log / miner_log.txt / miner_worker.log | 執行時 |
_watchdog_run()stopped.flag 存在(使用者乾淨關閉)→ 不動。instance.lock 的 PID,用 OpenProcess+GetExitCodeProcess(259=STILL_ACTIVE)判存活。Popen(_self_cmd(), DETACHED) 重開一個全新實例。_instance_guard()背景執行緒每 1.5 秒讀 instance.lock;若 owner PID ≠ 自己(有更晚開的視窗覆寫了鎖)→ 顯示覆蓋層、5 秒後 _terminate_all() + os._exit(0)。機制本質是「後開者贏」。
_check_update()啟動時 GET {server}/api/mining/version(timeout 10s),解析 {version, url, notes},逐段比版本號;有新版只顯示橫幅,不自動下載、不自動執行。「前往下載」用系統瀏覽器開伺服器回傳的 url。
{ status, token_set, token_mask:'', paused, running, workers_desired,
cpu_max, cpu_recommend, active_workers,
worker_list:[{wid,symbol,tf,direction,family,done,total}],
session:{variants_done, passed, runtime_sec},
log:[最近60條{t,msg}], superseded, app_version:'2.3.0',
update:{available,latest,url,notes}, autostart, recover, platform_win }
所有請求經 _http_json(url, payload, timeout):有 payload 則 POST(json.dumps body),否則 GET。Header Content-Type: application/json、User-Agent: miner/1.0。回應 json.loads,例外吞為 None。
| 用途 | 端點 | 方法 | 送出 / 收到 |
|---|---|---|---|
| 認領工作單 | {server}/api/mining/claim | POST | 送 {token} → 收 {ok, error, work_unit} |
| 上傳結果 | {server}/api/mining/submit | POST | 送 6 欄 payload(見下) |
| 心跳 | {server}/api/mining/heartbeat | POST | 送 {token, status, tasks},每 ~20s |
| 版本檢查 | {server}/api/mining/version | GET | 收 {version, url, notes} |
| 資料清單 | {data}/manifest.json | GET | 收 {files:[{name, sha256_gz}]} |
| 資料下載 | {data}/{csv}.gz | GET | 收 gzip bytes(timeout 300s) |
work_unit_id · symbol · tf · direction · family · n_samples · seed · data_base_url(預設 https://data.sheepnode.com) · gate{...}
{ token, work_unit_id,
results: [通過 gate 的 sample + 回測指標],
n_ran: len(samples),
client_version: 'miner/1.0',
runtime_sec: round(dt,1) }
每筆 result 含 IS/OOS 雙組指標:n_trades, sharpe, total_return_pct, max_drawdown_pct, win_rate_pct, profit_factor + is_n/is_ret/is_win/is_sharpe/is_dd + oos_n/oos_ret/oos_win/oos_sharpe/oos_dd。
| gate 欄 | 預設 | 判定 |
|---|---|---|
| min_oos_sharpe | cfg.min_sharpe(0.5) | oos_sharpe ≥ 門檻 |
| min_oos_win | 35 | oos_win ≥ 35(%) |
| oos_n_min / oos_n_max | 10 / 200 | 10 ≤ oos_n ≤ 200 |
| oos_ret_min / is_ret_min | 0 / 0 | oos_ret > 0 且 is_ret > 0 |
{ "server_url": "https://sheepnode.com", "token": "",
"data_dir": "miner_data", "min_trades": 10, "min_sharpe": 0.5 }
ensure(symbol, tf) 檢查 {symbol}_{tf}_3y.csv 與 {symbol}_1m_3y.csv(主週期+1m 撮合基準),缺則下載。_download:抓 .gz → sha256 比對 manifest(校驗壓縮檔)→ gzip.decompress 落地。manifest 取不到則降級為不校驗。
模組自述「不依賴面板/DB/網路,純計算」——可單獨打包進礦工,也可被伺服器 import 抽樣重跑(防作弊)。不含並行、不含工作分配、不含上傳、不含 GUI 回報,這些在上層。
# 決定性的關鍵:字串化 seed 建 RNG rng = random.Random(f"sheepnode-mine:{family}:{seed}") # 同 (family, seed, n) → 完全相同輸出 → 伺服器可重算驗證
_grid_pick(rng, spec):在 [min,max] 以 step 為格點隨機挑一格;整數型 spec 回 int,否則 round 6 位。slow>fast(均線交叉類):若挑出 slow≤fast 則重挑。tp_pct = pick(TP_SPEC)/100、sl_pct = pick(SL_SPEC)/100、max_hold = int(pick(MH_SPEC))。{params, tp_pct, sl_pct, max_hold}。26 個可挖家族(MINEABLE_FAMILIES):SMA/EMA/HMA/DEMA/TEMA/WMA/KAMA_Cross、RSI、Bollinger_Touch、BB_PercentB_Revert、Stoch/CCI/WillR/MFI_Oversold、Donchian_Breakout、ADX_DI/Aroon_Cross、Aroon_Osc/ROC/CMF/EFI_Threshold、TRIX_Cross、DPO_Revert、Vortex_Cross、ATR_Band_Break、Volatility_Squeeze。
呼叫引擎 run_backtest(..., require_1m_fill=True, reverse_mode=(direction=='short')) → 以切點 2025-05-27T00:00:00+00:00 把交易分 IS/OOS → 各跑 _seg_metrics 回 (n, 複利報酬%, 勝率%, sharpe, 最大回撤%)。status 僅 ok / no_data / ERR:<類別>,不做 pass 判定(門檻在 miner_client 的 gate)。
純後端核心,UI 入口為 Streamlit 的 backtest_panel2.py。同時是礦工的回測肌肉。
SHEEP_BITMART_KLINE_MARKET 切換entry_price = open[i+1])。worst_case 旗標決定先 SL 或先 TP。skip_1m 被政策禁止。# Sharpe(逐K淨值,非逐筆) bpy = 31557600 / bar_seconds # Julian year rf_per_bar = (1+rf_annual)**(1/bpy) - 1 sharpe = (mean(returns)-rf_per_bar) / std(returns,ddof=1) * sqrt(bpy) # 另有 Sortino(下行差)、Calmar(cagr/maxdd)、CAGR、最大回撤、勝率、payoff、profit_factor、expectancy
https://api-cloud.bitmart.com/spot/quotation/v3/klines(symbol/step/limit/before/after,limit 200)https://api-cloud-v2.bitmart.com/contract/public/kline(start_time/end_time)X-BM-RateLimit-* / Retry-After,遇 429/code 30013 退避;偽裝 Chrome 122 UA。{symbol}_{step}m_3y.csv(+ .meta.json/.lock),自動偵測 epoch s/ms/us/ns。Numba JIT(@njit/prange,約 68 處):撮合核心、指標批次、OB_FVG/SMC/Laguerre/TEMA_RSI 模擬皆有 _nb 版本與 _py fallback。GPU 路徑(PyTorch/DirectML,run_grid_gpu、TF32)用於快速格點掃描;啟用 1m 精準撮合或動態風控策略時自動改走 CPU/Numba 逐筆。
DEFAULT_FEE_SIDE = 0.00055 # 單邊 0.055% DEFAULT_SLIPPAGE = 0.0003 # 單邊 0.03% 來回成本 = 2*fee + 2*slip = 0.17% # 做多淨報酬 exec_entry = entry*(1+slip) exec_exit = exit *(1-slip) net = exec_exit*(1-fee)/(exec_entry*(1+fee)) - 1
| POLICY_VERSION | backtest_policy_v1 |
| BACKTEST_YEARS | 3 |
| INTRABAR_MIN | 1(強制) |
| EXECUTION_MODEL | main_signal_1m_microfill |
| WFE 總月 / IS / OOS / step | 36 / 18 / 6 / 6 |
| min_positive_oos_folds | 2 |
| min_wfe_ratio | 0.5 |
Walk-Forward 三折:fold1 IS[0,18)→OOS[18,24)、fold2 IS[6,24)→OOS[24,30)、fold3 IS[12,30)→OOS[30,36)。canonical_backtest_policy_payload() 把全部常數 + release 以 sha256 取前 24 字元當防作弊政策指紋。validate_backtest_policy_fields() 強制 years=3、intrabar=1,否則 raise。
| 類型 | 值 |
|---|---|
| 控制伺服器 | https://sheepnode.com |
| API 端點 | /api/mining/claim · /submit · /heartbeat · /version |
| 資料 CDN | https://data.sheepnode.com(/manifest.json · /{csv}.gz) |
| 行情來源 | api-cloud.bitmart.com(現貨)· api-cloud-v2.bitmart.com(合約) |
| 本機測試(docstring) | http://127.0.0.1:8093 |
| Token 格式 | mtok_…(明文存 miner_config.json) |
| User-Agent | miner/1.0(client)· miner-gui/2.3.0(GUI) |
| 系統修改 | HKCU\…\Run\SheepNodeMiner · schtasks SheepNodeMinerRecover |
| 本機落地 | %LOCALAPPDATA%\SheepNodeMiner\{instance.lock,stopped.flag} · miner_config.json · miner_data\ |
無 IP / .onion / webhook / pastebin / t.me / 硬編碼憑證 / API key。
| 稽核面向 | 結果 |
|---|---|
| 反調試 / 反 VM / 反沙箱 | 無 |
| 加殼 / 字串混淆 / 加密 payload | 無 |
| eval / exec / compile | 無 |
| 遠端 pickle / marshal 反序列化 | 無(網路全走 json.loads) |
| 動態下載並執行程式碼 | 無(更新僅顯示橫幅) |
| subprocess | 僅重啟自身 + schtasks/winreg,無 shell=True |
| 資料外洩面 | 僅回測結果 + 進度;未碰 hostname/MAC/憑證/剪貼簿/檔案 |
| boto3/google.auth/git/.NET/pefile | 連帶打包,自訂碼 0 引用(grep 確認) |
| 持久化 | HKCU Run + schtasks(可逆、UI 可關、user-level) |
| token 儲存 | 明文於 miner_config.json |
將反編譯出的純邏輯 .pyc 放入乾淨 Python 3.13.12 環境,直接 import 即執行成功:
[magic] 本機 magic = f30d0d0a # 與打包相符
[costs] FEE_SIDE=0.00055 SLIPPAGE=0.0003 resolve_costs(None)=(0.00055, 0.0003)
[policy] backtest_policy_v1 years=3 exec=main_signal_1m_microfill
[policy] WFE folds=3 reproducible hash=570cf971303035f7abfc0aa5
[gen] mineable_families=26 deterministic=True
[gen] SMA_Cross seed=42 first={'params':{'fast':46,'slow':225},'tp_pct':0.033,'sl_pct':0.038,'max_hold':35}
[space] families=32 trade_management_combos=153600
OK — 全部可複用模組驗證通過。
| 資產 | 狀態 | 價值 |
|---|---|---|
| backtest_costs | 實測可用 | 現成真實成本公式 |
| sheep_backtest_policy | 實測可用 | IS/OOS + Walk-Forward 防過擬合框架 + 可重現雜湊 |
| mining_core.gen_param_samples | 實測可用 | 決定性參數掃描,26 族 |
| 挖掘範圍.json | 純資料 | 32 族完整搜尋空間(交易管理就 153,600 組合) |
| backtest_runtime_core | 機制可行(依賴較重) | 完整回測引擎 |
data.sheepnode.com 需 token,且只是 BitMart 公開數據的快取。引擎內 BitMartRestClient(端點/分頁/限流)已完整還原,自己直接抓 BitMart 即可,數據主權握在自己手上。| 策略族 | 核心參數 / 邏輯 |
|---|---|
| OB_FVG 訂單塊+公允價值缺口 | 連續 N 根 (C-O)/O>r 且量>均量*g 定義趨勢;OB=趨勢前紅K、FVG=綠K 缺口;W 根內「漲至 OB_High*rise_thr→跌回 OB_Low*a→漲回」開單;RSI 濾網。走 per_entry。 |
| SMC Smart Money Concept | 對照 Pine Script:Pivot(Len,Len)、3 連同色K、突破 PH/PL 形成 OB、突破 Bearish OB 做多。 |
| LaguerreRSI_TEMA | gamma、tema_len,ATR 動態 SL/TP/Trailing(sl/tp/ts_dist/ts_act coef)。 |
| TEMA_RSI | fast/slow_len、rsi_len/thr、activation_pct、trail_ticks、mintick、tp/sl_pct、stake_pct(對應另一套實盤 GUI)。 |
| MULTI | 2–8 族合成,邏輯 AND / OR / EACH_OR。 |
sheep_runtime_paths 揭露除「礦工」外另有實盤交易 GUI(實盤程式/tema_rsi_gui_config.json、tema_rsi_state.json、execution_logs/)與 Streamlit 回測面板 backtest_panel2.py。SheepNode 是一套完整量化系統:研究面板 + 群眾算力礦工 + 實盤 TEMA_RSI 執行,這個 .exe 只是「群眾算力」那條手臂。