自动化交易机器人Beta猪

//+------------------------------------------------------------------+
//|                                          BetaPig.mq4 |
//|                                                                                     |
//|                            http://product.dangdang.com/23837128.html |
//+------------------------------------------------------------------+
#property copyright "BetaPig"
#property link      "http://product.dangdang.com/23837128.html"
#property version   "1.00"
#property strict

int magic = 114049717;
int selfMagic =  114049717;
int orders = 0;
datetime tLastOpen = 0;
double pPoint = Point();

double pLots = 0.05;
 
double pLastOpenBuy = 0.0;
double pLastOpenSell = 0.0;
int addedTimes = 0;
int longAddedTimes = 0;
int shortAddedTimes = 0;
datetime tLastOpenFirst = 0;

double lotsLastAdded = 0.0;
double lotsLastAddedAdverse = 0.0;
 input double lots = 1;  //手动输入下单手数
 int slp = 3;   //滑点
 
input int dStl = 30; //止损点数
input int dTf = 2000; //止盈点数
 
int pSlp = slp;
int OnInit()
  {
   //test();
   if(Digits == 5 || Digits == 3){  
      pPoint =  Point()* 10.0;     
      pSlp = slp*10;
    }
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }

void OnTick()
  {
   posClose();
   posOpen();
   
  }
input string indiName = "MACD22";//macd指标文件名称
double iMacd(int tf,int line, int i){
   return iCustom(NULL,tf,indiName,InpFastEMA,InpSlowEMA,InpSignalEMA,line,i);
}


input int  InpSlowEMA = 70;// MACD慢线周期数
input int  InpFastEMA  = 30;// MACD快线周期数
input int  InpSignalEMA = 5;// MACD信号线周期数  
double iDif(int timeframe,int i){
   return iMacd(timeframe,0,i);
   return  iMACD(NULL,timeframe,InpFastEMA,InpSlowEMA,InpSignalEMA,PRICE_CLOSE,MODE_MAIN,i);     
   }
double iDea(int timeframe, int i){
   return iMacd(timeframe,1,i);

   return iMACD(NULL,timeframe,InpFastEMA,InpSlowEMA,InpSignalEMA,PRICE_CLOSE,MODE_SIGNAL,i);
  }
double iMacd(int timeframe,int i){
   return 2*(iDif(timeframe,i)-iDea(timeframe,i));
   }
double iMa(int timeframe,int period,int i){
   return iMA(NULL,timeframe,period,0,MODE_EMA,PRICE_CLOSE,i);/注意计算方式的不同
   }
   
double iMacd2(int tf,int line, int i){
   return iCustom(NULL,tf,indiName,InpFastEMA2,InpSlowEMA2,InpSignalEMA2,line,i);
}
input int  InpSlowEMA2 = 13;// MACD慢线周期数2
input int  InpFastEMA2  = 5;// MACD快线周期数2
input int  InpSignalEMA2 = 1;// MACD信号线周期数2
double iDif2(int timeframe,int i){
   return iMacd2(timeframe,0,i);
   return  iMACD(NULL,timeframe,InpFastEMA2,InpSlowEMA2,InpSignalEMA2,PRICE_CLOSE,MODE_MAIN,i);     
   }
double iDea2(int timeframe, int i){
   return iMacd2(timeframe,1,i);

   return iMACD(NULL,timeframe,InpFastEMA2,InpSlowEMA2,InpSignalEMA2,PRICE_CLOSE,MODE_SIGNAL,i);
  }
double iMacd2(int timeframe,int i){
   return 2*(iDif2(timeframe,i)-iDea2(timeframe,i));
   }
 
   
 ENUM_TIMEFRAMES tfMa = PERIOD_CURRENT;  //
input ENUM_TIMEFRAMES tfMacd = PERIOD_CURRENT;  //MACD 时间框架
bool isCdMacd(int i){
   return  iDif(tfMacd,i+1)<iDea(tfMacd,i+1) && iDif(tfMacd,i+2)>iDea(tfMacd,i+2)  ;
}   
bool isCuMacd(int i){
   return  iDif(tfMacd,i+1)>iDea(tfMacd,i+1) && iDif(tfMacd,i+2)<iDea(tfMacd,i+2) ;
}
bool isCrossDownMacd(int i){
   return  iDif(tfMacd,i+1)<iDea(tfMacd,i+1) && iDif(tfMacd,i+2)>iDea(tfMacd,i+2) && iDif(tfMacd,i+1)<iDif(tfMacd,i+2) && iDif(tfMacd,i+1)>0;
}   
bool isCrossUpMacd(int i){
   return  iDif(tfMacd,i+1)>iDea(tfMacd,i+1) && iDif(tfMacd,i+2)<iDea(tfMacd,i+2)&& iDif(tfMacd,i+1)>iDif(tfMacd,i+2) && iDif(tfMacd,i+1)<0;
}   

