# coding=utf-8
import ujson
from binance.websocket.spot.websocket_client import SpotWebsocketClient as WebsocketClient
import time
import requests
from loguru import logger
import datetime
import pymysql
import math

g_prices = {}
g_dbif = None
g_lastts = 0
# 正在设置一个与币安的现货 Websocket API 交互以获取加密货币价格数据的环境。它还包括用于处理日志记录、发出 HTTP 请求以及与 MySQL 数据库交互的模块。以下是导入和初始化的细分：
# ujson：快速的JSON编码器和解码器。
# SpotWebsocketClient：币安用于现货交易的 WebSocket 客户端。
# time：用于时间相关功能的模块。
# requests：用于发出请求的 HTTP 库。
# logger：Python 的日志记录库。
# datetime：用于操作日期和时间的模块。
# pymysql：MySQL 客户端库。
# math：提供数学函数的模块。
# 该脚本初始化全局变量 、 和 。 似乎用于存储价格数据、与 MySQL 数据库交互以及存储上次操作的时间戳。g_prices g_dbif g_lastts g_pricesg_dbifg_lastts
def get_day60_rise(day, prices):
    total = 0
    cnt = 0
    for i in range(60):
        if str(day) in prices:
            cur_price = prices[str(day)]
            day = str(day - 3600 * 24)
            if day in prices:
                prev_price = prices[day]
                try:
                    #print(((cur_price-prev_price)/prev_price), day, cur_price, prev_price)
                    total += (((cur_price-prev_price)/prev_price))
                    cnt += 1
                except:
                    pass
                # print(day, total, cnt)
            day = int(day)
    return total
# 此函数“get_day60_rise”根据提供的价格数据计算过去 60 天的价格上涨百分比。以下是其工作原理的细分：
# -**参数**：
#  - 'day'：需要计算价格上涨的当天。
#  - 'prices'：包含价格数据的字典，其中键是时间戳，值是相应的价格。
# -**功能性**：
#  - 它初始化变量“total”和“cnt”，以跟踪总价格上涨和考虑的天数。
#  - 它从给定的“日期”向后迭代 60 天。
#  - 对于范围内的每一天，它会检查当天的价格数据是否在“价格”字典中可用。
#  - 如果当天和前一天的价格数据可用，它会计算价格上涨的百分比并将其添加到“总计”中。
#  - 它为每个有效的价格数据条目递增“cnt”变量。
#  - 最后，它返回过去 60 天的总百分比涨幅。
# 此函数似乎可用于分析特定时期的价格趋势
def get_days_rise(day, maxdays, prices):
    total = 0
    cnt = 0
    for i in range(maxdays):
        if str(day) in prices:
            cur_price = prices[str(day)]
            day = str(day - 3600 * 24)
            if day in prices:
                prev_price = prices[day]
                try:
                    #print(((cur_price-prev_price)/prev_price), day, cur_price, prev_price)
                    total += (((cur_price-prev_price)/prev_price))
                    cnt += 1
                except:
                    pass
                # print(day, total, cnt)
            day = int(day)
    print("get_days_rise", day, maxdays,cnt, total)
    return total
# “get_days_rise”函数是先前“get_day60_rise”函数的扩展。其工作原理如下：
# -**参数**：
#  - 'day'：需要计算价格上涨的当天。
#  - 'maxdays'：计算价格上涨时要考虑的最大天数。
#  - 'prices'：包含价格数据的字典，其中键是时间戳，值是相应的价格。
# -**功能性**：
#  - 它初始化变量“total”和“cnt”，以跟踪总价格上涨和考虑的天数。
#  - 它从给定的“day”向后循环到“maxdays”的天数范围。
#  - 对于范围内的每一天，它会检查当天的价格数据是否在“价格”字典中可用。
#  - 如果当天和前一天的价格数据可用，它会计算价格上涨的百分比并将其添加到“总计”中。
#  - 它为每个有效的价格数据条目递增“cnt”变量。
#  - 最后，它返回指定天数内的总百分比增长。
# 此函数通过允许计算由“maxdays”参数指定的自定义天数范围内的价格上涨来提供灵活性。
def append_jzr_day60(dbif, day, price, day60_rise, day7_rise, day30_rise, day90_rise):
    dbif.append_jzr60(day, price, day60_rise, day7_rise, day30_rise, day90_rise)
# “append_jzr_day60”功能似乎是将数据附加到数据库的更大系统的一部分。以下是它的作用的细分：
# -**参数**：
#  - 'dbif'：与数据库交互的接口。
#  - 'day'：当前日期或时间戳。
#  - 'price'：与当天对应的价格值。
#  - “day60_rise”：过去 60 天内价格上涨的百分比。
#  - “day7_rise”：过去 7 天内价格上涨的百分比。
#  - “day30_rise”：过去 30 天内价格上涨的百分比。
#  - “day90_rise”：过去 90 天内价格上涨的百分比。
# -**功能性**：
#  - 它在 'dbif' 对象上调用方法 'append_jzr60'，传递提供的参数。
#  - 此方法可能负责将数据追加或存储在数据库表或集合中。
# 该功能似乎是管理和分析价格数据系统的一部分，专门计算和存储不同时间间隔（60天、7天、30天、90天）的价格上涨百分比，并将其保存到数据库中以供进一步分析或报告
def sync_jzr_day60(dbif, prices):
    for day in prices:
        print(day, prices[day])
        day60_rise = get_days_rise(int(day), 60, prices)
        day7_rise = get_days_rise(int(day), 7, prices)
        day30_rise = get_days_rise(int(day), 30, prices)
        day90_rise = get_days_rise(int(day), 90, prices)
        print(day, day60_rise)
        append_jzr_day60(dbif, day, prices[day], day60_rise, day7_rise, day30_rise, day90_rise)
# “sync_jzr_day60”功能似乎通过计算给定价格数据集中每天在不同时间间隔（60 天、7 天、30 天、90 天）内的价格上涨百分比来同步数据。以下是它的作用的细分：
# -**参数**：
#  - 'dbif'：与数据库交互的接口。
#  - 'prices'：包含每天价格数据的字典。
# -**功能性**：
#  - 它在“价格”字典中每天都在迭代。
#  - 对于每一天，它使用“get_days_rise”函数计算过去 60、7、30 和 90 天的价格上涨百分比。
#  - 然后，它调用“append_jzr_day60”函数将此数据以及相应的日期和价格附加到数据库中。
# 总体而言，此功能负责通过计算和存储不同时间间隔内价格上涨的百分比来与数据库同步价格数据
def check_jzr60_sync(dbif):
    return dbif.check_jzr60_sync()
# “check_jzr60_sync”功能，用于检查数据库中 jzr60 表的数据同步是否完成。以下是它的作用：
# -**参数**：
#  - 'dbif'：与数据库交互的接口。
# -**功能性**：
#  - 它可能会查询数据库以检查“jzr60”表的数据同步是否完成。
#  - 此函数的具体实现将取决于数据库接口 （'dbif'） 的详细信息，但通常它涉及查询数据库以确定是否已同步所有必要的数据。
# 此函数可用于验证“jzr60”表的数据同步过程是否完成，这对于确保应用程序使用的数据的完整性非常重要
def append_jzr60day(dbif, day, price, day60_rise, day7_rise, day30_rise, day90_rise):
    dbif.append_jzr60_day(day, price, day60_rise, day7_rise, day30_rise, day90_rise)
# “append_jzr60day”函数似乎将特定日期的数据附加到数据库中的“jzr60”表中。以下是它的作用：
# -**参数**：
#  - 'dbif'：与数据库交互的接口。
#  - 'day'：追加数据的特定日期。
#  - 'price'：与当天相关的价格。
#  - “day60_rise”：过去 60 天内的价格上涨。
#  - “day7_rise”：过去 7 天的价格上涨。
#  - “day30_rise”：过去 30 天的价格上涨。
#  - “day90_rise”：过去 90 天内的价格上涨。
# -**功能性**：
#  - 它可能会在数据库的“jzr60”表中插入一个新行，其中包含提供的数据。
#  - 该函数将使用“dbif”接口执行 SQL 查询以将数据插入数据库。
#  - 这允许存储不同时间间隔（60 天、7 天、30 天和 90 天）的历史价格上涨数据以及相应的日期和价格。
# 此功能对于维护不同时间段内价格上涨数据的历史记录至关重要
def append_jzr60(dbif, dayutc, price, day60_rise, day7_rise, day30_rise, day90_rise):
    dbif.append_jzr60(dayutc, price, day60_rise, day7_rise, day30_rise, day90_rise)
# “append_jzr60”函数似乎将特定日期的数据附加到数据库中可能名为“jzr60”的表中。以下是其目的和功能的细分：
# -**参数**：
#  - 'dbif'：与数据库交互的接口。
#  - 'dayutc'：附加数据的特定日期的时间戳（以 UTC 为单位）。
#  - 'price'：与当天相关的价格。
#  - “day60_rise”：过去 60 天内的价格上涨。
#  - “day7_rise”：过去 7 天的价格上涨。
#  - “day30_rise”：过去 30 天的价格上涨。
#  - “day90_rise”：过去 90 天内的价格上涨。
# -**功能性**：
#  - 它可能会在数据库的“jzr60”表中插入一个新行，其中包含提供的数据。
#  - 该函数将使用“dbif”接口执行 SQL 查询以将数据插入数据库。
#  - 这允许存储不同时间间隔（60 天、7 天、30 天和 90 天）的历史价格上涨数据以及相应的时间戳和价格。
# 此功能对于维护不同时间段内价格上涨数据的历史记录至关重要
def clean_jzr60day(dbif, clean_day):
    dbif.clean_jzr60_day(clean_day)
# “clean_jzr60day”函数可能用于从数据库的“jzr60”表中清理或删除与特定日期相关的数据。以下是它的作用：
# - ** 参数 **：
# - 'dbif'：与数据库交互的接口。
# - “clean_day”：要从“jzr60”表中清除或删除数据的日期的时间戳（以UTC为单位）。
# - ** 功能性 **：
# - 它可能通过'dbif'接口执行SQL查询，以从'jzr60'表中删除与提供的'clean_day'关联的数据。
# - 此操作通过删除过时或不相关的记录来帮助维护数据的完整性。
# 出于各种原因，可能需要清理特定日期的数据，例如更正错误或删除重复条目。此功能可确保数据库保持最新和准确
def handle_jzr_day60(dbif, day, dayutc, price, prices):
    day60_rise = get_days_rise(dayutc, 60, prices)
    day7_rise = get_days_rise(dayutc, 7, prices)
    day30_rise = get_days_rise(dayutc, 30, prices)
    day90_rise = get_days_rise(dayutc, 90, prices)
    print(dayutc, price, day, day60_rise)
    append_jzr60day(dbif, day, price, day60_rise, day7_rise, day30_rise, day90_rise)
    append_jzr60(dbif, dayutc, price, day60_rise, day7_rise, day30_rise, day90_rise)
    clean_day = dayutc - 3600 * 24 * 2
    clean_jzr60day(dbif, clean_day)
