Polymarket 交易机器人踩坑实录

Polymarket交易机器人踩坑实录

末尾有连接测试代码

一、Python 版本问题

最开始我的环境是 Python 3.14。

运行代码时频繁出现:

text 复制代码
ConnectTimeout
ReadTimeout
SSL相关异常

刚开始以为是代码问题,后来发现很多第三方库对于最新版本 Python 的兼容性并不完善。

特比是对于网络请求、WebSocket、加密签名等场景

最终切换到 Python 3.11 后,这里没问题了。


二、pip 找不到命令

安装依赖时出现:

text 复制代码
pip : 无法将"pip"项识别为 cmdlet

原因:

安装 Python 后,环境变量没有正确刷新。

解决方案:

bash 复制代码
python -m pip install package_name

相比直接使用:

bash 复制代码
pip install package_name

这种方式更加可靠。

或者重启电脑,重配pip

bash 复制代码
python -m pip

避免环境变量带来的各种问题。


三、装错 WebSocket 库

代码:

python 复制代码
from websocket import WebSocketApp

运行后报错:

text 复制代码
ImportError: cannot import name 'WebSocketApp'

原因:

安装了错误的库:

bash 复制代码
pip install websocket

正确安装方式:

bash 复制代码
pip install websocket-client

虽然导入语句相同:

python 复制代码
from websocket import WebSocketApp

但底层实际来自 websocket-client。

这是一个非常经典的 Python 坑。


四、浏览器能访问,代码却超时

最开始测试:

python 复制代码
import requests

r = requests.get(
    "https://目标地址",
    timeout=20
)

print(r.status_code)

结果:

text 复制代码
ReadTimeout

但浏览器却能正常打开。

说明:

不是目标网站有问题。

而是:

text 复制代码
浏览器走代理
Python 没走代理

这是两条完全不同的网络链路。


五、代理配置看似正确,却始终超时

手动指定代理:

python 复制代码
proxies = {
    "http": "http://127.0.0.1:7892",
    "https": "http://127.0.0.1:7892",
}

测试成功:

python 复制代码
requests.get(url, proxies=proxies)

返回:

text 复制代码
200

说明:

  • 网络正常
  • 代理正常
  • 服务端正常

问题一定出在 SDK 内部。


六、SDK 请求不走代理

普通请求成功:

python 复制代码
requests.get(...)

但是 SDK 调用:

python 复制代码
client.create_or_derive_api_creds()

始终超时。

排查发现:

SDK 使用的是 httpx。

而我设置的代理并没有被 SDK 读取到,这一点是大坑,通过环境变量解决


七、环境变量大小写问题

最终定位到核心原因。

错误配置:

python 复制代码
os.environ["http_proxy"] = "http://127.0.0.1:7892"
os.environ["https_proxy"] = "http://127.0.0.1:7892"

可能某些情况下 SDK 没有正确读取,必须要大写。

改成:

python 复制代码
import os

os.environ["HTTP_PROXY"] = "http://127.0.0.1:7892"
os.environ["HTTPS_PROXY"] = "http://127.0.0.1:7892"

问题立刻解决。

之后:

python 复制代码
client.create_or_derive_api_creds()

成功返回结果。


七、测试代码

python 复制代码
import os

os.environ["HTTP_PROXY"] = "http://127.0.0.1:7892"
os.environ["HTTPS_PROXY"] = "http://127.0.0.1:7892"

try:
    from py_clob_client.client import ClobClient
    from py_clob_client.clob_types import OrderArgs
    from py_clob_client.order_builder.constants import BUY, SELL
    HAS_CLOB = True
except:
    HAS_CLOB = False
    print("Please install: pip install py-clob-client")

