我是编写mql4
代码的新手,如果在以下烛台模式出现时能得到一些绘制矩形的帮助,将不胜感激:
图。1:
Run code snippet
<blockquote class="imgur-embed-pub" lang="en" data-id="a/fRoPzsm"><a href="//imgur.com/a/fRoPzsm">Demand Zone 1</a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>
图2:
Run code snippet
<blockquote class="imgur-embed-pub" lang="en" data-id="a/4E8KE1R" data-context="false"><a href="//imgur.com/a/4E8KE1R">Demand Zone 2</a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>
和
图3:
Run code snippet
<blockquote class="imgur-embed-pub" lang="en" data-id="a/h6D6o6R"><a href="//imgur.com/a/h6D6o6R">Hidden Demand Zone</a></blockquote><script async src="//s.imgur.com/min/embed.js" charset="utf-8"></script>
和相应的供应区域,
并以指定的点数止损和止盈开立挂单。
请原谅我不直接包含图像。我没有足够的投票赞成这样做。
以下是链接图像中烛台图案的说明:
The general candlestick pattern
(Demand Zone) occurs when at least two or more consecutive bullish candles (with the last bullish candle high being the high of the time period) are followed by one or more bearish candles whose high and low are lower than the last bullish candle. Then finally followed by a bullish candle that forms the new high. The rectangle area which is the Demand Zone is taken from the Open to the Low of the last last bearish candle.
When a series of consecutive bullish candles has a candle with its low, lower than the previous candle and its High coinciding with its Close, then the Hidden Demand Zone is taken from the low to the open of the bullish candle.
The full explanation is available here for both demand and supply zones.
I am aware that bullish
and bearish
candles can be determined by
if ( ( Open[1] - Close[1] ) > 0)
{
// candle is bearish
}
else
{
// candle is bullish
}
I would really appreciate some help.
Seems these patterns are not fully described, so it is not possible to code them correctly. Ok, let us try with pattern#1.
The conditions used for pattern(what seems reasonable from the picture):
1. check at start of the new bar(bar#0).
2. bar 1(which is bar#3 in MQL4 if we compute 0 as the current) must be bullish.
3. bar 2(bar#2) is bearish. (or N bars in case of pattern#2, N can be 2 or more)
4. bar 3(bar#1 in MT4) is bullish.
5. its high=close.
6. its high>high of bar#3.
enum EnmDir
{
LONG = 1,
SHORT=-1,
NONE = 0,
};
int getCandleDirection(const int shift)
{
const double open=iOpen(_Symbol,0,shift), close=iClose(_Symbol,0,shift);
if(close-open>_Point/2.)
return LONG; //bullish
if(open-close>_Point/2.)
return SHORT; //bearish
return NONE; //doji
}
bool isPattern1Detected(const EnmDir dir)
{
if(dir==0)return(false);
if(getCandleDirection(3)!=dir)
return false; //rule#2
if(getCandleDirection(2)+dir!=0)
return false; //rule#3
if(getCandleDirection(1)!=dir)
return false; //rule#4
if(dir>0)
{
if(iHigh(_Symbol,0,1)-iClose(_Symbol,0,1)>_Point/2.)
return false; //rule#5 for long
if(iHigh(_Symbol,0,1)-iHigh(_Symbol,0,3)>_Point/2.)
return true; //rule#6 for long
return false; //if rule#6 is not hold
}
else
{
if(iClose(_Symbol,0,1)-iLow(_Symbol,0,1)>_Point/2.)
return false; //rule#5 for short
if(iLow(_Symbol,0,3)-iLow(_Symbol,0,1)>_Point/2.)
return true; //rule#6 for short
return false; //if rule#6 is not hold
}
}
bool isPattern2Detected(const EnmDir dir,const int numCandlesAgainst=1)
{
if(dir==NONE)return(false);
if(getCandleDirection(1)!=dir)
return false; //rule#4
for(int i=1;i<=numCandlesAgainst;i++)
{
if(getCandleDirection(1+i)!=dir)
return(false); //rule#3 - checking that all numCandlesAgainst must be bearish
}
if(getCandleDirection(2+numCandlesAgainst)!=dir)
return false; //rule#2
if(dir>0)
{
if(iHigh(_Symbol,0,1)-iClose(_Symbol,0,1)>_Point/2.)
return false; //rule#5 for long
if(iHigh(_Symbol,0,1)-iHigh(_Symbol,0,2+numCandlesAgainst)>_Point/2.)
return true; //rule#6 for long
return false; //if rule#6 is not hold
}
else
{
if(iClose(_Symbol,0,1)-iLow(_Symbol,0,1)>_Point/2.)
return false; //rule#5 for short
if(iLow(_Symbol,0,2+numCandlesAgainst)-iLow(_Symbol,0,1)>_Point/2.)
return true; //rule#6 for short
return false; //if rule#6 is not hold
}
}
您还需要什么?要检测矩形的HL?这很简单,规则很明确。让我们假设它们是:对于LONG,向上=条形#2的打开,向下=该条形的低。然后,
void detectRangeOfZone(double &top,double &bottom,const EnmDir dir)
{
if(dir>0)
{
top=iOpen(_Symbol,0,2);
bottom=iLow(_Symbol,0,2);
}
else if(dir<0)
{
top=iClose(_Symbol,0,2);
bottom=iHigh(_Symbol,0,2);
}
}
您需要画一个矩形吗?好的,但是您将如何决定何时停止绘制?让我们假设右边的N条就足够了,现在让我们忽略周末(如果要记住市场休市时的周末会稍微复杂一些)。
bool drawRectangle(const int dir,const double top,const double bottom)
{
const datetime starts=iTime(_Symbol,0,2), ends=starts+PeriodSeconds()*N_bars;//time of start and end of the rectangle
const string name=prefix+"_"+(dir>0?"DEMAND":"SUPPLY")+"_"+TimeToString(starts);//name would be unique sinse we use time of start of the range. DO NOT FORGET about prefix - it should be declared globally, you would be able to delete all the objects with 'ObjectsDeleteAll()' function that accepts prefix in one of its implementations.
if(!ObjectCreate(0,name,OBJ_RECTANGLE,0,0,0,0,0))
{
printf("%i %s: failed to create %s. error=%d",__LINE__,__FILE__,name,_LastError);
return false;
}
ObjectSetInteger(0,name,OBJPROP_TIME1,starts);
ObjectSetInteger(0,name,OBJPROP_TIME2,ends);
ObjectSetDouble(0,name,OBJPROP_PRICE1,top);
ObjectSetDouble(0,name,OBJPROP_PRICE2,bottom);
//add color, width, filling color, access modifiers etc, example is here https://docs.mql4.com/ru/constants/objectconstants/enum_object/obj_rectangle
return true;
}
这是主要的块,不要忘了添加一个新的条形检查,否则该工具将在每个刻度上检查对象,这很浪费时间。字符串前缀=“”; //为所有对象添加一些唯一的前缀const int N_bars = 15; //本例中为15条
void OnDeinit(const int reason){ObjectsDeleteAll(0,prefix);}
void OnTick()
{
if(!isNewBar())
return; //not necessary but waste of time to check every second
const bool pattern1Up=isPattern1Detected(1), pattern1Dn=isPattern1Detected(-1);
if(pattern1Up)
{
double top,bottom;
detectRangeOfZone(top,bottom,1);
drawRectangle(1,top,bottom);
PlacePendingOrder(1,top,bottom);
}
if(pattern1Dn)
{
double top,bottom;
detectRangeOfZone(top,bottom,-1);
drawRectangle(-1,top,bottom);
PlacePendingOrder(-1,top,bottom);
}
}
int PlacePendingOrder(const EnmDir dir,const double oop,const double suggestedSl)
{
const double lot=0.10; //FOR EXAMPLE, PUT YOUR DATA HERE
const string comment="example for SOF";
const int magicNumber=123456789;
int cmd=dir>0 ? OP_BUY : OP_SELL;
double price=(dir>0 ? Ask : Bid), spread=(Ask-Bid);
if(dir*(oop-price)>spread)
cmd+=(OP_BUYSTOP-OP_BUY);
else if(dir*(price-oop)>spread)
cmd+=(OP_BUYLIMIT-OP_BUY);
int attempt=0, ATTEMPTS=5, SLEEP=25, SLIPPAGE=10, result=-1, error=-1;
while(attempt<ATTEMPTS)
{
attempt++;
RefreshRates();
if(cmd<=OP_SELL)
{
price=dir>0 ? Ask : Bid;
result=OrderSend(_Symbol,cmd,lot,price,SLIPPAGE,0,0,comment,magicNumber);
}
else
{
result=OrderSend(_Symbol,cmd,lot,oop,SLIPPAGE,0,0,comment,magicNumber);
}
if(result>0)
break;
error=_LastError;
Sleep(SLEEP);
}
if(result>0)
{
if(OrderSelect(result,SELECT_BY_TICKET))
{
price=OrderOpenPrice();
if(!OrderModify(result,price,suggestedSl,0,OrderExpiration()))
printf("%i %s: failed to modify %d. error=%d",__LINE__,__FILE__,result,_LastError);
//tp is zero, sl is suggested SL, put yours when needed
}
return result;
}
printf("%i %s: failed to place %s at %.5f. error=%d",__LINE__,__FILE__,EnumToString((ENUM_ORDER_TYPE)cmd),(cmd>OP_SELL ? oop : price),error);
return -1;
}
感谢您的回答。我试图解释需求区,但我认为我做得不好。这是我加入YouTube链接的主要原因。前几分钟详细解释了该模式,但仅着重强调了您所要求的一些内容。问题中的图像1和2指的是同一模式。通常,该模式从至少一根看涨蜡烛开始,然后是至少一根看跌蜡烛,然后是一根比开始时看涨蜡烛高的蜡烛。1/3
因此,看空蜡烛组中的最后一个看跌蜡烛是我们感兴趣的。它开放且低位构成需求区域。隐藏的需求区域由一组至少两个看涨蜡烛组成的看涨蜡烛表示,其高点高于先前的蜡烛高点,而低点低于先前的蜡烛低点。公开和低点构成隐藏需求区。我想显示N_bars的矩形是可以的。如果您能提供一个完整的示例,包括在识别出模式后使用SL和TP设置挂单,我将不胜感激。2/3
在更通用的情况下(其中包含多个看跌蜡烛)找到模式似乎是您的解决方案和条件5中缺少的主要内容,因为您说的是不必要的。3/3
@DanielKniaz要获得对这个问题的赏金,您会丢失一些东西,这是基于上述图像的更通用的模式识别器。我按照TopLeft的建议观看了视频的前几分钟,并且对它们进行了很好的描述。还缺少带有待定订单示例的经过测试的代码。
@OnlyCodeMatters,所有模式都不同。好的,pattern#1和pattern#2相似,我添加了有关如何实现#2的代码(与#1非常相似)。对于#3-它与#1或#2不同,在您或TS检查并理解为了识别模式#1所完成的所有步骤之后,对其进行编码将非常容易。添加了待定示例,在实现
isNewBar()
函数(MQL5.com上的文章或任何其他实现,或隐藏该块)之后,代码将编译。