解决方案

将量化交易策略的信号自动同步到雪球模拟组合框架

完整框架

import easytrader


# ============================================================
# 1. 填写你的雪球模拟组合参数
# ============================================================

# 雪球 Cookie。
# 推荐填写完整 Cookie 字符串,也可以只填写 xq_a_token 的值。
# 示例:
# COOKIES = "xq_a_token=xxxxxxxx"
# COOKIES = "xxxxxxxx"
COOKIES = "xxxxxx"

# 雪球组合代码,例如:https://xueqiu.com/P/ZH3025080
PORTFOLIO_CODE = "ZH3114624"

# A 股组合一般填 cn;港股填 hk;美股填 us。
PORTFOLIO_MARKET = "cn"

# 是否真的提交调仓。
# False:只打印计划,不提交,适合第一次测试。
# True:连接雪球并提交调仓。
EXECUTE = False


# ============================================================
# 2. 填写目标调仓计划
# ============================================================

# 写法:股票代码 -> 目标权重
# 权重单位是百分比,例如 100 表示 100%,1 表示 1%。
#
# 注意:
# easytrader.adjust_weight 是“单只股票调到指定权重”,不会自动清空其它股票。
# 如果你想把组合完全切换成某几个标的,需要把不想持有的旧标的也写成 0。
#
# 示例 1:清空沪深300ETF,满仓银华日利
# TARGET_WEIGHTS = {
#     "SH510300": 0,
#     "SH511880": 100,
# }
#
# 示例 2:中国平安调到 1%
# TARGET_WEIGHTS = {
#     "SH601318": 1,
# }
TARGET_WEIGHTS = {
    "SH510300": 0,
    "SH511880": 100,
}


def normalize_cookie(cookies):
    """兼容完整 Cookie 和单独 xq_a_token。"""
    cookies = cookies.strip()
    if "=" in cookies:
        return cookies
    return f"xq_a_token={cookies}"


def mask_cookie(cookies):
    """打印时隐藏大部分 Cookie,避免泄露。"""
    if not cookies:
        return ""
    if len(cookies) <= 8:
        return "*" * len(cookies)
    return f"{cookies[:4]}...{cookies[-4:]}"


def check_config():
    """运行前做一些基础检查。"""
    if not COOKIES or COOKIES == "xxxxxx":
        raise ValueError("请先填写 COOKIES")

    if not PORTFOLIO_CODE:
        raise ValueError("请先填写 PORTFOLIO_CODE")

    if PORTFOLIO_MARKET not in ("cn", "hk", "us"):
        raise ValueError("PORTFOLIO_MARKET 只能是 cn、hk 或 us")

    if not TARGET_WEIGHTS:
        raise ValueError("请先填写 TARGET_WEIGHTS")

    for stock_code, weight in TARGET_WEIGHTS.items():
        if weight < 0 or weight > 100:
            raise ValueError(f"{stock_code} 的权重必须在 0 到 100 之间")


def print_plan():
    """打印即将执行的调仓计划。"""
    print("雪球组合自动调仓")
    print("-" * 40)
    print(f"组合代码:{PORTFOLIO_CODE}")
    print(f"市场:{PORTFOLIO_MARKET}")
    print(f"Cookie:{mask_cookie(COOKIES)}")
    print(f"是否执行:{EXECUTE}")
    print("调仓计划:")
    for stock_code, weight in TARGET_WEIGHTS.items():
        print(f"  {stock_code} -> {weight}%")
    print("-" * 40)


def main():
    check_config()
    print_plan()

    if not EXECUTE:
        print("当前 EXECUTE = False,只展示调仓计划,没有连接雪球,也没有提交调仓。")
        print("确认参数无误后,把 EXECUTE 改成 True 再运行。")
        return

    # 指定雪球
    user = easytrader.use("xq")

    # 初始化信息
    user.prepare(
        cookies=normalize_cookie(COOKIES),
        portfolio_code=PORTFOLIO_CODE,
        portfolio_market=PORTFOLIO_MARKET,
    )

    # 打印账户
    print("账户信息:")
    print(user.balance)

    # 打印持仓
    print("当前持仓:")
    print(user.position)

    # 调仓
    for stock_code, weight in TARGET_WEIGHTS.items():
        print(f"正在调仓:{stock_code} -> {weight}%")
        result = user.adjust_weight(stock_code, weight)
        if result:
            print(f"调仓返回:{result}")

    print("调仓请求已提交,请到雪球组合页面核对最终结果。")


