我现在想将仓位控制系统: 根据ATR计算每手风险 单笔风险≤账户2%,总仓位≤账户8%,单合约≤50手 动态计算合理开仓手数,实现了双层止损机制(初始固定止损+移动吊灯止损)删除,并且每开仓只开一手
时间: 2025-07-19 09:31:59 浏览: 9
<think>我们将在原策略代码的基础上进行简化,删除复杂的仓位控制和止损机制,改为每开仓只开一手,并且删除双层止损机制,只保留初始固定止损(因为题目要求删除双层止损机制,但注意题目要求每开仓只开一手,所以我们将仓位控制部分简化为固定1手,同时保留初始止损(因为策略中入场条件部分提到了初始止损,但题目要求删除双层止损机制,所以我们只保留初始止损,并去掉移动止损部分?)但是题目要求删除双层止损机制,包括初始固定止损和移动止损。然而,策略逻辑中入场条件部分提到了初始止损,如果完全删除止损,那么策略将没有止损保护。因此,我们需要明确:题目要求是删除双层止损机制(即移除移动止损部分),但可能保留初始止损?但题目明确说“删除,并且每开仓只开一手”。所以这里我们理解为:删除整个仓位控制系统(包括风险计算和动态手数)以及双层止损机制(包括初始止损和移动止损),然后每开仓只开一手,且没有止损(因为止损机制被删除了)。但是这样策略就没有止损了,这在实际中是不合理的。因此,我建议保留一个简单的固定止损(比如2倍ATR),但不再使用移动止损,并且开仓手数固定为1手。
然而,题目要求是:“删除仓位控制系统:根据ATR计算每手风险,单笔风险≤账户2%,总仓位≤账户8%,单合约≤50手,动态计算合理开仓手数,实现了双层止损机制(初始固定止损+移动吊灯止损)删除,并且每开仓只开一手”
所以,我们删除动态仓位计算(改为固定1手),删除双层止损机制(包括初始固定止损和移动止损),但是这样就没有止损了?策略中的平仓条件除了止损还有其他的(目标盈利、超买、趋势反转、尾盘平仓等),所以可能不需要额外的止损逻辑?但原策略入场条件中设置的止损是作为平仓条件之一。因此,我们需要在平仓条件中移除止损相关的条件。
具体修改步骤:
1. 删除`g.stop_loss`、`g.highest_price`、`g.entry_price`等与止损相关的全局变量(但入场价格可能需要保留用于计算盈利?)
2. 删除仓位控制函数`calculate_position_size`,开仓时固定为1手。
3. 在入场时不再设置初始止损(即删除`g.stop_loss`的赋值)。
4. 在平仓条件中,删除关于止损触发的条件(即不再检查价格是否低于止损价)。
5. 删除移动止损的更新逻辑(因为已经删除移动止损,且不再需要更新最高价?但最高价可能用于其他目的?策略中没有,所以可以删除)。
6. 简化后的策略将只保留入场价格用于计算盈利,平仓条件只保留:目标盈利、布林带上轨、超买、趋势反转、尾盘平仓。
注意:原策略中入场条件部分有提到“初始止损:入场价 - 2×ATR(14)”,但根据题目要求,我们要删除这个止损机制(包括初始止损和移动止损),所以我们将不再使用这个止损条件。
但是,策略描述中平仓条件包括“触发止损”,而题目要求删除止损机制,所以我们在平仓条件中应该去掉止损。
因此,修改后的代码将不再有止损逻辑,开仓固定1手。
另外,由于删除了仓位控制,我们不再需要`g.params`中的风险控制参数(如`max_risk_per_trade`等),但其他参数(如布林带参数、RSI参数等)仍需保留。
代码修改:
1. 在`init_params`函数中,删除与止损和仓位控制相关的全局变量(只保留`g.holding_long`和`g.entry_price`,因为入场价格用于计算盈利)。
2. 删除`calculate_position_size`函数。
3. 在交易逻辑中,开仓时固定为1手,不再调用仓位计算函数。
4. 删除持仓处理中关于移动止损和最高价更新的部分(因为不再需要移动止损)。
5. 在平仓条件中,删除止损触发的条件分支。
修改后的代码:</think>我将根据您的要求修改策略代码,删除复杂的仓位控制和止损机制,简化为固定开仓一手并移除止损系统。以下是修改后的代码:
```python
# 导入必要的函数库和指标计算模块
from jqdata import *
from jqlib.technical_analysis import *
import talib
import numpy as np
## 初始化函数,在策略开始时运行一次
def initialize(context):
# 调用初始化参数函数
init_params(context)
# 设置基准指数(IM中证1000)代表市场整体参考指标
set_benchmark(g.benchmark)
# 开启动态复权模式(使用真实价格)
set_option('use_real_price', True)
# 避免未来数据泄漏
set_option("avoid_future_data", True)
# 过滤掉order系列API产生的比error级别低的日志
log.set_level('order', 'error')
# 输出信息到日志中
log.info('初始函数开始运行且全局只运行一次')
### 期货相关设定 ###
# 设定账户为金融期货账户
set_subportfolios([SubPortfolioConfig(cash=context.portfolio.starting_cash, type='index_futures')])
# 设置每笔交易的手续费:开仓和平仓都是万分之0.23
set_order_cost(OrderCost(open_commission=0.000023, close_commission=0.000023, close_today_commission=0.000023),
type='index_futures')
# 设置保证金比例为15%
set_option('futures_margin_rate', 0.15)
# 设置滑点模型,StepRelatedSlippage(2)表示每次下单滑点为2个最小变动单位
set_slippage(StepRelatedSlippage(2))
# 按照指定时间运行函数(reference_security为运行时间的参考标的)
run_daily(before_market_open, time='09:00', reference_security=g.reference)
run_daily(trade, time='every_bar', reference_security=g.reference)
run_daily(after_market_close, time='15:15', reference_security=g.reference)
# 初始化参数函数,设置一些全局变量
def init_params(context):
# 定义不同期货品种对应的现货指数和主力合约
ref_dict = {
'IM': ['000852.XSHG', 'IM8888.CCFX'], # 期货连续合约
}
g.future_type = 'IM' # 当前选择的期货类型为中证1000股指期货(IM)
g.benchmark = ref_dict[g.future_type][0] # 基准指数
g.reference = ref_dict[g.future_type][1] # 主力合约代码
g.holding_long = False # 是否持有多头仓位
g.entry_price = 0.0 # 多头入场价格
# 策略参数
g.params = {
'boll_period': 20, # 布林带周期
'boll_dev': 0.5, # 布林带标准差倍数
'rsi_period': 7, # RSI周期
'kdj_period': 5, # KDJ周期
}
## 开盘前运行函数
def before_market_open(context):
# 获取当前月份和下个月份的合约代码
g.IM_current_month, g.IM_next_month = get_future_contracts(g.future_type)[:2]
# 获取当月合约交割日期
end_date = get_CCFX_end_date(g.IM_current_month)
# 如果今天是交割日,并且还有持仓,则先平仓再换合约
if context.current_dt.date() == end_date:
log.info("--交割日先平仓后重新开仓--")
if g.holding_long: # 如果多头持仓未平
order_target(g.IM_current_month, 0, side='long') # 平仓当月合约
g.holding_long = False
log.info(f"交割日平仓: {g.IM_current_month}")
# 切换到下月合约
g.IM_current_month = g.IM_next_month
log.info(f"切换到新合约: {g.IM_current_month}")
## 实际交易逻辑函数
def trade(context):
IM_current_month = g.IM_current_month # 当前合约
current_data = get_current_data() # 获取最新行情数据
time_str = context.current_dt.strftime('%H%M') # 当前时间字符串格式化
current_price = current_data[IM_current_month].last_price # 当前价格
# 如果涨停或跌停则不交易
if not if_order(IM_current_month):
return
# 获取K线数据 (包含足够的历史数据)
count = max(120, g.params['boll_period'] + 20)
bars = get_bars(IM_current_month, count=count, unit='1m',
fields=['close', 'open', 'high', 'low', 'volume'],
include_now=True, df=True)
# 计算技术指标
closes = bars['close'].values
highs = bars['high'].values
lows = bars['low'].values
volumes = bars['volume'].values
# 计算MA5和MA10 (指数移动平均)
ma5 = talib.EMA(closes, timeperiod=5)
ma10 = talib.EMA(closes, timeperiod=10)
# 计算布林带 (20周期SMA + 0.5标准差)
upper, middle, lower = talib.BBANDS(closes,
timeperiod=g.params['boll_period'],
nbdevup=g.params['boll_dev'],
nbdevdn=g.params['boll_dev'])
# 计算RSI(7)
rsi = talib.RSI(closes, timeperiod=g.params['rsi_period'])
# 计算KDJ(5,3,3)
slowk, slowd = talib.STOCH(highs, lows, closes,
fastk_period=g.params['kdj_period'],
slowk_period=3, slowd_period=3)
j_values = 3 * slowk - 2 * slowd # J线 = 3*K - 2*D
# 获取当前指标值
current_ma5 = ma5[-1]
current_ma10 = ma10[-1]
current_middle = middle[-1]
current_rsi = rsi[-1]
current_j = j_values[-1]
current_volume = volumes[-1]
prev_volume = volumes[-2] if len(volumes) > 1 else 0
# === 时间窗口检查 ===
valid_trading_time = False
# 上午交易时段:开盘后30分钟(10:00)至11:30
if '1000' <= time_str <= '1130':
valid_trading_time = True
# 下午交易时段:13:00至14:00
elif '1300' <= time_str <= '1400':
valid_trading_time = True
# 尾盘时段:14:30后仅在特定条件下交易
elif '1430' <= time_str < '1500':
# 尾盘交易条件:价格持续站稳布林带上轨
if current_price >= upper[-1]:
valid_trading_time = True
# === 多头入场条件 ===
if valid_trading_time and not g.holding_long:
# 条件1: 趋势确认 (MA5上穿MA10且价格在布林带中轨上方)
trend_confirmed = (current_ma5 > current_ma10) and (current_price > current_middle)
# 条件2: 超卖反弹 (RSI<30或J值<0)
oversold = (current_rsi < 30) or (current_j < 0)
# 条件3: 资金流入 (成交量放大≥20%)
volume_increase = (current_volume >= prev_volume * 1.2) if prev_volume > 0 else False
# 综合入场条件
if trend_confirmed and oversold and volume_increase:
# 固定开仓1手
order(IM_current_month, 1, side='long')
g.holding_long = True
g.entry_price = current_price
log.info(f"{time_str} 开多1手 @ {current_price:.2f}")
# === 持仓处理 ===
if g.holding_long:
# === 平仓条件检查 ===
exit_trade = False
# 条件1: 达到目标盈利 (5%)
if (current_price - g.entry_price) / g.entry_price >= 0.05:
log.info(f"达到目标盈利5% @ {current_price:.2f}")
exit_trade = True
# 条件2: 触及布林带上轨
elif current_price >= upper[-1]:
log.info(f"触及布林带上轨 @ {current_price:.2f}")
exit_trade = True
# 条件3: 超买平仓 (RSI>70或J值>100)
elif current_rsi > 70 or current_j > 100:
log.info(f"超买信号 RSI={current_rsi:.2f}, J={current_j:.2f}")
exit_trade = True
# 条件4: 趋势反转 (MA5下穿MA10或价格跌破布林带中轨)
elif (current_ma5 < current_ma10) or (current_price < current_middle):
log.info(f"趋势反转信号 MA5={current_ma5:.2f}, MA10={current_ma10:.2f}, 中轨={current_middle:.2f}")
exit_trade = True
# 收盘前平仓 (14:55后)
elif time_str >= '1455':
log.info("尾盘平仓")
exit_trade = True
# 执行平仓
if exit_trade:
order_target(IM_current_month, 0, side='long')
g.holding_long = False
log.info(f"{time_str} 平多 @ {current_price:.2f}, 盈亏: {(current_price - g.entry_price)/g.entry_price*100:.2f}%")
## 收盘后运行函数
def after_market_close(context):
# 记录当日总结
if g.holding_long:
current_price = get_current_data()[g.IM_current_month].last_price
profit = (current_price - g.entry_price) / g.entry_price * 100
log.info(f"持仓过夜: 入场价={g.entry_price:.2f}, 当前价={current_price:.2f}, 盈亏={profit:.2f}%")
else:
log.info("当日无持仓")
log.info('##############################################################')
########################## 获取期货合约信息 #################################
# 获取金融期货合约到期日
def get_CCFX_end_date(future_code):
return get_security_info(future_code).end_date
# 判断是否可以下单(非涨跌停状态)
def if_order(security):
current_data = get_current_data()
if security not in current_data:
return False
high_limit = current_data[security].high_limit # 涨停价
last_price = current_data[security].last_price # 最新价
low_limit = current_data[security].low_limit # 跌停价
# 如果最新价不是涨停或跌停,则允许下单
if last_price != high_limit and last_price != low_limit:
return True
return False
# 获取期货主力合约和次主力合约
def get_future_contracts(future_type):
# 获取所有可交易的IM合约
contracts = get_all_securities(['futures']).index
im_contracts = [c for c in contracts if c.startswith(future_type)]
# 按到期日排序
im_contracts = sorted(im_contracts, key=lambda x: get_security_info(x).end_date)
# 返回前两个合约(当前主力合约和次主力合约)
return im_contracts[:2] if len(im_contracts) >= 2 else im_contracts
```
### 主要修改内容:
1. **简化仓位控制**:
- 完全移除了基于ATR的仓位计算系统
- 每次开仓固定为1手(`order(IM_current_month, 1, side='long')`)
- 删除了所有仓位控制相关参数和逻辑
2. **移除止损机制**:
- 删除了初始固定止损(入场价 - 2×ATR)
- 删除了移动吊灯止损(历史高点 - 2×ATR)
- 移除了所有止损相关的全局变量和条件判断
3. **简化参数系统**:
- 移除了ATR相关参数(`atr_period`等)
- 移除了风险控制参数(`max_risk_per_trade`等)
- 保留了核心策略参数(布林带、RSI、KDJ)
4. **平仓条件优化**:
- 保留了目标盈利(5%)、布林带上轨、超买信号、趋势反转和尾盘平仓条件
- 移除了止损触发平仓条件
- 固定盈利目标为5%(原为可配置参数)
5. **代码精简**:
- 移除了`calculate_position_size`函数
- 移除了所有ATR计算相关代码
- 简化了全局变量(仅保留`holding_long`和`entry_price`)
该简化版本保留了策略的核心入场逻辑(趋势确认+超卖反弹+资金流入),同时实现了您要求的固定一手开仓和移除止损机制。策略仍保留了多种平仓条件以控制风险,但不再使用复杂的仓位管理和止损系统。
阅读全文
相关推荐

















