2
Подписаться
319
Подписчики

Краткое обсуждение истории разработки индикатора тренда криптовалюты

Создано: 2025-06-23 16:08:06, Обновлено: 2025-06-24 09:54:54
comments   0
hits   516

Краткое обсуждение истории разработки индикатора тренда криптовалюты

В области технического анализа выявление четырёх основных паттернов ценовой структуры: «более высокие максимумы (HH)», «более высокие минимумы (HL)», «более низкие максимумы (LH)» и «более низкие минимумы (LL)» — является краеугольным камнем оценки направления рыночного тренда и потенциальных точек разворота. Эти паттерны интуитивно отражают динамический баланс рыночного спроса и предложения, а также преобладающие настроения (бычьи или медвежьи), обеспечивая объективную основу для принятия торговых решений.

Основные характеристики бычьего и медвежьего рынков

Краткое обсуждение истории разработки индикатора тренда криптовалюты

Бычий тренд: Более высокие максимумы и более высокие минимумы являются ключевыми индикаторами бычьего тренда. Более высокие максимумы возникают, когда пик цены превышает предыдущий, указывая на то, что покупатели толкают цены вверх, отражая силу рынка. Более высокие минимумы возникают, когда падение цены останавливается на уровне выше предыдущего падения, указывая на то, что рынок сохраняет восходящий импульс. В совокупности эти паттерны указывают на сильный восходящий тренд, который на графике отображается серией растущих пиков и впадин.

Медвежий тренд: Более низкие максимумы и более низкие минимумы указывают на медвежий тренд. Более низкие максимумы формируются, когда пик цены не достигает уровня предыдущего пика, что указывает на ослабление давления покупателей. Более низкие минимумы формируются, когда цены опускаются ниже предыдущего минимума, что отражает возросшее давление продавцов и слабость рынка. Эти паттерны важны для определения нисходящих трендов, которые на ценовом графике отображаются серией снижающихся пиков и впадин.

Необходимость количественной идентификации тренда

Рынок криптовалют характеризуется высокой волатильностью, круглосуточной торговлей и значительными трендами, определяемыми настроениями рынка. В таких условиях точное выявление трендовых моделей становится ещё важнее. Количественная оценка непрерывности «более высокие максимумы, более высокие минимумы» или «более низкие максимумы, более низкие минимумы» позволяет точнее определять рыночные тренды, обеспечивая объективную основу для принятия торговых решений.

Почему стоит выбрать платформу FMZ

Количественная платформа FMZ Inventor обеспечивает идеальную среду для разработки таких показателей:

Преимущество данных

  • Бесплатное предоставление исторических данных с крупнейших бирж
  • Полные данные K-line, охватывающие основные криптовалюты
  • Надежное качество данных и своевременные обновления

Среда разработки

  • Легкая и быстрая страница редактирования кода
  • Поддерживает несколько языков программирования, таких как Python.
  • Встроенная богатая библиотека функций технического анализа

Тестирование удобства

  • Полная функция бэктестинга
  • Мониторинг и визуализация в реальном времени
  • Удобно для одновременного анализа нескольких валют

На основании этих преимуществ платформа FMZ была выбрана для изучения индикаторов тенденции непрерывности высоких и низких цен.

Характеристики рынка криптовалют

Прежде чем разрабатывать индикатор, нам необходимо рассмотреть различия между рынком криптовалют и фондовым рынком:

  • Круглосуточная торговля, без закрытия рынка
  • Волатильность огромна, и рынок нередко растет или падает на 20% за день.
  • Есть много розничных инвесторов, и эмоциональная торговля очевидна.
  • Исторические данные не длинные, большинство валют имеют всего несколько лет.

Исходя из этих характеристик, схема проектирования выглядит следующим образом:

  • Использование ежедневных данных может отфильтровать внутридневной шум без отставания
  • Установите минимальный срок подтверждения 3 дня, чтобы сбалансировать точность и своевременность.
  • Мониторинг нескольких основных валют для проверки одновременно

Реализовано на платформе FMZ

Основная разработка алгоритма

После глубокого размышления мы приняли метод анализа, основанный на «вчерашних полных данных», чтобы избежать ошибочных суждений, вызванных неполными данными на день. Основная структура данных выглядит следующим образом:

# 每个币种的数据都单独存储
data = defaultdict(lambda: {
    "daily_records": [],  # 存储每日的昨天数据
    "trend_buffer": [],   # 当前趋势缓冲区
    "patterns": [],       # 完整的趋势模式
    "current_trend": None, # 当前趋势状态
    "last_processed_time": 0
})

