1. 项目概述一个由LLM驱动的金融市场“数字孪生”如果你对金融市场的复杂性着迷或者正在研究多智能体系统、计算社会科学那么你很可能已经对传统市场模拟的局限性感到头疼。传统的模拟器要么是基于预设规则的“提线木偶”缺乏真实交易者的行为多样性要么是黑箱的统计模型难以解释群体行为如何涌现出市场现象。这正是TwinMarket这个项目试图解决的痛点。它不是一个简单的回测工具而是一个基于大语言模型LLM构建的、可扩展的行为与社会模拟平台旨在为金融市场创建一个高保真的“数字孪生”。简单来说TwinMarket的核心思想是用一个个具备“个性”和“思考能力”的LLM智能体来扮演市场中的各类参与者。这些智能体不仅会分析K线和技术指标还会像真人一样在论坛里交流信息、形成社交网络、对新闻事件做出情绪化反应并据此做出买卖决策。所有的订单最终会汇集到一个实时的撮合引擎中形成连续的价格走势。这样一来研究者就可以在一个可控的、透明的环境中观察羊群效应、信息传播、泡沫形成与破裂等经典市场现象是如何从微观个体的互动中“生长”出来的。这个项目由FreedomIntelligence团队开发并已在NeurIPS 2025发表更在ICLR 2025的金融AI研讨会上获得了最佳论文奖其学术价值和工程实践的扎实程度都得到了认可。对于金融科技FinTech从业者、计算社会科学研究者、多智能体系统开发者甚至是量化策略的初步验证者TwinMarket都提供了一个前所未有的沙盒环境。2. 核心设计思路从“规则驱动”到“行为涌现”为什么我们需要一个如此复杂的模拟器要理解TwinMarket的价值得先看看我们过去是怎么做的。2.1 传统市场模拟的瓶颈传统的金融市场模拟大致可以分为两类基于规则的模拟这是最主流的方式。我们定义一系列交易规则比如“当5日均线上穿20日均线时买入”。智能体严格遵循这些规则行动。这种方法的好处是可控、可解释、计算效率高。但缺点也显而易见市场是由无数拥有不同认知、情绪和信息的个体组成的预设的规则无法捕捉这种多样性更无法模拟“学习”和“适应”的过程。当出现规则之外的新情况比如突发黑天鹅事件时整个模拟系统就可能失效。基于统计/深度学习的模拟这类方法试图用历史数据训练模型来预测价格或生成订单流。它们可能很“准”但本质上是一个黑箱。我们很难理解模型内部发生了什么也无法将模拟结果例如一次市场崩盘归因于某个具体的个体行为或社会互动机制。这对于科学研究来说解释性不足。这两种方法都缺失了金融市场的一个核心维度社会性。人是社会动物交易决策深受同伴、舆论、媒体和群体情绪的影响。TwinMarket的设计哲学正是将这一维度置于核心。2.2 TwinMarket的“三位一体”架构TwinMarket的突破在于它用LLM作为智能体的“大脑”构建了一个涵盖个体行为、社会互动、市场环境的三位一体模拟框架。个体行为层面每个交易者智能体Trader Agent都由一个LLM实例驱动。你可以为它设定“人设”比如风险偏好保守/激进、投资经验新手/老手、初始资金、关注的投资标的等。更重要的是你可以注入行为金融学的特征例如“处置效应”过早卖出盈利股票而持有亏损股票或“彩票偏好”追逐极高风险、极小概率的收益。LLM会根据这些设定、当前的市场数据价格、成交量、个人持仓以及“读到”的新闻生成一个带有理由的买卖决策。这个过程不再是冷冰冰的规则判断而是带有“思考”痕迹的文本推理。社会互动层面这是TwinMarket最精彩的部分。系统模拟了一个股票论坛类似一个简化的社交媒体。智能体们可以在这里发布帖子由LLM生成内容可能是对某只股票的看法、对新闻的解读甚至是散布谣言。其他智能体可以浏览、评论这些帖子。通过这种互动信息包括真实信息和噪音得以传播观点得以形成或改变从而影响个体的交易决策。系统还会维护一个动态的社交关系图模拟“关注”与“被关注”的关系使得信息传播更具结构性和真实性。市场环境层面所有智能体产生的买卖订单会被发送到一个实时订单撮合引擎。这个引擎按照价格优先、时间优先的原则进行连续竞价匹配生成真实的成交记录和连续的价格序列K线。同时系统还会定时或事件驱动地发布“新闻”这些新闻会影响相关股票的基本面或市场情绪成为智能体决策的另一个重要输入。通过这三个层面的耦合TwinMarket实现了从微观异质性个体行为到中观社会网络动态再到宏观市场现象如波动率聚集、成交量飙升、价格趋势形成的完整闭环。研究者可以像做实验一样控制某个变量例如引入一条突发利空新闻或增加具有“跟风”特性的智能体比例然后观察整个系统会涌现出什么样的结果。注意这种基于LLM的模拟虽然强大但也带来了新的挑战主要是计算成本和行为稳定性。LLM API调用不便宜模拟成千上万个智能体需要精心的并发设计和成本控制。此外LLM输出具有一定随机性如何确保智能体行为在“合理”范围内波动而不是完全失控的“胡言乱语”需要设计良好的提示词Prompt和决策约束框架。3. 系统核心模块深度解析要上手或深度使用TwinMarket必须对其几个核心模块有清晰的理解。下面我们抛开代码先从逻辑层面拆解。3.1 交易者智能体拥有“人格”的LLM大脑交易者智能体是系统的原子单元。它的决策流程可以概括为以下几步信息感知在每个模拟步长例如每分钟智能体会收集三类信息私有状态自己的现金、持仓、盈亏情况、交易历史。公共市场信息所关注股票的最新价格、分时图、简单的技术指标如MA、RSI由系统计算提供。社会信息从论坛中爬取的近期热门帖子、关注的其他交易者动态。新闻信息系统广播的与持仓股票或大盘相关的新闻摘要。决策生成将以上信息整合成一个结构化的提示词Prompt提交给背后的LLM如GPT-4、Claude或开源模型。提示词的大致框架是“你是一个{风险偏好}{经验水平}的交易者当前市场情况是{…}你的持仓是{…}最近论坛里有人说{…}新闻显示{…}。请分析现状并决定买入、卖出还是持有如果交易数量是多少请给出你的理由。”动作执行与约束LLM会返回一个结构化的决策如{“action”: “BUY”, “symbol”: “AAPL”, “quantity”: 10, “reason”: “论坛普遍看好且技术面出现金叉”}。系统在执行前会进行一系列合理性检查现金是否足够下单数量是否超过仓位限制是否触发了日内交易限制这确保了模拟的金融合规性基础。记忆与学习智能体拥有一个简单的记忆机制会记录自己重要的交易决策及其结果盈亏。在后续决策中LLM可以引用这些记忆模拟“总结经验教训”的过程尽管目前这种学习还是基于上下文而非参数更新。实操心得设计有效的智能体“人设”要让模拟有趣且真实关键在于设计多样化的智能体类型。不要只设计“理性经济人”。你可以尝试混合以下类型趋势跟随者倾向于相信论坛中的主流观点和技术指标信号。价值投资者更关注新闻中透露的基本面信息对短期波动不敏感。噪声交易者其决策很大程度上基于情绪或随机因素是市场流动性的重要提供者也是价格偏离基本面的来源之一。高频套利者对微小价差敏感尝试捕捉不同智能体之间决策速度差带来的机会。 通过调整不同类型智能体的比例你可以模拟出截然不同的市场生态。3.2 社交网络与论坛模拟信息传播的温床论坛模块是模拟信息不对称和群体行为的关键。它的工作流程如下帖子生成智能体在特定条件下例如持仓股票大涨大跌、看到重大新闻会由LLM生成一篇帖子。提示词会引导它表达观点、分享“分析”或宣泄情绪。帖子内容可以是理性的分析也可以是充满情绪化的呐喊或谣言。帖子传播新发布的帖子会进入论坛的公共时间线。其他智能体根据其“社交活跃度”参数定期浏览时间线。社交关系图在这里起作用智能体更可能看到其“关注”的其他智能体发布的帖子。观点影响当智能体阅读帖子时LLM会评估该帖子内容对其原有观点的影响。一个被广泛转发、点赞可模拟此功能的帖子或是由一个被公认为“大神”的智能体发出的帖子其影响力权重会更高。这种影响会直接反馈到该智能体下一轮的决策提示词中例如“尽管我原本看空但多位资深交易者认为已到底部我决定谨慎观望”。这个模块极大地增加了模拟的涌现性。一条不起眼的假消息可能通过社交网络的放大最终引发一场不必要的恐慌性抛售。这正是现实市场中经常发生的。3.3 订单撮合引擎与市场状态生成这是将智能体“主观意愿”转化为客观市场数据的桥梁。它必须高效、准确。订单簿管理引擎维护一个中心限价订单簿Central Limit Order Book, CLOB。每个订单包含股票代码、买卖方向、价格、数量、时间戳、提交者ID。连续竞价撮合这是核心算法。遵循价格优先买价高的先成交卖价低的先成交时间优先同价订单按到达顺序的原则。当一个新的买单到达引擎会在卖单簿中寻找价格等于或低于其报价的订单进行匹配反之亦然。成交价通常为对手方订单的价格这是限价订单簿的标准行为。市场数据生成每一次成功的撮合产生一笔成交记录Trade。系统定期如每1分钟将期间的所有成交记录聚合生成一根K线包含开盘、最高、最低、收盘价和成交量。这个K线数据会立刻反馈给所有智能体成为他们下一轮决策的依据形成一个实时闭环。新闻事件注入系统管理员可以预设或在运行时动态注入新闻事件。新闻会影响相关股票的一个“基本面分数”或直接触发某些智能体的特定行为模式。这是进行可控实验的重要手段比如研究“美联储意外加息”公告对模拟市场的冲击路径。提示对于想要研究微观市场结构如订单流不平衡、买卖价差动态的研究者可以详细输出每一笔订单和成交的记录。对于更关注宏观现象的研究者则可以主要关注聚合后的K线数据。TwinMarket的架构支持这种不同颗粒度的数据输出。4. 从零开始搭建与运行你的第一次模拟理论说了这么多我们来点实际的。假设你已经在本地克隆了TwinMarket的仓库接下来如何让它跑起来4.1 环境配置与模型接入TwinMarket的核心依赖是Python和LLM API。首先解决最关键的一步配置模型。# 1. 复制配置文件模板 cp config/api_example.yaml config/api.yaml cp config/embedding_example.yaml config/embedding.yaml现在打开config/api.yaml。你需要配置LLM的访问点。项目通常支持OpenAI格式的API。# config/api.yaml 示例 (使用 OpenAI 兼容接口) openai: api_base: https://your-llm-api-endpoint/v1 # 如果是开源模型本地部署填写本地地址如 http://localhost:8080/v1 api_key: your-api-key-here # 如果是本地模型可能不需要或填写任意字符串 model: gpt-4 # 指定使用的模型名称本地模型则填写对应的模型名对于嵌入模型Embedding Model用于处理论坛帖子的语义分析或信息检索配置在config/embedding.yaml。如果你刚开始可以使用OpenAI的text-embedding模型或者使用开源的sentence-transformers库。# config/embedding.yaml 示例 (使用开源模型避免API调用) embedding: model_name: all-MiniLM-L6-v2 # 一个轻量级且效果不错的开源句子嵌入模型 # 如果使用此模型需要先安装 sentence-transformers: pip install sentence-transformers device: cpu # 或 cuda根据你的硬件情况重要注意事项成本控制如果你使用GPT-4等商用API模拟大量智能体或长时间运行费用会非常可观。强烈建议在初期使用小规模智能体如10-20个和开源模型进行测试。开源模型部署为了完全控制成本和隐私可以考虑在本地部署LLM。像Llama 3.1、Qwen 2.5等优秀的开源模型通过LM Studio、Ollama或vLLM等工具可以轻松部署成本地API服务然后将api_base指向http://localhost:11434/v1Ollama默认即可。虽然能力可能略逊于顶级商用模型但对于定义明确的交易决策任务通常已经足够。网络与延迟LLM API调用是网络IO密集型操作。模拟的实时性会受到网络延迟和API速率限制的影响。TwinMarket的并发设计就是为了优化这一点。4.2 编写你的第一个实验脚本项目提供了script/run.sh作为演示入口。但为了理解其内部逻辑我们可以看一个简化的Python脚本它完成了以下工作# my_first_simulation.py import asyncio from market.simulation_engine import SimulationEngine from trader.trader_factory import create_traders from social.forum import Forum from config.load_config import load_simulation_config async def main(): # 1. 加载配置 config load_simulation_config(config/simulation_example.yaml) # 2. 初始化核心组件 forum Forum() matching_engine MatchingEngine() # 3. 创建一群交易者智能体 # 假设配置中定义了5种不同类型的交易者各2个共10个 traders await create_traders(config[traders], forum) # 4. 初始化模拟引擎并注入组件 sim_engine SimulationEngine( traderstraders, forumforum, matching_enginematching_engine, configconfig ) # 5. 运行模拟例如模拟10个交易日每天240分钟4小时 total_steps 10 * 240 await sim_engine.run(stepstotal_steps) # 6. 收集并分析结果 results sim_engine.collect_results() print(f模拟结束。共产生 {results[total_trades]} 笔交易。) # 这里可以将 results 保存为CSV或进行可视化 if __name__ __main__: asyncio.run(main())你需要一个config/simulation_example.yaml来定义模拟参数# 模拟基础设置 simulation: symbols: [STOCK_A, STOCK_B] # 模拟的股票代码 initial_price: {STOCK_A: 100.0, STOCK_B: 50.0} # 初始价格 steps_per_day: 240 # 每日模拟步数每分钟一次 # 交易者群体配置 traders: - type: trend_follower count: 4 risk_appetite: medium initial_cash: 100000 - type: value_investor count: 3 risk_appetite: low initial_cash: 150000 - type: noise_trader count: 3 risk_appetite: high initial_cash: 50000 # 社交网络配置 social: enable_forum: true post_probability: 0.05 # 每个智能体每一步发帖的概率 max_posts_per_step: 5 # 论坛每步显示的最新帖子数 # 新闻事件计划可选 news_schedule: - step: 120 # 在第120步模拟的第二天中午注入新闻 symbol: STOCK_A content: 公司STOCK_A发布超预期季度财报净利润同比增长50%。 impact: positive # 系统会根据这个标签影响智能体运行这个脚本你就启动了一个拥有10个不同性格智能体、两只股票、带有论坛功能的微型金融市场。接下来就是观察和分析了。4.3 结果分析与可视化模拟结束后数据是最宝贵的财富。TwinMarket会生成丰富的数据流市场数据每个模拟步长的K线数据OHLCV。你可以用pandas和matplotlib或plotly像分析真实股票一样分析它。import pandas as pd import matplotlib.pyplot as plt # 假设 market_data 是一个包含时间、开盘价、最高价、最低价、收盘价、成交量的DataFrame plt.figure(figsize(12,6)) plt.plot(market_data[close]) plt.title(Simulated Stock Price) plt.xlabel(Simulation Step) plt.ylabel(Price) plt.grid(True) plt.show()个体数据每个交易者每一步的持仓、现金、资产总值、买卖订单历史。这可以用来计算夏普比率、最大回撤等传统指标更重要的是可以分析个体行为模式比如“处置效应”是否在模拟中显现盈利头寸持有时间是否显著短于亏损头寸。社交数据所有论坛帖子的内容、发帖人、时间戳。你可以进行简单的文本情感分析绘制帖子情感指数与市场价格波动的相关性图或者分析信息传播的网络结构。实操心得如何设计一个有价值的实验不要只满足于“跑起来”。科学的模拟需要控制变量。例如实验A论坛功能关闭。智能体仅根据私有信息和公开市场数据交易。实验B论坛功能开启但禁止发布假消息。实验C论坛功能开启且允许一定比例的谣言传播。 比较A、B、C三种情况下市场的波动率、价格偏离基本面的程度、羊群效应指标如订单流相关性有何差异。这样的实验才能揭示“社交互动”对市场稳定性的具体影响。5. 高级定制与扩展指南TwinMarket是一个框架其强大之处在于可扩展性。以下是几个常见的扩展方向。5.1 实现自定义交易策略虽然LLM是决策核心但你可以为其设计更专业的决策框架。项目在trader/trading_agent.py中提供了策略接口。假设你想实现一个结合了传统技术分析和LLM情绪分析的混合策略class HybridTradingAgent(BaseTradingAgent): def __init__(self, agent_id, config, llm_client, forum): super().__init__(agent_id, config, llm_client, forum) # 加载你的技术分析库 self.tech_analyzer TechnicalAnalyzer() async def decide_action(self, market_state, personal_state): # 1. 技术分析信号 tech_signal self.tech_analyzer.generate_signal(market_state[price_history]) # 2. 从论坛获取情绪信号通过LLM分析近期帖子摘要 forum_summary await self.summarize_forum_sentiment() # 3. 构建混合决策Prompt prompt f 你是一个混合型交易员。请综合以下信息做出决策 - 技术分析信号{tech_signal}。 - 当前市场情绪来自论坛摘要{forum_summary}。 - 你的当前状态{personal_state}。 请输出你的交易决策。 llm_decision await self.llm_client.query(prompt) # 4. 解析LLM输出并加入你自己的风险控制逻辑 final_action self._apply_risk_management(llm_decision, personal_state) return final_action def _apply_risk_management(self, llm_decision, state): # 例如如果LLM建议全仓买入但你的风险规则禁止仓位超过80%则进行调整。 if llm_decision[action] BUY and (state[position] llm_decision[quantity]) state[total_assets] * 0.8: llm_decision[quantity] int(state[total_assets] * 0.8 - state[position]) llm_decision[reason] (因风控规则调整了买入数量) return llm_decision5.2 添加新的评估指标在trader/utility.py或单独的分析模块中你可以添加任何感兴趣的指标。def calculate_herding_degree(order_flow): 计算羊群效应程度。 输入一段时间内所有交易者的订单流列表包含买卖方向。 输出羊群效应指标例如订单方向一致性的赫芬达尔指数。 from collections import Counter if not order_flow: return 0.0 # 统计买单和卖单数量 action_counts Counter(order_flow) buy_count action_counts.get(BUY, 0) sell_count action_counts.get(SELL, 0) total buy_count sell_count if total 0: return 0.0 # 计算赫芬达尔-赫希曼指数 (HHI)用于衡量集中度 hhi (buy_count/total)**2 (sell_count/total)**2 # HHI越接近0.5两个方向各半羊群效应越弱越接近1完全一致羊群效应越强。 # 我们将其归一化到0-1之间1表示完全羊群。 herding_degree (hhi - 0.5) * 2 # 当hhi0.5时为0hhi1时为1 return max(0.0, herding_degree) # 确保非负 def analyze_disposition_effect(trade_history): 分析处置效应。 输入一个交易者的交易历史每条记录包含股票、买入价、卖出价、持有时间、盈亏。 输出盈利交易平均持有时间 vs 亏损交易平均持有时间。 winning_trades [t for t in trade_history if t[pnl] 0] losing_trades [t for t in trade_history if t[pnl] 0] if not winning_trades or not losing_trades: return None avg_hold_win sum(t[hold_period] for t in winning_trades) / len(winning_trades) avg_hold_lose sum(t[hold_period] for t in losing_trades) / len(losing_trades) return { avg_hold_winning: avg_hold_win, avg_hold_losing: avg_hold_lose, disposition_effect_ratio: avg_hold_lose / avg_hold_win if avg_hold_win 0 else float(inf) # 比率大于1表明存在处置效应亏损持有更久 }5.3 接入真实数据与进行回测TwinMarket的初始价格是设定的但你可以轻松地将其改造成一个“历史情境模拟器”。数据接入编写一个数据加载器从CSV、数据库或在线API如雅虎财经读取某只股票的历史K线数据。情境注入将历史数据按时间步长“喂”给模拟引擎作为每个步长的公开市场信息开盘、最高、最低、收盘价。这样智能体就是在真实的历史价格环境下进行决策。决策与回测智能体基于历史价格、模拟的新闻和社交信息做出买卖决策。但由于价格历史是固定的他们的订单不会影响历史价格本身即没有反事实影响。这更像是一个“在历史中模拟交易者行为”的实验可以用来测试不同行为模型在历史波动中的表现或者研究如果历史上存在某种社交网络信息传播会如何改变交易行为。这种模式对于验证智能体策略在历史压力下的稳健性非常有用。6. 常见问题、踩坑记录与性能优化在实际使用中你肯定会遇到一些问题。以下是我在实验过程中总结的一些典型问题和解决方案。6.1 LLM相关问题问题可能原因解决方案智能体决策荒谬如以天价买入Prompt设计不佳未给予足够的约束和上下文。在Prompt中明确角色设定、风险约束和决策格式。例如“你最多只能使用20%的现金进行单笔交易”“价格必须在最近10根K线的最高价和最低价之间”。使用少样本提示Few-shot Prompting在Prompt里给几个正确决策的例子。API调用速度慢模拟卡顿网络延迟或API速率限制。智能体串行调用。1.使用异步并发TwinMarket本身使用asyncio确保你的自定义Agent也采用异步方式调用LLM。2.批量请求如果后端API支持可以将多个智能体的Prompt打包成一个批量请求。3.使用更轻量的模型对于决策任务GPT-3.5-Turbo或优秀的开源7B/13B模型通常足够且更快更便宜。成本失控智能体数量多、模拟步长长、使用了昂贵模型。1.本地部署开源模型这是控制成本的终极方案。2.缓存LLM响应对于相似的市场状态智能体可能做出相同决策。可以设计一个简单的缓存机制以智能体类型市场状态哈希为键缓存决策结果。3.减少模拟频率不一定需要每分钟决策一次可以调整为每5分钟或每小时。输出格式不稳定LLM可能不严格按照要求的JSON格式输出。在调用LLM时使用函数调用Function Calling或结构化输出JSON Mode特性。几乎所有主流API和开源模型框架都支持。这能极大提高输出解析的稳定性。6.2 模拟逻辑与性能问题问题可能原因解决方案市场流动性枯竭所有智能体观点一致只买不卖或只卖不买。1.引入做市商智能体专门提供流动性在买卖盘挂出小额订单。2.增加噪声交易者比例他们的随机交易能为市场提供基础流动性。3.引入外生冲击定时注入让部分智能体强制平仓或调整仓位的“生活支出”事件。价格波动过于剧烈或死寂智能体行为同质化太强或参数设置不合理。1.增强智能体多样性确保有趋势跟踪者、反转交易者、价值投资者、噪声交易者等多种类型。2.调整决策阈值例如提高智能体做出交易决策所需的“信心度”。3.在撮合引擎中加入小幅滑点或随机延迟以平滑交易。模拟速度随智能体数量增加线性下降每个智能体的决策、论坛交互都是计算/IO瓶颈。1.事件驱动优化并非每个步长每个智能体都必须决策。可以设置为当价格波动超过一定幅度、或收到相关新闻时再触发决策。2.论坛信息聚合智能体不阅读所有帖子而是阅读由系统LLM生成的“每日/每时段市场情绪摘要”大幅减少调用次数。3.使用更快的嵌入模型如果用到语义检索all-MiniLM-L6-v2在CPU上就很快足以应对实验需求。6.3 研究可复现性问题问题可能原因解决方案每次运行结果差异巨大LLM输出的随机性、智能体初始化的随机性。1.设置随机种子为Python的random、numpy以及LLM如果支持设置固定的随机种子。2.多次运行取统计量任何基于LLM的模拟实验其结果都应被视为一个分布。关键指标如平均收益率、波动率需要报告其多次运行后的均值和标准差。3.记录完整配置将使用的模型版本、Prompt模板、所有智能体参数、随机种子完整记录在实验日志中。最后一点个人体会TwinMarket打开了一扇新的大门但它不是一个“即插即用”的答案生成器。最大的挑战和乐趣在于如何设计一个“合理”的模拟世界。这需要你对金融市场、行为经济学、多智能体系统都有一定的理解。开始时不妨从最简单的设定入手一两只股票三五类智能体先让系统稳定跑起来观察基础现象。然后像做实验一样每次只改变一个变量比如增加论坛的谣言传播概率仔细观察市场动态如何变化。这个过程本身就是对我们所理解的金融市场的一次深刻检验和探索。