Как ИИ получил руки для торговли на бирже
- вторник, 10 февраля 2026 г. в 00:00:04
Исходный код, разобранный в статье, размещён по ссылке
На картинах или геральдике Георгий Победоносец всегда с копьём. Но почему копьё? Можно было изобразить лук, мечь, булаву. Длинное древко копья идет в облако в небеса (к начальству): знание и сила работают с инструментом действия как левая и правая нога.

Именно в этом проблема Claude Code.
Claude Code — это AI-агент от Anthropic для автономной разработки кода. Он обладает сверхчеловеческим распознаванием паттернов, может проанализировать 50MB логов бэктеста за секунды (сам придумав и отладив python скрипт через разработку тестированием), определить почему 80% сделок закрываются по таймауту или SL, и модифицировать Pine Script индикаторы с хирургической точностью.
Но у него нет рук.
Если отбросить маркетинг, реальный процесс создания автоматизированной production торговой стратегии выглядит так. TradingView заменил MetaTrader, торговые стратегии пишут на нём.
Пишем стратегию в веб‑редакторе Pine Script на сайте TradingView.
Запускаем бэктест (лимит ~5000 баров если нет банковской карты).
Скачиваем CSV.
Отправляем в Claude/Grok/DeepSeek
Меняем одну строчку.
Повторяем.
Стоимость итерации слишком высокая из-за кривых рук человека: количество CSV файлов либо превращает папку загрузок в помойку, либо прогон недели времени backtest происходит за день вдумчивой работы так как нужно именовать и размещать по папкам файлы. Человек так физически долго не проработает
А ещё можно передать в чат не тот файл и словить look ahead bias
Язык Pine Script это синтаксический сахар для for loop где переменные объявляются внутри блока и вне блока цикла
// Локально в итерации цикла по свечам long_cond = ta.crossover(ema_fast, ema_slow) and rsi > 40 and rsi < 65 and trend_up and vol_spike and mom_up short_cond = ta.crossunder(ema_fast, ema_slow) and rsi < 60 and rsi > 35 and trend_down and vol_spike and mom_down // Глобально вне цикла var int bars_since_signal = 0
Как следствие, если нужно дождаться благоприятных условий на быстром (15m) и долгом (4h) таймфрейме, то получаются костыли
ema200_4h = request.security( syminfo.tickerid, "240", ta.ema(close, 200), lookahead = barmerge.lookahead_off )
Ближайший аналог такого кода из математики - комплексное число. Сама цифра ничего не значит: нужна динамика изменения ряда чисел (в общем растет или падает). А двойные циклы for это неэффективно (квадратичная сложность), поэтому их не запилили. А ещё непонятно что делает barmerge.lookahead_off
// Правильно так? breakeven = entryPrice * (1 + commissionPct * 2 + slippagePct * 2) // Или так? breakeven = entryPrice * (1 + entryFee) / (1 - exitFee - slippage) // А может так? trueBreakeven := entryPrice * (1 + entryCommission) / (1 - exitCommission - slippage) * (1 + fundingRate * holdingPeriod / 8)
Ещё веселее дела с математикой безубытка: этот код нечитаем, любая галлюцинации языковой модели визуально неотличимо сделает убыток. При этом, программист будет убежден что проблема в индикаторах
Для того, чтобы исключить человеческий фактор нужно создать систему, которая будет
Запускать Pine Script локально self hosted
Уже сделано в https://github.com/QuantForgeOrg/PineTS Визуализация индикаторов уже в опенсорсе, торговые стратегии в рамках статьи не интересны
Обеспечить временную синхронизацию вне редактируемого LLM кода
Разобрано в статье https://habr.com/ru/articles/979116/ Важно вынести критический код из зоны работы ИИ агенты чтобы избежать халтуры или галюцинаций
Одинаковый код в backtest/live/paper
Разобрано в статье https://habr.com/ru/articles/980736/ Там рассказано о торговых стратегиях на естественном языке, но бесшовная миграция live/paper/dev уже сделана
Вести структурированные JSONL‑логи как разметка нативная LLM агентам
JSONL (JSON Lines) это формат как для dataset в huggingface, так и для логов. Claude читает их с расширенным лимитом или сам пишет скрипт для быстрого поиска строки
Файл Agent Skills чтобы избежать повторный research на новом контексте чата
Создается автоматически при запуске команды npx -y @backtest-kit/sidekick. Так же это позволяет попросить обычнай чат Claude использовать код backtest-kit для исследования создав docker контейнер на стороне сервера не трогая машину программиста
Дополнительно, так как всё opensource, это можно запустить на любой бирже, в том числе которой нет в TradingView или компания отключила брокера
Чтобы совместить данные разных таймфреймов нужно запустить два отдельных индикатора единомоментно. Полный код программы по ссылке уже содержит механизм кеширования старшено таймфрейма 4h, вычисления оптимизированы
import { addStrategySchema } from "backtest-kit"; import { randomString } from "functools-kit"; import * as math_15m from "../../math/timeframe_15m.math.mjs"; import * as math_4h from "../../math/timeframe_4h.math.mjs"; import StrategyName from "../../enum/StrategyName.mjs"; import RiskName from "../../enum/RiskName.mjs"; addStrategySchema({ strategyName: StrategyName.MainStrategy, interval: "5m", getSignal: async (symbol) => { const signalId = randomString(); const data_4h = await math_4h.getData(signalId, symbol); // await pinescript.run( // File.fromPath("timeframe_4h.pine"), // { symbol, timeframe: "4h", limit: 100 } // ) if (data_4h.noTrades) { return null; } const data_15m = await math_15m.getData(signalId, symbol); // await run( // File.fromPath("timeframe_15m.pine"), // { symbol, timeframe: "15m", limit: 100 } // ) if (data_15m.position === 0) { return null; } if (data_4h.allowShort && data_15m.position === 1) { return null; } if (data_4h.allowLong && data_15m.position === -1) { return null; } { math_15m.dumpPlot(signalId, symbol); math_4h.dumpPlot(signalId, symbol); } return await math_15m.getSignal(signalId, symbol); }, riskList: [ RiskName.TakeProfitDistanceRisk, RiskName.StopLossDistanceRisk ], });
Я не смогу рассказать кратко. На изображениях можно видеть пример выхода из позиции по Келли: цена не достигла TP, но локальный спайк (левый нижний угол) позволил заработать 90% прибыли через выход частями на таймфрейме 15 минут не взирая на то, что дальше цена колебалась в боковике (правый нижний угол) и на часовом таймфрейме начала падение

Доступен не только технический, но и Мультитаймфреймовый, Фундаментальный анализ. Antropic уже создали и поддерживают инструменты поиска в интернете для Claude, поэтому он сам найдет новости в интернете и, если надо, будет открывать только short. Так же, пакет @backtest-kit/ollama и асинхронная природа функции getSignal позволяют искать новости и прогнозы в интернете на лету не меняя код бота. Но связка Claude Code on the web плюс GitHub Actions значительно удобнее: команду адаптировать стратегию можно дать с iPad находясь в отпуске
Человек: Создай крипто-торгового бота используя RSI дивергенцию и подтверждение объёмом
Claude Code:
npx @backtest-kit/sidekick crypto-bot cd crypto-bot # Читает сгенерированные Pine Script шаблоны cat config/source/timeframe_15m.pine
Claude Code: Вижу шаблон с EMA кроссовером. Модифицирую его для RSI дивергенции...
# Редактирует Pine Script стратегию cat > config/source/rsi_divergence.pine << 'EOF' //@version=5 indicator("RSI Divergence Strategy") // Вычисление RSI rsi = ta.rsi(close, 14) rsi_prev = ta.rsi(close[1], 14) // Определение дивергенции цены bullish_div = close < close[5] and rsi > rsi[5] and rsi < 35 bearish_div = close > close[5] and rsi < rsi[5] and rsi > 65 // Подтверждение объёмом vol_spike = volume > ta.sma(volume, 20) * 1.5 // Сигналы long_signal = bullish_div and vol_spike short_signal = bearish_div and vol_spike plot(long_signal ? 1 : short_signal ? -1 : 0, "Signal") plot(close, "Close") plot(close * 0.98, "StopLoss") // 2% стоп plot(close * 1.03, "TakeProfit") // 3% цель EOF
Claude Code: Запускаю бэктест на октябре 2025 (период крипто-краха)...
npm start -- \ --mode backtest \ --frame October2025 \ --strategy rsi-divergence \ --symbol BTCUSDT
Результаты бэктеста:

Claude Code: Хм, убыток во время волатильности. Добавлю динамические стопы на базе ATR и фильтр тренда...
# Модифицирует Pine Script str_replace_editor \ --path config/source/rsi_divergence.pine \ --old_str "plot(close * 0.98, \"StopLoss\")" \ --new_str "atr = ta.atr(14)\nplot(close - atr * 2, \"StopLoss\")" # Добавляет 4H фильтр тренда cat > config/source/trend_filter.pine << 'EOF' //@version=5 indicator("Trend Filter 4H") ema200 = ta.ema(close, 200) bullish_trend = close > ema200 bearish_trend = close < ema200 plot(bullish_trend ? 1 : bearish_trend ? -1 : 0, "TrendBias") EOF
Claude Code: Перезапускаю бэктест с динамическими стопами + фильтром тренда...

Claude Code: Стратегия теперь прибыльна. Деплою в paper trading для живой валидации...
npm start -- \ --mode paper \ --strategy rsi-divergence \ --symbol BTCUSDT