Главная / Статьи

Агент для торговли LangChain с поддержкой актуальных данных рынка EODHD, шаг за шагом

Почему торговые агенты на основе LLM терпят неудачу без реальных данных, как работает цикл ReAct и как создать агента LangChain с тремя инструментами на основе цен EODHD, фундаментальных показателей и индикатора RSI.

Издатель: REACTAPP.TOP8 мин чтения1769 слов

Источники: Building a Trading Agent with LangChain and the EODHD API

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

Короче говоря, агент — это LLM, которому предоставляются инструменты (функции) и свобода решать, когда и как их использовать, вместо того чтобы отвечать на основе знаний, полученных в процессе обучения. LangChain — это фреймворк на Python, который объединяет модель, инструменты, память и цикл принятия решений в одну рабочую единицу. EODHD обеспечивает то, чего у моделей нет по умолчанию: реальные цены, фундаментальные показатели, технические индикаторы и свежие финансовые новости через REST API. В совокупности это позволяет создать агента, который может ответить на вопрос «Стоит ли эта акция сейчас находиться под моим наблюдением?» на основе актуальных данных, а не устаревшей информации из памяти.

Модель — не слабое место

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

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

Технологическая стек-схема

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

EODHD заполняет пробелы в данных. Благодаря своему API агент может получать данные о ценах OHLCV в реальном времени и за прошлые периоды, фундаментальные показатели компаний, такие как коэффициенты, балансовый отчет и доходы, технические индикаторы вроде RSI, средние значения и MACD, а также новости с информацией о настроениях рынка. Практические причины выбора этого инструмента для подобной автоматизации очевидны: он охватывает биржи по всему миру, а не только NYSE и NASDAQ. Фундаментальные данные, технические показатели и новости находятся по отдельным точкам доступа, что позволяет использовать каждый из них как отдельный инструмент. К тому же бесплатный тариф достаточно щедр, чтобы создать прототип перед масштабированием.

Оценка EODHD в качестве слоя данных

Любой поставщик данных заслуживает тщательной проверки перед тем, как его использовать в агенте. С положительной стороны, цены, фундаментальные показатели, технический анализ и новости объединены в одном интерфейсе и по одной тарифной плане, так что не нужно соединять данные трех разных поставщиков. Многие бесплатные альтернативы, такие как скраперы на базе Yahoo и ограниченные тарифные планы Alpha Vantage, поддерживают только американские тикеры, в то время как EODHD охватывает десятки бирж, что важно для акций за пределами США. Результаты представлены в формате JSON с предсказуемыми полями (close, change_p, PERatio и т. д.), поэтому создание оболочек для инструментов происходит просто, и ничего не зависит от нестабильного парсинга HTML. Вы можете создать и протестировать весь агент, учитывающий цены, фундаментальные показатели и индикатор RSI, прежде чем вносить оплату. Лимиты на количество запросов задокументированы и предсказуемы, что важно, когда агент может вызывать инструмент несколько раз для решения одного вопроса.

Есть и недостатки. Бесплатный тариф имеет ограничения по количеству запросов в день, что подходит для личного списка наблюдения, но недостаточно для многопользовательского производственного сервиса. Обновления фундаментальных данных происходят по графику провайдера, а не сразу после публикации отчетов — это ограничение характерно для всех API фундаментальных данных, но важно, если ваш агент нуждается в анализе данных в тот же день. Кроме того, описание инструментов остается вашей ответственностью: плохо написанный инструмент LangChain всё равно может быть вызван в неподходящий момент или неправильно интерпретирован моделью, независимо от качества API. Для агента, нуждающегося в структурированных финансовых данных без использования инструментов для сбора информации, такие компромиссы делают хостинговое API предпочтительнее самостоятельно созданного слоя данных.

Как работает цикл рассуждений

В большинстве учебников опускается объяснение того, как именно функционирует «агент». Агент LangChain, использующий шаблон ReAct (Reason плюс Act), выполняет цикл, состоящий из четырех этапов.

  1. LLM, который читает вопрос и описания инструментов, а затем выбирает следующий шаг.
  2. Инструменты — это функции с именами, описаниями, а также указанием ожидаемых входных и выходных данных, такие как get_live_price, get_fundamentals и get_rsi.
  3. Экзекутор, который фактически запускает выбранный инструмент, передает полученный результат обратно модели, позволяя ей решить, что делать дальше.
  4. Память временных данных — это постоянный отчет о шагах мышления, действий и наблюдений в рамках одного запроса, что помогает модели запоминать уже проверенную информацию.

Вопрос вроде «Стоит ли нам сейчас обращать внимание на AAPL.US?» приводит к такой цепочке действий. Сначала модель запрашивает цену:

Thought: I need the current price first.
Action: get_live_price("AAPL.US")
Observation: AAPL.US: current price 227.50, change +0.8%

Затем оно приходит к выводу, что цена сама по себе мало говорит, и переходит к анализу импульса роста и оценки стоимости:

Thought: Price alone isn't enough — check momentum.
Action: get_rsi("AAPL.US")
Observation: AAPL.US — RSI(14): 58.3Thought: Not overbought. Check if valuation is reasonable.
Action: get_fundamentals("AAPL.US")
Observation: AAPL.US — PE: 31.2, Market Cap: 3.4T, Dividend Yield: 0.4%Thought: I now have enough data to answer.
Final Answer: [synthesized response]

Это архитектурная разница между агентом и чат-ботом с системным промптом. Модель выбирает порядок вызовов инструментов во время выполнения на основе информации, полученной от каждого наблюдения, и при этом не используется фиксированный скрипт. Именно поэтому качество и структура источника данных имеют такое большое значение. Если функция get_fundamentals возвращает бесполезные или устаревшие данные, каждое решение, основанное на них, унаследует эту ошибку без какого-либо видимого предупреждения. Каждый шаг рассуждений зависит от надежности предыдущего, и это главная причина, по которой финансовым агентам нужен настоящий, структурированный API вместо данных, полученных путем скрапинга или кэширования.

Создание

У агента есть три инструмента, связанных с EODHD: текущая цена, фундаментальные показатели и технические индикаторы. Начните с установки соответствующих пакетов:

pip install langchain langchain-openai requests

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

import requests
from langchain.tools import tool
EODHD_API_KEY = "YOUR_API_KEY"
BASE_URL = "https://eodhd.com/api"
@tool
def get_live_price(ticker: str) -> str:
    """Returns the current price of a stock. Example ticker: AAPL.US"""
    url = f"{BASE_URL}/real-time/{ticker}"
    params = {"api_token": EODHD_API_KEY, "fmt": "json"}
    r = requests.get(url, params=params).json()
    return f"{ticker}: current price {r['close']}, change {r['change_p']}%"
@tool
def get_fundamentals(ticker: str) -> str:
    """Returns key fundamental metrics: PE ratio, market cap, dividend yield."""
    url = f"{BASE_URL}/fundamentals/{ticker}"
    params = {"api_token": EODHD_API_KEY}
    r = requests.get(url, params=params).json()
    highlights = r.get("Highlights", {})
    return (
        f"{ticker} - PE: {highlights.get('PERatio')}, "
        f"Market Cap: {highlights.get('MarketCapitalization')}, "
        f"Dividend Yield: {highlights.get('DividendYield')}"
    )
@tool
def get_rsi(ticker: str) -> str:
    """Returns the 14-day RSI to assess overbought or oversold conditions."""
    url = f"{BASE_URL}/technical/{ticker}"
    params = {"api_token": EODHD_API_KEY, "function": "rsi", "period": 14, "fmt": "json"}
    r = requests.get(url, params=params).json()
    latest = r[-1]
    return f"{ticker} - RSI(14): {latest['rsi']} as of {latest['date']}"

Затем соберите агента из чат-модели, инструментов и промпта ReAct:

from langchain_openai import ChatOpenAI
from langchain.agents import create_react_agent, AgentExecutor
from langchain import hub

llm = ChatOpenAI(model="gpt-4o", temperature=0)
tools = [get_live_price, get_fundamentals, get_rsi]

prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
prompt = hub.pull("hwchase17/react")
agent = create_react_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

Это три инструмента: один LLM и один цикл, который выбирает среди них в зависимости от вопроса. Вызов выглядит так:

response = executor.invoke({
    "input": "Should we be looking at AAPL.US right now?"
})
print(response["output"])

Агент не отвечает на основе запомненных данных. Сначала он вызывает функцию get_live_price, затем get_rsi, а при необходимости оценки — get_fundamentals; после этого все три результата объединяются в ответ, основанный на реальных данных, а не на выдуманной информации в убедительном формате. К естественным расширениям относятся агент, способный сравнивать несколько акций в одном запросе, система, добавляющая новости через интерфейс для анализа настроений рынка, и задача ежечасного уведомления, отслеживающая список акций для наблюдения.

Что стоит запомнить

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

Ниже приведены несколько распространённых вопросов. Что такое агент в среде торговли? Это система, в которой LLM выбирает инструменты для выполнения задачи — от цен и фундаментальных данных до новостей, используя реальные данные, а не только знания, полученные в процессе обучения. Почему использовать LangChain вместо прямого вызова API? Он управляет циклом принятия решений: определяет, какой инструмент использовать, когда и как объединять результаты нескольких инструментов, что в противном случае пришлось бы жёстко задавать для каждого случая. Требуется ли платный аккаунт EODHD, чтобы попробовать это? Нет, достаточно бесплатного тарифа для создания прототипа. В чём основной компромисс по сравнению с созданием собственного потока обработки данных? Вы теряете полный контроль над источниками данных в обмен на скорость и надёжность; один структурированный API заменяет несколько скраперов или интеграций с поставщиками. Ограничением, с которым придётся считаться после завершения этапа разработки прототипов, является ежедневный лимит бесплатного тарифа.