artmedia70 вы то врятли сможете ;)
Естественно, куда ж мне ...
Даю вам шанс попробовать =)
Скорее это ваш шанс разобраться, понять и написать. Нет? Главное - чёткое понимание того, что вам нужно. И начните с самого определения. Что для вас доджи?
Артем, насколько я мог бы описать доджи, почти уверен, что моё описание на языке mql вызовет всегда возражение в лице кого-то другого. Возможно можно лишь сойтись в том, что open будет равен close, а вот тени...)
artmedia70 нет, мой вопрос стоит прямо. Как вы бы описали паттерн доджи на mql?
Если это молот, то:
делим диапазон бара на 100 при бычьем молоте прибавляем определенный процент от 50% к лоу,
медвежьем отнимаем от хай. Потом проверяем опен и клоз ниже или выше.
А, если по существу они не работают. Как-то пробовал бычьи и медвежьи молоты складывать для
индикатора и смотреть пересечение. Тоже не "грааль".
Похвастаюсь. У меня это выглядит так (класс детектора-дожи и высокой волны и дальше - класс детектора "несколько дожи или высоких волн"):
MQH файл:
#include <MyLib\Indicators\Patterns\PatternDetectorT.mq5>
enum EDojiOrHW
{
DOH_DOJI_ONLY,
DOH_HIGHWAVE_ONLY,
DOH_DOJI_OR_HW
};
class CDojiHWDetector:public CPatternDetectorT
{
public:
static const uint DOJI_PATTERN_SIZE;
protected:
double m_dDojiMaxSize;
EDojiOrHW m_dohMode;
virtual uint _GetTestedPurePatternSize(int & riShiftOfPattern) { riShiftOfPattern = GetShift(); return(DOJI_PATTERN_SIZE); }; // Должна быть перегружена в наследнике.
virtual bool _TestPurePattern(uint uiIdx);
bool _TestOnDoji(uint uiIdx);
bool _TestOnHighWave(uint uiIdx);
public:
CDojiHWDetector(int iShiftFromBar,EDojiOrHW dohMode,double dDojiMaxSize = 0):CPatternDetectorT(iShiftFromBar) { m_piPatternID = PID_DOJI; ASSERT(dDojiMaxSize >=0); m_dDojiMaxSize = dDojiMaxSize; m_dohMode = dohMode; };
~CDojiHWDetector() {};
};
class CNDojiDetector:public CPatternDetectorT
{
protected:
static const double TRENDLINE_EXT_DISTANCE;
static const double TRENDLINE_SL_MARGIN;
static const double PATTERN_EXT_SL_MARGIN;
uint m_uiNumOfDoji;
double m_dDojiMaxSize;
EDojiOrHW m_dohMode;
virtual uint _GetTestedPurePatternSize(int & riShiftOfPattern) { riShiftOfPattern = GetShift(); return(0); };
virtual bool _CreateAndInitSubpatterns(CMySeriesContainerI* pmscContainer);
public:
CNDojiDetector(int iShiftFromBar,uint uiNumOfDoji,EDojiOrHW dohMode,double dDojiMaxSize = 0):CPatternDetectorT(iShiftFromBar) { m_piPatternID = PID_NDOJI;ASSERT(uiNumOfDoji >0); ASSERT(dDojiMaxSize >=0); m_uiNumOfDoji = uiNumOfDoji; m_dDojiMaxSize = dDojiMaxSize; m_dohMode = dohMode;};
~CNDojiDetector() {};
virtual bool GetTrailingSLTP(CPositionInfo *ppiPosition,CTrendLineCollection* ptlcTrendLines,CPriceLevelCollection* pplcSRLevels,double &dSL,double &dTP);
};
Файл mq5:
#property library
#include <MyLib\Indicators\Patterns\DojiHWDetector.mqh>
const uint CDojiHWDetector::DOJI_PATTERN_SIZE = 1;
bool CDojiHWDetector::_TestOnHighWave(uint uiIdx)
{
if(_HighShadow(uiIdx) < _Body(uiIdx))
return(false);
if(_LowShadow(uiIdx) < _Body(uiIdx))
return(false);
return(true);
};
bool CDojiHWDetector::_TestOnDoji(uint uiIdx)
{
if(_Body(uiIdx) > m_dDojiMaxSize)
return(false);
return(true);
};
bool CDojiHWDetector::_TestPurePattern(uint uiIdx)
{
RETURN_IF_FALSE(_BarExists(uiIdx));
switch(m_dohMode)
{
case DOH_DOJI_ONLY:
return(_TestOnDoji(uiIdx));
case DOH_HIGHWAVE_ONLY:
return(_TestOnHighWave(uiIdx));
case DOH_DOJI_OR_HW:
if(_TestOnDoji(uiIdx))
return(true);
return(_TestOnHighWave(uiIdx));
default:
break;
};
ASSERT(false);
return(false);
};
const double CNDojiDetector::TRENDLINE_EXT_DISTANCE = 0.0100;
const double CNDojiDetector::TRENDLINE_SL_MARGIN = 0.0030;
const double CNDojiDetector::PATTERN_EXT_SL_MARGIN = 0.0050;
bool CNDojiDetector::_CreateAndInitSubpatterns(CMySeriesContainerI* pmscContainer)
{
CDojiHWDetector* pddDetector;
for(int iCurShift = 0; iCurShift<(int)m_uiNumOfDoji; ++iCurShift)
{
pddDetector = new CDojiHWDetector(iCurShift,m_dohMode,m_dDojiMaxSize);
if(_AddSubPatternWithInit(pddDetector,pmscContainer) == false)
{
delete pddDetector;
return(false);
};
if((pddDetector.Init(pmscContainer)) != true)
return(false);
};
return(true);
};
bool CNDojiDetector::GetTrailingSLTP(CPositionInfo *ppiPosition,CTrendLineCollection* ptlcTrendLines,CPriceLevelCollection* pplcSRLevels,double &dSL,double &dTP)
{
ASSERT_STDPOINTER_OR_NULL(ppiPosition);
ASSERT(ptlcTrendLines != NULL);
ASSERT(pplcSRLevels != NULL);
// Проверим, может быть, позиции и нет ?
if(ppiPosition == NULL)
return(false);
uint uiExtremumIdx = UINT_MAX;
double dMaxOrMin = EMPTY_VALUE;
CTrendLine* ptlTrendline = NULL;
double dSuggestedSL = EMPTY_VALUE;
if(ppiPosition.PositionType() == POSITION_TYPE_SELL)
{
uiExtremumIdx = GetPatternExtremum(true,dMaxOrMin);
TRACE_DATETIME("Момент экстремума ",_Moment(uiExtremumIdx));
TRACE_DOUBLE5("Экстремум модели ",dMaxOrMin);
ptlTrendline = ptlcTrendLines.GetExtremalTrendline(TREND_DOWN,uiExtremumIdx,_Close(1),dMaxOrMin,TRENDLINE_EXT_DISTANCE);
if(ptlTrendline != NULL)
{
TRACE_DOUBLE5("Цена трендлинии на сформировавшемся баре ",ptlTrendline.PriceOnIdx(1));
dSuggestedSL = ptlTrendline.PriceOnIdx(1)+TRENDLINE_SL_MARGIN;
TRACE_DOUBLE5("Выставляем СЛ чуть выше трендлинии: ",dSuggestedSL);
}
else
{
dSuggestedSL = dMaxOrMin+PATTERN_EXT_SL_MARGIN;
TRACE_DOUBLE5("Выставляем СЛ чуть выше экстремума паттерна ",dSuggestedSL);
}
if(dSuggestedSL < ppiPosition.StopLoss())
{
dSL = dSuggestedSL;
return(true);
};
TRACE_DOUBLE5("Текущий СЛ ",ppiPosition.StopLoss());
TRACE("Предложенные СЛ больше текущего, трейлинг невозможен");
return(false);
};
ASSERT( ppiPosition.PositionType() == POSITION_TYPE_BUY);
uiExtremumIdx = GetPatternExtremum(false,dMaxOrMin);
TRACE_DATETIME("Момент экстремума ",_Moment(uiExtremumIdx));
TRACE_DOUBLE5("Экстремум модели ",dMaxOrMin);
ptlTrendline = ptlcTrendLines.GetExtremalTrendline(TREND_UP,uiExtremumIdx,_Close(1),dMaxOrMin,TRENDLINE_EXT_DISTANCE);
if(ptlTrendline != NULL)
{
TRACE_DOUBLE5("Цена трендлинии на полностью сформированном баре ",ptlTrendline.PriceOnIdx(1));
dSuggestedSL = ptlTrendline.PriceOnIdx(1)- TRENDLINE_SL_MARGIN;
TRACE_DOUBLE5("Выставляем СЛ чуть ниже трендлинии ",dSuggestedSL);
}
else
{
dSuggestedSL = dMaxOrMin - PATTERN_EXT_SL_MARGIN;
TRACE_DOUBLE5("Выставляем СЛ чуть ниже экстремума ",dSuggestedSL);
}
if(dSuggestedSL > ppiPosition.StopLoss())
{
dSL = dSuggestedSL;
return(true);
};
TRACE_DOUBLE5("Текущий СЛ ",ppiPosition.StopLoss());
TRACE("Предложенные СЛ меньше текущего, трейлинг невозможен");
return(false);
};
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования