English Русский Español Deutsch 日本語 Português
preview
外汇掉期套利:构建合成投资组合,创造持续稳定的掉期收益流

外汇掉期套利:构建合成投资组合,创造持续稳定的掉期收益流

MetaTrader 5交易系统 |
84 3
Yevgeniy Koshtenko
Yevgeniy Koshtenko

在算法交易领域,毫厘之差往往决定成败。然而,外汇掉期套利这一鲜为人知的领域,能将长期策略从“盈利”升级为“暴利”。它就是外汇市场的掉期套利。当多数交易者追逐波动性、押注短期价格走势时,真正的资本高手正在构建能穿越牛熊市、每日生息的系统性结构。


货币对掉期差异的隐藏潜力

掉期不仅是外汇市场的技术性特征,更是反映不同货币利率差异的根本经济现象。当两国央行设定不同的再融资利率时,系统性盈利的机会便应运而生。试想:我们通常将外汇市场视为汇率波动的投机场所,但其结构中却隐藏着一个机制 —— 仅凭利率差异,即可每年带来高达10%-15%的收益!

尤其值得注意的是,掉期利率的调整频率远低于汇率波动。这为构建投资组合创造了独特机遇 —— 长期持有特定头寸不仅可行,更能带来极高的收益。2015-2025年的数据分析显示,通过合理的投资组合优化,仅掉期收益即可实现每年5%-8%的额外的回报。长期来看,复利效应将使这一收益呈指数级增长。


但为何多数交易者忽视掉期作为收入策略的核心要素?

市场心理往往误导交易者。为了博取短期波动的快钱,多数参与者完全忽视了长期的套利良机。掉期被视为细枝末节,甚至是需要避免的“持仓过夜”负担。这种心理障碍造成了市场的系统性低效,而您恰好可以借此获利。

技术交易者专注于图表,基本面交易者紧盯经济指标。然而,鲜有人将掉期纳入综合策略。分析数据显示,仅有不到5%的零售交易者会主动利用掉期。这就创造了套利空间 —— 通过系统性分析和优化掉期,可从市场低效中获利。

另一个障碍是计算的复杂性。如果无专业算法,几乎不可能优化考虑所有参数的投资组合:交易方向、头寸规模、货币对相关性,以及市场回报与掉期的相互作用。因此,开发如SwapArbitrageAnalyzer这类软件解决方案,正成为关键的竞争优势。


市场波动与掉期收入的协同效应

真正的奥妙在于三个维度的交汇:市场回报、掉期收益与波动率。设想一个投资组合,每个头寸不仅优化以捕捉市场波动,更通过最大化正掉期,最小化整体波动来提升收益。

我们的研究显示,使用正确方法,您可以构建如下结构:

  1. 货币对之间的相关性降低投资组合的波动性
  2. 正掉期确保每日稳定的资金流入
  3. 汇率波动带来的市场收益提升了整体盈利

这种组合创造了近乎理想的投资工具,具备正数学期望值。值得注意的是,在市场动荡期间(多数策略失效时),掉期优化组合常因每日累积掉期点而保持稳定。

十年回测表明,掉期优化组合的总回报率较传统外汇策略高出25%-40%。更重要的是,夏普比率越高,表明风险回报比更优。

后续章节将详细解析该策略的数学模型,并分析在MetaTrader 5平台实现的具体方法。<


外汇市场中掉期点的定义与机制

理解外汇掉期机制是本策略的核心。与股票或期货不同,外汇现货市场内置了一个反映不同国家经济差异的机制 —— 掉期点

每晚持仓时,多数交易者未察觉的操作正在发生:掉期展期。这不仅仅是技术环节——它直接反映了货币对中两种货币的利率差异。实际上,我们是在为“虚拟贷款”(一种货币)和“虚拟存款”(另一种货币)支付或收取利息。

以下是分析器中的一个具体案例:

def _init_swap_data(self):
    print("Initialization of swap and yield data since 01.01.2015...")
    available_pairs = 0
    start_date = datetime(2015, 1, 1)
    for pair in self.pairs:
        symbol_info = mt5.symbol_info(pair)
        if not symbol_info:
            continue
            
        swap_long = symbol_info.swap_long
        swap_short = symbol_info.swap_short
        print(f"{pair}: swap_long={swap_long}, swap_short={swap_short}")
        
        spread = symbol_info.spread * symbol_info.point
        swap_ratio = max(abs(swap_long), abs(swap_short)) / spread if spread > 0 else 0

这段代码提取了关键信息:各货币对的swap_long(做多掉期)和swap_short(做空掉期)值。请重点关注以下公式:swap_ratio = max(abs(swap_long), abs(swap_short)) / spread。该公式计算掉期与点差的比率,用于评估掉期收益相对于交易成本的潜在回报。


正向掉期累积策略的数学原理

本策略的数学优势在于系统性累积正向掉期收益,同时对冲市场风险。其核心是通过以下方式计算考虑掉期后的预期收益:

# Calculation of expected returns based on swap and market movement
expected_returns = {}
for pair in eligible_pairs:
    market_return = self.swap_info[pair]['avg_return'] * self.config['leverage'] if self.swap_info[pair]['direction'] == 'long' else -self.swap_info[pair]['avg_return'] * self.config['leverage']
    swap_return = self.swap_info[pair]['avg_swap']
    volatility = self.swap_info[pair]['volatility'] * self.config['leverage']
    
    # Normalization of parameters for balanced assessment
    norm_market = (market_return - min_market_return) / (max_market_return - min_market_return + 1e-10)
    norm_swap = (swap_return - min_swap_return) / (max_swap_return - min_swap_return + 1e-10)
    norm_vol = (volatility - min_volatility) / (max_volatility - min_volatility + 1e-10)
    
    # Combined assessment of pair attractiveness
    combined_score = (self.config['swap_weight'] * norm_swap + 
                     self.config['return_weight'] * norm_market - 
                     self.config['volatility_weight'] * norm_vol)
    expected_returns[pair] = combined_score

以下代码段展示了如何为每个货币对综合评估三大核心因素:

  1. 平均市场盈利能力(取决于交易方向)
  2. 平均掉期收益
  3. 波动率(策略力求最小化)

请关注我们如何对每个参数进行标准化处理,并通过配置文件中定义的权重进行加权组合:self.config['swap_weight'] , self.config['return_weight'] и self.config['volatility_weight'] 这样一来,为我们提供了对每个货币对吸引力的综合评分。


为何利用货币相关性可以实现策略优势?

构建投资组合时,真正的“魔法”开始显现。货币对之间的相关性并非障碍,而是风险管理的利器。请参见以下负责投资组合优化的代码段:

def _optimize_portfolio(self):
    # ... (pre-processing of data)
    
    returns_data = {pair: self.swap_info[pair]['returns'] * self.config['leverage'] + self.swap_info[pair]['avg_swap'] 
                   if self.swap_info[pair]['direction'] == 'long' 
                   else -self.swap_info[pair]['returns'] * self.config['leverage'] + self.swap_info[pair]['avg_swap'] 
                   for pair in eligible_pairs}
    returns_df = pd.DataFrame(returns_data)
    cov_matrix = returns_df.cov()  # Covariance matrix is the key to understanding correlations.
    
    # ... (forming the objective function and limitations)
    
    # Optimization objective function
    def objective(weights, expected_returns, cov_matrix, risk_free_rate):
        returns, std, sharpe = portfolio_performance(weights, expected_returns, cov_matrix, risk_free_rate)
        return -sharpe  # Maximize the Sharpe ratio

在此阶段,协方差矩阵cov_matrix记录了各货币对收益率之间的相互依赖关系。正是通过这一矩阵,算法能够找到一组货币对及其权重组合,使正相关与负相关性相互抵消,从而降低投资组合的整体波动率。

让我们通过具体案例分析优化结果。完成分析后,投资组合结构可能呈现如下分布:

