import pymysql
import requests
import time
import schedule
from datetime import datetime

# MySQL连接函数
def connect_to_db():
    return pymysql.connect(
        host="127.0.0.1",        # 数据库主机
        user="root",             # 数据库用户名
        password="2GS@bPYcgiMyL14A",    # 数据库密码
        database="binance_api",  # 数据库名称
        port=4423                # 数据库端口
    )

# 执行SQL查询的函数
def execute_query(query, params=None):
    conn = connect_to_db()  # 连接数据库
    with conn.cursor() as cursor:
        cursor.execute(query, params)  # 执行SQL语句
        conn.commit()  # 提交事务
    conn.close()  # 关闭数据库连接

# 北京时间转换函数
def bj_time(timestamp):
    # 将时间戳转换为北京时间
    return datetime.utcfromtimestamp(timestamp / 1000).strftime('%Y-%m-%d %H:%M:%S')

# Binance API客户端
class BinanceAPI:
    base_url = "https://fapi.binance.com"  # Binance的基础API URL

    @staticmethod
    def get(endpoint, params=None):
        # 发送GET请求到Binance API
        response = requests.get(f"{BinanceAPI.base_url}{endpoint}", params=params)
        return response.json()  # 返回JSON格式的响应数据

# 任务1：获取资金费率并插入数据库
def funding_rate():
    # 获取BTC和ETH的资金费率数据
    btc_data = BinanceAPI.get("/fapi/v1/fundingRate", {"symbol": "BTCUSDT"})
    eth_data = BinanceAPI.get("/fapi/v1/fundingRate", {"symbol": "ETHUSDT"})

    # 准备SQL插入语句
    btc_sql = """INSERT INTO fundingrate(symbol, ts, fundingRate)
                 VALUES ("BTCUSDT", %s, %s)"""
    eth_sql = """INSERT INTO fundingrate(symbol, ts, fundingRate)
                 VALUES ("ETHUSDT", %s, %s)"""

    # 执行SQL插入操作
    execute_query(btc_sql, (btc_data[-1]['fundingTime'], btc_data[-1]['fundingRate']))
    execute_query(eth_sql, (eth_data[-1]['fundingTime'], eth_data[-1]['fundingRate']))

# 任务2：获取未平仓合约数并插入数据库
def open_interest():
    # 获取BTC和ETH的未平仓合约数数据
    btc_data = BinanceAPI.get("/fapi/v1/openInterest", {"symbol": "BTCUSDT"})
    eth_data = BinanceAPI.get("/fapi/v1/openInterest", {"symbol": "ETHUSDT"})

    # 准备SQL插入语句
    btc_sql = """INSERT INTO openInterest(symbol, ts, openInterest)
                 VALUES ("BTCUSDT", %s, %s)"""
    eth_sql = """INSERT INTO openInterest(symbol, ts, openInterest)
                 VALUES ("ETHUSDT", %s, %s)"""

    # 执行SQL插入操作
    execute_query(btc_sql, (btc_data['time'], btc_data['openInterest']))
    execute_query(eth_sql, (eth_data['time'], eth_data['openInterest']))

# 任务3：获取长短比并插入数据库
def long_short_ratio(interval):
    # 获取BTC和ETH的长短比数据
    btc_data = BinanceAPI.get("/futures/data/takerlongshortRatio", {
        "symbol": "BTCUSDT", "period": interval
    })
    eth_data = BinanceAPI.get("/futures/data/takerlongshortRatio", {
        "symbol": "ETHUSDT", "period": interval
    })

    # 准备SQL插入语句
    btc_sql = f"""INSERT INTO longshortratio{interval}(symbol, ts, buyVol, sellVol, buySellRatio)
                  VALUES ("BTCUSDT", %s, %s, %s, %s)"""
    eth_sql = f"""INSERT INTO longshortratio{interval}(symbol, ts, buyVol, sellVol, buySellRatio)
                  VALUES ("ETHUSDT", %s, %s, %s, %s)"""

    # 执行SQL插入操作
    execute_query(btc_sql, (btc_data[-1]['timestamp'], btc_data[-1]['buyVol'], btc_data[-1]['sellVol'], btc_data[-1]['buySellRatio']))
    execute_query(eth_sql, (eth_data[-1]['timestamp'], eth_data[-1]['buyVol'], eth_data[-1]['sellVol'], eth_data[-1]['buySellRatio']))

# 定时任务调度
def schedule_jobs():
    # 每天0点、8点和16点1分执行资金费率任务
    schedule.every().day.at("00:01").do(funding_rate)
    schedule.every().day.at("08:01").do(funding_rate)
    schedule.every().day.at("16:01").do(funding_rate)

    # 每分钟的15秒执行未平仓合约数任务
    schedule.every().minute.at(":15").do(open_interest)
    schedule.every().minute.at(":25").do(open_interest)
    schedule.every().minute.at(":35").do(open_interest)
    schedule.every().minute.at(":45").do(open_interest)
    schedule.every().minute.at(":55").do(open_interest)

    # 每分钟的15秒执行长短比任务，周期为5m, 15m, 30m等
    intervals = ["5m", "15m", "30m", "1h", "2h", "4h", "6h", "12h", "1d"]
    for interval in intervals:
        schedule.every().minute.at(":15").do(long_short_ratio, interval=interval)

# 启动任务调度
def run():
    schedule_jobs()  # 设置定时任务
    while True:
        schedule.run_pending()  # 执行所有待处理任务
        time.sleep(1)  # 每秒检查一次任务是否到期

if __name__ == "__main__":
    run()  # 运行定时任务调度