Backtrader策略开发实战:从信号策略到复杂交易逻辑

Backtrader策略开发实战:从信号策略到复杂交易逻辑

【免费下载链接】backtrader Python Backtesting library for trading strategies 【免费下载链接】backtrader 项目地址: https://gitcode.com/gh_mirrors/ba/backtrader

本文深入探讨了Backtrader量化交易框架中的核心策略开发技术,全面对比了Strategy基类与SignalStrategy信号策略模式的差异与适用场景,详细解析了市价单、限价单、止损单等多种订单类型的执行机制,系统介绍了头寸管理与资金分配的Sizer机制,并深入讲解了多时间框架策略的同步实现方法。文章通过丰富的代码示例、流程图和对比表格,为开发者提供了从基础到高级的完整策略开发指南。

Strategy基类与信号策略模式对比

在Backtrader量化交易框架中,策略开发存在两种核心模式:基于Strategy基类的传统策略模式和基于SignalStrategy的信号驱动模式。这两种模式各有特点,适用于不同的交易场景和开发需求。

策略基类(Strategy)模式

Strategy基类是Backtrader中最基础也是最灵活的策略开发方式。它提供了完整的生命周期管理,允许开发者完全控制策略的执行流程。

核心生命周期方法
class MyStrategy(bt.Strategy):
    def __init__(self):
        # 初始化指标和变量
        self.sma = bt.indicators.SimpleMovingAverage(self.data.close, period=20)
        self.crossover = bt.indicators.CrossOver(self.data.close, self.sma)
        
    def next(self):
        # 每个bar执行的主逻辑
        if self.crossover > 0:  # 金叉信号
            self.buy(size=100)
        elif self.crossover < 0:  # 死叉信号
            self.sell(size=100)
            
    def notify_order(self, order):
        # 订单状态通知
        if order.status in [order.Completed]:
            if order.isbuy():
                print(f'买入执行: {order.executed.price}')
            else:
                print(f'卖出执行: {order.executed.price}')
Strategy模式的特点
特性描述
完全控制开发者需要手动处理所有交易逻辑
生命周期完整提供init、next、notify_order等完整生命周期方法
灵活性高可以处理复杂的交易逻辑和条件判断
代码量较大需要编写更多的代码来实现相同功能

信号策略(SignalStrategy)模式

SignalStrategyStrategy的子类,专门为简化策略开发而设计。它采用声明式编程模式,通过添加信号来自动执行交易。

信号策略示例
class SmaCross(bt.SignalStrategy):
    params = dict(sma1=10, sma2=30)
    
    def __init__(self):
        sma1 = bt.ind.SMA(period=self.params.sma1)
        sma2 = bt.ind.SMA(period=self.params.sma2)
        crossover = bt.ind.CrossOver(sma1, sma2)
        self.signal_add(bt.SIGNAL_LONG, crossover)
信号类型说明

Backtrader提供了多种信号类型来满足不同的交易需求:

mermaid

SignalStrategy模式的特点
特性描述
声明式编程通过添加信号自动执行交易,无需手动处理订单
代码简洁大幅减少代码量,提高开发效率
自动化执行系统自动处理信号到订单的转换
灵活性受限对于复杂交易逻辑的支持相对有限

两种模式的对比分析

架构差异

mermaid

性能考虑

在实际应用中,两种模式的性能表现有所不同:

  • Strategy模式:由于需要手动处理所有逻辑,在复杂策略中可能更高效
  • SignalStrategy模式:信号处理引擎会引入一定的开销,但对于简单策略更加高效
适用场景对比
场景Strategy模式SignalStrategy模式
简单均线策略⚪ 适用✅ 更优
复杂多条件策略✅ 更优⚪ 适用
高频交易策略✅ 更优⚪ 适用
快速原型开发⚪ 适用✅ 更优
机器学习集成✅ 更优⚪ 适用

混合使用模式

在实际开发中,可以结合两种模式的优点:

class HybridStrategy(bt.SignalStrategy):
    def __init__(self):
        # 使用信号处理主要交易逻辑
        sma_crossover = bt.ind.CrossOver(
            bt.ind.SMA(period=10),
            bt.ind.SMA(period=30)
        )
        self.signal_add(bt.SIGNAL_LONG, sma_crossover)
        
        # 使用传统方法处理复杂逻辑
        self.rsi = bt.ind.RSI(self.data.close, period=14)
        
    def next(self):
        # 在next中处理信号模式无法覆盖的复杂逻辑
        if self.rsi > 70:
            # 手动平仓或调整仓位
            pass

最佳实践建议

  1. 新手入门:从SignalStrategy开始,快速上手和理解Backtrader的基本概念
  2. 简单策略:使用SignalStrategy提高开发效率
  3. 复杂策略:使用Strategy基类获得完全的控制权
  4. 生产环境:根据性能要求和复杂度选择合适的模式
  5. 团队协作:统一代码风格,避免混合模式造成维护困难

通过深入理解这两种策略开发模式的差异和适用场景,开发者可以根据具体需求选择最合适的方法,在开发效率和策略复杂度之间找到最佳平衡点。

订单类型详解:市价单、限价单、止损单

在Backtrader量化交易框架中,订单系统是策略执行的核心组件。框架提供了多种订单类型来满足不同的交易需求,从简单的市价单到复杂的条件单,每种订单类型都有其特定的执行逻辑和应用场景。理解这些订单类型的工作原理对于构建有效的交易策略至关重要。

订单类型概述

Backtrader支持8种主要的订单执行类型,每种类型都有独特的执行机制:

订单类型枚举值描述适用场景
Market0市价单,以当前市场最优价格立即执行快速成交,不计较价格
Close1收盘价单,以当日收盘价执行避免盘中波动
Limit2限价单,指定价格或更优价格执行控制成交价格
Stop3止损单,触发后转为市价单风险控制
StopLimit4止损限价单,触发后转为限价单精确控制止损价格
StopTrail5跟踪止损单,动态调整止损位趋势跟踪
StopTrailLimit6跟踪止损限价单高级趋势管理
Historical7历史订单,用于回测分析策略验证

市价单 (Market Order)

市价单是最基本的订单类型,旨在以当前市场最优价格立即成交。当速度比价格更重要时,市价单是最佳选择。

执行特点:

  • 立即以当前可用的最佳价格执行
  • 不保证具体成交价格,只保证成交
  • 适用于需要快速进入或退出市场的场景

代码示例:

# 创建市价买单
self.buy(exectype=bt.Order.Market, size=100)

# 创建市价卖单  
self.sell(exectype=bt.Order.Market, size=100)

# 等效的简写形式(默认为市价单)
self.buy(size=100)
self.sell(size=100)

执行流程图: mermaid

限价单 (Limit Order)

限价单允许交易者指定一个具体的成交价格,只有在达到或优于该价格时才会执行。

执行特点:

  • 指定具体的成交价格限制
  • 可以设置有效期(valid参数)
  • 可能部分成交或完全未成交
  • 适用于对成交价格有严格要求的场景

代码示例:

# 创建限价买单(低于当前价格3%)
limit_price = self.data.close[0] * 0.97
self.buy(exectype=bt.Order.Limit, 
         price=limit_price, 
         size=100,
         valid=datetime.timedelta(days=3))  # 3天内有效

# 创建限价卖单(高于当前价格5%)
limit_price = self.data.close[0] * 1.05
self.sell(exectype=bt.Order.Limit, 
          price=limit_price, 
          size=100)

限价单状态转换: mermaid

止损单 (Stop Order)

止损单是一种条件订单,当市场价格达到指定的触发价格时,该订单会转为市价单执行。

执行特点:

  • 需要设置触发价格(price参数)
  • 触发后转为市价单执行
  • 常用于风险控制和止损退出
  • 成交价格可能不如预期

代码示例:

# 创建止损买单(突破入场)
stop_price = self.data.high[0] * 1.02  # 突破前高2%
self.buy(exectype=bt.Order.Stop, 
         price=stop_price, 
         size=100)

# 创建止损卖单(止损退出)
stop_price = self.data.close[0] * 0.95  # 亏损5%时止损
self.sell(exectype=bt.Order.Stop, 
          price=stop_price, 
          size=100)

止损限价单 (StopLimit Order)

止损限价单结合了止损单和限价单的特点,触发后转为限价单而不是市价单。

执行特点:

  • 需要设置触发价格(price)和限价价格(plimit)
  • 触发后以限价单形式等待成交
  • 提供更精确的价格控制
  • 可能无法成交(如果价格快速波动)

代码示例:

# 创建止损限价买单
stop_price = self.data.high[0] * 1.02  # 触发价格
limit_price = stop_price * 1.01        # 限价价格(略高于触发价)

self.buy(exectype=bt.Order.StopLimit, 
         price=stop_price, 
         plimit=limit_price,
         size=100)

# 创建止损限价卖单
stop_price = self.data.close[0] * 0.95  # 触发价格
limit_price = stop_price * 0.98         # 限价价格(略低于触发价)

self.sell(exectype=bt.Order.StopLimit, 
          price=stop_price, 
          plimit=limit_price,
          size=100)

高级订单类型

跟踪止损单 (StopTrail Order)

跟踪止损单会动态调整止损位,根据市场价格变化自动更新触发价格。

# 跟踪止损卖单(固定金额跟踪)
self.sell(exectype=bt.Order.StopTrail, 
          trailamount=2.0,  # 固定2点跟踪
          size=100)

# 跟踪止损卖单(百分比跟踪)
self.sell(exectype=bt.Order.StopTrail, 
          trailpercent=0.02,  # 2%跟踪
          size=100)
收盘价单 (Close Order)

收盘价单确保以当日收盘价成交,避免盘中价格波动的影响。

# 收盘价买单
self.buy(exectype=bt.Order.Close, size=100)

# 收盘价卖单
self.sell(exectype=bt.Order.Close, size=100)

订单管理最佳实践

1. 订单状态监控

def notify_order(self, order):
    if order.status in [order.Submitted, order.Accepted]:
        # 订单已提交/接受,等待执行
        self.log('订单等待执行')
    
    elif order.status == order.Completed:
        # 订单已完成
        if order.isbuy():
            self.log(f'买单成交: {order.executed.price}')
        else:
            self.log(f'卖单成交: {order.executed.price}')
    
    elif order.status in [order.Canceled, order.Margin, order.Rejected]:
        # 订单被取消、保证金不足或被拒绝
        self.log('订单未完成')

2. 订单有效期管理

# 设置订单有效期
valid_until = self.data.datetime.date(0) + datetime.timedelta(days=5)
self.buy(exectype=bt.Order.Limit, 
         price=100, 
         size=100, 
         valid=valid_until)

3. 订单组合使用(括号订单)

# 创建括号订单:限价买单 + 止损卖单 + 止盈卖单
entry_price = self.data.close[0] * 0.98
stop_loss = entry_price * 0.95
take_profit = entry_price * 1.06

# 使用buy_bracket简化操作
bracket_orders = self.buy_bracket(
    price=entry_price,
    stopprice=stop_loss, 
    limitprice=take_profit,
    size=100
)

订单执行机制深度解析

Backtrader的订单执行基于事件驱动机制,每个订单都经历以下生命周期:

mermaid

性能考虑与优化建议

市价单 vs 限价单性能影响:

  • 市价单:执行速度快,但成交价格不确定
  • 限价单:价格可控,但可能无法成交
  • 在回测中,限价单的模拟需要更多计算资源

订单数量管理:

# 避免过多的未完成订单
if len(self.orders) > 5:
    self.cancel(self.orders[0])  # 取消最早的订单

# 使用订单引用管理
self.orefs = []
order = self.buy(size=100)
self.orefs.append(order.ref)

通过深入理解Backtrader的各种订单类型及其执行机制,交易者可以构建更加精细和有效的交易策略。每种订单类型都有其特定的应用场景和优缺点,在实际交易中需要根据市场条件、风险偏好和策略目标来选择合适的订单类型。

头寸管理与资金分配策略

在量化交易中,头寸管理和资金分配是决定策略成败的关键因素。Backtrader提供了强大的Sizer机制,让开发者能够灵活控制每次交易的资金分配比例,实现科学的头寸管理。

Sizer基础架构

Backtrader的Sizer是所有头寸管理策略的基类,它定义了统一的接口规范:

class Sizer(with_metaclass(MetaParams, object)):
    strategy = None
    broker = None
    
    def getsizing(self, data, isbuy):
        comminfo = self.broker.getcommissioninfo(data)
        return self._getsizing(comminfo, self.broker.getcash(), data, isbuy)
    
    def _getsizing(self, comminfo, cash, data, isbuy):
        raise NotImplementedError

