Python量化交易框架实战:从事件驱动架构到策略回测全解析

news2026/5/10 6:18:22
1. 项目概述量化交易的开源工具箱最近几年量化交易的热度持续不减无论是机构还是个人开发者都在寻找高效、可靠的策略研发与回测工具。如果你也在这个领域摸索大概率听说过或者用过一些知名的开源框架比如backtrader、zipline或者更现代的vectorbt。今天我想和大家深入聊聊一个相对较新但在设计理念和工程实践上让我眼前一亮的项目dsinyakov/quant。这个项目本质上是一个用 Python 构建的量化交易研究框架。它不是一个提供“圣杯”策略的代码库而是一个工具箱和脚手架旨在帮助开发者快速、规范地构建、回测和评估自己的交易策略。我第一次接触它是因为厌倦了在Jupyter Notebook里写一堆难以维护的“面条代码”也受够了某些框架过于笨重、学习曲线陡峭的问题。quant吸引我的地方在于它的“恰到好处”——它提供了必要的结构比如数据管理、事件驱动引擎、风险控制模块但又没有过度封装保留了足够的灵活性让你能清晰地掌控策略的每一个逻辑环节。简单来说dsinyakov/quant适合这样几类朋友一是已经有了一些金融市场和 Python 基础想系统化学习量化策略开发流程的入门者二是正在寻找一个轻量级、可扩展框架来替代现有杂乱研究环境的进阶开发者三是希望理解一个事件驱动型回测系统内部如何运作并可能想自己动手造轮子的技术爱好者。接下来我会结合自己实际使用的经验从设计思路到核心模块再到实操中的坑与技巧为你完整拆解这个项目。2. 核心架构与设计哲学解析2.1 事件驱动引擎一切的核心与许多基于向量化运算一次性对整个时间序列进行计算的回测库不同quant采用了经典的事件驱动Event-Driven架构。这是它最核心的设计也是理解其所有组件的基础。为什么选择事件驱动向量化回测速度快实现简单非常适合验证简单的指标逻辑。但它有一个致命缺点无法处理复杂的、依赖于当前状态和未来信息不可见的交易逻辑。例如当你的策略需要根据当前持仓、可用资金、以及刚刚到达的订单成交回报来决定下一笔交易时向量化回测就力不从心了因为它本质上是在“上帝视角”下一次性处理所有数据。事件驱动则模拟了真实交易环境。它将市场数据如新的K线、订单状态更新、时间推移等都封装为“事件”Event并按时间顺序推送给策略引擎。策略像在真实交易中一样被动地响应这些事件并做出决策。这种方式回测速度相对较慢但仿真度极高能够处理任意复杂的、有状态stateful的策略逻辑包括仓位管理、风险控制、订单类型限价单、市价单的模拟等。在quant中主要的事件类型包括MarketEvent: 新的行情数据到达。SignalEvent: 策略逻辑产生的交易信号。OrderEvent: 根据信号生成的订单请求。FillEvent: 订单在模拟交易所中成交的回报。这种设计让策略的逻辑流非常清晰数据流 - 策略生成信号 - 投资组合模块处理信号生成订单 - 执行模拟器撮合订单 - 更新账户状态形成一个闭环。2.2 模块化设计高内聚与低耦合quant的代码结构体现了清晰的模块化思想每个组件职责单一通过定义良好的接口进行通信。这种设计带来的最大好处是可维护性和可测试性极佳。你可以轻易地替换其中任何一个模块比如把从 CSV 文件读取数据换成从数据库或在线 API如akshare,yfinance获取数据而无需改动策略逻辑。主要模块包括数据处理器DataHandler负责所有市场数据的获取、清洗和组织。它向策略提供统一的接口来请求历史数据和实时数据。策略Strategy这是你发挥创意的地方。它订阅数据在接收到MarketEvent后运行你的交易逻辑并可能产生SignalEvent。投资组合Portfolio这是策略的“大脑”和“风控”。它接收SignalEvent但决定是否执行、执行多少。它综合考虑当前持仓、风险暴露、资金情况、交易成本滑点、佣金等最终生成具体的OrderEvent。这是区分业余和专业策略的关键模块。执行处理器ExecutionHandler模拟交易所的撮合引擎。它接收OrderEvent根据设定的撮合规则例如下一根K线的开盘价成交或考虑买卖盘口模拟限价单生成FillEvent。回测引擎Backtest负责将以上所有模块串联起来驱动事件循环推进时间并记录每一笔交易和最终绩效。注意很多新手会直接把交易逻辑写在Strategy里而忽略了Portfolio的重要性。实际上一个健壮的Portfolio模块应该负责仓位大小计算、金字塔加仓/减仓、整体止损止盈等风险管理功能。Strategy只应负责产生“方向性信号”例如“强烈看多”、“看空”具体的交易规模应由Portfolio决定。3. 关键组件深度拆解与实战配置3.1 数据层灵活接入与规范化处理数据是量化的基石。quant默认的数据处理器通常从 CSV 或pandas.DataFrame读取数据但我们可以轻松扩展它。这里以接入akshare获取A股数据为例展示如何自定义数据处理器。首先你需要理解数据处理器必须提供的核心方法主要是get_latest_bars和update_bars。下面是一个简化的自定义类import pandas as pd import akshare as ak from abc import ABC, abstractmethod class AkshareDataHandler(DataHandler): def __init__(self, symbol_list, start_date, end_date): self.symbol_list symbol_list self.start_date start_date self.end_date end_date self.data self._load_data() self.continue_backtest True self.bar_index 0 def _load_data(self): 使用akshare批量下载数据并转换为统一的格式。 注意akshare的数据接口可能有频率限制生产环境需考虑缓存和容错。 all_data {} for symbol in self.symbol_list: # 示例获取日线前复权数据 df ak.stock_zh_a_hist(symbolsymbol[3:], perioddaily, start_dateself.start_date, end_dateself.end_date, adjustqfq) # 规范化列名和索引 df.rename(columns{ 日期: datetime, 开盘: open, 最高: high, 最低: low, 收盘: close, 成交量: volume }, inplaceTrue) df[datetime] pd.to_datetime(df[datetime]) df.set_index(datetime, inplaceTrue) df.sort_index(inplaceTrue) all_data[symbol] df return all_data def get_latest_bars(self, symbol, N1): 获取某个标的最近N条Bar数据。 这是策略中最常用的方法。 if N 1: # 返回一个Series提高效率 return self.data[symbol].iloc[self.bar_index] else: # 返回一个DataFrame end_idx self.bar_index 1 start_idx max(0, end_idx - N) return self.data[symbol].iloc[start_idx:end_idx] def update_bars(self): 推进到下一个时间点。当所有数据都消耗完时标记回测结束。 self.bar_index 1 if self.bar_index min(len(self.data[sym]) for sym in self.symbol_list): self.continue_backtest False实操要点数据对齐多标的回测时必须确保所有数据的时间索引完全对齐否则会导致持仓计算错乱。可以使用pandas.DataFrame.align方法。数据质量务必检查并处理缺失值NaN。常见的做法是前向填充ffill或直接删除缺失日期。akshare等接口返回的节假日数据可能为空。性能考虑如果数据量很大频繁调用get_latest_bars可能会成为瓶颈。可以考虑将数据预加载到内存中的字典或使用更高效的数据结构如numpy数组。3.2 策略开发从想法到信号事件策略类需要继承框架的基类并实现两个核心方法calculate_signals和在初始化时设置数据订阅。下面实现一个简单的双均线交叉策略class MovingAverageCrossStrategy(Strategy): 经典的双均线交叉策略。 当短期均线上穿长期均线时产生多头信号下穿时产生空头信号。 def __init__(self, data, symbols, short_window20, long_window50): self.data data self.symbols symbols self.short_window short_window self.long_window long_window # 用于记录策略内部状态例如是否已持仓 self.bought {symbol: False for symbol in self.symbols} def calculate_signals(self, event): if event.type MARKET: for symbol in self.symbols: # 获取足够的历史数据来计算长周期均线 bars self.data.get_latest_bars(symbol, Nself.long_window) if len(bars) self.long_window: # 数据不足跳过 continue df pd.DataFrame(bars) if isinstance(bars, pd.Series) else bars short_sma df[close].rolling(windowself.short_window).mean().iloc[-1] long_sma df[close].rolling(windowself.long_window).mean().iloc[-1] # 生成信号逻辑 if short_sma long_sma and not self.bought[symbol]: # 金叉且未持仓产生多头信号 signal SignalEvent(symbol, LONG) # 将信号放入事件队列 self.events.put(signal) self.bought[symbol] LONG elif short_sma long_sma and self.bought[symbol]: # 死叉且持有多头产生平仓信号或空头信号取决于策略设计 signal SignalEvent(symbol, EXIT) # 这里用EXIT平仓 self.events.put(signal) self.bought[symbol] False注意事项未来函数这是策略开发第一大忌。确保在计算指标时只使用到当前bar_index及之前的数据。get_latest_bars(N)返回的是截止当前时点的最近N条数据必须正确理解这个“当前”。信号闪烁在高频或tick级数据中价格微小波动可能导致指标在临界点反复交叉产生大量无效交易信号。需要在策略中加入过滤条件例如要求价格突破均线一定百分比或者加入时间延迟确认。状态管理self.bought这样的状态变量至关重要。它帮助策略记住当前的持仓立场避免在已经持有多头的情况下连续发出多头信号。更复杂的策略可能需要记录更多状态如入场价格、持仓时间等。3.3 投资组合管理策略的“大脑”这是最能体现量化功力的模块。一个简单的Portfolio可能只是机械地执行所有信号但一个成熟的Portfolio需要处理以下问题头寸规模计算是固定股数/手数还是固定资金比例是否使用凯利公式或波动率调整仓位风险管理单笔交易最大亏损、每日最大亏损、整体净值回撤控制。订单生成逻辑如何将抽象的“多头信号”转化为具体的“以当前市价买入100股”的订单交易成本佣金、印花税、滑点Slippage的精确模拟。下面是一个简化版的、按固定比例分配资金的组合管理模块核心逻辑class NaivePortfolio(Portfolio): def __init__(self, data, initial_capital100000.0): self.data data self.initial_capital initial_capital self.current_capital initial_capital self.positions {} # 记录各标的持仓 {symbol: shares} self.holdings pd.DataFrame(columns[cash, total]) # 记录每日持仓明细 def update_signal(self, signal_event): symbol signal_event.symbol direction signal_event.signal_type current_price self.data.get_latest_bars(symbol)[close] # 简单的固定比例仓位管理每次动用20%的总资产 target_value self.current_capital * 0.20 if direction LONG and symbol not in self.positions: # 计算可买股数向下取整 quantity int(target_value / current_price) if quantity 0: order OrderEvent(symbol, BUY, quantity) self.events.put(order) elif direction EXIT and symbol in self.positions: # 平仓全部持仓 quantity self.positions[symbol] order OrderEvent(symbol, SELL, quantity) self.events.put(order) def update_fill(self, fill_event): 根据成交回报更新现金和持仓。 这是最核心的会计逻辑务必准确。 symbol fill_event.symbol fill_price fill_event.fill_price quantity fill_event.quantity direction fill_event.direction # 计算交易成本此处简化仅考虑佣金 commission abs(fill_price * quantity) * 0.0003 # 假设万三佣金 cost fill_price * quantity commission if direction BUY: self.current_capital - cost self.positions[symbol] self.positions.get(symbol, 0) quantity elif direction SELL: self.current_capital (fill_price * quantity - commission) self.positions[symbol] - quantity if self.positions[symbol] 0: del self.positions[symbol] # 更新每日持仓记录 self._update_holdings()核心心得持仓市值计算在_update_holdings方法中需要遍历所有持仓用最新市价计算总市值。current_capital 所有持仓市值 总资产净值。这个净值曲线是计算所有绩效指标的基础。滑点模拟在ExecutionHandler中模拟滑点更为合适。可以在成交价上加上一个随机扰动或固定比例的点差。例如fill_price order_price * (1 np.random.uniform(-0.0005, 0.0005))模拟5个基点的滑点。多标的资金分配当同时交易多个标的时需要有一个全局的资金分配器防止过度使用杠杆。上面的简单例子是独立分配更好的做法是有一个中央资金池所有订单申请都向资金池提出由它统一审批和分配。4. 完整回测流程搭建与执行4.1 环境配置与依赖安装首先你需要将项目克隆到本地。由于dsinyakov/quant可能没有发布到 PyPI最直接的方式是从 GitHub 克隆。git clone https://github.com/dsinyakov/quant.git cd quant检查项目根目录下是否有requirements.txt或setup.py文件。通常核心依赖包括pandasnumpy: 数据处理基石。matplotlib: 用于绘制净值曲线和绩效图表。可能还有seaborn,scipy等用于统计分析。建议使用虚拟环境进行管理python -m venv venv # Windows venv\Scripts\activate # Linux/Mac source venv/bin/activate pip install -r requirements.txt # 如果没有requirements.txt手动安装 pip install pandas numpy matplotlib4.2 组装你的第一个回测现在我们将数据、策略、组合、执行器像拼乐高一样组装起来并运行回测。以下是一个完整的脚本示例import pandas as pd import matplotlib.pyplot as plt from quant.data import CSVDataHandler from quant.strategy import MovingAverageCrossStrategy from quant.portfolio import NaivePortfolio from quant.execution import SimulatedExecutionHandler from quant.backtest import Backtest # 1. 定义参数 symbol_list [000001.SZ, 000002.SZ] # 股票代码需与数据文件对应 initial_capital 100000.0 start_date 2020-01-01 end_date 2023-12-31 data_dir ./your_data_folder/ # 2. 实例化组件 data_handler CSVDataHandler(symbol_list, data_dir) strategy MovingAverageCrossStrategy(data_handler, symbol_list, 10, 30) portfolio NaivePortfolio(data_handler, initial_capital) execution SimulatedExecutionHandler() # 3. 创建并运行回测引擎 backtest Backtest(data_handler, strategy, portfolio, execution, initial_capitalinitial_capital) results, equity_curve backtest.run() # 4. 输出绩效报告 print(回测结果摘要:) print(f初始资金: {initial_capital}) print(f最终净值: {results[final_portfolio_value]:.2f}) print(f总收益率: {results[total_return]*100:.2f}%) print(f年化收益率: {results[annualized_return]*100:.2f}%) print(f最大回撤: {results[max_drawdown]*100:.2f}%) print(f夏普比率: {results[sharpe_ratio]:.2f}) print(f总交易次数: {results[total_trades]}) # 5. 绘制净值曲线 plt.figure(figsize(12,6)) plt.plot(equity_curve.index, equity_curve[total], label策略净值, linewidth2) # 可以叠加基准曲线如沪深300指数 # plt.plot(benchmark.index, benchmark[close] / benchmark[close].iloc[0] * initial_capital, label基准, linestyle--) plt.title(策略净值曲线) plt.xlabel(日期) plt.ylabel(资产净值 (元)) plt.legend() plt.grid(True, linestyle--, alpha0.5) plt.show()运行与调试首次运行大概率会报错最常见的是路径错误或数据格式不匹配。耐心查看错误堆栈信息从最下面开始读起。使用print或logging模块在关键节点如事件产生、订单成交输出信息是调试事件驱动系统最有效的方法。建议先用单一标的、短时间的数据跑通整个流程再逐步增加复杂度。4.3 绩效分析超越简单的收益率回测跑出净值曲线只是第一步深入分析绩效报告才能判断策略的真实潜力与风险。quant项目通常包含一个performance模块来计算各类指标你需要理解这些指标的含义指标计算公式与说明解读与经验阈值总收益率(最终净值 - 初始资金) / 初始资金最直观的盈利指标但单独看意义不大。年化收益率(1 总收益率)^(252 / 交易日数) - 1标准化到每年的收益。A股主观多头策略年化15-20%已属优秀。最大回撤净值从前期高点回落的最大幅度。Max(1 - 当日净值 / 之前最高净值)核心风险指标。描述你可能承受的最大亏损。超过20%的回撤对大多数投资者来说难以忍受。夏普比率(年化收益率 - 无风险利率) / 年化波动率衡量承担每单位风险所获得的超额回报。通常大于1为可接受大于2为优秀假设无风险利率为3%。索提诺比率(年化收益率 - 无风险利率) / 下行波动率类似夏普但只惩罚下跌波动坏波动对趋势策略更友好。胜率盈利交易次数 / 总交易次数并非越高越好。高胜率策略往往盈亏比较低。需结合盈亏比看。平均盈亏比平均盈利金额 / 平均亏损金额衡量策略的赔率。一般追求大于1.5。交易次数总开平仓次数过于频繁的交易可能导致收益被手续费侵蚀。重要提示切勿过度优化Over-fitting策略参数以追求漂亮的回测结果。这会导致策略在未来实盘中失效。务必进行样本外测试将数据分为训练集和测试集和向前滚动窗口分析Walk-Forward Analysis来检验策略的稳健性。5. 进阶话题与常见问题排查5.1 如何引入更复杂的策略逻辑基础均线策略只是入门。你可以将任何你能用代码表述的逻辑融入Strategy.calculate_signals方法中。机器学习策略在数据处理器中计算特征如技术指标、价量关系、基本面因子在策略中加载训练好的模型进行预测将预测结果转化为信号。注意严防前瞻性偏差特征计算必须仅使用历史数据。多因子合成计算多个因子如价值、动量、质量等进行标准化、中性化处理后通过加权打分生成综合信号。事件驱动策略监听财报发布日期、宏观经济数据公布等事件在事件发生后特定时间窗口内执行交易逻辑。这需要在数据流中注入自定义的NewsEvent或MacroEvent。5.2 回测中常见的“坑”与解决方案幸存者偏差回测使用的股票列表都是“活到”今天的公司那些已经退市的公司被排除在外了这会导致回测结果虚高。解决方案使用全历史股票池。在每一个回测时点只使用当时已上市且未被ST的股票。这需要更复杂的数据支持。前视偏差不小心使用了未来的信息。除了指标计算更隐蔽的包括使用了财报发布日期后才公布的财务数据实际获取有延迟、使用了调整后的复权价格但交易逻辑却按未复权价格思考。解决方案严格进行时间对齐。确保任何用于决策的数据其“知晓时间”不晚于决策时间。对财务数据引入报告期滞后如3个月。过拟合在历史数据上反复调整参数直到曲线完美拟合。解决方案坚持样本外检验。用70%的数据训练集开发策略用剩下30%测试集验证。参数优化应使用交叉验证等方法。交易成本与流动性低估回测中假设任何数量的股票都能以收盘价瞬间成交这在高频或大资金策略中完全不现实。解决方案在ExecutionHandler中引入更精细的滑点模型固定比例、随机比例、基于订单簿深度的模型和成交量限制单笔交易不超过当日成交量的某个百分比。5.3 性能优化技巧当股票池很大或回测周期很长时纯Python循环可能变得很慢。以下是一些优化思路向量化操作在策略的信号计算部分尽量使用pandas和numpy的向量化函数避免在时间循环内进行标的循环。例如可以一次性计算全股票池的均线矩阵。使用numba或Cython对计算密集型的核心函数如指标计算使用numba进行即时编译可获得数十倍的速度提升。事件循环优化检查事件队列的处理逻辑确保没有不必要的循环或重复计算。5.4 从回测到模拟交易的桥梁quant框架的事件驱动架构有一个天然优势回测引擎和实盘交易引擎可以共享绝大部分代码数据处理器、策略、投资组合。要将策略部署到实盘主要需要替换两个模块数据处理器从回测的 CSV/数据库读取改为订阅实时行情 API如券商提供的接口、付费数据源。执行处理器从模拟撮合器改为连接实盘交易 API 的下单器。你需要处理网络重连、异常处理、订单状态查询、心跳维护等工程性问题。建议先从模拟交易Paper Trading开始即使用实时数据但交易指令不发往交易所而是由本地模拟器撮合验证策略在实时环境下的稳定性。6. 项目总结与个人实践建议经过对dsinyakov/quant项目的深度拆解和使用我认为它最大的价值不在于提供了多少现成的策略而在于它提供了一个清晰、规范、可扩展的量化研究框架范本。通过亲手实现或修改其中的每一个模块你能深刻理解一个交易系统是如何运作的数据如何流动风险如何控制。这是使用那些高度封装的“一键回测”平台所无法获得的经验。对于想要深入学习的开发者我的建议是不要急于求成不要一开始就想着开发赚钱的策略。先用这个框架把双均线策略从头到尾跑通理解每一个事件、每一行代码的作用。精读源码花时间阅读项目源码尤其是Backtest类中的事件循环逻辑这是整个框架的引擎。动手改造尝试修改它。比如把简单的固定比例仓位管理改成基于波动率ATR的动态仓位管理或者在投资组合中加入一个最大回撤止损的模块。重视回测的“真实性”在你能想到的范围内尽可能让回测环境接近真实。考虑成本、滑点、涨停跌停限制、停牌、除权除息。一个在“理想国”里表现优异的策略在现实世界中可能不堪一击。保持怀疑对任何漂亮的回测结果保持高度怀疑。思考其中是否存在前面提到的各种偏差。量化交易是一场与概率和自身认知偏差的战斗一个好的框架是你可靠的武器但如何使用它取决于持剑的人。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2599838.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…