Safety Guest'T blog

  • 首页
  • 归档
  • 软件开发
  • 网络安全
  • 逆向破解
  • 人工智能
  • 资源分享
  • 区 块 链
  • 隐私政策
  • 友情链接

币安API 通过Python赛选ema值

  • Tz
  • 2024-06-03
  • 0

需求:
做一个可以智能按照时间级别筛选符合条件的币种,
比如我要筛选币安永续合约交易队里面,所有实时价格大于周线 ema52 值的交易队的币种数据,或者日线 ema52 值的。反之小于的也一样。
另外再做个特殊的,就是当前实时价格,在周线ema52 值正负不超过x个点的交易队。
其中时间级别要可以自己设置,EMA的值要可以设置(固定也行,最好是能实时优化),x要能设置,x指百分点,比如现在的值是 100,正负不超过 10 个点的,那么就是在当前选取的级别下 ema52 的实时价格在 90-110 的交易队都要显示出来。

代码:

import tkinter as tk
from tkinter import ttk
from threading import Thread
import pandas as pd
from binance.client import Client
from concurrent.futures import ThreadPoolExecutor

api_key = ''  # 确保这里是正确的密钥
secret_key = ''  # 确保这里是正确的密钥密钥
client = Client(api_key, secret_key)

# 创建窗口
root = tk.Tk()
root.title("加密货币 EMA 筛选器")
root.geometry("450x500")  # 调整窗口大小以容纳更多内容
root.resizable(False, False)  # 禁用窗口放大

# 创建样式
style = ttk.Style()
style.configure('TButton', font=('Arial', 10), padding=10)
style.configure('TLabel', font=('Arial', 10), padding=5)
style.configure('TEntry', font=('Arial', 10), padding=5)
style.configure('TProgressbar', thickness=20)

# 参数输入
ttk.Label(root, text="时间间隔:").grid(column=0, row=0, sticky='w')
interval_values = [
    "1分钟", "3分钟", "5分钟", "15分钟", "30分钟",
    "1小时", "2小时", "4小时", "6小时", "8小时", "12小时",
    "1天", "3天", "1周", "1月"
]
interval_mapping = {
    "1分钟": "1m", "3分钟": "3m", "5分钟": "5m", "15分钟": "15m", "30分钟": "30m",
    "1小时": "1h", "2小时": "2h", "4小时": "4h", "6小时": "6h", "8小时": "8h", "12小时": "12h",
    "1天": "1d", "3天": "3d", "1周": "1w", "1月": "1M"
}
interval_combobox = ttk.Combobox(root, values=interval_values, width=27)
interval_combobox.grid(column=1, row=0, sticky='we')
interval_combobox.current(0)  # 默认选择"1分钟"

ttk.Label(root, text="EMA 长度:").grid(column=0, row=1, sticky='w')
ema_length_entry = ttk.Entry(root, width=30)
ema_length_entry.grid(column=1, row=1, sticky='we')
ema_length_entry.insert(0, "52")

ttk.Label(root, text="百分比阈值:").grid(column=0, row=2, sticky='w')
percentage_threshold_entry = ttk.Entry(root, width=30)
percentage_threshold_entry.grid(column=1, row=2, sticky='we')
percentage_threshold_entry.insert(0, "10")

# 添加状态选择下拉框
ttk.Label(root, text="状态:").grid(column=0, row=3, sticky='w')
status_values = ["全部", "大于", "小于", "等于"]
status_combobox = ttk.Combobox(root, values=status_values, width=27)
status_combobox.grid(column=1, row=3, sticky='we')
status_combobox.current(0)  # 默认选择"全部"

# 输出表格
tree = ttk.Treeview(root, columns=('symbol', 'current_price', 'ema', 'percentage'), show='headings')
tree.heading('symbol', text='交易对', command=lambda: sort_treeview_column(tree, 'symbol', False))
tree.heading('current_price', text='当前价格', command=lambda: sort_treeview_column(tree, 'current_price', False))
tree.heading('ema', text='EMA', command=lambda: sort_treeview_column(tree, 'ema', False))
tree.heading('percentage', text='百分比', command=lambda: sort_treeview_column(tree, 'percentage', False))

tree.column('symbol', width=100)
tree.column('current_price', width=100)
tree.column('ema', width=100)
tree.column('percentage', width=100)

tree.grid(column=0, row=6, columnspan=2, padx=10, pady=5, sticky='nsew')

# 进度条
progress = ttk.Progressbar(root, mode='determinate', maximum=100)
progress.grid(column=0, row=5, columnspan=2, sticky='we')