每个Sizer必须实现_getsizing方法,该方法接收四个关键参数:

  • comminfo: 佣金信息对象,用于计算交易成本
  • cash: 当前可用资金
  • data: 交易标的的数据对象
  • isbuy: 布尔值,True表示买入操作,False表示卖出操作

固定头寸大小策略

FixedSize Sizer是最基础的固定头寸管理策略:

class FixedSize(bt.Sizer):
    params = (('stake', 1), ('tranches', 1))

    def _getsizing(self, comminfo, cash, data, isbuy):
        if self.p.tranches > 1:
            return abs(int(self.p.stake / self.p.tranches))
        else:
            return self.p.stake

参数说明:

  • stake: 每次交易的头寸大小
  • tranches: 分批建仓的批次数量

使用示例:

# 每次交易100股
cerebro.addsizer(bt.sizers.FixedSize, stake=100)

# 分5批建仓,每次20股
cerebro.addsizer(bt.sizers.FixedSize, stake=100, tranches=5)

百分比资金管理策略

PercentSizer根据账户资金百分比进行头寸分配:

class PercentSizer(bt.Sizer):
    params = (('percents', 20), ('retint', False))

    def _getsizing(self, comminfo, cash, data, isbuy):
        position = self.broker.getposition(data)
        if not position:
            size = cash / data.close[0] * (self.params.percents / 100)
        else:
            size = position.size
        
        if self.p.retint:
            size = int(size)
        return size

参数说明:

  • percents: 资金使用百分比
  • retint: 是否返回整数头寸

使用场景对比:

策略类型适用场景优点缺点
FixedSize小资金、固定合约简单易用无法动态调整
PercentSizer大资金、波动市场动态调整头寸计算复杂度高

全仓投入策略

AllInSizer是百分比策略的特例,使用全部可用资金:

class AllInSizer(PercentSizer):
    params = (('percents', 100),)

这种策略适合趋势明确的单边行情,但风险也相对较高。

头寸反转策略

FixedReverser Sizer专门用于头寸反转操作:

class FixedReverser(bt.Sizer):
    params = (('stake', 1),)

    def _getsizing(self, comminfo, cash, data, isbuy):
        position = self.strategy.getposition(data)
        size = self.p.stake * (1 + (position.size != 0))
        return size

该策略在已有头寸时执行反转操作,头寸大小为平时的两倍。

自定义头寸管理策略

开发者可以基于实际需求创建自定义Sizer:

class RiskAdjustedSizer(bt.Sizer):
    params = (
        ('risk_per_trade', 0.02),  # 每笔交易风险2%
        ('stop_loss_pct', 0.05),   # 止损幅度5%
    )

    def _getsizing(self, comminfo, cash, data, isbuy):
        # 计算风险调整后的头寸
        risk_amount = cash * self.p.risk_per_trade
        stop_loss_amount = data.close[0] * self.p.stop_loss_pct
        position_size = risk_amount / stop_loss_amount
        
        return int(position_size)

多策略资金分配

Backtrader支持为不同策略配置不同的Sizer:

# 为策略1配置固定头寸
cerebro.addsizer(bt.sizers.FixedSize, stake=100)

# 为策略2配置百分比头寸  
cerebro.addsizer_byidx(1, bt.sizers.PercentSizer, percents=30)

头寸管理流程图

mermaid

实际应用案例

假设我们有一个10万元账户,希望每笔交易风险不超过2%,止损幅度为5%:

class ConservativeSizer(bt.Sizer):
    params = (('risk_per_trade', 0.02), ('stop_loss', 0.05))
    
    def _getsizing(self, comminfo, cash, data, isbuy):
        risk_capital = cash * self.p.risk_per_trade
        entry_price = data.close[0]
        stop_loss_price = entry_price * (1 - self.p.stop_loss)
        risk_per_share = entry_price - stop_loss_price
        
        if risk_per_share <= 0:
            return 0
            
        position_size = risk_capital / risk_per_share
        return int(position_size)

# 使用保守型头寸管理
cerebro.addsizer(ConservativeSizer, risk_per_trade=0.02, stop_loss=0.05)

头寸管理的最佳实践

  1. 风险控制优先:每笔交易风险不应超过账户总额的2%
  2. 分散投资:避免过度集中单一标的
  3. 动态调整:根据市场波动性调整头寸大小
  4. 止损保护:结合止损订单使用,控制下行风险
  5. 定期评估:根据策略表现调整头寸管理参数

通过科学的头寸管理,交易者可以在控制风险的前提下最大化收益,这是量化交易系统中不可或缺的重要组成部分。

多时间框架策略同步实现

在量化交易中,多时间框架分析是提升策略效果的关键技术。Backtrader通过其强大的数据重采样和回放机制,为开发者提供了灵活的多时间框架策略实现方案。本文将深入探讨如何在Backtrader中实现多时间框架策略的同步与协调。

多时间框架策略的核心概念

多时间框架策略的核心思想是在不同时间粒度上分析市场,利用长期趋势判断方向和短期波动寻找入场时机。Backtrader通过DataResamplerDataReplayer两个核心组件来实现这一功能。

mermaid

数据重采样与回放机制

Backtrader提供了两种主要的多时间框架处理方式:

数据重采样(Resampling):将高频数据聚合为低频数据 数据回放(Replaying):模拟实时交易环境,按时间顺序处理数据

from backtrader import ResamplerDaily, ResamplerWeekly, ResamplerMonthly
from backtrader import ReplayerDaily, ReplayerWeekly, ReplayerMonthly

# 创建周线重采样数据
weekly_data = bt.DataResampler(
    dataname=daily_data,
    timeframe=bt.TimeFrame.Weeks,
    compression=1
)

# 或者使用过滤器方式
weekly_data = bt.DataClone(dataname=daily_data)
weekly_data.addfilter(ResamplerWeekly)

多时间框架策略实现示例

下面是一个完整的多时间框架策略实现,结合日线和周线数据进行交易决策:

class MultiTimeframeStrategy(bt.Strategy):
    params = (
        ('fast_period', 10),
        ('slow_period', 30),
        ('trend_period', 50),
    )

    def __init__(self):
        # 日线数据指标(短期)
        self.daily_sma_fast = bt.indicators.SMA(self.data0, period=self.p.fast_period)
        self.daily_sma_slow = bt.indicators.SMA(self.data0, period=self.p.slow_period)
        self.daily_crossover = bt.indicators.CrossOver(self.daily_sma_fast, self.daily_sma_slow)
        
        # 周线数据指标(长期趋势)
        self.weekly_sma_trend = bt.indicators.SMA(self.data1, period=self.p.trend_period)
        
        # 交易状态跟踪
        self.order = None
        self.trade_count = 0

    def next(self):
        # 确保周线数据可用
        if len(self.data1) < self.p.trend_period:
            return
            
        # 趋势判断:周线在趋势线之上为多头市场
        trend_bullish = self.data1.close[0] > self.weekly_sma_trend[0]
        trend_bearish = self.data1.close[0] < self.weekly_sma_trend[0]
        
        # 交易逻辑
        if not self.position:
            # 多头入场:趋势向上且日线金叉
            if trend_bullish and self.daily_crossover[0] == 1:
                self.buy(size=self.calculate_position_size())
            # 空头入场:趋势向下且日线死叉
            elif trend_bearish and self.daily_crossover[0] == -1:
                self.sell(size=self.calculate_position_size())
        else:
            # 多头出场:趋势转空或日线死叉
            if self.position.size > 0 and (trend_bearish or self.daily_crossover[0] == -1):
                self.close()
            # 空头出场:趋势转多或日线金叉
            elif self.position.size < 0 and (trend_bullish or self.daily_crossover[0] == 1):
                self.close()

    def calculate_position_size(self):
        # 基于账户价值的仓位管理
        return int(self.broker.getvalue() * 0.1 / self.data0.close[0])

时间框架同步的关键技术

在多时间框架策略中,数据同步是技术难点。Backtrader提供了多种同步机制:

时间框架对齐表

原始时间框架目标时间框架可用转换方式
TicksSecondsResample/Replay
SecondsMinutesResample/Replay
MinutesHoursResample/Replay
DaysWeeksResample/Replay
DaysMonthsResample/Replay
WeeksMonthsResample/Replay

同步参数配置

