🚀 AI 一键生成 ptrade 策略代码

PTrade 融资融券实战:一步步教你完成“融资买入-持股-卖券还款”全流程

ptrade | 发布时间: 2025/12/18
以下内容由 EasyQuant 生成。

问题描述

我想用代码实现一个完整的融资交易流程,包括查询可融资额度、融资买入、最后再卖掉股票还钱,该怎么写?

解决方案

这是一个关于如何在 PTrade 中实现**融资交易(Margin Trading - Long)**全流程的策略示例。

核心逻辑说明

融资交易主要包含三个步骤:

  1. 查询额度:使用 get_crdt_fund() 查询当前账户的融资可用资金。
  2. 融资买入:使用 margincash_open() 进行融资买入开仓。这会增加你的持仓,同时产生负债。
  3. 卖券还款:使用 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

代码关键点解析

  1. get_crdt_fund():

    • 这是两融专用的查询接口。
    • 返回的字典中 enable_balance 代表当前账户可以用于融资买入的最大资金额度。
    • 注意:在回测或实盘中,必须确保账户性质是信用账户(两融账户),否则此函数可能返回 None 或 0。
  2. margincash_open(security, amount):

    • 融资买入指令。
    • 与普通 order 不同,它使用的是信用额度,成交后会产生负债和利息。
    • amount 必须是正数。
  3. margincash_close(security, amount):

    • 卖券还款指令。
    • 这是最常用的了结融资负债的方式。它卖出股票,所得资金优先偿还该股票对应的融资负债。
    • 如果使用普通的 order 卖出,资金会变成可用现金,而不会自动偿还负债(除非券商柜台有特殊设置),通常建议显式使用 margincash_close
  4. get_position(security):

    • 用于确认当前确实持有该股票,避免在没有持仓的情况下下达卖出指令导致废单。

常见问题 (Q&A)

Q: 为什么回测时 get_crdt_fund() 返回的可用资金很少或为0?
A: 请检查回测设置中的“初始资金”分配。在两融回测中,通常需要设置自有资金,系统会根据保证金比例(如1:1或1:0.5)自动计算信用额度。如果自有资金太少,融资额度也会很低。

Q: margincash_direct_refundmargincash_close 有什么区别?
A:

  • margincash_close (卖券还款):是卖出股票,用卖股票的钱还债。
  • margincash_direct_refund (直接还款):是不卖股票,直接用账户里的现金去还债。适用于你账户里有闲置现金,想降低负债利息的情况。

Q: 融资买入的股票可以当天卖出吗?
A: A股市场实行 T+1 制度,当天融资买入的股票,当天不能通过 margincash_close 卖出,必须等到下一个交易日。

Q: 如何查询当前的负债总额?
A: 可以使用 get_margin_assert() 函数,返回字典中的 total_debit 字段即为负债总额,fin_compact_balance 为融资合约金额。