# “handle_jzr_day60”功能似乎用于管理与“jzr60”指标相关的数据的处理和存储，这可能表示 60 天的价格上涨。以下是它的作用的细分：
# -**参数**：
#  - 'dbif'：与数据库交互的接口。
#  - 'day'：处理数据的日期的时间戳。
#  - 'dayutc'：处理数据的当天的 UTC 时间戳。
#  - 'price'：与当天相关的价格。
#  - 'prices'：包含历史价格数据的字典。
# -**功能性**：
#  1. 使用“get_days_rise”函数计算 60 天、7 天、30 天和 90 天的价格上涨。
#  2. 打印 UTC 时间戳、价格和 60 天价格上涨，以便进行调试或监控。
#  3. 使用“append_jzr60day”功能将计算出的指标（'day60_rise'、'day7_rise'、'day30_rise'、'day90_rise'）附加到数据库。
#  4. 使用“append_jzr60”函数将相同的指标附加到数据库，但带有 UTC 时间戳 （'dayutc'）。
#  5. 使用“clean_jzr60day”功能清理当天 2 天（“clean_day”）的数据。
# 总体而言，此函数可确保计算出的价格上涨指标存储在特定日期和相应的 UTC 时间戳的数据库中。此外，它还会清理数据以保持数据库干净
class Arh99DbIf:
    def __init__(self, host="172.17.0.1", port=4423, user="root", password="2GS@bPYcgiMyL14A", dbname="btcdb"):
        self.conn = pymysql.connect(host=host, port=port, user=user, password=password, database=dbname, cursorclass=pymysql.cursors.DictCursor)
        print("init  arh99 db suceess!")
    # “Arh99DbIf”类似乎是与数据库交互的接口。以下是其结构的细分：
    # - ** 属性 **：
    # - 'conn'：此属性表示使用“pymysql.connect”方法与数据库的连接。它存储连接详细信息，例如主机、端口、用户名、密码、数据库名称和游标类。
    # - ** 方法 **：
    # - '__init__'：这是初始化
    # 'Arh99DbIf'
    # 类的构造函数方法。它采用多个参数来获取数据库连接详细信息（主机、端口、用户、密码、dbname），并使用“pymysql.connect”建立与数据库的连接。连接成功后，它会打印一条消息，指示初始化成功。
    # 总的来说，这个类充当MySQL数据库连接的包装器，允许代码库的其他部分轻松地与数据库进行交互
    def check_sync(self):
        synced = False
        with self.conn.cursor() as cursor:
            sql_query = "SELECT COUNT(id) FROM `arh99v3a`"
            cursor.execute(sql_query)
            result = cursor.fetchone()
            print(result)
            if result is not None:
                if "COUNT(id)" in result:
                    if result["COUNT(id)"] > 0:
                        synced = True
        self.conn.commit()
        #print("synced", synced)
        return synced
    # “check_sync”方法检查数据库表“arh99v2a”是否已同步。以下是其功能的细分：
    # - ** 方法签名 **：
    # - 'check_sync（self）'：此方法除“self”外不接受任何参数，表明它是“Arh99DbIf”类的实例方法。
    # - ** 功能性 **：
    # - 它将'synced'变量初始化为'False'，表示尚未确认同步。
    # - 在“with”语句中，它会打开一个光标来执行数据库操作。
    # - 它执行SQL查询，使用'COUNT（id）'函数计算'arh99v2a'表中的行数。
    # - 获取SQL查询的结果。
    # - 如果结果不是“None”，它会检查结果字典中是否存在键“COUNT（id）”，以及其值是否大于0。如果是这样，它会将“synced”设置为“True”。
    # - 它提交事务以应用游标所做的任何更改。
    # - 最后，它返回'synced'的值，指示同步是否已确认 （'True'） 或未 （'False'）。
    # 此方法提供了一种检查数据库表“arh99v2a”的同步状态的方法
    def append(self, day, price, arh99, arh99x):
        with self.conn.cursor() as cursor:
            sql_query = "SELECT COUNT(id) FROM `arh99v3a` WHERE unixdt=FROM_UNIXTIME(%s)"
            cursor.execute(sql_query, (int(day),))
            result = cursor.fetchone()
            #print(dt_utc)
            #print(result)
            if result is not None:
                if "COUNT(id)" in result:
                    if result["COUNT(id)"] > 0:
                        sql_update = 'UPDATE arh99v3a SET `arh99`=%s, `arh99x`=%s, `price`=%s, `unixdt`=FROM_UNIXTIME(%s)  WHERE unixdt=FROM_UNIXTIME(%s)'
                        print(sql_update)
                        cursor.execute(sql_update, (arh99, arh99x, price, int(day), int(day)))
                    else:
                        sql_insert = "INSERT INTO `arh99v3a` (`unixdt`, `price`, `arh99`, `arh99x`) VALUES (FROM_UNIXTIME(%s), %s, %s, %s)"
                        print(sql_insert)
                        cursor.execute(sql_insert, (day, price, arh99, arh99x))
        self.conn.commit()
    # “Arh99DbIf”类的“append”方法负责根据提供的参数添加或更新“arh99v2a”表中的记录。以下是其工作原理的解释：
    # - ** 方法签名 **：
    # - 'append（self， day， price， arh99， arh99x）'：此方法采用四个参数：
    # - 'day'：Unix格式的当天时间戳。
    # - 'price'：价格值。
    # - 'arh99'：arh99的值。
    # - 'arh99x'：arh99x的值。
    # - 'self'：此参数是指'Arh99DbIf'类本身的实例。
    # - ** 功能性 **：
    # - 在“with”语句中，它会打开一个光标来执行数据库操作。
    # - 它执行SQL查询以计算'arh99v2a'表中的行数，其中'unixdt' （Unix时间戳） 与提供的'day'匹配。
    # - 获取SQL查询的结果。
    # - 如果给定的“日期”有现有记录：
    # - 它构造一个SQL'UPDATE'语句，使用新值'arh99'、'arh99x'、'price'和'unixdt'更新现有记录。
    # - 'UPDATE'语句更新与提供的'day'匹配的记录的'arh99'、'arh99x'、'price'和'unixdt'字段。
    # - 如果给定的“日期”没有现有记录：
    # - 它构造一个SQL'INSERT'语句，将提供值为'day'、'price'、'arh99'和'arh99x'的新记录插入到'arh99v2a'表中。
    # - 'INSERT'语句在表中插入具有指定值的新记录。
    # - 执行SQL语句后，它会提交事务以应用游标所做的任何更改。
    # 此方法提供了根据提供的参数在“arh99v2a”表中添加新记录或更新现有记录的功能
    def append_day(self, day, price, arh99, arh99x):
        with self.conn.cursor() as cursor:
            sql_insert = "INSERT INTO `arh99v3aday` (`unixdt`, `price`, `arh99`, `arh99x`) VALUES (FROM_UNIXTIME(%s), %s, %s, %s)"
            print(sql_insert)
            cursor.execute(sql_insert, (day, price, arh99, arh99x))
        self.conn.commit()
    # “Arh99DbIf”类的“append_day”方法似乎与“append”方法具有类似的用途，但它专门在“arh99v2aday”表中插入了一条新记录。其工作原理如下：
    # - ** 方法签名 **：
    # - 'append_day（self， day， price， arh99， arh99x）'：此方法采用四个参数：
    # - 'day'：Unix格式的当天时间戳。
    # - 'price'：价格值。
    # - 'arh99'：arh99的值。
    # - 'arh99x'：arh99x的值。
    # - 'self'：此参数是指'Arh99DbIf'类本身的实例。
    # - ** 功能性 **：
    # - 在“with”语句中，它会打开一个光标来执行数据库操作。
    # - 它构造一个SQL'INSERT'语句，将提供值为'day'、'price'、'arh99'和'arh99x'的新记录插入到'arh99v2aday'表中。
    # - 'INSERT'语句在表中插入具有指定值的新记录。
    # - 执行SQL语句后，它会提交事务以应用游标所做的任何更改。
    # 此方法可用于专门将记录插入到“arh99v2aday”表中
    def clean_day(self, day):
        with self.conn.cursor() as cursor:
            sql_clean = "DELETE from arh99v3aday where unixdt<FROM_UNIXTIME(%s)"
            print(sql_clean)
            cursor.execute(sql_clean, (int(day),))
        self.conn.commit()
    # “Arh99DbIf”类中的“clean_day”方法负责从“arh99v2aday”表中删除“unixdt”值早于指定日期的记录。其工作原理如下：
    # - ** 方法签名 **：
    # - 'clean_day（self， day）'：此方法采用一个参数：
    # - 'day'：Unix格式的当天时间戳。
    # - ** 功能性 **：
    # - 在“with”语句中，它会打开一个光标来执行数据库操作。
    # - 它构造一个SQL'DELETE'语句，以从'arh99v2aday'表中删除'unixdt'值早于指定日期的记录。
    # - “DELETE”语句根据提供的条件从表中删除记录。
    # - 执行SQL语句后，它会提交事务以应用游标所做的任何更改。
    # 此方法可用于清理“arh99v2aday”表中的过时记录
    def check_jzr60_sync(self):
        synced = False
        with self.conn.cursor() as cursor:
            sql_query = "SELECT COUNT(id) FROM `jzr60v3a`"
            cursor.execute(sql_query)
            result = cursor.fetchone()
            print(result)
            if result is not None:
                if "COUNT(id)" in result:
                    if result["COUNT(id)"] > 0:
                        synced = True
        self.conn.commit()
        #print("synced", synced)
        return synced
    # “Arh99DbIf”类中的“check_jzr60_sync”方法旨在确定“jzr60v2a”表是否已同步。以下是其功能的细分：
    # - ** 方法签名 **：
    # - 'check_jzr60_sync（self）'：此方法不接受任何参数。
    # - ** 功能性 **：
    # - 它将布尔变量'synced'初始化为'False'，表示同步状态最初假定为未同步。
    # - 在'with'语句中，它会打开一个光标来执行SQL查询。
    # - 该方法构造一个SQL'SELECT'查询来计算'jzr60v2a'表中的记录数。
    # - 执行查询后，它使用'cursor.fetchone（）'获取结果。
    # - 如果结果不是“None”，而是包含键“COUNT（id）”，则检查计数是否大于“0”。如果是这样，它会将“synced”设置为“True”，表示表已同步。
    # - 最后，它提交光标所做的任何更改。
    # 此方法的目的是提供有关“jzr60v2a”表是否已同步的信息
    def append_jzr60(self, day, price, jzr60, jzr7, jzr30, jzr90):
        with self.conn.cursor() as cursor:
            sql_query = "SELECT COUNT(id) FROM `jzr60v3a` WHERE unixdt=FROM_UNIXTIME(%s)"
            cursor.execute(sql_query, (int(day),))
            result = cursor.fetchone()
            #print(dt_utc)
            #print(result)
            if result is not None:
                if "COUNT(id)" in result:
                    if result["COUNT(id)"] > 0:
                        sql_update = 'UPDATE jzr60v3a SET `jzr60`=%s,`jzr7`=%s,`jzr30`=%s,`jzr90`=%s,`price`=%s, `unixdt`=FROM_UNIXTIME(%s)  WHERE unixdt=FROM_UNIXTIME(%s)'
                        print(sql_update)
                        cursor.execute(sql_update, (jzr60, jzr7, jzr30, jzr90, price, int(day), int(day)))
                    else:
                        sql_insert = "INSERT INTO `jzr60v3a` (`unixdt`, `price`, `jzr60`, `jzr7`, `jzr30`, `jzr90`) VALUES (FROM_UNIXTIME(%s), %s, %s, %s, %s, %s)"
                        print(sql_insert)
                        cursor.execute(sql_insert, (day, price, jzr60, jzr7, jzr30, jzr90))
        self.conn.commit()
    # “Arh99DbIf”类中的“append_jzr60”方法负责附加与“jzr60v2a”表相关的数据。以下是对其功能的分析：
    # - ** 方法签名 **：
    # - 'append_jzr60（self， day， price， jzr60， jzr7， jzr30， jzr90）'：此方法采用以下参数：
    # - 'day'：表示日期的UNIX时间戳。
    # - 'price'：与当天相关的价格。
    # - 'jzr60'：JZR（60天上涨）值。
    # - 'jzr7'：JZR（7天上涨）值。
    # - 'jzr30'：JZR（30天上涨）值。
    # - 'jzr90'：JZR（90天上涨）值。
    # - ** 功能性 **：
    # - 该方法首先在“with”语句中初始化游标以执行 SQL 查询。
    # - 它构造一个SQL'SELECT'查询来计算指定日期的'jzr60v2a'表中的记录数。
    # - 执行查询后，它使用'cursor.fetchone（）'获取结果。
    # - 如果结果不是“None”，而是包含键“COUNT（id）”，则检查计数是否大于“0”。如果为true，则使用SQL“UPDATE”查询使用提供的值更新现有记录。否则，它将使用SQL“INSERT”查询插入具有所提供值的新记录。
    # - 最后，它提交光标所做的任何更改。
    # 此方法允许根据提供的参数附加或更新与数据库中的“jzr60v2a”表相关的数据
    def append_jzr60_day(self, day, price, jzr60, jzr7, jzr30, jzr90):
        with self.conn.cursor() as cursor:
            sql_insert = "INSERT INTO `jzr60v3aday` (`unixdt`, `price`, `jzr60`, `jzr7`, `jzr30`, `jzr90`) VALUES (FROM_UNIXTIME(%s), %s, %s, %s, %s, %s)"
            print(sql_insert)
            cursor.execute(sql_insert, (day, price, jzr60, jzr7, jzr30, jzr90))
        self.conn.commit()
    # “Arh99DbIf”类中的“append_jzr60_day”方法负责附加与“jzr60v2aday”表相关的数据。以下是对其功能的分析：
    # - ** 方法签名 **：
    # - 'append_jzr60_day（self， day， price， jzr60， jzr7， jzr30， jzr90）'：此方法采用以下参数：
    # - 'day'：表示日期的UNIX时间戳。
    # - 'price'：与当天相关的价格。
    # - 'jzr60'：JZR（60天上涨）值。
    # - 'jzr7'：JZR（7天上涨）值。
    # - 'jzr30'：JZR（30天上涨）值。
    # - 'jzr90'：JZR（90天上涨）值。
    # - ** 功能性 **：
    # - 该方法首先在“with”语句中初始化游标以执行 SQL 查询。
    # - 它构造一个SQL'INSERT'查询，以使用提供的值将新记录插入到'jzr60v2aday'表中。
    # - 构造查询后，它会打印SQL查询以进行调试。
    # - 然后，它使用提供的参数执行SQL“INSERT”查询。
    # - 最后，它提交光标所做的任何更改。
    # 此方法允许根据提供的参数附加与数据库中的“jzr60v2aday”表相关的新数据
    def clean_jzr60_day(self, day):
        with self.conn.cursor() as cursor:
            sql_clean = "DELETE from jzr60v3aday where unixdt<FROM_UNIXTIME(%s)"
            print(sql_clean)
            cursor.execute(sql_clean, (int(day),))
        self.conn.commit()
    # “Arh99DbIf”类中的“clean_jzr60_day”方法负责清理特定日期的“jzr60v2aday”表中的数据。以下是对其功能的分析：
    # - ** 方法签名 **：
    # - 'clean_jzr60_day（self， day）'：此方法采用单个参数：
    # - 'day'：UNIX时间戳，表示需要删除数据的前一天。
    # - ** 功能性 **：
    # - 该方法首先在'with'语句中创建一个游标来执行SQL查询。
    # - 它构造一个SQL'DELETE'查询，以从'jzr60v2aday'表中删除'unixdt'列值小于提供的日期的记录。
    # - 构造查询后，它会打印SQL查询以进行调试。
    # - 然后，它使用提供的参数执行SQL'DELETE'查询。
    # - 最后，它提交光标所做的任何更改。
    # 此方法允许根据提供的时间戳从特定日期的“jzr60v2aday”表中清理旧数据
    def check_ma730_sync(self):
        synced = False
        with self.conn.cursor() as cursor:
            sql_query = "SELECT COUNT(id) FROM `ma730v3a`"
            cursor.execute(sql_query)
            result = cursor.fetchone()
            print(result)
            if result is not None:
                if "COUNT(id)" in result:
                    if result["COUNT(id)"] > 0:
                        synced = True
        self.conn.commit()
        #print("synced", synced)
        return synced
    # “Arh99DbIf”类中的“check_ma730_sync”方法负责检查“ma730v2a”表是否同步。以下是其功能的细分：
    # - ** 方法签名 **：
    # - 'check_ma730_sync（self）'：此方法不接受任何参数。
    # - ** 功能性 **：
    # - 它首先将布尔变量“synced”初始化为“False”。
    # - 在'with'语句中，它创建一个游标来执行SQL查询。
    # - 它构造一个SQL'SELECT'查询来计算'ma730v2a'表中的行数。
    # - 执行查询后，它使用'cursor.fetchone（）'获取结果。
    # - 如果结果不是“None”，它会检查结果字典中是否存在键“COUNT（id）”，以及其值是否大于“0”。如果是这样，它会将“synced”设置为“True”。
    # - 它提交光标所做的任何更改。
    # - 最后，它返回'synced'的值，指示表是否同步。
    # 此方法提供了一种方法，通过检查“ma730v2a”表是否包含任何记录来确定它是否同步。如果是这样，则认为该表是同步的
    def append_ma730(self, day, price, ma730, ma365, ma200):
        with self.conn.cursor() as cursor:
            sql_query = "SELECT COUNT(id) FROM `ma730v3a` WHERE unixdt=FROM_UNIXTIME(%s)"
            cursor.execute(sql_query, (int(day),))
            result = cursor.fetchone()
            #print(dt_utc)
            #print(result)
            if result is not None:
                if "COUNT(id)" in result:
                    ma730x5 = ma730*5
                    if result["COUNT(id)"] > 0:
                        sql_update = 'UPDATE ma730v3a SET `ma730`=%s, `ma730x5`=%s, `ma365`=%s, `ma200`=%s, `price`=%s, `unixdt`=FROM_UNIXTIME(%s)  WHERE unixdt=FROM_UNIXTIME(%s)'
                        print(sql_update)
                        cursor.execute(sql_update, (ma730, ma730x5, ma365, ma200, price, int(day), int(day)))
                    else:
                        sql_insert = "INSERT INTO `ma730v3a` (`unixdt`, `price`, `ma730`, `ma730x5`, `ma365`, `ma200`) VALUES (FROM_UNIXTIME(%s), %s, %s, %s, %s, %s)"
                        print(sql_insert)
                        cursor.execute(sql_insert, (day, price, ma730, ma730x5, ma365, ma200))
        self.conn.commit()
    # “Arh99DbIf”类中的“append_ma730”方法负责将与730天移动平均线相关的数据附加到数据库。以下是其功能的细分：
    # - ** 方法签名 **：
    # - 'append_ma730（self， day， price， ma730， ma365， ma200）'：此方法采用表示日期（UNIX时间戳格式）、价格、730天移动平均线、365天移动平均线和200天移动平均线的参数。
    # - ** 功能性 **：
    # - 它首先创建一个游标，以便在“with”语句中执行 SQL 查询。
    # - 该方法构造一个SQL“SELECT”查询，以计算“ma730v2a”表中“unixdt”列与给定日期匹配的行数。
    # - 执行查询后，它使用'cursor.fetchone（）'获取结果。
    # - 如果结果不是“None”，则检查结果字典中是否存在键“COUNT（id）”。
    # - 它将“ma730x5”计算为“ma730”值的五倍。
    # - 如果记录计数大于'0'，则构造SQL'UPDATE'语句，使用提供的数据更新现有记录。
    # - 如果给定日期没有记录，它将构造一个SQL'INSERT'语句，以插入包含所提供数据的新记录。
    # - 更改将提交到数据库，并且方法完成。
    # 此方法允许将与730天移动平均线相关的数据添加到数据库中的“ma730v2a”表中。如果给定日期的记录已存在，则会更新现有记录;
    # 否则，它会插入一个新的记录
    def append_ma730_day(self, day, price, ma730, ma365, ma200):
        with self.conn.cursor() as cursor:
            ma730x5 = ma730*5
            sql_insert = "INSERT INTO `ma730v3aday` (`unixdt`, `price`, `ma730`, `ma730x5`, `ma365`, `ma200`) VALUES (FROM_UNIXTIME(%s), %s, %s, %s, %s, %s)"
            print(sql_insert)
            cursor.execute(sql_insert, (day, price, ma730, ma730x5, ma365, ma200))
        self.conn.commit()
    # “Arh99DbIf”类中的“append_ma730_day”方法负责将与730天移动平均线相关的每日数据附加到数据库。以下是其功能的细分：
    # - ** 方法签名 **：
    # - 'append_ma730_day（self， day， price， ma730， ma365， ma200）'：此方法采用表示日期（UNIX时间戳格式）、价格、730天移动平均线、365天移动平均线和200天移动平均线的参数。
    # - ** 功能性 **：
    # - 它首先创建一个游标，以便在“with”语句中执行 SQL 查询。
    # - 它将“ma730x5”计算为“ma730”值的五倍。
    # - 它构造一个SQL'INSERT'语句，将新记录插入到包含所提供数据的'ma730v2aday'表中。
    # - 打印SQL查询以进行调试。
    # - 该方法使用'cursor.execute（）'使用提供的数据执行SQL'INSERT'语句。
    # - 更改将提交到数据库，并且方法完成。
    # 此方法允许将与730天移动平均线相关的每日数据添加到数据库中的“ma730v2aday”表中。每次调用此方法都会添加一条新记录，表示当天的数据
    def clean_ma730_day(self, day):
        with self.conn.cursor() as cursor:
            sql_clean = "DELETE from ma730v3aday where unixdt<FROM_UNIXTIME(%s)"
            print(sql_clean)
            cursor.execute(sql_clean, (int(day),))
        self.conn.commit()
    # “Arh99DbIf”类中的“clean_ma730_day”方法负责从数据库中清理与730天移动平均线相关的每日数据。以下是其功能的概述：
    # - ** 方法签名 **：
    # - 'clean_ma730_day（self， day）'：此方法采用参数'day'，表示截止日（采用UNIX时间戳格式）。“ma730v2aday”表中时间戳早于此截止日期的所有记录都将被删除。
    # - ** 功能性 **：
    # - 它首先创建一个游标，以便在“with”语句中执行 SQL 查询。
    # - 它构造一个SQL'DELETE'语句，以从'ma730v2aday'表中删除UNIX时间戳 （'unixdt'） 早于提供的'day'的记录。
    # - 打印SQL查询以进行调试。
    # - 该方法使用'cursor.execute（）'使用提供的数据执行SQL'DELETE'语句。
    # - 更改将提交到数据库，并且方法完成。
    # 此方法允许从数据库的“ma730v2aday”表中删除与730天移动平均线相关的过时每日数据
