🚀 AI 一键生成 joinquant 策略代码
立即体验
👉 AI 生成代码 👈

JoinQuant聚宽平台融资融券交易指南:实现类似 target_value 的自动调仓功能

joinquant | 发布时间: 2026/6/24
以下内容由 EasyQuant 生成。

问题描述

关于融券融资中是否有类似target_value的函数

写了一个策略可能需要融券融资,但仔细看了聚宽里的API,找不到类似普通交易中的target_value函数,请问是否能够根据通过给定目标价格自动购买至指定仓位。我目前想到的一个方法就是先平仓再交易,但这好像会亏手续费。
然后请问一下有什么代码可以看到当期自己账户的融券仓位情况吗?
或者是否有这种功能,当我的target_value大于我的流动资金时自动融资,当我的target_value为负的时候自动融券?

解决方案

针对您在 JoinQuant(聚宽)平台上编写融资融券策略时遇到的问题,以下是详细的解答和解决方案:

一、 融资融券是否有类似 target_value 的函数?

目前聚宽的官方 API 中,融资融券专用 API 并没有直接提供类似 order_target_value 的函数。官方提供的融资融券函数主要是按数量(股数)下单的,例如:

  • margincash_open (融资买入)
  • margincash_close (卖券还款)
  • marginsec_open (融券卖出)
  • marginsec_close (买券还券)

您想到的“先平仓再交易”确实会产生不必要的手续费。正确的做法是自己编写一个逻辑函数,计算当前持仓价值与目标价值的差额,然后根据差额调用对应的融资或融券函数。下文第三部分会提供一个现成的自定义函数供您参考。

二、 如何查看当期自己账户的融券仓位情况?

在聚宽中,融券卖出属于空头仓位。您可以通过 context.portfolio.short_positions 来查看当前账户的所有空单(融券)持仓情况。

这是一个字典,键是标的代码,值是 Position 对象。您可以使用以下代码在策略中打印或获取融券仓位信息:

def check_short_positions(context):
    short_positions = context.portfolio.short_positions
    if not short_positions:
        log.info("当前无融券空头仓位")
    else:
        for security, position in short_positions.items():
            log.info(f"标的: {security}, 融券空仓数量: {position.total_amount}, 仓位价值: {position.value}, 建仓均价: {position.avg_cost}")

(注:如果是多头/融资买入的仓位,则在 context.portfolio.long_positions 中)

三、 能否实现自动融资融券(超出资金自动融资,目标为负自动融券)?

聚宽原生的 order_target_value 不会自动触发融资融券。如果您直接使用普通下单函数,当资金不足时订单会被拒,当目标为负时股票不支持直接做空。

为了实现您的需求,您可以自己封装一个 margin_order_target_value 函数。以下是一个实现该逻辑的参考代码:

def margin_order_target_value(context, security, target_value):
    """
    自定义融资融券目标价值下单函数
    :param context: 策略上下文
    :param security: 标的代码
    :param target_value: 目标价值(正数表示做多/融资做多,负数表示做空/融券做空,0表示清仓)
    """
    # 获取当前价格用于计算需要交易的数量
    current_data = get_current_data()
    price = current_data[security].last_price
    if price == 0 or math.isnan(price):
        return
        
    # 获取当前多头和空头持仓价值
    long_pos = context.portfolio.long_positions.get(security)
    short_pos = context.portfolio.short_positions.get(security)
    
    current_long_value = long_pos.value if long_pos else 0
    current_short_value = short_pos.value if short_pos else 0
    
    # 1. 目标是清仓
    if target_value == 0:
        if current_long_value > 0:
            order_target(security, 0) # 普通卖出平多
        if current_short_value > 0:
            marginsec_close(security, short_pos.total_amount) # 买券还券平空
        return

    # 2. 目标是做多 (target_value > 0)
    if target_value > 0:
        # 如果有空头仓位,先平空
        if current_short_value > 0:
            marginsec_close(security, short_pos.total_amount)
            
        # 计算需要增加或减少的价值
        diff_value = target_value - current_long_value
        
        if diff_value > 0: # 需要加仓
            available_cash = context.portfolio.available_cash
            if diff_value <= available_cash:
                # 现金充足,普通买入
                order_value(security, diff_value)
            else:
                # 现金不足,先用光现金普通买入,剩余部分融资买入
                if available_cash > 0:
                    order_value(security, available_cash)
                # 计算需要融资的金额并转换为股数 (注意聚宽A股必须是100的整数倍)
                margin_need_value = diff_value - max(available_cash, 0)
                margin_amount = int(margin_need_value / price / 100) * 100
                if margin_amount > 0:
                    margincash_open(security, margin_amount)
        elif diff_value < 0: # 需要减仓
            order_value(security, diff_value) # 普通卖出即可
            
    # 3. 目标是做空/融券 (target_value < 0)
    elif target_value < 0:
        target_short_value = abs(target_value)
        
        # 如果有多头仓位,先平多
        if current_long_value > 0:
            order_target(security, 0)
            
        # 计算需要增加或减少的空头价值
        diff_short_value = target_short_value - current_short_value
        
        if diff_short_value > 0: # 需要增加融券仓位
            margin_amount = int(diff_short_value / price / 100) * 100
            if margin_amount > 0:
                marginsec_open(security, margin_amount)
        elif diff_short_value < 0: # 需要减少融券仓位 (买券还券)
            reduce_amount = int(abs(diff_short_value) / price / 100) * 100
            if reduce_amount > 0:
                marginsec_close(security, reduce_amount)

使用注意事项:

  1. 初始化账户类型:要使用融资融券,必须在 initialize 中将账户类型设置为 stock_margin
    set_subportfolios([SubPortfolioConfig(cash=context.portfolio.starting_cash, type='stock_margin')])
    
  2. 标的限制:并非所有股票都可以融资融券。在调用融资融券下单前,建议使用 get_margincash_stocks()get_marginsec_stocks() 检查标的是否在可融资/可融券列表中。
  3. 整数倍限制:A股交易必须是100股的整数倍,上述自定义函数中已经包含了 int(value / price / 100) * 100 的向下取整逻辑,避免下单失败。