问题描述
解决方案
在PTrade中实现融券策略(即卖空策略),核心在于“高位融券卖出”和“低位买券还券”。
根据PTrade API文档,实现这一逻辑主要需要调用以下两个核心交易函数:
marginsec_open(security, amount, ...):融券卖出。用于在价格高点借入证券并卖出。marginsec_close(security, amount, ...):买券还券。用于在价格低点买入证券并归还给券商,从而平仓获利。
此外,为了策略的稳健性,通常还需要配合查询函数,如 get_marginsec_stocks()(查询是否为融券标的)和 get_position()(查询当前持仓状态)。
策略逻辑说明
以下代码实现了一个简单的双均线融券策略:
- 高点判断:当短期均线(5日)下穿长期均线(10日)形成死叉,且当前没有空头持仓时,视为高点/下跌趋势,执行融券卖出。
- 低点判断:当短期均线(5日)上穿长期均线(10日)形成金叉,且当前持有空头仓位时,视为低点/反转趋势,执行买券还券。
策略代码实现
import numpy as np
def initialize(context):
"""
初始化函数,设置股票池和全局变量
"""
# 设置我们要操作的股票,这里以 600519.SS (贵州茅台) 为例
# 注意:实盘中需确保该股票在券商的融券标的池中
g.security = '600519.SS'
set_universe(g.security)
# 设置均线周期
g.short_window = 5
g.long_window = 10
def handle_data(context, data):
"""
盘中运行函数,每个周期(如每天或每分钟)执行一次
"""
security = g.security
# 1. 获取历史收盘价数据,长度取长周期 + 2 以确保计算足够
# count设置为20,确保有足够数据计算10日均线
history = get_history(20, '1d', 'close', security, fq='pre', include=False)
# 如果数据不足,直接返回
if len(history) < g.long_window:
return
close_prices = history['close'].values
# 2. 计算短期和长期均线
# 计算5日均线
ma_short = close_prices[-g.short_window:].mean()
# 计算10日均线
ma_long = close_prices[-g.long_window:].mean()
# 获取当前持仓信息
position = get_position(security)
# 获取空头持仓数量 (short_amount)
short_amount = position.short_amount
# 获取当前最新价格
current_price = data[security]['close']
# 打印调试信息
log.info("当前价格: %.2f, MA5: %.2f, MA10: %.2f, 空头持仓: %d" % (current_price, ma_short, ma_long, short_amount))
# 3. 交易逻辑
# 【融券卖出逻辑】:死叉(短均线下穿长均线)且无空头持仓 -> 认为处于高点/下跌趋势
if ma_short < ma_long and short_amount == 0:
log.info("满足融券卖出条件(高点/死叉),执行融券卖出...")
# 检查是否为融券标的 (可选,增强稳健性)
# margin_stocks = get_marginsec_stocks()
# if security in margin_stocks:
# 融券卖出 100 股
# 注意:amount 必须为正数
marginsec_open(security, 100)
# 【买券还券逻辑】:金叉(短均线上穿长均线)且有空头持仓 -> 认为处于低点/反弹趋势
elif ma_short > ma_long and short_amount > 0:
log.info("满足买券还券条件(低点/金叉),执行买券还券...")
# 买券还券,归还所有空头持仓
# 注意:amount 必须为正数
marginsec_close(security, short_amount)
代码关键点解析
-
marginsec_open(security, 100):- 这是核心函数。当策略判断当前价格处于高位(本例中使用均线死叉判断)时调用。
- 参数
amount填入正整数(如100),表示融券卖出的数量。 - 注意:调用此函数前,账户必须开通两融权限,且该股票必须在券商的融券标的名单内。
-
marginsec_close(security, short_amount):- 这是平仓函数。当策略判断价格回落到低位(本例中使用均线金叉判断)时调用。
- 它会从市场买入股票并直接归还给券商,了结负债。
-
get_position(security).short_amount:- 在普通股票交易中我们通常关注
amount,但在两融策略中,必须区分多头和空头。 short_amount专门用于获取当前的融券卖出持仓数量(即负债数量)。
- 在普通股票交易中我们通常关注
-
get_history:- 用于获取计算均线所需的历史数据。建议
count设置得稍大一些(如20),以防止数据计算边界问题。
- 用于获取计算均线所需的历史数据。建议
常见问题 (Q&A)
Q: 如何确认一只股票是否允许融券卖出?
A: 可以使用 get_marginsec_stocks() 函数。该函数返回当前交易所披露的可融券标的列表。在实盘中,建议在下单前判断 if security in get_marginsec_stocks(): 以避免废单。
Q: marginsec_direct_refund 和 marginsec_close 有什么区别?
A:
marginsec_close(买券还券):是你手里没有股票,使用资金从市场买入股票,买入后立即自动还给券商。这是最常用的平仓方式。marginsec_direct_refund(直接还券):是你账户里已经持有了现券(比如通过普通买入获得的股票),直接把这些现券划转给券商用来还债。
Q: 融券卖出时,价格可以随便填吗?
A: 不可以。根据交易所规定,融券卖出的申报价格不得低于该证券的最新成交价(即“提价规则”)。如果使用限价单(limit_price),需要注意价格限制。上述代码中未指定价格,默认使用市价或最新价逻辑(视回测/实盘配置而定),系统通常会自动处理合规性。
Q: 回测和实盘在两融函数上有什么区别?
A: marginsec_open 和 marginsec_close 是 PTrade 专用的两融交易函数。在实盘中,必须登录两融账号(信用账户)才能调用成功。在回测中,需要在设置中开启融资融券模式,否则可能会报错或无法成交。