🚀 AI 一键生成 ptrade 策略代码

PTrade 两融高级教程:如何实现自动化卖券还款与直接还款策略?

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

问题描述

请帮我写一个策略,当某只融资买入的股票盈利达到15%时,自动卖出股票来偿还融资。

解决方案

这是一个基于PTrade量化交易平台的策略代码。该策略主要用于融资融券账户(信用账户),逻辑是轮询当前持仓,当某只股票的浮动盈亏比例达到或超过15%时,执行“卖券还款”操作。

策略说明

  1. 适用账户:必须是开通了融资融券权限的信用账户。
  2. 核心逻辑
    • handle_data 中遍历当前所有持仓。
    • 计算收益率公式:(当前价格 - 持仓成本) / 持仓成本
    • 如果收益率 $\ge$ 15%,调用 margincash_close 函数。
  3. 关键函数
    • margincash_close(security, amount):这是PTrade中专门用于卖券还款的接口。它会卖出股票,并优先使用卖出的资金偿还融资负债。

策略代码

def initialize(context):
    """
    初始化函数,设置全局变量和股票池
    """
    # 设置我们要操作的股票池
    # 注意:实际实盘中,get_positions会自动获取当前账户持仓,
    # 这里设置universe主要是为了确保handle_data能收到行情推送。
    # 您可以将关注的股票代码放入列表中,例如 ['600519.SS', '000001.SZ']
    g.security = ['600519.SS'] 
    set_universe(g.security)
    
    # 设置止盈阈值,0.15 代表 15%
    g.profit_target = 0.15

def handle_data(context, data):
    """
    盘中运行函数,根据频率(分钟或日线)周期性执行
    """
    # 获取当前账户的所有持仓信息
    # context.portfolio.positions 返回的是一个字典,key是股票代码,value是Position对象
    positions = context.portfolio.positions
    
    # 遍历所有持仓股票
    for security in positions:
        # 获取该股票的持仓对象
        pos = positions[security]
        
        # 如果可用股份数为0,跳过(可能已经卖出、冻结或无持仓)
        if pos.enable_amount <= 0:
            continue
            
        # 获取持仓成本价
        cost = pos.cost_basis
        
        # 获取当前市场价格
        # 优先从data中获取最新行情,如果data中没有(例如停牌),则尝试取持仓快照中的价格
        if security in data:
            current_price = data[security]['close']
        else:
            current_price = pos.last_sale_price
            
        # 计算收益率,需确保成本大于0以避免除零错误
        if cost > 0:
            # 收益率计算公式:(当前价 - 成本价) / 成本价
            profit_rate = (current_price - cost) / cost
            
            # 判断是否达到止盈目标 (>= 15%)
            if profit_rate >= g.profit_target:
                # 记录日志
                log.info("股票 %s 达到止盈条件。" % security)
                log.info("当前价格: %.2f, 成本价: %.2f, 收益率: %.2f%%" % (current_price, cost, profit_rate * 100))
                log.info("执行卖券还款,数量: %d" % pos.enable_amount)
                
                # 执行卖券还款操作
                # margincash_close: 卖券还款接口
                # 参数1: security 股票代码
                # 参数2: amount 数量(这里卖出该股票所有可用持仓)
                margincash_close(security, pos.enable_amount)

def before_trading_start(context, data):
    """
    盘前处理函数(可选)
    """
    pass

def after_trading_end(context, data):
    """
    盘后处理函数(可选)
    """
    pass

注意事项

  1. 卖券还款 vs 普通卖出
    • 代码中使用了 margincash_close,这是专门针对融资负债的接口。如果您只是想普通卖出(不优先还款,或者资金转入余额),可以使用 orderorder_target,但在两融账户中,通常为了减少利息支出,建议使用 margincash_close
  2. 持仓成本 (cost_basis)
    • PTrade 的 cost_basis 通常是根据您的买入均价计算的。如果您的券商柜台计算成本的方式(如摊薄成本)与策略端不同,可能会导致收益率计算有细微偏差。
  3. 交易频率
    • 如果在回测或实盘中选择“分钟线”频率,handle_data 会每分钟运行一次,一旦盘中触及15%即刻卖出。
    • 如果选择“日线”频率,则会在每日收盘前检测一次。
  4. Python版本兼容性
    • 代码已遵循 Python 3.5 兼容性规范(使用 % 进行字符串格式化,未使用 f-string),可直接在 PTrade 环境中运行。

Q&A

Q1: 如果我只想卖出持仓的一半而不是全部,怎么修改?
A1: 将 margincash_close(security, pos.enable_amount) 修改为 margincash_close(security, int(pos.enable_amount * 0.5))。注意需要取整,因为股票交易数量通常需要是整数(且通常为100的倍数,但在清仓或还款时柜台通常允许零股)。

Q2: margincash_closemargincash_direct_refund 有什么区别?
A2: margincash_close卖券还款,即卖出股票,用卖得的钱还款。margincash_direct_refund直接还款,即直接使用账户里的可用现金(Cash)来偿还融资负债,不涉及卖股票的操作。

Q3: 如何在策略中同时设置止损(例如亏损10%卖出)?
A3: 在判断收益率的 if 语句中增加一个 elif 分支即可:

elif profit_rate <= -0.10:
    log.info("股票 %s 触发止损,收益率: %.2f%%" % (security, profit_rate * 100))
    margincash_close(security, pos.enable_amount)