Вы когда-нибудь мечтали, чтобы за вас торговал робот, который не спит, не паникует и не идет в разнос на новостях? Я тоже. Но все туториалы, что я видел, либо предлагали купить подписку на «готового бота» (спойлер: они сливают депозит), либо уходили в дебри теории, из которой непонятно, что делать дальше.
Я решил разобраться сам и написал полноценного ИИ-трейдера, который реально работает с биржей через API. За основу взял Finam Trade API (этот брокер один из немногих, кто даёт удобный REST API для России), а в качестве мозга — LLM с LangChain. Весь код лежит в открытом репозитории, и сегодня я покажу, как собрать такого агента с нуля.
Почему LLM, а не классическая стратегия
Классический торговый робот — это система правил: если RSI > 70, продавай. Но рынок шире любых фиксированных алгоритмов. LLM умеет читать новости, интерпретировать разнородные данные и адаптироваться к контексту. Проблема в другом: модель может галлюцинировать и совершить идиотскую сделку. Поэтому архитектура должна быть с защитными слоями.
Мы будем использовать CodeAct — подход, при котором агент генерирует и исполняет Python-код для принятия решений. Это даёт максимальную гибкость. Подробнее о том, как это работает, я писал в статье «CodeAct — темная лошадка среди AI-агентов».
Что нам понадобится
- Python 3.12+ (на момент 2026 года уже не грех использовать последнюю стабильную)
- LangChain 0.3.x — фреймворк для построения цепочек LLM
- OpenAI API или любая локальная модель (например, Llama 4) — я советую Claude 4 Opus или GPT-4o как самый надёжный вариант для финансовых расчётов
- Finam Trade API — бесплатный доступ для торговли на реале и песочнице
- SQLite для хранения истории ордеров
- FastAPI + Uvicorn — лёгкий HTTP-сервер для управления агентом
⚠️ Важно: Никогда не храните API-ключи в коде. Я покажу, как использовать переменные окружения (.env). Один утекший токен — и ваш счёт может обнулиться за минуту. История знает такие случаи.
Архитектура нашего монстра
Система состоит из трёх микросервисов, которые общаются через Redis Pub/Sub:
- Data Fetcher — забирает котировки каждую минуту, пишет в InfluxDB (или просто в CSV).
- Decision Agent — LLM, которая анализирует данные и решает, что делать. Использует
get_portfolio(),place_order()иget_news()как инструменты LangChain. - Execution Engine — выполняет ордера через Finam API, проверяет лимиты, логирует всё в SQLite.
Звучит сложно? На деле — 150 строк кода. Начинаем.
1 Поднимаем окружение и зависимости
python -m venv venv
source venv/bin/activate # или venv\Scripts\activate на Windows
pip install langchain langchain-community finam-trade-api fastapi uvicorn python-dotenv httpx redis sqlalchemy
2 Настройка Finam API (песочница)
Идём в личный кабинет Финама, раздел «API-доступ». Создаём токен с правами на чтение котировок и торговлю. Для теста используем песочницу — она работает с теми же эндпоинтами, но с виртуальными деньгами.
# config.py
import os
from dotenv import load_dotenv
load_dotenv()
FINAM_API_TOKEN = os.getenv("FINAM_API_TOKEN")
FINAM_CLIENT_ID = os.getenv("FINAM_CLIENT_ID")
FINAM_BASE_URL = "https://trade-api.finam.ru" # для песочницы
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
3 Инструменты для агента
Агент будет использовать три инструмента: получение портфеля, получение текущей цены и размещение ордера. Реализуем их через @tool из LangChain.
from langchain.tools import tool
from finam_trade_api import FinamTradeApi
api = FinamTradeApi(token=FINAM_API_TOKEN, base_url=FINAM_BASE_URL)
@tool
def get_portfolio() -> str:
"""Возвращает текущий портфель: список позиций, баланс, P&L."""
portfolio = api.get_portfolio(client_id=FINAM_CLIENT_ID)
return str(portfolio)
@tool
def get_candle(symbol: str, interval: str = "D") -> str:
"""Возвращает последнюю свечу для заданного тикера."""
candle = api.get_candle(symbol=symbol, interval=interval)
return f"Close: {candle.close}, Volume: {candle.volume}"
@tool
def place_order(symbol: str, side: str, quantity: int) -> str:
"""Размещает рыночный ордер. side: 'buy' или 'sell'."""
order = api.place_order(client_id=FINAM_CLIENT_ID, symbol=symbol, side=side, quantity=quantity)
return f"Order placed: {order.order_id}"
4 Собираем агента с памятью
Без памяти агент будет каждый раз забывать предыдущие сделки и контекст. Используем ConversationBufferMemory.
from langchain.memory import ConversationBufferMemory
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4o", temperature=0.2)
tools = [get_portfolio, get_candle, place_order]
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
agent = create_tool_calling_agent(llm, tools, prompt="Вы финансовый аналитик. Принимайте решения на основе данных. Риск-менеджмент: никогда не рисковать более 2% от портфеля на одну сделку.")
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True, memory=memory)
5 Запускаем цикл принятия решений
Лучше не давать агенту торговать постоянно — он может спамить ордерами. Я ставлю таймер на каждые 5 минут и добавляю проверку: если рынок закрыт или нет новых данных — пропускаем.
import asyncio
async def trading_loop():
while True:
# Получаем текущую позицию
portfolio = await get_portfolio.ainvoke({})
# Запрашиваем решение у агента
decision = await agent_executor.ainvoke({"input": f"Текущий портфель: {portfolio}. Предложи действие."})
print(decision["output"])
await asyncio.sleep(300) # 5 минут
if __name__ == "__main__":
asyncio.run(trading_loop())
Грабли, на которые я наступил
- Галлюцинации модели. Агент однажды решил «купить всё» и отправил ордер на 10 000 акций при балансе 1000$. Спасло только то, что я выставил лимит на количество контрактов в инструменте. Добавьте проверку:
if quantity > max_allowed: return "Лимит превышен". - Формат ордера. Finam API требует передавать уникальный ID для предотвращения дублей. Я забыл — получил двойной ордер. Всегда используйте
uuid. - Rate limit. После 3-4 последовательных вызова Finam может забанить на минуту. Вставьте
time.sleep(1)между запросами. - Безопасность. Если у вас открыт API-ключ в коде, вы рискуете всем. Используйте
python-dotenvи не коммитьте.envв репозиторий.
Тестирование на симуляторе
Прежде чем запускать на реале, обязательно прогнать агента на исторических данных. Для этого я использую симулятор, который поднимает сервер с историческими котировками и эмулирует исполнение ордеров. Мы подробно разбирали такой инструмент в статье «ArenaGo.ru: собираем AI-трейдинг симулятор на реальных данных» — рекомендую.
Если хотите системно подойти к обучению трейдингу и разобраться в стратегиях, советую пройти курс по трейдингу на Skillbox. Там учат контролировать риски и строить собственные стратегии — это пригодится, даже если у вас бот.
Что дальше
Запускать такого агента на реальном счёте с суммой меньше 100 000 рублей — бессмысленно. Комиссии съедят прибыль. Но для обучения и отработки стратегий — идеально.
Кстати, многие спрашивают: а не проще ли использовать уже готовых агентов вроде OpenClaw? Да, если не хотите писать код. Но мой опыт говорит, что самописный бот даёт 100% контроль. Когда случится сбой (а он случится), вы сможете быстро исправить, а не ждать обновления от вендора.
И последнее: не забывайте про налоги. Если бот заработал — вы обязаны отчитаться. Впрочем, это уже другая история.
FAQ: быстрые ответы
Какие LLM лучше всего подходят для трейдинга?
На практике GPT-4o и Claude 4 Opus дают наименьшее количество ошибок в расчётах. Локальные Llama 4 пока уступают, но для песочницы сойдут.
Сколько стоит запуск такого бота?
Затраты на API OpenAI: примерно $10-20 в месяц при активности 24/7. Плюс сервер на $5-10. Итого $15-30. На истории можно тестировать бесплатно.
Что делать, если бот теряет деньги?
Установите стоп-лосс на уровне 5% от портфеля в коде агента. И никогда не оставляйте его без присмотра на первом этапе. Лучше сначала погонять на симуляторе хотя бы месяц.
Код из этой статьи доступен на GitHub (ссылка в конце). Берите, форкайте, дорабатывайте. Если наступите на грабли — пишите в комментарии, разберёмся вместе.