问题描述
解决方案
这是一个基于聚宽(JoinQuant)API编写的融资融券策略。
策略说明
- 账户设置:在
initialize中必须使用set_subportfolios将账户类型设置为'stock_margin'(融资融券账户),否则无法调用融资接口。 - 开仓逻辑(融资买入):当股价突破20日均线时,使用
margincash_open进行融资买入(向券商借钱买股)。 - 平仓逻辑(卖券还款):
- 止盈:当收益率达到 10% 时触发。
- 止损:当收益率跌破 -5% 时触发。
- 使用
margincash_close进行卖券还款(卖出股票,资金优先偿还融资负债)。
策略代码
# -*- coding: utf-8 -*-
from jqdata import *
def initialize(context):
"""
初始化函数,设定基准、账户类型及全局变量
"""
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 过滤掉order系列API产生的比error级别低的log
log.set_level('order', 'error')
# 【关键步骤】初始化融资融券账户
# 默认账户类型是 stock,必须设置为 stock_margin 才能进行融资融券交易
# 这里我们将所有初始资金都分配给融资融券账户
init_cash = context.portfolio.starting_cash
set_subportfolios([SubPortfolioConfig(cash=init_cash, type='stock_margin')])
# 设定要操作的股票:平安银行
g.security = '000001.XSHE'
# 策略参数设置
g.ma_days = 20 # 均线周期
g.tp_ratio = 0.10 # 止盈比例 10%
g.sl_ratio = 0.05 # 止损比例 5%
# 每天开盘时运行
run_daily(market_open, time='09:30')
def market_open(context):
"""
每日交易逻辑
"""
security = g.security
# 获取当前标的的持仓对象
position = context.portfolio.positions[security]
# 获取当前行情数据
current_data = get_current_data()[security]
# 如果停牌则跳过
if current_data.paused:
return
current_price = current_data.last_price
# -----------------------------------------------------------------
# 1. 止盈止损逻辑 (如果有持仓)
# -----------------------------------------------------------------
if position.total_amount > 0:
# 获取持仓成本
cost = position.avg_cost
# 计算当前收益率
returns = (current_price - cost) / cost
# 检查止盈
if returns >= g.tp_ratio:
log.info("触发止盈 (收益率: %.2f%%),执行卖券还款: %s" % (returns * 100, security))
# 【关键API】卖券还款:卖出股票,获得的资金自动用于归还融资负债
# closeable_amount 为可卖出的股数
margincash_close(security, position.closeable_amount)
return
# 检查止损
elif returns <= -g.sl_ratio:
log.info("触发止损 (收益率: %.2f%%),执行卖券还款: %s" % (returns * 100, security))
# 【关键API】卖券还款
margincash_close(security, position.closeable_amount)
return
# -----------------------------------------------------------------
# 2. 开仓逻辑 (如果没有持仓)
# -----------------------------------------------------------------
else:
# 获取过去 g.ma_days 天的收盘价数据
hist = attribute_history(security, g.ma_days, '1d', ['close'])
# 计算均线
ma_price = hist['close'].mean()
# 如果当前价格高于均线,视为上涨趋势,进行买入
if current_price > ma_price:
# 获取账户可用资金
cash = context.portfolio.available_cash
# 计算可买数量 (向下取整到100的倍数)
# 注意:融资买入时,系统会自动根据保证金比例计算最大可买数量
# 这里简单演示使用当前可用现金的一半进行开仓,保留部分保证金
amount = int((cash * 0.5) / current_price / 100) * 100
if amount > 0:
log.info("价格(%.2f)突破%d日均线(%.2f),执行融资买入: %s, 数量: %d" % (current_price, g.ma_days, ma_price, security, amount))
# 【关键API】融资买入:向券商借钱买入股票
margincash_open(security, amount)
常见问题 (Q&A)
Q: 为什么回测时报错 AttributeError: 'SubPortfolio' object has no attribute 'margincash_open'?
A: 这是因为没有正确初始化账户类型。默认的账户类型是 'stock'(普通股票账户),不支持融资融券。必须在 initialize 函数中使用 set_subportfolios 将 type 设置为 'stock_margin'。
Q: margincash_close 和 order_target 有什么区别?
A: 在融资融券账户中:
margincash_close是卖券还款。卖出股票后,资金会优先偿还融资负债,剩余部分变成可用资金。order系列函数(如order_target)在融资融券账户中通常用于普通买卖担保品,或者在某些特定设置下行为可能不同。为了明确意图,建议融资买入用margincash_open,卖券还款用margincash_close。
Q: 如何设置融资利率和保证金比例?
A: 可以使用 set_option 进行设置,例如:
set_option('margincash_interest_rate', 0.08)设置年化融资利率为 8%。set_option('margincash_margin_rate', 1.0)设置融资保证金比例为 100%。