顺水外汇EA交易网MT4

标题: 俄国人写的一个牛逼ea [打印本页]

作者: 245680    时间: 2018-1-11 00:44
标题: 俄国人写的一个牛逼ea
增长曲线很漂亮,但是怎么用作者只是说自己去看代码.
有人看懂后回个帖简要介绍一下他的思想啊

作者: chenhuade6000    时间: 2018-1-11 02:16
资金管理与下单手数量的关系写法收集  
2010-06-02 10:29:56|  分类: 默认分类 |字号 订阅
//---------------------------------------------------------------------------------------

double Lots()
   {
   lots =NormalizeDouble(AccountEquity()*资金百分比/100/1000,1);               // 计算标准手总数
   double 最小手数 = MarketInfo(Symbol(), MODE_MINLOT);                         // 最小标准手
   if ( lots== 0 )  lots = 最小手数;                                                                      // 如果计算的手数为0(因资金百分比未赋值),则采用最小规定手数
   return(lots);                                                                                                  // 返回手数计算结果值
   }

#property copyright "laoyee"
#property link      "qq:921795"
//指标在主图显示
#property indicator_chart_window
extern color TextColor=Red;
int cnt;
string TextBarString,DotBarString,HLineBarString,VLineBarString;
int init()
   {
      return(0);
   }
int deinit()
   {
      Comment("");
      ObjectsDeleteAll(0);
      return(0);
   }
int start()
   {
      iMain();
      return(0);
   }
void iMain()
   {
      //定义统计变量
      int BuyHistoryOrders,SellHistoryOrders,ProfitHistoryOrders,HistoryOrderTotal;//买入历史订单、卖出历史订单、盈利历史订单、历史订单总数
      int WinHistory,LossHistory; //历史盈利/亏损单累计
      double TotalHistoryLots;//历史交易总手数
      double TotalHistoryProfit,TotalHistoryLoss;//盈利总数、亏损总数变量
      color myLineColor=Blue;
      iDisplayInfo("Author", "[联系老易 QQ:921795]",0,210,1,7,"",Gray);
      iDisplayInfo("Times","动态报价时间:"+TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS)+" 星期"+DayOfWeek(),0,4,15,9,"Verdana",TextColor);
      //遍历历史订单,计算相关信息
      HistoryOrderTotal=OrdersHistoryTotal(); //统计历史订单总数
      for (cnt=0;cnt0)  myLineColor=Blue;
                        if (OrderProfit()0)  myLineColor=Blue;
                        if (OrderProfit()0)
                     {
                        WinHistory=WinHistory+1;
                        TotalHistoryProfit=TotalHistoryProfit+OrderProfit();
                     }
                  if (OrderProfit()0)  myLineColor=Blue;
                  if (OrderProfit()myMaxLots)
         {
            iDisplayInfo("Waring", "持仓量已超过警戒线,请慎重下单!",0,4,110,12,"黑体",Olive);
         }
         else iDisplayInfo("Waring", "",0,4,110,12,"",Olive);
      return(0);
   }
/*
函   
数:在屏幕上显示文字标签
输入参数:string LableName 标签名称,如果显示多个文本,名称不能相同
          string LableDoc 文本内容
          int Corner 文本显示角
          int LableX 标签X位置坐标
          int LableY 标签Y位置坐标
          int DocSize 文本字号
          string DocStyle 文本字体
          color DocColor 文本颜色
输出参数:在指定的位置(X,Y)按照指定的字号、字体及颜色显示指定的文本
算法说明:
*/
void iDisplayInfo(string LableName,string LableDoc,int Corner,int LableX,int LableY,int DocSize,string DocStyle,color DocColor)
   {
      if (Corner == -1) return(0);
      ObjectCreate(LableName, OBJ_LABEL, 0, 0, 0);
      ObjectSetText(LableName, LableDoc, DocSize, DocStyle,DocColor);
      ObjectSet(LableName, OBJPROP_CORNER, Corner);
      ObjectSet(LableName, OBJPROP_XDISTANCE, LableX);
      ObjectSet(LableName, OBJPROP_YDISTANCE, LableY);
   }
/*
函    数:两点间连线(主图)
输入参数:string myLineName  线段名称
          int myFirstTime  起点时间
          int myFirstPrice  起点价格
          int mySecondTime  终点时间
          int mySecondPrice  终点价格
          int myLineStyle  线型 0-实线 1-断线 2-点线 3-点划线 4-双点划线
          color myLineColor 线色
输出参数:在指定的两点间连线
算法说明:
*/
void iTwoPointsLine(string myLineName,int myFirstTime,double myFirstPrice,int mySecondTime,double mySecondPrice,int myLineStyle,color myLineColor)
   {
      ObjectCreate(myLineName,OBJ_TREND,0,myFirstTime,myFirstPrice,mySecondTime,mySecondPrice);//确定两点坐标
      ObjectSet(myLineName,OBJPROP_STYLE,myLineStyle); //线型
      ObjectSet(myLineName,OBJPROP_COLOR,myLineColor); //线色
      ObjectSet(myLineName,OBJPROP_WIDTH, 1); //线宽
      ObjectSet(myLineName,OBJPROP_BACK,false);
      ObjectSet(myLineName,OBJPROP_RAY,false);
   }
   
/*
函    数:标注符号和画线、文字
参数说明:string myType 标注类型:Dot画点、HLine画水平线、VLine画垂直线、myString显示文字
          int myBarPos 指定蜡烛坐标
          double myPrice 指定价格坐标
          color myColor 符号颜色
          int mySymbol 符号代码,108为
圆点
          string myString 文字内容,在指定的蜡烛位置显示文字
函数返回:在指定的蜡烛和价格位置标注符号或者画水平线、垂直线
*/
void iDrawSign(string myType,int myBarPos,double myPrice,color myColor,int mySymbol,string myString,int myDocSize)
      {
         if (myType=="Text")
            {
               TextBarString=myType+Time[myBarPos];
               ObjectCreate(TextBarString,OBJ_TEXT,"",Time[myBarPos],myPrice);
               ObjectSet(TextBarString,OBJPROP_COLOR,myColor);//颜色
               ObjectSet(TextBarString,OBJPROP_FONTSIZE,myDocSize);//大小
               ObjectSetText(TextBarString,myString);//文字内容
               ObjectSet(TextBarString,OBJPROP_BACK,true);
            }
         if (myType=="Dot")
            {
               DotBarString=myType+Time[myBarPos];
               ObjectCreate(DotBarString,OBJ_ARROW,0,Time[myBarPos],myPrice);
               ObjectSet(DotBarString,OBJPROP_COLOR,myColor);
               ObjectSet(DotBarString,OBJPROP_ARROWCODE,mySymbol);
               ObjectSet(DotBarString,OBJPROP_BACK,false);
            }
         if (myType=="HLine")
            {
               HLineBarString=myType+Time[myBarPos];
               ObjectCreate(HLineBarString,OBJ_HLINE,0,Time[myBarPos],myPrice);
               ObjectSet(HLineBarString,OBJPROP_COLOR,myColor);
               ObjectSet(HLineBarString,OBJPROP_BACK,false);
            }
         if (myType=="VLine")
            {
               VLineBarString=myType+Time[myBarPos];
               ObjectCreate(VLineBarString,OBJ_VLINE,0,Time[myBarPos],myPrice);
               ObjectSet(VLineBarString,OBJPROP_COLOR,myColor);
               ObjectSet(VLineBarString,OBJPROP_BACK,false);
            }
     }