def get_history_price(dbif):
    global g_prices
    response_price = requests.get(
        "https://data.nasdaq.com/api/v3/datatables/QDL/BCHAIN?code=MKPRU;api_key=FZqXog4sR-b7cYnXcRVV")
    if response_price.status_code == 200:
        # print(response_price.content)
        priceweb = ujson.loads(response_price.content)
        if "datatable" in priceweb:
            priceset = priceweb["datatable"]
            if "data" in priceset:
                pricedata = priceset["data"]
                for price in pricedata:
                    daystr = price[1]
                    p = price[2]
                    dayutc = time.mktime(time.strptime(daystr, "%Y-%m-%d"))
                    g_prices[str(int(dayutc))] = float(p)
    return g_prices
# “get_history_price”函数似乎从纳斯达克数据集中获取历史比特币价格，并将其存储在全局变量“g_prices”中。以下是其功能的细分：
# - **功能签名**：
#  - 'get_history_price（dbif）'：此函数采用参数 'dbif'，该参数在函数中似乎未使用。它获取历史价格数据并返回它。
# -**功能性**：
#  - 它向纳斯达克 API 端点发送 GET 请求以获取比特币市场价格数据。
#  - 如果响应状态代码为 200（表示成功），则使用 'ujson.loads' 将 JSON 响应解析为 Python 字典。
#  - 它从解析的 JSON 响应中提取历史价格数据。
#  - 对于每个价格条目，它提取日期和价格，将日期转换为 UNIX 时间戳，并将价格存储在“g_prices”字典中，并将时间戳作为键。
#  - 最后，它返回包含历史价格数据的“g_prices”字典。
# 总体而言，此函数从纳斯达克 API 检索历史比特币价格数据，并将其存储在全局变量中以供进一步处理或使用
def get_history_price2(dbif):
    global g_prices
    #pricedict = {}
    dayt = time.gmtime()
    daystr = time.strftime("%Y", dayt)
    year = int(daystr)
    end_year = year
    while True:
        url = ""
        if end_year != year:
            start_year = end_year
            url = "https://data.messari.io/api/v1/assets/bitcoin/metrics/price/time-series?start="
        else:
            url = "https://data.messari.io/api/v1/assets/bitcoin/metrics/price/time-series?after=" + str(
                year) + "-01-01&order=descending"

        if end_year != year:
            url = url + str(start_year) + "-01-01&end=" + str(end_year) + "-12-31&order=descending"
        header_set = {}
        header_set["x-messari-api-key"] = "aH2pyj5i4QGo1k1gLxXEbIJ5RJr+FYKLEWk6cRT6RuSc6lRY"
        # header_set["Content-Type"] = "application/json"
        print(header_set, url)
        response_price = requests.get(url, headers=header_set)
        # print(response_price)
        if response_price.status_code == 200:
            # print(response_price.content)
            priceweb = ujson.loads(response_price.content)
            if "data" in priceweb:
                priceset = priceweb["data"]
                if "values" in priceset:
                    valueset = priceset["values"]
                    if valueset is not None:
                        for supply in valueset:
                            dayutc = int(supply[0] / 1000)
                            s = supply[1]
                            ret_time = time.gmtime(dayutc)
                            ret_daystr = time.strftime("%d %b %Y", ret_time)
                            ret_dayutc = int(time.mktime(time.strptime(ret_daystr, "%d %b %Y")))
                            g_prices[str(ret_dayutc)] = float(s)
                            # self.pricedict[str(ret_dayutc)] = float(s)
                            # print(s, dayutc, pricedict[str(dayutc)])
                            # break
                    else:
                        break
        else:
            break
        end_year -= 1
        time.sleep(2)
    #print(self.pricedict)
    #return self.pricedict
    get_history_price(dbif);
    return g_prices
