Последняя активность 2 days ago

Версия 0df32b45056457cd0e0bef516e61ce69d0b2442b

test ideas.md Исходник

Отличный план. Вы правильно выделили два главных сценария (базовый и копитрейдинг). Чтобы покрытие было полным и гарантировало стабильность системы, я предлагаю дополнить их сценариями на обработку ошибок и граничные случаи.

Вот Топ-5 идей для тестов backtest-runner, отсортированные от базовых к сложным:

1. "Smoke Test": Запуск примитивной стратегии (Infrastructure Check)

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

  • Цель: Убедиться, что Docker запускается, вольюмы монтируются, конфиг валиден, и Freqtrade в принципе способен завершить работу.
  • Ожидаемый результат:
    • Инструмент возвращает success: true.
    • В логах (logTail) присутствует фраза Backtesting finished.
    • В результатах есть хотя бы одна сделка.

2. "Data Fetcher Test": Копитрейдинг с реальными данными (SanR Integration)

Суть: Тест стратегии, которая импортирует sdk.py и запрашивает сигналы для реального пользователя (например, semaca) и реальной пары (BTC/USDT:USDT).

  • Цель: Проверить работу prepareMarketData. Это самое узкое место. Тест должен убедиться, что:
    1. Система парсит конфиг и находит нужные пары.
    2. Делает запрос к SanR API / Santiment API.
    3. Скачивает JSON-файлы в market_cache.
    4. Freqtrade внутри Docker видит эти данные.
  • Ожидаемый результат: Бэктест проходит успешно, не падает с ошибкой No data found.

3. "The One-Day Edge Case": Граничный случай с датами

Суть: Запуск бэктеста, где дата начала равна дате конца (например, timerange: "20241001-20241001").

  • Почему это важно: В вашем коде (src/mastra/pro/tools/freqtrade.ts и tools.ts) есть специальная логика, которая расширяет такой диапазон на +1 день. Если это сломается, Freqtrade загрузит 0 свечей и выдаст ошибку.
  • Ожидаемый результат: Система должна автоматически расширить диапазон до 20241002, загрузить данные за сутки и провести тест (24 свечи на 1h таймфрейме).

4. "The Crash Test": Обработка Runtime-ошибки в Python

Суть: Подсунуть стратегию с синтаксически верным кодом, но с логической ошибкой, которая вызовет краш во время выполнения (например, деление на ноль в populate_indicators или обращение к несуществующей колонке DataFrame).

  • Цель: Проверить, как backtest-runner обрабатывает падение контейнера или Python-исключения. Агент не должен падать сам, он должен вернуть лог с ошибкой.
  • Ожидаемый результат:
    • Инструмент возвращает success: false (или true, но с явным описанием ошибки в логах).
    • В logTail содержится Python Traceback (например, ZeroDivisionError).

5. "Missing Data Handling": Запрос несуществующей пары

Суть: В конфиге указать пару, которой не существует на бирже или в Santiment (например, NONEXISTENTCOIN/USDT:USDT).

  • Цель: Проверить валидацию данных до запуска тяжелого Docker-контейнера.
  • Ожидаемый результат:
    • Инструмент должен выбросить ошибку на этапе prepareMarketData.
    • Ошибка должна быть понятной: "Missing slugs for pairs..." или "Failed to fetch data".
    • Docker запускаться не должен (экономия ресурсов).

Как это реализовать в коде (Пример для Vitest)

Вы можете создать файл src/mastra/super/skills/backtest-runner/scenarios.spec.ts и реализовать эти сценарии, используя моки для exec (чтобы не ждать реальный докер долго) или реальные интеграционные тесты (как в примере 2).

Пример структуры теста для кейса №1:

it('Smoke Test: should complete a simple backtest successfully', async () => {
  // 1. Подготовка файлов (Strategy + Config)
  await writeFile(strategyPath, minimalWorkingStrategy);
  await writeFile(configPath, JSON.stringify(validConfig));
  
  // 2. Выполнение
  const result = await runBacktest.execute({ timerange: '20240101-20240105' }, context);
  
  // 3. Проверки
  expect(result.success).toBe(true);
  expect(result.logTail).toContain('Backtesting finished');
  expect(result.logTail).not.toContain('Traceback');
});