//+------------------------------------------------------------------+
//| BetaPig.mq4 |//| |//| http://product.dangdang.com/23837128.html |//+------------------------------------------------------------------+#property copyright "BetaPig"#property link "http://product.dangdang.com/23837128.html"#property version "1.00"#property strictint 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慢线周期数2input int InpFastEMA2 = 5;// MACD快线周期数2input 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可能A2.3.1.1案例1 出现金叉前的金叉死叉之间那个区域,那个区域K线最低值是锤子线,如下图,锤子线标准是:下影线长度>主体线长度*2 2.3.1.2案例2 出现死叉前的金叉死叉之间那个区域,那个区域K线最高值是射击之星线,如下图,锤子线标准是:上影线长度>主体线长度*2 2.3.1可能B2.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线的距离是否超过10bool 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.5bool 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> 下影线长度>主体线长度*32> 主体线长度大于等于上影线长度。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; //相反交叉时全平要求赚到的点数80double 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;}