BigQuant使用文档

快速入门

由jliang创建,最终由small_q 被浏览 54 用户

快速开始第一个策略

新建策略

打开 编写策略 > 点击左侧 + AIStudio 新建策略 > 点击模版 可视化线性策略 > 回车确认

新建可视化线性策略

运行回测

点击右上角 全部运行,运行回测,查看回测绩效

部署模拟交易

点击右上角 提交模拟 > 提交任务 确定 > 模拟交易任务页面上点击 查看模拟交易详情 > 查看模拟交易运行情况

查看策略信号

打开 微信 > 打开关注的公众号 BigQuant > 确认收到任务运行后的信号推送 > 查看信号详情。为了避免因微信服务号折叠而漏收消息,请参考下图三给 BigQuant 开启 置顶服务号

如果没有收到信号,进入 我的策略 > 确认策略开启了微信调仓提醒

交易引擎

运行回测

打开 编写策略 > 点击左侧 + AIStudio 新建策略 > 点击模版 空白代码策略 > 回车确认,输入如下代码,运行,查看回测绩效

from bigmodule import M

def handle_data(context, data):
    pass

# 使用 bigtrader 模块运行策略代码,并画出回测曲线图
# 需要指定回测参数:起止时间,初始资金capital_base,回测频率frequency,基准代码
m5 = M.bigtrader.v35(
    data={"instruments": ["600900.SH"]},
    start_date="2024-01-01",
    end_date="2024-01-31",
    handle_data=handle_data
)

  • M.bigtrader 交易引擎,无缝支持回测和模拟交易,使用版本是 v35
  • 上述代码加载股票 600900.SH 的数据,回测时间区间从 2024-01-01 到 2024-01-31,股票、日频,每日收盘后回调 handle_data 函数

策略-买入并持有

from bigmodule import M

def handle_data(context, data):
    # context.data -> M.bigtrader 的参数 data
    # context.get_position 查询指定股票代码的持仓情况,current_qty 持仓量
    if context.get_position(context.data["instruments"][0]).current_qty == 0:
        # 买入 3000 股
        context.order(context.data["instruments"][0], 3000)

# 使用 bigtrader 模块运行策略代码,并画出回测曲线图
# 需要指定回测参数:起止时间,初始资金capital_base,回测频率frequency,基准代码
m5 = M.bigtrader.v35(
    data={"instruments": ["600900.SH"]},
    start_date="2024-01-01",
    end_date="2024-01-31",
    handle_data=handle_data,
    # 设置初始资金为 100000
    capital_base=100000
)

策略-轮流持有

from bigmodule import M

def handle_data(context, data):
    # 三只股票,每天轮流买入持有一只

    # 卖出持有的股票:发出卖出指令,order_target 买卖到目标仓位,0表示目标仓位为0
    for instrument, position in context.get_account_positions().items():
        context.order_target(instrument, 0)

    # 买入下一只股票
    # context.trading_day_index 是交易日计数,从0开始
    # context.order_target_percent 表示买入到目标仓位,1 表示 100%仓位
    context.order_target_percent(context.data["instruments"][context.trading_day_index % len(context.data["instruments"])], 1)

m5 = M.bigtrader.v35(
    data={"instruments": ["000001.SZ", "600900.SH", "601398.SH"]},
    start_date="2024-01-01",
    end_date="2024-01-31",
    handle_data=handle_data,
    capital_base=1000000,
    # 买入在开盘时
    order_price_field_buy="open",
    # 卖出在开盘时
    order_price_field_sell="open",
)

均线策略

import os
from bigmodule import M

def initialize(context):
    from bigtrader.finance.commission import PerOrder
    # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))

def handle_data(context, data):
    instrument = context.data["instruments"][0]

    # 获取过去五天的历史价格
    average_price = data.history(instrument, "close", 5, "1d").mean()
    # #获取当前价格
    current_price = data.current(instrument, "close")

    # 如果上一时间点价格高出五天平均价1%, 则全仓买入
    if current_price > average_price * 1.01:
        context.order_target_percent(instrument, 1.0)
    # 如果上一时间点价格低于五天平均价, 则空仓卖出
    elif current_price < average_price and context.get_position(instrument).current_qty > 0:
        context.order_target(instrument, 0)

