') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - HeteroCat/AsyncTrader: Building quantitative trading systems automatically with ChatGPT sounds pretty cool, doesn't it?(2023百度大模型应用创新挑战赛最佳创意奖) · GitHub
Skip to content

Repository files navigation

AsyncTrader

A quantitative trading automation tool powered by LangChain + OpenAI. 基于 LangChain 和 OpenAI 的量化交易自动化工具。


What is this? / 这是什么?

English: AsyncTrader uses large language models (LLM) to automatically generate, backtest, and optimize quantitative trading strategies. It integrates with Freqtrade (crypto), AkShare (China financial data), and Vnpy (China quant trading). Version 2.0 adds a modern web UI so you can do everything in the browser.

中文: AsyncTrader 利用大语言模型自动生成、回测和优化量化交易策略。目前已集成 Freqtrade(加密货币)、AkShare(中国金融数据)和 Vnpy(中国量化交易)。v2.0 新增了现代化 Web 界面,所有操作都可以在浏览器中完成。


Quick Start / 快速开始

1. Install Dependencies / 安装依赖

pip install -r requirements.txt

Core packages / 核心包:fastapi, uvicorn, langchain>=1.0, langchain-openai, chromadb, akshare

2. Start the Server / 启动服务

uvicorn app.main:app --host 0.0.0.0 --port 5000

Then open your browser and visit / 然后打开浏览器访问:/

3. Configure API Key / 配置 API Key

On the Configuration page, enter your OpenAI API Key and click "Save Configuration". The page will show "Ready" when the LLM is active.

系统配置 页面,输入你的 OpenAI API Key,点击 "保存配置"。配置成功后状态会显示 "就绪"。


Web UI Guide / 界面功能说明

Click the 中文/English button at the bottom of the sidebar to switch language.

点击侧边栏底部的 中文/English 按钮可切换语言。

Page / 页面What it does / 功能
Configuration / 系统配置Set OpenAI API Key, model, and temperature. / 设置 OpenAI API Key、模型和温度参数。
Strategy Generator / 策略生成器Describe your strategy in plain language, AI generates Freqtrade or Vnpy code. / 用自然语言描述策略,AI 自动生成 Freqtrade 或 Vnpy 策略代码。
Web Extractor / 网页策略提取Paste a URL containing a trading strategy, AI extracts the logic. / 粘贴包含交易策略的网页链接,AI 自动提取策略逻辑。
Data Query / 数据查询Ask for financial data in natural language (e.g., "Get SHFE copper futures daily data"). Powered by AkShare. / 用自然语言查询金融数据(例如:获取上期所铜期货日线数据)。底层使用 AkShare。
Doc Q&A / 文档问答Build a knowledge base from markdown docs, then ask questions. / 从 Markdown 文档构建知识库,然后进行问答。

API Endpoints / API 接口

MethodEndpointDescription / 说明
GET/api/llm/statusCheck LLM status / 检查大模型状态
POST/api/llm/configureConfigure API Key & model / 配置 API Key 和模型
POST/api/strategy/generateGenerate strategy code / 生成策略代码
POST/api/strategy/extractExtract strategy from URL / 从网页提取策略
POST/api/data/queryQuery AkShare data / 查询 AkShare 数据
POST/api/chat/buildBuild document index / 构建文档索引
POST/api/chat/askAsk document question / 文档问答
GET/api/systems/statusCheck external systems / 检查外部系统可用性

Architecture / 项目架构

app/
main.py # FastAPI entrypoint / FastAPI 入口
routers/ # API routes / API 路由
services/ # Business logic / 业务逻辑
static/ # Web frontend / Web 前端
trading_system/
base.py # LLMManager / 大模型配置管理
tools.py # Strategy & web extraction tools / 策略和网页提取工具
akshare_tools.py # AkShare data query / AkShare 数据查询
rag.py # Document Q&A chain / 文档问答链

Notes / 注意事项

  1. API Key required / 需要 API Key: All AI features require a valid OpenAI API Key. / 所有 AI 功能都需要有效的 OpenAI API Key。
  2. External systems / 外部系统: Freqtrade and Vnpy require separate installation. The UI shows their availability status. / Freqtrade 和 Vnpy 需要单独安装,界面会显示它们的可用状态。
  3. Doc Q&A / 文档问答: Requires markdown (.md) files in the specified docs folder. / 需要在指定文档文件夹中放置 Markdown 文件。
  4. LangChain version / LangChain 版本: v2.0 is based on LangChain 1.0+. It is not compatible with the old 0.0.x API. / v2.0 基于 LangChain 1.0+,与旧版 0.0.x API 不兼容。

Legacy Docs / 旧版文档

The original CLI-based workflow documentation is preserved in docs/:

  • docs/freqtrade_system.md
  • docs/akshare_system.md
  • docs/vnpy_system.md

旧版基于命令行的使用文档保留在 docs/ 目录下。

About

Building quantitative trading systems automatically with ChatGPT sounds pretty cool, doesn't it?(2023百度大模型应用创新挑战赛最佳创意奖)

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages