• 请不要在回答技术问题时复制粘贴 AI 生成的内容
xiaopenggggggg
V2EX  ›  程序员

量化大佬看过来, postman-gpui 经过迭代现在已经支持 HTTP 的全流程编排了!用 100 行 YAML 跑通了币安自动跟单与止盈策略!

  •  
  •   xiaopenggggggg · 18h 29m ago · 663 views

    量化大佬看过来,postman-gpui 经过迭代现在已经支持 HTTP 的全流程编排了!用 100 行 YAML 跑通了币安自动跟单与止盈策略!

    大家好!前段时间我们在社区首次分享了基于 Rust + GPUI 构建的高性能 API 客户端 **postman-gpui**,收到了许多开发者的关注与宝贵反馈。

    经过最近一段高强度的架构迭代与深打磨,项目迎来了一次质的跃迁:我们正式抽离并完善了底层的声明式流程编排引擎 —— postman-flow 与极速无头运行器 **postman-g**。

    为了验证这套引擎在工业级、严苛场景下的可用性,我们拿币安合约( Binance Futures )真实交易与风控场景做了一次极限压力实战。结果让我们非常惊喜:原本需要写上千行 Python/Node.js 胶水代码、配一堆外部依赖的自动化交易与风控策略,现在只需要不到 100 行清晰的 YAML ,单二进制直接毫秒级跑通!


    一、 传统写量化/监控脚本的痛,你一定踩过:

    平时大家写个定时抄底、网格挂单或者资产巡检脚本,常规操作是拉个 Python 项目,装上 requestsaiohttpccxt

    1. 环境依赖地狱:换台云服务器或放进 Docker ,光装 Python 3.10+、配虚拟环境和编译 C 扩展依赖就折腾半天;
    2. 手工算签名的痛苦:币安合约对 API 鉴权要求极严,必须提取 Query 、参数按字典序排序、拼接密钥计算 HMAC-SHA256 。只要少拼一个参数或编码不一致,就是冰冷的 Signature for this request is not valid
    3. 时钟偏移导致的神秘报错:本地 NTP 稍微慢了一两秒,请求就会被币安风控无情拦截(-1021 INVALID_TIMESTAMP);
    4. 未捕获异常导致进程静默死掉:网络偶发抖动、返回的 JSON 偶尔少了个字段,脚本抛出 KeyError 直接退出,往往第二天醒来才发现监控早就挂了。

    二、 现在,用纯声明式 Flow 编排长什么样?

    我们开源了一份开箱即用的实战参考:👉 **flow-binance-example**(默认对齐币安测试网,零风险开箱即用)。

    来看一段真实的策略流定义:“探测 BTC 价格 ➔ 低于 60000 触发 3 倍杠杆 ➔ 根据账户可用余额动态算仓市价开多 ➔ 开仓成功后自动以 80000 价格挂只减仓止盈单”

    schema_version: 1
    flow:
      name: binance-btc-auto-profit-strategy
      inputs:
        - name: host
          default: https://testnet.binancefuture.com
        - name: symbol
          default: BTCUSDT
        - name: trigger_price
          default: "60000"
    
      steps:
        # 1. 实时查余额:内置时间戳 + 引擎级原生自动计算 HMAC-SHA256 签名!
        - id: step-1-get-account
          name: 1. Query Current Account Info and Available Balance
          request:
            kind: http
            method: GET
            url:
              concat:
                - input: host
                - literal: /fapi/v2/account?timestamp=
                - input: $timestamp_ms            # 毫秒级动态时钟,发包瞬间自动计算
                - literal: '&recvWindow=60000'     # 60s 宽容窗口,彻底告别时钟偏移
            headers:
              - name: { literal: X-MBX-APIKEY }
                value: { input: api_key }
            auth:
              type: hmac_sha256                   # 原生自动加签,不用手工拼字符串!
              secret: { input: api_secret }
          checks:
            - kind: status
              equals: 200
          exports:
            - name: usdt_avail
              path: $.availableBalance
    
        # 2. 查询 BTCUSDT 实时行情
        - id: step-2-get-btc-price
          name: 2. Query Realtime BTC Price
          request:
            kind: http
            method: GET
            url:
              concat:
                - input: host
                - literal: /fapi/v1/ticker/price?symbol=
                - input: symbol
          checks:
            - kind: status
              equals: 200
          exports:
            - name: btc_price
              path: $.price
    
        # 3. 条件分支:仅当 BTC < 60000 时,调整为 3 倍杠杆
        - id: step-3-set-leverage
          name: 3. Set 3x Leverage (When BTC < 60000)
          when:
            lt:
              - output: { step: step-2-get-btc-price, name: btc_price }
              - input: trigger_price
          request: ... # 自动调整杠杆
    
        # 4. 原生动态算仓开多:保留 3 位精度,内置 10% 保证金缓冲垫
        - id: step-4-open-long-order
          name: 4. Open Long Order (When BTC < 60000)
          when:
            and:
              - lt:
                  - output: { step: step-2-get-btc-price, name: btc_price }
                  - input: trigger_price
              - gt:
                  - output: { step: step-1-get-account, name: usdt_avail }
                  - literal: 50                   # 严格匹配币安 50U 最小名义价值
          request:
            kind: http
            method: POST
            url:
              concat:
                - input: host
                - literal: /fapi/v1/order?symbol=
                - input: symbol
                - literal: '&side=BUY&type=MARKET&quantity='
                # 引擎内置的高性能数学计算表达式,防浮点溢出:
                - calc: "floor(((step-1-get-account.usdt_avail * 0.9 * 3) / step-2-get-btc-price.btc_price) * 1000) / 1000"
                - literal: '&timestamp='
                - input: $timestamp_ms
                - literal: '&recvWindow=60000'
            auth:
              type: hmac_sha256
              secret: { input: api_secret }
          checks:
            - kind: status
              equals: 200
          exports:
            - name: order_status
              path: $.status
            - name: executed_qty
              path: $.executedQty
    
        # 5. 开仓成功后自动挂 80,000u 只减仓止盈单(用 coalesce 熔断兜底)
        - id: step-5-take-profit-order
          name: 5. Place Take-Profit Limit Order (reduceOnly=true)
          when:
            eq:
              - coalesce:
                  - output: { step: step-4-open-long-order, name: order_status }
                  - literal: "NOT_OPENED"         # 开仓没触发时安全判定为 false ,绝不抛异常中断!
              - literal: "FILLED"
          request:
            kind: http
            method: POST
            url:
              concat:
                - input: host
                - literal: /fapi/v1/order?symbol=
                - input: symbol
                - literal: '&side=SELL&type=LIMIT&timeInForce=GTC&price=80000.0&reduceOnly=true&quantity='
                - coalesce:
                    - output: { step: step-4-open-long-order, name: executed_qty }
                    - literal: "0"
                - literal: '&timestamp='
                - input: $timestamp_ms
                - literal: '&recvWindow=60000'
            auth:
              type: hmac_sha256
              secret: { input: api_secret }
          checks:
            - kind: status
              equals: 200
    
      # 6. 每轮执行自动汇总并打印格式化看板
      outputs:
        - name: "1_symbol"
          value: { input: symbol }
        - name: "2_current_price"
          value: { output: { step: step-2-get-btc-price, name: btc_price } }
        - name: "3_wallet_balance"
          value: { output: { step: step-1-get-account, name: wallet_balance } }
        - name: "4_available_balance"
          value: { output: { step: step-1-get-account, name: usdt_avail } }
        - name: "5_open_order_id"
          value:
            coalesce:
              - output: { step: step-4-open-long-order, name: order_id }
              - literal: "NONE_PRICE_UNMET"
    

    三、 相比传统代码,它到底带来了什么颠覆?

    1. 单二进制直接跑,零解释器依赖: 底层编译为单一原生二进制 postman-g,只有十几兆,冷启动不到 5 毫秒,常驻内存仅几兆。不需要装 Node 、Python 、虚拟环境,直接丢在几块钱一个月的海外廉价 VPS 上就能跑。
    2. 极速体验:还没反应过来就执行完了: 纯 Rust 编写的异步网络栈,没有 GC 停顿,单次 5 个步骤连环请求在本地实测只需 200~300ms
    3. 确定性状态机与天然安全熔断: 借助 when 守卫与 coalesce 表达式,即便没有触发开仓条件,整个流程也不会因为引用了空输出而崩溃;止盈单严格锁死 reduceOnly=true,从协议层杜绝反向开空的严重事故。
    4. 支持 Docker 容器每 30 秒定时轮询: 自带 Dockerfile 与 Compose 配置,一条命令挂在后台常驻运行:
      INTERVAL=30 docker compose up -d
      
      本地改动 ./flows 目录下的 YAML 文件,下一秒轮询自动热加载最新策略,无需重新构建镜像!
    5. 已支持大容量数据零拷贝流式上传(kind: file: 不仅是金融高频交易,最近我们还支持了百万级数据集(如 Meilisearch 1M HackerNews )的零拷贝文件流,大体积文件推送内存常驻不到 30MB 。

    四、 欢迎体验与 Star 🌟

    整个生态现已完全开源,欢迎大家上手把玩,提出你的真实场景与反馈:

    如果觉得这种声明式接口编排的思路有意思,欢迎来 GitHub 点个 Star ⭐️ 支持一下!接下来我们也将正式开始把 Flow 的全套编排与实时执行看板无缝集成到 GPUI 桌面端中,敬请期待!

    iorilu
        1
    iorilu  
       18h 24m ago
    可以阿, 最佳 rust 的 gpui 火起来了

    这样除了 tauri 又有个选择了

    不高你这工具不是替代 postman 吗, 和量化啥关系
    xiaopenggggggg
        2
    xiaopenggggggg  
    OP
       18h 22m ago
    @iorilu postman-flow 是 http 的编排, 量化 example 只是一种实践,其他涉及到 http 编排都能用 去搞,声明式 DSL ,很好玩。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   978 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 22:07 · PVG 06:07 · LAX 15:07 · JFK 18:07
    ♥ Do have faith in what you're doing.