当前位置:首页>python>手把手带你用 Python 搭建多品种量化回测系统

手把手带你用 Python 搭建多品种量化回测系统

  • 2026-02-07 23:27:59
手把手带你用 Python 搭建多品种量化回测系统
01
多品种 RSI 量化回测系统

在量化投资的世界里,“回测”是连接交易灵感与实盘获利之间最重要的桥梁。很多初学者掌握了基础的 Python 语法,却苦于不知道如何将策略逻辑转化为可视化的回测报告。

今天,我们将通过三份依次进阶的代码示例,详细拆解如何使用 Python 最流行的回测框架 Backtrader,结合 Tushare 数据源,搭建一个支持多品种并行自定义资金分析且拥有专业图表展示的量化系统。

在开始之前,我们需要认识一下支撑这个系统的“四驾马车”:

  1. Backtrader: Python 界的量化回测“瑞士军刀”,功能强大且灵活。

  2. Tushare: 免费且好用的金融数据接口,为策略提供“燃料”。

  3. Pandas: 数据处理神器,用于清洗和准备行情数据。

  4. Matplotlib: 绘图库,负责将枯燥的数据转化为直观的资金曲线。

策略逻辑:反直觉的 RSI 动量策略

通常教科书上的 RSI(相对强弱指标)用法是“高抛低吸”(>70 卖出,<30 买入)。但本代码采用了动量突破的逻辑:

  • 买入信号:当 RSI > 70 且当前无持仓时,买入。

    • 逻辑:认为市场进入强势上涨区间,追涨。

  • 卖出信号:当 RSI < 30 且持有仓位时,卖出。

    • 逻辑:认为市场趋势彻底反转,止损或止盈离场。

这个策略不再博取震荡收益,而是试图捕捉强劲的单边趋势。

代码拆解

1. 数据的准备与清洗

量化的第一步是获取高质量数据。代码中定义了三个主要指数:中证500、中证1000、创业板指。代码展示了如何处理多只股票/指数。Backtrader 允许同时加载多个数据源(Data Feeds),这对于测试投资组合策略至关重要。

# 数据获取与清洗核心片段for code, name in indices:    df = ts.get_k_data(code, start='2014-01-01'# 从 Tushare 获取数据    # ... 数据清洗步骤 ...    data_feed = bt.feeds.PandasData(..., dataname=df)    cerebro.adddata(data_feed, name=name) # 加载到回测引擎

2. 策略引擎的实现

这是整个系统的“大脑”。我们在 MultiAssetRSIStrategy 类中定义交易规则。

class MultiAssetRSIStrategy(bt.Strategy):    def __init__(self):        # 为每一个数据源(指数)单独创建一个 RSI 指标        self.rsi_indicators = []        for data in self.datas:            rsi = bt.indicators.RSI(data.close, period=14)            self.rsi_indicators.append(rsi)    def next(self):        # 遍历所有资产,独立判断买卖逻辑        for data, rsi in self.asset_indicators:            position = self.getposition(data)            if not position and rsi[0] > 70# 强势突破买入                self.buy(data=data, size=100)            elif position and rsi[0] < 30:   # 趋势走坏卖出                self.sell(data=data, size=100)
zip(self.datas, self.rsi_indicators)的写法非常 Pythonic,优雅地实现了多品种的循环遍历,互不干扰。

3. 独家定制:资金分析器 (Analyzer)

Backtrader 自带的绘图虽然方便,但无法灵活定制。为了画出类似基金净值的曲线,代码中手写了一个 CashValueAnalyzer

class CashValueAnalyzer(bt.Analyzer):    def next(self):        # 每一个交易日,记录下当天的总资产(现金+持仓市值)        current_value = self.strategy.broker.getvalue()        self.cash_values.append(current_value)

4. 专业级可视化 (Visualization)

代码最精彩的部分在于最后的绘图优化。为了解决 Matplotlib 默认日期显示杂乱的问题,代码使用了专业的 Locator 和 Formatter。

图表优化细节:

  • 中文字体支持:配置 SimHei 等字体,彻底解决乱码。

  • 主/副刻度分离

    • 主刻度:显示年份(如 2015, 2016),不仅清晰而且不拥挤。

    • 副刻度:显示季度/月份,提供细节参考。

