[转FX988]Forex Combo 1.46 详解笔记一

这是它的网站介绍:
运行的货币:EURUSD (貌似最新版有GBPUSD)一般使用于EURUSD
时间周期:5M
测试图(亲测)2008.01.01 - 2011.12.31
 

这个EA是有三种模式里面,我们都可以从它的参数得知这个EA拥有的模式。
extern bool Use_FXCOMBO_Scalping = TRUE;//剥头皮
extern bool Use_FXCOMBO_Breakout = TRUE;//趋势突破
extern bool Use_FXCOMBO_Reversal = TRUE;//逆势交易

EA给三种模式都设置了开关,给客户提供了方便的接口,可以单模式进行优化测试,的确很方便
extern bool Use_ECN_Broker = FALSE;//ECN平台的开关。
//ECN打开的话,下的订单都是没有止损止盈,都是从代码来实现的。
//三种模式的下单注释
extern string CommentSys1 = "==== 1 ====";
extern string CommentSys2 = "==== 2 ====";
extern string CommentSys3 = "==== 3 ====";

//三种模式的标识符
extern int Magic1 = 111;
extern int Magic2 = 222;
extern int Magic3 = 333;

//使用的最大点差
extern double MaxSPREAD = 4.0;
//下单的滑点
extern int Slippage = 2;
//自动判断时区(自动获取只有在不是测试模式下并且Auto是TRUE的情况)
extern bool AutoGMT_Offset = TRUE;
extern int GMT_Offset_TestMode = 2;
//AutoGMT_Offset = FALSE的时候,GMT就由这个参数来设定
//是否采用有风险的资金管理(亏损加仓)
extern bool UseAgresiveMM = FALSE;
/* 下面这段代码可以看出这个参数作用
   if (UseAgresiveMM != TRUE) {//默认的情况下这个参数是关闭的,那么就符合!=TRUE就会运行下面三句代码
      LossFactorSys1 = 1;
      LossFactorSys2 = 1;
      LossFactorSys3 = 1;
   }

    //这样一来无论下面怎么设置LossFactorSys1\2\3 都好CalcTradeMM1\2\3得到的值永远等于 TradeMM1\2\3 本身的值
*/

接下来是三种模式的资金管理(亏损加仓)设置

extern string MMSys1 = "==== FXCOMBO Scalping MM Parameters ====";
extern double LotsSys1 = 0.1;
extern double TradeMMSys1 = 0.0;
extern double LossFactorSys1 = 2.0;
int gi_196 = 0;
int gi_200 = 2;
int gi_204 = 0;

extern string MMSys2 = "==== FXCOMBO Breakout MM Parameters ====";
extern double LotsSys2 = 0.1;
extern double TradeMMSys2 = 0.0;
extern double LossFactorSys2 = 2.0;
int gi_240 = 0;
int gi_244 = 2;
int gi_248 = 0;

extern string MMSys3 = "==== FXCOMBO Reversal MM Parameters ====";
extern double LotsSys3 = 0.1;
extern double TradeMMSys3 = 0.0;
extern double LossFactorSys3 = 2.0;
int gi_284 = 0;
int gi_288 = 2;
int gi_292 = 0;

从上面我们可以看出三种模式都拥有6个参数。可以判断的是,三个模式的这6个参数的意义是一样的,并且最后三个参数已经写死了的。就是没有提供外部参数让客户改
骚片AV我们接分析这6个参数具体意义

我们来看一下第一个参数LotsSys(我以LotsSys1为例子),我寻找一下有关于它的代码:我标注了一下。
      if (LotsSys1 != 0.0) {
         //在LotsSys1和货币允许的最小最大手数之间通过MAX和MIN来获取合法的手数
         l_lots_392 = MathMin(g_maxlot_564, MathMax(g_minlot_556,LotsSys1));
        if (TradeMMSys1 > 0.0) l_lots_392 = MathMax(g_minlot_556, MathMin(g_maxlot_564, NormalizeDouble(CalcTradeMMSys1() / 100.0 * AccountFreeMargin() / g_minlot_556 / (g_lotsize_576 / 100), 0) * g_minlot_556));

         …………
         …………
        }

不难的看出,LotsSys1\2\3是三种模式的手数设定,在它下面还看到TradeMMSys这个参数的使用。

接着看看TradeMMSys这个参数:

if (TradeMMSys1 > 0.0) l_lots_392 = MathMax(g_minlot_556, MathMin(g_maxlot_564, NormalizeDouble(CalcTradeMMSys1() / 100.0 * AccountFreeMargin() / g_minlot_556 / (g_lotsize_576 / 100), 0) * g_minlot_556));