bool isCrossDownMacdO(int i){
   return  iDif(tfMacd,i+1)<iDea(tfMacd,i+1) && iDif(tfMacd,i+2)>iDea(tfMacd,i+2)  && iDif(tfMacd,i+1)<0;
}   
bool isCrossUpMacdO(int i){
   return  iDif(tfMacd,i+1)>iDea(tfMacd,i+1) && iDif(tfMacd,i+2)<iDea(tfMacd,i+2)&& iDif(tfMacd,i+1)>0;
}   

bool isDownMacdO(int i){
   return  iDif(tfMacd,i+1)<iDea(tfMacd,i+1) && iDif(tfMacd,i+1)<0;
}   
bool isUpMacdO(int i){
   return  iDif(tfMacd,i+1)>iDea(tfMacd,i+1) && iDif(tfMacd,i+1)>0;
}
 bool isDownMacd(int i){
   return  iDif(tfMacd,i+1)<iDea(tfMacd,i+1) ;
}   
bool isUpMacd(int i){
   return  iDif(tfMacd,i+1)>iDea(tfMacd,i+1)  ;
}
 bool isMacdL( int i ){
   return isCuMacd(i)  ;
}
bool isMacdS( int i ){
   return isCdMacd(i) ;
}
//(0 - MODE_MAIN, 1 - MODE_UPPER, 2 - MODE_LOWER).

  ENUM_TIMEFRAMES tfBands = PERIOD_CURRENT;   //布林线时间周期
input int prdBands = 20;   //布林线周期
double iBands(int tf,int i){
   return iBands(NULL,tf,prdBands,2,0,PRICE_CLOSE,MODE_MAIN,i);
}
double iBandsUpr(int tf,int i){
   return iBands(NULL,tf,prdBands,2,0,PRICE_CLOSE,MODE_UPPER,i);
}
double iBandsLwr(int tf,int i){
   return iBands(NULL,tf,prdBands,2,0,PRICE_CLOSE,MODE_LOWER,i);
}
bool isCsBands(int i){
   return iHigh(NULL,tfBands,i)>iBands(tfBands,i) && iLow(NULL,tfBands,i)<iBands(tfBands,i);
}   

bool isBandsOk(int i){
   return !isCsBands(i+1) && !isCsBands(i+2) && !isCsBands(i+3);
}   

 int search = 500;
int getStLtCu(int i){
   int m = 0;
    while(true){
      if(isCuMacd(i) ) return i;
      if(m>search) return 0;
      m++;
      i++;
   }
   return -1;
}
int getStLtCd(int i){
   int m = 0;
    while(true){
      if(isCdMacd(i) ) return i;
      if(m>search) return -1;
      m++;
      i++;
   }
   return -1;
}
ENUM_TIMEFRAMES tfUse = PERIOD_CURRENT;
bool isBandsL(int i){//当前金叉,出现金叉前的金叉死叉之间那个区域 最低值必须下破布林线下轨(布林线默认为20)
   int stCd = getStLtCd(i);
   //datetime tStCd = iTime(NULL,tfUse,stCd);
   //if(isOpenedAft(tStWhite)) return false;
   int stL = iLowest(NULL,tfUse,MODE_LOW,stCd,i);
   double pL = Low[stL];
   return pL<iBandsLwr(tfUse,stL);
   return false;
}   
bool isBandsS(int i){//当前金叉,出现金叉前的金叉死叉之间那个区域 最低值必须下破布林线下轨(布林线默认为20)
   int stCu = getStLtCu(i);
   //datetime tStCd = iTime(NULL,tfUse,stCd);
   //if(isOpenedAft(tStWhite)) return false;
   int stH = iHighest(NULL,tfUse,MODE_HIGH,stCu,i);
   double pH = High[stH];
   return pH>iBandsUpr(tfUse,stH);
   return false;
}

//出现金叉前的金叉死叉之间那个区域,那个区域K线最高/低值设为本单的止损点;
//input int dStl = 350;//止损点数
//input int dTf = 550;//  止盈点数
double getPstl(int type,int i){    
   if(type == OP_BUY){
      int stCd = getStLtCd(i);
      int stL = iLowest(NULL,tfUse,MODE_LOW,stCd,i);
      double pL = Low[stL];
      return pL;
          return Ask-dStl*pPoint;
    }else{// if(type == OP_SELL)
      int stCu = getStLtCu(i);
      //datetime tStCd = iTime(NULL,tfUse,stCd);
      //if(isOpenedAft(tStWhite)) return false;
      int stH = iHighest(NULL,tfUse,MODE_HIGH,stCu,i);
      double pH = High[stH];
      return pH;
          return Bid+dStl*pPoint;
    }
}          
 
double getPtf(int type){
    if(type == OP_BUY){
          return Ask+dTf*pPoint;
    }else{// if(type == OP_SELL)
          return Bid-dTf*pPoint;
    }
}