该图表展示了资金在不同货币对间的分配比例,并标注了持仓方向(L—做多,S—做空)。请注意,算法如何通过对相关货币对反向建仓,实现市场风险的部分对冲。

此类投资组合的收益由两部分构成:市场波动收益与掉期收益。以下图表能够直观地展示出二者的差异:

如果考虑再投资与定期追加存款,则该图表展现出的收益表现尤为亮眼:

负责收益建模的核心代码段,清晰地展示了每日掉期收益对总回报率的显著影响:

def _simulate_portfolio_performance(self):
    # ... (initializing variables)
    
    for date in all_dates:
        daily_return = 0
        daily_swap = 0
        for pair, weight in self.optimal_portfolio['weights'].items():
            if date in self.swap_info[pair]['data'].index:
                pair_return = self.swap_info[pair]['data'].loc[date, 'return'] if not pd.isna(self.swap_info[pair]['data'].loc[date, 'return']) else 0
                pair_swap = self.swap_info[pair]['data'].loc[date, 'swap_return']
                if weight > 0:
                    daily_return += pair_return * weight * self.config['leverage']
                    daily_swap += pair_swap * abs(weight)
                else:
                    daily_return += -pair_return * abs(weight) * self.config['leverage']
                    daily_swap += pair_swap * abs(weight)
        
        is_weekend = date.weekday() >= 5
        daily_swap_applied = 0 if is_weekend else daily_swap * initial_capital
        
        # Calculation of profitability with and without swaps
        # ...

请注意以下代码行:daily_swap_applied = 0 if is_weekend else daily_swap * initial_capital。此处有一个关键细节:掉期收益仅在交易日结算,准确建模时必须考虑这一点。

从数学角度出发,我们的策略旨在最大化以下函数:

Sharpe = R p − R f σ p \text{Sharpe} = \frac{R_p - R_f}{\sigma_p} Sharpe=σp Rp −Rf​​

其中:

  • Rp为投资组合总收益率(市场收益 + 掉期收益)
  • Rf为无风险利率
  • σp为投资组合收益率的标准差

同时,我们对掉期收益施加正约束:

∑ i = 1 n ∣ w i ∣ × S i > 0 \sum_{i=1}^{n} |w_i| \times S_i > 0 ∑i=1n ∣wi ∣×Si >0

其中:

  • wi为投资组合中第 i个货币对的权重
  • Si为该货币对的平均掉期值

这一优化问题的设定确保了投资组合不仅通过市场波动获利,还能通过每日掉期收益产生正向现金流,形成独特的协同效应。


数学框架:超越简单的“买入并持有”策略

在算法交易领域,直觉型策略与数学优化系统之间存在巨大鸿沟。我们的掉期套利方法完全属于后者,通过复杂的数学工具在市场中构建结构性优势。本章节将深入探讨SwapArbitrageAnalyzer的底层数学模型,并揭示其优于传统交易方法的原因。

基于风险的收益优化:纳入掉期差异

我们的核心创新在于将掉期收益直接融入经典的马科维茨(Markowitz)投资组合优化模型。与传统方法不同,我们没有将掉期视为次要因素,而是将其直接纳入收益率函数:

def portfolio_performance(weights, expected_returns, cov_matrix, risk_free_rate):
    weights = np.array(weights)
    returns = np.sum(expected_returns * weights)
    std = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
    return returns, std, (returns - risk_free_rate) / std if std > 0 else 0
需要注意的是,在此函数中,expected_returns已同时包含市场收益与掉期收益。实际上,我们是针对每种货币对单独计算其综合收益率:
returns_data = {pair: self.swap_info[pair]['returns'] * self.config['leverage'] + self.swap_info[pair]['avg_swap'] 
               if self.swap_info[pair]['direction'] == 'long' 
               else -self.swap_info[pair]['returns'] * self.config['leverage'] + self.swap_info[pair]['avg_swap'] 
               for pair in eligible_pairs}

该公式综合考量以下因素:

  1. 货币对的历史收益率(returns)
  2. 持仓方向(多头或空头)
  3. 使用的杠杆倍数(leverage)
  4. 平均掉期收益(avg_swap)

