当前位置:首页>java>龙头动量轮动策略代码更新(年化超110%)

龙头动量轮动策略代码更新(年化超110%)

  • 2026-01-30 21:19:09
龙头动量轮动策略代码更新(年化超110%)

一、策略表现

图1:策略主要业绩指标

图2:策略与科创50累计收益/最大回撤对比
图3:策略与等权重组合累计收益/最大回撤对比

二、策略思路

这是一款基于风险调整动量的龙头股票主动轮动策略,核心依托 “动量效应(强者恒强)”,同时通过风险校准和定期调仓控制波动,最终目标是跑赢科创 50ETF 基准和龙头股票等权重组合,具体投资思路可拆解为以下 7 点:

  1. 标的池定位:聚焦核心赛道龙头筛选 22 只 A 股各核心赛道(消费、新能源、金融、科技、有色等)龙头股票作为投资标的池,确保标的具备足够的流动性和趋势稳定性;同时选定科创 50ETF 作为业绩基准,构建龙头股票等权重组合作为辅助对比,用于验证策略的超额收益能力。

  2. 动量指标优化:引入风险调整修正不采用简单的原始收益率作为动量指标,而是构建风险调整后动量(Adj_Momentum)

    • 先计算个股 N 日(默认 20 天)平均收益率(原始动量),反映短期价格趋势强度;
    • 再计算个股 N 日收益率方差(波动率),衡量趋势的稳定性和风险;
    • 最终以 “N 日平均收益率 /√N 日收益率方差” 得到调整动量,规避 “高收益高波动” 的激进标的,提升策略稳健性。
  3. 选股核心规则:正动量 + 优中选优选股环节设置双重筛选,确保只捕捉 “强势且稳健” 的标的:

    • 第一重:仅筛选原始动量为正的标的,排除趋势走弱的股票,坚守 “只做上涨趋势” 的逻辑;
    • 第二重:在正动量标的中,按风险调整后动量从高到低排序,选取前 L 只(默认 5 只)作为持仓标的,强化 “强者恒强” 的动量效应。
  4. 调仓机制设计:定期调仓 + 无缝衔接采用固定周期定期调仓策略,兼顾操作可行性和趋势跟踪效率:

    • 调仓间隔:每 K 个交易日(默认 5 天)调仓一次,平衡交易成本和趋势更新速度;
    • 调仓起点:从第 N 个交易日开始(确保有足够数据计算 N 日动量,避免数据不足的偏差);
    • 持仓周期:单次调仓的权重生效至下一次调仓日前一天,实现持仓周期的无缝衔接,无空窗期。
  5. 权重分配逻辑:动量归一化加权对选中的 L 只标的,不采用等权重分配,而是按其风险调整后动量值进行归一化处理(单个标的权重 = 该标的调整动量 / 所有选中标的调整动量之和),让趋势更强、风险更低的标的获得更高持仓权重,进一步放大超额收益空间。

  6. 交易实操模拟:规避未来函数计算策略每日收益率时,采用 “权重滞后 1 天” 的处理方式(当日调仓决策,次日买入),模拟实际交易中的 “T 日决策、T+1 日执行” 的操作流程,避免未来函数对回测结果的失真,让回测收益更贴近真实交易场景。

  7. 业绩验证与复盘:多维度对比 + 数据留存

    • 绩效测算:通过年化收益、年化波动率、最大回撤、夏普比率、卡玛比率 5 个核心指标,对比策略、科创 50ETF、等权重组合的业绩表现;
    • 可视化呈现:绘制累计收益率走势和最大回撤曲线,直观展示策略的收益能力和风险控制能力;
    • 复盘留存:保存每日权重、标的选中频率、动量数据等,便于后续调整 N(动量周期)、K(调仓间隔)、L(持仓数量)等参数,优化策略效果。
三、代码思路

第一部分:加载软件包与中文字体配置

主要思路

  • 工程稳健性思路
    先判断 R 包是否已安装,未安装则自动安装,避免因缺少包导致代码运行中断,同时避免重复安装已存在的包,提升运行效率。
  • 功能分类思路
    按 “金融数据处理→绩效分析→数据清洗→可视化→格式优化” 的逻辑加载对应包,形成完整的回测工具链,满足策略回测的全流程需求。
  • 可视化适配思路
    解决 R 语言 ggplot2 绘图中中文乱码的问题,保证后续图表的中文标签(如策略名称、指标名称)正常显示,提升结果的可读性。

具体作用

  • 条件安装与加载包
    批量加载 12 个核心 R 包,覆盖金融数据下载(quantmod)、投资绩效量化(PerformanceAnalytics)、数据清洗(dplyr/tidyr)、高级绘图(ggplot2/patchwork)、格式优化(scales/knitr)等全流程,为后续回测奠定工具基础。
  • 中文字体配置
    通过showtext包添加黑体(simhei),设置绘图主题的默认字体为黑体,自动启用字体支持,消除后续图表中中文标签的乱码、方框等显示问题。

第二部分:配置核心回测参数

主要思路

  • 策略参数化思路
    将动量周期、调仓间隔、持仓数量等核心策略变量提取为可配置参数,便于后续参数调优(如修改 N=10/30 对比策略效果),无需修改核心代码。
  • 对照基准思路
    明确科创 50ETF 作为市场基准,构建龙头股票标的池,同时设置等权重组合作为辅助对照,通过 “策略 vs 市场基准 vs 等权基准” 的三重对比,全面验证策略有效性。
  • 信息透明化思路
    通过cat函数输出参数汇总,让用户在回测开始前清晰掌握当前配置,便于后续复盘和参数溯源。

具体作用

  • 定义核心参数
    确定回测时间范围、动量计算周期(N)、调仓间隔(K)、持仓标的数量(L),为后续数据下载、动量计算、调仓选股提供标准。
  • 构建标的体系
    筛选 22 只 A 股各赛道龙头股票作为投资标的池,添加科创 50ETF 作为市场基准,整合为统一的标的列表,为批量数据下载做准备。
  • 输出参数清单
    以清晰的格式打印当前策略配置,包括参数值、回测时间、标的数量、基准信息,提升回测过程的透明度和可追溯性。

第三部分:下载和清洗金融数据

主要思路

  • 容错性思路
    添加 3 次重试机制,应对网络波动、Yahoo Finance 接口临时不可用等问题,提升数据下载的成功率,避免因单个标的下载失败导致整体回测中断。
  • 数据质量思路
    仅提取调整后收盘价(复权价),消除除权、除息对股票价格趋势的干扰,保证后续动量计算和收益测算的准确性。
  • 数据标准化思路
    将所有标的的价格数据合并为统一的 xts 时间序列对象,保证数据格式一致、日期对齐,便于后续批量处理和计算。

具体作用

  • 实现稳健的数据下载
    通过自定义download_data函数,循环遍历所有标的,对下载失败的标的进行最多 3 次重试,捕获并提示错误信息,过滤下载失败的标的数据。
  • 提取高质量核心数据
    使用Ad()函数提取每个标的的调整后收盘价,作为后续分析的唯一价格数据源,避免复权因素导致的趋势失真。
  • 合并与校验数据
    将所有成功下载的价格数据合并为 xts 时间序列,打印数据维度和时间范围,校验数据完整性,若无有效数据则抛出错误终止回测,避免后续无意义计算。

第四部分:计算每日动量数据

主要思路

  • 指标优化思路
    不使用简单的原始收益率作为动量指标,构建 “风险调整动量”(动量 /√波动率),兼顾收益趋势强度和波动风险,规避 “高收益高波动” 的激进标的,提升策略稳健性。
  • 批量处理思路
    通过循环和函数封装,批量计算所有标的的动量相关指标,提高代码复用性和运行效率,避免重复编写单个标的的计算逻辑。
  • 数据留存思路
    将每个标的的日收益率、原始动量、波动率、调整动量统一存储,既满足当前选股需求,也为后续复盘(如分析标的波动特征)提供数据支撑。

具体作用

  • 构建完整的动量指标体系
    通过calculate_momentum函数,分步计算:
    • 日算术收益率(动量计算的基础);
    • N 日平均收益率(原始动量,反映短期趋势强度);
    • N 日收益率方差(波动率,反映趋势的稳定性和风险);
    • 风险调整动量(原始动量 /√波动率,标准化风险后的趋势强度)。
  • 批量生成标的动量数据
    循环遍历所有标的,调用动量计算函数,将结果存储在momentum_list中,形成每个标的的专属动量指标集。
  • 整合选股核心数据
    提取所有标的的原始动量和调整动量,合并为统一的 xts 对象,为后续调仓选股提供直接可用的指标数据。

第五部分:生成每日权重和组合收益率

主要思路

  • 定期调仓思路
    采用固定周期调仓(每 K 天),兼顾交易成本和趋势跟踪效率,避免频繁调仓增加成本,也避免调仓间隔过长错失趋势变化。
  • 选股严谨性思路
    设置 “正动量筛选 + 调整动量排序” 的双重选股规则,仅选择趋势向上且稳健的标的,坚守 “强者恒强” 的动量逻辑,同时规避下跌趋势标的。
  • 权重合理化思路
    按调整动量归一化分配权重,让趋势更强、风险更低的标的获得更高持仓,放大超额收益空间,而非简单等权重配置。
  • 规避未来函数思路
    将权重滞后 1 天,模拟 “T 日决策、T+1 日买入” 的实际交易流程,避免使用当日价格数据计算当日收益,保证回测结果的真实性和可复制性。

具体作用

  • 生成每日持仓权重
    通过generate_daily_weights函数,完成核心选股和权重分配:
    • 确定调仓日(从第 N 天开始,每 K 天一次,保证有足够数据计算动量);
    • 筛选正原始动量标的,排除下跌趋势;
    • 按调整动量排序选取前 L 只标的,优中选优;
    • 归一化调整动量,分配权重并赋值给整个调仓周期,实现无缝持仓衔接。
  • 构建每日权重清单
    过滤权重大于 0 的记录,按日期存储持仓标的和权重,便于后续复盘每日持仓结构。
  • 计算真实策略收益
    权重滞后 1 天,对齐收益率与权重的日期,计算加权日收益率,得到策略的每日收益序列,为后续累计收益和绩效测算提供基础。

第六部分:计算等权重组合收益率

主要思路

  • 对照验证思路
    构建龙头股票的等权重组合,作为 “策略有效性” 的辅助对照 —— 若动量轮动策略仅跑赢市场基准,但未跑赢等权重组合,说明策略价值有限,仅靠标的本身而非轮动逻辑获利。
  • 公平对比思路
    等权重组合的标的池与动量策略完全一致(均为 22 只龙头股票),仅改变权重分配方式,排除标的差异对对比结果的干扰,保证对比的公平性。

具体作用

  • 构建等权重基准
    创建等权重矩阵(每只龙头股票权重为 1 / 股池数量),对齐日期后计算等权重组合的每日收益率。
  • 生成对比收益序列
    将等权重组合的收益转换为 xts 序列,为后续 “策略 vs 等权” 的可视化对比和绩效量化提供数据支撑,验证动量轮动逻辑是否具备超额收益能力。

