获取掉期规模

对于中期和长期战略的实施,掉期规模很重要,因为其可能对财务结果产生重大影响,而且通常是负面的影响。但是,一些读者可能是“利差交易”策略的粉丝,这种策略最初建立在从积极的掉期交易中止盈的基础上。MQL5 有几个交易品种特性,可提供对与掉期相关的规范字符串的访问。

标识符

说明

SYMBOL_SWAP_MODE

掉期计算模型 ENUM_SYMBOL_SWAP_MODE

SYMBOL_SWAP_ROLLOVER3DAYS

三倍掉期信用对应的星期几 ENUM_DAY_OF_WEEK

SYMBOL_SWAP_LONG

多头仓位的掉期规模

SYMBOL_SWAP_SHORT

空头仓位的掉期规模

ENUM_SYMBOL_SWAP_MODE 枚举包含指定度量单位选项和掉期计算原则的元素。和 SYMBOL_SWAP_ROLLOVER3DAYS 一样,其引用了 ENUM_SYMBOL_INFO_INTEGER 的整数特性。

掉期规模直接在 SYMBOL_SWAP_LONG 和 SYMBOL_SWAP_SHORT 特性中指定,作为 ENUM_SYMBOL_INFO_DOUBLE 的一部分,即 double 类型。

以下是 ENUM_SYMBOL_SWAP_MODE 的元素。

标识符

说明

SYMBOL_SWAP_MODE_DISABLED

无掉期

SYMBOL_SWAP_MODE_POINTS

点数

SYMBOL_SWAP_MODE_CURRENCY_SYMBOL

交易品种的基础货币

SYMBOL_SWAP_MODE_CURRENCY_MARGIN

交易品种的保证金货币

SYMBOL_SWAP_MODE_CURRENCY_DEPOSIT

存款货币

SYMBOL_SWAP_MODE_INTEREST_CURRENT

计算掉期时金融工具价格的年度百分比

SYMBOL_SWAP_MODE_INTEREST_OPEN

每年占交易品种头寸开盘价的百分比

SYMBOL_SWAP_MODE_REOPEN_CURRENT

点数(以收盘价重新开仓)

SYMBOL_SWAP_MODE_REOPEN_BID

点数(以新一天的买入价格重新开仓)(在 SYMBOL_SWAP_LONG 和 SYMBOL_SWAP_SHORT 参数中)

对于 SYMBOL_SWAP_MODE_INTEREST_CURRENT 和 SYMBOL_SWAP_MODE_INTEREST_OPEN 期权,假设一年中有 360 个银行工作日。

对于 SYMBOL_SWAP_MODE_REOPEN_CURRENT 和 SYMBOL_SWAP_MODE_REOPEN_BID 期权,在交易日结束时强行平仓,但之后两者的行为存在差异。

使用 SYMBOL_SWAP_MODE_REOPEN_CURRENT 时,持仓次日会以前一天的收盘价+/-指定的点数重新开仓。使用 SYMBOL_SWAP_MODE_REOPEN_BID 时,持仓次日会以当前买入价+/-指定点数重新开仓。在这两种情况下,点数都在 SYMBOL_SWAP_LONG和SYMBOL_SWAP_SHORT 参数中。

我们使用脚本 SymbolFilterSwap.mq5 来检查特性的操作。在输入参数中,我们提供了分析上下文的选择:Market Watch 或所有依赖于 UseMarketWatch 的交易品种。当 ShowPerSymbolDetails 参数为 false 时,我们将计算统计数据,即 ENUM_SYMBOL_SWAP_MODE 中的一个或另一个模式在交易品种中使用了多少次。当 ShowPerSymbolDetails 参数为 true 时,我们将使用 mode 中指定的模式输出所有交易品种的数组,并按照 SYMBOL_SWAP_LONG 和 SYMBOL_SWAP_SHORT 字段中值的降序对数组进行排序。

input bool UseMarketWatch = true;
input bool ShowPerSymbolDetails = false;
input ENUM_SYMBOL_SWAP_MODE Mode = SYMBOL_SWAP_MODE_POINTS;

对于掉期组合数组的元素,我们用交易品种名称和掉期值来说明 SymbolSwap 结构。掉期的方向用名称字段中的前缀表示:“+”表示多头掉期;“-”表示空头掉期。

struct SymbolSwap
{
   string name;
   double value;
};

按照惯例,我们在 OnStart 的开头描述筛选对象。但是,根据 ShowPerSymbolDetails 变量的值,下面的代码会有很大的不同。

void OnStart()
{
   SymbolFilter f;                // filter object
   PrintFormat("===== Swap modes for %s symbols =====",
      (UseMarketWatch ? "Market Watch" : "all available"));
   
   if(ShowPerSymbolDetails)
   {
      // summary table of swaps of the selected Mode
      ...
   }
   else
   {
      // calculation of mode statistics
      ...
   }
}

先介绍第二个分支。此处,我们使用取自 SYMBOL_SWAP_MODE 特性的筛选器 (symbols) 和掉期模式 (values),用交易品种名称填充数组。结果值累积在数组映射 MapArray<ENUM_SYMBOL_SWAP_MODE,int> stats 中。

      // calculation of mode statistics
      string symbols[];
      long values[];
      MapArray<ENUM_SYMBOL_SWAP_MODE,intstats// counters for each mode
      // apply filter and collect mode values
      f.select(UseMarketWatchSYMBOL_SWAP_MODEsymbolsvalues);
      const int n = ArraySize(symbols);
      for(int i = 0i < n; ++i)
      {
         stats.inc((ENUM_SYMBOL_SWAP_MODE)values[i]);
      }
      ...