# “get_history_price2”函数似乎从 Messari API 获取历史比特币价格并将其存储在“g_prices”全局变量中。以下是其功能的细分：
# - **功能签名**：
#  - 'get_history_price2（dbif）'：此函数采用参数 'dbif'，该参数在函数中似乎也未使用。它获取历史价格数据并返回它。
# -**功能性**：
#  - 它初始化一些与时间相关的变量，以获取当前年份。
#  - 它构造用于从 Messari API 获取历史价格数据的 URL。
#  - 它向 Messari API 端点发送 GET 请求，以获取比特币价格时间序列数据。
#  - 如果响应状态代码为 200（表示成功），则使用 'ujson.loads' 将 JSON 响应解析为 Python 字典。
#  - 它从解析的 JSON 响应中提取历史价格数据。
#  - 对于每个价格条目，它提取日期，将时间戳转换为人类可读的格式，然后将其转换回 UNIX 时间戳。然后，它将价格存储在“g_prices”字典中，并将时间戳作为键。
#  - 该过程每年继续进行，直到循环结束。
#  - 最后，它返回包含历史价格数据的“g_prices”字典。
# 此函数将来自 Messari API 的数据和现有的“get_history_price”函数组合在一起，并使用来自 Messari 的其他数据更新“g_prices”字典
def get_coin_days(day):
    birthday = time.mktime(time.strptime("2009-01-03", "%Y-%m-%d"))
    days = (int(day) - birthday)/3600/24
    #print(day, birthday, days)
    return days
# “get_coin_days”函数计算自比特币诞生（2009 年 1 月 3 日）到给定日期的天数。
# - **功能签名**：
#  - 'get_coin_days（day）'：此函数采用参数 'day'，该参数应为表示特定日期的 UNIX 时间戳。
# -**功能性**：
#  - 它使用比特币发布日期的 UNIX 时间戳 2009 年 1 月 3 日初始化“birthday”变量。
#  - 它计算比特币的给定“日”和“生日”之间经过的秒数。
#  - 它通过除以一天中的秒数 （'3600 * 24'） 将总秒数转换为天数。
#  - 最后，它将计算出的天数作为浮点数返回，表示自比特币诞生以来的小数天数。
def get_coin_exp(days):
    try:
        temp = 5.84*math.log10(days)-17.01
        #print("temp", temp, math.log10(days), days)
        exp = math.pow(10,temp)
        return exp
    except:
        return 0
