www.opentraders.ru/downloads/497/

#property copyright "MA МТФ. +MA.mq4 2.2. Copyright © FXcoder, 2008-2014"
#property link "http://fxcoder.ru"
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Crimson
#property indicator_color2 C'165,15,45'
#property indicator_color3 C'110,10,30'
#property indicator_color4 C'55,5,15'
/* Параметры расчета */
// период MA
extern int MAPeriod = 20;
// метод расчёта
extern int MAMethod = MODE_SMA;
// ТФ расчета, 0 - текущий
extern int TimeFrame = 1440;
// интерполяция: false - расчет на ТФ, true - интерполяция
extern bool Interpolate = false;
// расчетный тип цены
extern int AppliedPrice = PRICE_CLOSE;
/* Оформление */
// основной цвет
extern color LineColor = Crimson;
// цвет касания
extern color TouchColor = CLR_NONE;
// стиль линии
extern int LineStyle = STYLE_SOLID;
// толщина линии (работает только для стиля STYLE_SOLID)
extern int LineWidth = 1;
// чувствительность касания, 0 - отключено
extern int TouchDistance = 300;
double MA1[], MA2[], MA3[], MA4[];
int mc = 4;
int maPeriod;
int tf;
int init()
{
tf = TimeFrame > 0 ? TimeFrame : Period();
maPeriod = MAPeriod * tf / Period();
int db = MAPeriod;
if (Interpolate)
db = maPeriod;
SetIndexBuffer(0, MA1);
SetIndexBuffer(1, MA2);
SetIndexBuffer(2, MA3);
SetIndexBuffer(3, MA4);
string mas = MAMethodToString(MAMethod);
string l = mas + MAPeriod + "@" + PeriodToStr(tf) + (Interpolate ? " (~" + mas + maPeriod + ")" : "");
for (int i = 0; i < mc; i++)
{
SetIndexDrawBegin(i, db);
SetIndexLabel((mc - 1) - i, l);
}
IndicatorShortName(WindowExpertName() + ": " + l);
updateColors();
return(0);
}
int start()
{
// недостаточно баров для расчёта даже одного бара
if (Interpolate && (Bars - maPeriod - 1 < 1))
return(0);
// тф индикатора меньше текущего
if (!Interpolate && tf < Period())
return(0);
// На больших ТФ не соблюдаются соотношения периодов
if (Interpolate && (tf > 1440 || Period() > 1440))
return(0);
int countedBars = IndicatorCounted();
if (countedBars > 0)
countedBars--;
int barsToCalc = Bars - countedBars;
if (!Interpolate)
barsToCalc = MathMax(barsToCalc, TimeFrame / Period());
// Всегда считать на один бар больше (необходимо для отбражения касания)
barsToCalc = MathMin(barsToCalc + 1, Bars);
// обновить цвета
updateColors();
double ma, ma1;
// предыдущие значения, нужны для оптимизации
double prevMA = 0;
int prevJ0 = -1;
//
for (int i = barsToCalc - 1; i >= 0 ; i--)
{
MA1[i] = EMPTY_VALUE;
MA2[i] = EMPTY_VALUE;
MA3[i] = EMPTY_VALUE;
MA4[i] = EMPTY_VALUE;
if (Interpolate)
{
ma = iMA(NULL, 0, maPeriod, 0, MAMethod, AppliedPrice, i);
ma1 = iMA(NULL, 0, maPeriod, 0, MAMethod, AppliedPrice, i + 1);
}
else
{
int per=Period();
int k=TimeFrame/per;
ma = iMA(NULL, 0, maPeriod*k, 0, MAMethod, AppliedPrice, i);
ma1 = iMA(NULL, 0, maPeriod*k, 0, MAMethod, AppliedPrice, i + 1);
}
MA1[i] = ma;
// Расстояние от линии до цены
double distance = MathMin(MathAbs(ma - High[i]), MathAbs(Low[i] - ma)) / Point;
if (TouchDistance > 0)
{
if (High[i] >= ma && Low[i] <= ma)
{
distance = 0;
}
if (distance < 2 * TouchDistance)
{
MA2[i] = ma;
MA2[i+1] = ma1;
}
if (distance < 1 * TouchDistance)
{
MA3[i] = ma;
MA3[i+1] = ma1;
}
if (distance == 0)
{
MA4[i] = ma;
MA4[i+1] = ma1;
}
}
}
return(0);
}
// Обновить цвета
void updateColors()
{
color freeColor = LineColor;
color touchColor = TouchColor;
if (ColorIsNone(freeColor))
freeColor = GetBGColor();
if (ColorIsNone(touchColor))
touchColor = GetBGColor();
for (int i = 0; i < mc; i++)
{
SetIndexStyle(i, DRAW_LINE, LineStyle, LineWidth, MixColors(freeColor, touchColor, 1.0 * i / mc, 1));
}
}
#import "gdi32.dll"
int GetPixel(int hDC, int x, int y);
#import
#import "user32.dll"
int GetWindowDC(int h);
int ReleaseDC(int h, int hDC);
#import
int IntPutInRange(int value, int from, int to)
{
if (to >= from)
{
if (value > to)
value = to;
else if (value < from)
value = from;
}
return(value);
}
double DoublePutInRange(double value, double from, double to)
{
if (to >= from)
{
if (value > to)
value = to;
else if (value < from)
value = from;
}
return(value);
}
/* Гиперболические функции */
color GetBGColor(int h = 0)
{
color bgColor = CLR_NONE;
if (h == 0)
h = WindowHandle(Symbol(), Period());
// Получить цвет фона заданного окна
if (h != 0)
{
int hDC = GetWindowDC(h);
// Отрезок из двух точек, пересекающий рамку чарта
int c1 = GetPixel(hDC, 3, 10); // фон
int c2 = GetPixel(hDC, 4, 10); // рамка
// Если рамка есть, то цвет определен верно (окно активно)
if (c1 != c2)
bgColor = c1;
ReleaseDC(h, hDC);
}
return(bgColor);
}
bool ColorToRGB(color c, int& r, int& g, int& b)
{
// Если цвет задан неверный, либо задан как отсутствующий, вернуть false
if ((c >> 24) > 0)
{
r = 255;
g = 255;
b = 255;
return(false);
}
// 0x00BBGGRR
b = (c & 0xFF0000) >> 16;
g = (c & 0x00FF00) >> 8;
r = (c & 0x0000FF);
return(true);
}
color RGBToColor(int r, int g, int b)
{
// 0x00BBGGRR
return(((b & 0x0000FF) << 16) + ((g & 0x0000FF) << 8) + (r & 0x0000FF));
}
color MixColors(color color1, color color2, double mix, double step = 16)
{
// Коррекция параметров
step = DoublePutInRange(step, 1.0, 255.0);
mix = DoublePutInRange(mix, 0.0, 1.0);
int r1, g1, b1;
int r2, g2, b2;
// Разбить на компоненты
ColorToRGB(color1, r1, g1, b1);
ColorToRGB(color2, r2, g2, b2);
// вычислить
int r = IntPutInRange(MathRound((r1 + mix * (r2 - r1)) / step) * step, 0, 255);
int g = IntPutInRange(MathRound((g1 + mix * (g2 - g1)) / step) * step, 0, 255);
int b = IntPutInRange(MathRound((b1 + mix * (b2 - b1)) / step) * step, 0, 255);
return(RGBToColor(r, g, b));
}
bool ColorIsNone(color c)
{
return((c >> 24) > 0);
}
string PeriodToStr(int period = 0)
{
if (period == 0)
period = Period();
if (period < PERIOD_H1)
return(StringConcatenate("M", period));
else if (period < PERIOD_D1 && period % 60 == 0)
return(StringConcatenate("H", period / 60));
else if (period < PERIOD_W1 && period % 1440 == 0)
return(StringConcatenate("D", period / 1440));
else if (period == PERIOD_MN1 && period % 10080 == 0)
return(StringConcatenate("W", period / 10080));
else if (period == PERIOD_MN1)
return("MN1");
else
return(StringConcatenate("M", period));
}
string MAMethodToString(int mm)
{
switch (mm)
{
case MODE_SMA: return("SMA");
case MODE_EMA: return("EMA");
case MODE_SMMA: return("SMMA");
case MODE_LWMA: return("LWMA");
default: return("MA(type " + mm +")");
}
}
// 2014-02-15 15:44:12 UTC
// MQLMake 1.20. Copyright © FXcoder, 2011-2014. http://fxcoder.ru
AM2