if __name__ == "__main__":
    try:
        main()
    except Exception as error:
        print(f"运行失败:{error}")

雪球组合自动调仓教程

这个项目只有两个文件:

  • 雪球组合自动调仓.py:主程序。
  • README.md:使用说明。

它基于 easytrader 操作雪球模拟组合,适合用来演示量化策略如何把目标仓位同步到雪球组合。

1. 安装依赖

先安装 Python,然后安装 easytrader

pip install easytrader==0.23.7

2. 修改主程序参数

打开 雪球组合自动调仓.py,主要改这几处。

COOKIES

填写雪球登录 Cookie。

COOKIES = "xxxxxx"

推荐填写:

COOKIES = "xq_a_token=你的token"

如果你只有 token 值,也可以直接填:

COOKIES = "你的token"

程序会自动补成 xq_a_token=你的token

注意:Cookie 等同于登录凭证,不要公开,不要上传到 GitHub。

PORTFOLIO_CODE

填写雪球组合代码。

例如组合链接是:

https://xueqiu.com/P/ZH3025080

那么组合代码就是:

PORTFOLIO_CODE = "ZH3025080"

PORTFOLIO_MARKET

A 股组合一般填写:

PORTFOLIO_MARKET = "cn"

其它市场:

PORTFOLIO_MARKET = "hk"  # 港股
PORTFOLIO_MARKET = "us"  # 美股

EXECUTE

是否真的提交调仓。

第一次测试建议保持:

EXECUTE = False

这样只会打印调仓计划,不会连接雪球,也不会提交调仓。

确认参数没问题后再改成:

EXECUTE = True

3. 修改调仓计划

TARGET_WEIGHTS 里填写目标权重。

格式是:

TARGET_WEIGHTS = {
    "股票代码": 权重,
}

权重单位是百分比。

示例 1:清空沪深300ETF,满仓银华日利

TARGET_WEIGHTS = {
    "SH510300": 0,
    "SH511880": 100,
}

这等价于你最开始的代码:

user.adjust_weight("SH510300", 0)
user.adjust_weight("SH511880", 100)

示例 2:中国平安调到 1%

TARGET_WEIGHTS = {
    "SH601318": 1,
}

注意:adjust_weight 是把“某一只股票”调到目标权重,不会自动清空其它股票。

如果原组合里还有其它持仓,它们可能会继续保留。想完全切换组合时,需要把不想持有的旧标的也写成 0

例如原来有士兰微,现在想只保留中国平安 1%,可以写:

TARGET_WEIGHTS = {
    "SH600460": 0,
    "SH601318": 1,
}

4. 运行程序

在当前目录打开 PowerShell:

python .\雪球组合自动调仓.py

如果 EXECUTE = False,只会看到类似输出:

雪球组合自动调仓
----------------------------------------
组合代码:ZH3025080
市场:cn
是否执行:False
调仓计划:
  SH601318 -> 1%
----------------------------------------
当前 EXECUTE = False,只展示调仓计划,没有连接雪球,也没有提交调仓。

确认后把 EXECUTE 改成 True,再运行:

python .\雪球组合自动调仓.py

程序会:

  1. 登录雪球组合。
  2. 打印账户信息。
  3. 打印当前持仓。
  4. TARGET_WEIGHTS 顺序提交调仓。
  5. 提示你去雪球页面核对结果。

5. 常见问题

报错:请先填写 COOKIES

说明主程序里的 COOKIES 还是默认值,需要换成你的雪球 Cookie。

报错:not enough values to unpack

通常是 Cookie 格式不对。

可以尝试把:

COOKIES = "你的token"

改成:

COOKIES = "xq_a_token=你的token"

调仓后权重超过 100%

原因通常是只新增或调整了一只股票,但原来的其它持仓还在。

解决办法:把不想持有的旧标的也写进 TARGET_WEIGHTS,并把权重设为 0

为什么程序默认不执行

自动调仓程序必须先看计划,再执行。EXECUTE = False 是保护开关,避免别人刚下载代码就误提交调仓。

6. 免责声明

本程序用于雪球模拟组合教学和量化策略测试,不构成投资建议。请保管好 Cookie,公开分享代码时不要包含真实 Cookie。

发表回复