# 核心绘图优化代码ax.xaxis.set_major_locator(MonthLocator(interval=12, bymonth=1)) # 每年一个主刻度ax.xaxis.set_major_formatter(DateFormatter('%Y'))                # 格式:2024ax.xaxis.set_minor_locator(MonthLocator(interval=3))             # 每季度一个副刻度

运行效果展示,当你运行这段代码时,你将看到两部分输出:

1. 终端输出,清晰的资金变动情况:

2. 可视化图表

你会得到一张包含两部分的专业图表:

  • Backtrader 原生图:展示K线、买卖点信号(三角形图标)以及 RSI 指标的走势。

  • 独立资金曲线图:这是一张蓝色的折线图,X轴的时间刻度非常整洁(例如只显示年份),你可以清晰地看到策略在 2015 年牛市是否抓住了机会,或者在 2018 年熊市是否控制住了回撤。

02
专业级 Python 量化系统:风控、复利与绩效评估

在上小节文章中,我们搭建了一个基础的多品种 RSI 策略框架。今天,我们将给这个引擎装上“涡轮增压”和“安全气囊”。

我们将解决新手最容易忽略的两个问题:“买多少?”(仓位管理)和“怎么输得少?”(风控指标)。我们将把这个“玩具级”的回测脚本升级为“实战入门级”的量化系统。

我们将重点进行以下 4项硬核升级

  1. 仓位管理 (Position Sizing):从傻瓜式的“固定买100股”升级为“按资金比例下单”(例如每次使用20%资金),让复利效应发挥作用。

  2. 风险控制 (Risk Management):新增移动止损 (Trailing Stop) 逻辑。在趋势策略中,止损比止盈更重要,能保住胜利果实。

  3. 交易日志 (Logging System):增加详细的订单打印功能,让你清楚看到每一笔买卖的价格、费用和盈亏,拒绝“黑箱操作”。

  4. 专业绩效评估 (Performance Metrics):除了看最终资金,我们还要计算 夏普比率 (Sharpe Ratio) 和 最大回撤 (Max Drawdown),这才是专业机构评价策略的核心指标。

升级代码:

import backtrader as btimport tushare as tsimport pandas as pdimport numpy as npimport matplotlib.pyplot as pltfrom matplotlib.dates import DateFormatter, MonthLocator, date2num# --- 配置 Matplotlib 中文显示 ---plt.rcParams["font.family"] = ["SimHei""WenQuanYi Micro Hei""Heiti TC"]plt.rcParams['axes.unicode_minus'] = False# 1. 资金曲线分析器 (保持不变)class CashValueAnalyzer(bt.Analyzer):    def __init__(self):        self.cash_values = []        self.dates = []    def next(self):        self.dates.append(self.strategy.datas[0].datetime.date(0))        self.cash_values.append(self.strategy.broker.getvalue())    def get_analysis(self):        return {'dates'self.dates, 'cash_values'self.cash_values}# 2. 升级版策略:增加日志、风控与动态仓位class ProMultiAssetRSIStrategy(bt.Strategy):    params = (        ('rsi_period'14),        ('stop_loss_dist'0.05), # 5% 移动止损        ('printlog'True),       # 是否打印日志    )    def log(self, txt, dt=None):        """ 日志打印辅助函数 """        if self.params.printlog:            dt = dt or self.datas[0].datetime.date(0)            print(f'[{dt.isoformat()}{txt}')    def __init__(self):        self.rsi_indicators = []        self.orders = {} # 记录每个资产的订单状态        for data in self.datas:            rsi = bt.indicators.RSI(data.close, period=self.params.rsi_period)            self.rsi_indicators.append(rsi)            self.orders[data] = None # 初始化订单状态        self.asset_indicators = list(zip(self.datas, self.rsi_indicators))    def notify_order(self, order):        """ 订单状态变化通知 """        if order.status in [order.Submitted, order.Accepted]:            return        if order.status in [order.Completed]:            if order.isbuy():                self.log(f'BUY EXECUTED: {order.data._name}, Price: {order.executed.price:.2f}, Cost: {order.executed.value:.2f}, Comm: {order.executed.comm:.2f}')            elif order.issell():                self.log(f'SELL EXECUTED: {order.data._name}, Price: {order.executed.price:.2f}, Cost: {order.executed.value:.2f}, Comm: {order.executed.comm:.2f}')        elif order.status in [order.Canceled, order.Margin, order.Rejected]:            self.log(f'Order Canceled/Margin/Rejected: {order.data._name}')        self.orders[order.data] = None    def notify_trade(self, trade):        """ 交易结算是通知 (计算盈亏) """        if not trade.isclosed:            return        self.log(f'OPERATION PROFIT: {trade.data._name}, GROSS {trade.pnl:.2f}, NET {trade.pnlcomm:.2f}')    def next(self):        for data, rsi in self.asset_indicators:            # 如果有未完成的订单,不进行新操作            if self.orders[data]:                return            position = self.getposition(data)            # --- 核心交易逻辑 ---            # 1. 买入:无持仓 且 RSI > 70 (动量突破)            if not position:                if rsi[0] > 70:                    self.log(f'BUY CREATE: {data._name} (RSI: {rsi[0]:.2f})')                    # 使用 Sizer 自动计算数量,这里只发信号                    self.orders[data] = self.buy(data=data)            # 2. 卖出:有持仓 且 (RSI < 30 或 触发移动止损)            else:                # 移动止损逻辑:如果收盘价跌破了 (买入价 * 0.95),则止损                # 注意:Backtrader有专门的TrailingStop订单,这里为了演示逻辑手动写个简单的                stop_price = position.price * (1.0 - self.params.stop_loss_dist)                if rsi[0] < 30:                    self.log(f'SELL CREATE (Signal): {data._name} (RSI: {rsi[0]:.2f})')                    self.orders[data] = self.sell(data=data)                elif data.close[0] < stop_price:                    self.log(f'SELL CREATE (Stop Loss): {data._name} (Price: {data.close[0]:.2f} < Stop: {stop_price:.2f})')                    self.orders[data] = self.sell(data=data)# 3. 数据准备 (保持稳定)indices = [('000905''中证500'), ('000852''中证1000'), ('399006''创业板指')]cerebro = bt.Cerebro()for code, name in indices:    # 注意:实际使用建议将数据下载到本地 CSV,避免频繁请求接口    df = ts.get_k_data(code, start='2018-01-01'# 缩短时间范围以加快演示    if df.empty: continue    df['date'] = pd.to_datetime(df['date'])    df = df.set_index('date', drop=True)    data_feed = bt.feeds.PandasData(        dataname=df, fromdate=pd.Timestamp('2018-01-01'), todate=pd.Timestamp.now(),        open=0, high=1, low=2, close=3, volume=4, openinterest=-1    )    cerebro.adddata(data_feed, name=name)# 4. 升级配置:仓位与分析器cerebro.addstrategy(ProMultiAssetRSIStrategy)cerebro.addanalyzer(CashValueAnalyzer, _name='cash')# [新增] 夏普比率分析器cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe', timeframe=bt.TimeFrame.Years, riskfreerate=0.02)# [新增] 最大回撤分析器cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')# [升级] 仓位管理:每次交易使用当前总资金的 20%cerebro.addsizer(bt.sizers.PercentSizer, percents=20)cerebro.broker.setcash(1000000.0)cerebro.broker.setcommission(commission=0.001)print('--- 回测开始 ---')results = cerebro.run()strat = results[0]# 5. 打印专业绩效报告print('\n--- 绩效报告 ---')print(f'初始资金: {1000000.00:.2f}')print(f'最终资金: {cerebro.broker.getvalue():.2f}')print(f'夏普比率: {strat.analyzers.sharpe.get_analysis()["sharperatio"]:.4f}')print(f'最大回撤: {strat.analyzers.drawdown.get_analysis()["max"]["drawdown"]:.2f}%')print(f'回撤金额: {strat.analyzers.drawdown.get_analysis()["max"]["moneydown"]:.2f}')# 6. 绘图 (只绘制独立的资金曲线,更清晰)cash_data = strat.analyzers.cash.get_analysis()dates_num = date2num(cash_data['dates'])cash_values = cash_data['cash_values']plt.figure(figsize=(126))plt.plot_date(dates_num, cash_values, 'r-', linewidth=1.5, label='策略净值')# 填充回撤区域 (可视化优化)plt.fill_between(dates_num, cash_values, 1000000, where=(np.array(cash_values) < 1000000),                  facecolor='red', alpha=0.1, label='亏损区域')plt.fill_between(dates_num, cash_values, 1000000, where=(np.array(cash_values) >= 1000000),                  facecolor='green', alpha=0.1, label='盈利区域')ax = plt.gca()ax.xaxis.set_major_locator(MonthLocator(interval=12, bymonth=1))ax.xaxis.set_major_formatter(DateFormatter('%Y'))ax.xaxis.set_minor_locator(MonthLocator(interval=3))plt.title('多品种 RSI 策略资金曲线 (含仓位管理)', fontsize=14)plt.grid(True, linestyle='--', alpha=0.5)plt.legend()plt.tight_layout()plt.show()