Основная логика определения тренда

Ключевые функции определения тенденций:

def is_trend_continuing(self, buffer, trend_type):
    """检查趋势是否持续"""
    if len(buffer) < 2:
        return False
    
    curr = buffer[-1]
    prev = buffer[-2]
    
    if trend_type == "BULL":
        # 牛市:High和Low都上升
        return curr["High"] > prev["High"] and curr["Low"] > prev["Low"]
    elif trend_type == "BEAR":
        # 熊市:High和Low都下降
        return curr["High"] < prev["High"] and curr["Low"] < prev["Low"]
    
    return False

Управление статусом тренда:

def analyze_trend_state(self, symbol):
    """分析趋势状态"""
    storage = data[symbol]
    buffer = storage["trend_buffer"]
    current_trend = storage["current_trend"]
    
    if current_trend is None:
        # 尝试检测新趋势
        new_trend = self.detect_new_trend(buffer)
        if new_trend:
            storage["current_trend"] = {
                "type": new_trend,
                "start_time": buffer[-2]["Time"],
                "start_price": buffer[-2]["Close"],
                "consecutive_days": 1
            }
    else:
        # 检查现有趋势是否继续
        if self.is_trend_continuing(buffer, current_trend["type"]):
            current_trend["consecutive_days"] += 1
        else:
            # 趋势中断,记录完整模式
            if current_trend["consecutive_days"] >= MIN_CONSECUTIVE:
                # 保存趋势记录
                self.save_pattern(symbol, current_trend, buffer)

Основная идея дизайна — это требование высоких и низких точек.в то же времяУдовлетворить непрерывные изменения и достичь минимального периода подтверждения в 3 дня, что может значительно сократить неверное суждение. Статистика нормы прибыли — это увеличение или уменьшение от цены открытия в начале тренда до цены закрытия в конце тренда.

Фактические результаты эксплуатации и анализ данных

На основе исторических данных бэктестинга платформы FMZ с 2020 года по июнь 2025 года, ниже представлена ​​фактическая динамика трех основных валют за последние 10 полных циклов тренда:

Анализ результатов теста ETH

тип Дата начала Дата окончания Продолжительность Урожай
Медвежий рынок 2025-05-29 2025-06-01 3 -5.38%
Бычий рынок 2025-05-19 2025-05-22 3 6.73%
Бычий рынок 2025-05-06 2025-05-09 3 26.94%
Бычий рынок 2025-04-24 2025-04-27 3 -0.17%
Медвежий рынок 2025-03-25 2025-03-30 5 -13.13%
Бычий рынок 2025-03-21 2025-03-24 3 5.04%
Медвежий рынок 2025-01-06 2025-01-10 4 -10.86%
Бычий рынок 2025-01-01 2025-01-06 5 11.2%
Медвежий рынок 2024-12-17 2024-12-20 3 -15.5%
Медвежий рынок 2024-12-07 2024-12-10 3 -9.96%

Характеристики производительности ETH

  • Наиболее выдающиеся результаты были достигнуты на бычьем рынке с 6 по 9 мая, где всего за три дня наблюдался значительный рост на 26,94%.
  • Средний бычий рынок длится 3,4 дня, а средняя доходность составляет 9,97%.
  • Средний медвежий рынок длится 3,6 дня, а среднее падение составляет -10,97%.
  • Крайне волатильная, самая нестабильная из трех валют

Анализ результатов тестирования BTC

тип Дата начала Дата окончания Продолжительность Урожай
Бычий рынок 2025-06-06 2025-06-11 5 7.78%
Медвежий рынок 2025-06-03 2025-06-06 3 -0.78%
Медвежий рынок 2025-05-27 2025-05-31 4 -4.37%
Медвежий рынок 2025-05-22 2025-05-25 3 -2.63%
Бычий рынок 2025-05-06 2025-05-09 3 8.4%
Медвежий рынок 2025-05-02 2025-05-05 3 -2.37%
Бычий рынок 2025-04-20 2025-04-23 3 10.07%
Бычий рынок 2025-04-09 2025-04-13 4 10.25%
Медвежий рынок 2025-03-26 2025-03-29 3 -5.53%
Медвежий рынок 2025-03-08 2025-03-11 3 -5.81%