第七部分:计算基准收益率(科创 50ETF)

主要思路

  • 市场对照思路
    提取科创 50ETF 的收益率作为市场整体表现的基准,验证动量轮动策略是否具备 “跑赢大盘” 的超额收益能力,这是策略回测的核心对照标准。
  • 容错性思路
    添加列名校验,若基准名称未匹配成功,则默认使用最后一列数据作为基准,避免因列名不一致导致基准收益计算失败,保证回测流程的连贯性。

具体作用

  • 提取市场基准收益
    从收益率数据中筛选出科创 50ETF 的每日收益率,转换为专属 xts 序列,命名为基准名称,便于后续识别和对比。
  • 保障基准数据有效性
    通过列名校验和兜底处理,确保基准收益数据的完整性,为后续 “策略 vs 市场” 的对比提供可靠数据源。

第八部分:绘制图表与计算绩效指标

主要思路

  • 可视化思路
    通过 “累计收益率线图 + 最大回撤面积图” 的组合图表,直观展示策略的收益走势和风险表现,相比单纯的数字更易理解策略的优劣。
  • 多维度量化思路
    选取年化收益、年化波动率、最大回撤、夏普比率、卡玛比率五大核心指标,从收益能力、风险水平、风险收益比三个维度全面量化策略表现,避免单一指标的片面性。
  • 三重对比思路
    通过 “策略 vs 市场基准 vs 等权基准” 的可视化和量化对比,全面验证策略的超额收益能力、风险控制能力和逻辑有效性。

具体作用

  • 计算核心对比数据
    计算三者的累计收益率(展示长期收益走势)和最大回撤(展示极端风险),转换为数据框便于 ggplot 绘图。
  • 生成高质量可视化图表
    通过create_combined_plot函数,优化图表样式(中文适配、图例布局、百分比刻度),生成两张对比图,直观展示策略的收益优势和风险控制能力。
  • 量化绩效并汇总
    通过calculate_performance函数,批量计算三者的五大核心绩效指标,合并为绩效汇总表,量化对比策略的超额收益和稳健性,为策略评价提供数据支撑。

 第九部分:保存结果到文件

  • 归档化思路
    创建以参数命名的专属文件夹,将所有回测结果按类别保存,便于后续离线复盘、参数调优对比和结果归档,避免不同参数回测结果的混淆。
  • 可追溯性思路
    保存每日权重、股票选中频率、动量数据等细节信息,便于后续深入复盘(如分析哪些标的贡献了主要收益、调仓时点是否合理),为策略优化提供数据支撑。
  • 完整性思路
    保存量化数据、可视化图表、复盘细节等全量结果,保证回测结果的可复现性和可追溯性,满足后续深入分析和报告输出的需求。

具体作用

  • 创建专属归档文件夹
    以 “策略名称 + 参数” 命名文件夹,自动创建不存在的文件夹,实现结果的分类存储。
  • 批量保存回测结果
    • 保存量化数据(绩效汇总、累计收益、回撤等);
    • 保存复盘细节(每日权重、股票选中频率、动量示例等);
    • 保存可视化图表(两张对比图);
  • 输出保存清单
    打印保存文件的列表,让用户清晰掌握归档内容,便于后续快速查找所需数据。
