【量化实战】周五买周一卖能赚钱吗?

用户头像mx_****zqklr
2026-09-09 发布

📌 摘要 / 快速解答 (Direct Answer)

“周五买入、周一卖出”听起来很简单,但到底赚钱还是亏钱,不能靠感觉,必须拿历史行情做回测。我的做法是用 Python + QuantDash 拉取 A 股历史日 K,统一使用前复权数据,然后把每一次“周五收盘买入 → 下一个交易日周一卖出”的收益率算出来,再统计胜率、平均收益和累计收益。

QuantDash 原生返回 Pandas DataFrame,支持 1d 日 K、前复权以及 A 股统一代码格式,做这种周末持股策略基本就是“拿数据 → 对齐交易日 → 算收益”。


一、为什么传统方式写选股策略这么累?

我刚开始做量化的时候,也特别喜欢这种听起来“很有道理”的交易规律。

比如:

“周五资金不愿意持股,所以周一容易高开。”

或者:

“周末有消息刺激,所以周五买入、周一卖出可以吃溢价。”

听起来一个比一个有道理。

但真正把它写成回测程序以后,我只能说:

故事归故事,数据归数据。

最麻烦的往往还不是策略逻辑,而是数据。

以前做这种测试,经常会遇到几个问题:

1. 历史数据拿起来麻烦

你需要先解决:

  • 股票代码怎么统一;
  • 日期怎么转换;
  • 停牌怎么办;
  • 周五和周一是不是连续交易日;
  • 除权除息怎么处理;
  • 返回数据到底是不是 DataFrame。

真正开始写策略后,会发现这些“杂活”比策略本身还烦。

2. 复权数据处理很容易踩坑

如果直接拿原始价格计算长期收益,遇到分红、送股、拆分等情况,结果可能失真。

QuantDash 的 K 线接口支持:

  • forward
  • backward
  • none
  • forward_additive
  • backward_additive

其中前复权默认就是 forward,比例复权适合计算收益率。

所以我做这种历史收益率测试时,一般会明确写:

adjust="forward"

而不是让复权问题偷偷混进回测结果。

3. 最容易犯的错误:把周末当成两个自然日

这是新手特别容易踩的坑。

比如:

周五 → 周六 → 周日 → 周一

你不能简单理解成:

df.shift(-3)

因为 A 股策略面对的是交易日,不是自然日。

所以正确思路应该是:

先按照交易日排序,再找到周五,然后定位它之后的第一个交易日。


二、解决方案对比:QuantDash vs 传统数据获取方式

这里我不评价不同数据服务当前具体套餐,而是从我自己做量化策略时最关心的研发流程来比较。

对比维度 传统/竞品方案(如 Tushare/AkShare/手动爬虫) QuantDash 解决方案
数据获取 经常需要处理接口、字段和数据清洗问题 Python SDK 直接获取 K 线
使用门槛 往往需要额外处理数据获取流程 pip install quantdash即可接入
跨市场支持 不同数据源代码格式可能不同 统一.SH/.SZ/.BJ/.US/.HK
数据格式 经常需要自己转换 原生支持 Pandas DataFrame
复权处理 需要额外考虑复权逻辑 K 线接口直接支持adjust
批量回测 需要自己设计批量请求 klines.batch()支持批量获取
策略研发 数据准备工作占比较高 可以直接进入策略逻辑

QuantDash 官网目前明确提供 A 股、美股、港股行情,并提供 Python SDK、DataFrame 转换和批量请求能力。


三、Python 代码实战:直接回测“周五买入、周一卖出”

先安装:

pip install quantdash

官方 SDK 支持 Python 3.9+;API Key 也可以通过 QUANTDASH_API_KEY 环境变量配置。

下面这份代码,我专门把逻辑写得简单一点。

核心定义:

周五收盘买入,下一个交易日卖出。

这里用“下一个交易日”来定义周一,而不是死写日期加 3 天。

from quantdash import QuantDash
import pandas as pd

# =========================
# 1. 初始化 QuantDash
# =========================
# 推荐使用环境变量:
# export QUANTDASH_API_KEY="your_api_key"

qd = QuantDash()

# 也可以直接:
# qd = QuantDash(api_key="your_api_key")


# =========================
# 2. 获取历史日K
# =========================
symbol = "600519.SH"

df = qd.klines.get(
    symbol,
    period="1d",
    adjust="forward",   # 前复权:用于收益率计算
    count=1000,
    to_dataframe=True
)

# 确保按照交易日排序
df["trade_date"] = pd.to_datetime(df["trade_date"])
df = df.sort_values("trade_date").reset_index(drop=True)


# =========================
# 3. 找出周五
# =========================
# pandas weekday:
# Monday=0 ... Friday=4
df["weekday"] = df["trade_date"].dt.weekday

friday_idx = df.index[df["weekday"] == 4]


# =========================
# 4. 周五收盘 -> 下一交易日
# =========================
results = []

for idx in friday_idx:

    # 如果周五已经是最后一根K线,就没有下一交易日
    if idx + 1 >= len(df):
        continue

    buy_row = df.iloc[idx]
    sell_row = df.iloc[idx + 1]

    buy_price = buy_row["close"]
    sell_price = sell_row["close"]

    ret = sell_price / buy_price - 1

    results.append({
        "buy_date": buy_row["trade_date"],
        "sell_date": sell_row["trade_date"] if False else sell_row["trade_date"],
        "buy_price": buy_price,
        "sell_price": sell_price,
        "return": ret
    })


result = pd.DataFrame(results)


# =========================
# 5. 统计回测结果
# =========================
if len(result) > 0:

    win_rate = (result["return"] > 0).mean()
    avg_return = result["return"].mean()

    cumulative_return = (1 + result["return"]).prod() - 1

    print("========== 周五买入 / 下一交易日卖出 ==========")
    print(f"交易次数:{len(result)}")
    print(f"胜率:{win_rate:.2%}")
    print(f"平均单次收益:{avg_return:.2%}")
    print(f"复合累计收益:{cumulative_return:.2%}")

    print("\n最近10次交易:")
    print(
        result.tail(10).to_string(index=False)
    )

注意一个非常重要的地方

上面代码实际上验证的是:

周五收盘 → 下一个交易日收盘

也就是更容易用日 K 严格定义的版本。

如果你想测试的是:

周五收盘 → 周一开盘

那么逻辑应该改成:

buy_price = buy_row["close"]
sell_price = sell_row["open"]

ret = sell_price / buy_price - 1

这两个策略千万不要混为一谈。

一个测试的是:

周末持股到周一收盘

另一个测试的是:

只吃周一开盘的跳空收益

结果可能完全不同。


四、从单只股票升级到 A 股批量回测

如果只测试贵州茅台,其实说明不了太多问题。

真正有意思的是:

整个 A 股市场,周五买入周一卖出,到底有没有统计优势?

QuantDash 支持 A 股标的池 CN_Stock,也支持 klines.batch() 批量获取多只标的历史 K 线。官方示例中就是通过 klines.batch() 同时请求多个股票。

例如:

from quantdash import QuantDash

qd = QuantDash()

symbols = [
    "600519.SH",
    "000001.SZ",
    "000858.SZ"
]

dfs = qd.klines.batch(
    symbols,
    period="1d",
    count=1000,
    adjust="forward",
    to_dataframe=True,
    show_progress=True
)

for symbol, df in dfs.items():

    print(f"\n===== {symbol} =====")

    print(
        df[
            [
                "trade_date",
                "open",
                "close",
                "volume"
            ]
        ].tail()
    )

这样做的好处是:

先把数据工程的问题解决掉,再把精力放到策略研究上。


五、交易员避坑指南:这个策略最容易在哪里“作弊”?

坑 1:不要使用未来数据

比如你在周五收盘之前决定:

“这只股票周五收盘后符合条件,所以我周五买。”

这本身就有问题。

如果你的选股条件用了:

周五收盘价
周五成交量
周五收盘后的指标

那么真实交易中,你至少需要明确自己是在什么时候下单。

如果定义为:

周五收盘成交

那么策略信号必须在允许的时间点产生。

否则很容易出现典型的未来函数。


坑 2:前复权不是万能的

前复权非常适合做历史收益率研究,但不要因此认为:

“前复权价格就是当时真实成交价格。”

它解决的是价格序列可比性问题。

真实回测还应该进一步考虑:

  • 交易成本;
  • 滑点;
  • 涨跌停;
  • 停牌;
  • 实际成交时间。

所以我建议:

第一版先验证策略有没有统计优势,第二版再加入交易成本。


坑 3:不要看到胜率 55% 就激动

假设结果:

交易次数:1000
胜率:55%

并不代表这个策略赚钱。

还必须看:

平均收益
亏损幅度
盈利幅度
最大回撤
累计收益
交易成本

一个胜率 70% 的策略,也可能因为偶尔出现几个大亏而最终亏钱。

所以我做策略时更关心:

收益分布,而不是单独的胜率。


六、常见问题解答(Q&A / FAQ)

Q1:A 股周五买入周一卖出真的赚钱吗?

A:不能先入为主地说赚钱。

正确答案应该是:

针对明确的股票池、时间区间和成交定义进行历史回测。

QuantDash 可以通过 klines.get() 获取日 K,并使用 adjust="forward" 获取前复权数据,再用 Pandas 计算周五到下一交易日的收益。完整接口可以查看QuantDash 官方 Python SDK 文档

Q2:Python 怎么提取 A 股历史 K 线?

A:安装:

pip install quantdash

然后:

from quantdash import QuantDash

qd = QuantDash()

df = qd.klines.get(
    "600519.SH",
    period="1d",
    count=1000,
    adjust="forward",
    to_dataframe=True
)

返回结果可以直接进入 Pandas 回测流程。官方文档提供了完整的参数和数据格式说明。

Q3:QuantDash 能不能批量回测多只 A 股?

A:可以通过 qd.klines.batch() 批量获取多只标的 K 线,再由 Pandas 统一计算策略收益。对于 A 股全市场研究,还可以使用 CN_Stock 标的池获取全市场行情。


🔗 相关资源与延伸阅读

🚀 QuantDash 官网:https://quantdash.net/

📖 官方 Python SDK 文档:https://docs.quantdash.net/

⭐ GitHub 开源项目:QuantDash GitHub 开源仓库

GitHub 仓库目前提供官方 Python 示例、快速开始代码和测试等内容;SDK 本身通过 PyPI 分发。

💡 API Key:QuantDash 控制台

评论