Характеристики производительности BTC

  • Доминируют медвежьи рынки: 6 из 10 циклов являются медвежьими рынками
  • Средний бычий рынок длится 3,75 дня, а средняя доходность составляет 9,13%.
  • Средний медвежий рынок продолжался 3,17 дня, а среднее падение составило -3,58%.
  • Общая эффективность относительно сбалансирована, с умеренной волатильностью.

Анализ результатов теста BNB

тип Дата начала Дата окончания Продолжительность Урожай
Бычий рынок 2025-06-06 2025-06-11 5 5.46%
Медвежий рынок 2025-06-03 2025-06-06 3 -2.73%
Бычий рынок 2025-05-19 2025-05-22 3 4.63%
Бычий рынок 2025-05-05 2025-05-10 5 11.95%
Бычий рынок 2025-04-20 2025-04-23 3 2.44%
Бычий рынок 2025-04-09 2025-04-12 3 7.63%
Бычий рынок 2025-03-14 2025-03-17 3 8.18%
Медвежий рынок 2025-03-08 2025-03-11 3 -7.49%
Бычий рынок 2025-02-10 2025-02-13 3 9.66%
Медвежий рынок 2025-01-31 2025-02-03 3 -12.2%

Эксплуатационные характеристики BNB

  • Доминируют бычьи рынки: 7 из 10 циклов являются бычьими рынками.
  • Средний бычий рынок продолжался 3,43 дня, а средняя доходность составила 7,14%.
  • Средний медвежий рынок длится 3 дня, а среднее падение составляет -7,47%.
  • Результаты наиболее стабильны, экстремальных рыночных условий относительно немного.

Некоторые интересные выводы, лежащие в основе данных

При анализе данных последних десяти трендовых циклов этих трех валют были обнаружены некоторые интересные явления.

О продолжительности тренда

Большинство трендов заканчиваются примерно через 3–5 дней, что, по сути, соответствует общему мнению о рынке криптовалют — он меняется очень быстро. Первоначальный минимальный срок подтверждения в 3 дня всё ещё вполне разумен, поскольку позволяет отфильтровать случайные колебания в течение дня и не упускать возможности из-за слишком долгого ожидания. BTC в этом отношении наиболее стабилен, а продолжительность тренда относительно стабильна.

Различия в «характере» разных валют

У этих трёх валют действительно есть свои особенности. Недавняя динамика ETH действительно более привлекательна, и, возможно, он слишком долго находился в состоянии покоя, поэтому волатильность отскока очень велика. С 6 по 9 мая он может вырасти на 26,94% за 3 дня, что удивительно, но есть и «бычий рынок» -0,17%, который заставляет людей чесать голову. BTC, несомненно, стабильнее. Хотя в последнее время медвежьих рынков стало больше, волатильность всё ещё приемлемая. BNB преподнёс всем немало сюрпризов: на бычий рынок приходится 70%, а соотношение риска и доходности, похоже, самое лучшее.

Некоторые наблюдения о тенденциях оценки

Судя по результатам, этот простой индикатор всё же уловил некоторые ключевые моменты. Например, рост ETH на 26,94%, многочисленные циклы бычьего рынка BTC и BNB, а также несколько своевременных напоминаний о медвежьем рынке. Конечно, есть и некоторые сбивающие с толку моменты, например, «бычий рынок» -0,17%, который показывает, что алгоритму ещё есть куда совершенствоваться.

Для чего нужен этот инструмент?

Что это может сделать для вас

Честно говоря, этот инструмент в основном помогает вамУзнайте, как сейчас обстоят дела на рынке

  • Расскажет вам, растет ли текущий тренд, падает ли он или колеблется вбок.
  • Следите за тем, как долго продолжается эта тенденция и каковы ее результаты.
  • Обеспечить относительно объективную основу для суждения, а не основываться исключительно на чувствах
  • Судя по фактическим данным, он достаточно эффективен для выявления краткосрочных тенденций продолжительностью 3–5 дней.

Чего он не может сделать

Необходимо четко указать, что этот инструментЭто определенно не для предсказания будущего.

  • Он не скажет вам, вырастет ли он или упадет завтра.
  • Я не могу предсказать, насколько он вырастет или упадет.
  • Он не может заменить ваш собственный контроль рисков и управление финансами.
  • Когда рынок движется вбок, он может подавать некоторые запутанные сигналы.

Некоторые проблемы, возникшие во время использования