/*参数条件:
      datetime tO = OrderOpenTime();
      int st = iBarShift(NULL,tfUse,tO,false);
      int stL = iLowest(NULL,tfUse,MODE_LOW,st,0);
      double pL = Low[stL];
第1章 参数设置

1> 每次交易0.1手;(可以调节)
2> 当保证金<1000美金时不交易(可以调节)
3> MACD线默认参数为FastEMA 30, SlowEMA 70, SingleSMA 5 (可以调节)
4> 止损默认0 (可以调节)
5> 止赢默认0 (可以调节)


第2章 开单条件
开单条件如下:必须同时满足条件1234:
2.1【条件1:金叉死叉开单】
以MACD5分钟线为例,当MACD出现金叉(死叉同理)时(我这里的金叉概念是前5分钟标线Diff<DEA,这5分钟标线Diff>DEA,然后在下5分钟刚开始就开始下多单,不知我们的理解是否相同?)

比如上图金叉时间分别跨过了10:50;10:55;11:00

那么应该在11:00的时候(11点刚开始就立刻)下多单
2.2【最低/高值必须下破布林线下/上轨】

条件2>
出现金叉前的金叉死叉之间那个区域 最低值必须下破布林线下轨(布林线默认为20)



2.3【K线的若干可能】
条件3> 条件3包括以下ABC若干可能:几个”可能”之间是或关系。也就是说满足ABC任一可能,则条件3就被满足。
2.3.1可能A
2.3.1.1案例1

  出现金叉前的金叉死叉之间那个区域,那个区域K线最低值是锤子线,如下图,锤子线标准是:下影线长度>主体线长度*2
  
2.3.1.2案例2
  出现死叉前的金叉死叉之间那个区域,那个区域K线最高值是射击之星线,如下图,锤子线标准是:上影线长度>主体线长度*2
  

2.3.1可能B
2.3.1.1案例1

例子1:拿金叉做个例子,出现金叉前的金叉死叉之间那个区域,那个区域K线最低值是阴线,但其下一根线为阳线,且阴线开盘价<阳线收盘价,如下图


2.3.1.2案例2
例子2:拿死叉做个例子,出现死叉前的死叉金叉之间那个区域,那个区域K线最高值是阳线,但其下一根线为阴线,且阳线开盘价<阴线收盘价,如下图



2.3.1.3案例3
例子3:再拿死叉做个例子,出现死叉前的死叉金叉之间那个区域,那个区域K线最高值是阴线,但其下一根线也为阴线,且前一根阴线收盘价>后一根阴线收盘价,如下图


2.3.1可能C平底/平顶
2.3.1.1案例1

例1:拿金叉做个例子,出现金叉前的金叉死叉之间那个区域,那个区域K线最低值与次低值之间差<0.004,比如最低值1199.33,次低值1199.34,最低值1199.33减次低值1199.34<0.04如下图所示


当然也有可能出现两个最低值,那这个条件也满足
2.3.1.2案例2

例2:平顶的情况,与平底类似

2.4【不超过4个点】
条件4> 条件4为开单时开单价钱与出现金叉前的金叉死叉之间那个区域,那个区域K线最低值两者价差不超过4个点。

条件1234必须同时满足后才开单


第3章 止损条件

止损点设置如下:出现金叉前的金叉死叉之间那个区域,那个区域K线最低值设为本单的止损点;

第4章 平仓条件

如果金叉开单,则死叉出现后平仓。如果死叉开单,则出现金叉后平仓。

*/
 
 bool isLots(double flots){
    if(flots<MarketInfo(Symbol(),MODE_MINLOT)){
      printf("交易量" + flots + " 小于当前货币对: "+Symbol()+" 最小交易量<" + MarketInfo(Symbol(),MODE_MINLOT) +  ">,请修改参数");
      return false;
   }
   return true;
}

double getPpointLo(){
   int tkt = getTktLatestPos(magic);
   
      if(OrderSelect(tkt,SELECT_BY_TICKET,MODE_TRADES)){
          if(OrderType() == OP_BUY){
            return (Bid-OrderOpenPrice()) /pPoint;
         }else if(OrderType()  == OP_SELL){
           return (OrderOpenPrice()-Ask) /pPoint;
         }  
      }
   
   return 0;
}
input int dDifC = 80;   //交叉平仓收盘价与开单价价差点数
int getTktLatestPos(int fmagic){
   orders = OrdersTotal();
   int tktLastPos =0;   
   for(int i=orders-1;i>=0;i--){
     if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) {
          if( (isSymbolMagic(fmagic) ) && OrderType()<=1 ){
          //printf("MODE "  + OrderTicket());
            if(OrderTicket()>tktLastPos) tktLastPos = OrderTicket();
         }   
     }
   }
   return tktLastPos;
}
 bool isSymbolMagic(int fmagic){
   if(OrderSymbol()==Symbol() && OrderMagicNumber()==fmagic) return true;
   else return false;
}
bool isDifClose(int i){
    return getPpointLo()>dDifC;
   return false;
}   