四、策略源代码
# ==================== 第一部分:加载软件包 ====================if (!require("quantmod")) install.packages("quantmod")if (!require("PerformanceAnalytics")) install.packages("PerformanceAnalytics")if (!require("ggplot2")) install.packages("ggplot2")if (!require("dplyr")) install.packages("dplyr")if (!require("tidyr")) install.packages("tidyr")if (!require("scales")) install.packages("scales")if (!require("patchwork")) install.packages("patchwork")if (!require("cowplot")) install.packages("cowplot")if (!require("RColorBrewer")) install.packages("RColorBrewer")if (!require("knitr")) install.packages("knitr")if (!require("showtext")) install.packages("showtext")library(quantmod) # 金融数据获取与分析library(PerformanceAnalytics) # 投资组合绩效分析library(ggplot2) # 高级绘图library(dplyr) # 数据处理library(tidyr) # 数据整理library(scales) # 图形标度调整library(patchwork) # 图形组合library(cowplot) # 图形组合(更精细的控制)library(RColorBrewer) # 颜色调色板library(knitr) # 报表输出library(showtext) # 字体支持# 添加中文字体支持font_add("simhei""simhei.ttf")showtext_auto()theme_set(theme_bw(base_family = "simhei")) # 使用bw主题# ==================== 第二部分:配置参数 ====================# 回测时间段backtest_start <- "2024-01-01"backtest_end <- Sys.Date()# 动量计算参数N <- 20 # 动量计算周期(默认20天)K <- 5 # 调仓间隔天数(默认5天,表示每5个交易日调仓一次)L <- 5 # 选择标的数量(默认选择前5名)# 基准参数benchmark_symbol <- "588000.SS" # 科创50ETFbenchmark_name <- "科创50ETF"# 转换为日期类型start_date <- as.Date(backtest_start)end_date <- as.Date(backtest_end)# 定义股票代码和名称(龙头股票)- 使用更常见的股票stock_symbols <- c(  "600111.SS""002460.SZ""601899.SS""600988.SS""002230.SZ",  "300750.SZ""002594.SZ""603259.SS""601939.SS""688256.SS",  "601606.SS""688981.SS""300502.SZ""601138.SS""300308.SZ",  "300476.SZ""300394.SZ""688041.SS""601336.SS""600519.SS",  "601288.SS""601319.SS")stock_names <- c(  "北方稀土""赣锋锂业""紫金矿业""赤峰黄金""科大讯飞",  "宁德时代""比亚迪""药明康德""建设银行""寒武纪",  "长城军工""中芯国际""新易盛""工业富联""中际旭创",  "胜宏科技""天孚通信""海光信息""新华保险""贵州茅台",  "农业银行""中国人保")# 将基准加入股票列表all_symbols <- c(stock_symbols, benchmark_symbol)all_names <- c(stock_names, benchmark_name)cat("==================== 参数设置 ====================\n")cat(sprintf("动量计算周期 N = %d 天\n", N))cat(sprintf("调仓间隔 K = %d 天\n", K))cat(sprintf("选择标的数量 L = %d 只\n", L))cat(sprintf("回测期间: %s 至 %s\n", backtest_start, as.character(end_date)))cat(sprintf("股票数量: %d 只龙头股票\n"length(stock_symbols)))cat(sprintf("基准: %s (%s)\n", benchmark_name, benchmark_symbol))cat("================================================\n\n")# ==================== 第三部分:下载和清洗数据 ====================cat("正在从Yahoo Finance获取数据...\n")# 设置下载重试机制download_data <- function(symbols, from_date, to_date, max_retries = 3) {  price_list <- list()  for (i in 1:length(symbols)) {    symbol <- symbols[i]    retry_count <- 0    success <- FALSE    while (retry_count < max_retries && !success) {      tryCatch(        {          symbol_data <- getSymbols(symbol,            from = from_date,            to = to_date,            src = "yahoo",            auto.assign = FALSE,            warnings = FALSE          )          # 使用调整后收盘价          price_list[[i]] <- Ad(symbol_data)          colnames(price_list[[i]]) <- all_names[i]          success <- TRUE          cat(sprintf("  √ 成功下载: %s (%s)\n", all_names[i], symbol))        },        error = function(e) {          retry_count <- retry_count + 1          if (retry_count == max_retries) {            cat(sprintf("  × 下载失败: %s (%s) - %s\n", all_names[i], symbol, e$message))            price_list[[i]] <- NULL          } else {            cat(sprintf("  ! 重试下载: %s (%s) 第%d次\n", all_names[i], symbol, retry_count))            Sys.sleep(1# 等待1秒后重试          }        }      )    }  }  # 过滤掉NULL值  price_list <- price_list[!sapply(price_list, is.null)]  return(price_list)}# 下载数据price_list <- download_data(all_symbols, start_date, end_date)# 检查是否成功下载数据if (length(price_list) == 0) {  stop("未能下载任何数据,请检查网络连接和股票代码")}# 合并所有价格数据cat("正在合并数据...\n")price_xts <- do.call(merge, price_list)# 检查数据cat(sprintf("价格数据维度: %d 行 × %d 列\n", nrow(price_xts), ncol(price_xts)))cat(sprintf(  "数据时间范围: %s 至 %s\n",  as.character(index(price_xts)[1]),  as.character(index(price_xts)[nrow(price_xts)])))cat("\n")# ==================== 第四部分:计算每日动量数据 ====================# 动量计算函数calculate_momentum <- function(price_series, window = N) {  # 计算日收益率  returns <- dailyReturn(price_series, type = "arithmetic")  colnames(returns) <- "Return"  # 计算N日平均收益率(动量)  momentum <- rollapply(returns,    width = window,    FUN = mean, align = "right", fill = NA  )  colnames(momentum) <- "Momentum"  # 计算N日收益率方差(波动率)  volatility <- rollapply(returns,    width = window,    FUN = var, align = "right", fill = NA  )  colnames(volatility) <- "Volatility"  # 计算调整动量(动量/波动率,使用标准差进行标准化)  adj_momentum <- momentum / sqrt(volatility)  colnames(adj_momentum) <- "Adj_Momentum"  return(list(    returns = returns,    momentum = momentum,    volatility = volatility,    adj_momentum = adj_momentum  ))}# 为每个股票计算动量指标,以list形式存储cat(sprintf("正在计算%d日动量指标...\n", N))momentum_list <- list()for (stock in colnames(price_xts)) {  momentum_list[[stock]] <- calculate_momentum(price_xts[, stock])}# 提取所有股票的调整动量和动量,用于后续选股adj_momentum_all <- do.call(merge, lapply(momentum_list, function(xx$adj_momentum))momentum_all <- do.call(merge, lapply(momentum_list, function(xx$momentum))colnames(adj_momentum_all) <- colnames(price_xts)colnames(momentum_all) <- colnames(price_xts)cat(sprintf("动量数据维度: %d 行 × %d 列\n", nrow(adj_momentum_all), ncol(adj_momentum_all)))cat("\n")# ==================== 第五部分:生成每日权重和组合收益率 ====================# 生成每日权重的函数generate_daily_weights <- function(adj_momentum_df, momentum_df,                                   rebalance_freq = K, select_count = L) {  # 初始化权重数据框  weights_df <- as.data.frame(adj_momentum_df)  weights_df[] <- 0 # 所有值初始化为0  # 获取所有交易日日期  all_dates <- index(adj_momentum_df)  # 确定调仓日:从第N个交易日开始,每隔K个交易日调仓一次  if (length(all_dates) < N) {    stop(sprintf("数据不足,需要至少%d个交易日的数据,当前只有%d个", N, length(all_dates)))  }  # 确定所有可能的调仓日  start_idx <- N # 从第N天开始(因为需要N天数据计算动量)  rebalance_indices <- seq(start_idx, length(all_dates), by = rebalance_freq)  cat(sprintf("总交易日数: %d\n"length(all_dates)))  cat(sprintf("调仓日数量: %d\n"length(rebalance_indices)))  cat(sprintf("首次调仓日: %s\n", as.character(all_dates[start_idx])))  cat(sprintf("最后调仓日: %s\n", as.character(all_dates[rebalance_indices[length(rebalance_indices)]])))  cat(sprintf("每期选择标的数量: %d\n", select_count))  # 对每个调仓日计算权重  for (rebalance_idx in rebalance_indices) {    # 获取当日的调整动量值和动量值    current_adj_momentum <- as.numeric(adj_momentum_df[rebalance_idx, ])    current_momentum <- as.numeric(momentum_df[rebalance_idx, ])    # 筛选动量为正数的标的(排除基准)    # 假设基准是最后一列    selectable_idx <- 1:(ncol(adj_momentum_df) - 1# 排除最后一个(基准)    selectable_momentum <- current_momentum[selectable_idx]    positive_momentum_idx <- selectable_idx[which(selectable_momentum > 0 & !is.na(selectable_momentum))]    if (length(positive_momentum_idx) > 0) {      # 获取正动量标的的调整动量值      positive_adj_momentum <- current_adj_momentum[positive_momentum_idx]      # 如果正动量标的超过select_count个,选择调整动量排名前select_count的      if (length(positive_momentum_idx) > select_count) {        adj_momentum_rank <- order(positive_adj_momentum, decreasing = TRUE)        top_idx <- adj_momentum_rank[1:select_count]        selected_idx <- positive_momentum_idx[top_idx]        selected_adj_momentum <- positive_adj_momentum[top_idx]      } else {        # 如果不超过select_count个,全部选择        selected_idx <- positive_momentum_idx        selected_adj_momentum <- positive_adj_momentum      }      # 按调整动量大小归一化计算权重      normalized_weights <- selected_adj_momentum / sum(selected_adj_momentum)      # 确定该权重生效的日期范围:从当前调仓日到下一个调仓日前一天      if (rebalance_idx == rebalance_indices[length(rebalance_indices)]) {        end_idx <- length(all_dates) # 最后一个调仓日      } else {        next_rebalance_idx <- rebalance_indices[which(rebalance_indices == rebalance_idx) + 1]        end_idx <- next_rebalance_idx - 1      }      end_idx <- min(end_idx, length(all_dates))      # 应用权重到该调仓周期内的所有交易日      for (i in rebalance_idx:end_idx) {        weights_df[i, selected_idx] <- normalized_weights      }    }  }  # 转换为时间序列  weights_xts <- xts(weights_df, order.by = all_dates)  colnames(weights_xts) <- colnames(adj_momentum_df)  return(weights_xts)}# 生成权重序列cat(sprintf("正在计算每日权重(调仓间隔K=%d天,选择标的L=%d只)...\n", K, L))weights <- generate_daily_weights(adj_momentum_all, momentum_all, K, L)# 将每日权重以list形式存储 - 只保留权重不为0的记录cat("正在创建每日权重列表(只保留权重大于0的记录)...\n")daily_weights_list <- list()weights_df <- as.data.frame(weights) # 转换为数据框# 使用整数索引循环,只保存权重大于0的记录for (i in 1:nrow(weights_df)) {  date <- index(weights)[i] # 从原始的xts对象获取日期  # 获取当日的权重向量  weight_vector <- as.numeric(weights_df[i, ])  # 找出权重大于0的股票  positive_weights_idx <- which(weight_vector > 0)  if (length(positive_weights_idx) > 0) {    # 只保存权重大于0的记录    weight_df <- data.frame(      Stock = colnames(weights)[positive_weights_idx],      Weight = weight_vector[positive_weights_idx],      Date = as.Date(date),      stringsAsFactors = FALSE    )    # 按日期字符串作为列表的键    daily_weights_list[[as.character(date)]] <- weight_df  }}cat(sprintf("成功创建每日权重列表,包含 %d 个交易日的权重数据\n"length(daily_weights_list)))# 如果没有权重数据,创建空的列表if (length(daily_weights_list) == 0) {  cat("警告: 没有找到权重大于0的记录\n")}# 计算投资组合每日收益率(权重滞后一天,按次日开盘价买入)cat("正在计算投资组合每日收益率...\n")returns_all <- do.call(merge, lapply(momentum_list, function(xx$returns))colnames(returns_all) <- colnames(price_xts)# 检查returns_all的列名cat("收益率数据列名:\n")print(colnames(returns_all))cat("\n")# 调整权重的时间索引,确保与收益率对齐lagged_weights <- lag(weights, 1# 权重滞后一天# 检查权重和收益率的日期范围cat(sprintf(  "权重数据日期范围: %s 至 %s\n",  as.character(index(weights)[1]),  as.character(index(weights)[nrow(weights)])))cat(sprintf(  "收益率数据日期范围: %s 至 %s\n",  as.character(index(returns_all)[1]),  as.character(index(returns_all)[nrow(returns_all)])))# 对齐索引:使用公共日期common_dates <- intersect(index(lagged_weights), index(returns_all))cat(sprintf("公共日期数量: %d\n"length(common_dates)))if (length(common_dates) == 0) {  stop("权重和收益率数据没有公共日期,无法计算策略收益率")}# 使用公共日期提取数据lagged_weights_aligned <- lagged_weights[common_dates, ]returns_all_aligned <- returns_all[common_dates, ]# 处理缺失值lagged_weights_aligned[is.na(lagged_weights_aligned)] <- 0# 计算策略日收益率(只计算龙头股票的加权收益率,排除基准)# 假设基准是最后一列strategy_stocks_returns <- returns_all_aligned[, -ncol(returns_all_aligned)] # 排除基准strategy_stocks_weights <- lagged_weights_aligned[, -ncol(lagged_weights_aligned)] # 排除基准strategy_returns <- rowSums(strategy_stocks_returns * strategy_stocks_weights, na.rm = TRUE)strategy_returns <- xts(strategy_returns, order.by = index(returns_all_aligned))colnames(strategy_returns) <- "龙头动量轮动策略"cat(sprintf("策略收益率数据长度: %d\n"length(strategy_returns)))cat("策略收益率数据预览:\n")print(head(strategy_returns, 5))cat("\n")# ==================== 第六部分:计算等权重组合收益率 ====================cat("正在计算等权重组合收益率...\n")# 计算等权重组合(龙头股票等权重)num_stocks <- ncol(returns_all_aligned) - 1 # 排除基准equal_weights <- matrix(1 / num_stocks, nrow = nrow(returns_all_aligned), ncol = num_stocks)equal_weights <- xts(equal_weights, order.by = index(returns_all_aligned))colnames(equal_weights) <- colnames(returns_all_aligned)[1:num_stocks]equal_returns <- rowSums(returns_all_aligned[, 1:num_stocks] * equal_weights, na.rm = TRUE)equal_returns <- xts(equal_returns, order.by = index(returns_all_aligned))colnames(equal_returns) <- "等权重组合"cat("等权重组合收益率数据预览:\n")print(head(equal_returns, 5))cat("\n")# ==================== 第七部分:计算基准收益率 ====================cat("正在计算基准收益率...\n")# 检查基准名称是否在收益率数据列名中if (benchmark_name %in% colnames(returns_all_aligned)) {  benchmark_returns <- returns_all_aligned[, benchmark_name]  colnames(benchmark_returns) <- benchmark_nameelse {  # 如果基准名称不在列名中,尝试使用最后一列  cat(sprintf("警告: 基准名称 '%s' 不在收益率数据列名中,使用最后一列作为基准\n", benchmark_name))  benchmark_returns <- returns_all_aligned[, ncol(returns_all_aligned)]  colnames(benchmark_returns) <- benchmark_name}cat("基准收益率数据预览:\n")print(head(benchmark_returns, 5))cat("\n")# ==================== 第八部分:绘制图表 ====================# 1. 计算累计收益率cat("正在计算累计收益率和最大回撤...\n")calculate_cumulative_returns <- function(returns) {  # 用0填充NA值  returns_filled <- na.fill(returns, 0)  cumprod(1 + returns_filled) - 1}strategy_cumulative <- calculate_cumulative_returns(strategy_returns)benchmark_cumulative <- calculate_cumulative_returns(benchmark_returns)equal_cumulative <- calculate_cumulative_returns(equal_returns)# 合并累计收益率cumulative_all <- merge(strategy_cumulative, benchmark_cumulative, equal_cumulative)colnames(cumulative_all) <- c("龙头动量轮动策略", benchmark_name, "等权重组合")# 转换为数据框用于ggplotcumulative_df <- data.frame(  Date = index(cumulative_all),  as.data.frame(cumulative_all))# 2. 计算最大回撤calculate_drawdown <- function(returns) {  returns_filled <- na.fill(returns, 0)  cum_returns <- cumprod(1 + returns_filled)  drawdown <- cum_returns / cummax(cum_returns) - 1  return(drawdown)}strategy_dd <- calculate_drawdown(strategy_returns)benchmark_dd <- calculate_drawdown(benchmark_returns)equal_dd <- calculate_drawdown(equal_returns)# 合并回撤数据drawdown_all <- merge(strategy_dd, benchmark_dd, equal_dd)colnames(drawdown_all) <- c("龙头动量轮动策略", benchmark_name, "等权重组合")# 转换为数据框用于ggplotdrawdown_df <- data.frame(  Date = index(drawdown_all),  as.data.frame(drawdown_all))# 3. 创建组合图函数create_combined_plot <- function(cumulative_data, drawdown_data,                                 strategy1, strategy2,                                 title, colors) {  # 准备累计收益率数据  cumulative_long <- cumulative_data %>%    select(Date, all_of(c(strategy1, strategy2))) %>%    pivot_longer(cols = -Date, names_to = "策略", values_to = "累计收益率")  # 准备回撤数据  drawdown_long <- drawdown_data %>%    select(Date, all_of(c(strategy1, strategy2))) %>%    pivot_longer(cols = -Date, names_to = "策略", values_to = "回撤")  # 累计收益率图 - 使用bw主题,删除X轴标题,图例无边框且背景透明  p_cumulative <- ggplot(cumulative_long, aes(x = Date, y = 累计收益率, color = 策略)) +    geom_line(size = 1.2) +    labs(title = title, subtitle = "累计收益率"y = "累计收益率"x = "") +    scale_y_continuous(labels = percent_format()) +    scale_color_manual(values = colors) +    theme_bw(base_family = "simhei") + # 使用bw主题    theme(      legend.position = c(0.020.98),      legend.justification = c(01),      legend.direction = "vertical",      legend.title = element_blank(),      # 图例无边框,背景透明      legend.background = element_blank(), # 透明背景      legend.key = element_blank(), # 图例键无边框      legend.box.background = element_blank(), # 图例框背景透明      legend.box.margin = margin(5555),      legend.spacing.y = unit(0.2"cm"),      legend.text = element_text(size = 10),      plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),      plot.subtitle = element_text(hjust = 0.5, size = 12),      axis.title.x = element_blank(), # 删除X轴标题      axis.text.x = element_blank(),      axis.ticks.x = element_blank()    )  # 最大回撤图 - 使用bw主题,删除图例  p_drawdown <- ggplot(drawdown_long, aes(x = Date, y = 回撤, fill = 策略)) +    geom_area(position = "identity", alpha = 0.3) +    labs(y = "回撤"x = "日期") +    scale_y_continuous(labels = percent_format()) +    scale_fill_manual(values = colors) +    theme_bw(base_family = "simhei") + # 使用bw主题    theme(      legend.position = "none"# 删除图例      plot.title = element_blank(),      axis.title.x = element_text(size = 12)    )  # 组合两个图  plot_grid(p_cumulative, p_drawdown,    ncol = 1, align = "v",    rel_heights = c(10.9)  )}# 4. 绘制组合和基准的对比图cat("正在生成组合和基准的对比图...\n")colors_vs_benchmark <- c(  "龙头动量轮动策略" = "#E41A1C"# 红色  "科创50ETF" = "#377EB8" # 蓝色)p1 <- create_combined_plot(  cumulative_df, drawdown_df,  "龙头动量轮动策略""科创50ETF",  sprintf("龙头动量轮动策略 vs 科创50ETF (N=%d, K=%d, L=%d)", N, K, L),  colors_vs_benchmark)# 5. 绘制组合和等权重组合的对比图cat("正在生成组合和等权重组合的对比图...\n")colors_vs_equal <- c(  "龙头动量轮动策略" = "#E41A1C"# 红色  "等权重组合" = "#4DAF4A" # 绿色)p2 <- create_combined_plot(  cumulative_df, drawdown_df,  "龙头动量轮动策略""等权重组合",  sprintf("龙头动量轮动策略 vs 等权重组合 (N=%d, K=%d, L=%d)", N, K, L),  colors_vs_equal)# 6. 显示图表cat("\n正在显示图表...\n")print(p1)cat("\n\n")print(p2)# 7. 计算并显示绩效指标汇总 - 计算五个核心指标cat("\n正在计算绩效指标...\n")calculate_performance <- function(returns, name) {  # 检查收益率数据  if (length(returns) == 0 || all(is.na(returns))) {    return(data.frame(      策略 = name,      年化收益 = NA,      年化波动率 = NA,      最大回撤 = NA,      夏普比率 = NA,      卡玛比率 = NA    ))  }  # 移除NA值  returns_clean <- na.omit(returns)  if (length(returns_clean) < 2) {    return(data.frame(      策略 = name,      年化收益 = NA,      年化波动率 = NA,      最大回撤 = NA,      夏普比率 = NA,      卡玛比率 = NA    ))  }  # 计算年化收益率、年化波动率和夏普比率  perf <- tryCatch(    {      table.AnnualizedReturns(returns_clean)    },    error = function(e) {      cat(sprintf("计算%s绩效指标时出错: %s\n", name, e$message))      return(matrix(NA, nrow = 3, ncol = 1))    }  )  # 计算最大回撤  max_dd <- tryCatch(    {      maxDrawdown(returns_clean)    },    error = function(e) {      cat(sprintf("计算%s最大回撤时出错: %s\n", name, e$message))      return(NA)    }  )  # 计算卡玛比率(卡尔马比率)  calmar <- tryCatch(    {      CalmarRatio(returns_clean)    },    error = function(e) {      cat(sprintf("计算%s卡玛比率时出错: %s\n", name, e$message))      return(NA)    }  )  df <- data.frame(    策略 = name,    年化收益 = if (!all(is.na(perf))) round(perf[11] * 1002else NA,    年化波动率 = if (!all(is.na(perf))) round(perf[21] * 1002else NA,    最大回撤 = if (!is.na(max_dd)) round(abs(max_dd) * 1002else NA, # 取绝对值,以正数显示    夏普比率 = if (!all(is.na(perf))) round(perf[31], 3else NA,    卡玛比率 = if (!is.na(calmar)) round(calmar, 3else NA  )  colnames(df) <- c("策略""年化收益""年化波动率""最大回撤""夏普比率""卡玛比率")  row.names(df) <- NULL  return(df)}# 计算各策略绩效strategy_perf <- calculate_performance(strategy_returns, "龙头动量轮动策略")benchmark_perf <- calculate_performance(benchmark_returns, benchmark_name)equal_perf <- calculate_performance(equal_returns, "等权重组合")# 合并绩效指标 - 使用dplyr的bind_rows处理列名不一致问题performance_summary <- rbind(strategy_perf, benchmark_perf, equal_perf)cat("\n==================== 绩效指标汇总 ====================\n\n")print(performance_summary)cat("\n")# ==================== 保存结果到文件 ====================cat("正在保存结果到文件...\n")output_dir <- sprintf("龙头动量轮动策略_N%d_K%d_L%d", N, K, L)if (!dir.exists(output_dir)) {  dir.create(output_dir)}# 保存绩效指标write.csv(performance_summary,  file = paste0(output_dir, "/performance_summary.csv"),  row.names = FALSE, fileEncoding = "UTF-8")# 保存累计收益率数据write.csv(cumulative_df,  file = paste0(output_dir, "/cumulative_returns.csv"),  row.names = FALSE, fileEncoding = "UTF-8")# 保存回撤数据write.csv(drawdown_df,  file = paste0(output_dir, "/drawdowns.csv"),  row.names = FALSE, fileEncoding = "UTF-8")# 保存每日权重列表(将列表转换为数据框保存)- 只保存权重大于0的记录if (length(daily_weights_list) > 0) {  daily_weights_df <- do.call(rbind, daily_weights_list)  write.csv(daily_weights_df,    file = paste0(output_dir, "/daily_weights_nonzero.csv"),    row.names = FALSE, fileEncoding = "UTF-8"  )  # 保存每日权重汇总(每个交易日权重合计和选中标的数)  daily_summary <- data.frame(    Date = as.Date(names(daily_weights_list)),    权重合计 = sapply(daily_weights_list, function(df) sum(df$Weight)),    选中标的数 = sapply(daily_weights_list, function(df) nrow(df))  )  write.csv(daily_summary,    file = paste0(output_dir, "/daily_summary.csv"),    row.names = FALSE, fileEncoding = "UTF-8"  )  # 计算每个股票被选中的总天数和平均权重  stock_summary <- daily_weights_df %>%    group_by(Stock) %>%    summarise(      选中天数 = n(),      平均权重 = round(mean(Weight, na.rm = TRUE) * 1003),      选中比例 = round(n() / length(daily_weights_list) * 1001)    ) %>%    arrange(desc(选中天数))  write.csv(stock_summary,    file = paste0(output_dir, "/stock_selection_summary.csv"),    row.names = FALSE, fileEncoding = "UTF-8"  )  cat("股票选中频率排名(前10名):\n")  print(head(stock_summary, 10))  cat("\n")else {  cat("警告: 没有权重大于0的记录,跳过保存权重文件\n")}# 保存动量数据(前5个股票作为示例)momentum_samples <- list()sample_stocks <- colnames(price_xts)[1:min(5, ncol(price_xts))]for (stock in sample_stocks) {  momentum_samples[[stock]] <- data.frame(    Date = index(momentum_list[[stock]]$momentum),    Stock = stock,    Momentum = as.numeric(momentum_list[[stock]]$momentum),    Volatility = as.numeric(momentum_list[[stock]]$volatility),    Adj_Momentum = as.numeric(momentum_list[[stock]]$adj_momentum)  )}momentum_samples_df <- do.call(rbind, momentum_samples)write.csv(momentum_samples_df,  file = paste0(output_dir, "/momentum_samples.csv"),  row.names = FALSE, fileEncoding = "UTF-8")# 保存图表ggsave(paste0(output_dir, "/momentum_vs_benchmark.png"), p1, width = 10, height = 8, dpi = 300)ggsave(paste0(output_dir, "/momentum_vs_equal_weight.png"), p2, width = 10, height = 8, dpi = 300)cat("==================== 回测完成 ====================\n")cat("结果已保存到文件夹:", output_dir, "\n")cat("包含文件:\n")cat("1. performance_summary.csv - 绩效指标汇总\n")cat("2. cumulative_returns.csv - 累计收益率数据\n")cat("3. drawdowns.csv - 回撤数据\n")if (length(daily_weights_list) > 0) {  cat("4. daily_weights_nonzero.csv - 每日权重数据(只包含权重大于0的记录)\n")  cat("5. daily_summary.csv - 每日权重汇总\n")  cat("6. stock_selection_summary.csv - 股票选中频率汇总\n")}cat("7. momentum_samples.csv - 动量数据示例(前5个股票)\n")cat("8. momentum_vs_benchmark.png - 组合和基准对比图\n")cat("9. momentum_vs_equal_weight.png - 组合和等权重组合对比图\n")cat("\n")cat("运行时间统计:\n")cat(sprintf("股票数量: %d\n", ncol(price_xts)))cat(sprintf("交易日数量: %d\n", nrow(price_xts)))cat(sprintf("公共日期数量: %d\n"length(common_dates)))if (length(daily_weights_list) > 0) {  cat(sprintf("有权重分配的交易日数: %d\n"length(daily_weights_list)))}cat(sprintf("策略开始日期: %s\n", as.character(index(strategy_returns)[1])))cat(sprintf("策略结束日期: %s\n", as.character(index(strategy_returns)[length(strategy_returns)])))cat("\n")

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-02-08 14:14:11 HTTP/2.0 GET : https://f.mffb.com.cn/a/463856.html
  2. 运行时间 : 0.218682s [ 吞吐率:4.57req/s ] 内存消耗:4,570.23kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=416b1a8db3fe6492078ec18fd1412c99
  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.001200s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.002153s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000693s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000670s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001758s ]
  6. SELECT * FROM `set` [ RunTime:0.000593s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001885s ]
  8. SELECT * FROM `article` WHERE `id` = 463856 LIMIT 1 [ RunTime:0.003610s ]
  9. UPDATE `article` SET `lasttime` = 1770531251 WHERE `id` = 463856 [ RunTime:0.009519s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 65 LIMIT 1 [ RunTime:0.000699s ]
  11. SELECT * FROM `article` WHERE `id` < 463856 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.001402s ]
  12. SELECT * FROM `article` WHERE `id` > 463856 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001481s ]
  13. SELECT * FROM `article` WHERE `id` < 463856 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.011114s ]
  14. SELECT * FROM `article` WHERE `id` < 463856 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.017668s ]
  15. SELECT * FROM `article` WHERE `id` < 463856 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.003612s ]
0.222471s