def calculate_ema(data, ema_length):
    k = 2 / (ema_length + 1)  # 平滑常数
    ema = [data[0]]  # 初始化EMA数组和第一个EMA值
    for close_price in data[1:]:
        ema.append(close_price * k + ema[-1] * (1 - k))
    return ema

def process_symbol(symbol, interval, ema_length, percentage_threshold):
    try:
        klines = client.futures_klines(symbol=symbol, interval=interval, limit=1000)
        df = pd.DataFrame(klines, columns=['open_time', 'open', 'high', 'low', 'close', 'volume', 'close_time', 'quote_asset_volume', 'number_of_trades', 'taker_buy_base_asset_volume', 'taker_buy_quote_asset_volume', 'ignore'])
        df['close'] = pd.to_numeric(df['close'])
        closes = df['close'].tolist()

        # 计算EMA
        k = 2 / (ema_length + 1)
        ema = [closes[0]]
        for close in closes[1:]:
            ema.append(close * k + ema[-1] * (1 - k))
        
        current_price = closes[-1]
        current_ema = ema[-1]
        lower_bound = current_ema * (1 - percentage_threshold / 100)
        upper_bound = current_ema * (1 + percentage_threshold / 100)

        # 根据状态选择进行筛选
        status = status_combobox.get()
        percentage_diff = ((current_price - current_ema) / current_ema) * 100
        if (status == "全部" or
            (status == "大于" and current_price > current_ema) or
            (status == "小于" and current_price < current_ema) or
            (status == "等于" and current_price == current_ema)):
            if abs(percentage_diff) <= percentage_threshold:
                return (symbol, current_price, current_ema, percentage_diff)
    except Exception as e:
        return (symbol, f"Error: {str(e)}", "", "", "")
    return None

def update_output():
    try:
        for i in tree.get_children():
            tree.delete(i)

        interval = interval_mapping[interval_combobox.get()]
        ema_length = int(ema_length_entry.get())
        percentage_threshold = int(percentage_threshold_entry.get())

        # 获取U本位永续合约交易对列表
        info = client.futures_exchange_info()
        symbols = [s['symbol'] for s in info['symbols'] if s['contractType'] == 'PERPETUAL' and s['quoteAsset'] == 'USDT']
        total_symbols = len(symbols)
        selected_symbols = []

        with ThreadPoolExecutor(max_workers=10) as executor:  # 使用线程池并行处理
            futures = [executor.submit(process_symbol, symbol, interval, ema_length, percentage_threshold) for symbol in symbols]
            for i, future in enumerate(futures):
                result = future.result()
                if result:
                    selected_symbols.append(result)
                # 更新进度条
                progress['value'] = (i + 1) / total_symbols * 100
                root.update_idletasks()

        for sym in selected_symbols:
            symbol, current_price, current_ema, percentage_diff = sym
            color_tag = 'positive' if percentage_diff > 0 else 'negative'
            tree.insert('', tk.END, values=(symbol, current_price, current_ema, f"{percentage_diff:.2f}%"), tags=(color_tag,))
            tree.tag_configure('positive', background='green')
            tree.tag_configure('negative', background='yellow')

    except Exception as e:
        tree.insert('', tk.END, values=("Error", str(e), "", "", ""))
    finally:
        progress['value'] = 100  # 确保完成时进度条设置为100%

def sort_treeview_column(tv, col, reverse):
    """Sorts Treeview column when header is clicked."""
    l = [(tv.set(k, col), k) for k in tv.get_children('')]
    l.sort(reverse=reverse, key=lambda t: float(t[0]) if col in ['current_price', 'ema'] else float(t[0][:-1]) if col == 'percentage' else t[0])

    for index, (_, k) in enumerate(l):
        tv.move(k, '', index)

    tv.heading(col, command=lambda: sort_treeview_column(tv, col, not reverse))

def copy_to_clipboard(event):
    if tree.selection():
        item = tree.selection()[0]
        values = tree.item(item, "values")
        clipboard_content = "\t".join(values)
        root.clipboard_clear()
        root.clipboard_append(clipboard_content)
        messagebox.showinfo("已复制", "行内容已复制到剪贴板")
    else:
        messagebox.showwarning("未选择", "请选择一行后再复制")

# 绑定表格点击事件
tree.bind("<Double-1>", copy_to_clipboard)

# 使用线程来避免界面冻结
def threaded_update():
    thread = Thread(target=update_output)
    thread.start()

# 更新按钮
update_button = ttk.Button(root, text="更新", command=threaded_update)
update_button.grid(column=0, row=4, columnspan=2, pady=5)

root.mainloop()
© 2025 Safety Guest'T blog
Theme by Wing
渝ICP备 2021011909号 渝公网安备 50019002502382号
  • {{ item.name }}
  • {{ item.name }}