bool isLong(int i){
   //return  isCuMacd(i) && isBandsL(i)&& isTkconL(i);// && isThreeL(i);
   //if(isCuMacd(i) && isBandsL(i)&& isShiZiXingkconL(i))
   //   return  true;
   if(isCuMacd(i) && isBandsL(i)&& isThreeL(i))
      return  true;
   /*
   if(isCuMacd(i) && isBandsL(i)&& isTkconL(i))
      return  true;

      
   if(isCuMacd(i) && isBandsL(i) && isDoubleL(i))
      return  true;  
      
      */
   //if(isCuMacd(i) && isBandsL(i)&& isTkconL(i))
   //   return  true;
   
   //if(isCuMacd(i) && isBandsL(i) && isQingpenkconL(i))
  //    return  true;

      
   //if(isCuMacd(i) && isBandsL(i) && isPingL(i))
   //   return  true;          

   return false;
}
bool isShort(int i){
   //return  isCdMacd(i) && isBandsS(i)&& isTkconS(i);// && isThreeS(i);
   //if(isCdMacd(i) && isBandsS(i)&& isShiZiXingkconS(i))
   //   return  true;
   if(isCdMacd(i) && isBandsS(i) && isThreeS(i))
      return  true;
   /*
   if(isCdMacd(i) && isBandsS(i)&& isTkconS(i))
      return  true;

     
   if(isCdMacd(i) && isBandsS(i) && isDoubleH(i))
      return  true;
      */
      
   //if(isCdMacd(i) && isBandsS(i)&& isTkconS(i))
  //    return  true;
   //if(isCdMacd(i) && isBandsS(i) && isPingH(i))
   //   return  true;  
   
  //if(isCdMacd(i) && isBandsS(i) && isQingpenkconS(i))
  //    return  true;     

   return false;
}      
 
int tf0 =0;
int getStMacdL(int i){
   int stCd = getStLtCd(i);
   double pMacdMin = iDif2(tf0,i);
   int st = i;
   for(int m=i;m<stCd+2;m++){
      if(iDif2(tf0,m)<pMacdMin){
         pMacdMin = iDif2(tf0,m);
         st = m;
      }
   }
   return st;
}       
int getStMacdS(int i){
   int stCu = getStLtCu(i);
   double pMacdMax = iDif2(tf0,i);
   int st = i;
   for(int m=i;m<stCu+2;m++){
      if(iDif2(tf0,m)>pMacdMax){
         pMacdMax = iDif2(tf0,m);
         st = m;
      }
   }
   return st;
}  
//---------------获取区间内第二高的K线高值----------------//
int getSecondKlineL(int i){
   int stCd = getStLtCd(i);
   int LowestK = iLowest(NULL,tfUse,MODE_LOW,stCd-i+2,i+2);
   double Value_LowSecondK = Low [i+2];
   int second = i+2;
   for(int m=i+2;m<stCd+2;m++){
      if(Low[m] <= Value_LowSecondK  && Low[m] >= Low[LowestK] && m!=LowestK){
         second = m;
         Value_LowSecondK = Low[m];
      }
   }
   return second;
}       
int getSecondKlineH(int i){
   int stCu = getStLtCu(i);
   int HighestK = iHighest(NULL,tfUse,MODE_HIGH,stCu-i+2,i+2);
   double Value_HighSecondK = High [i+2];
   int second = i+2;
   for(int m=i+2;m<stCu+2;m++){
      if(High[m] >= Value_HighSecondK  && High[m] <= High[HighestK] && m!=HighestK){
         second = m;
         Value_HighSecondK = High[m];
      }
   }
   return second;
}  

//---------------获取区间内第三高的K线高值----------------//
int getThirdKlineL(int i){
   int stCd = getStLtCd(i);
   int LowestK = iLowest(NULL,tfUse,MODE_LOW,stCd-i+2,i+2);
   int stSecondL=getSecondKlineL(i);
   double Value_LowThirdK = Low [i+2];
   int third = i+2;
   for(int m=i+2;m<stCd+2;m++){
      if(Low[m] <= Value_LowThirdK  && Low[m] > Low[stSecondL] && m!=stSecondL && m!=LowestK){
         third = m;
         Value_LowThirdK = Low[m];
      }
   }
   return third;
}       
int getThirdKlineH(int i){
   int stCu = getStLtCu(i);
   int HighestK = iHighest(NULL,tfUse,MODE_HIGH,stCu-i+2,i+2);
   int stSecondH=getSecondKlineH(i);
   double Value_HighThirdK = High [i+2];
   int third = i+2;
   for(int m=i+2;m<stCu+2;m++){
      if(High[m] >= Value_HighThirdK  && High[m] < High[stSecondH] && m!=stSecondH && m!=HighestK ){
         third = m;
         Value_HighThirdK = High[m];
      }
   }
   return third;
}  


input int kMacdCnt = 8; //距离长度大于等于8个柱
input int kSt = 0;   //左偏移量
bool  isThreeL(int i){//当前金叉,出现金叉前的金叉死叉之间那个区域 最低值必须下破布林线下轨(布林线默认为20)
   int stCd = getStLtCd(i);
   //datetime tStCd = iTime(NULL,tfUse,stCd);
   //if(isOpenedAft(tStWhite)) return false;
   int stL = iLowest(NULL,tfUse,MODE_LOW,stCd-i+2,i+2);
   int stMacdMin = getStMacdL(i);
   return stMacdMin!=stL && MathAbs(stL-stMacdMin)>6; //&& MathAbs(stL-i)>7;
    
}          
bool  isThreeS(int i){//当前金叉,出现金叉前的金叉死叉之间那个区域 最低值必须下破布林线下轨(布林线默认为20)
   int stCu = getStLtCu(i);
   //datetime tStCd = iTime(NULL,tfUse,stCd);
   //if(isOpenedAft(tStWhite)) return false;
   int stH = iHighest(NULL,tfUse,MODE_HIGH,stCu-i+2,i+2);
   int stMacdMax = getStMacdS(i);
   return stMacdMax!=stH && MathAbs(stH-stMacdMax)>6; //&& MathAbs(stH-i)>7;
   
}  