# “get_coin_exp”函数使用比特币创造者中本聪提出的指数增长模型，根据比特币诞生以来的天数来估计存在的比特币数量。
# - **功能签名**：
#  - 'get_coin_exp（days）'：此函数采用参数“days”，表示自比特币推出以来的天数。
# -**功能性**：
#  - 它使用公式“5.84 * log10（days） - 17.01”计算指数“temp”。
#  - 它将 10 提高到 'temp' 的幂，以计算比特币的估计数量 （'exp'）。
#  - 如果在计算过程中发生任何错误，则返回 0 作为结果。
#  - 它返回计算出的估计比特币数量。
# 该函数根据中本聪早期提出的指数增长模型估计比特币的数量
def cal_day200_price(prices, day):
    total = 0
    cnt = 0
    for i in range(200):
        if day in prices:
            total += prices[day]
            cnt += 1
            #print(day, total, cnt)
        day = str(int(day) - 3600 * 24)

    if cnt > 0:
        return total/cnt
    return 0
# 函数“cal_day200_price（prices， day）”计算比特币在 200 天内的平均价格。
# - **功能签名**：
#  - 'cal_day200_price（prices， day）'：此函数采用两个参数：
#  - 'prices'：包含比特币历史价格的字典。
#  - 'day'：需要计算平均价格的当天。
# -**功能性**：
#  - 它初始化变量“total”和“cnt”，分别存储价格总和和天数。
#  - 它在 200 天的范围内进行迭代，在每次迭代中将“天”减少一天。
#  - 对于每一天，如果“价格”字典中提供了当天的价格，则会将其添加到“总计”中并递增“cnt”。
#  - 循环后，它通过将“总计”除以“cnt”来计算平均价格。
#  - 如果 200 天内的任何一天没有可用的价格，则返回 0 作为平均价格。
#  - 否则，它将返回计算出的平均价格
def cal_arh99(prices, day, price):
    day200 = cal_day200_price(prices, day)
    #print("day200", day200)
    days = get_coin_days(day)
    #print("days", days)
    exp = get_coin_exp(days)
    #print("exp", exp, price)
    try:
        arh99 = (float(price)/day200)*(float(price)/exp)
        arh99x = (day200/float(price))*(exp/float(price))*3
    except:
        arh99 = 0
        arh99x = 0
    #print("arh99", arh99)
    print("cal_arh99", day, price, arh99, arh99x)
    return arh99, arh99x
# 函数“cal_arh99（prices， day， price）”计算比特币给定日期和价格的 ARH99 和 ARH99x 值。
# - **功能签名**：
#  - 'cal_arh99（prices， day， price）'：此函数采用三个参数：
#  - 'prices'：包含比特币历史价格的字典。
#  - 'day'：需要计算 ARH99 和 ARH99x 值的当前日期。
#  - 'price'：比特币在给定日期的价格。
# -**功能性**：
#  - 它首先使用“cal_day200_price（）”函数计算比特币的 200 天平均价格。
#  - 然后，它使用“get_coin_days（）”函数计算比特币诞生以来的天数。
#  - 接下来，它使用“get_coin_exp（）”函数计算比特币的预期价格。
#  - 然后，它使用提供的公式计算 ARH99 和 ARH99x 值：
#  - 'arh99 = （价格 / day200） * （价格 / exp）'
#  - 'arh99x = （day200 / 价格） * （exp / 价格） * 3'
#  - 如果在计算过程中出现任何错误（例如，除以零），则将“arh99”和“arh99x”都设置为0。
#  - 最后，它打印计算值并返回 'arh99' 和 'arh99x'
def check_sync(dbif):
    return dbif.check_sync()
# “check_sync（dbif）”函数检查与提供的“dbif”对象关联的数据库表是否同步。以下是其功能的细分：
# - **功能签名**：
#  - 'check_sync（dbif）'：此函数采用单个参数：
#  - 'dbif'：表示数据库接口的对象。
# -**功能性**：
#  - 它调用提供的 'dbif' 对象的 'check_sync（）' 方法，该方法可能检查数据库中的特定表是否同步。
#  - 该方法返回一个布尔值，指示同步是否完成 （'True'） 或未完成 （'False'）。
#  - 最后，该函数返回此布尔值。
# 在“dbif”对象中实际实现“check_sync（）”方法将涉及查询数据库以检查同步指示器，例如是否存在某些表示同步过程完成的记录或标志
def append_arh99(dbif, day, price, arh99, arh99x):
    dbif.append(day, price, arh99, arh99x)
# 'append_arh99（dbif， day， price， arh99， arh99x）' 函数用于通过提供的 'dbif' 对象将与 ARH99 和 ARH99X 值相关的数据附加到数据库中。以下是其功能的细分：
# - **功能签名**：
#  - 'append_arh99（dbif， day， price， arh99， arh99x）'：此函数采用五个参数：
#  - 'dbif'：表示数据库接口的对象。
#  - 'day'：计算 ARH99 和 ARH99X 值的日期。
#  - 'price'：与所提供日期相关的价格。
#  - 'arh99'：计算出的 ARH99 值。
#  - 'arh99x'：计算出的 ARH99X 值。
# -**功能性**：
#  - 它调用提供的 'dbif' 对象的 'append（）' 方法，在数据库中插入或更新 ARH99 和 ARH99X 值。
#  - 'append（）' 方法可能会执行 SQL 查询，以便在数据库中不存在指定日期的数据时插入新记录，或者更新现有记录（如果存在）。
#  - 传递给 'append（）' 方法的参数包括 day、price、ARH99 和 ARH99X 值。
#  - 将数据追加到数据库后，将提交更改。
# 在“dbif”对象中实际实现“append（）”方法将涉及执行 SQL 查询以与数据库交互并相应地插入或更新 ARH99 和 ARH99X 值。
def sync_arh99(dbif, prices):
    for day in prices:
        print(day, prices[day])
        arh99, arh99x = cal_arh99(prices, int(day), prices[day])
        print(day, arh99, arh99x)
        append_arh99(dbif, day, prices[day], arh99, arh99x)
# “sync_arh99（dbif， prices）”功能似乎将 ARH99 和 ARH99X 数据与提供的价格数据同步。其工作原理如下：
# - **功能签名**：
#  - 'sync_arh99（dbif， prices）'：此函数采用两个参数：
#  - 'dbif'：表示数据库接口的对象。
#  - 'prices'：包含不同日期价格数据的字典。
# -**功能性**：
#  - 它在“价格”字典中每天都会迭代。
#  - 对于每天，它使用“cal_arh99（）”函数计算 ARH99 和 ARH99X 值。
#  - 'cal_arh99（）' 函数根据特定日期的价格数据计算这些值。
#  - 计算完成后，它会调用 'append_arh99（）' 函数，使用提供的 'dbif' 对象将 day、price、ARH99 和 ARH99X 值附加到数据库中。
#  - 在附加之前，它会打印出日期和相关价格，以及计算出的 ARH99 和 ARH99X 值，以便进行调试或监控。
# 此功能实质上是将数据库中的 ARH99 和 ARH99X 数据与提供的价格数据同步，确保数据库反映最新的计算值
def append_arh99day(dbif, day, price, arh99, arh99x):
    dbif.append_day(day, price, arh99, arh99x)
# 'append_arh99day（dbif， day， price， arh99， arh99x）' 函数似乎将特定日期的 ARH99 和 ARH99X 数据附加到数据库中。其工作原理如下：
# - **功能签名**：
#  - 'append_arh99day（dbif， day， price， arh99， arh99x）'：此函数采用五个参数：
#  - 'dbif'：表示数据库接口的对象。
#  - 'day'：追加 ARH99 和 ARH99X 数据的日期。
#  - 'price'：指定日期的价格。
#  - 'arh99'：指定日期的计算 ARH99 值。
#  - 'arh99x'：指定日期的计算值 ARH99X。
# -**功能性**：
#  - 它调用 'dbif' 对象的 'append_day（）' 方法，传递 'day'、'price'、'arh99' 和 'arh99x' 值作为参数。
#  - “append_day（）”方法应处理将数据插入到与 ARH99 值关联的数据库表中。
#  - 此函数实质上是将指定日期的 ARH99 和 ARH99X 数据附加到数据库接口对象的任务委托给数据库接口对象。
# 此函数可用于每天或特定时间间隔将 ARH99 和 ARH99X 数据附加到数据库
def clean_arh99day(dbif, day):
    dbif.clean_day(day)
# “clean_arh99day（dbif， day）”功能似乎从数据库中清除了特定日期的 ARH99 和 ARH99X 数据。其工作原理如下：
# - **功能签名**：
#  - 'clean_arh99day（dbif， day）'：此函数采用两个参数：
#  - 'dbif'：表示数据库接口的对象。
#  - 'day'：清理 ARH99 和 ARH99X 数据的日期。
# -**功能性**：
#  - 它调用 'dbif' 对象的 'clean_day（）' 方法，将 'day' 值作为参数传递。
#  - “clean_day（）”方法应处理从数据库表中删除指定日期的 ARH99 和 ARH99X 数据。
#  - 该函数实质上是将清理指定日期的 ARH99 和 ARH99X 数据的任务委托给数据库接口对象。
# 此功能可用于从数据库中删除过时或不必要的 ARH99 和 ARH99X 数据，以保持数据存储的高效和最新。
def arh99_handler(message):
    global g_prices
    global g_dbif
    global g_lastts
    coin_data = message["data"]
    #coin_symbol = coin_data["s"]
    coin_ts = int(coin_data["E"])
    coin_price = float(coin_data["c"])
    #print((coin_ts/1000), int((coin_ts/1000)%60))
    if int((coin_ts/1000)%60) == 0:
        #if coin_ts / 1000 / 60 != g_lastts:
        if coin_ts/1000 - g_lastts >= 15:
            #print(coin_ts, coin_price)
            coin_ts2 = time.gmtime(coin_ts/1000)
            daystr = time.strftime("%d %b %Y", coin_ts2)
            print(daystr)
            dayutc = int(time.mktime(time.strptime(daystr, "%d %b %Y")))
            g_prices[str(dayutc)] = coin_price
            arh99, arh99x = cal_arh99(g_prices, dayutc, coin_price)
            print(dayutc, coin_price, arh99, arh99x)
            append_arh99day(g_dbif, coin_ts/1000, coin_price, arh99, arh99x)
            append_arh99(g_dbif, dayutc, coin_price, arh99, arh99x)
            clean_day = dayutc - 3600*24*2
            clean_arh99day(g_dbif, clean_day)

            handle_jzr_day60(g_dbif, coin_ts/1000, dayutc, coin_price, g_prices)
            handle_ma_day730(g_dbif, coin_ts / 1000, dayutc, coin_price, g_prices)
            g_lastts = coin_ts/1000
# “arh99_handler（message）”函数似乎用于处理与 ARH99 计算相关的传入消息。以下是其功能的细分：
# - **功能签名**：
#  - 'arh99_handler（message）'：此函数采用单个参数 'message'，该参数应为包含与 ARH99 计算相关的数据的字典。
# - **全局变量**：
#  - “g_prices”：存储一段时间内的价格数据。
#  - 'g_dbif'：表示数据库接口对象。
#  - “g_lastts”：跟踪上次处理的消息的时间戳。
# -**功能性**：
#  - 从传入消息中提取相关数据，例如时间戳 （'coin_ts'） 和价格 （'coin_price'）。
#  - 检查当前时间戳是否与新小时的开始相对应。
#  - 如果是新小时的开始（当时间戳的秒部分为 0 时）：
#  - 使用相应日期的新价格更新“g_prices”。
#  - 使用“cal_arh99（）”函数计算 ARH99 和 ARH99X 值。
#  - 使用“append_arh99day（）”和“append_arh99（）”函数将ARH99和ARH99X数据附加到数据库。
#  - 使用“clean_arh99day（）”函数清理过时的 ARH99 和 ARH99X 数据。
#  - 调用 'handle_jzr_day60（）' 和 'handle_马_day730（）' 函数来处理相关计算。
#  - 使用当前时间戳更新“g_lastts”。
# 此函数是处理 ARH99 相关消息、执行必要计算和相应更新数据库的主要入口点。
def start_arh99(dbif, prices):
    ws_client = WebsocketClient()
    ws_client.start()
    ws_client.instant_subscribe(
        stream=['btcusdt@miniTicker'],
        callback=arh99_handler,
    )
# “start_arh99”功能似乎启动了监控 ARH99 计算的实时数据的过程。下面是一个细分：
# - **功能签名**：
#  - 'start_arh99（dbif， prices）'：此函数采用两个参数：
#  - 'dbif'：用于数据存储的数据库接口对象。
#  - 'prices'：存储历史价格数据的字典。
# -**功能性**：
#  - 启动 WebSocket 客户端 （'ws_client'） 以连接到数据源。
#  - 启动 WebSocket 客户端。
#  - 订阅“btcusdt@miniTicker”流，该流可能会提供比特币兑 USDT 的实时价格更新。
#  - 指定 'arh99_handler' 作为回调函数，用于处理来自订阅流的传入消息。
# 通过启动 WebSocket 客户端并订阅相关流，此功能可以持续监控比特币的实时价格数据，并触发“arh99_handler”功能来处理传入的消息并相应地更新数据库
def arh99():
    global g_dbif
    g_dbif = Arh99DbIf()
    prices = get_history_price2(g_dbif)
    # print(prices)
    # list1 = []
    # list2 = []
    # for key, value in prices.items():
    #     old_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(int(key)))
    #     new_time = old_time[0:10] + " 08:00:00"
    #     new_key = int(time.mktime(time.strptime(new_time, "%Y-%m-%d %H:%M:%S")))
    #     list1.append(str(new_key))
    #     list2.append(value)
    # prices = dict(zip(list1, list2))
    #if not check_sync(g_dbif):
    if True:
        sync_arh99(g_dbif, prices)
    #if not check_jzr60_sync(g_dbif):
    if True:
        sync_jzr_day60(g_dbif, prices)
    #if not check_ma730_sync(g_dbif):
    if True:
        sync_ma_day730(g_dbif, prices)
    start_arh99(g_dbif, prices)
# “arh99”功能似乎是启动 ARH99 监控过程的入口点。下面是一个细分：
# - **功能签名**：
#  - 'arh99（）'：此函数不接受任何参数。
# -**功能性**：
#  - 使用“Arh99DbIf”实例初始化全局“g_dbif”变量，表示 ARH99 数据存储的数据库接口。
#  - 使用“get_history_price2”功能检索历史价格数据。
#  - 打印检索到的历史价格数据。
#  - 通过调用“sync_arh99”函数启动 ARH99 数据与数据库的同步。
#  - 通过调用“sync_jzr_day60”函数启动 JZR60 数据与数据库的同步。
#  - 通过调用“sync_马_day730”函数启动MA730数据与数据库的同步。
#  - 通过格数据的“start_a调用具有数据库接口和历史价rh99”函数来启动 ARH99 监控过程
#2-year ma multiplier
def get_day730_rise(day, prices):
    total = 0
    cnt = 0
    for i in range(730):
        if str(day) in prices:
            cur_price = prices[str(day)]
            total += cur_price
            cnt += 1
            day = str(day - 3600 * 24)
            day = int(day)
    if cnt > 0:
        return total/cnt
    print("get_day730_rise", day, total, cnt)
    return 0
# “get_day730_rise”函数计算 730 天内的平均价格上涨。
# -**参数**：
#  - 'day'：计算平均价格上涨的起始日期。
#  - 'prices'：包含历史价格数据的字典，其中键是时间戳，值是相应的价格。
# -**功能性**：
#  - 在给定“日”之前的 730 天范围内进行迭代。
#  - 检查“prices”字典中是否存在当天的价格。
#  - 如果价格存在，它会将价格添加到“总计”中，并递增“cnt”变量，该变量计算可用价格的天数。
#  - 在所有天数遍历后，它通过将价格总和除以天数 （'cnt'） 来计算平均价格上涨。
#  - 如果没有可用的价格 （'cnt == 0'），则返回 0。
#  - 打印调试信息，包括日期、价格总和以及可用价格的天数
def get_day365_rise(day, maxdays, prices):
    total = 0
    cnt = 0
    for i in range(maxdays):
        if str(day) in prices:
            cur_price = prices[str(day)]
            total += cur_price
            cnt += 1
            day = str(day - 3600 * 24)
            day = int(day)
    if cnt > 0:
        return total/cnt
    print("get_day365_rise", total, cnt)
    return 0