1. 动态仓位管理 (Smart Sizing)

旧版本每次只买 100 股,这在资金量大时毫无意义。

  • 代码

    cerebro.addsizer(bt.sizers.PercentSizer, percents=20)

  • 原理:无论你现在有 100 万还是 200 万,每次开仓都动用总资金的 20%。这能实现**“赢了加仓,输了减仓”**的复利效果。

2. 交易全透明 (Logging)

不再是黑箱。我们在策略中增加了 notify_order 和 notify_trade 方法。

  • 效果:终端会打印如下信息,这让你能精确核对每一笔交易是否符合预期,排查 Bug 必备。

3. 硬核风控 (Risk Control)

RSI 策略最大的弱点是“钝化”(指标在高位一直不下来,或者暴跌时指标虽低但价格还在跌)。

  • 逻辑:我们在 next 方法中加入了一个简单的止损逻辑:if data.close[0] < stop_price

  • 意义:假设买入后价格下跌超过 5%(stop_loss_dist),强制平仓。这能防止单次交易造成毁灭性打击。

4. 机构级指标 (Metrics)

光看赚了多少钱是不够的,如果赚 50% 却经历过 40% 的回撤,那这个策略很难坚持。

  • 夏普比率 (Sharpe Ratio):衡量性价比。大于 1 是良好,大于 2 是优秀。

  • 最大回撤 (Max Drawdown):历史上最惨的一次跌幅。代码会在最后打印:最大回撤: 15.30%,让你对风险心知肚明。

5. 图表升级细节

我们在绘图中增加了一个“盈亏区域填充”功能:

  • 绿色背景区域:代表当前资金高于初始资金(赚钱)。

  • 红色背景区域:代表当前资金低于初始资金(亏钱)。

这种视觉反馈能让你一眼看出策略在哪些年份表现挣扎,哪些年份在躺赚。

03
再次升级:添加趋势过滤与基准对比系统

在上一版本中,我们加入了仓位管理和止损。但在实战中,单纯的 RSI 动量策略有一个致命弱点:在长期熊市中,RSI 也会偶尔突破 70,诱骗你进场,然后价格继续暴跌。

这一次,我们将把系统升级为“基金经理级”。我们将引入两个量化交易中的核心概念:

  1. 趋势过滤 (Trend Filtering):解决 RSI 在熊市中频繁“假突破”导致亏损的痛点。

  2. 基准对比 (Benchmark Comparison):不跟大盘比收益的策略都是耍流氓。我们将把策略净值与“沪深300”的走势画在同一张图上,一目了然地看到你是否跑赢了市场。

升级核心:

  • SMA 趋势过滤:只有当价格位于 200 日均线之上(牛市区域)时,才允许开仓。这叫“顺大势,逆小势”。

  • 基准对比可视化:自动下载沪深300数据,模拟“买入持有”策略,与你的策略净值同台竞技。

import backtrader as btimport tushare as tsimport pandas as pdimport numpy as npimport matplotlib.pyplot as pltfrom matplotlib.dates import DateFormatter, MonthLocator, date2num# --- 配置 Matplotlib 中文显示 ---plt.rcParams["font.family"] = ["SimHei""WenQuanYi Micro Hei""Heiti TC"]plt.rcParams['axes.unicode_minus'] = False# 1. 资金曲线分析器class CashValueAnalyzer(bt.Analyzer):    def __init__(self):        self.cash_values = []        self.dates = []    def next(self):        self.dates.append(self.strategy.datas[0].datetime.date(0))        self.cash_values.append(self.strategy.broker.getvalue())    def get_analysis(self):        return {'dates'self.dates, 'cash_values'self.cash_values}# 2. 高阶策略:带趋势过滤的 RSIclass TrendFilteredRSIStrategy(bt.Strategy):    params = (        ('rsi_period'14),        ('filter_period'200),  # 新增:200日均线作为牛熊分界线        ('stop_loss_dist'0.08), # 放宽止损到 8%    )    def __init__(self):        self.inds = {}         for data in self.datas:            self.inds[data] = {}            # RSI 指标            self.inds[data]['rsi'] = bt.indicators.RSI(data.close, period=self.params.rsi_period)            # SMA 趋势过滤指标 (200日均线)            self.inds[data]['sma'] = bt.indicators.SMA(data.close, period=self.params.filter_period)        # 记录订单避免重复提交        self.orders = {data: None for data in self.datas}    def notify_order(self, order):        if order.status in [order.Completed]:            # 简化的日志,只看成交            if order.isbuy():                print(f'[买入] {order.data._name} 价格: {order.executed.price:.2f}')            elif order.issell():                print(f'[卖出] {order.data._name} 价格: {order.executed.price:.2f}')        self.orders[order.data] = None    def next(self):        for data in self.datas:            if self.orders[data]: continue  # 有未完成订单则跳过            position = self.getposition(data)            rsi = self.inds[data]['rsi'][0]            current_price = data.close[0]            sma_filter = self.inds[data]['sma'][0]            # --- 核心升级:双重条件开仓 ---            # 1. RSI > 70 (动量)             # 2. 现价 > 200日均线 (趋势向上)            if not position:                if rsi > 70 and current_price > sma_filter:                    self.buy(data=data)                    print(f' >> 信号触发: {data._name} 突破且位于均线之上')            # --- 卖出逻辑 ---            else:                stop_price = position.price * (1.0 - self.params.stop_loss_dist)                # 止盈:RSI 回落                if rsi < 40                    self.sell(data=data)                # 止损:跌破止损线                elif current_price < stop_price:                    self.sell(data=data)                    print(f' >> 止损触发: {data._name}')# 3. 数据准备 (包含策略数据 和 基准数据)cerebro = bt.Cerebro()# 策略交易的标的indices = [('399006''创业板指'), ('000905''中证500')]start_date = '2019-01-01'for code, name in indices:    df = ts.get_k_data(code, start=start_date)    if df.empty: continue    df['date'] = pd.to_datetime(df['date'])    df = df.set_index('date', drop=True)    data = bt.feeds.PandasData(        dataname=df, fromdate=pd.Timestamp(start_date),        open=0, high=1, low=2, close=3, volume=4, openinterest=-1    )    cerebro.adddata(data, name=name)# 4. 获取基准数据 (沪深300) 用于对比# 注意:这部分数据不加入 cerebro,而是用于最后画图benchmark_df = ts.get_k_data('hs300', start=start_date)benchmark_df['date'] = pd.to_datetime(benchmark_df['date'])benchmark_df = benchmark_df.set_index('date')# 计算基准的归一化净值 (从1开始)benchmark_norm = benchmark_df['close'] / benchmark_df['close'].iloc[0] * 1000000# 5. 系统配置cerebro.addstrategy(TrendFilteredRSIStrategy)cerebro.addanalyzer(CashValueAnalyzer, _name='cash')cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='sharpe', riskfreerate=0.02, timeframe=bt.TimeFrame.Years)cerebro.addanalyzer(bt.analyzers.DrawDown, _name='drawdown')# 动态仓位:资金分成 2 份,每份用 45% (留点余地防止拒单)cerebro.addsizer(bt.sizers.PercentSizer, percents=45cerebro.broker.setcash(1000000.0)cerebro.broker.setcommission(commission=0.001)print('--- 回测开始 ---')results = cerebro.run()strat = results[0]# 6. 最终结果与绘图final_value = cerebro.broker.getvalue()print(f'\n策略最终资金: {final_value:.2f}')print(f'基准最终模拟: {benchmark_norm.iloc[-1]:.2f}')print(f'夏普比率: {strat.analyzers.sharpe.get_analysis()["sharperatio"]:.4f}')# --- 绘图升级:策略 vs 基准 ---cash_data = strat.analyzers.cash.get_analysis()dates = cash_data['dates']strategy_values = cash_data['cash_values']plt.figure(figsize=(147))# 绘制策略曲线plt.plot(dates, strategy_values, 'r-', linewidth=2, label='我的量化策略')# 绘制基准曲线 (需要对齐时间轴)# 将 benchmark 数据截取到策略相同的时间段aligned_benchmark = benchmark_norm.reindex(dates).fillna(method='ffill')plt.plot(dates, aligned_benchmark, 'k--', alpha=0.6, linewidth=1.5, label='沪深300 (基准)')# 填充超额收益区域plt.fill_between(dates, strategy_values, aligned_benchmark,                  where=(np.array(strategy_values) > np.array(aligned_benchmark)),                 facecolor='red', alpha=0.1, label='跑赢市场')plt.fill_between(dates, strategy_values, aligned_benchmark,                  where=(np.array(strategy_values) <= np.array(aligned_benchmark)),                 facecolor='gray', alpha=0.1, label='跑输市场')# 格式化ax = plt.gca()ax.xaxis.set_major_locator(MonthLocator(interval=12, bymonth=1))ax.xaxis.set_major_formatter(DateFormatter('%Y'))plt.title(f'策略 vs 沪深300:是否存在超额收益 (Alpha)?', fontsize=14)plt.ylabel('资金净值')plt.grid(True, linestyle='--', alpha=0.5)plt.legend()plt.tight_layout()plt.show()