class Trader:
    def __init__(self):
        self.client = None
        self.connected = False
        self.address = None
    
    def connect(self):
        """Connect py-clob client."""
        pk = "xxxx"  	#私钥
        if not pk:
            print("PRIVATE_KEY not set", "ERR")
            return False
        
        try:
            if not pk.startswith("0x"):
                pk = "0x" + pk
            
            print("Connecting CLOB client...")
            temp = ClobClient(host="https://clob.polymarket.com", chain_id=137, key=pk)
            self.address = temp.get_address()
            print(f"Wallet: {self.address}")
            
            creds = temp.create_or_derive_api_creds()
            funder = "xxx" or self.address			#钱包地址
            sig_type = "2"
            
            self.client = ClobClient(
                host="https://clob.polymarket.com",
                chain_id=137,
                key=pk,
                creds=creds,
                signature_type=sig_type,
                funder=funder
            )
            self.connected = True
            print("CLOB client connected", "OK")
            return True
        except Exception as e:
            print(f"Connect failed: {e}", "ERR")
            return False
    
    def place_order(self, token_id, side, price, size):
        """Place limit order."""
        if not self.connected:
            print("CLOB client not connected", "ERR")
            return None
        
        try:
            print(f"Order: {side} ${size} @ {price:.3f}", "TRADE")
            
            order_args = OrderArgs(
                token_id=token_id,
                price=price,
                size=size,
                side=BUY if side == "BUY" else SELL
            )
            
            signed_order = self.client.create_order(order_args)
            resp = self.client.post_order(signed_order)
            
            if resp and resp.get("orderID"):
                order_id = resp.get("orderID")
                print(f"Order placed, id: {order_id}", "OK")
                return order_id
            else:
                print("Order rejected", "ERR")
                return None
        except Exception as e:
            print(f"Order error: {e}", "ERR")
            return None
    
    def get_order_status(self, order_id):
        """Poll order status."""
        if not self.connected or not order_id:
            return None
        
        try:
            order = self.client.get_order(order_id)
            if order:
                status = order.get("status", "").upper()
                original_size = float(order.get("original_size", 0) or 0)
                size_matched = float(order.get("size_matched", 0) or 0)
                
                return {
                    "status": status,
                    "original_size": original_size,
                    "size_matched": size_matched,
                    "filled": size_matched >= original_size if original_size > 0 else False
                }
        except Exception as e:
            print(f"get_order failed: {e}", "WARN")
        return None
    
    def cancel_order(self, order_id):
        """Cancel open order."""
        if not self.connected or not order_id:
            return False
        
        try:
            print(f"Cancel order: {order_id}", "WARN")
            resp = self.client.cancel(order_id)
            if resp:
                print("Order canceled", "OK")
                return True
            else:
                print("Cancel failed", "ERR")
                return False
        except Exception as e:
            print(f"Cancel error: {e}", "ERR")
            return False


if __name__ == "__main__":
    trader = Trader()
    ok = trader.connect()

    print("连接结果:", ok)
    print("是否已连接:", trader.connected)
    print("钱包地址:", trader.address)

连接成功显示如下

相关推荐
不正经学生8 分钟前
C语言预处理详解:编译器真正动手之前的那些事
c语言·开发语言·算法·面试·bug
门思科技18 分钟前
LoRaWAN 设备类别:Class A、B、C 对比与选型指南
c语言·开发语言·php
恋恋西风3 小时前
C++ 理解 std::thread 在单核和多核上的行为差异
开发语言·c++
Brilliantwxx3 小时前
【Linux】 进程(9)程序与进程地址空间(基础+进阶+面试题)
linux·运维·服务器·开发语言·c++
BizzZ_4 小时前
C++(22)——类型转换和IO流
开发语言·c++
小范同学_4 小时前
JDK1.7 与 JDK1.8 HashMap 底层原理对比 + 数组并发扩容死循环详解
java·开发语言
geovindu4 小时前
CSharp: 万年历
开发语言·后端·c#·.net
傲笑风4 小时前
【openvino】tinybert基于openvino服务化部署(四)
人工智能·python·自然语言处理·nlp·bert·openvino
我找到地球的支点啦5 小时前
Matlab系列(009) 一CRC循环冗余校验详解
开发语言·数据结构·算法·matlab·信息与通信
维基框架5 小时前
WIKI 知识库 v1.1.1 正式发布
人工智能·python