快速入门
由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()
- dai 数据查询和计算,简单、高性能
- 数据表 股票后复权日行情(cn_stock_bar1d)
.query("SELECT ..")
,执行 SQL 查询.df()
:返回数据转为 pandas DataFrame
查询多表
查询股票收盘价和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()
- 连接数据表 股票状态(cn_stock_status)
date
(日期)和instrument
(股票代码)是很多表的主键,这里用这两个做连接
计算因子
计算股票收盘价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提供多个版本,满足用户不同阶段对数据、算力、算法和平台功能的不同需求
- 社区版:完全免费注册和使用,适合初学者和一般用户
- 标准版:适合专业学习和研究阶段的用户
- 旗舰版:适合深度研究和实盘交易用户,专业、高质量的服务
\