# wyex **Repository Path**: intirain/wyex ## Basic Information - **Project Name**: wyex - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-06 - **Last Updated**: 2026-10-07 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 未央神人交易所 一个游戏性质的沙盒交易所:注册即送虚拟币,可以自己发行标的、自己定价、公开撮合, 支持**做多与做空**,并带实时 K 线 / 成交量 / 均线 / 订单流看盘界面。 - 后端:Python 3.14 + Flask + SQLAlchemy + MariaDB(Docker) - 前端:Jinja2 模板 + 原生 JS + TradingView lightweight-charts(**已本地 vendor,零 npm 构建**) - 实时:Flask-Sock 原生 WebSocket,撮合线程广播成交/K线/盘口 - 启动:**单进程 `python run.py`** --- ## 快速开始 ```bash # 1) 起数据库(MariaDB 11.4,映射到 127.0.0.1:3307,数据卷自包含) docker compose up -d # 2) 装依赖 python3 -m venv .venv .venv/bin/pip install -r requirements.txt # 3) 启动 .venv/bin/python run.py ``` 打开 。首次启动会自动建表,并创建两个系统账户: | 账户 | 作用 | |---|---| | `__platform__` 平台金库 | 收手续费、发放注册赠送/充值(允许为负,是资金水龙头) | | `__market_maker__` 未央做市商 | 盘口兜底,保证任何标的都有买卖价 | 配置全部在 `.env`(改完重启生效),常用项: ```ini WYEX_SIGNUP_CASH=1000000 # 注册赠送 WYEX_DEPOSIT_AMOUNT=1000000 # 单次充值 WYEX_FEE_RATE=0.001 # 手续费率(买卖各收一次) WYEX_MM_SPREAD=0.005 # 做市价差 ±0.5% WYEX_MM_LOT_SIZE=100 # 做市每侧手数 WYEX_MM_INV_UPPER=2000 # 做市库存上限(手) WYEX_MM_INV_LOWER=-2000 # 做市库存下限(手) WYEX_MIN_LISTING_LOTS=100 # 发行最少入库手数 WYEX_ALLOW_SHORT=1 # 允许做空 ``` --- ## 玩法 ### 1. 注册 随便起个用户名,注册即得 **1,000,000 未央币**,不需要绑定任何东西。首页可随时"再充值"(沙盒,无上限)。 ### 2. 发行标的 「发行标的」页填:代码、名称、**发行价(每手)**、**入库手数(≥100)**。 起始资金 = 发行价 × 手数,从你的账户扣。 上市后: - 全部库存以**发行价**挂成卖单 → 所以**第一笔成交价就是你定的发行价** - 之后价格**自由涨跌,没有涨跌停** - 首发库存卖完后,做市商会接手继续供货 - 每人最多发行 5 个标的(可配) ### 3. 交易 - **限价 / 市价**两种单,价格优先 → 时间优先撮合 - **做多**:买入持有,等涨 - **做空**:卖出超过持仓的部分即为开空,按**全额保证金**冻结(不会穿仓) - 撤销挂单、部分成交都支持;**自己的买卖单不会互相成交**(防对敲刷量) - 手续费 0.1%(买卖各收一次),进平台金库 ### 4. 看盘(行情页) | 面板 | 内容 | |---|---| | K 线 | 1分/5分/15分/1时/1天 五档周期,实时更新 | | 成交量 | K 线下方柱状图,红绿区分涨跌 | | 均线 | MA5 / MA10 / MA20 | | 订单流 | 逐笔成交时间线 + 累计净流入曲线(Canvas 自绘) | | 盘口 | 买卖各 8 档,带深度条 | | 下单 | 价格可一键取买一/卖一/最新,手数支持 25%/50%/100% 快捷 | | 我的挂单 | 直接撤单 | --- ## 架构 ``` run.py 启动入口(单进程) app/ config.py 全部配置 + Decimal 精度常量 db.py 引擎/会话(每次写事务后失效缓存) models/__init__.py ORM:用户/账户/标的/订单/成交/持仓/K线/流水 engine.py 撮合引擎(核心,单写线程) seed.py 系统账户初始化 services/market.py 账户/鉴权/发行/只读行情 views/ REST API + 页面路由 ws/hub.py WebSocket 广播中心 static/js/symbol.js 行情页前端(图表/订单流/下单) templates/ Jinja2 模板 tools/ 验证脚本(见下) docker-compose.yml MariaDB ``` ### 撮合引擎设计(`app/engine.py`) - **单写线程 + 任务队列**:全交易所状态只有撮合线程能改,HTTP 线程只投递任务并等结果, 因此不存在两个请求同时改同一仓位/余额的竞态 - **记账精度**:全用 `Decimal`,现金 6 位小数、价格 8 位、数量 4 位,绝不用 float 记账 - **记账不变式**(`tools/check_invariants.py` 会校验): - 任何账户 `cash >= 0`、`locked_cash >= 0` - 卖出数量 ≤ 可用持仓 - `Σ流水 == 可用现金 + 挂单冻结 + 空头保证金` - 实物股票守恒:`Σ多头 − Σ空头 == −Σ总入库` - **缓存原则**:只缓存纯数据,ORM 行对象绝不跨 session 缓存 (否则 commit 后对象 detached,属性赋值不会被 flush,账目会静默错乱) --- ## 用 Python 写策略 后端是标准 REST + WebSocket,`tools/wyex_client.py` 提供了封装好的客户端: ```python import sys; sys.path.insert(0, "/home/ryp/wyex/tools") from wyex_client import WyexClient maker, taker = WyexClient.pair("bot_a", "bot_b") # 防自成交,需两个账号 maker.issue("TEST", "测试币", price="10.00", lots=500) taker.buy("TEST", 100, price="10.00") # 跨账号成交 print(taker.candles("TEST"), taker.position("TEST")) ``` 完整说明见 **[tools/API.md](tools/API.md)**(含全部方法、推送字段、错误码、示例策略)。 ## 验证脚本 服务跑起来后执行: ```bash .venv/bin/python tools/client_check.py # Python 客户端(24 项) .venv/bin/python tools/e2e_check.py # 全链路:注册→充值→发行→买卖→平仓→K线→撤单→风控 .venv/bin/python tools/short_test.py # 空头全生命周期,每步校验账目不变式 .venv/bin/python tools/ws_check.py # WebSocket 实时推送(trade/candle/book/order) PYTHONPATH=. .venv/bin/python tools/check_invariants.py # 账目不变式 ``` --- ## 已知限制 - 撮合是**单进程内存态**,因此不能用 `gunicorn -w N` 多 worker 部署(会各跑一套账) - 建表用 `create_all`,**改字段不会自动迁移**;加字段需要手动 `ALTER TABLE` 或重建表 - 做空是全额保证金,没有强制平仓(`WYEX_SHORT_LIQUIDATION_RATIO` 默认 0,可开启) - 无涨跌停、无集合竞价、无交易时段限制(按需求选择的设计)