这一方法与传统方式的根本性差异在于,后者通常先基于市场收益率优化投资组合。至多是在后续步骤中检查掉期收益是否为负。而前者将总收益率建模为单一参数,使算法能够发现传统分步优化中容易被忽略的独特组合。

尤为关键的是,我们采用差异化策略确定持仓方向。针对每种货币对,我们综合分析历史价格走势与掉期收益,判断多头或空头哪一方更具盈利潜力。

direction = 'long' if swap_long > swap_short else 'short'
self.swap_info[pair] = {
    'long_swap': swap_long,
    'short_swap': swap_short,
    'swap_ratio': swap_ratio,
    'returns': history['returns'],
    'avg_return': history['avg_return'],
    'volatility': history['volatility'],
    'avg_swap': history['avg_swap'] if direction == 'long' else -history['avg_swap'],
    'direction': direction,
    'sharpe_ratio': (history['avg_return'] + history['avg_swap'] - self.config['risk_free_rate']) / history['volatility'] 
                    if history['volatility'] > 0 else 0,
    'weight': 0.0,
    'data': history['data']
}

夏普比率在评估掉期调整后投资组合中的关键作用

我们优化投资组合的核心标准是夏普比率——衡量单位风险超额收益的经典指标。在掉期套利场景中,夏普比率的公式具有特殊意义:

Sharpe = R m + R s − R f σ \text{Sharpe} = \frac{R_m + R_s - R_f}{\sigma} Sharpe=σRm +Rs −Rf​​

其中:

  • Rm为市场收益率
  • Rs为掉期收益
  • Rf为无风险利率
  • σ为总收益率的标准差

需要注意的是,分子中包含Rs——这一点是核心创新。掉期收益是一种近乎确定性的盈利来源,可显著提升收益的风险比。其代码如下:

def objective(weights, expected_returns, cov_matrix, risk_free_rate):
    returns, std, sharpe = portfolio_performance(weights, expected_returns, cov_matrix, risk_free_rate)
    return -sharpe  # The optimizer minimizes, so we use a negative Sharp
在求解优化问题时,我们采用scipy.optimize库中的SLSQP(序列最小二乘规划)方法。该方法支持处理非线性约束条件。
result = sco.minimize(
    objective,
    initial_weights,
    args=(np.array(list(expected_returns.values())), cov_matrix.values, self.config['risk_free_rate']),
    method='SLSQP',
    bounds=bounds,
    constraints=constraints
)

此处的关键约束条件为投资组合的累计掉期为正:

def swap_constraint(weights, eligible_pairs):
    total_swap = np.sum([self.swap_info[pair]['avg_swap'] * abs(weights[i]) for i, pair in enumerate(eligible_pairs)])
    return total_swap  # Must be >= 0

这样一来,使得我们能够排除那些可能具有高市场回报但掉期为负的投资组合,这一点对长期策略至关重要。

模型中波动率、市场方向和掉期利率的相互作用机制

我们的模型并非将这三个核心因素视为独立变量,而是作为单一系统中相互关联的组成部分。以下关键的代码段展示了如何计算货币对吸引力的综合评估值:

# Normalization of parameters
norm_market = (market_return - min([self.swap_info[p]['avg_return'] * self.config['leverage'] if self.swap_info[p]['direction'] == 'long' 
                                   else -self.swap_info[p]['avg_return'] * self.config['leverage'] for p in eligible_pairs])) / \
             (max([self.swap_info[p]['avg_return'] * self.config['leverage'] if self.swap_info[p]['direction'] == 'long' 
                   else -self.swap_info[p]['avg_return'] * self.config['leverage'] for p in eligible_pairs]) - 
              min([self.swap_info[p]['avg_return'] * self.config['leverage'] if self.swap_info[p]['direction'] == 'long' 
                   else -self.swap_info[p]['avg_return'] * self.config['leverage'] for p in eligible_pairs]) + 1e-10)
