You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

币安期货Tkinter工具:获取最新价格并计算下单量实现多空委托

币安期货量化工具问题修复与功能完善

核心问题梳理

  1. 初始加载时未选中交易对就发起价格请求,导致API调用失败
  2. 最新价格仅显示在标签中,未存储为可用于计算的变量
  3. 未实现实际下单量=输入金额/最新价格的核心计算逻辑
  4. 缺乏输入验证与错误处理,容易触发无效订单或程序崩溃

修复后完整代码

from tkinter import *
import os
import tkinter
from tkinter import ttk
from tkinter import messagebox
from binance.client import Client

#### API KEYS
api_key = os.environ.get('binance_api')
api_secret = os.environ.get('binance_secret')
client = Client(api_key, api_secret)

# 全局变量存储最新价格
latest_price = 0.0

# 界面初始化
root = Tk()
root.geometry('350x350')
root.title("币安期货市价下单工具")

l = Label(root, text="MARKET ORDER")
l.config(font=("Arial", 20))
l.pack(pady=10)

# 交易对选择栏
l = Label(root, text="选择USDT交易对")
l.config(font=("Arial", 10))
l.pack()
exchange_info = client.futures_exchange_info()
usdt_pairs = [s['symbol'] for s in exchange_info['symbols'] if 'USDT' in s['symbol']]

def search(event):
    value = event.widget.get()
    if value == '':
        combo_box['values'] = usdt_pairs
    else:
        data = [item for item in usdt_pairs if value.lower() in item.lower()]
        combo_box['values'] = data

combo_box = ttk.Combobox(root, value=usdt_pairs, width=25)
combo_box.set('')
combo_box.pack(pady=5)
combo_box.bind('<KeyRelease>', search)

# 价格获取与更新
def show_ticker_info(event=None):
    global latest_price
    selected_symbol = combo_box.get()
    if selected_symbol:
        try:
            # 移除无效的timeframe参数,正确调用期货ticker接口
            ticker_info = client.futures_ticker(symbol=selected_symbol)
            latest_price = float(ticker_info['lastPrice'])
            ticker_text.config(text=f"最新价格: {latest_price:.4f} USDT")
        except Exception as e:
            ticker_text.config(text=f"价格获取失败: {str(e)}")
    # 每隔1秒更新一次价格,避免请求过于频繁
    root.after(1000, show_ticker_info)

ticker_text = Label(root, text="请选择交易对查看价格", font=("Arial", 10))
ticker_text.pack(pady=5)
combo_box.bind("<<ComboboxSelected>>", show_ticker_info)
# 启动价格更新循环
root.after(1000, show_ticker_info)

# 金额输入栏
l = Label(root, text="输入下单金额(USDT)")
l.config(font=("Arial", 10))
l.pack(pady=5)
qty_entry = Entry(root, width=20)
qty_entry.pack()

# 辅助函数:获取交易对的数量步长
def get_quantity_step(symbol):
    for s in exchange_info['symbols']:
        if s['symbol'] == symbol:
            for filter in s['filters']:
                if filter['filterType'] == 'LOT_SIZE':
                    return float(filter['stepSize'])
    return 0.01  # 默认步长

# 卖单按钮逻辑
def buttonFunction():
    global latest_price
    selected_symbol = combo_box.get()
    input_amount_str = qty_entry.get()
    
    # 输入验证
    if not selected_symbol:
        messagebox.showerror("错误", "请先选择交易对")
        return
    if not input_amount_str.replace('.', '', 1).isdigit():
        messagebox.showerror("错误", "请输入有效的数字金额")
        return
    if latest_price <= 0:
        messagebox.showerror("错误", "未获取到有效价格,请检查交易对选择")
        return
    
    input_amount = float(input_amount_str)
    # 计算实际下单量
    raw_qty = input_amount / latest_price
    # 获取币安要求的数量步长并调整精度
    step_size = get_quantity_step(selected_symbol)
    qty = round(raw_qty / step_size) * step_size
    
    try:
        order = client.futures_create_order(
            symbol=selected_symbol,
            side=Client.SIDE_SELL,
            type=Client.ORDER_TYPE_MARKET,
            leverage=20,
            quantity=qty
        )
        # 弹出订单成功提示
        pop = Toplevel(root)
        pop.title("SELL 订单成功")
        pop.geometry("250x150")
        pop.config(bg="#00ff00")
        pop_label = Label(pop, text=f"订单已提交\n订单ID: {order['orderId']}", bg="#000000", fg="#ffffff", font=("Arial", 10))
        pop_label.pack(pady=20)
    except Exception as e:
        messagebox.showerror("下单失败", str(e))

b = Button(root, text="卖空(Sell)", bg="#ff4444", fg="white", command=buttonFunction, width=10)
b.config(font=("Arial", 12))
b.pack(side=LEFT, padx=20, pady=20)

# 买单按钮逻辑
def buttonFunction2():
    global latest_price
    selected_symbol = combo_box.get()
    input_amount_str = qty_entry.get()
    
    # 输入验证
    if not selected_symbol:
        messagebox.showerror("错误", "请先选择交易对")
        return
    if not input_amount_str.replace('.', '', 1).isdigit():
        messagebox.showerror("错误", "请输入有效的数字金额")
        return
    if latest_price <= 0:
        messagebox.showerror("错误", "未获取到有效价格,请检查交易对选择")
        return
    
    input_amount = float(input_amount_str)
    # 计算实际下单量
    raw_qty = input_amount / latest_price
    # 获取币安要求的数量步长并调整精度
    step_size = get_quantity_step(selected_symbol)
    qty = round(raw_qty / step_size) * step_size
    
    try:
        order = client.futures_create_order(
            symbol=selected_symbol,
            side=Client.SIDE_BUY,
            type=Client.ORDER_TYPE_MARKET,
            leverage=20,
            quantity=qty
        )
        # 弹出订单成功提示
        pop = Toplevel(root)
        pop.title("BUY 订单成功")
        pop.geometry("250x150")
        pop.config(bg="#00ff00")
        pop_label = Label(pop, text=f"订单已提交\n订单ID: {order['orderId']}", bg="#000000", fg="#ffffff", font=("Arial", 10))
        pop_label.pack(pady=20)
    except Exception as e:
        messagebox.showerror("下单失败", str(e))

b2 = Button(root, text="做多(Buy)", bg="#00cc00", fg="white", command=buttonFunction2, width=10)
b2.config(font=("Arial", 12))
b2.pack(side=RIGHT, padx=20, pady=20)

root.mainloop()

关键修复点说明

  1. 价格获取逻辑优化

    • 新增全局变量latest_price存储最新价格,用于后续下单计算
    • 仅当选中交易对时才发起API请求,避免无意义的错误调用
    • 移除无效的timeframe参数,符合Binance期货API规范
    • 添加错误捕获,显示价格获取失败原因
  2. 下单量计算实现

    • 实现实际下单量=输入金额/最新价格的核心公式
    • 新增get_quantity_step函数获取币安要求的数量步长,确保下单量符合平台规则
    • 对计算结果按步长取整,避免因精度问题导致下单失败
  3. 输入验证与错误处理

    • 检查交易对是否选中、输入金额是否为有效数字、价格是否有效
    • 对API调用异常进行捕获,弹出明确的错误提示
    • 订单成功后显示订单ID,提升用户体验
  4. 界面与性能优化

    • 调整界面布局,增加间距提升可读性
    • 将价格更新频率改为1秒一次,避免API请求过于频繁触发限流

内容的提问来源于stack exchange,提问作者Eq1NoX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 02:10:16