从这句代码里面,我们可以看到一个函数CalcTradeMMSys1()
double CalcTradeMMSys1() {
   int li_8;
   double ld_16;
   double ld_ret_0 = TradeMMSys1;
   int li_12 = 0;
   if (Digits <= 3) ld_16 = 0.01;
   else ld_16 = 0.0001;
  // 这个FOR循环,有意思,li_12记录着连续亏损的订单数量,gi_204这个参数也是6个参数之一,在这里大致的作用起一个盈利目标的作用
   for (int l_hist_total_24 = OrdersHistoryTotal(); l_hist_total_24 >= 0; l_hist_total_24--) {//注意是订单的历史记录
      if (OrderSelect(l_hist_total_24, SELECT_BY_POS, MODE_HISTORY)) {
         if (OrderType() <= OP_SELL && OrderSymbol() == Symbol() && OrderMagicNumber() == Magic1) {
            if (OrderProfit() > 0.0) {
               if (gi_204 == 0) break;
               if (MathAbs(OrderClosePrice() - OrderOpenPrice()) / ld_16 > gi_204) break;//符合盈利目标就跳出循环
            } else li_12++;

         }
      }
   }
//gi_196(默认是0),gi_200(默认是2),LossFactorSys1(默认是2.0) 这三个都是6个参数之一,这样一来我们就找到这个6个参数的所在地方了。
//不难看出呀,gi_196是连续亏损的参数设置,gi_200是用来计算幂
   if (li_12 > gi_196 && gi_200 > 1) {
   //大概的意思是:如果连续亏损次数>gi_196设定的次数并且设定gi_200大于1那么进入控制语句里面去
      li_8 = MathMod(li_12, gi_200);
      //求得 li_12除以gi_200 的余数.按照默认的情况li_8有可能的结果为0,1
      ld_ret_0 *= MathPow(LossFactorSys1, li_8);
      //通过计算得到li_8,用来做幂,底数为LossFactorSys1,返回的结果也有只有两种1,或者LossFactorSys1的值。这里还没完
      //MathPow()得到的结果还需要与ld_ret_0相乘。ld_ret_0的值现在的情况应该是等于0, TradeMMSys1 就是ld_ret_0初始化时候的值.
   }
   if (MMMax > 0.0 && ld_ret_0 > MMMax) ld_ret_0 = MMMax;
   //通过上面的计算还没完,得判断一下最后的结果是否在最大的允许范围内。超过就等于最大的,然后下面返回它的值
   return (ld_ret_0);
}

这个函数用到了6个参数中的5个参数,其中有3个是官方不提供外部参数的,看来是过于复杂,担心客户接受不了还是什么的。

接着返回到函数调用处:(我们通过一个例子来计算一下)
AccountFreeMargin 为 500
g_minlot_556 这个变量是货币的最小的手数 0.1
g_lotsize_576 这个是1个标准手数大小 10W
TradeMMSys1 = 1;默认为0,0的话无法启动这个亏损加仓机制,所以我们给它1,其他的参数的数值不改变
li_12 = 2;假设连续亏损2次
li_8 得到的结果 0
MathPow(LossFactorSys1,li_8)  得到结果 1
ld_ret_0 最后结果 1 并且小于 MMMax 那返回去
CalcTradeMMSys1() 函数得到的结果应该为 1
CalcTradeMMSys1() / 100.0 * AccountFreeMargin() / g_minlot_556 / (g_lotsize_576 / 100)进入代入:
1/100*500/0.1/(100000/100)=0.05
可是NormalizeDouble(0.05,0)结果是为0的。
MathMax(g_minlot_556, 0)就用最小手数0.1来下单了。证明在这个机制的情况,加仓的风险还是比较低比较安全的。

但如果要体现它这个资金管理是否合理,我们就需要大胆的改一下了:
AccountFreeMargin 为 10000
TradeMMSys1 = 3;
LossFactorSys1 = 3.0;
li_12 = 3 连续亏损3次
li_8 得到的结果 1
MathPow(LossFactorSys1,li_8)  得到结果 3
ld_ret_0 = 9.0 代入代码中 不详解
CalcTradeMMSys1()  = 9.0
9/100*10000/0.1/1000 = 9.0
NormalizeDouble(9.0,0)结果是为9
当然不可能是9手,后面还需要乘以0.1,之前因为等于0,所以没说需要NormailzeDouble的结果还需要乘以0.1
所以最后需要下的手数为0.9手

这个资金管理还是很周密的,如果有需要用到的话,根本可以提取代码。
通过保证金以及连续亏损次数得到一个适合自己的手数。真不错。
通过观察,我们现在就知道了这6个参数的作用。没有提供外部参数的3个参数要修改的话真的看你的需要了。毕竟这是少部分人。

今晚笔记到此!待续…………

var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?44d5929b98ed1fd093ffc3d47ec712b9"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })();