//+------------+-----------------------------------------------------+ //| v.11.09.06 | SnakeInBorders.mq4 | //+------------+ "ФИЛЬТРУЙ БАЗАР!" | //| Комплект | Bookkeeper, 2006, yuzefovich@gmail.com | //+------------------------------------------------------------------+ //| Snake рассчитывает коридор отфильтрованного рынка, ограниченный | //| двумя бордюрами BorderTop[] и BorderBot[], и сигнальную Mart[]. | //| | //| Внешние переменные: | //| SnakeRange - полупериод расчета оси Snake'а Axis[] - оптимально | //| = 4; | //| FilterPeriod - период фильтрации. ( оптимально больше 13); | //| MartFiltr - коэффициент фильтрации рынка. Чем MartFiltr больше, | //| тем уже коридор отфильтрованного рынка. Коэффициент надо | //| подбирать, по умолчанию = 2; | //| У Snake'а два режима: HardCalc = true - не пересчитывать, и | //| = false - пересчитывать значения Axis[Pos]...[Pos+SnakeRange+1].| //| Поведение сигнальной Mart[] внутри коридора: | //| При движении рынка вверх - сигнальная отходит от нижнего | //| бордюра, пересекает коридор и сливается с верхним бордюром. | //| Аналогично, с точностью до наоборот, - при движении рынка вниз. | //| До тех пор, пока рынок будет двигаться направленно, сигнальная | //| будет "держаться" соответствующей границы коридора. При этом | //| увеличение ширины коридора означает направленное движение. При | //| колебаниях рынка коридор начинает сужаться. Сужением коридора | //| сопровождается движением сигнальной от одной границы к другой | //| внутри коридора, после достижения противоположной границы - | //| коридор начнет расширяться. | //| Snake можно использовать как самостоятельно, сравнивая движение | //| сигнальной на разных ТФ одновременно, так и для построения | //| других индикаторов, используя Mart[] вместо цены бара. Для | //| индикаторов типа MA, OA, AC,.. использовать HardCalc = true, а | //| для индикаторов типа ZigZag, Channel,.. - HardCalc = false, а | //| значение MartFiltr подбирать от 3...5. При этом можно отсеивать | //| истинные и ложные вершины: если вершина промежуточная, | //| сигнальная Mart[] не будет совпадать с бордюром. | //+------------------------------------------------------------------+ #property copyright "" #property link "yuzefovich@gmail.com" //---- #property indicator_chart_window #property indicator_buffers 3 #property indicator_color1 Red #property indicator_color2 Red #property indicator_color3 Blue //---- extern int SnakeRange = 2; extern int FilterPeriod = 24; extern double MartFiltr = 2; extern bool HardCalc = true; //---- double BorderTop[]; double BorderBot[]; double Mart[]; double Axis[]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void deinit() { Comment(""); return; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int init() { int draw_begin; draw_begin = FilterPeriod + SnakeRange + 2; IndicatorBuffers (4); SetIndexBuffer (0, BorderTop); SetIndexBuffer (1, BorderBot); SetIndexBuffer (2, Mart); SetIndexBuffer (3, Axis); SetIndexStyle (0, DRAW_LINE); SetIndexStyle (1, DRAW_LINE); SetIndexStyle (2, DRAW_LINE, 0, 2); SetIndexDrawBegin (0, draw_begin); SetIndexDrawBegin (1, draw_begin); SetIndexDrawBegin (2, draw_begin); return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int start() { int counted_bars = IndicatorCounted(); int limit, i; if(counted_bars < 0) return(-1); if(Bars <= (FilterPeriod + SnakeRange+2)) return(0); if(SnakeRange < 4) SnakeRange = 4; if(counted_bars > 0) counted_bars--; limit = Bars - counted_bars; for(i = limit; i >= 0; i--) MainCalculation(i); return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void MainCalculation(int Pos) { int v; MartAxis(Pos); if(HardCalc == true) SmoothOverMart2(Pos); else SmoothOverMart(Pos); //---- return; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void MartAxis(int Pos) { int SnakeWeight, i, w, ww, Shift; double SnakeSum; Axis[Pos] = iMA(NULL, 0, SnakeRange + 1, 0, MODE_LWMA, PRICE_WEIGHTED, Pos); for(Shift = Pos + SnakeRange + 2; Shift > Pos; Shift--) { SnakeSum = 0.0; SnakeWeight = 0; i = 0; w = Shift + SnakeRange; ww = Shift - SnakeRange; if(ww < Pos) ww = Pos; while(w >= Shift) { i++; SnakeSum = SnakeSum + i*SnakePrice(w); SnakeWeight = SnakeWeight + i; w--; } while(w >= ww) { i--; SnakeSum = SnakeSum + i*SnakePrice(w); SnakeWeight = SnakeWeight + i; w--; } Axis[Shift] = SnakeSum / SnakeWeight; } return; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double SnakePrice(int Shift) { return((2*Close[Shift] + High[Shift] + Low[Shift]) / 4); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void SmoothOverMart(int Pos) { // Правим историю на последних Pos...(Pos+SnakeRange+2) барах int Shift; double a, t, b; for(Shift = Pos + SnakeRange + 2; Shift >= Pos; Shift--) { t = Axis[ArrayMaximum(Axis, FilterPeriod, Shift)]; b = Axis[ArrayMinimum(Axis, FilterPeriod, Shift)]; a = Axis[Shift]; BorderTop[Shift] = (2*(1 + MartFiltr)*a + (t - b)) / 2 / (1 + MartFiltr); BorderBot[Shift] = (2*(1 + MartFiltr)*a - (t - b)) / 2 / (1 + MartFiltr); Mart[Shift] = (2*(2 + MartFiltr)*a - (t + b)) / 2 / (1 + MartFiltr); } return; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void SmoothOverMart2(int Shift) { // Не подправляем историю на последних барах double a, t, b; t = Axis[ArrayMaximum(Axis, FilterPeriod, Shift)]; b = Axis[ArrayMinimum(Axis, FilterPeriod, Shift)]; a = Axis[Shift]; BorderTop[Shift] = (2*(1 + MartFiltr)*a + (t - b))/2/(1 + MartFiltr); BorderBot[Shift] = (2*(1 + MartFiltr)*a - (t - b))/2/(1 + MartFiltr); Mart[Shift] = (2*(2 + MartFiltr)*a - (t + b)) / 2 / (1 + MartFiltr); return; } //---------------------------------------------------------------------