norm_swap = (swap_return - min([self.swap_info[p]['avg_swap'] for p in eligible_pairs])) / \
           (max([self.swap_info[p]['avg_swap'] for p in eligible_pairs]) - 
            min([self.swap_info[p]['avg_swap'] for p in eligible_pairs]) + 1e-10)
norm_vol = (volatility - min([self.swap_info[p]['volatility'] * self.config['leverage'] for p in eligible_pairs])) / \
          (max([self.swap_info[p]['volatility'] * self.config['leverage'] for p in eligible_pairs]) - 
           min([self.swap_info[p]['volatility'] * self.config['leverage'] for p in eligible_pairs]) + 1e-10)

combined_score = (self.config['swap_weight'] * norm_swap + 
                 self.config['return_weight'] * norm_market - 
                 self.config['volatility_weight'] * norm_vol)

由此可见,复杂关系如下:

  1. 参数标准化—— 作为关键步骤,用于比较不同量纲的变量。对于每个参数,计算其在[0, 1]区间内的相对位置。
  2. 权重系数 —— swap_weight、return_weight和volatility_weight参数允许您调整模型对不同因素的敏感度。
  3. 波动率的反向作用 —— 请关注volatility_weight前的负号,这反映了我们降低波动率的意图。

需要注意的是,这些权重可通过配置文件灵活调整:

self.config = {
    # ...
    'risk_aversion': 2.0,
    'swap_weight': 0.3,
    'return_weight': 0.6,
    'volatility_weight': 0.1,
    # ...
}

这些参数可以根据不同市场环境和投资者偏好进行调整。例如,提高swap_weight将更侧重于最大化掉期收入,这在市场波动率较低的时期可能更为可取。

尤为有趣的是观察模型如何处理相互冲突的目标。高正掉期收益的货币对往往趋于贬值(从利率平价理论看是合理的),这导致市场收益(Rm)与掉期收益(Rs)之间产生冲突。我们的模型通过协方差矩阵识别非显性分散化机会,在这些冲突目标间找到最优平衡。

算法结果参见以下收益图表:蓝色线代表不含掉期的收益,红色线代表掉期收益,紫色线代表掉期、定期存款及再投资的综合收益。

将掉期交易纳入策略后,夏普比率从0.95提升至1.68,改善效果尤为显著。这表明系统性掉期收益可以显著优化风险收益比。

在下一章节中,我们将探讨SwapArbitrageAnalyzer的具体架构与实现方式。助您将数学原理应用于实际交易。


SwapArbitrageAnalyzer:架构与实现

理论如果脱离实践,终将只是纸上谈兵。为将复杂的掉期套利数学模型转化为实战工具,我们开发了SwapArbitrageAnalyzer —— 一套从数据采集到组合优化及可视化的全流程自动化软件系统。本节将深入剖析系统架构,并探讨实现中的关键要点。

系统设计体系与组件分析

SwapArbitrageAnalyzer遵循职责分离原则设计,每个组件承担明确功能。类结构体现了逐步分析流程:

class SwapArbitrageAnalyzer:
    def __init__(self, config=None):
        # Initialization of configuration and basic variables
        
    def initialize(self):
        # Connecting to MetaTrader and verifying data access
        
    def analyze(self):
        # Main method that triggers entire analysis process
        
    def _get_current_market_rates(self):
        # Getting current market prices
        
    def _init_swap_data(self):
        # Initializing swap data
        
    def _get_historical_data(self, symbol, start_date):
        # Getting and handling historical data
        
    def _optimize_portfolio(self):
        # Portfolio optimization
        
    def _simulate_portfolio_performance(self):
        # Simulating performance of optimized portfolio
        
    def _create_visualizations(self):
        # Creating visualizations for analyzing results

该架构遵循逻辑数据流:

  1. 数据采集 —— 获取市场价格与掉期数据
  2. 数据处理 —— 计算历史收益与统计指标
  3. 组合优化 —— 确定货币对的最优权重分配
  4. 策略回测 —— 基于历史数据测试策略表现
  5. 结果可视化 —— 以图形化的方式呈现分析结果

可配置性原则尤为重要。系统通过灵活的参数结构,影响分析流程的各个环节。

self.config = {
    'target_volume': 100.0,
    'max_pairs': 28,
    'leverage': 2,  # Leverage 1:10
    'broker_suffix': '',
    'risk_free_rate': 0.001,
    'optimization_period': int((datetime(2025, 3, 17) - datetime(2015, 1, 1)).days),  # С 01.01.2015 до 17.03.2025
    'panel_width': 750,
    'panel_height': 500,
    'risk_aversion': 2.0,
    'swap_weight': 0.3,
    'return_weight': 0.6,
    'volatility_weight': 0.1,
    'simulation_days': int((datetime(2025, 3, 17) - datetime(2015, 1, 1)).days),
    'monthly_deposit_rate': 0.02  # 2% of the initial capital monthly
}

这种灵活性使您无需修改底层代码,即可根据不同的市场环境、经纪商及交易者个人偏好调整系统配置。

2015至2025年数据采集方案

有效的策略需要可靠的数据支撑。SwapArbitrageAnalyzer通过直接连接MetaTrader 5,获取历史与实时数据:

def initialize(self):
    if not mt5.initialize():
        print(f"MetaTrader5 initialization failed, error={mt5.last_error()}")
        return False
    
    account_info = mt5.account_info()
    if not account_info:
        print(“Failed to get account information")
        return False
        
    print(f"MetaTrader5 initialized. Account: {account_info.login}, Balance: {account_info.balance}")
    self._get_current_market_rates()
    self._init_swap_data()
    self.initialized = True
    return True

我们尤其重视历史数据的处理。为实现精准优化,我们采集了为期十年的日数据:

def _get_historical_data(self, symbol, start_date):
    try:
        now = datetime.now()
        rates = mt5.copy_rates_range(symbol, mt5.TIMEFRAME_D1, start_date, now)
        if rates is None or len(rates) < 10:
            print(f"Not enough data for {symbol}: {len(rates) if rates is not None else 'None'} bars")
            return None
            
        df = pd.DataFrame(rates)
        df['time'] = pd.to_datetime(df['time'], unit='s')
        df.set_index('time', inplace=True)
        df['return'] = df['close'].pct_change()
        
        symbol_info = mt5.symbol_info(symbol)
        best_swap = max(symbol_info.swap_long, symbol_info.swap_short)
        swap_in_points = best_swap if symbol_info.swap_long > symbol_info.swap_short else -best_swap
        point_value = symbol_info.point
        df['swap_return'] = (swap_in_points * point_value) / df['close'] * self.config['leverage']  # Leverage account
        
        # ...

理解如何计算掉期收益尤为重要:

df['swap_return'] = (swap_in_points * point_value) / df['close'] * self.config['leverage']

该方法可将掉期收益统一为与市场回报相同的计量单位,即投资资本的百分比。这对于正确的投资组合优化至关重要。

一种平衡收益、波动率与掉期收入的加权算法

SwapArbitrageAnalyzer的核心是一个投资组合优化算法。与标准方法不同,其不单纯追求预期收益或夏普比率的最大化,而是采用综合方法,充分考虑掉期套利的特殊性。

关键创新在于针对货币对吸引力的标准化评估方法:

combined_score = (self.config['swap_weight'] * norm_swap + 
                 self.config['return_weight'] * norm_market - 
                 self.config['volatility_weight'] * norm_vol)

该公式综合考量以下因素:

  • 标准化市场收益(norm_market)
  • 标准化掉期收入(norm_swap)
  • 标准化波动率(norm_vol)

各组成部分的权重通过配置参数调整,使得策略能够适应不同市场环境。在默认情况下,我们采用以下权重值:掉期权重(swap_weight)=0.3、收益权重(return_weight)=0.6、波动率权重(volatility_weight)=0.1,这一配置在掉期的稳定收益与市场潜在收益之间实现了良好的平衡。

值得注意的是,该算法并非简单地选择得分最高的货币对。相反,通过解决一个复杂的优化问题,将货币对之间的相关性纳入考量。

result = sco.minimize(
    objective,
    initial_weights,
    args=(np.array(list(expected_returns.values())), cov_matrix.values, self.config['risk_free_rate']),
    method='SLSQP',
    bounds=bounds,
    constraints=constraints
)

因此,结果中会出现一些看似不起眼的货币对组合 —— 它们各自表现平平,但通过分散配置,却能共同构建出异常高效的投资组合。

该算法还引入了随机性元素,以探索更广泛的解空间:

num_pairs = random.randint(1, min(self.config['max_pairs'], len(eligible_pairs)))
eligible_pairs = random.sample(eligible_pairs, num_pairs)

在掉期套利场景中,这一点尤为关键,因为局部最优解可能数量众多且效率差异极小。

该算法的输出结果为最优投资组合的结构:

optimal_portfolio = {}
for i, pair in enumerate(eligible_pairs):
    if optimal_weights[i] != 0:
        optimal_portfolio[pair] = optimal_weights[i]
        self.swap_info[pair]['weight'] = optimal_weights[i] * 100

print("\nOptimal portfolio with positive swap:")
for pair, weight in sorted(optimal_portfolio.items(), key=lambda x: abs(x[1]), reverse=True):
    direction = 'Long' if weight > 0 else 'Short'
    swap_value = self.swap_info[pair]['long_swap'] if weight > 0 else self.swap_info[pair]['short_swap']
    print(f”Pair: {pair}, Direction: {direction}, Weight: {abs(weight)*100:.2f}%, Swap: {swap_value:.2f}")
典型的结果可能如下所示:
An optimal portfolio with a positive swap:
Pair: GBPAUD, Direction: Short, Weight: 18.45%, Swap: 2.68
Pair: EURNZD, Direction: Long, Weight: 15.22%, Swap: 3.15
Pair: EURCAD, Direction: Short, Weight: 14.87%, Swap: 1.87
Pair: AUDNZD, Direction: Long, Weight: 12.34%, Swap: 2.92
Pair: GBPJPY, Direction: Long, Weight: 11.78%, Swap: 2.21
Pair: USDJPY, Direction: Long, Weight: 10.56%, Swap: 1.94
Pair: CHFJPY, Direction: Long, Weight: 9.47%, Swap: 2.35
Pair: EURJPY, Direction: Long, Weight: 7.31%, Swap: 1.68

优化完成后,系统会模拟投资组合在历史时间段内的收益表现:

def _simulate_portfolio_performance(self):
    # ... (initializing variables)
    
    for date in all_dates:
        daily_return = 0
        daily_swap = 0
        for pair, weight in self.optimal_portfolio['weights'].items():
            # ... (calculation of daily return and swap)
        
        # Calculation of return without swap
        market_profit = current_capital * daily_return
        current_capital += market_profit
        
        # Calculation of return with swap
        market_profit_with_swap = current_capital_with_swap * daily_return
        current_capital_with_swap += market_profit_with_swap + daily_swap_applied
        
        # Calculation of return, taking into account deposits and reinvestment
        # ...

模拟结果通过多种图表进行可视化展示:

def _create_visualizations(self):
    # ... (creating visualizations)
    
    # 1. The portfolio and its proportions
    plt.figure(figsize=(self.config['panel_width']/100, self.config['panel_height']/100), dpi=100)
    sorted_weights = sorted(self.optimal_portfolio['weights'].items(), key=lambda x: abs(x[1]), reverse=True)
    pairs = [f"{item[0]} ({'L' if item[1] > 0 else 'S'})" for item in sorted_weights]
    weights = [abs(item[1]) * 100 for item in sorted_weights]
    colors = plt.cm.viridis(np.linspace(0, 0.9, len(pairs)))
    plt.pie(weights, labels=pairs, autopct='%1.1f%%', colors=colors, textprops={'fontsize': 8})
    plt.title('Portfolio proportions (L=Long, S=Short)')
    plt.tight_layout()
    plt.savefig('portfolio_proportions.png', dpi=100, bbox_inches='tight')
    plt.close()
    
    # ... (creating other charts)

因此,SwapArbitrageAnalyzer架构完成了多重优势的有机融合:通过现代投资组合优化方法确保数学严谨性,借助与交易终端的直接连接及对真实市场条件的考量保障实用性,通过广泛的定制化选项满足多样化需求与偏好,并依托全面的可视化功能提升决策透明度。

这样一来,使得该系统不仅成为专业交易员的得力工具,更助力市场研究人员深入解析外汇市场中各盈利因素间的复杂关联。

本文由MetaQuotes Ltd译自俄文
原文地址: https://www.mql5.com/ru/articles/17522

附加的文件 |
最近评论 | 前往讨论 (3)
Aleksey Vyazmikin
Aleksey Vyazmikin | 1 4月 2025 在 09:03

引自文章:

Надежная стратегия требует надежных данных. SwapArbitrageAnalyzer использует прямое подключение к MetaTrader 5 для получения как исторических, так и текущих данных:

我不明白你是如何获得 SWOP 历史数据的?终端不提供这些数据。

如果能对一种方法进行回顾性评估,即在每年的一个窗口中进行优化,并对该年或其他时期的结果进行交易,这样至少可以持续五年,那将会非常有趣。

Yevgeniy Koshtenko
Yevgeniy Koshtenko | 1 4月 2025 在 14:23
Aleksey Vyazmikin #:

引自文章:

我不明白你是如何获得 SWOP 历史数据的?终端不提供这些数据。

如果能对一种方法进行回顾性评估,即在每年的一个窗口中进行优化,并对该年或其他时期的结果进行交易,这样至少可以持续五年,那将会非常有趣。

向前走 "是个好主意。掉期是当前的,但毕竟可以通过世界银行的 wdata 下载利率差来计算。

Aleksey Vyazmikin
Aleksey Vyazmikin | 1 4月 2025 在 18:02
Yevgeniy Koshtenko #:
掉期是当前的,但可以通过世界银行使用 wdata 下载利率差来计算。

没有这些数据,就根本谈不上这种方法的有效性。

所谓掉期因外汇交易商而异,通常是收取额外佣金的一种方式,与利率无关。

通常,客户和外汇交易商签订的是远期价格变动合同(交易),而不是掉期合同。

从基础到中级:指标(一) 从基础到中级:指标(一)
在本文中,我们将创建第一个完全实用和功能齐全的指标。目标不是展示如何创建应用程序,而是帮助您了解如何开发自己的想法,并让您有机会以安全、简单和实用的方式应用它们。
您应当知道的 MQL5 向导技术(第 64 部分):运用 DeMarker 和包络通道形态,搭配白噪内核 您应当知道的 MQL5 向导技术(第 64 部分):运用 DeMarker 和包络通道形态,搭配白噪内核
DeMarker 振荡器和包络指标是动量和支撑/阻力工具,能够在开发智能系统时配对。我们延续上一篇文章,概述在机器学习中加入把这对指标。我们正在使用一个循环神经网络,利用白噪内核来处理来自这两个指标的向量化信号。这是在一个自定义信号类文件中完成,其与 MQL5 向导汇编的智能系统搭配工作。
新手在交易中的10个基本错误 新手在交易中的10个基本错误
新手在交易中会犯的10个基本错误: 在市场刚开始时交易, 获利时不适当地仓促, 在损失的时候追加投资, 从最好的仓位开始平仓, 翻本心理, 最优越的仓位, 用永远买进的规则进行交易, 在第一天就平掉获利的仓位,当发出建一个相反的仓位警示时平仓, 犹豫。
从基础到中级:事件(二) 从基础到中级:事件(二)
在本文中,我们将看到并非所有内容都需要以某种特定的方式实现。解决问题还有其他方法。要正确理解这篇文章,有必要掌握前几篇文章中描述的概念。此处提供的材料仅用于教育目的。不要将其视为已完成的应用程序,它的目的是研究这里提出的概念。