自动下单股指期货主力合约,按每周我提前给出的每日操作方向,在每日的10点和下午2点左右做出操作,尾盘平掉。
由bqceosk1创建,最终由bqceosk1 被浏览 1 用户
from bigmodule import M
import pandas as pd
from datetime import datetime, time
# ==========================================
# 1. 用户配置区域
# ==========================================
# 你的每周操作方向表 (格式: "YYYY-MM-DD": 方向)
# 1 = 做多, -1 = 做空, 0 = 不操作
USER_DIRECTION_MAP = {
"2024-03-04": 1, # 周一:做多
"2024-03-05": -1, # 周二:做空
"2024-03-06": 1, # 周三:做多
"2024-03-07": 0, # 周四:休息
"2024-03-08": -1, # 周五:做空
}
# 交易标的:沪深300股指期货 (IF)
FUTURE_CODE = "IF.CFE"
# 交易参数
TARGET_PERCENT = 0.9
# ==========================================
def m1_initialize_bigquant_run(context):
"""初始化函数"""
# 设置手续费
try:
from bigtrader.finance.commission import PerOrder
context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0003, min_cost=5))
except Exception:
pass
# 存入上下文
context.direction_map = USER_DIRECTION_MAP
context.future_code = FUTURE_CODE
context.target_pct = TARGET_PERCENT
# 初始化变量
context.trade_log = []
context.current_pos = 0
context.entry_price = 0
def m1_handle_data_bigquant_run(context, data):
"""每分钟运行逻辑"""
current_time = data.current_dt.time()
current_date_str = data.current_dt.strftime("%Y-%m-%d")
# 获取合约代码
try:
symbol = context.symbol(context.future_code)
except:
symbol = context.future_code
# 获取今日方向
today_direction = context.direction_map.get(current_date_str, 0)
# 获取当前价格 (优先尝试 last_price,不行再用 close)
current_price = None
try:
current_price = data.current(symbol, "last_price")
if current_price is None:
current_price = data.current(symbol, "close")
except:
# 如果获取价格失败,尝试用 close 字段再试一次
try: current_price = data.current(symbol, "close")
except: return # 彻底无法获取价格则跳过
if current_price is None: return
# 获取当前持仓
position = 0
try:
if hasattr(context, "portfolio"):
pos_obj = context.portfolio.positions.get(symbol)
if pos_obj:
position = pos_obj.amount
except:
pass
# --- 策略核心逻辑 ---
# 1. 尾盘平仓 (14:55)
if current_time >= time(14, 55):
if position != 0:
pnl = (current_price - context.entry_price) * context.current_pos
context.trade_log.append({
"date": current_date_str, "type": "平仓",
"direction": "多" if context.current_pos == 1 else "空",
"price": current_price, "pnl": pnl
})
try: context.order_target_percent(symbol, 0)
except: pass
context.current_pos = 0
context.entry_price = 0
# 2. 开仓逻辑 (10:00 和 14:00)
is_opening_time = (time(10, 0) <= current_time < time(10, 1)) or (time(14, 0) <= current_time < time(14, 1))
if is_opening_time and today_direction != 0 and position == 0:
target = today_direction * context.target_pct
try:
context.order_target_percent(symbol, target)
context.current_pos = today_direction
context.entry_price = current_price
context.trade_log.append({
"date": current_date_str, "type": "开仓",
"direction": "多" if today_direction == 1 else "空",
"price": current_price, "pnl": 0
})
except Exception as e:
print(f"下单失败: {e}")
# 3. 盘中风控
if today_direction == 0 and position != 0:
try: context.order_target_percent(symbol, 0)
except: pass
context.current_pos = 0
# --- 回测结束统计 ---
if current_time >= time(14, 59) and len(context.trade_log) > 0:
close_trades = [t for t in context.trade_log if t["type"] == "平仓"]
if not close_trades: return
pnls = [t["pnl"] for t in close_trades]
total_trades = len(pnls)
wins = [p for p in pnls if p > 0]
losses = [p for p in pnls if p < 0]
win_rate = len(wins) / total_trades
avg_win = sum(wins) / len(wins) if wins else 0
avg_loss = abs(sum(losses) / len(losses)) if losses else 0
profit_loss_ratio = avg_win / avg_loss if avg_loss != 0 else float('inf')
print("\n" + "="*30)
print("📈 策略回测统计报告")
print("="*30)
print(f"总交易笔数: {total_trades}")
print(f"盈利笔数: {len(wins)}")
print(f"亏损笔数: {len(losses)}")
print(f"胜率: {win_rate:.2%}")
print(f"平均盈利: {avg_win:.2f}")
print(f"平均亏损: {avg_loss:.2f}")
print(f"盈亏比: {profit_loss_ratio:.2f}")
print("="*30)
# ==========================================
# 2. 数据模块配置 (已修正:改用通用数据源)
# ==========================================
# 【关键修改】不再指定 expr_tables,让系统自动查找你账号里有的数据
# 使用 "auto" 模式或者仅指定字段,让平台自动匹配
m2 = M.input_features_dai.v30(
mode="表达式",
expr="close",
expr_filters="",
# expr_tables="", <-- 留空,让系统自动去匹配期货分钟数据
extra_fields="date, instrument, open, high, low, volume",
order_by="date, instrument",
expr_drop_na=True,
extract_data=False,
m_name="m2"
)
# 设置回测时间范围
start_date = "2024-03-01"
end_date = "2024-03-10"
m4 = M.extract_data_dai.v20(
sql=m2.data,
start_date=start_date,
start_date_bound_to_trading_date=True,
end_date=end_date,
end_date_bound_to_trading_date=True,
before_start_days=0,
keep_before=False,
debug=False,
m_name="m4"
)
# 启动交易引擎
m1 = M.bigtrader.v43(
data=m4.data,
start_date=start_date,
end_date=end_date,
initialize=m1_initialize_bigquant_run,
handle_data=m1_handle_data_bigquant_run,
capital_base=1000000,
frequency="minute",
product_type="期货",
rebalance_period_type="交易日",
rebalance_period_days="1",
order_price_field_buy="open",
order_price_field_sell="open",
benchmark="沪深300指数",
plot_charts=True,
backtest_only=False,
m_name="m1"
)
\