Browse Source

单项下单

lushdog 1 month ago
parent
commit
a8faebf102
1 changed files with 144 additions and 0 deletions
  1. 144 0
      bid.mjs

+ 144 - 0
bid.mjs

@@ -0,0 +1,144 @@
+//npm install @polymarket/clob-client
+//npm install ethers
+//npm install dotenv
+
+import {
+  ClobClient,
+  OrderType,
+  Side,
+} from '@polymarket/clob-client'
+import { Wallet } from '@ethersproject/wallet'
+import dotenv from 'dotenv'
+
+// 加载环境变量 (.env.local 优先)
+dotenv.config({ path: '.env.local' })
+
+// 必填校验
+if (!process.env.PRIVATE_KEY) {
+  console.error('错误: 请在 .env.local 文件中设置 PRIVATE_KEY')
+  process.exit(1)
+}
+if (!process.env.FUNDER_ADDRESS) {
+  console.error('错误: 请在 .env.local 文件中设置 FUNDER_ADDRESS')
+  process.exit(1)
+}
+
+const host = 'https://clob.polymarket.com'
+const funder = process.env.FUNDER_ADDRESS
+const signer = new Wallet(process.env.PRIVATE_KEY)
+
+// 从环境变量读取默认下单参数
+const signatureType = parseInt(process.env.SIGNATURE_TYPE) || 1
+const orderPrice = parseFloat(process.env.ORDER_PRICE) || 0.49
+const orderSize = parseInt(process.env.ORDER_SIZE) || 5
+
+function getSlug() {
+  const now = new Date()
+  const utcTimestamp = Math.floor(now.getTime() / 1000)
+  const intervalSeconds = 15 * 60
+  const nextInterval = Math.ceil(utcTimestamp / intervalSeconds) * intervalSeconds
+  const slug = `btc-updown-15m-${nextInterval}`
+
+  console.log('当前时间:', now.toISOString())
+  console.log('当前 UTC 时间戳:', utcTimestamp)
+  console.log('下一个 15 分钟间隔时间戳:', nextInterval)
+  console.log('生成的 slug:', slug)
+  return slug
+}
+
+async function getTokenIdsBySlug() {
+  const slug = getSlug()
+  console.log('正在获取市场信息,slug:', slug)
+
+  const response = await fetch(`https://gamma-api.polymarket.com/markets?slug=${slug}`)
+  if (!response.ok) {
+    throw new Error(`HTTP 错误: ${response.status} ${response.statusText}`)
+  }
+  const data = await response.json()
+  if (!data || data.length === 0) {
+    throw new Error(`未找到 slug 为 ${slug} 的市场`)
+  }
+  if (!data[0].clobTokenIds) {
+    throw new Error('市场数据中缺少 clobTokenIds 字段')
+  }
+  const clobTokenIds = JSON.parse(data[0].clobTokenIds)
+  console.log('市场信息:', data[0].question)
+  console.log('UP tokenID:', clobTokenIds[0])
+  console.log('DOWN tokenID:', clobTokenIds[1])
+  return { upTokenID: clobTokenIds[0], downTokenID: clobTokenIds[1] }
+}
+
+function parseDirectionArg() {
+  const arg = (process.argv[2] || '').toLowerCase()
+  if (arg !== 'up' && arg !== 'down') {
+    console.error('用法: node bid.mjs <up|down> [price] [size]')
+    console.error('示例: node bid.mjs up 0.49 5')
+    process.exit(1)
+  }
+  const priceArg = process.argv[3]
+  const sizeArg = process.argv[4]
+  const price = priceArg ? parseFloat(priceArg) : orderPrice
+  const size = sizeArg ? parseInt(sizeArg) : orderSize
+  if (Number.isNaN(price) || Number.isNaN(size)) {
+    console.error('价格或数量无效。示例: node bid.mjs up 0.49 5')
+    process.exit(1)
+  }
+  return { direction: arg, price, size }
+}
+
+async function main() {
+  try {
+    const { direction, price, size } = parseDirectionArg()
+    console.log('配置信息:')
+    console.log('- 下单方向:', direction.toUpperCase())
+    console.log('- 订单价格:', price)
+    console.log('- 订单数量:', size)
+    console.log('- 签名类型:', signatureType)
+    console.log('- 地址:', funder)
+
+    console.log('正在初始化 CLOB 客户端...')
+    const creds = await new ClobClient(host, 137, signer).createOrDeriveApiKey()
+
+    const clobClient = new ClobClient(
+      host,
+      137,
+      signer,
+      creds,
+      signatureType,
+      funder
+    )
+
+    console.log('正在获取市场 tokenID...')
+    const { upTokenID, downTokenID } = await getTokenIdsBySlug()
+    const tokenID = direction === 'up' ? upTokenID : downTokenID
+
+    console.log(`创建 ${direction.toUpperCase()} 限价单...`)
+    const result = await clobClient.createAndPostOrder(
+      {
+        tokenID,
+        price,
+        side: Side.BUY,
+        size,
+        feeRateBps: 0,
+      },
+      {
+        tickSize: '0.01',
+        negRisk: false,
+      },
+      OrderType.GTC
+    )
+
+    if (result?.success) {
+      console.log(`${direction.toUpperCase()} 订单成功:`, result)
+    } else {
+      console.log(`${direction.toUpperCase()} 订单返回:`, result)
+    }
+  } catch (error) {
+    console.error('下单失败:', error.message)
+    console.error('完整错误信息:', error)
+    process.exit(1)
+  }
+}
+
+// 执行
+main()