Головна / Статті

Агент для торгівлі 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 (міркування плюс дія), працює у циклі, що складається з чотирьох етапів.

  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 замінює скрейпери чи кілька інтеграцій з постачальниками. Обмеженням, яке потрібно враховувати, є щоденний ліміт безкоштовного тарифу після завершення етапу створення прототипу.