🚀 AI 一键生成 ptrade 策略代码
立即体验

如何在 ptrade 策略中根据当前的登录资金账号执行不同的止损或限额等风控逻辑?

ptrade | 发布时间: 2026/8/7
以下内容由 EasyQuant 生成。

问题描述

ptrade 多账户风控实战:利用 get_user_name 接口实现资金账号差异化风控策略
如何在 ptrade 策略中根据当前的登录资金账号执行不同的止损或限额等风控逻辑?

解决方案

在多账户托管或分仓交易场景中,针对不同的资金账号实施差异化的风控逻辑(如不同的止损阈值、单笔最大下单限额等)是保障资金安全的关键。ptrade 提供了 get_user_name() 接口,允许策略在运行期动态获取当前登录终端的资金账号,从而实现“一套代码,多户风控”。

一、核心接口介绍

get_user_name()

  • 使用场景:仅在回测、交易模块可用。
  • 接口说明:用于获取当前登录终端的资金账号。
  • 返回值:返回登录终端的资金账号(str)或 None(获取失败时)。

二、多账户差异化风控设计思路

  1. 账户风控配置表:在 initialize 阶段,定义一个字典,以资金账号为 key,对应的风控参数(如 max_limit 单笔限额、stop_loss_ratio 止损比例)为 value
  2. 动态获取当前账户:在策略初始化或交易时,调用 get_user_name() 获取当前运行的资金账号。
  3. 匹配风控规则:如果获取到的账号在配置表中,则应用该账号的专属风控规则;若不在,则应用默认的安全风控规则。

三、实战策略源码

以下是一个完整的 ptrade 策略示例,展示了如何根据不同的资金账号执行差异化的买入限额与止损风控:

def initialize(context):
    # 1. 设置操作的股票池
    g.security = '600570.SS'  # 恒生电子
    set_universe(g.security)
    
    # 2. 获取当前登录的资金账号
    g.user_name = get_user_name()
    log.info("当前登录的资金账号为: %s" % g.user_name)
    
    # 3. 定义多账户差异化风控配置表
    # 账号 '12345678':高风险偏好,单笔限额 50000 元,止损比例 5%
    # 账号 '87654321':低风险偏好,单笔限额 10000 元,止损比例 2%
    g.risk_config = {
        '12345678': {
            'max_order_value': 50000.0,
            'stop_loss_ratio': 0.05
        },
        '87654321': {
            'max_order_value': 10000.0,
            'stop_loss_ratio': 0.02
        }
    }
    
    # 默认风控配置(若未在配置表中登记)
    g.default_risk = {
        'max_order_value': 5000.0,
        'stop_loss_ratio': 0.01
    }
    
    # 记录买入时的成本价,用于计算止损
    g.buy_price = None

def handle_data(context, data):
    sid = g.security
    current_price = data[sid]['close']
    
    # 获取当前账户的风控配置
    if g.user_name in g.risk_config:
        config = g.risk_config[g.user_name]
        log.info("已匹配账号 %s 的专属风控规则" % g.user_name)
    else:
        config = g.default_risk
        log.warning("未匹配到专属规则,启用默认保守风控")
        
    max_value = config['max_order_value']
    stop_loss_ratio = config['stop_loss_ratio']
    
    # 获取当前持仓
    position = get_position(sid)
    
    # --- 1. 买入逻辑(带单笔限额风控) ---
    if position.amount == 0:
        # 计划买入 1000 股
        target_value = current_price * 1000
        
        # 风控检查:如果买入金额超过当前账户的单笔限额,则进行截断或调整
        if target_value > max_value:
            adjusted_amount = int(max_value / current_price / 100) * 100
            if adjusted_amount >= 100:
                log.warning("【风控触发】账号 %s 计划买入金额 %s 元超过限额 %s 元,调整买入数量为 %s 股" 
                            % (g.user_name, target_value, max_value, adjusted_amount))
                order(sid, adjusted_amount)
                g.buy_price = current_price
            else:
                log.error("【风控触发】账号 %s 限额过低,无法起购 100 股,取消委托" % g.user_name)
        else:
            log.info("【风控通过】账号 %s 委托买入 1000 股" % g.user_name)
            order(sid, 1000)
            g.buy_price = current_price
            
    # --- 2. 卖出/止损逻辑(带差异化止损风控) ---
    elif position.enable_amount > 0 and g.buy_price is not None:
        # 计算当前亏损比例
        loss_rate = (g.buy_price - current_price) / g.buy_price
        
        # 风控检查:如果亏损比例达到或超过当前账户设定的止损阈值,则执行清仓
        if loss_rate >= stop_loss_ratio:
            log.critical("【风控触发】账号 %s 达到止损阈值 %s%%(当前亏损 %s%%),执行清仓!" 
                         % (g.user_name, stop_loss_ratio * 100, round(loss_rate * 100, 2)))
            order_target(sid, 0)
            g.buy_price = None

四、注意事项

  1. 实盘环境测试:在实盘运行前,请务必通过 log.info(get_user_name()) 确认柜台返回的资金账号格式(部分券商可能带有前缀或后缀),确保风控配置表中的 key 与接口返回值完全一致。
  2. 异常处理:若 get_user_name() 因网络或柜台异常返回 None,策略应默认启用最严格的 g.default_risk 保守风控,避免风控失效。