HN 표시: 전략의 제한이 없는 WASM 시장 시뮬레이터

hackernews | | 🔬 연구
#review #wasm #백테스팅 #시뮬레이터 #알고리즘 매매 #파이썬
원문 출처: hackernews · Genesis Park에서 요약 및 분석

요약

WebAssembly 기반의 시뮬레이터를 브라우저에서 실행하고 매매 전략은 로컬 파이썬 환경에서 구동하는 독특한 백테스팅 플랫폼이 공개되었습니다. 이 구조는 GPU, 외부 API 등 제약 없는 로컬 전략 실행을 지원하며, AI 코딩 에이전트가 자율적으로 전략을 작성하고 결과를 개선하는 워크플로우에 최적화되어 있습니다. 또한 각 티켓 단위의 추적을 통한 정밀한 분석 기능을 제공하며, 현재 피드백 수집 기간 동안 무료로 사용할 수 있습니다.

본문

A Python client library for controlling the browser-based WASM trading engine. Build, backtest, and evaluate algorithmic trading strategies programmatically. This library works alongside the Hawk-Backtester web app — your strategies run locally in Python while the simulation engine runs in the browser via WASM. See the documentation for detailed usage and setup instructions. Browser (WASM Engine + UI) ↕ WebSocket (binary, lock-step RPC) hawk-bt (Python) ↕ py_engine_rust (Rust extension, required) - WASM Engine: The core trading simulation running in the browser - hawk-bt: Python client handling strategy execution and state management - py_engine_rust: Rust extension for WebSocket communication, binary codec, and RPC (required dependency) - Python >= 3.10 py-engine-rust (Rust extension, required)numpy >= 1.23 pip install -e . import asyncio from py_engine.runtime.rust_engine_async_adapter import RustEngineAsyncAdapter from py_engine.runtime.loop import run_attached from py_engine.strategy.api import Strategy, Context class MyStrategy(Strategy): async def step(self, ctx: Context) -> None: s = ctx.state.statics price = s.current_rate if price > 100.0 and s.tickets_num == 0: await ctx.engine.place_ticket(side="buy", units=10, sub_limit_pips=5.0, stop_order_pips=3.0) async def main(): engine = RustEngineAsyncAdapter(host="127.0.0.1", port=8787) await engine.start() await engine.wait_connected(timeout=None) result = await run_attached(engine, MyStrategy(), gate_policy="eager") print(f"Steps: {result.steps}, Final assets: {result.final_assets()}") asyncio.run(main()) Subclass Strategy and implement step() . It is called automatically on every simulation step. class Strategy(ABC): @abstractmethod async def step(self, ctx: Context) -> None: ... Available via ctx : ctx.state.statics — Current assets, price, and position info (Statics )ctx.engine — Engine operations (BoundEngine )ctx.state.done — Simulation completion flagctx.user — Free-usedict for state persistence, logging, etc. out = await ctx.engine.place_ticket( side="buy", # "buy" | "sell" units=100, # lot size sub_limit_pips=5.0, # TP (absolute price difference, optional) stop_order_pips=3.0, # SL (absolute price difference, optional) trail_pips=2.0, # trailing stop (optional) ) # out: shape (14,) — [0]=flag (ticket ID), [1..4]=reward fields, [5]=current_rate, ... out = await ctx.engine.place_token( side="sell", # "buy" | "sell" order="limit", # "limit" | "stop" price=90.0, # order price units=80, sub_limit_pips=8.0, # TP (optional) stop_order_pips=25.0, # SL (optional) trail_pips=None, # trailing stop (optional) time_limits=240.0, # expiry in steps (optional) ) # out: shape (18,) — [0]=flag (token ID), ... events = await ctx.engine.close_step( flags=[ticket_flag], # target ticket flag (ID) actions=[1], # 1=full close, 2=partial close (REDUCE) ratios=[0.0], # ratio for action=2 (0.0–1.0) ) # events: shape (N, 5) — close results Batch closing of multiple tickets is supported by passing arrays. # Current state statics = await ctx.engine.get_statics() statics.assets # account balance statics.virtual_assets # balance including unrealized P&L statics.current_rate # current price statics.current_step # current step statics.total_steps # total steps statics.margin_ratio # margin ratio statics.tickets_num # open ticket count statics.token_num # pending order count # ... 20+ fields # Ticket list tickets = await ctx.engine.get_ticket_list() # shape (rows, cols) — each row is one ticket's details Runs the strategy against OHLC data already loaded in the browser. result = await run_attached(engine, strategy, gate_policy="eager") Sends OHLC data from Python and runs the backtest. result = await run_backtest(engine, strategy, ohlc5, steps=5000) ohlc5 : np.ndarray shape (N, 5) — [time_ms, open, close, high, low] result.steps # number of steps executed result.assets # np.ndarray — asset history per step result.virtual_assets # np.ndarray — asset history including unrealized P&L result.price # np.ndarray — price history result.final_assets() # final account balance result.max_drawdown() # max drawdown (negative value) from py_engine.runtime.rust_engine_async_adapter import RustEngineAsyncAdapter engine = RustEngineAsyncAdapter(host="127.0.0.1", port=8787) await engine.start() await engine.wait_connected() Controls intra-step state synchronization. Can be set in the browser UI or auto-detected via get_gate_policy_hint() . eager (default): Runsaffect +get_statics after every operation. Accurate but slower.step_end : Syncs only at step end. Faster but intermediate state may be stale. gate_policy = await engine.get_gate_policy_hint() or "eager" result = await run_attached(engine, strategy, gate_policy=gate_policy) - WebSocket connection management (server startup, connection waiting, disconnect detection) - Binary protocol encode/decode (Rust implementation) - RPC communication (send → await response, timeout, error handling) - Step loop control ( run_attached /run_backtest ) - Au

Genesis Park 편집팀이 AI를 활용하여 작성한 분석입니다. 원문은 출처 링크를 통해 확인할 수 있습니다.

공유

관련 저널 읽기

전체 보기 →