//+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #include class Ranger { private: int counter; datetime start, vWapStart; string symbol; ENUM_TIMEFRAMES tf; CArrayDouble pr, md, rs; double vWap, stopLoss, takeProfit, close[]; //Определение диапазонов используя макд int RangeCheck() { //Хэндлы и подготовка int macd_handle = iMACD(symbol,tf,12,26,9,PRICE_CLOSE); double macd[], sig[]; ArraySetAsSeries(macd, true); ArraySetAsSeries(sig, true); //UPD 3 значения в буфере необходимы что бы избежать перерисовки, путем сдвига на 2-1 индекс вместо 1-0 CopyBuffer(macd_handle,0,0,3,macd); CopyBuffer(macd_handle,1,0,3,sig); if((macd[2] > 0 && macd[1] < 0) || (macd[2] < 0 && macd[1] > 0)) { start = TimeCurrent(); } else if (start != TimeCurrent() && ((macd[1] > 0 && sig[2] < macd[2] && sig[1] > macd[1]) || (macd[1] < 0 && sig[2] > macd[2] && sig[1] < macd[1]))) { counter = Bars(symbol,tf,start,TimeCurrent()); start = TimeCurrent(); } return ((counter > 2 && macd[1] < 0) ? counter+1 : (counter > 2 && macd[1] > 0) ? -counter-1 : NULL); }; //Заполнение массивов экстремумами //Разобраться с заполнением данными, косяки со сдвигами присутствуют//done for now?? void Arranger()//Сбор и упорядочивание данных для последующих процедур { int range = MathAbs(RangeCheck()); if(range-2 > 0 && range < 10000) { //Volume tests MqlRates candle[]; MqlRates daily[]; long volArray[]; vector volume; ArraySetAsSeries(volArray, true); ArraySetAsSeries(candle, true); ArraySetAsSeries(daily,true); CopyRates(symbol,tf,1,range,candle); CopyRates(symbol,PERIOD_D1,0,1,daily); int totalBars = Bars(symbol,tf,daily[0].time,TimeCurrent()); double avgVol = (double)daily[0].tick_volume/totalBars; //Print("Daily Avg Vol: ", avgVol); //CopyTickVolume(symbol,tf,candle[range-1].time,candle[1].time,volArray); ArrayResize(volArray,range); for(int i=0; i Хэндлы и подготовка int macd_handle = iMACD(symbol,tf,12,26,9,PRICE_CLOSE); int rsi_handle = iRSI(symbol,tf,14,PRICE_CLOSE); double price[], macd[], rsi[]; ArraySetAsSeries(price, true); ArraySetAsSeries(macd, true); ArraySetAsSeries(rsi, true); //Получение последней клозины CopyClose(symbol,tf,0,1,close); //Заполнение массивов индикаторов CopyBuffer(macd_handle,0,0,range,macd); CopyBuffer(rsi_handle,0,0,range,rsi); //Проверка какой из экстремумов использовать, заполнение массива price if(macd[0] < 0) { ArrayResize(price,range); for(int i=0; i 0 && ((md.At(0) > 0 && md.At(md.Total()-1) < 0) || (md.At(0) < 0 && md.At(md.Total()-1) > 0))) { pr.Shutdown(); md.Shutdown(); rs.Shutdown(); vWapStart = NULL; return; } } }; public: double Rrange(string currentSymbol, ENUM_TIMEFRAMES currentTF, int rangesToSignal) { //Конструктор для дальнейшей передачи в Arranger //Доработать проверку на спред. При большом среднем(?) спреде(?) игнорить вход целиком symbol = currentSymbol; tf = currentTF; double signal = 0; Arranger(); //Формирование векторов при условии достаточного количества значений, иначе выход if(pr.Total() == rangesToSignal && md.Total() == rangesToSignal && rs.Total() == rangesToSignal) { if((md.At(rangesToSignal-2) > 0 && md.At(rangesToSignal-1) > 0) || (md.At(rangesToSignal-2) < 0 && md.At(rangesToSignal-1) < 0)) { int bb_handle = iBands(symbol,PERIOD_M30,20,0,2,PRICE_CLOSE); double upper[], mid[], lower[]; ArraySetAsSeries(upper,true); ArraySetAsSeries(mid,true); ArraySetAsSeries(lower,true); CopyBuffer(bb_handle,1,0,3,upper); CopyBuffer(bb_handle,0,0,3,mid); CopyBuffer(bb_handle,2,0,3,lower); if(md.At(rangesToSignal-1) > 0 && (close[0] > upper[0] || close[0] < mid[0])) { pr.Shutdown(); md.Shutdown(); rs.Shutdown(); vWapStart = NULL; //Print("BB range check false"); return 0; } else if(md.At(rangesToSignal-1) < 0 && (close[0] < lower[0] || close[0] > mid[0])) { pr.Shutdown(); md.Shutdown(); rs.Shutdown(); vWapStart = NULL; //Print("BB range check false"); return 0; } vector priceRange, mdRange, rsRange; priceRange.Init(rangesToSignal); mdRange.Init(rangesToSignal); rsRange.Init(rangesToSignal); for(int i=0; i 0 && (mdCorr < 0 || rsCorr < 0)) { //Подключаем VWAP int vWapBars = Bars(symbol,tf,vWapStart,TimeCurrent()); MqlRates candle[]; double price[]; long volumeArray[]; vector wap, volume; ArraySetAsSeries(candle, true); ArraySetAsSeries(price, true); ArraySetAsSeries(volumeArray, true); ArrayResize(volumeArray,vWapBars); ArrayResize(price,vWapBars); CopyRates(symbol,tf,0,vWapBars,candle); for(int i=0; i 0 && mdCorr*rsCorr > 0 && (mdCorr < 0 || rsCorr < 0)) { //Подключаем VWAP int vWapBars = Bars(symbol,tf,vWapStart,TimeCurrent()); MqlRates candle[]; double price[]; long volumeArray[]; vector wap, volume; ArraySetAsSeries(candle, true); ArraySetAsSeries(price, true); ArraySetAsSeries(volumeArray, true); ArrayResize(volumeArray,vWapBars); ArrayResize(price,vWapBars); CopyRates(symbol,tf,0,vWapBars,candle); for(int i=0; i