//---------------检查最高K线和次高K线的距离是否超过10


bool  isDoubleL(int i){//
   int stCd = getStLtCd(i);
   //datetime tStCd = iTime(NULL,tfUse,stCd);
   //if(isOpenedAft(tStWhite)) return false;
   int stL = iLowest(NULL,tfUse,MODE_LOW,stCd-i+2,i+2);
   int stSecondL=getSecondKlineL(i);
   return MathAbs(stL-stSecondL)>10;
    
}


bool  isDoubleH(int i){//
   int stCu = getStLtCu(i);
   //datetime tStCd = iTime(NULL,tfUse,stCd);
   //if(isOpenedAft(tStWhite)) return false;
   int stH = iHighest(NULL,tfUse,MODE_HIGH,stCu-i+2,i+2);
   int stSecondH = getSecondKlineH(i);
   return MathAbs(stH-stSecondH)>10;
   
}  



//---------------检查最高K线和次高K线,第三高的K线的值之间的差是否小于<0.5


bool  isPingL(int i){//
   int stCd = getStLtCd(i);
   int stCu = getStLtCu(i);
   //datetime tStCd = iTime(NULL,tfUse,stCd);
   //if(isOpenedAft(tStWhite)) return false;
   int stL = iLowest(NULL,tfUse,MODE_LOW,stCd-i+2,i+2);
   int stSecondL=getSecondKlineL(i);
   int stThirdL=getThirdKlineL(i);
   return MathAbs(Low[stL]-Low[stSecondL])<0.11 && MathAbs(stCu-stCd)>6 ;
    
}


bool  isPingH(int i){//
   int stCd = getStLtCd(i);
   int stCu = getStLtCu(i);
   //datetime tStCd = iTime(NULL,tfUse,stCd);
   //if(isOpenedAft(tStWhite)) return false;
   int stH = iHighest(NULL,tfUse,MODE_HIGH,stCu-i+2,i+2);
   int stSecondH= getSecondKlineH(i);
   int stThirdH = getThirdKlineH(i);
   return MathAbs(High[stH]-High[stSecondH])<0.11 && MathAbs(stCu-stCd)>6 ;
   
}  


/*出现金叉前的金叉死叉之间那个区域,金叉前的金叉死叉区域K线最低值不是对应MACD(5,13,1)最低值,
且与MACD最低值距离长度大于等于8个柱(假如MACD最低值为第1个柱,然后第2个柱.....第7个柱,然后K线最低值所对应的是第8个柱)。,如下图,

出现金叉前的金叉死叉之间那个区域,金叉前的金叉死叉区域K线最低值不是对应MACD(5,13,1)最低值,
且与MACD(5,13,1)最低值距离长度大于等于8个柱(假如从MACD(5,13,1)最低值开始数,为第1个柱,然后第2个柱.....第7个柱,
然后K线最低值所对应的MACD(5,13,1)是第8个柱)。*/



bool isTklineL(int i){
   bool isDnYing = MathMin(Open[i],Close[i])-Low[i]>MathAbs(Open[i]-Close[i])*3;
   bool isReal = MathAbs(Open[i]-Close[i])>=High[i] - MathMax(Open[i],Close[i]);
   return isDnYing && isReal;
}
bool isTklineS(int i){
   bool isUpYing = High[i] - MathMax(Open[i],Close[i])>MathAbs(Open[i]-Close[i])*3;
   bool isReal = MathAbs(Open[i]-Close[i])>=MathMin(Open[i],Close[i])-Low[i];
   return isUpYing && isReal;
}

//---------------满足倾盆大雨行情的  最低为阴线 下一根为阳线 阴线开盘<阳线收盘
bool isQingpengKlineL(int i){
   bool isXiangCha = (MathAbs(Open[i]-Close[i]) < MathAbs(Open[i-1]-Close[i-1])*2) &&  (MathAbs(Open[i]-Close[i])*2 > MathAbs(Open[i-1]-Close[i-1]));
   //if (Open[i] > Close[i] && Open[i-1] < Close[i-1] && Open[i] < Close[i-1] && isXiangCha)
   if (Open[i] > Close[i] && Open[i-1] < Close[i-1] && Open[i] < Close[i-1] && isXiangCha)
      return true;
   
   return false;
}
bool isQingpengKlineS(int i){ //最高为阳线 下一根为阴线 阴线收盘<阳线收盘
   bool isXiangCha = (MathAbs(Open[i]-Close[i]) < MathAbs(Open[i-1]-Close[i-1])*2) &&  (MathAbs(Open[i]-Close[i])*2 > MathAbs(Open[i-1]-Close[i-1]));
   //if (Open[i] < Close[i] && Open[i-1] > Close[i-1] && Open[i] > Close[i-1] && isXiangCha)
   if (Open[i] < Close[i] && Open[i-1] > Close[i-1] && Open[i] > Close[i-1] && isXiangCha)
      return true;
      
   return false;
}





bool isShiZiXingKline(int i){
   bool isDnYing = MathMin(Open[i],Close[i])-Low[i]>MathAbs(Open[i]-Close[i])*4;
   bool isUpYing = High[i] - MathMax(Open[i],Close[i])>MathAbs(Open[i]-Close[i])*4;
   bool isReal1 = High[i] - MathMax(Open[i],Close[i]) < (MathMin(Open[i],Close[i])-Low[i])*2;
   bool isReal2 = (High[i] - MathMax(Open[i],Close[i])) *2 > MathMin(Open[i],Close[i])-Low[i];
   return isDnYing && isReal1 && isReal2 && isUpYing;
}

/*2.3.3.1案例1

出现金叉前的金叉死叉之间那个区域,那个区域K线最低值是锤子线,如下图,
锤子线标准是:
1> 下影线长度>主体线长度*3
2> 主体线长度大于等于上影线长度。
3> 金叉前的金叉死叉区域K线最低值就是对应MACD(5,13,1)最低值
4> 金叉前的金叉死叉之间那个区域长度大于等于8个柱*/
bool isTkconL(int i){
    int stCd = getStLtCd(i);
    int stCu = getStLtCu(i);
   int stL = iLowest(NULL,tfUse,MODE_LOW,stCd-i+2,i+2);
   int stMacdMin = getStMacdL(i);
   bool isKt  = isTklineL(stL);
   return (stMacdMin==stL && MathAbs(stCu-stCd)>4 && isKt) || (MathAbs(stCu-stCd)>8 && isKt);
    
}          
bool  isTkconS(int i){
   int stCd = getStLtCd(i);
   int stCu = getStLtCu(i);
   int stH = iHighest(NULL,tfUse,MODE_HIGH,stCu-i+2,i+2);
   int stMacdMax = getStMacdS(i);
   bool isKt  = isTklineS(stH);
   return (stMacdMax==stH && MathAbs(stCu-stCd)>4 && isKt) || (MathAbs(stCu-stCd)>8 && isKt);

   
}  


//--------------检查MACD5,13,1最低拐点是否为倾盆大雨------
bool isQingpenkconL(int i){
    int stCd = getStLtCd(i);
    int stCu = getStLtCu(i);
   int stL = iLowest(NULL,tfUse,MODE_LOW,stCd-i+2,i+2);
   int stMacdMin = getStMacdL(i);
   bool isQingpen  = isQingpengKlineL(stL);
   return stMacdMin==stL && MathAbs(stCu-stCd)>10 && isQingpen;
    
}          
bool  isQingpenkconS(int i){
   int stCd = getStLtCd(i);
   int stCu = getStLtCu(i);
   int stH = iHighest(NULL,tfUse,MODE_HIGH,stCu-i+2,i+2);
   int stMacdMax = getStMacdS(i);
   bool isQingpen  = isQingpengKlineS(stH);
   return stMacdMax==stH && MathAbs(stCu-stCd)>10 && isQingpen;
   
}

//---检查MACD5,13,1最低拐点是否为十字星, 且与最低点只相差1------//

bool isShiZiXingkconL(int i){
    int stCd = getStLtCd(i);
    int stCu = getStLtCu(i);
   int stL = iLowest(NULL,tfUse,MODE_LOW,stCd-i+2,i+2);
   int stMacdMin = getStMacdL(i);
   bool isShiZiXing  = isShiZiXingKline(stL-1);
   return stMacdMin==(stL-1) && MathAbs(stCu-stCd)>4&& isShiZiXing;
   //return MathAbs(stCu-stCd)>4&& isShiZiXing;
    
}          
bool  isShiZiXingkconS(int i){
   int stCd = getStLtCd(i);
   int stCu = getStLtCu(i);
   int stH = iHighest(NULL,tfUse,MODE_HIGH,stCu-i+2,i+2);
   int stMacdMax = getStMacdS(i);
   bool isShiZiXing  = isShiZiXingKline(stH-1);
   return stMacdMax==(stH-1) && MathAbs(stCu-stCd)>4 && isShiZiXing;
   //return MathAbs(stCu-stCd)>4 && isShiZiXing;
   
}  







//----------------------------------------------------------
  int posMax = 1;   //最大持仓单数

bool isLongTrend(int i){
   return  true;
}
bool isShortTrend(int i){
   return  true;
}
double lotsProcess(){
   return lots;
}   
void posOpen1(){
    if(getPosSym(magic)<posMax && isShort(0) && isShortTrend(0) && tLastOpen != Time[0]){//  
      pLots = lotsProcess();
      int tkts = OrderSend(NULL,OP_SELL,pLots,Bid,slp,Bid+dStl*pPoint,Bid-dTf*pPoint,"",magic,0,Red);
      if(checkOrderOpen(tkts,"空头 开仓",OP_SELL)){
          tLastOpen = Time[0];
      }
   }else if(getPosSym(magic)<posMax &&  isLong(0)&& isLongTrend(0)  && tLastOpen != Time[0]){//  
         pLots = lotsProcess();
        int tktl = OrderSend(NULL,OP_BUY,pLots,Ask,slp,Ask-dStl*pPoint,Ask+dTf*pPoint,"",magic,0,Blue);  
        if(checkOrderOpen(tktl,"多头 开仓",OP_BUY)){
          tLastOpen = Time[0];
      }
 
   }
}  
void posOpen(){
    if(getPosSym(magic)<posMax && isShort(0)  && tLastOpen != Time[0]){//  
      pLots = lotsProcess();
      int tkts = OrderSend(NULL,OP_SELL,pLots,Bid,slp,getPstl(OP_SELL,0),getPtf(OP_SELL),"",magic,0,Red);
      if(checkOrderOpen(tkts,"空头 开仓",OP_SELL)){
          tLastOpen = Time[0];
          reset();
      }
   }else if(getPosSym(magic)<posMax &&  isLong(0)&& isLongTrend(0)  && tLastOpen != Time[0]){//  
         pLots = lotsProcess();
        int tktl = OrderSend(NULL,OP_BUY,pLots,Ask,slp,getPstl(OP_BUY,0),getPtf(OP_BUY),"",magic,0,Blue);  
        if(checkOrderOpen(tktl,"多头 开仓",OP_BUY)){
          tLastOpen = Time[0];
          reset();
      }
 
   }
}
 
 void reset(){
   isCf = false;
   isCs = false;
}   
 bool isCl(int i){
   return false;
}   
bool isCs(int i){
   return false;
}
/*如果金叉开单,则赚到3个点时平总仓50% 赚到5个点时平总仓25%

死叉出现后全部平仓。

以0.4手为例,如果金叉开单,则赚到3个点时0.2手 赚到5个点时平0.1手
死叉出现后全部平仓。*/
input int dCloseF = 1000;  //赚到300个点时
input double pcCf = 50; //平总仓50%
input int dCloseS = 1500;  //赚到500个点
input double pcCs = 25; //平总仓25%
input int dCloseAll = 80;  //相反交叉时全平要求赚到的点数80
double getPpointPrf(){
   if(OrderType() == OP_BUY){
      return (OrderClosePrice()-OrderOpenPrice()) /pPoint;
   }else if(OrderType()  == OP_SELL){
     return (OrderOpenPrice()-OrderClosePrice()) /pPoint;
   }  
   return 0;
}         

bool isCf = false;
bool isCs = false;
void posClose(){
     int orders = OrdersTotal();
   if(orders>0){
      for(int i=orders-1;i>=0;i--){
         if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
         if(isBuySymbolMagic() ){
            if(isCdMacd(0) && getPpointPrf()>dCloseAll){
               closeOrderCurSymbol();
            }else if(getPpointPrf()>dCloseS && !isCs){
               closeOrderCurSymbol(OrderLots()*(pcCs/(100.0-pcCf)));
               isCs = true;
            }else if(getPpointPrf()>dCloseF && !isCf){
               closeOrderCurSymbol(OrderLots()*(pcCf/(100.0)));
               isCf = true;
            }   
             
         }else if(isSellSymbolMagic()  ){
            if(isCuMacd(0) && getPpointPrf()>dCloseAll){
               closeOrderCurSymbol();
            }else if(getPpointPrf()>dCloseS && !isCs){
               closeOrderCurSymbol(OrderLots()*(pcCs/(100.0-pcCf)));
               isCs = true;
            }else if(getPpointPrf()>dCloseF && !isCf){
               closeOrderCurSymbol(OrderLots()*(pcCf/(100.0)));
               isCf = true;
            }  
             
         }
      }   
   }
}

void closeOrderCurSymbol(double lotsC){
   if(isBuySymbol()){
      if(!OrderClose(OrderTicket(),lotsC,Bid,0,Violet))
         Print("OrderClose error ",GetLastError());
      return;
   }else if( isSellSymbol()){
       if(!OrderClose(OrderTicket(),lotsC,Ask,0,Violet))
         Print("OrderClose error ",GetLastError());
      return;
   }      
}

///
 
bool orderModifyStop(double stopPrice){
   double pStop = OrderStopLoss();
   if(isBuySymbol() && pStop>=0 && stopPrice<=pStop) return false;
   if(isSellSymbol() && pStop>=0 && stopPrice>=pStop)return false;   
   bool isModi = OrderModify(OrderTicket(),OrderOpenPrice(),stopPrice,OrderTakeProfit(),0,Yellow);
   
   if(!isModi) Print("OrderModify error ",GetLastError(),"ticket: " ,OrderTicket()+ " modifiy price : " + stopPrice + " stl: " + OrderStopLoss());
   return isModi;
}

  int dTsp = 10; //追踪止损点数
 
  int dTspSta = 15; //启动追踪止损盈利点数
// posProcess
//追踪止损
void posTspProcess(){
    int orders = OrdersTotal();    
   if(orders>0){
      for(int i=orders-1;i>=0;i--){
         if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
         
         //printf("OrderComment()==comBuyFirstisFirstOrder:" + isFirstOrder());
         if(isBuySymbol()  ){
            if(Bid>OrderStopLoss()+dTsp*pPoint && Bid>OrderOpenPrice()+dTspSta*pPoint){
               orderModifyStop(Bid-dTsp*pPoint);
            }   
             
         }else if(isSellSymbol()){
            if(Ask<OrderStopLoss()-dTsp*pPoint && Ask<OrderOpenPrice()-dTspSta*pPoint){
               orderModifyStop(Ask+dTsp*pPoint);
            }   
             
         }
      }   
   }
}   
 
 int getPosSym(  int fmagic){
   int orders = OrdersTotal();
   int symOrders = 0;
   if(orders>0){
      for(int i=orders-1; i>=0; i--){
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
            if(isSymbol() && OrderType() <=OP_SELL && OrderMagicNumber() == fmagic){
               symOrders++;
            }
         }
      }
   }
   return symOrders;
}
 int getSymOrders(int type, int fmagic){
   int orders = OrdersTotal();
   int symOrders = 0;
   if(orders>0){
      for(int i=orders-1; i>=0; i--){
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
            if(isSymbol() && OrderType() == type && OrderMagicNumber() == fmagic){
               symOrders++;
            }
         }
      }
   }
   return symOrders;
}
 int getSymOrdersAll(  int fmagic){
   int orders = OrdersTotal();
   int symOrders = 0;
   if(orders>0){
      for(int i=orders-1; i>=0; i--){
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
            if(isSymbol() && OrderMagicNumber() == fmagic){
               symOrders++;
            }
         }
      }
   }
   return symOrders;
}
int getSymPos(  int fmagic){
   int orders = OrdersTotal();
   int symOrders = 0;
   if(orders>0){
      for(int i=orders-1; i>=0; i--){
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)){
            if(isSymbol() && OrderMagicNumber() == fmagic&& OrderType()<=OP_SELL){
               symOrders++;
            }
         }
      }
   }
   return symOrders;
}
    
    
bool checkOrderOpen(int ticket,string con, int type){
   string orderType = "";
   if(ticket>0){
      if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)){
         
 
         if(isBuySymbol()){
            orderType = "多单开仓::";
           // pLastOpenBuy = OrderOpenPrice();
        
         }else if(isSellSymbol()){
            orderType = "空单开仓::";
           // pLastOpenSell = OrderOpenPrice();
          
         }
 
         Print(" " ,orderType,"开仓成功,价格为 : ",OrderOpenPrice(),", 手数为 " ,OrderLots(),
         ", 止损点数为 " , OrderStopLoss(), ", 止盈点数为 " , OrderTakeProfit(), ", 订单号" + OrderTicket() + ", 说明:" + con);
          
      }                 
   }
   else {
      if(type==OP_BUY){
        orderType = "多单::";
      }  
      else if(type == OP_SELL){
        orderType = "空单::";
      }else orderType = type;  
      //Print("Error opening  order : ",GetLastError());
      printf("Error opening " + orderType +" : 错误信息" + GetLastError()+ "说明: " + con);
   }   
 
   return ticket>0;
 
}

bool isBuyStopSymbol(){
   if(OrderType()==OP_BUYSTOP && OrderSymbol()== Symbol()) return true;
   return false;
}
bool isSellStopSymbol(){
   if(OrderType()==OP_SELLSTOP && OrderSymbol()== Symbol()) return true;
   return false;
}

bool isBuyLimitSymbol(){
   if(OrderType()==OP_BUYLIMIT && OrderSymbol()== Symbol()) return true;
   return false;
}
bool isSellLimitSymbol(){
   if(OrderType()==OP_SELLLIMIT && OrderSymbol()== Symbol()) return true;
   return false;
}

   // orderClose
   
void closeOrderCurSymbol(){
   if(isBuySymbol()){
      if(!OrderClose(OrderTicket(),OrderLots(),Bid,0,Violet))
         Print("OrderClose error ",GetLastError());
      return;
   }else if( isSellSymbol()){
       if(!OrderClose(OrderTicket(),OrderLots(),Ask,0,Violet))
         Print("OrderClose error ",GetLastError());
      return;
   }      
}

bool isSymbol(){
   if(OrderSymbol()==Symbol()) return true;
   else return false;
}
   
bool isBuySymbol(){
   if(OrderType()==OP_BUY && isSymbol()) return true;
   return false;
}
bool isSellSymbol(){
   if(OrderType()==OP_SELL && isSymbol()) return true;
   return false;
}

 bool isSymbolMagic(){
   if(OrderSymbol()==Symbol() && OrderMagicNumber()==magic) return true;
   else return false;
}
 
bool isBuySymbolMagic(){
   if(OrderType()==OP_BUY && isSymbolMagic()) return true;
   return false;
}
bool isSellSymbolMagic(){
   if(OrderType()==OP_SELL && isSymbolMagic() ) return true;
   return false;
}

转载于:https://www.cnblogs.com/programmerinterview/p/5391634.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值