========================================================================================================
  if (资管模式  100)  使用手数=100;
        }
        else  使用手数=手数;
  if (资管模式 >0)   {
      使用手数=MathCeil(AccountBalance()*资管风险/10000)/10;
      /*if (使用手数 >1)
        {
        使用手数=MathCeil(使用手数);
        }
      if (使用手数 100)
        {
        使用手数 =100;
        }
    }
  ===================================================================================================
     lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);    //手数赋值为 将可用保证金乘以最大风险率/1000后精确化
  ===================================================================================================
lot= NormalizeDouble(MaximumRisk * AccountBalance() /AccountLeverage(), 1);     //开仓量计算
if(lotmaxLots)  lot=maxLots;
========================================================================================================
if( 标准账户==1 ) {                                                      
   if(资管 != 0)
      lotsi =MathCeil(AccountBalance() *风险 /10000) ;
   else lotsi =手数;
     }
else {
   if(资管 != 0)
     lotsi =MathCeil(AccountBalance() *风险 /10000) /10 ;
   else lotsi =手数; //迷你仓计算
     }
if( lotsi >100 )  lotsi =100;                                                        //手数最大限制为100手
//+------------------------------------------------------------------+

double LotsOptimized()//函数目的,根据要求 计算出订单交易量
  {
   double lot=Lots;
   int    orders= HistoryTotal();                                    // history orders total 历史出场订单的个数
   int    losses=0;                                                  // number of losses orders without a break
   lot= NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000,1);   //通过风险系数的计算获得当前入场单应该采用的交易量
   // lot=NormalizeDouble(AccountFreeMargin()*最大风险*交易倍数/100000,1);// 减少因子存在
   if(DecreaseFactor>0)
     {
      for(int i=orders-1; i>=0; i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)     //循环查询出场单队列
           { Print("Error in history!"); break; }//如果没有历史单子子,则
         if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;           //
         if(OrderProfit()>0) break;
         if(OrderProfit()1) lot= NormalizeDouble(lot-lot*losses/DecreaseFactor,1);       //如果亏损额大于1,则下一入场单的交易量修正为新的计算结果。
     }
   if(lotOrderOpenTime())
                       {
                        temptime= OrderOpenTime();
                        tick= OrderTicket();
                       }
                    }
                 }
               return(tick);
      case 2:
               tick= 0;
               temptime= TimeCurrent();
               for(i=0; iOrderOpenTime())
                        {
                         temptime= OrderOpenTime();
                         tick= OrderTicket();
                        }
                     }
                  }
                return(tick);
     }
  }

datetime Expiration 持单有效时间的理解
此参数是以秒为单位。下单时用当前的时间(服务器时间或本地时间)加上你计划的期限(以秒计算)即可,
例如:
OrderSend(…….,TimeCurrent()+Period()*60,..);
假如当前的图表是日线图,则该挂单就会在24小时后失效

=================================================================================================
时间限制
if (TimeDayOfWeek(CurTime()) == 1)
  {
  if (TimeHour(CurTime()) =0;  index--)
   if ( OrderSelect(index, SELECT_BY_POS)   &&OrderMagicNumber()==MagicNumber  &&OrderSymbol()==Symbol() )
    {
    ticket[count]= OrderTicket();                  
    price[count] = OrderOpenPrice();
    oot[count]   = OrderOpenTime();
    count++;
    }
   
int order[100];                                                             // 插入分类
for (int kk=0;   kk0 && oot[order[ii-1]] > oot[kk];  ii--)
       { order[ii]=order[ii-1];}                                            // kk   oot[kk] order[kk]   oot[order[kk]]
                                                                            // 0    3.      1           1.
    order[ii]=kk;                                                           // 1    1.      2           2.
}                                                                           // 2    2.      0           3.
// ticket[order[0]]        is the oldest
// ticket[order[count-1]]  is the latest
====================================================================================================
[Script] 打印各种订单类型的总数

extern int ExpertMagicNumber=123456;
//+-------------- 计算所有的订单类型 子函数() ----------------------------------------------------+
int MyOrdersTotal(int  buyNumber, int sellNumber,int buyLimitNumber
   ,int sellLimitNumber,int  buyStopNumber, int sellStopNumber, int MagicNumber=0 )  //
   {
   int res,
       orderType;
//----
   buyNumber=0;
   sellNumber=0;
   buyLimitNumber=0;
   sellLimitNumber=0;
   buyStopNumber=0;
   sellStopNumber=0;
   for (int i=OrdersTotal()-1;  i>=0;  i--)
      if (OrderSelect(i, SELECT_BY_POS))
         {
         if (MagicNumber==0 || (OrderMagicNumber()==MagicNumber && MagicNumber!=0))    //
            {
            switch(OrderType())
               {
               case OP_BUY: buyNumber++;break;
               case OP_SELL: sellNumber++;break;
               case OP_BUYLIMIT: buyLimitNumber++;break;
               case OP_SELLLIMIT: sellLimitNumber++;break;
               case OP_BUYSTOP: buyStopNumber++;break;
               case OP_SELLSTOP: sellStopNumber++;break;
               }
            }
         }
//----
   res=buyNumber+sellNumber+buyLimitNumber+sellLimitNumber+buyStopNumber+sellStopNumber;
   return(res);   
   }
//+----------------脚本程序主函数  --------------------------------------------------+
int start()
  {
   int buys,  sells,  buyLs,  sellLs,  buySts,  sellSts;
   if (MyOrdersTotal(buys,sells,buyLs,sellLs,buySts,sellSts,ExpertMagicNumber)>0)
   Print("买单=",buys," 卖单=",sells,"  限价买单=",buyLs,"  限价卖单=",sellLs," 突破价买单=",buySts," 突破价卖单=",sellSts);
   return(0);
  }
====================================================================================================
被止损或止赢的检查返回结果的程序段
start()
{
    OrderEvents(MAGIC); //调用该子函数
...
}
//------------------------------------在历史中分别查找止损单和赢利单 子函数--------------------------------+
void OrderEvents( int magic ) {  
    static datetime lastCheck;
    for( int o = 0;  o  lastCheck )
            if( OrderClosePrice() == OrderStopLoss() )                    //(是否忽略了大于小于的情况未知)
                OnStopLoss(OrderTicket());
            else if( OrderClosePrice() == OrderTakeProfit() )           //(是否忽略了大于小于的情况未知)
                OnTakeProfit(OrderTicket());
    }
    lastCheck = TimeCurrent();
}

//--------------
void OnStopLoss( int ticket )
{
...
}
//---------------
void OnTakeProfit( int ticket )
{
...
}






//==========================================================
/*
start() {
    检查订单被止子函数(MAGIC);
    if(类型==OP_BUY ||类型==OP_BUYLIMIT||类型==OP_BUYSTOP) OP=买;
    if(类型==OP_BUY ||类型==OP_BUYLIMIT||类型==OP_BUYSTOP) OP=卖;
...
}
void 检查订单被止子函数( int 标识符 ) {
    static datetime 最后检查时间;
    for( int 个 = 0; 个  最后检查时间 )
               
            if(OP==买)
               if( OrderClosePrice() = OrderTakeProfit() )
                被止赢价(OrderTicket());
            if(OP==卖)
                if( OrderClosePrice() >= OrderTakeProfit() )
                被止损价(OrderTicket());
                else if( OrderClosePrice()
}
void 被止赢价( int ticket ) {
...
}
*/
====================================================================================================

    if(已成买单数>0){
      for(i=0; i=0; i--){
   OrderSelect(i, SELECT_BY_POS,MODE_HISTORY);
   if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic){
      //--买单时
      if(OrderType()==OP_BUY && OrderProfit()>0)
         历史最后单结果= "买赢";
      if(OrderType()==OP_BUY && OrderProfit()0)
         历史最后单结果= "卖赢";
      if(OrderType()==OP_SELL && OrderProfit()=0; i--){
   OrderSelect(i, SEL_BY_POS, MODE_HISTORY);
   if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic){
      if(OrderProfit()=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderSymbol()==Symbol()){
      for(int x=0; x=oct[x]) {      
            for(int(y=x; y0)
      return(1);
   return(0);
  }
//---------------------------------------------+
   int    Prev_Orders = -1;                  //place this before the start section
//=======This goes in section 2
   if(Prev_OrdersPrev_Orders)
      int MN= Get_Magic_Num());  //history orders has increased, so an order must have closed>>>>> lets get it's Magic Number & do something with it
   if(MN0 && OrderSymbol()==Symbol() && OrderMagicNumber()==16384){
   for(int cnnt=Bistory; cnnt>=1; cnnt--){
      if(OrderSelect(OrdersHistoryTotal()-cnnt,SELECT_BY_POS,MODE_HISTORY) && OrderProfit()>=0)
         LosCount=0;
      if(OrderSelect(OrdersHistoryTotal()-cnnt,SELECT_BY_POS,MODE_HISTORY) && OrderProfit()=0; i--){
      OrderSelect(i, SELECT_BY_POS,MODE_HISTORY);   
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic){
         if(OrderType()==OP_BUY || OP_BUYLIMIT || OP_BUYSTOP || OP_SELL || OP_SELLLIMIT || OP_SELLSTOP && OrderProfit()=0; i--){
      if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
         continue;
      int type= OrderType();
      //--initial balance not considered
      if(i==0 && type==OP_BALANCE)
         break;
      if(type==OP_BUY || type==OP_SELL){
         //--计算浮赢
         double profit= OrderProfit()+OrderCommission()+OrderSwap();
         //---- and decrease balance
         initial_deposit -= profit;
        }
      if(type==OP_BALANCE || type==OP_CREDIT)
         initial_deposit -= OrderProfit();
     }
   return(initial_deposit);
  }
  
  
  
  2010年08月29日 三种建仓的简洁函数写法  
2010-08-29 14:23:02|  分类: 默认分类 |字号 订阅
每个智能交易程序里都有一段代码是控制建仓的。它在所有的定单中不断搜索,通过信息选择仓位,然后进行修改和关闭。这段代码看上去都差不多,并且往往具有相同的功能。这就是为什么这段经常被重复的代码可以从程序中提取出来成为函数,从而使程序更易写更简洁。
首先,我们按功能把任务分成三个步骤 — 这三个步骤其实是三种智能交易程序:
智能交易程序在同一时间只能新建一个仓位
智能交易程序在同一时间可以新建每个类型的一个仓位(比如, 多头和空头的仓位)
智能交易程序可以同时新建多个仓位
2. 一个仓位
只新建一个仓位有许多中策略。这种控制代码块非常简单,但写出来也会耗费一定的时间和精力。
举一个简单的例子,一个来自于 MACD 线交叉点(信号线和基础线)的建仓信号,简化它的控制代码块,程序如下:
extern int  _MagicNumber = 1122;       int start()  {      //---- 记住指标值做分析数据      double MACD_1 = iMACD(Symbol(), 0, 12, 26, 9, PRICE_CLOSE,                            MODE_MAIN, 1 );      double MACD_2 = iMACD(Symbol(), 0, 12, 26, 9, PRICE_CLOSE,                            MODE_MAIN, 2 );         int _GetLastError = 0, _OrdersTotal = OrdersTotal();      //---- 在开仓位置搜索        for ( int z = _OrdersTotal - 1; z >= 0; z -- )        {  // 如果在搜索中生成错误,转至下一个仓位          if ( !OrderSelect( z, SELECT_BY_POS ) )            {            _GetLastError = GetLastError();            Print("OrderSelect( ", z, ", SELECT_BY_POS ) - 错误 #",                  _GetLastError );              continue;          }       // 如果当前的货币对没有开仓,   // 忽略过          if ( OrderSymbol() != Symbol() ) continue;       // 如果 MagicNumber不等于_MagicNumber,   // 忽略这个仓位          if ( OrderMagicNumber() != _MagicNumber ) continue;             //---- 如果BUY舱位开仓,            if ( OrderType() == OP_BUY )          {              //---- 如果MACD 遇到下降的零线,                if(NormalizeDouble(MACD_1, Digits + 1) = 0.0)                {                  //---- 平仓                  if(!OrderClose( OrderTicket(), OrderLots(),                      Bid, 5, Green))                    {                     _GetLastError = GetLastError();                     Alert("错误OrderClose 鈩?", _GetLastError);                     return(-1);                  }                }  // 如果信号线没有改变,退出:    // 开新仓位过早              else              { return(0); }            }          //---- 如果 SELL 仓位开仓,          if ( OrderType() == OP_SELL )            {              //---- 如果 MACD 遇到上升的零线              if(NormalizeDouble(MACD_1, Digits + 1) >  0.0 &&                  NormalizeDouble(MACD_2, Digits + 1 )   0.0 &&             NormalizeDouble( MACD_2, Digits + 1 ) = 0.0)        {          //---- open a SELL position          if(OrderSend( Symbol(), OP_SELL, 0.1, Bid, 5, 0.0, 0.0,             "MACD_test",                 _MagicNumber, 0, Red ) = 0; z -- )        {          if ( !OrderSelect( z, SELECT_BY_POS ) )            {            _GetLastError = GetLastError();            Print("OrderSelect( ", z, ", SELECT_BY_POS ) -错误#",                   _GetLastError );            continue;          }            if(OrderMagicNumber() == magic && OrderSymbol() ==              Symbol())            {            _Ticket    = OrderTicket();            _Type      = OrderType();            _Lots      = NormalizeDouble( OrderLots(), 1 );            _OpenPrice = NormalizeDouble( OrderOpenPrice(), Digits);            _StopLoss = NormalizeDouble( OrderStopLoss(), Digits);            _TakeProfit = NormalizeDouble( OrderTakeProfit(), Digits);            _OpenTime   = OrderOpenTime();            _Profit     = NormalizeDouble( OrderProfit(), 2 );            _Swap       = NormalizeDouble( OrderSwap(), 2 );            _Commission = NormalizeDouble( OrderCommission(), 2 );            _Comment    = OrderComment();            _Expiration = OrderExpiration();            return;          }        }  }
如你所见,这非常简单: 一共 11 个变量,每个都储存仓位的相关信息(ticket #, type, lot size, 等等). 当函数开始运行时,这些变量被归零。作为全局变量这是必需的。函数被调用时变量也可以不归零,但我们需要的不是先前的信息,我们需要的是最近的。然后所有的仓位会以标准的方式被搜索,一旦获得需要的信号和MagicNumber 值,信息将被存储在相应的变量中。
现在我们将函数用到智能交易程序中:
extern int  _MagicNumber = 1122;     #include      int start()    {      int _GetLastError = 0;        // 记住开仓的参量(如果可用)      OneOrderInit( _MagicNumber );         //---- 记住指标值用作分析        double MACD_1 = iMACD(Symbol(), 0, 12, 26, 9, PRICE_CLOSE,                             MODE_MAIN, 1 );      double MACD_2 = iMACD(Symbol(), 0, 12, 26, 9, PRICE_CLOSE,                               MODE_MAIN, 2 );         // 现在,代替在仓位中的搜索       // 存在开仓:      if ( _Ticket > 0 )        {          //----如果BUY 仓位开仓,          if ( _Type == OP_BUY )            {              //---- 如果MACD 遇到下降的零线,               if(NormalizeDouble( MACD_1, Digits + 1 ) = 0.0)                {                  //---- 平仓                  if(!OrderClose( _Ticket, _Lots, Bid, 5, Green))                    {                    _GetLastError = GetLastError();                    Alert( "错误 OrderClose 鈩?", _GetLastError);                    return(-1);                  }                }              // 如果信号没有改变,退出:               // 开新仓位过早            else return(0);          }          //----如果 SELL 仓位开仓,            if ( _Type == OP_SELL )          {              //---- 如果MACD 遇到上升的零线                if(NormalizeDouble( MACD_1, Digits + 1 ) >  0.0 &&                  NormalizeDouble( MACD_2, Digits + 1 )   0.
0 &&          N
ormalizeDouble( MACD_2, Digits + 1 ) = 0.0    )        {          //---- 开SELL仓位          if(OrderSend(Symbol(), OP_SELL, 0.1, Bid, 5, 0.0, 0.0,             "CrossMACD",                 _MagicNumber, 0, Red ) = 0; z -- )        {          // 如果在搜索中生成错误,            // 转至下一个仓位          if ( !OrderSelect( z, SELECT_BY_POS ) )            {            _GetLastError = GetLastError();            Print("OrderSelect(", z, ", SELECT_BY_POS) - Error #",                 _GetLastError );            continue;          }       // 如果当前货币对没有开仓仓位,忽略它   if ( OrderSymbol() != Symbol() ) continue;       // 如果MagicNumber 不等于 _MagicNumber,   // 忽略这个仓位          if ( OrderMagicNumber() != _MagicNumber ) continue;             // 取决于仓位类型,          // 改变变量值:            switch ( OrderType() )          {            case OP_BUY:      BuyOrder      = OrderTicket(); break;            case OP_SELL:     SellOrder     = OrderTicket(); break;            case OP_BUYSTOP:  BuyStopOrder  = OrderTicket(); break;            case OP_SELLSTOP: SellStopOrder = OrderTicket(); break;          }        }         //---- 如果我们有两个挂单交易,退出      //---- 等待他们开启      if ( BuyStopOrder > 0 && SellStopOrder > 0 ) return(0);         // 在全部定单中第二次搜索       // 现在运行它们:        _OrdersTotal = OrdersTotal();      for ( z = _OrdersTotal - 1; z >= 0; z -- )        {          // 如果在仓位搜索中生成错误,          // 转至下一个仓位          if ( !OrderSelect( z, SELECT_BY_POS ) )            {              _GetLastError = GetLastError();              Print("OrderSelect
(", z, ", SELEC
T_BY_POS) - 错误 #",                     _GetLastError );              continue;          }               // 如果对于当前的货币对没有开仓          // 忽略它          if ( OrderSymbol() != Symbol() ) continue;             // 如果 MagicNumber 不等于 _MagicNumber,           // 忽略这个仓位            if ( OrderMagicNumber() != _MagicNumber ) continue;             // 取决于仓位的类型,           // 改变变量值:            switch ( OrderType() )          {              //----如果BUY仓位开仓,              case OP_BUY:              {                    // 如果 SellStop定单还没有删除,                   // 删除:                  if ( SellStopOrder > 0 )                  {                      if ( !OrderDelete( SellStopOrder ) )                    {                        Alert(OrderDelete Error #", GetLastError());                      return(-1);                    }                    }                  // 检测止损被移动:                  // 如果追踪止损的大小不是很小,                  if(TrailingStop > MarketInfo( Symbol(),                        MODE_STOPLEVEL ) )                  {                      // 如果赢利点超过追踪止损点,                      if(NormalizeDouble( Bid - OrderOpenPrice(),                          Digits ) >                          NormalizeDouble(TrailingStop*Point,                            Digits ) )                      {                          // 如果新的止损水平超过当前仓位的水平                           // (或者如果仓位没有止损),                          if(NormalizeDouble(Bid -                              TrailingStop*Point, Digits ) >                              OrderStopLoss() || OrderStopLoss()  0 )                    {                      if ( !OrderDelete( BuyStopOrder ) )                        {                          Alert("OrderDelete 错误 #",                                 GetLastError());                          return(-1);                      }                    }                  if(TrailingStop > MarketInfo( Symbol(),                      MODE_STOPLEVEL ) )                    {                    if(NormalizeDouble(OrderOpenPrice() - Ask,                     Digits) > NormalizeDouble(TrailingStop*Point,                     Digits ) )                        {                        if(NormalizeDouble(Ask + TrailingStop*Point,                            Digits )  0 )        { _StopLossLevel = NormalizeDouble( _OpenPriceLevel -                          StopLoss*Point, Digits ); }        else      { _StopLossLevel = 0.0; }         if ( TakeProfit > 0 )        { _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel +                            TakeProfit*Point, Digits ); }        else      { _TakeProfitLevel = 0.0; }         if ( OrderSend ( Symbol(), OP_BUYSTOP, Lot, _OpenPriceLevel,           5, _StopLossLevel, _TakeProfitLevel, "",            _MagicNumber )  0 )        { _StopLossLevel = NormalizeDouble( _OpenPriceLevel +                          StopLoss*Point, Digits ); }        else      { _StopLossLevel = 0.0; }         if ( TakeProfit > 0 )        { _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel -                            TakeProfit*Point, Digits ); }        else      { _TakeProfitLevel = 0.0; }         if ( OrderSend ( Symbol(), OP_SELLSTOP, Lot, _OpenPriceLevel,            5, _StopLossLevel,                      _TakeProfitLevel, "", _MagicNumber ) = 0; z -- )        {          if ( !OrderSelect( z, SELECT_BY_POS ) )            {            _GetLastError = GetLastError();            Print("OrderSelect(", z, ",SELECT_BY_POS) - Error #",                     _GetLastError );            continue;          }          if ( OrderMagicNumber() == magic && OrderSymbol() ==                 Symbol() )          {            switch ( OrderType() )              {              case OP_BUY:               _BuyTicket     = OrderTicket();               _BuyLots       = NormalizeDouble( OrderLots(), 1 );               _BuyOpenPrice  = NormalizeDouble( OrderOpenPrice(),                                                 Digits );               _BuyStopLoss   = NormalizeDouble( OrderStopLoss(),                                                  Digits );               _BuyTakeProfit = NormalizeDouble( OrderTakeProfit(),                                                 Digits );               _BuyOpenTime   = OrderOpenTime();               _BuyProfit     = NormalizeDouble( OrderProfit(), 2 );               _BuySwap       = NormalizeDouble( OrderSwap(), 2 );               _BuyCommission = NormalizeDouble( OrderCommission(),                                   
              2
);               _BuyComment    = OrderComment();               break;             case OP_SELL:               _SellTicket     = OrderTicket();               _SellLots       = NormalizeDouble( OrderLots(), 1 );               _SellOpenPrice  = NormalizeDouble( OrderOpenPrice(),                                                  Digits );               _SellStopLoss   = NormalizeDouble( OrderStopLoss(),                                                  Digits );               _SellTakeProfit = NormalizeDouble( OrderTakeProfit(),                                                  Digits );               _SellOpenTime   = OrderOpenTime();               _SellProfit     = NormalizeDouble( OrderProfit(), 2 );               _SellSwap       = NormalizeDouble( OrderSwap(), 2 );               _SellCommission = NormalizeDouble( OrderCommission(),                                                  2 );               _SellComment    = OrderComment();               break;             case OP_BUYSTOP:               _BuyStopTicket     = OrderTicket();               _BuyStopLots       = NormalizeDouble( OrderLots(), 1 );               _BuyStopOpenPrice  = NormalizeDouble( OrderOpenPrice(),                                                     Digits );               _BuyStopStopLoss   = NormalizeDouble( OrderStopLoss(),                                                     Digits );               _BuyStopTakeProfit = NormalizeDouble( OrderTakeProfit(),                                                     Digits );               _BuyStopOpenTime   = OrderOpenTime();               _BuyStopComment    = OrderComment();               _BuyStopExpiration = OrderExpiration();               break;            case OP_SELLSTOP:               _SellStopTicket     = OrderTicket();               _SellStopLots       = NormalizeDouble( OrderLots(), 1 );               _SellStopOpenPrice  = NormalizeDouble( OrderOpenPrice(),                                                      Digits );               _SellStopStopLoss   = NormalizeDouble( OrderS
topLoss(),     
                                                 Digits );               _SellStopTakeProfit = NormalizeDouble( OrderTakeProfit(),                                                      Digits );               _SellStopOpenTime   = OrderOpenTime();               _SellStopComment    = OrderComment();               _SellStopExpiration = OrderExpiration();               break;            case OP_BUYLIMIT:               _BuyLimitTicket     = OrderTicket();               _BuyLimitLots       = NormalizeDouble( OrderLots(), 1 );               _BuyLimitOpenPrice  = NormalizeDouble( OrderOpenPrice(),                                                      Digits );               _BuyLimitStopLoss   = NormalizeDouble( OrderStopLoss(),                                                      Digits );               _BuyLimitTakeProfit = NormalizeDouble( OrderTakeProfit(),                                                      Digits );               _BuyLimitOpenTime   = OrderOpenTime();   
作者: chenhuade6000    时间: 2018-1-11 03:53
资金管理与下单手数量的关系写法收集  
2010-06-02 10:29:56|  分类: 默认分类 |字号 订阅
//---------------------------------------------------------------------------------------

double Lots()
   {
   lots =NormalizeDouble(AccountEquity()*资金百分比/100/1000,1);               // 计算标准手总数
   double 最小手数 = MarketInfo(Symbol(), MODE_MINLOT);                         // 最小标准手
   if ( lots== 0 )  lots = 最小手数;                                                                      // 如果计算的手数为0(因资金百分比未赋值),则采用最小规定手数
   return(lots);                                                                                                  // 返回手数计算结果值
   }

#property copyright "laoyee"
#property link      "qq:921795"
//指标在主图显示
#property indicator_chart_window
extern color TextColor=Red;
int cnt;
string TextBarString,DotBarString,HLineBarString,VLineBarString;
int init()
   {
      return(0);
   }
int deinit()
   {
      Comment("");
      ObjectsDeleteAll(0);
      return(0);
   }
int start()
   {
      iMain();
      return(0);
   }
void iMain()
   {
      //定义统计变量
      int BuyHistoryOrders,SellHistoryOrders,ProfitHistoryOrders,HistoryOrderTotal;//买入历史订单、卖出历史订单、盈利历史订单、历史订单总数
      int WinHistory,LossHistory; //历史盈利/亏损单累计
      double TotalHistoryLots;//历史交易总手数
      double TotalHistoryProfit,TotalHistoryLoss;//盈利总数、亏损总数变量
      color myLineColor=Blue;
      iDisplayInfo("Author", "[联系老易 QQ:921795]",0,210,1,7,"",Gray);
      iDisplayInfo("Times","动态报价时间:"+TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS)+" 星期"+DayOfWeek(),0,4,15,9,"Verdana",TextColor);
      //遍历历史订单,计算相关信息
      HistoryOrderTotal=OrdersHistoryTotal(); //统计历史订单总数
      for (cnt=0;cnt0)  myLineColor=Blue;
                        if (OrderProfit()0)  myLineColor=Blue;
                        if (OrderProfit()0)
                     {
                        WinHistory=WinHistory+1;
                        TotalHistoryProfit=TotalHistoryProfit+OrderProfit();
                     }
                  if (OrderProfit()0)  myLineColor=Blue;
                  if (OrderProfit()myMaxLots)
         {
            iDisplayInfo("Waring", "持仓量已超过警戒线,请慎重下单!",0,4,110,12,"黑体",Olive);
         }
         else iDisplayInfo("Waring", "",0,4,110,12,"",Olive);
      return(0);
   }
/*
函   
数:在屏幕上显示文字标签
输入参数:string LableName 标签名称,如果显示多个文本,名称不能相同
          string LableDoc 文本内容
          int Corner 文本显示角
          int LableX 标签X位置坐标
          int LableY 标签Y位置坐标
          int DocSize 文本字号
          string DocStyle 文本字体
          color DocColor 文本颜色
输出参数:在指定的位置(X,Y)按照指定的字号、字体及颜色显示指定的文本
算法说明:
*/
void iDisplayInfo(string LableName,string LableDoc,int Corner,int LableX,int LableY,int DocSize,string DocStyle,color DocColor)
   {
      if (Corner == -1) return(0);
      ObjectCreate(LableName, OBJ_LABEL, 0, 0, 0);
      ObjectSetText(LableName, LableDoc, DocSize, DocStyle,DocColor);
      ObjectSet(LableName, OBJPROP_CORNER, Corner);
      ObjectSet(LableName, OBJPROP_XDISTANCE, LableX);
      ObjectSet(LableName, OBJPROP_YDISTANCE, LableY);
   }
/*
函    数:两点间连线(主图)
输入参数:string myLineName  线段名称
          int myFirstTime  起点时间
          int myFirstPrice  起点价格
          int mySecondTime  终点时间
          int mySecondPrice  终点价格
          int myLineStyle  线型 0-实线 1-断线 2-点线 3-点划线 4-双点划线
          color myLineColor 线色
输出参数:在指定的两点间连线
算法说明:
*/
void iTwoPointsLine(string myLineName,int myFirstTime,double myFirstPrice,int mySecondTime,double mySecondPrice,int myLineStyle,color myLineColor)
   {
      ObjectCreate(myLineName,OBJ_TREND,0,myFirstTime,myFirstPrice,mySecondTime,mySecondPrice);//确定两点坐标
      ObjectSet(myLineName,OBJPROP_STYLE,myLineStyle); //线型
      ObjectSet(myLineName,OBJPROP_COLOR,myLineColor); //线色
      ObjectSet(myLineName,OBJPROP_WIDTH, 1); //线宽
      ObjectSet(myLineName,OBJPROP_BACK,false);
      ObjectSet(myLineName,OBJPROP_RAY,false);
   }
   
/*
函    数:标注符号和画线、文字
参数说明:string myType 标注类型:Dot画点、HLine画水平线、VLine画垂直线、myString显示文字
          int myBarPos 指定蜡烛坐标
          double myPrice 指定价格坐标
          color myColor 符号颜色
          int mySymbol 符号代码,108为
圆点
          string myString 文字内容,在指定的蜡烛位置显示文字
函数返回:在指定的蜡烛和价格位置标注符号或者画水平线、垂直线
*/
void iDrawSign(string myType,int myBarPos,double myPrice,color myColor,int mySymbol,string myString,int myDocSize)
      {
         if (myType=="Text")
            {
               TextBarString=myType+Time[myBarPos];
               ObjectCreate(TextBarString,OBJ_TEXT,"",Time[myBarPos],myPrice);
               ObjectSet(TextBarString,OBJPROP_COLOR,myColor);//颜色
               ObjectSet(TextBarString,OBJPROP_FONTSIZE,myDocSize);//大小
               ObjectSetText(TextBarString,myString);//文字内容
               ObjectSet(TextBarString,OBJPROP_BACK,true);
            }
         if (myType=="Dot")
            {
               DotBarString=myType+Time[myBarPos];
               ObjectCreate(DotBarString,OBJ_ARROW,0,Time[myBarPos],myPrice);
               ObjectSet(DotBarString,OBJPROP_COLOR,myColor);
               ObjectSet(DotBarString,OBJPROP_ARROWCODE,mySymbol);
               ObjectSet(DotBarString,OBJPROP_BACK,false);
            }
         if (myType=="HLine")
            {
               HLineBarString=myType+Time[myBarPos];
               ObjectCreate(HLineBarString,OBJ_HLINE,0,Time[myBarPos],myPrice);
               ObjectSet(HLineBarString,OBJPROP_COLOR,myColor);
               ObjectSet(HLineBarString,OBJPROP_BACK,false);
            }
         if (myType=="VLine")
            {
               VLineBarString=myType+Time[myBarPos];
               ObjectCreate(VLineBarString,OBJ_VLINE,0,Time[myBarPos],myPrice);
               ObjectSet(VLineBarString,OBJPROP_COLOR,myColor);
               ObjectSet(VLineBarString,OBJPROP_BACK,false);
            }
     }
========================================================================================================
  if (资管模式  100)  使用手数=100;
        }
        else  使用手数=手数;
  if (资管模式 >0)   {
      使用手数=MathCeil(AccountBalance()*资管风险/10000)/10;
      /*if (使用手数 >1)
        {
        使用手数=MathCeil(使用手数);
        }
      if (使用手数 100)
        {
        使用手数 =100;
        }
    }
  ===================================================================================================
     lot=NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000.0,1);    //手数赋值为 将可用保证金乘以最大风险率/1000后精确化
  ===================================================================================================
lot= NormalizeDouble(MaximumRisk * AccountBalance() /AccountLeverage(), 1);     //开仓量计算
if(lotmaxLots)  lot=maxLots;
========================================================================================================
if( 标准账户==1 ) {                                                      
   if(资管 != 0)
      lotsi =MathCeil(AccountBalance() *风险 /10000) ;
   else lotsi =手数;
     }
else {
   if(资管 != 0)
     lotsi =MathCeil(AccountBalance() *风险 /10000) /10 ;
   else lotsi =手数; //迷你仓计算
     }
if( lotsi >100 )  lotsi =100;                                                        //手数最大限制为100手
//+------------------------------------------------------------------+

double LotsOptimized()//函数目的,根据要求 计算出订单交易量
  {
   double lot=Lots;
   int    orders= HistoryTotal();                                    // history orders total 历史出场订单的个数
   int    losses=0;                                                  // number of losses orders without a break
   lot= NormalizeDouble(AccountFreeMargin()*MaximumRisk/1000,1);   //通过风险系数的计算获得当前入场单应该采用的交易量
   // lot=NormalizeDouble(AccountFreeMargin()*最大风险*交易倍数/100000,1);// 减少因子存在
   if(DecreaseFactor>0)
     {
      for(int i=orders-1; i>=0; i--)
        {
         if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false)     //循环查询出场单队列
           { Print("Error in history!"); break; }//如果没有历史单子子,则
         if(OrderSymbol()!=Symbol() || OrderType()>OP_SELL) continue;           //
         if(OrderProfit()>0) break;
         if(OrderProfit()1) lot= NormalizeDouble(lot-lot*losses/DecreaseFactor,1);       //如果亏损额大于1,则下一入场单的交易量修正为新的计算结果。
     }
   if(lotOrderOpenTime())
                       {
                        temptime= OrderOpenTime();
                        tick= OrderTicket();
                       }
                    }
                 }
               return(tick);
      case 2:
               tick= 0;
               temptime= TimeCurrent();
               for(i=0; iOrderOpenTime())
                        {
                         temptime= OrderOpenTime();
                         tick= OrderTicket();
                        }
                     }
                  }
                return(tick);
     }
  }

datetime Expiration 持单有效时间的理解
此参数是以秒为单位。下单时用当前的时间(服务器时间或本地时间)加上你计划的期限(以秒计算)即可,
例如:
OrderSend(…….,TimeCurrent()+Period()*60,..);
假如当前的图表是日线图,则该挂单就会在24小时后失效

=================================================================================================
时间限制
if (TimeDayOfWeek(CurTime()) == 1)
  {
  if (TimeHour(CurTime()) =0;  index--)
   if ( OrderSelect(index, SELECT_BY_POS)   &&OrderMagicNumber()==MagicNumber  &&OrderSymbol()==Symbol() )
    {
    ticket[count]= OrderTicket();                  
    price[count] = OrderOpenPrice();
    oot[count]   = OrderOpenTime();
    count++;
    }
   
int order[100];                                                             // 插入分类
for (int kk=0;   kk0 && oot[order[ii-1]] > oot[kk];  ii--)
       { order[ii]=order[ii-1];}                                            // kk   oot[kk] order[kk]   oot[order[kk]]
                                                                            // 0    3.      1           1.
    order[ii]=kk;                                                           // 1    1.      2           2.
}                                                                           // 2    2.      0           3.
// ticket[order[0]]        is the oldest
// ticket[order[count-1]]  is the latest
====================================================================================================
[Script] 打印各种订单类型的总数

extern int ExpertMagicNumber=123456;
//+-------------- 计算所有的订单类型 子函数() ----------------------------------------------------+
int MyOrdersTotal(int  buyNumber, int sellNumber,int buyLimitNumber
   ,int sellLimitNumber,int  buyStopNumber, int sellStopNumber, int MagicNumber=0 )  //
   {
   int res,
       orderType;
//----
   buyNumber=0;
   sellNumber=0;
   buyLimitNumber=0;
   sellLimitNumber=0;
   buyStopNumber=0;
   sellStopNumber=0;
   for (int i=OrdersTotal()-1;  i>=0;  i--)
      if (OrderSelect(i, SELECT_BY_POS))
         {
         if (MagicNumber==0 || (OrderMagicNumber()==MagicNumber && MagicNumber!=0))    //
            {
            switch(OrderType())
               {
               case OP_BUY: buyNumber++;break;
               case OP_SELL: sellNumber++;break;
               case OP_BUYLIMIT: buyLimitNumber++;break;
               case OP_SELLLIMIT: sellLimitNumber++;break;
               case OP_BUYSTOP: buyStopNumber++;break;
               case OP_SELLSTOP: sellStopNumber++;break;
               }
            }
         }
//----
   res=buyNumber+sellNumber+buyLimitNumber+sellLimitNumber+buyStopNumber+sellStopNumber;
   return(res);   
   }
//+----------------脚本程序主函数  --------------------------------------------------+
int start()
  {
   int buys,  sells,  buyLs,  sellLs,  buySts,  sellSts;
   if (MyOrdersTotal(buys,sells,buyLs,sellLs,buySts,sellSts,ExpertMagicNumber)>0)
   Print("买单=",buys," 卖单=",sells,"  限价买单=",buyLs,"  限价卖单=",sellLs," 突破价买单=",buySts," 突破价卖单=",sellSts);
   return(0);
  }
====================================================================================================
被止损或止赢的检查返回结果的程序段
start()
{
    OrderEvents(MAGIC); //调用该子函数
...
}
//------------------------------------在历史中分别查找止损单和赢利单 子函数--------------------------------+
void OrderEvents( int magic ) {  
    static datetime lastCheck;
    for( int o = 0;  o  lastCheck )
            if( OrderClosePrice() == OrderStopLoss() )                    //(是否忽略了大于小于的情况未知)
                OnStopLoss(OrderTicket());
            else if( OrderClosePrice() == OrderTakeProfit() )           //(是否忽略了大于小于的情况未知)
                OnTakeProfit(OrderTicket());
    }
    lastCheck = TimeCurrent();
}

//--------------
void OnStopLoss( int ticket )
{
...
}
//---------------
void OnTakeProfit( int ticket )
{
...
}






//==========================================================
/*
start() {
    检查订单被止子函数(MAGIC);
    if(类型==OP_BUY ||类型==OP_BUYLIMIT||类型==OP_BUYSTOP) OP=买;
    if(类型==OP_BUY ||类型==OP_BUYLIMIT||类型==OP_BUYSTOP) OP=卖;
...
}
void 检查订单被止子函数( int 标识符 ) {
    static datetime 最后检查时间;
    for( int 个 = 0; 个  最后检查时间 )
               
            if(OP==买)
               if( OrderClosePrice() = OrderTakeProfit() )
                被止赢价(OrderTicket());
            if(OP==卖)
                if( OrderClosePrice() >= OrderTakeProfit() )
                被止损价(OrderTicket());
                else if( OrderClosePrice()
}
void 被止赢价( int ticket ) {
...
}
*/
====================================================================================================

    if(已成买单数>0){
      for(i=0; i=0; i--){
   OrderSelect(i, SELECT_BY_POS,MODE_HISTORY);
   if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic){
      //--买单时
      if(OrderType()==OP_BUY && OrderProfit()>0)
         历史最后单结果= "买赢";
      if(OrderType()==OP_BUY && OrderProfit()0)
         历史最后单结果= "卖赢";
      if(OrderType()==OP_SELL && OrderProfit()=0; i--){
   OrderSelect(i, SEL_BY_POS, MODE_HISTORY);
   if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic){
      if(OrderProfit()=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderSymbol()==Symbol()){
      for(int x=0; x=oct[x]) {      
            for(int(y=x; y0)
      return(1);
   return(0);
  }
//---------------------------------------------+
   int    Prev_Orders = -1;                  //place this before the start section
//=======This goes in section 2
   if(Prev_OrdersPrev_Orders)
      int MN= Get_Magic_Num());  //history orders has increased, so an order must have closed>>>>> lets get it's Magic Number & do something with it
   if(MN0 && OrderSymbol()==Symbol() && OrderMagicNumber()==16384){
   for(int cnnt=Bistory; cnnt>=1; cnnt--){
      if(OrderSelect(OrdersHistoryTotal()-cnnt,SELECT_BY_POS,MODE_HISTORY) && OrderProfit()>=0)
         LosCount=0;
      if(OrderSelect(OrdersHistoryTotal()-cnnt,SELECT_BY_POS,MODE_HISTORY) && OrderProfit()=0; i--){
      OrderSelect(i, SELECT_BY_POS,MODE_HISTORY);   
      if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic){
         if(OrderType()==OP_BUY || OP_BUYLIMIT || OP_BUYSTOP || OP_SELL || OP_SELLLIMIT || OP_SELLSTOP && OrderProfit()=0; i--){
      if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
         continue;
      int type= OrderType();
      //--initial balance not considered
      if(i==0 && type==OP_BALANCE)
         break;
      if(type==OP_BUY || type==OP_SELL){
         //--计算浮赢
         double profit= OrderProfit()+OrderCommission()+OrderSwap();
         //---- and decrease balance
         initial_deposit -= profit;
        }
      if(type==OP_BALANCE || type==OP_CREDIT)
         initial_deposit -= OrderProfit();
     }
   return(initial_deposit);
  }
  
  
  
  2010年08月29日 三种建仓的简洁函数写法  
2010-08-29 14:23:02|  分类: 默认分类 |字号 订阅
每个智能交易程序里都有一段代码是控制建仓的。它在所有的定单中不断搜索,通过信息选择仓位,然后进行修改和关闭。这段代码看上去都差不多,并且往往具有相同的功能。这就是为什么这段经常被重复的代码可以从程序中提取出来成为函数,从而使程序更易写更简洁。
首先,我们按功能把任务分成三个步骤 — 这三个步骤其实是三种智能交易程序:
智能交易程序在同一时间只能新建一个仓位
智能交易程序在同一时间可以新建每个类型的一个仓位(比如, 多头和空头的仓位)
智能交易程序可以同时新建多个仓位
2. 一个仓位
只新建一个仓位有许多中策略。这种控制代码块非常简单,但写出来也会耗费一定的时间和精力。
举一个简单的例子,一个来自于 MACD 线交叉点(信号线和基础线)的建仓信号,简化它的控制代码块,程序如下:
extern int  _MagicNumber = 1122;       int start()  {      //---- 记住指标值做分析数据      double MACD_1 = iMACD(Symbol(), 0, 12, 26, 9, PRICE_CLOSE,                            MODE_MAIN, 1 );      double MACD_2 = iMACD(Symbol(), 0, 12, 26, 9, PRICE_CLOSE,                            MODE_MAIN, 2 );         int _GetLastError = 0, _OrdersTotal = OrdersTotal();      //---- 在开仓位置搜索        for ( int z = _OrdersTotal - 1; z >= 0; z -- )        {  // 如果在搜索中生成错误,转至下一个仓位          if ( !OrderSelect( z, SELECT_BY_POS ) )            {            _GetLastError = GetLastError();            Print("OrderSelect( ", z, ", SELECT_BY_POS ) - 错误 #",                  _GetLastError );              continue;          }       // 如果当前的货币对没有开仓,   // 忽略过          if ( OrderSymbol() != Symbol() ) continue;       // 如果 MagicNumber不等于_MagicNumber,   // 忽略这个仓位          if ( OrderMagicNumber() != _MagicNumber ) continue;             //---- 如果BUY舱位开仓,            if ( OrderType() == OP_BUY )          {              //---- 如果MACD 遇到下降的零线,                if(NormalizeDouble(MACD_1, Digits + 1) = 0.0)                {                  //---- 平仓                  if(!OrderClose( OrderTicket(), OrderLots(),                      Bid, 5, Green))                    {                     _GetLastError = GetLastError();                     Alert("错误OrderClose 鈩?", _GetLastError);                     return(-1);                  }                }  // 如果信号线没有改变,退出:    // 开新仓位过早              else              { return(0); }            }          //---- 如果 SELL 仓位开仓,          if ( OrderType() == OP_SELL )            {              //---- 如果 MACD 遇到上升的零线              if(NormalizeDouble(MACD_1, Digits + 1) >  0.0 &&                  NormalizeDouble(MACD_2, Digits + 1 )   0.0 &&             NormalizeDouble( MACD_2, Digits + 1 ) = 0.0)        {          //---- open a SELL position          if(OrderSend( Symbol(), OP_SELL, 0.1, Bid, 5, 0.0, 0.0,             "MACD_test",                 _MagicNumber, 0, Red ) = 0; z -- )        {          if ( !OrderSelect( z, SELECT_BY_POS ) )            {            _GetLastError = GetLastError();            Print("OrderSelect( ", z, ", SELECT_BY_POS ) -错误#",                   _GetLastError );            continue;          }            if(OrderMagicNumber() == magic && OrderSymbol() ==              Symbol())            {            _Ticket    = OrderTicket();            _Type      = OrderType();            _Lots      = NormalizeDouble( OrderLots(), 1 );            _OpenPrice = NormalizeDouble( OrderOpenPrice(), Digits);            _StopLoss = NormalizeDouble( OrderStopLoss(), Digits);            _TakeProfit = NormalizeDouble( OrderTakeProfit(), Digits);            _OpenTime   = OrderOpenTime();            _Profit     = NormalizeDouble( OrderProfit(), 2 );            _Swap       = NormalizeDouble( OrderSwap(), 2 );            _Commission = NormalizeDouble( OrderCommission(), 2 );            _Comment    = OrderComment();            _Expiration = OrderExpiration();            return;          }        }  }
如你所见,这非常简单: 一共 11 个变量,每个都储存仓位的相关信息(ticket #, type, lot size, 等等). 当函数开始运行时,这些变量被归零。作为全局变量这是必需的。函数被调用时变量也可以不归零,但我们需要的不是先前的信息,我们需要的是最近的。然后所有的仓位会以标准的方式被搜索,一旦获得需要的信号和MagicNumber 值,信息将被存储在相应的变量中。
现在我们将函数用到智能交易程序中:
extern int  _MagicNumber = 1122;     #include      int start()    {      int _GetLastError = 0;        // 记住开仓的参量(如果可用)      OneOrderInit( _MagicNumber );         //---- 记住指标值用作分析        double MACD_1 = iMACD(Symbol(), 0, 12, 26, 9, PRICE_CLOSE,                             MODE_MAIN, 1 );      double MACD_2 = iMACD(Symbol(), 0, 12, 26, 9, PRICE_CLOSE,                               MODE_MAIN, 2 );         // 现在,代替在仓位中的搜索       // 存在开仓:      if ( _Ticket > 0 )        {          //----如果BUY 仓位开仓,          if ( _Type == OP_BUY )            {              //---- 如果MACD 遇到下降的零线,               if(NormalizeDouble( MACD_1, Digits + 1 ) = 0.0)                {                  //---- 平仓                  if(!OrderClose( _Ticket, _Lots, Bid, 5, Green))                    {                    _GetLastError = GetLastError();                    Alert( "错误 OrderClose 鈩?", _GetLastError);                    return(-1);                  }                }              // 如果信号没有改变,退出:               // 开新仓位过早            else return(0);          }          //----如果 SELL 仓位开仓,            if ( _Type == OP_SELL )          {              //---- 如果MACD 遇到上升的零线                if(NormalizeDouble( MACD_1, Digits + 1 ) >  0.0 &&                  NormalizeDouble( MACD_2, Digits + 1 )   0.
0 &&          N
ormalizeDouble( MACD_2, Digits + 1 ) = 0.0    )        {          //---- 开SELL仓位          if(OrderSend(Symbol(), OP_SELL, 0.1, Bid, 5, 0.0, 0.0,             "CrossMACD",                 _MagicNumber, 0, Red ) = 0; z -- )        {          // 如果在搜索中生成错误,            // 转至下一个仓位          if ( !OrderSelect( z, SELECT_BY_POS ) )            {            _GetLastError = GetLastError();            Print("OrderSelect(", z, ", SELECT_BY_POS) - Error #",                 _GetLastError );            continue;          }       // 如果当前货币对没有开仓仓位,忽略它   if ( OrderSymbol() != Symbol() ) continue;       // 如果MagicNumber 不等于 _MagicNumber,   // 忽略这个仓位          if ( OrderMagicNumber() != _MagicNumber ) continue;             // 取决于仓位类型,          // 改变变量值:            switch ( OrderType() )          {            case OP_BUY:      BuyOrder      = OrderTicket(); break;            case OP_SELL:     SellOrder     = OrderTicket(); break;            case OP_BUYSTOP:  BuyStopOrder  = OrderTicket(); break;            case OP_SELLSTOP: SellStopOrder = OrderTicket(); break;          }        }         //---- 如果我们有两个挂单交易,退出      //---- 等待他们开启      if ( BuyStopOrder > 0 && SellStopOrder > 0 ) return(0);         // 在全部定单中第二次搜索       // 现在运行它们:        _OrdersTotal = OrdersTotal();      for ( z = _OrdersTotal - 1; z >= 0; z -- )        {          // 如果在仓位搜索中生成错误,          // 转至下一个仓位          if ( !OrderSelect( z, SELECT_BY_POS ) )            {              _GetLastError = GetLastError();              Print("OrderSelect
(", z, ", SELEC
T_BY_POS) - 错误 #",                     _GetLastError );              continue;          }               // 如果对于当前的货币对没有开仓          // 忽略它          if ( OrderSymbol() != Symbol() ) continue;             // 如果 MagicNumber 不等于 _MagicNumber,           // 忽略这个仓位            if ( OrderMagicNumber() != _MagicNumber ) continue;             // 取决于仓位的类型,           // 改变变量值:            switch ( OrderType() )          {              //----如果BUY仓位开仓,              case OP_BUY:              {                    // 如果 SellStop定单还没有删除,                   // 删除:                  if ( SellStopOrder > 0 )                  {                      if ( !OrderDelete( SellStopOrder ) )                    {                        Alert(OrderDelete Error #", GetLastError());                      return(-1);                    }                    }                  // 检测止损被移动:                  // 如果追踪止损的大小不是很小,                  if(TrailingStop > MarketInfo( Symbol(),                        MODE_STOPLEVEL ) )                  {                      // 如果赢利点超过追踪止损点,                      if(NormalizeDouble( Bid - OrderOpenPrice(),                          Digits ) >                          NormalizeDouble(TrailingStop*Point,                            Digits ) )                      {                          // 如果新的止损水平超过当前仓位的水平                           // (或者如果仓位没有止损),                          if(NormalizeDouble(Bid -                              TrailingStop*Point, Digits ) >                              OrderStopLoss() || OrderStopLoss()  0 )                    {                      if ( !OrderDelete( BuyStopOrder ) )                        {                          Alert("OrderDelete 错误 #",                                 GetLastError());                          return(-1);                      }                    }                  if(TrailingStop > MarketInfo( Symbol(),                      MODE_STOPLEVEL ) )                    {                    if(NormalizeDouble(OrderOpenPrice() - Ask,                     Digits) > NormalizeDouble(TrailingStop*Point,                     Digits ) )                        {                        if(NormalizeDouble(Ask + TrailingStop*Point,                            Digits )  0 )        { _StopLossLevel = NormalizeDouble( _OpenPriceLevel -                          StopLoss*Point, Digits ); }        else      { _StopLossLevel = 0.0; }         if ( TakeProfit > 0 )        { _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel +                            TakeProfit*Point, Digits ); }        else      { _TakeProfitLevel = 0.0; }         if ( OrderSend ( Symbol(), OP_BUYSTOP, Lot, _OpenPriceLevel,           5, _StopLossLevel, _TakeProfitLevel, "",            _MagicNumber )  0 )        { _StopLossLevel = NormalizeDouble( _OpenPriceLevel +                          StopLoss*Point, Digits ); }        else      { _StopLossLevel = 0.0; }         if ( TakeProfit > 0 )        { _TakeProfitLevel = NormalizeDouble( _OpenPriceLevel -                            TakeProfit*Point, Digits ); }        else      { _TakeProfitLevel = 0.0; }         if ( OrderSend ( Symbol(), OP_SELLSTOP, Lot, _OpenPriceLevel,            5, _StopLossLevel,                      _TakeProfitLevel, "", _MagicNumber ) = 0; z -- )        {          if ( !OrderSelect( z, SELECT_BY_POS ) )            {            _GetLastError = GetLastError();            Print("OrderSelect(", z, ",SELECT_BY_POS) - Error #",                     _GetLastError );            continue;          }          if ( OrderMagicNumber() == magic && OrderSymbol() ==                 Symbol() )          {            switch ( OrderType() )              {              case OP_BUY:               _BuyTicket     = OrderTicket();               _BuyLots       = NormalizeDouble( OrderLots(), 1 );               _BuyOpenPrice  = NormalizeDouble( OrderOpenPrice(),                                                 Digits );               _BuyStopLoss   = NormalizeDouble( OrderStopLoss(),                                                  Digits );               _BuyTakeProfit = NormalizeDouble( OrderTakeProfit(),                                                 Digits );               _BuyOpenTime   = OrderOpenTime();               _BuyProfit     = NormalizeDouble( OrderProfit(), 2 );               _BuySwap       = NormalizeDouble( OrderSwap(), 2 );               _BuyCommission = NormalizeDouble( OrderCommission(),                                   
              2
);               _BuyComment    = OrderComment();               break;             case OP_SELL:               _SellTicket     = OrderTicket();               _SellLots       = NormalizeDouble( OrderLots(), 1 );               _SellOpenPrice  = NormalizeDouble( OrderOpenPrice(),                                                  Digits );               _SellStopLoss   = NormalizeDouble( OrderStopLoss(),                                                  Digits );               _SellTakeProfit = NormalizeDouble( OrderTakeProfit(),                                                  Digits );               _SellOpenTime   = OrderOpenTime();               _SellProfit     = NormalizeDouble( OrderProfit(), 2 );               _SellSwap       = NormalizeDouble( OrderSwap(), 2 );               _SellCommission = NormalizeDouble( OrderCommission(),                                                  2 );               _SellComment    = OrderComment();               break;             case OP_BUYSTOP:               _BuyStopTicket     = OrderTicket();               _BuyStopLots       = NormalizeDouble( OrderLots(), 1 );               _BuyStopOpenPrice  = NormalizeDouble( OrderOpenPrice(),                                                     Digits );               _BuyStopStopLoss   = NormalizeDouble( OrderStopLoss(),                                                     Digits );               _BuyStopTakeProfit = NormalizeDouble( OrderTakeProfit(),                                                     Digits );               _BuyStopOpenTime   = OrderOpenTime();               _BuyStopComment    = OrderComment();               _BuyStopExpiration = OrderExpiration();               break;            case OP_SELLSTOP:               _SellStopTicket     = OrderTicket();               _SellStopLots       = NormalizeDouble( OrderLots(), 1 );               _SellStopOpenPrice  = NormalizeDouble( OrderOpenPrice(),                                                      Digits );               _SellStopStopLoss   = NormalizeDouble( OrderS
topLoss(),     
                                                 Digits );               _SellStopTakeProfit = NormalizeDouble( OrderTakeProfit(),                                                      Digits );               _SellStopOpenTime   = OrderOpenTime();               _SellStopComment    = OrderComment();               _SellStopExpiration = OrderExpiration();               break;            case OP_BUYLIMIT:               _BuyLimitTicket     = OrderTicket();               _BuyLimitLots       = NormalizeDouble( OrderLots(), 1 );               _BuyLimitOpenPrice  = NormalizeDouble( OrderOpenPrice(),                                                      Digits );               _BuyLimitStopLoss   = NormalizeDouble( OrderStopLoss(),                                                      Digits );               _BuyLimitTakeProfit = NormalizeDouble( OrderTakeProfit(),                                                      Digits );               _BuyLimitOpenTime   = OrderOpenTime();   
作者: henryliu    时间: 2018-1-11 04:05
有源码是吗,研究一下。以前见过一个跟这类似的曲线,不知这个ea的策略是否跟以前见的相同。
作者: fengyiyang    时间: 2018-1-11 04:19
传说中的沙发
作者: bull    时间: 2018-1-11 05:33
漂亮的线
作者: wytb369    时间: 2018-1-11 06:23
顶顶顶顶
作者: Scalper    时间: 2018-1-11 07:32
顶顶顶顶
作者: 平和心态    时间: 2018-1-11 08:18
谢谢分享。。
作者: moxian    时间: 2018-1-11 09:18
金币啊啊啊啊啊啊啊啊啊啊啊啊啊
作者: moxian    时间: 2018-1-11 10:51
金币啊啊啊啊啊啊啊啊啊啊啊啊啊
作者: 终南隐者    时间: 2018-1-11 11:29
确实漂亮!
作者: 终南隐者    时间: 2018-1-11 11:49
得请牛版主研究
[attach]12597[/attach]

作者: yang05888    时间: 2018-1-11 12:51
得请牛版主研究
作者: yang05888    时间: 2018-1-11 13:31
得请牛版主研究
作者: 我的宝马    时间: 2018-1-11 14:30
谢谢分享。。
作者: 74007    时间: 2018-1-11 15:35
谢谢楼主分享
作者: qq123    时间: 2018-1-11 16:14
收获收获收获




欢迎光临 顺水外汇EA交易网MT4 (http://waterforex.com/) Powered by Discuz! X3.2