接下来,我们显示收集的统计数据。

      PrintFormat("Total symbols: %d"n);
      Print("Stats per swap mode:");
      stats.print();
      Print("Legend: key=swap mode, value=count");
      for(int i = 0i < stats.getSize(); ++i)
      {
         PrintFormat("%d -> %s"stats.getKey(i), EnumToString(stats.getKey(i)));
      }

对于用掉期值构造表的情况,算法如下。多头和空头的掉期是分别请求的,因此我们为名称和值定义了成对数组。它们将一起被放入 swaps 结构体数组中。

      // summary table of swaps of the selected Mode
      string buyers[], sellers[];    // arrays for names
      double longs[], shorts[];      // arrays for swap values
      SymbolSwap swaps[];            // total array to print

在筛选器中设置所选掉期模式的条件。这是比较和排序数组元素所必需的。

      f.let(SYMBOL_SWAP_MODEMode);

然后我们对不同的特性(SYMBOL_SWAP_LONG 和 SYMBOL_SWAP_SHORT)应用筛选器两次,并用其值 (longs, shorts) 填充不同的数组。在每次调用中,数组按升序排序。

      f.select(UseMarketWatchSYMBOL_SWAP_LONGbuyerslongstrue);
      f.select(UseMarketWatchSYMBOL_SWAP_SHORTsellersshortstrue);

理论上,数组的大小应相同,因为筛选条件是相同的,但是为了清楚起见,让我们为每个大小分配一个变量。由于每个交易品种将在结果表中出现两次,对于多头和空头,我们为 swaps 数组提供了双倍规模。

      const int l = ArraySize(longs);
      const int s = ArraySize(shorts);
      const int n = ArrayResize(swapsl + s); // should be l == s
      PrintFormat("Total symbols with %s: %d"EnumToString(Mode), l);

接下来,我们连接两个数组 longsshorts,以相反的顺序对其进行处理,因为我们需要从正值到负值进行排序。

      if(n > 0)
      {
         int i = l - 1j = s - 1k = 0;
         while(k < n)
         {
            const double swapLong = i >= 0 ? longs[i] : -DBL_MAX;
            const double swapShort = j >= 0 ? shorts[j] : -DBL_MAX;
            
            if(swapLong >= swapShort)
            {
               swaps[k].name = "+" + buyers[i];
               swaps[k].value = longs[i];
               --i;
               ++k;
            }
            else
            {
               swaps[k].name = "-" + sellers[j];
               swaps[k].value = shorts[j];
               --j;
               ++k;
            }
         }
         Print("Swaps per symbols (ordered):");
         ArrayPrint(swaps);
      }

有趣的是用不同的设置多次运行这个脚本。例如,默认情况下,我们可以得到以下结果。

===== Swap modes for Market Watch symbols =====
Total symbols: 13
Stats per swap mode:
    [key] [value]
[0]     1      10
[1]     0       2
[2]     2       1
Legend: key=swap mode, value=count
1 -> SYMBOL_SWAP_MODE_POINTS
0 -> SYMBOL_SWAP_MODE_DISABLED
2 -> SYMBOL_SWAP_MODE_CURRENCY_SYMBOL

统计数据显示,10 个交易品种具有掉期模式,SYMBOL_SWAP_MODE_POINTS;两个交易品种禁用掉期,SYMBOL_SWAP_MODE_DISABLED;一个交易品种处于基础货币,SYMBOL_SWAP_MODE_CURRENCY_SYMBOL。

我们来确定什么样的交易品种有 SYMBOL_SWAP_MODE_POINTS,并找出其掉期。为此,我们将 ShowPerSymbolDetails 设置为 true(参数 mode 已设置为 SYMBOL_SWAP_MODE_POINTS)。

===== Swap modes for Market Watch symbols =====
Total symbols with SYMBOL_SWAP_MODE_POINTS: 10
Swaps per symbols (ordered):
        [name]   [value]
[ 0] "+AUDUSD"   6.30000
[ 1] "+NZDUSD"   2.80000
[ 2] "+USDCHF"   0.10000
[ 3] "+USDRUB"   0.00000
[ 4] "-USDRUB"   0.00000
[ 5] "+USDJPY"  -0.10000
[ 6] "+GBPUSD"  -0.20000
[ 7] "-USDCAD"  -0.40000
[ 8] "-USDJPY"  -0.60000
[ 9] "+EURUSD"  -0.70000
[10] "+USDCAD"  -0.80000
[11] "-EURUSD"  -1.00000
[12] "-USDCHF"  -1.00000
[13] "-GBPUSD"  -2.20000
[14] "+USDSEK"  -4.50000
[15] "-XAUUSD"  -4.60000
[16] "-USDSEK"  -4.90000
[17] "-NZDUSD"  -6.70000
[18] "+XAUUSD" -12.60000
[19] "-AUDUSD" -14.80000

你可以将这些值与交易品种规范进行比较。

最后,我们将模式改为 SYMBOL_SWAP_Mode_CURRENCY_SYMBOL。在我们的示例中,我们应得到一个交易品种,但是分成两行:名称中有一个加号和一个减号。

===== Swap modes for Market Watch symbols =====
Total symbols with SYMBOL_SWAP_MODE_CURRENCY_SYMBOL: 1
Swaps per symbols (ordered):
       [name]   [value]
[0] "-SP500m" -35.00000
[1] "+SP500m" -41.41000

从表中可以看出,两种掉期均为负。