# “get_day365_rise”功能计算指定天数（最多 365 天）的平均价格上涨。
# -**参数**：
#  - 'day'：计算平均价格上涨的起始日期。
#  - “maxdays”：计算时要考虑的最大天数。
#  - 'prices'：包含历史价格数据的字典，其中键是时间戳，值是相应的价格。
# -**功能性**：
#  - 遍历“maxdays”范围，表示给定“day”之前的天数。
#  - 检查“prices”字典中是否存在当天的价格。
#  - 如果价格存在，它会将价格添加到“总计”中，并递增“cnt”变量，该变量计算可用价格的天数。
#  - 在所有天数遍历后，它通过将价格总和除以天数 （'cnt'） 来计算平均价格上涨。
#  - 如果没有可用的价格 （'cnt == 0'），则返回 0。
#  - 打印调试信息，包括价格总和以及可用价格的天数。
def append_ma_day730(dbif, day, price, day730_rise, day365_rise, day200_rise):
    dbif.append_ma730(day, price, day730_rise, day365_rise, day200_rise)
# “append_马_day730”函数似乎将与 730 天移动平均线相关的数据附加到数据库。
# -**参数**：
#  - 'dbif'：数据库接口对象的实例。
#  - 'day'：追加数据的日期的时间戳。
#  - 'price'：与当天相关的价格值。
#  - “day730_rise”：计算出过去 730 天内的平均价格涨幅。
#  - “day365_rise”：过去 365 天内计算出的平均价格涨幅。
#  - “day200_rise”：过去 200 天内计算出的平均价格涨幅。
# -**功能性**：
#  - 使用“dbif”对象将提供的数据追加到与 730 天移动平均线相关的数据库表中。
#  - 附加数据包括当天的时间戳（“天”）、相应的价格（“价格”）以及计算出的平均价格在 730、365 和 200 天内的上涨。
# 此函数看起来很简单，并且应该按预期工作，假设数据库接口 （'dbif'） 具有处理数据追加的方法。
def sync_ma_day730(dbif, prices):
    for day in prices:
        print(day, prices[day])
        day730_rise = get_day730_rise(int(day), prices)
        day365_rise = get_day365_rise(int(day), 365, prices)
        day200_rise = get_day365_rise(int(day), 200, prices)
        print(day, day730_rise)
        append_ma_day730(dbif, day, prices[day], day730_rise, day365_rise, day200_rise)
# “sync_ma_day730”函数似乎将与 730 天移动平均线相关的数据与数据库同步。
# -**参数**：
#  - 'dbif'：数据库接口对象的实例。
#  - 'prices'：包含历史价格数据的字典，其中键是时间戳，值是相应的价格值。
# -**功能性**：
#  - 在提供的“价格”字典中遍历每一天。
#  - 使用辅助函数计算过去 730 天 （'day730_rise'）、365 天 （'day365_rise'） 和 200 天 （'day200_rise'） 的平均价格上涨。
#  - 使用“append_ma_day730”函数将计算数据追加到数据库。
# 此功能应有效地将 730 天移动平均线数据与历史价格数据中每天的数据库同步。
def check_ma730_sync(dbif):
    return dbif.check_ma730_sync()
# “check_ma730_sync”功能显示，用于检查与730天移动平均线相关的数据是否与数据库同步。
# -**参数**：
#  - 'dbif'：数据库接口对象的实例。
# -**功能性**：
#  - 查询数据库接口对象，查看730日移动平均线相关数据是否同步。
#  - 返回一个布尔值，指示同步检查是否成功。
# 此函数允许您验证与 730 天移动平均线相关的数据是否是最新的并与数据库同步
def append_ma730day(dbif, day, price, day730_rise, day365_rise, day200_rise):
    dbif.append_ma730_day(day, price, day730_rise, day365_rise, day200_rise)
# “append_ma730day”函数似乎将与 730 天移动平均线相关的数据附加到数据库表中。
# -**参数**：
#  - 'dbif'：数据库接口对象的实例。
#  - 'day'：表示日期的 Unix 时间戳。
#  - 'price'：价格值。
#  - “day730_rise”：过去 730 天的价格上涨。
#  - “day365_rise”：过去 365 天内的价格上涨。
#  - “day200_rise”：过去 200 天的价格上涨。
# -**功能性**：
#  - 使用提供的数据在数据库表中插入 730 天移动平均线的新记录。
# 该功能负责将与 730 天移动平均线相关的每日数据附加到数据库中，确保存储历史价格信息以供分析和将来参考
def append_ma730(dbif, dayutc, price, day730_rise, day365_rise, day200_rise):
    dbif.append_ma730(dayutc, price, day730_rise, day365_rise, day200_rise)
# “append_ma730”函数似乎将与 730 天移动平均线相关的数据附加到数据库表中。
# -**参数**：
#  - 'dbif'：数据库接口对象的实例。
#  - 'dayutc'：表示日期的 Unix 时间戳。
#  - 'price'：价格值。
#  - “day730_rise”：过去 730 天的价格上涨。
#  - “day365_rise”：过去 365 天内的价格上涨。
#  - “day200_rise”：过去 200 天的价格上涨。
# -**功能性**：
#  - 使用提供的数据在数据库表中插入 730 天移动平均线的新记录。
# 此功能似乎是跟踪和分析不同时间段内价格走势的系统的一部分，特别关注 730 天的走势
def clean_ma730day(dbif, clean_day):
    dbif.clean_ma730_day(clean_day)
# “clean_ma730day”功能负责从数据库中清理与特定日期的 730 天移动平均线相关的数据。
# -**参数**：
#  - 'dbif'：数据库接口对象的实例。
#  - 'clean_day'：表示需要清理数据的日期的 Unix 时间戳。
# -**功能性**：
#  - 从数据库表中删除早于指定“clean_day”的 730 天移动平均线的记录。这有助于通过删除过时或不必要的数据来维护数据库
def handle_ma_day730(dbif, day, dayutc, price, prices):
    day730_rise = get_day730_rise(dayutc, prices)
    day365_rise = get_day365_rise(dayutc, 365, prices)
    day200_rise = get_day365_rise(dayutc, 200, prices)
    print(dayutc, price, day, day730_rise)
    append_ma730day(dbif, day, price, day730_rise, day365_rise, day200_rise)
    append_ma730(dbif, dayutc, price, day730_rise, day365_rise, day200_rise)
    clean_day = dayutc - 3600 * 24 * 2
    clean_ma730day(dbif, clean_day)
# “handle_ma_day730”函数计算并处理与特定日期的 730 天移动平均线相关的数据。
# -**参数**：
#  - 'dbif'：数据库接口对象的实例。
#  - 'day'：表示日期的 Unix 时间戳。
#  - 'dayutc'：表示 UTC 日期的 Unix 时间戳。
#  - 'price'：当天的价格值。
#  - 'prices'：包含不同日期价格数据的字典。
# -**功能性**：
#  - 使用“get_day730_rise”和“get_day365_rise”函数计算给定“dayUTC”的 730 天移动平均线、365 天移动平均线和 200 天移动平均线。
#  - 使用“append_ma730day”和“append_ma730”函数将计算出的移动平均数据附加到相应的数据库表中。
#  - 使用“clean_ma730day”功能清理数据库中的过时数据，以确保数据的完整性和效率
arh99()
# 此函数似乎处理与 ARH99（从比特币价格派生的指标）相关的数据同步、计算和附加到数据库的过程。arh99()
# 下面是该函数功能的简要概述：arh99()
# 它初始化数据库接口。
# 它使用该函数检索历史价格数据。get_history_price2()
# 它检查数据库中的 ARH99 数据是否需要同步。
# 如果需要同步，它会使用该功能同步 ARH99 数据。sync_arh99()
# 它检查数据库中 60 天的 JZR （Juzhen） 数据是否需要同步。
# 如果需要同步，它将使用该函数同步 60 天的 JZR 数据。sync_jzr_day60()
# 它检查数据库中的 730 天移动平均线 （MA730） 数据是否需要同步。
# 如果需要同步，它会使用该功能同步 MA730 数据。sync_ma_day730()
# 它启动 ARH99 websocket 客户端以侦听实时数据更新并使用该函数进行处理。arh99_handler()
# 该功能似乎协调了管理和更新与比特币价格及其衍生品相关的各种指标和数据点的整个过程

