策略能有效回测但提交实盘没有信号
由jameszhanfeng0创建,最终由jameszhanfeng0 被浏览 2 用户
策略社区的小市值策略拿来修改了一下(增加一些选股条件),能回测但提交实盘不产生信号,策略代码如下:
from bigquant import bigtrader, dai
import pandas as pd
def initialize(context: bigtrader.IContext):
context.set_commission(bigtrader.PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
# 策略参数
stock_num = 3 # 持股数量
float_market_cap_threshold = 500000000 # 流通市值下限 5亿
pe_lower_bound = 0
pe_upper_bound = 50
pb_upper_bound = 5
net_profit_yoy_threshold = 0.2
revenue_yoy_threshold = 0.2
list_days_threshold = 365 # 上市天数一年
context.holding_nums = stock_num
context.counter = 1
context.logger.info("开始计算选股数据...")
sql = """
SELECT
date,
instrument,
total_market_cap,
-- 等权重
1.0/$stock_num AS weight
FROM cn_stock_prefactors
WHERE
-- 非ST股票
st_status = 0
-- 非科创板
AND list_sector != 3
AND list_sector != 4
-- 非停牌
AND suspended = 0
-- 流通市值大于 5 亿元
AND float_market_cap > $float_market_cap_threshold
-- 非新股,上市时间大于一年
AND list_days > $list_days_threshold
-- 净利润同比增长 > 20%
AND net_profit_to_parent_shareholders_ttm_yoy > $net_profit_yoy_threshold
-- 营业收入同比增长 > 20%
AND total_operating_revenue_ttm_yoy > $revenue_yoy_threshold
AND total_liabilities / total_assets < 0.6
-- 0 < 市盈率 < 50
AND pe_ttm > $pe_lower_bound AND pe_ttm < $pe_upper_bound
-- 市净率 < 5
AND pb < $pb_upper_bound
-- 近一个月无减持公告 (假设字段存在)
-- AND NOT has_reduction_announcement_1m
ORDER BY date, total_market_cap ASC
"""
params = {
"stock_num": stock_num,
"float_market_cap_threshold": float_market_cap_threshold,
"pe_lower_bound": pe_lower_bound,
"pe_upper_bound": pe_upper_bound,
"pb_upper_bound": pb_upper_bound,
"net_profit_yoy_threshold": net_profit_yoy_threshold,
"revenue_yoy_threshold": revenue_yoy_threshold,
"list_days_threshold": list_days_threshold
}
# 查询数据
df = dai.query(sql, filters={"date": [context.add_trading_days(context.start_date, -10), context.end_date]}, params=params).df()
context.logger.info(f"数据计算完成,共 {len(df)} 条记录")
# # 每个交易日选取总市值最小的前N只股票
# df = df.groupby('date').head(stock_num)
# df = bigtrader.TradingDaysRebalance(5, context=context).select_rebalance_data(df) # 每5个交易日调仓
# 保存到context中供后续使用
context.data = df
def handle_data(context: bigtrader.IContext, data: bigtrader.IBarData):
#获取当前日期
current_date = data.current_dt.strftime("%Y-%m-%d")
# 获取当日数据
current_day_data = context.data[context.data["date"] == current_date]
instrument_list = current_day_data.sort_values(["total_market_cap"], ascending=[True])["instrument"].values[:context.holding_nums]
context.target_weights = {ins: 1/len(instrument_list) for ins in instrument_list}
if len(current_day_data) == 0:
return
context.counter += 1
if context.counter == 3:
context.counter = 0
# 获取当前已持有股票
current_hold_instruments = set(context.get_account_positions().keys())
for ins in current_hold_instruments:
# 若长线大于短线且有持仓
if ins not in instrument_list:
context.order_target(ins, 0)
for ins in instrument_list:
# 若短线大于长线且没有持仓
if ins not in current_hold_instruments:
context.order_target_percent(ins, context.target_weights[ins])
performance = bigtrader.run(
market=bigtrader.Market.CN_STOCK,
frequency=bigtrader.Frequency.DAILY,
start_date="2025-01-01",
end_date="2026-04-17",
capital_base=300000.00,
initialize=initialize,
handle_data=handle_data,
)
performance.render()
\