# 配置重采样参数
resampler_params = {
    'timeframe': bt.TimeFrame.Weeks,  # 目标时间框架
    'compression': 1,                 # 压缩比例
    'bar2edge': True,                 # 对齐到时间边界
    'adjbartime': True,               # 调整bar时间
    'rightedge': True,                # 使用右边界
    'boundoff': 0,                    # 边界偏移
    'takelate': True,                 # 接受延迟数据
}

高级多时间框架策略模式

三重时间框架策略:结合月线、周线、日线三个时间框架

class TripleTimeframeStrategy(bt.Strategy):
    def __init__(self):
        # 月线趋势判断
        self.monthly_trend = bt.indicators.EMA(self.data2, period=12)
        
        # 周线动量确认
        self.weekly_momentum = bt.indicators.RSI(self.data1, period=14)
        
        # 日线入场信号
        self.daily_entries = bt.indicators.MACD(self.data0)
        
        self.trade_allowed = False

    def next(self):
        # 确保所有时间框架数据就绪
        if len(self.data2) < 12 or len(self.data1) < 14:
            return
        
        # 月线趋势过滤
        monthly_bullish = self.data2.close[0] > self.monthly_trend[0]
        monthly_bearish = self.data2.close[0] < self.monthly_trend[0]
        
        # 周线动量确认
        weekly_strong = self.weekly_momentum[0] > 60 if monthly_bullish else self.weekly_momentum[0] < 40
        
        # 日线信号
        daily_signal = self.daily_entries.macd[0] > self.daily_entries.signal[0]
        
        # 综合交易逻辑
        if monthly_bullish and weekly_strong and daily_signal:
            if not self.position:
                self.buy()
        elif monthly_bearish and weekly_strong and not daily_signal:
            if not self.position:
                self.sell()

性能优化与注意事项

内存管理:多时间框架策略可能消耗较多内存,建议:

# 优化内存使用的配置
cerebro = bt.Cerebro()
cerebro.addstrategy(MultiTimeframeStrategy)
cerebro.adddata(daily_data)
cerebro.adddata(weekly_resampled)

# 运行配置
cerebro.run(
    preload=True,           # 预加载数据
    runonce=True,           # 一次性运行
    oldsync=False,          # 使用新的同步机制
    stdstats=False          # 禁用标准统计
)

数据同步问题处理

def next(self):
    # 检查数据长度避免索引错误
    if len(self.data1) == 0 or len(self.data0) == 0:
        return
        
    # 使用try-except处理可能的同步问题
    try:
        # 策略逻辑
        if self.data1.datetime[0] > self.data0.datetime[0]:
            # 处理时间不同步情况
            pass
    except IndexError:
        # 处理索引错误
        return

实战技巧与最佳实践

  1. 时间框架选择:通常选择3-5倍关系的时间框架组合,如5分钟-30分钟-日线

  2. 指标参数优化:不同时间框架使用不同的指标参数

  3. 回测验证:确保在多时间框架回测中数据同步正确

# 验证数据同步
def next(self):
    print(f"Daily bars: {len(self.data0)}, Weekly bars: {len(self.data1)}")
    print(f"Daily time: {self.data0.datetime.datetime()}, Weekly time: {self.data1.datetime.datetime()}")
  1. 实时交易考虑:在实盘交易中注意不同时间框架数据的更新时间差异

通过Backtrader强大的多时间框架支持,交易者可以构建复杂的多层次策略,充分利用不同时间维度的市场信息,提升策略的稳定性和盈利能力。关键在于合理选择时间框架组合、正确处理数据同步问题,以及优化策略性能。

总结

Backtrader作为功能强大的量化交易框架,为开发者提供了从简单信号策略到复杂交易逻辑的完整解决方案。通过深入理解Strategy基类与SignalStrategy模式的适用场景,掌握各种订单类型的执行特性,实施科学的头寸管理策略,以及运用多时间框架分析技术,交易者可以构建出更加稳健和高效的量化交易系统。本文涵盖的核心概念和实战技巧将为Backtrader使用者在策略开发过程中提供重要参考,帮助他们在风险可控的前提下实现更好的投资回报。

【免费下载链接】backtrader Python Backtesting library for trading strategies 【免费下载链接】backtrader 项目地址: https://gitcode.com/gh_mirrors/ba/backtrader

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值