深度解析升级内容

1. 增加系统过滤条件

新手死于追高,老手死于抄底,高手死于震荡。 RSI 策略最大的坑在于:在熊市反弹(Dead Cat Bounce)时,RSI 很容易突破 70,发出买入信号,然后市场继续暴跌。

  • 代码逻辑if rsi > 70 and current_price > sma_filter

  • 白话解释:这就像是在说,“我只在天气晴朗(价格在200日均线之上)的时候,才去冲浪(RSI 突破)”。

  • 效果:这会大幅减少交易次数,可能会让你错过一些机会,但能帮你躲过 2018 年或 2022 年那种持续阴跌的“绞肉机”行情。

2. 基准对比:寻找真实的 Alpha

很多策略号称“年化 20%”,结果一看那年大盘涨了 30%。这种策略是没有价值的,不如直接买指数 ETF。

  • 实现方式:我们在绘图部分,引入了 hs300 (沪深300) 数据,并将其初始资金也归一化为 100 万。

  • 可视化创新

    • 红色阴影区:表示你的策略跑赢了大盘。这是你作为量化交易员存在的意义。

    • 灰色阴影区:表示策略跑输了大盘。这时候你需要反思策略逻辑。

3. 多标的并行与资金分配

代码中将资金分配逻辑调整为:

cerebro.addsizer(bt.sizers.PercentSizer, percents=45)

因为我们有两个标的(创业板 + 中证500),如果设为 50%,当资金稍微有一点波动或产生佣金时,第二只股票可能因为资金不足(Cash < 50%)而无法买入。设为 45% 是一个安全的工程实践技巧。

运行结果

至此,我们的系统已经具备了择时(RSI)、过滤(均线)、风控(止损)和 归因分析(Benchmark)等功能
最后的说明
文中代码与条件设定均为示例载体,核心目标在于传递解决问题的方法论——建议聚焦于思路的理解与迁移,而非局限于示例结果本身。在掌握基础方法后,可结合自身思考对代码进行迭代优化,构建更健壮、高效的量化策略,真正实现从“理解”到构建策略”的进阶。

如您想获取文章完整代码,请关注数量技术宅公众号,后台回复关键词:组合测试

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-02-08 02:51:28 HTTP/2.0 GET : https://f.mffb.com.cn/a/474244.html
  2. 运行时间 : 0.141748s [ 吞吐率:7.05req/s ] 内存消耗:4,462.95kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=5442dc94bce5493d4a791c342e3197c8
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000403s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000535s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.022860s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.001804s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000821s ]
  6. SELECT * FROM `set` [ RunTime:0.001318s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000778s ]
  8. SELECT * FROM `article` WHERE `id` = 474244 LIMIT 1 [ RunTime:0.002765s ]
  9. UPDATE `article` SET `lasttime` = 1770490289 WHERE `id` = 474244 [ RunTime:0.013096s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000936s ]
  11. SELECT * FROM `article` WHERE `id` < 474244 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000836s ]
  12. SELECT * FROM `article` WHERE `id` > 474244 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.000454s ]
  13. SELECT * FROM `article` WHERE `id` < 474244 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000987s ]
  14. SELECT * FROM `article` WHERE `id` < 474244 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.018964s ]
  15. SELECT * FROM `article` WHERE `id` < 474244 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.001306s ]
0.144206s