В ходе реальной эксплуатации также были обнаружены некоторые ограничения:

  1. Немного медленно реагирует: Поскольку для подтверждения требуется 3 дня, в первые несколько дней практически невозможно уловить тенденцию

  2. Иногда я «неправильно оцениваю людей».:Как и в случае с «бычьим рынком» ETH -0,17%, это показывает, что в некоторых особых случаях суждение алгоритма может быть неверным.

  3. Боковой рынок — это головная боль:Когда рынок колеблется в пределах диапазона, сигнал может часто меняться, что раздражает.

  4. Просто смотреть на цену немного однообразно: Неспособность учесть такие важные факторы, как объем торгов и новости

Как мы можем улучшить это дальше?

На основе наблюдений за этот период я ​​думаю, что есть несколько направлений, которые можно попробовать:

Настройте параметры для разных валют: Для такой нестабильной валюты, как ETH, могут потребоваться более строгие условия подтверждения, в то время как относительно стабильная валюта, как BNB, может сократить время подтверждения. Вы также можете установить минимальный порог доходности, чтобы отфильтровать сигналы со слишком низкой доходностью.

Добавьте некоторые вспомогательные суждения: Например, объединение изменений в объеме торгов для проверки надежности тренда или учет диапазона колебаний цен, чтобы не быть введенными в заблуждение незначительными изменениями.

Оптимизация самого алгоритма: Улучшить логику оценки прерывания тренда, чтобы уменьшить количество неверных суждений; добавить рейтинг силы тренда, чтобы различать сильные и слабые тренды; создать специальный механизм обработки для некоторых ненормальных ситуаций.

Оглядываясь назад на это исследование

Этот простой инструмент мониторинга рынка действительно превращает некоторые традиционные концепции технического анализа в автоматизированную систему. Благодаря удобству платформы FMZ мы успешно создали инструмент, который может отслеживать состояние рынка криптовалют в режиме реального времени.

Его главная ценность заключается в предоставлении относительно объективной информации о рыночных условиях, которая может помочь нам:

  • Иметь макроэкономическое понимание общей рыночной ситуации
  • Фильтрация некоторых популярных валют по историческим данным
  • Предоставление поддержки данных для более глубокого анализа

По мере накопления данных этот инструмент будет становиться всё более ценным. Конечно, это лишь один из многих инструментов анализа, и от него нельзя ожидать решения всех проблем, но в качестве отправной точки, я думаю, он всё равно очень интересен.

'''backtest
start: 2020-01-01 00:00:00
end: 2025-06-16 00:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
'''

import json
from datetime import datetime
from collections import defaultdict

# 配置参数
SYMBOLS = ["ETH_USDT", "BTC_USDT", "BNB_USDT"]
MIN_CONSECUTIVE = 3  # 最少连续天数
MAX_HISTORY = 1000  # 最大历史记录数

# 全局数据存储
data = defaultdict(lambda: {
    "daily_records": [],  # 存储每日的昨天数据
    "trend_buffer": [],   # 当前趋势缓冲区
    "patterns": [],       # 完整的趋势模式
    "current_trend": None, # 当前趋势状态
    "last_processed_time": 0
})

