//+------------------------------------------------------------------+
//| 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;
}