下载MetaTrader 5

请观看如何免费下载自动交易

有趣的脚本?
因此发布一个链接 -
让其他人评价

喜欢这个脚本? 在MetaTrader 5客户端尝试它

显示:
373
等级:
投票: 16
已发布:
2017.04.21 10:58
已更新:
2018.02.15 17:30

这是一个根据每次交易所承担风险来计算手数数值的实例。

更新: 2016 年12月28日-> 版本 1.001

新的内容:

增加了计算手数时的两个用于输出(打印)的方法。方法 1 — 当把止损设为0时.

      //--- 变数 #1: StopLoss=0.0
      sl=0.0;
      check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),sl);
      Print("sl=0.0",
            " CheckOpenLong: ",DoubleToString(check_open_long_lot,2),
            ", 余额: ",    DoubleToString(m_account.Balance(),2),
            ", 净值: ",     DoubleToString(m_account.Equity(),2),
            ", 可用保证金: ", DoubleToString(m_account.FreeMargin(),2));

方法 2 — 参见下面列出的代码:

      //--- 变数 #2: StopLoss!=0.0
      sl=m_symbol.Bid()-ExtStopLoss;
      check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),sl);
      Print("sl=",DoubleToString(sl,m_symbol.Digits()),
            " CheckOpenLong: ",DoubleToString(check_open_long_lot,2),
            ", 余额: ",    DoubleToString(m_account.Balance(),2),
            ", 净值: ",     DoubleToString(m_account.Equity(),2),
            ", 可用保证金: ", DoubleToString(m_account.FreeMargin(),2));

另外,现在会检查交易操作的结果:

            if(m_trade.Buy(chek_volime_lot,NULL,m_symbol.Ask(),m_symbol.Bid()-ExtStopLoss,m_symbol.Bid()+ExtStopLoss))
              {
               if(m_trade.ResultDeal()==0)
                  count--;

              }
            else
               count--;

首先检查: 如果在 Buy 方法操作的末尾返回 "true", 但是 ResultDeal() 方法返回 "0" (这可能在重新报价的时候会出现) — "count" 计数器应该减去1.

第二个检查: 如果在 Buy 方法操作的末尾返回了 "false", "count" 计数器应该减去1.

我们为什么要把 "count" 减去1呢?在这种情况下,我们不需要等待980个订单分时了,我们可以尝试在下一个分时就进场。

如何工作: 

设置每次交易的风险百分比 ( % risk 参数) 和止损 (StopLoss (点数) 参数)。这定义了可能损失的存款的参数。

固定风险资金输入参数 

以下的循环是用于模拟交易的:

   static long count=-21;
   if(count%980==0) // 我们略过 980 个订单分时
     {
      //--- 取得建立买入仓位的手数大小 (CMoneyFixedRisk)

初始值 count=-21 设置用于策略测试器。然后计算把count除以980的余数 (这个数字是随机选择的),也就是说,每过980个订单分时,手数计算循环就会开始,在其中考虑到风险计算每次交易的手数。

手数计算的循环依赖于每次交易的风险 (计算买入仓位):

第一步

      //--- getting lot size for open long position (CMoneyFixedRisk)
      double sl=0.0;
      double check_open_long_lot=0.0;
      //--- 变数 #1: StopLoss=0.0
      sl=0.0;
      check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),sl);
      Print("sl=0.0",
            ", CheckOpenLong: ",DoubleToString(check_open_long_lot,2),
            ", 余额: ",    DoubleToString(m_account.Balance(),2),
            ", Equity: ",     DoubleToString(m_account.Equity(),2),
            ", FreeMargin: ", DoubleToString(m_account.FreeMargin(),2));
      //--- 变数 #2: StopLoss!=0.0
      sl=m_symbol.Bid()-ExtStopLoss;
      check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),sl);
      Print("sl=",DoubleToString(sl,m_symbol.Digits()),
            ", CheckOpenLong: ",DoubleToString(check_open_long_lot,2),
            ", 余额: ",    DoubleToString(m_account.Balance(),2),
            ", Equity: ",     DoubleToString(m_account.Equity(),2),
            ", FreeMargin: ", DoubleToString(m_account.FreeMargin(),2));
      if(check_open_long_lot==0.0)
         return;

然后得到根据止损计算所得的买入仓位的手数,在check_open_long_lot变量中得到,使用的是CMoneyFixedRisk类的 CheckOpenLong方法:

      double check_open_long_lot=m_money.CheckOpenLong(m_symbol.Ask(),m_symbol.Bid()-ExtStopLoss);

以下参数会打印到专家日志中: 止损, 根据每次交易风险计算的手数, 计算时交易账户的余额, 计算时的保证金。

如果计算返回了 "0.0", 就退出:

      if(check_open_long_lot==0.0)
         return;

第二步