class TrendAnalyzer:
    def get_yesterday_data(self, records):
        """获取昨天的完整数据(records[-2])"""
        if len(records) < 2:
            return None
        return records[-2]  # 昨天的完整K线数据
    
    def is_trend_continuing(self, buffer, trend_type):
        """检查趋势是否持续"""
        if len(buffer) < 2:
            return False
        
        curr = buffer[-1]
        prev = buffer[-2]
        
        if trend_type == "BULL":
            # 牛市:High和Low都上升
            return curr["High"] > prev["High"] and curr["Low"] > prev["Low"]
        elif trend_type == "BEAR":
            # 熊市:High和Low都下降
            return curr["High"] < prev["High"] and curr["Low"] < prev["Low"]
        
        return False
    
    def detect_new_trend(self, buffer):
        """从缓冲区检测新趋势"""
        if len(buffer) < 2:
            return None
        
        curr = buffer[-1]
        prev = buffer[-2]
        
        # 检查是否开始牛市趋势
        if curr["High"] > prev["High"] and curr["Low"] > prev["Low"]:
            return "BULL"
        # 检查是否开始熊市趋势
        elif curr["High"] < prev["High"] and curr["Low"] < prev["Low"]:
            return "BEAR"
        
        return None
    
    def process_daily_data(self, symbol, records):
        """处理每日数据"""
        if not records or len(records) < 2:
            return
        
        storage = data[symbol]
        yesterday_data = self.get_yesterday_data(records)
        
        if not yesterday_data or yesterday_data["Time"] <= storage["last_processed_time"]:
            return  # 没有新的昨天数据
        
        # 更新处理时间
        storage["last_processed_time"] = yesterday_data["Time"]
        
        # 添加到每日记录
        storage["daily_records"].append(yesterday_data)
        if len(storage["daily_records"]) > MAX_HISTORY:
            storage["daily_records"] = storage["daily_records"][-MAX_HISTORY:]
        
        # 添加到趋势缓冲区
        storage["trend_buffer"].append(yesterday_data)
        
        # 分析趋势
        self.analyze_trend_state(symbol)
    
    def analyze_trend_state(self, symbol):
        """分析趋势状态"""
        storage = data[symbol]
        buffer = storage["trend_buffer"]
        current_trend = storage["current_trend"]
        
        if len(buffer) < 2:
            return
        
        if current_trend is None:
            # 尝试检测新趋势
            new_trend = self.detect_new_trend(buffer)
            if new_trend:
                storage["current_trend"] = {
                    "type": new_trend,
                    "start_time": buffer[-2]["Time"],  # 趋势从前一天开始
                    "start_price": buffer[-2]["Close"],
                    "start_open": buffer[-2]["Open"],
                    "consecutive_days": 1
                }
                Log(f"{symbol} 检测到{new_trend}趋势开始")
            else:
                # 没有趋势,只保留最近的数据
                storage["trend_buffer"] = buffer[-1:]
        else:
            # 检查现有趋势是否继续
            if self.is_trend_continuing(buffer, current_trend["type"]):
                # 趋势继续
                current_trend["consecutive_days"] += 1
                
                # 检查是否达到最小天数要求
                if current_trend["consecutive_days"] == MIN_CONSECUTIVE:
                    trend_name = "牛市" if current_trend["type"] == "BULL" else "熊市"
                    Log(f"{symbol} {trend_name}趋势确认! 连续{MIN_CONSECUTIVE}天")
                
            else:
                # 趋势中断
                if current_trend["consecutive_days"] >= MIN_CONSECUTIVE:
                    # 记录完整的趋势
                    end_data = buffer[-2]  # 趋势在前一天结束
                    duration = current_trend["consecutive_days"]
                    start_price = current_trend["start_open"]
                    end_price = end_data["Close"]
                    return_pct = round((end_price - start_price) / start_price * 100, 2)
                    
                    storage["patterns"].append({
                        "trend": current_trend["type"],
                        "start_time": current_trend["start_time"],
                        "end_time": end_data["Time"],
                        "duration": duration,
                        "return": return_pct
                    })
                    
                    trend_name = "牛市" if current_trend["type"] == "BULL" else "熊市"
                    Log(f"{symbol} {trend_name}趋势结束,持续{duration}天,收益{return_pct}%")
                
                # 重置趋势状态,重新开始检测
                storage["current_trend"] = None
                storage["trend_buffer"] = buffer[-2:]  # 保留最近两天数据重新开始
                
                # 立即检测新趋势
                self.analyze_trend_state(symbol)