m5 = M.bigtrader.v35(
    data={"instruments": ["600900.SH"]},
    # 模拟交易模式下,TRADING_DATE 为交易日期,回测模式下没有这个变量
    start_date=os.getenv("TRADING_DATE", "2024-01-01"),
    # 模拟交易模式下,TRADING_DATE 为交易日期,回测模式下没有这个变量
    end_date=os.getenv("TRADING_DATE", "2024-02-28"),
    # 初始化函数,只最开始运行一次,一般用于设置手续费等
    initialize=initialize,
    handle_data=handle_data,
    capital_base=1000000,
    # 买入指令在开盘时执行
    order_price_field_buy="open",
    # 卖出指令在收盘时执行
    order_price_field_sell="close",
)

  • 通过 os.getenv("TRADING_DATE", "2024-01-01")在模拟交易模式下使用模拟交易日期
  • 可以点击右上角 提交模拟 部署此策略到模拟交易

交易引擎流程框架

图:执行,体现的时间周期,回测/模拟交易的图

数据平台

查询单表

查询A股2024年1月全市场行情数据

import dai
df = dai.query("""
SELECT date, instrument, open, high, low, close, volume
FROM cn_stock_bar1d
WHERE date BETWEEN '2024-01-01' AND '2024-01-31'
ORDER BY date, instrument
"""
).df()

查询多表

查询股票收盘价和ST状态

import dai
df = dai.query("""
SELECT date, instrument, close, st_status
FROM cn_stock_bar1d
    JOIN cn_stock_status USING(date, instrument)
WHERE date BETWEEN '2024-01-01' AND '2024-01-31'
ORDER BY date, instrument
"""
).df()

计算因子

计算股票收盘价5日移动均值

import dai
df = dai.query("""
SELECT date, instrument, m_ta_ema(close, 5) AS ema5
FROM cn_stock_bar1d
WHERE date BETWEEN '2024-01-01' AND '2024-01-31'
ORDER BY date, instrument
"""
).df()
df

  • dai内置了主要常用算子
  • 一般情况下 m_ 前缀的是时序算子(按股票代码分组,按时间排序,分组计算),c_ 前缀的是截面计算(按日期分组,分组计算)

简单动量策略

  • 计算指标:对于每只股票,计算其当前价格与过去5日移动平均价(5日均价)的比值
  • 排序:根据上述比值对所有股票进行排序
  • 选股:选择比值最高的前5只股票进行买入
import os
from bigmodule import M
import dai

# 数据查询和因子score计算,这里可以使用dai的向量化并行计算,在大量数据和复杂因子上,相比于在handle_data中计算因子,可以有10~100x的性能提升
df = dai.query("""
SELECT date, instrument, close / m_ta_ema(close, 5) AS score
FROM cn_stock_bar1d
WHERE date BETWEEN '2024-01-01' AND '2024-01-31'
QUALIFY score IS NOT NULL
ORDER BY date, score DESC, instrument
"""
).df()

def initialize(context):
    from bigtrader.finance.commission import PerOrder
    # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))

    # 定义变量:持仓数量
    context.hold_count = 5
    # 定义变量:等权重持有
    context.weight = 1.0 / context.hold_count

def handle_data(context, data):
    current_df = context.data[context.data["date"] == data.current_dt.strftime("%Y-%m-%d")][:context.hold_count]

    to_hold_instruments = set(current_df["instrument"])
    # 卖出
    for instrument, position in context.get_account_positions().items():
        if instrument not in to_hold_instruments:
            context.order_target(instrument, 0)
    # 买入,目标仓位
    for instrument in current_df["instrument"]:
        context.order_target_percent(instrument, context.weight)

m5 = M.bigtrader.v35(
    data=df,
    # 这里不使用参数 start_date/end_date,bigtrader会使用 data=df 数据的开始/结束日期
    initialize=initialize,
    handle_data=handle_data,
    capital_base=1000000,
    # 日频回测
    frequency="daily",
    # 买入指令在开盘时执行
    order_price_field_buy="open",
    # 卖出指令在收盘时执行
    order_price_field_sell="close",
    # M.bigtrader 默认开启了缓存,这里关闭缓存
    m_cached=False,
)

DAI

AI建模

多因子线性组合

  • 动量因子:截面排序百分位 c_pct_rank(total_market_cap),权重 0.4
  • 市值因子:截面排序百分位 c_pct_rank(close / m_ta_ema(close, 5)),权重 0.6
import os
from bigmodule import M

def extract_data(sql, start_date, end_date):
    import dai
    df = dai.query(sql, filters={"date": [start_date, end_date]}).df()
    return {"data_1": dai.DataSource.write_bdb(df)}

# 数据抽取缓存
m1 = M.python.v2(run=extract_data, input_1="""SELECT date, instrument, c_pct_rank(total_market_cap) * 0.4 +  c_pct_rank(close / m_ta_ema(close, 5)) * 0.6 AS score
FROM cn_stock_bar1d JOIN cn_stock_valuation USING(date, instrument)
QUALIFY score IS NOT NULL
ORDER BY date, score DESC, instrument
""", input_2=os.getenv("TRADING_DATE", "2024-01-01"), input_3=os.getenv("TRADING_DATE", "2024-12-31"))

def initialize(context):
    from bigtrader.finance.commission import PerOrder
    # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))

    # 定义变量:持仓数量
    context.hold_count = 3
    # 定义变量:等权重持有
    context.weight = 1.0 / context.hold_count

def handle_data(context, data):
    current_df = context.data[context.data["date"] == data.current_dt.strftime("%Y-%m-%d")][:context.hold_count]

    to_hold_instruments = set(current_df["instrument"])
    # 卖出
    for instrument, position in context.get_account_positions().items():
        if instrument not in to_hold_instruments:
            context.order_target(instrument, 0)
    # 买入,目标仓位
    for instrument in current_df["instrument"]:
        context.order_target_percent(instrument, context.weight)

m5 = M.bigtrader.v35(
    data=m1.data_1,
    # 这里不使用参数 start_date/end_date,bigtrader会使用 data=df 数据的开始/结束日期
    initialize=initialize,
    handle_data=handle_data,
    capital_base=1000000,
    # 日频回测
    frequency="daily",
    # 买入指令在开盘时执行
    order_price_field_buy="open",
    # 卖出指令在收盘时执行
    order_price_field_sell="close",
)

多因子AI模型

使用 动量因子 和 市值因子,使用机器学习训练模型,预测股票排序

import os
import structlog
from bigmodule import M

logger = structlog.get_logger()

def extract_data(sql, start_date, end_date):
    # TODO: 这里需要考虑往前多取几天数据,因为因子中有用到几天前数据的,不然在模拟交易时 start_date=end_date 只有一天,数据为空,不能出结果
    logger.info(f"extract data {start_date=}, {end_date=} ..")
    import dai
    df = dai.query(sql, filters={"date": [start_date, end_date]}).df()
    return {"data_1": dai.DataSource.write_bdb(df)}

feature_sql = """SELECT
    date,
    instrument,
    c_pct_rank(total_market_cap) AS total_market_cap_pct_rank, c_pct_rank(close / m_ta_ema(close, 5)) momentum_pct_rank
FROM cn_stock_bar1d JOIN cn_stock_valuation USING(date, instrument)
QUALIFY COLUMNS(*) IS NOT NULL
ORDER BY date, instrument
"""

feature_and_label_sql = f"""WITH data AS ({feature_sql})
SELECT 
    data.*,
    m_lead(close, 5) / m_lead(open, 1) AS _future_return,
    c_quantile_cont(_future_return, 0.01) AS _future_return_1pct,
    c_quantile_cont(_future_return, 0.99) AS _future_return_99pct,
    clip(_future_return, _future_return_1pct, _future_return_99pct) AS _clipped_return,
    c_cbins(_clipped_return, 20) AS label
FROM data JOIN cn_stock_bar1d USING(date, instrument)
QUALIFY COLUMNS(*) IS NOT NULL
ORDER BY date, instrument
"""

# 训练数据
m1 = M.python.v2(run=extract_data, input_1=feature_and_label_sql, input_2="2022-01-01", input_3="2023-12-31")
# 测试数据
m2 = M.python.v2(run=extract_data, input_1=feature_sql, input_2="2024-01-01", input_3="2024-12-31")

m3 = M.stockranker.v9(
    train_data=m1.data_1,
    predict_data=m2.data_1,
    learning_algorithm="""排序""",
    # 这里因子比较少,我们用小一点的模型参数
    number_of_leaves=10,
    min_docs_per_leaf=200,
    number_of_trees=10,
    learning_rate=0.1,
    max_bins=1023,
    feature_fraction=1,
    data_row_fraction=1,
    sort_by="""date,instrument""",
    plot_charts=True,
    ndcg_discount_base=1,
)

def initialize(context):
    from bigtrader.finance.commission import PerOrder
    # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))

    # 定义变量:持仓数量
    context.hold_count = 3
    # 定义变量:等权重持有
    context.weight = 1.0 / context.hold_count

def handle_data(context, data):
    current_df = context.data[context.data["date"] == data.current_dt.strftime("%Y-%m-%d")][:context.hold_count]

    to_hold_instruments = set(current_df["instrument"])
    # 卖出
    for instrument, position in context.get_account_positions().items():
        if instrument not in to_hold_instruments:
            context.order_target(instrument, 0)
    # 买入,目标仓位
    for instrument in current_df["instrument"]:
        context.order_target_percent(instrument, context.weight)

m5 = M.bigtrader.v35(
    data=m3.predictions,
    # 这里不使用参数 start_date/end_date,bigtrader会使用 data=df 数据的开始/结束日期
    initialize=initialize,
    handle_data=handle_data,
    capital_base=1000000,
    # 日频回测
    frequency="daily",
    # 买入指令在开盘时执行
    order_price_field_buy="open",
    # 卖出指令在收盘时执行
    order_price_field_sell="close",
)

使用更多计算资源可以加速模型训练,建议切换到 4C~32C。如上例子在8核上,需要训练 2~3分钟。\n

模块化与可视化

可视化线性策略

克隆如下策略并运行和部署模拟交易

https://bigquant.com/codesharev3/f5060072-5af9-4622-bc54-f034c75467f3

可视化AI策略

https://bigquant.com/codesharev3/5251724f-9ac4-4c8a-9cf1-12c831b4cbe0

常用模块

  • 输入特征
  • 抽取数据
  • StockRanker:训练
  • BigTrader:回测&交易

BigQuant平台

BigQuant是一站式量化策略开发AI平台和社区。BigQuant提供的可视化AI开发IDE (AIStudio)和AI Agent (QuantAgent),在降低技术门槛和提高开发效率的同时,增强策略透明度和可理解性、促进创新和灵活性和支持多样化的策略类型。

  • QuantAgent:智能投研和量化策略开发 AI Agent,支持端到端的策略开发、回测和部署,让每个想法都可以并且更高效的实现为策略去验证和运行,适合所有用户
  • AIStudio:专业AI与量化开发IDE,适合希望专业进阶的用户
  • 策略社区:分享策略,学习代码
  • 学院:学习AI与量化知识,获得教学策略用于进一步研究
  • 知识库:做最专业最全面的AI量化知识库,在学习知识的同时,可从这里获得大量的投资研报、论文和策略代码等
  • 数据
  • 因子

BigQuant Pro

BigQuant是一个AI量化平台,为投资者提供新型数据和AI技术服务,是国内目前用户最多和最活跃的AI量化平台。BigQuant提供多个版本,满足用户不同阶段对数据、算力、算法和平台功能的不同需求

  • 社区版:完全免费注册和使用,适合初学者和一般用户
  • 标准版:适合专业学习和研究阶段的用户
  • 旗舰版:适合深度研究和实盘交易用户,专业、高质量的服务

\

标签

模拟交易交易信号

文档

◆快速入门开发量化策略快速教程部署策略复刻策略
{link}