问题描述
解决方案
这是一个关于如何在 PTrade 中实现**融资交易(Margin Trading - Long)**全流程的策略示例。
核心逻辑说明
融资交易主要包含三个步骤:
- 查询额度:使用
get_crdt_fund()查询当前账户的融资可用资金。 - 融资买入:使用
margincash_open()进行融资买入开仓。这会增加你的持仓,同时产生负债。 - 卖券还款:使用
margincash_close()卖出股票。所得资金会自动优先偿还融资负债,剩余部分(如有)归入自有资金。
策略代码实现
以下代码展示了一个完整的流程:策略启动后,第一天查询额度并融资买入指定股票,持有 5 天后,执行卖券还款操作。
def initialize(context):
"""
初始化函数
"""
# 设定要操作的股票(需确保该标的在券商的两融标的池中)
g.security = '600570.SS'
# 设置股票池
set_universe(g.security)
# 策略控制变量
g.has_financed = False # 是否已融资买入标记
g.hold_days = 0 # 持仓天数计数器
def handle_data(context, data):
"""
盘中运行函数,每个周期(日线或分钟)运行一次
"""
# 获取当前标的
security = g.security
# ---------------------------------------------------
# 第一步 & 第二步:查询额度 并 融资买入
# ---------------------------------------------------
if not g.has_financed:
# 1. 查询可融资金信息
# get_crdt_fund 返回字典,包含 enable_balance(可用资金) 等字段
credit_fund = get_crdt_fund()
if credit_fund is not None:
# 获取融资可用资金
enable_balance = credit_fund.get('enable_balance', 0)
log.info("当前融资可用资金: %s" % enable_balance)
# 假设我们想用 100,000 元进行融资买入(需确保可用资金充足)
target_value = 100000
if enable_balance > target_value:
# 获取当前股价,计算大概买入数量(向下取整到100股)
current_price = data[security]['close']
amount = int(target_value / current_price / 100) * 100
if amount > 0:
# 2. 融资买入 (margincash_open)
# 参数:标的代码,数量,限价(可选)
log.info("资金充足,准备融资买入 %s,数量: %s" % (security, amount))
margincash_open(security, amount)
# 更新状态
g.has_financed = True
g.hold_days = 0
else:
log.info("融资可用资金不足,无法买入")
else:
log.info("获取融资资金信息失败")
# ---------------------------------------------------
# 持仓期:简单计数
# ---------------------------------------------------
elif g.has_financed and g.hold_days < 5:
g.hold_days += 1
log.info("已融资持有 %s 天" % g.hold_days)
# ---------------------------------------------------
# 第三步:卖券还款
# ---------------------------------------------------
elif g.has_financed and g.hold_days >= 5:
# 获取当前持仓
position = get_position(security)
# 检查是否有持仓
if position.amount > 0:
log.info("持仓时间已到,执行卖券还款")
# 3. 卖券还款 (margincash_close)
# 该接口卖出股票后,资金会自动用于归还融资负债
# 卖出所有持仓
margincash_close(security, position.amount)
# 重置状态,以便循环测试(实际策略可视情况决定是否重置)
g.has_financed = False
g.hold_days = 0
else:
log.info("账户无持仓,无法卖券还款")
g.has_financed = False
代码关键点解析
-
get_crdt_fund():- 这是两融专用的查询接口。
- 返回的字典中
enable_balance代表当前账户可以用于融资买入的最大资金额度。 - 注意:在回测或实盘中,必须确保账户性质是信用账户(两融账户),否则此函数可能返回 None 或 0。
-
margincash_open(security, amount):- 融资买入指令。
- 与普通
order不同,它使用的是信用额度,成交后会产生负债和利息。 amount必须是正数。
-
margincash_close(security, amount):- 卖券还款指令。
- 这是最常用的了结融资负债的方式。它卖出股票,所得资金优先偿还该股票对应的融资负债。
- 如果使用普通的
order卖出,资金会变成可用现金,而不会自动偿还负债(除非券商柜台有特殊设置),通常建议显式使用margincash_close。
-
get_position(security):- 用于确认当前确实持有该股票,避免在没有持仓的情况下下达卖出指令导致废单。
常见问题 (Q&A)
Q: 为什么回测时 get_crdt_fund() 返回的可用资金很少或为0?
A: 请检查回测设置中的“初始资金”分配。在两融回测中,通常需要设置自有资金,系统会根据保证金比例(如1:1或1:0.5)自动计算信用额度。如果自有资金太少,融资额度也会很低。
Q: margincash_direct_refund 和 margincash_close 有什么区别?
A:
margincash_close(卖券还款):是卖出股票,用卖股票的钱还债。margincash_direct_refund(直接还款):是不卖股票,直接用账户里的现金去还债。适用于你账户里有闲置现金,想降低负债利息的情况。
Q: 融资买入的股票可以当天卖出吗?
A: A股市场实行 T+1 制度,当天融资买入的股票,当天不能通过 margincash_close 卖出,必须等到下一个交易日。
Q: 如何查询当前的负债总额?
A: 可以使用 get_margin_assert() 函数,返回字典中的 total_debit 字段即为负债总额,fin_compact_balance 为融资合约金额。