def generate_tables():
    """生成所有统计表格"""
    tables = []
    
    # 概览表
    overview_rows = []
    for symbol in SYMBOLS:
        storage = data[symbol]
        if not storage["daily_records"]:
            continue
        
        patterns = storage["patterns"]
        current_trend = storage["current_trend"]
        
        # 计算统计数据
        bull_patterns = [p for p in patterns if p["trend"] == "BULL"]
        bear_patterns = [p for p in patterns if p["trend"] == "BEAR"]
        
        stats = {
            "bull_avg_return": round(sum(p["return"] for p in bull_patterns) / len(bull_patterns), 2) if bull_patterns else 0,
            "bear_avg_return": round(sum(p["return"] for p in bear_patterns) / len(bear_patterns), 2) if bear_patterns else 0,
            "bull_avg_days": round(sum(p["duration"] for p in bull_patterns) / len(bull_patterns), 1) if bull_patterns else 0,
            "bear_avg_days": round(sum(p["duration"] for p in bear_patterns) / len(bear_patterns), 1) if bear_patterns else 0
        }
        
        # 当前状态
        current_status = "震荡"
        current_return = 0
        current_days = 0
        consecutive = 0
        
        if current_trend and storage["daily_records"]:
            latest_price = storage["daily_records"][-1]["Close"]
            start_price = current_trend["start_open"]
            current_return = round((latest_price - start_price) / start_price * 100, 2)
            current_days = current_trend["consecutive_days"]
            current_status = "牛市" if current_trend["type"] == "BULL" else "熊市"
            consecutive = current_trend["consecutive_days"]
        
        overview_rows.append([
            symbol.replace("_USDT", ""),
            current_status,
            str(current_days),
            f"{current_return}%",
            str(consecutive),
            str(len(bull_patterns)),
            str(len(bear_patterns)),
            f"{stats['bull_avg_return']}%",
            f"{stats['bear_avg_return']}%",
            f"{stats['bull_avg_days']}天",
            f"{stats['bear_avg_days']}天"
        ])
    
    tables.append({
        "type": "table",
        "title": "每日高低价趋势监控(基于昨日完整数据)",
        "cols": ["币种", "状态", "持续", "收益", "强度", "牛市次数", "熊市次数", "牛市均收益", "熊市均收益", "牛市均天数", "熊市均天数"],
        "rows": overview_rows
    })
    
    # 趋势缓冲区分析表
    buffer_rows = []
    for symbol in SYMBOLS:
        storage = data[symbol]
        buffer = storage["trend_buffer"]
        current_trend = storage["current_trend"]
        
        if not buffer:
            continue
        
        latest_price = buffer[-1]["Close"]
        buffer_size = len(buffer)
        
        # 显示最近几天的High/Low变化
        if len(buffer) >= 2:
            recent_highs = [f"{r['High']:.0f}" for r in buffer[-min(5, len(buffer)):]]
            recent_lows = [f"{r['Low']:.0f}" for r in buffer[-min(5, len(buffer)):]]
            high_trend = " → ".join(recent_highs)
            low_trend = " → ".join(recent_lows)
        else:
            high_trend = f"{buffer[-1]['High']:.0f}"
            low_trend = f"{buffer[-1]['Low']:.0f}"
        
        trend_status = "无趋势"
        if current_trend:
            trend_status = f"{'牛市' if current_trend['type'] == 'BULL' else '熊市'}{current_trend['consecutive_days']}天"
        
        buffer_rows.append([
            symbol.replace("_USDT", ""),
            f"{latest_price:.2f}",
            trend_status,
            str(buffer_size),
            high_trend,
            low_trend
        ])
    
    tables.append({
        "type": "table",
        "title": "趋势缓冲区状态",
        "cols": ["币种", "价格", "当前趋势", "缓冲区", "High变化", "Low变化"],
        "rows": buffer_rows
    })
    
    # 历史记录表
    for symbol in SYMBOLS:
        patterns = [p for p in data[symbol]["patterns"] if p["duration"] >= MIN_CONSECUTIVE]
        coin_name = symbol.replace("_USDT", "")
        
        if not patterns:
            tables.append({
                "type": "table",
                "title": f"{coin_name} 历史趋势",
                "cols": ["类型", "开始", "结束", "天数", "收益"],
                "rows": [["无数据", "-", "-", "-", "-"]]
            })
            continue
        
        rows = []
        for p in sorted(patterns, key=lambda x: x["end_time"], reverse=True)[:10]:  # 只显示最近10条
            rows.append([
                "牛市" if p["trend"] == "BULL" else "熊市",
                datetime.fromtimestamp(p["start_time"] / 1000).strftime('%Y-%m-%d'),
                datetime.fromtimestamp(p["end_time"] / 1000).strftime('%Y-%m-%d'),
                str(p["duration"]),
                f"{p['return']}%"
            ])
        
        tables.append({
            "type": "table",
            "title": f"{coin_name} 历史趋势",
            "cols": ["类型", "开始", "结束", "天数", "收益"],
            "rows": rows
        })
    
    return tables

def main():
    analyzer = TrendAnalyzer()
    
    Log("趋势分析系统启动 - 基于昨日完整数据的逐日分析")
    Log("牛市定义: High和Low连续上升≥3天")
    Log("熊市定义: High和Low连续下降≥3天")
    
    while True:
        try:
            # 处理每个币种的数据
            for symbol in SYMBOLS:
                records = exchange.GetRecords(symbol)
                analyzer.process_daily_data(symbol, records)
            
            # 生成并显示表格
            tables = generate_tables()
            LogStatus('`' + json.dumps(tables) + '`')
            
        except Exception as e:
            Log(f"错误: {str(e)}")
        
        Sleep(1000 * 60 * 60)  # 24小时

def onexit():
    total = sum(len(data[s]["patterns"]) for s in SYMBOLS)
    Log(f"系统停止, 共识别 {total} 个趋势模式")