随后,我们如果有足够的资金,就可以得到买入仓位的手数,其数值是在chek_volime_lot 变量中得到的,使用了CTrade类的 CheckVolume 方法。以下参数会传入: m_symbol.Name() — 交易品种名称, check_open_long_lot — 我们想要建立的仓位的交易量 (这个参数是之前计算得到的): 

      //--- 在 OrderSend 之前检查交易量以避免 "资金不足" 错误 (CTrade)
      double chek_volime_lot=m_trade.CheckVolume(m_symbol.Name(),check_open_long_lot,m_symbol.Ask(),ORDER_TYPE_BUY);

第三步

如果 CheckVolume 返回了不是 "0.0" 的数值, 我们就检查条件: 我们是否有足够的资金来建立根据风险计算所得的手数。

      if(chek_volime_lot!=0.0)
         if(chek_volime_lot>=check_open_long_lot)
            m_trade.Buy(chek_volime_lot,NULL,m_symbol.Ask(),m_symbol.Bid()-ExtStopLoss,m_symbol.Bid()+ExtStopLoss);
      else
         Print("CMoneyFixedRisk lot = ",DoubleToString(check_open_long_lot,2),
               ", CTrade lot = ",DoubleToString(chek_volime_lot,2));

如果我们有足够的资金,就建立仓位,如果没有 — 根据每次交易风险计算的手数值 (DoubleToString(check_open_long_lot,2))以及我们所必需的资金数 (DoubleToString(chek_volime_lot,2)) 就在专家日志中打印出来。

例子 (当您在策略测试器中测试, 选择 EURUSD, M1, 测试期间为从 2016.11.28, 存款 $3000):

Money Fixed Risk.png 

建立了一个买入仓位 (从测试器日志中获得) — 根据每次交易风险计算所得的手数是 2.23.

Money Fixed Risk (EURUSD,M1)    2016.11.28 00:03:24   sl=0.0 CheckOpenLong: 0.01, Balance: 3000.00, Equity: 3000.00, FreeMargin: 3000.00
Money Fixed Risk (EURUSD,M1)    2016.11.28 00:03:24   sl=1.05942 CheckOpenLong: 2.23, Balance: 3000.00, Equity: 3000.00, FreeMargin: 3000.00
Trade   2016.11.28 00:03:32   instant buy 2.23 EURUSD at 1.06076 sl: 1.05942 tp: 1.06142 (1.06042 / 1.06076 / 1.06042)
Trades  2016.11.28 00:03:32   deal #2 buy 2.23 EURUSD at 1.06076 done (based on order #2)
Trade   2016.11.28 00:03:32   deal performed [#2 buy 2.23 EURUSD at 1.06076]
Trade   2016.11.28 00:03:32   order performed buy 2.23 at 1.06076 [#2 buy 2.23 EURUSD at 1.06076]
Money Fixed Risk (EURUSD,M1)    2016.11.28 00:03:32   CTrade::OrderSend: instant buy 2.23 EURUSD at 1.06076 sl: 1.05942 tp: 1.06142 [done at 1.06076]
Money Fixed Risk (EURUSD,M1)    2016.11.28 00:48:32   sl=0.0 CheckOpenLong: 0.01, Balance: 3000.00, Equity: 2828.29, FreeMargin: 462.80
Money Fixed Risk (EURUSD,M1)    2016.11.28 00:48:32   sl=1.05899 CheckOpenLong: 2.60, Balance: 3000.00, Equity: 2828.29, FreeMargin: 462.80
Money Fixed Risk (EURUSD,M1)    2016.11.28 00:48:32   CMoneyFixedRisk lot = 2.60, CTrade lot = 0.43
Trade   2016.11.28 00:53:15   stop loss triggered #2 buy 2.23 EURUSD 1.06076 sl: 1.05942 tp: 1.06142 [#3 sell 2.23 EURUSD at 1.05942]
Trades  2016.11.28 00:53:15   deal #3 sell 2.23 EURUSD at 1.05942 done (based on order #3)
Trade   2016.11.28 00:53:15   deal performed [#3 sell 2.23 EURUSD at 1.05942]
Trade   2016.11.28 00:53:15   order performed sell 2.23 at 1.05942 [#3 sell 2.23 EURUSD at 1.05942]

看起来资金不足,不够建立第二个仓位。

要注意的是,当没有制定止损时 (StopLoss=0.0), 计算的手数就等于允许的最小手数值。

结果,第一个仓位因为止损而关闭,损失了 298.82:

Money Fixed Risk 历史

这对应了差不多$3000存款的10%.

本文译自 MetaQuotes Software Corp. 撰写的俄文原文
官方代码: https://www.mql5.com/ru/code/17199

市场能量平衡 市场能量平衡

市场能量平衡 (使用了提高的 Jurik 过滤器来计算).

Hercules A.T.C. 2006 Hercules A.T.C. 2006

本EA交易根据移动平均的突破进行交易。它使用了以下指标: 两个 iMAs (移动平均, MA), iRSI(相对强弱指数, RSI) 以及两个 iEnvelopes (包络线).

AdxVma trend AdxVma trend

AdxVma 趋势.

ShowImportantParams ShowImportantParams

显示了重要的交易品种和账户参数。