From 32af8d84a29de5e6dabf4e72c320516d6a257a05 Mon Sep 17 00:00:00 2001 From: 9nix6 Date: Tue, 5 Dec 2017 13:16:14 +0100 Subject: [PATCH] Update to version 2.02 --- ...arsExample.mq5 => RangeBars_ExampleEA.mq5} | 80 +- Experts/RangeBars_ExampleEA2.mq5 | 233 ++++++ Include/AZ-INVEST/SDK/CommonSettings.mqh | Bin 0 -> 10014 bytes Include/AZ-INVEST/SDK/RangeBarIndicator.mqh | 766 ++++++++++++++++++ Include/AZ-INVEST/SDK/RangeBarSettings.mqh | 345 ++++++++ Include/{ => AZ-INVEST/SDK}/RangeBars.mqh | 356 ++++---- Include/AZ-INVEST/SDK/TradeFunctions.mqh | 611 ++++++++++++++ Include/RangeBarIndicator.mqh | 309 ------- Include/RangeBarSettings.mqh | 318 -------- Indicators/RangeBars/RangeBars_ADX.mq5 | 203 +++++ .../RangeBars/RangeBars_AroonOscillator.mq5 | Bin 0 -> 21704 bytes Indicators/RangeBars/RangeBars_CCI.mq5 | 168 ++++ Indicators/RangeBars/RangeBars_ColorHMA.mq5 | Bin 0 -> 17254 bytes Indicators/RangeBars/RangeBars_Fractals.mq5 | 134 +++ .../RangeBars_Gann_Hi_Lo_Activator_SSL.mq5 | 175 ++++ .../RangeBars/RangeBars_HA_Smoothed.mq5 | Bin 0 -> 18284 bytes .../RangeBars/RangeBars_Heiken_Ashi.mq5 | 137 ++++ Indicators/RangeBars/RangeBars_Ichimoku.mq5 | 179 ++++ Indicators/RangeBars/RangeBars_MA.mq5 | 257 ++++++ Indicators/{ => RangeBars}/RangeBars_MACD.mq5 | 8 +- Indicators/RangeBars/RangeBars_Momentum.mq5 | 147 ++++ .../RangeBars/RangeBars_ParabolicSAR.mq5 | 248 ++++++ Indicators/RangeBars/RangeBars_ROC.mq5 | 136 ++++ Indicators/{ => RangeBars}/RangeBars_RSI.mq5 | 40 +- .../{ => RangeBars}/RangeBars_Stochastic.mq5 | 23 +- .../RangeBars/RangeBars_VEMA_Wilders_DMI.mq5 | 246 ++++++ Indicators/RangeBars/RangeBars_VWAP_lite.mq5 | 388 +++++++++ Indicators/RangeBars/RangeBars_WPR.mq5 | Bin 0 -> 12104 bytes Indicators/RangeBars/RangeBars_ZigZag.mq5 | 322 ++++++++ .../RangeBars/RangeBars_dt_oscillator.mq5 | 247 ++++++ Indicators/RangeBars/RangeBars_gmma.mq5 | Bin 0 -> 23606 bytes Indicators/RangeBars/RangeBars_volumes.mq5 | 139 ++++ 32 files changed, 5341 insertions(+), 874 deletions(-) rename Experts/{RangeBarsExample.mq5 => RangeBars_ExampleEA.mq5} (68%) create mode 100644 Experts/RangeBars_ExampleEA2.mq5 create mode 100644 Include/AZ-INVEST/SDK/CommonSettings.mqh create mode 100644 Include/AZ-INVEST/SDK/RangeBarIndicator.mqh create mode 100644 Include/AZ-INVEST/SDK/RangeBarSettings.mqh rename Include/{ => AZ-INVEST/SDK}/RangeBars.mqh (57%) create mode 100644 Include/AZ-INVEST/SDK/TradeFunctions.mqh delete mode 100644 Include/RangeBarIndicator.mqh delete mode 100644 Include/RangeBarSettings.mqh create mode 100644 Indicators/RangeBars/RangeBars_ADX.mq5 create mode 100644 Indicators/RangeBars/RangeBars_AroonOscillator.mq5 create mode 100644 Indicators/RangeBars/RangeBars_CCI.mq5 create mode 100644 Indicators/RangeBars/RangeBars_ColorHMA.mq5 create mode 100644 Indicators/RangeBars/RangeBars_Fractals.mq5 create mode 100644 Indicators/RangeBars/RangeBars_Gann_Hi_Lo_Activator_SSL.mq5 create mode 100644 Indicators/RangeBars/RangeBars_HA_Smoothed.mq5 create mode 100644 Indicators/RangeBars/RangeBars_Heiken_Ashi.mq5 create mode 100644 Indicators/RangeBars/RangeBars_Ichimoku.mq5 create mode 100644 Indicators/RangeBars/RangeBars_MA.mq5 rename Indicators/{ => RangeBars}/RangeBars_MACD.mq5 (96%) create mode 100644 Indicators/RangeBars/RangeBars_Momentum.mq5 create mode 100644 Indicators/RangeBars/RangeBars_ParabolicSAR.mq5 create mode 100644 Indicators/RangeBars/RangeBars_ROC.mq5 rename Indicators/{ => RangeBars}/RangeBars_RSI.mq5 (80%) rename Indicators/{ => RangeBars}/RangeBars_Stochastic.mq5 (88%) create mode 100644 Indicators/RangeBars/RangeBars_VEMA_Wilders_DMI.mq5 create mode 100644 Indicators/RangeBars/RangeBars_VWAP_lite.mq5 create mode 100644 Indicators/RangeBars/RangeBars_WPR.mq5 create mode 100644 Indicators/RangeBars/RangeBars_ZigZag.mq5 create mode 100644 Indicators/RangeBars/RangeBars_dt_oscillator.mq5 create mode 100644 Indicators/RangeBars/RangeBars_gmma.mq5 create mode 100644 Indicators/RangeBars/RangeBars_volumes.mq5 diff --git a/Experts/RangeBarsExample.mq5 b/Experts/RangeBars_ExampleEA.mq5 similarity index 68% rename from Experts/RangeBarsExample.mq5 rename to Experts/RangeBars_ExampleEA.mq5 index 8922d39..02222d3 100644 --- a/Experts/RangeBarsExample.mq5 +++ b/Experts/RangeBars_ExampleEA.mq5 @@ -1,6 +1,6 @@ #property copyright "Copyright 2017, AZ-iNVEST" #property link "http://www.az-invest.eu" -#property version "2.03" +#property version "2.05" #property description "Example EA showing the way to use the RangeBars class defined in RangeBars.mqh" // @@ -11,14 +11,13 @@ // the RangeBars indicator attached. // -#define SHOW_INDICATOR_INPUTS +//#define SHOW_INDICATOR_INPUTS // -// You need to include the rangeBars.mqh header file +// You need to include the RangeBars.mqh header file // -#include - +#include // // To use the RangeBars indicator in your EA you need do instantiate the indicator class (RangeBars) // and call the Init() method in your EA's OnInit() function. @@ -64,7 +63,7 @@ void OnDeinit(const int reason) } // -// At this point you may use the rangebars data fetching methods in your EA. +// At this point you may use the range bars data fetching methods in your EA. // Brief demonstration presented below in the OnTick() function: // @@ -107,7 +106,8 @@ void OnTick() // MA1[2] contains the 1st moving average value for the 2nd bar to the left from the latest (uncompleted) bar // MA1[3]..MA1[n] do not exist since we retrieved the values for 3 bars (defined by "numnberOfBars") // - // The values for the 2nd moving average are stored in MA2[] and are accessed identically to values of MA1[] (shown above) + // The values for the 2nd and 3rd moving average are stored in MA2[] & MA3[] + // and are accessed identically to values of MA1[] (shown above) } // @@ -117,25 +117,68 @@ void OnTick() // MqlRates RangeBarRatesInfoArray[]; // This array will store the MqlRates data for range bars - startAtBar = 1; // get values starting from the last completed bar. - numberOfBars = 2; // gat a total of 2 MqlRates values (for 2 bars starting from bar 1 (last completed)) + startAtBar = 0; // get values starting from the last completed bar. + numberOfBars = 3; // gat a total of 3 MqlRates values (for 3 bars starting from bar 0 (current uncompleted)) if(rangeBars.GetMqlRates(RangeBarRatesInfoArray,startAtBar,numberOfBars)) - { + { // - // Check if a range bars reversal bar has formed + // Check if a range bar reversal bar has formed // + + string infoString; - if((RangeBarRatesInfoArray[0].open < RangeBarRatesInfoArray[0].close) && - (RangeBarRatesInfoArray[1].open > RangeBarRatesInfoArray[1].close)) + if((RangeBarRatesInfoArray[1].open < RangeBarRatesInfoArray[1].close) && + (RangeBarRatesInfoArray[2].open > RangeBarRatesInfoArray[2].close)) { // bullish reversal + infoString = "Previous bar formed bullish reversal"; } - else if((RangeBarRatesInfoArray[0].open > RangeBarRatesInfoArray[0].close) && - (RangeBarRatesInfoArray[1].open < RangeBarRatesInfoArray[1].close)) + else if((RangeBarRatesInfoArray[1].open > RangeBarRatesInfoArray[1].close) && + (RangeBarRatesInfoArray[2].open < RangeBarRatesInfoArray[2].close)) { // bearish reversal + infoString = "Previous bar formed bearish reversal"; } + else + { + infoString = ""; + } + + // + // Output some data to chart + // + + Comment("\nNew bar opened on "+(string)RangeBarRatesInfoArray[0].time+ + "\nPrevious bar OPEN price:"+DoubleToString(RangeBarRatesInfoArray[1].open,_Digits)+", bar opened on "+(string)RangeBarRatesInfoArray[1].time+ + "\n"+infoString+ + "\n"); + } + + // + // All charts that contain real volume information (i.e. stocks, futures, ...) + // also contain the brekdown of volume into BUY, SELL and BUY/SELL volume. + // This data is accessed using the + // GetBuySellVolumeBreakdown(long &buy[], long &sell[], long &buySell[], int start, int count) + // method. Example below: + + double buyVolume[]; // This array will store the values of the BUY volume + double sellVolume[]; // This array will store the values of the SELL volume + double buySellVolume[]; // This array will store the values of the BUY/SELL volume + + // When you add BUY, SELL and BUY/SELL volume numbers for a bar they will be equal + // to the Real Volume number that can be accessed using the + // GetMqlRates(MqlRates &ratesInfoArray[], int start, int count) + // metod described above. + + startAtBar = 1; // get values starting from the last completed bar. + numberOfBars = 2; // gat a total of 2 values (for 2 bars starting from bar 1 (last completed)) + + if(rangeBars.GetBuySellVolumeBreakdown(buyVolume,sellVolume,buySellVolume,startAtBar,numberOfBars)) + { + // + // Apply your real volume analysis logic here... + // } // @@ -147,7 +190,8 @@ void OnTick() double HighArray[]; // This array will store the values of the high band double MidArray[]; // This array will store the values of the middle band double LowArray[]; // This array will store the values of the low band - startAtBar = 1; // get values starting from the last completed bar. + + startAtBar = 1; // get values starting from the last completed bar. numberOfBars = 20; // gat a total of 20 values (for 20 bars starting from bar 1 (last completed)) if(rangeBars.GetDonchian(HighArray,MidArray,LowArray,startAtBar,numberOfBars)) @@ -167,7 +211,7 @@ void OnTick() // MidArray[] array will store the values of the middle band // LowArray[] array will store the values of the low band - startAtBar = 1; // get values starting from the last completed bar. + startAtBar = 1; // get values starting from the last completed bar. numberOfBars = 10; // gat a total of 10 values (for 10 bars starting from bar 1 (last completed)) if(rangeBars.GetBollingerBands(HighArray,MidArray,LowArray,startAtBar,numberOfBars)) @@ -187,7 +231,7 @@ void OnTick() // MidArray[] array will store the values of the SuperTrend value // LowArray[] array will store the values of the low SuperTrend line - startAtBar = 1; // get values starting from the last completed bar. + startAtBar = 1; // get values starting from the last completed bar. numberOfBars = 3; // gat a total of 3 values (for 3 bars starting from bar 1 (last completed)) if(rangeBars.GetSuperTrend(HighArray,MidArray,LowArray,startAtBar,numberOfBars)) diff --git a/Experts/RangeBars_ExampleEA2.mq5 b/Experts/RangeBars_ExampleEA2.mq5 new file mode 100644 index 0000000..012476d --- /dev/null +++ b/Experts/RangeBars_ExampleEA2.mq5 @@ -0,0 +1,233 @@ +#property copyright "Copyright 2017, AZ-iNVEST" +#property link "http://www.az-invest.eu" +#property version "1.00" +#property description "Example EA: Trading based on RangeBars SuperTrend signals." +#property description "One trade at a time. Each trade has TP & SL" + +// +// Helper functions for placing market orders. +// + +#include + +// +// Inputs +// + +input double InpLotSize = 0.1; +input int InpSLPoints = 200; +input int InpTPPoints = 600; + +input ulong InpMagicNumber=5150; +input ulong InpDeviationPoints = 0; +input int InpNumberOfRetries = 50; +input int InpBusyTimeout_ms = 1000; +input int InpRequoteTimeout_ms = 250; + +// +// Globa variables +// + +ENUM_POSITION_TYPE Signal; +ulong currentTicket; + +// +// SHOW_INDICATOR_INPUTS *NEEDS* to be defined, if the EA needs to be *tested in MT5's backtester* +// ------------------------------------------------------------------------------------------------- +// Using '#define SHOW_INDICATOR_INPUTS' will show the RangeBars indicator's inputs +// NOT using the '#define SHOW_INDICATOR_INPUTS' statement will read the settigns a chart with +// the RangeBars indicator attached. +// + +//#define SHOW_INDICATOR_INPUTS + +// +// You need to include the RangeBars.mqh header file +// + +#include +// +// To use the RangeBars indicator in your EA you need do instantiate the indicator class (RangeBars) +// and call the Init() method in your EA's OnInit() function. +// Don't forget to release the indicator when you're done by calling the Deinit() method. +// Example shown in OnInit & OnDeinit functions below: +// + +RangeBars * rangeBars; +CMarketOrder * marketOrder; + +//+------------------------------------------------------------------+ +//| Expert initialization function | +//+------------------------------------------------------------------+ +int OnInit() +{ + rangeBars = new RangeBars(); + if(rangeBars == NULL) + return(INIT_FAILED); + + rangeBars.Init(); + if(rangeBars.GetHandle() == INVALID_HANDLE) + return(INIT_FAILED); + + // + // Init MarketOrder class - used for placing market ortders. + // + + CMarketOrderParameters params; + { + params.m_async_mode = false; + params.m_magic = InpMagicNumber; + params.m_deviation = InpDeviationPoints; + params.m_type_filling = ORDER_FILLING_FOK; + + params.numberOfRetries = InpNumberOfRetries; + params.busyTimeout_ms = InpBusyTimeout_ms; + params.requoteTimeout_ms = InpRequoteTimeout_ms; + } + marketOrder = new CMarketOrder(params); + + return(INIT_SUCCEEDED); +} +//+------------------------------------------------------------------+ +//| Expert deinitialization function | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) +{ + if(rangeBars != NULL) + { + rangeBars.Deinit(); + delete rangeBars; + } + + // + // delete MarketOrder class + // + + if(marketOrder != NULL) + { + delete marketOrder; + } +} + +// +// At this point you may use the range bar data fetching methods in your EA. +// Brief demonstration presented below in the OnTick() function: +// + +//+------------------------------------------------------------------+ +//| Expert tick function | +//+------------------------------------------------------------------+ +void OnTick() +{ + // + // It is considered good trading & EA coding practice to perform calculations + // when a new bar is fully formed. + // The IsNewBar() method is used for checking if a new range bar has formed + // + + if(rangeBars.IsNewBar()) + { + + // + // Getting SuperTrend values is done using the + // GetSuperTrend(double &SuperTrendHighArray[], double &SuperTrendArray[], double &SuperTrendLowArray[], int start, int count) + // method. Example below: + // + + double HighArray[]; // This array will store the values of the high SuperTrend line + double MidArray[]; // This array will store the values of the middle SuperTrend line + double LowArray[]; // This array will store the values of the low SuperTrend line + + int startAtBar = 1; // get values starting from the last completed bar. + int numberOfBars = 2; // gat a total of 3 values (for 3 bars starting from bar 1 (last completed)) + + if(rangeBars.GetSuperTrend(HighArray,MidArray,LowArray,startAtBar,numberOfBars)) + { + // + // Read signal bar's time for optional debug log + // + + string barTime = ""; + MqlRates RangeBarRatesInfoArray[]; // This array will store the MqlRates data for range bars + if(rangeBars.GetMqlRates(RangeBarRatesInfoArray,startAtBar,numberOfBars)) + barTime = (string)RangeBarRatesInfoArray[0].time; + // + // + // + + if(SuperTrendSignal(HighArray,MidArray,LowArray,Signal,barTime)) + { + if(Signal == POSITION_TYPE_NONE) + return; + + // + // Trade signal on the SuperTrend indicator + // Open trade only if there are currntly no active trades + // + + if(!marketOrder.IsOpen(currentTicket,_Symbol,InpMagicNumber)) + { + if(Signal == POSITION_TYPE_BUY) + { + Print("BUY signal at "+barTime); // optional debug log + + if(marketOrder.Long(_Symbol,InpLotSize,InpSLPoints,InpTPPoints)) + Print("Long position opened."); + } + else if(Signal == POSITION_TYPE_SELL) + { + Print("SELL singal at "+barTime); // optional debug log + + if(marketOrder.Short(_Symbol,InpLotSize,InpSLPoints,InpTPPoints)) + Print("Short position opened."); + } + } + + + } + } + + } +} + +// +// Function determines the trade signal on the SuperTrend indicator +// + +bool SuperTrendSignal(double &H[], double &M[], double &L[], ENUM_POSITION_TYPE &signal,string time) +{ + if((H[1] == 0) && (L[1] == 0)) // no data to process + { + signal = POSITION_TYPE_NONE; + return false; + } + + // Uncomment line below for optional debug output: + //Print(time+": H[1] = "+DoubleToString(H[1],_Digits)+" L[0] = "+DoubleToString(L[0],_Digits)+" | L[1] = "+DoubleToString(L[1],_Digits)+" H[0] = "+DoubleToString(H[0],_Digits)); + + if((H[1] == M[1]) && (L[0] == M[0])) + { + // + // Super trend shifted from Low to High band => Buy Signal + // + + signal = POSITION_TYPE_BUY; + return true; + } + else if((L[1] == M[1]) && (H[0] == M[0])) + { + // + // Super trend shifted from High to Low band => Sell Signal + // + + signal = POSITION_TYPE_SELL; + return true; + } + + // + // No signal detected + // + + signal = POSITION_TYPE_NONE; + return false; +} \ No newline at end of file diff --git a/Include/AZ-INVEST/SDK/CommonSettings.mqh b/Include/AZ-INVEST/SDK/CommonSettings.mqh new file mode 100644 index 0000000000000000000000000000000000000000..33fcdbfa470462fadfe75cfd655759d40e2c09f4 GIT binary patch literal 10014 zcmcIqT~8ZF6ur-t`X5$}R1wiA@tTC7s1IPAfZ~8_J57@pL~TP*96&aN(5Sz*5B(Qy z&zZ|IcfGqaYfNPs&#cd!xpU8*J0IrXe;&xWOyvxJ$N0REYe{72>er~B$gzCH(?oud zR>{*;o=5|)N1~;5`3cxf`G6-UvM0YvTlz9U>+j_|_nv|65bqQ8lF0AiJd+7ZyTBa) zsrX&AeTAn#}+4T`PQ?vr6&*N#ckhX;4kGfINRWV z3;cm>$v$2khxz9IK7egUG6LrjkX>MU4*wcB;(HF2;JXC1ml(}NW1`3u%3Ii3N$eR<2$2(lz#Ax|Hcay0bq1GH5;SX<7z`>^dj?3o$cPT^7dmDc?k z(c}#x=m6@p5f3}?`Zj89`3*I;UR)(|k);iuKFXW0i;-2OmG$m9yy{1yezkmU$H%Cz zekosDzG9Z0AqE+TLwJLcW23+IwlnBH*u zs5-!`eh14qGX|K0EqRS6oI~o>4cUpKoPC>M zpYLNM*vAyMtAC4ql+BfS-!C2`)_Narca0BbNZMb{x=3_-IH&N2EdR>P~Y9cR|U#|L>@h(3;O1{H>p z@#*ODE%IzH!NPrM%un7|S&LIxF?1_?ok+8us){d;ZU#s%^0P1|vwI!4?vvX3!;xhuTHU#=HC0r14pa!)Sc z_0KK~Oc6Ugm2hrQ*E7_3F3EIG-2R`>xJK&9C6OOdXBOhwfN^_?R@`y1ui33dw2W`g z1@5_r_~e+I)9d73$NIaJRq%H_{0He&4DN-&m>;J<>`PVmVc&jp^vS+cm(p3c!)+j9R$ z>n@-SJv_uH>3eF(9qa(AF)P2osC``V+&ICTx>UV-;L1?eKL50;CC_3WwP@S^5^cLU zJM6#{cei`n&EaL*w{rcfkG$u7jAZB8q8GCm*@JFhp(Iz^DeM|Ub3HpQ>eC%W1Mde0 zcyo=_9wvzFUBn3Ed+1_@5pj3#b>R1_CHh#zH_Ss*Hx|aedT8H8I%A%vZN|L!yN}1B zzq2Rw1vAnBZRz)NPt>vUEj&C%7Gln!e|i3AM&%6M$0wD&y0O|?S%;hLCz#civj;xL z#uWXs5A{b?Ua5{ewR;l`nyKHxZrV>>7qydX3EOtz1I8P71k6fDcx$w2hRR#1xt_fq zS7s*fSFY!@b<1VFNzTT*GUZ!)BpWDa*Em%B2WcF&Tq;+CcXB2M{8qVhY>O*yD zd;Fygda7WwjB*NlONisWK=B^RTEd*b({(iu?@GGJw7X#9U6wytSe`@ZOr@{kv$LE< zi;j%*f-@qE4(-KfEkDBQIqNM;m-cn)GAM78t9?|**Qv|D%lkS-oZpYHQCn zRZ?qV`>mP{iRsx8tEkq({8rV5#B^=oH!M5en6?f4>SggUeffL2$7?NQf9e#?^wnAz zZ}m;1`ldO3wHD^L`le3pFy88$M)gf|`f4rAZ}m;1`ldO3wHD^L`le3p5WbnyS8E}B z1E+#aU6zUE9q3s8F3G(fn?|rr!^?7rcg+xC(>C0?u@iBdwZ7n{gFSD)1$Mj{kwfLC6%(fOE)0f%S;$!+U r+gf}~UuIj2kLk;7Yw + +class RangeBarIndicator +{ + private: + + RangeBars * rangeBars; + int rates_total; + int prev_calculated; + bool getVolumes; + bool getVolumeBreakdown; + bool getTime; + bool useAppliedPrice; + ENUM_APPLIED_PRICE applied_price; + + bool dataReady; + + public: + + datetime Time[]; + double Open[]; + double Low[]; + double High[]; + double Close[]; + double Price[]; + long Tick_volume[]; + long Real_volume[]; + double Buy_volume[]; + double Sell_volume[]; + double BuySell_volume[]; + bool IsNewBar; + + RangeBarIndicator(); + ~RangeBarIndicator(); + + void SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) { this.useAppliedPrice = true; this.applied_price = _applied_price; }; + void SetGetVolumesFlag() { this.getVolumes = true; }; + void SetGetVolumeBreakdownFlag() { this.getVolumeBreakdown = true; }; + void SetGetTimeFlag() { this.getTime = true; }; + + bool OnCalculate(const int rates_total,const int prev_calculated, const datetime &_Time[]); + int GetPrevCalculated() { return prev_calculated; }; + void BufferShiftLeft(double &buffer[]); + + private: + + bool CheckStatus(); + bool NeedsReload(); + int GetOLHC(int start, int count); + int GetOLHCForIndicatorCalc(double &o[],double &l[],double &h[],double &c[],datetime &t[],long &tickVolume[],long &realVolume[], double &buyVolume[], double &sellVolume[], double &buySellVolume[], int start, int count); + int GetOLHCAndApplPriceForIndicatorCalc(double &o[],double &l[],double &h[],double &c[],datetime &t[],long &tickVolume[],long &realVolume[], double &buyVolume[], double &sellVolume[], double &buySellVolume[], double &price[],ENUM_APPLIED_PRICE applied_price, int start, int count); + void OLHCShiftRight(); + void OLHCResize(); + + bool Canvas_IsNewBar(const datetime &_Time[]); + bool Canvas_IsRatesTotalChanged(int ratesTotalNow); + int Canvas_RatesTotalChangedBy(int ratesTotalNow); + + double CalcAppliedPrice(const MqlRates &_rates, ENUM_APPLIED_PRICE applied_price); + double CalcAppliedPrice(const double &o,const double &l,const double &h,const double &c,ENUM_APPLIED_PRICE applied_price); + + ENUM_TIMEFRAMES TFMigrate(int tf); + datetime iTime(string symbol,int tf,int index); +}; + +RangeBarIndicator::RangeBarIndicator(void) +{ + rangeBars = new RangeBars(); + if(rangeBars != NULL) + rangeBars.Init(); + + useAppliedPrice = false; + getVolumes = false; + getTime = false; + + dataReady = false; +} + +RangeBarIndicator::~RangeBarIndicator(void) +{ + if(rangeBars != NULL) + { + rangeBars.Deinit(); + delete rangeBars; + } +} + +bool RangeBarIndicator::CheckStatus(void) +{ + int handle = rangeBars.GetHandle(); + if(handle == INVALID_HANDLE) + return false; + + return true; +} + +bool RangeBarIndicator::NeedsReload(void) +{ + if(rangeBars.Reload()) + { + Print("Chart settings changed - reloading indicator with new settings"); + return true; + } + + return false; +} + +bool RangeBarIndicator::OnCalculate(const int _rates_total,const int _prev_calculated, const datetime &_Time[]) +{ + static bool firstRun = true; + + if(firstRun) + { + Canvas_IsNewBar(_Time); + Canvas_RatesTotalChangedBy(_rates_total); + IsNewBar = rangeBars.IsNewBar(); + + firstRun = false; + } + + if(!CheckStatus()) + { + if(rangeBars != NULL) + delete rangeBars; + + rangeBars = new RangeBars(); + if(rangeBars != NULL) + rangeBars.Init(); + + return false; + } + + ArraySetAsSeries(this.Time,false); + ArraySetAsSeries(this.Open,false); + ArraySetAsSeries(this.High,false); + ArraySetAsSeries(this.Low,false); + ArraySetAsSeries(this.Close,false); + ArraySetAsSeries(this.Price,false); + ArraySetAsSeries(this.Tick_volume,false); + ArraySetAsSeries(this.Real_volume,false); + ArraySetAsSeries(this.Buy_volume,false); + ArraySetAsSeries(this.Sell_volume,false); + ArraySetAsSeries(this.BuySell_volume,false); + + bool needsReload = (NeedsReload() || (!this.dataReady)); + + if(needsReload) + { + GetOLHC(0,_rates_total); + this.prev_calculated = 0; + return false; + } + + /* + if(needsReload || IsNewBar || canvasIsNewTime || (change != 0)) + { + Print("reload="+needsReload+", renkoisnewbar="+IsNewBar+", canvasIsNewTime="+canvasIsNewTime+", change="+change); + GetOLHC(0,_rates_total); + this.prev_calculated = ArraySize(this.Open); + return true; + } + */ + bool change = Canvas_RatesTotalChangedBy(_rates_total); + if(change != 0) + { + #ifdef DISPLAY_DEBUG_MSG + Print("rates total changed to:"+_rates_total); + #endif + if(change == 1) + { + #ifdef DISPLAY_DEBUG_MSG + Print("changed by 1 => Resize called"); + #endif + OLHCResize(); + } + else + { + #ifdef DISPLAY_DEBUG_MSG + Print("changed by "+change+" => getting ALL"); + #endif + GetOLHC(0,_rates_total); + } + this.prev_calculated = 0;//_prev_calculated; + Canvas_IsNewBar(_Time); + return true; + } + else if(Canvas_IsNewBar(_Time)) + { + #ifdef DISPLAY_DEBUG_MSG + Print("Got Canvas_IsNewBar"); + #endif + + if(ArraySize(this.Open) == 0) + { + GetOLHC(0,_rates_total); + this.prev_calculated = 0; + return true; ///////// false + } + + OLHCShiftRight(); + this.prev_calculated = _prev_calculated; + return true; + } + + IsNewBar = rangeBars.IsNewBar(); + if(IsNewBar) + { + GetOLHC(0,_rates_total); + this.prev_calculated = 0; + return true; + } + + + // + // Only recalculate last bar + // + + GetOLHC(0,0); + this.prev_calculated = _prev_calculated; + + return true; +} + +int RangeBarIndicator::GetOLHC(int start, int count) +{ + if((start == 0) && (count == 0) && dataReady) + { + MqlRates tempRates[1]; + double b[1],s[1],bs[1]; + + int last = ArraySize(Open)-1; + + if(last < 0) + return 0; + + rangeBars.GetMqlRates(tempRates,0,1); + this.Open[last] = tempRates[0].open; + this.Low[last] = tempRates[0].low; + this.High[last] = tempRates[0].high; + this.Close[last] = tempRates[0].close; + if(getTime) + { + this.Time[last] = tempRates[0].time; + } + if(getVolumes) + { + this.Tick_volume[last] = tempRates[0].tick_volume; + this.Real_volume[last] = tempRates[0].real_volume; + } + if(useAppliedPrice) + { + this.Price[last] = CalcAppliedPrice(tempRates[0],this.applied_price); + } + if(getVolumeBreakdown) + { + rangeBars.GetBuySellVolumeBreakdown(b,s,bs,0,1); + this.Buy_volume[last] = b[0]; + this.Sell_volume[last] = s[0]; + this.BuySell_volume[last] = bs[0]; + } + + return 1; + } + else + { + return GetOLHCAndApplPriceForIndicatorCalc(this.Open,this.Low,this.High,this.Close,this.Time,this.Tick_volume,this.Real_volume, this.Buy_volume, this.Sell_volume, this.BuySell_volume, this.Price,this.applied_price,0,count); + } +} + + +void RangeBarIndicator::OLHCShiftRight() +{ + int count = ArraySize(this.Open); + + if(count <= 0) + return; + + count--; + + for(int i=count; i>0; i--) + { + this.Open[i] = this.Open[i-1]; + this.High[i] = this.High[i-1]; + this.Low[i] = this.Low[i-1]; + this.Close[i] = this.Close[i-1]; + if(getTime) + this.Time[i] = this.Time[i-1]; + if(useAppliedPrice) + this.Price[i] = this.Price[i-1]; + if(getVolumes) + { + this.Tick_volume[i] = this.Tick_volume[i-1]; + this.Real_volume[i] = this.Real_volume[i-1]; + } + if(getVolumeBreakdown) + { + this.Buy_volume[i] = this.Buy_volume[i-1]; + this.Sell_volume[i] = this.Sell_volume[i-1]; + this.BuySell_volume[i] = this.BuySell_volume[i-1]; + } + } + + this.Open[0] = 0.0; + this.High[0] = 0.0; + this.Low[0] = 0.0; + this.Close[0] = 0.0; + + if(getTime) + this.Time[0] = 0; + if(useAppliedPrice) + this.Price[0] = 0.0; + if(getVolumes) + { + this.Tick_volume[0] = 0.0; + this.Real_volume[0] = 0.0; + } + if(getVolumeBreakdown) + { + this.Buy_volume[0] = 0; + this.Sell_volume[0] = 0; + this.BuySell_volume[0] = 0; + } +} + +void RangeBarIndicator::OLHCResize() +{ + int count = ArraySize(this.Open); + + if(count <= 0) + return; + + ArrayResize(this.Open,count+1); + ArrayResize(this.Low,count+1); + ArrayResize(this.High,count+1); + ArrayResize(this.Close,count+1); + + if(getTime) + ArrayResize(this.Time,count+1); + if(useAppliedPrice) + ArrayResize(this.Price,count+1); + if(getVolumes) + { + ArrayResize(this.Tick_volume,count+1); + ArrayResize(this.Real_volume,count+1); + } + if(getVolumeBreakdown) + { + ArrayResize(this.Buy_volume,count+1); + ArrayResize(this.Sell_volume,count+1); + ArrayResize(this.BuySell_volume,count+1); + } + + OLHCShiftRight(); +} + +bool RangeBarIndicator::Canvas_IsNewBar(const datetime &_Time[]) +{ + ArraySetAsSeries(_Time,true); + datetime now = _Time[0]; + ArraySetAsSeries(_Time,false); + + static datetime prevTime = 0; + + if(prevTime != now) + { + prevTime = now; + return true; + } + + return false; +} + +bool RangeBarIndicator::Canvas_IsRatesTotalChanged(int ratesTotalNow) +{ + static int prevRatesTotal = 0; + + if(prevRatesTotal == 0) + prevRatesTotal = ratesTotalNow; + + if(prevRatesTotal != ratesTotalNow) + { + prevRatesTotal = ratesTotalNow; + return true; + } + + return false; +} + +int RangeBarIndicator::Canvas_RatesTotalChangedBy(int ratesTotalNow) +{ + int changedBy = 0; + static int prevRatesTotal = 0; + + if(prevRatesTotal == 0) + prevRatesTotal = ratesTotalNow; + + if(prevRatesTotal != ratesTotalNow) + { + changedBy = (ratesTotalNow - prevRatesTotal); + prevRatesTotal = ratesTotalNow; + return changedBy; + } + + return 0; +} + +int RangeBarIndicator::GetOLHCForIndicatorCalc(double &o[],double &l[],double &h[],double &c[],datetime &t[], long &tickVolume[],long &realVolume[], double &buyVolume[], double &sellVolume[], double &buySellVolume[], int start, int count) +{ + int handle; + double temp[]; + + if(ArrayResize(temp,count) == -1) + return -1; + if(ArrayResize(o,count) == -1) + return -1; + if(ArrayResize(l,count) == -1) + return -1; + if(ArrayResize(h,count) == -1) + return -1; + if(ArrayResize(c,count) == -1) + return -1; + + if(getVolumes) + { + if(ArrayResize(tickVolume,count) == -1) + return -1; + if(ArrayResize(realVolume,count) == -1) + return -1; + } + + if(getTime) + { + if(ArrayResize(t,count) == -1) + return -1; + } + + if(getVolumeBreakdown) + { + if(ArrayResize(buyVolume,count) == -1) + return -1; + if(ArrayResize(sellVolume,count) == -1) + return -1; + if(ArrayResize(buySellVolume,count) == -1) + return -1; + } + + handle = rangeBars.GetHandle(); + if(handle == INVALID_HANDLE) + return -1; + int _count = CopyBuffer(handle,RANGEBAR_OPEN,start,count,temp); + if(_count == -1) + { + int errorCode = GetLastError(); + if(errorCode == ERR_INDICATOR_DATA_NOT_FOUND) + { + Print("Waiting for buffers ready flag"); + return -2; + } + else + return -1; + } + + if(_count < count) + { + #ifdef DISPLAY_DEBUG_MSG + Print("Fixing offset (req:"+count+" res:"+_count+")"); + #endif + + ArrayInitialize(o,0x0); + ArrayInitialize(l,0x0); + ArrayInitialize(h,0x0); + ArrayInitialize(c,0x0); + if(getTime) + ArrayInitialize(t,0x0); + if(getVolumes) + { + ArrayInitialize(tickVolume,0x0); + ArrayInitialize(realVolume,0x0); + } + if(getVolumeBreakdown) + { + ArrayInitialize(buyVolume,0x0); + ArrayInitialize(sellVolume,0x0); + ArrayInitialize(buySellVolume,0x0); + } + // less data - indicator requres more + + ArrayCopy(o,temp,(count-_count),0); + + if(CopyBuffer(handle,RANGEBAR_LOW,start,_count,temp) == -1) + return -1; + ArrayCopy(l,temp,(count-_count),0); + + if(CopyBuffer(handle,RANGEBAR_HIGH,start,_count,temp) == -1) + return -1; + ArrayCopy(h,temp,(count-_count),0); + + if(CopyBuffer(handle,RANGEBAR_CLOSE,start,_count,temp) == -1) + return -1; + ArrayCopy(c,temp,(count-_count),0); + + if(getTime) + { + if(CopyBuffer(handle,RANGEBAR_BAR_OPEN_TIME,start,_count,temp) == -1) + return -1; + ArrayCopy(t,temp,(count-_count),0); + } + + if(getVolumes) + { + if(CopyBuffer(handle,RANGEBAR_TICK_VOLUME,start,_count,temp) == -1) + return -1; + ArrayCopy(tickVolume,temp,(count-_count),0); + + if(CopyBuffer(handle,RANGEBAR_REAL_VOLUME,start,_count,temp) == -1) + return -1; + ArrayCopy(realVolume,temp,(count-_count),0); + } + +#ifdef P_RANGEBAR_BR + #ifdef P_RANGEBAR_BR_PRO + if(getVolumeBreakdown) + { + if(CopyBuffer(handle,RANGEBAR_BUY_VOLUME,start,_count,temp) == -1) + return -1; + ArrayCopy(buyVolume,temp,(count-_count),0); + + if(CopyBuffer(handle,RANGEBAR_SELL_VOLUME,start,_count,temp) == -1) + return -1; + ArrayCopy(sellVolume,temp,(count-_count),0); + + if(CopyBuffer(handle,RANGEBAR_BUYSELL_VOLUME,start,_count,temp) == -1) + return -1; + ArrayCopy(buySellVolume,temp,(count-_count),0); + } + #else + #endif +#else + if(getVolumeBreakdown) + { + if(CopyBuffer(handle,RANGEBAR_BUY_VOLUME,start,_count,temp) == -1) + return -1; + ArrayCopy(buyVolume,temp,(count-_count),0); + + if(CopyBuffer(handle,RANGEBAR_SELL_VOLUME,start,_count,temp) == -1) + return -1; + ArrayCopy(sellVolume,temp,(count-_count),0); + + if(CopyBuffer(handle,RANGEBAR_BUYSELL_VOLUME,start,_count,temp) == -1) + return -1; + ArrayCopy(buySellVolume,temp,(count-_count),0); + } +#endif + + } + else + { + if(CopyBuffer(handle,RANGEBAR_OPEN,start,count,o) == -1) + return -1; + if(CopyBuffer(handle,RANGEBAR_LOW,start,count,l) == -1) + return -1; + if(CopyBuffer(handle,RANGEBAR_HIGH,start,count,h) == -1) + return -1; + if(CopyBuffer(handle,RANGEBAR_CLOSE,start,count,c) == -1) + return -1; + + if(getTime) + { + if(CopyBuffer(handle,RANGEBAR_BAR_OPEN_TIME,start,count,temp) == -1) + return -1; + ArrayCopy(t,temp); + } + + if(getVolumes) + { + if(CopyBuffer(handle,RANGEBAR_TICK_VOLUME,start,count,temp) == -1) + return -1; + ArrayCopy(tickVolume,temp); + if(CopyBuffer(handle,RANGEBAR_REAL_VOLUME,start,count,temp) == -1) + return -1; + ArrayCopy(realVolume,temp); + } + +#ifdef P_RANGEBAR_BR + #ifdef P_RANGEBAR_BR_PRO + if(getVolumeBreakdown) + { + if(CopyBuffer(handle,RANGEBAR_BUY_VOLUME,start,count,temp) == -1) + return -1; + ArrayCopy(buyVolume,temp); + + if(CopyBuffer(handle,RANGEBAR_SELL_VOLUME,start,count,temp) == -1) + return -1; + ArrayCopy(sellVolume,temp); + + if(CopyBuffer(handle,RANGEBAR_BUYSELL_VOLUME,start,count,temp) == -1) + return -1; + ArrayCopy(buySellVolume,temp); + } + #else + #endif +#else + if(getVolumeBreakdown) + { + if(CopyBuffer(handle,RANGEBAR_BUY_VOLUME,start,count,temp) == -1) + return -1; + ArrayCopy(buyVolume,temp); + + if(CopyBuffer(handle,RANGEBAR_SELL_VOLUME,start,count,temp) == -1) + return -1; + ArrayCopy(sellVolume,temp); + + if(CopyBuffer(handle,RANGEBAR_BUYSELL_VOLUME,start,count,temp) == -1) + return -1; + ArrayCopy(buySellVolume,temp); + } +#endif + } + + return count; +} + +// +// Get "count" Renko MqlRates into "ratesInfoArray[]" array starting from "start" bar +// + +int RangeBarIndicator::GetOLHCAndApplPriceForIndicatorCalc(double &o[],double &l[],double &h[],double &c[],datetime &t[],long &tickVolume[],long &realVolume[],double &buyVolume[], double &sellVolume[], double &buySellVolume[],double &price[],ENUM_APPLIED_PRICE _applied_price, int start, int count) +{ + dataReady = true; + + int _count = GetOLHCForIndicatorCalc(o,l,h,c,t,tickVolume,realVolume,buyVolume,sellVolume,buySellVolume,start,count); + if(_count < 0) + { + dataReady = false; + return _count; + } + if(applied_price == PRICE_CLOSE) + { + return ArrayCopy(price,c); + } + else if(applied_price == PRICE_OPEN) + { + return ArrayCopy(price,o); + } + else if(applied_price == PRICE_HIGH) + { + return ArrayCopy(price,h); + } + else if(applied_price == PRICE_LOW) + { + return ArrayCopy(price,l); + } + else + { + if(ArrayResize(price,_count) == -1) + return -1; + + for(int i=0; i<_count; i++) + { + price[i] = CalcAppliedPrice(o[i],l[i],h[i],c[i],_applied_price); + } + } + + return _count; +} + +ENUM_TIMEFRAMES RangeBarIndicator::TFMigrate(int tf) + { + switch(tf) + { + case 0: return(PERIOD_CURRENT); + case 1: return(PERIOD_M1); + case 5: return(PERIOD_M5); + case 15: return(PERIOD_M15); + case 30: return(PERIOD_M30); + case 60: return(PERIOD_H1); + case 240: return(PERIOD_H4); + case 1440: return(PERIOD_D1); + case 10080: return(PERIOD_W1); + case 43200: return(PERIOD_MN1); + + case 2: return(PERIOD_M2); + case 3: return(PERIOD_M3); + case 4: return(PERIOD_M4); + case 6: return(PERIOD_M6); + case 10: return(PERIOD_M10); + case 12: return(PERIOD_M12); + case 16385: return(PERIOD_H1); + case 16386: return(PERIOD_H2); + case 16387: return(PERIOD_H3); + case 16388: return(PERIOD_H4); + case 16390: return(PERIOD_H6); + case 16392: return(PERIOD_H8); + case 16396: return(PERIOD_H12); + case 16408: return(PERIOD_D1); + case 32769: return(PERIOD_W1); + case 49153: return(PERIOD_MN1); + default: return(PERIOD_CURRENT); + } + } + +datetime RangeBarIndicator::iTime(string symbol,int tf,int index) +{ + if(index < 0) return(-1); + ENUM_TIMEFRAMES timeframe=TFMigrate(tf); + datetime Arr[]; + if(CopyTime(symbol, timeframe, index, 1, Arr)>0) + return(Arr[0]); + else return(-1); +} + +// +// Function used for calculating the Apllied Price based on Renko OLHC values +// + +double RangeBarIndicator::CalcAppliedPrice(const MqlRates &_rates, ENUM_APPLIED_PRICE _applied_price) +{ + if(_applied_price == PRICE_CLOSE) + return _rates.close; + else if (_applied_price == PRICE_OPEN) + return _rates.open; + else if (_applied_price == PRICE_HIGH) + return _rates.high; + else if (_applied_price == PRICE_LOW) + return _rates.low; + else if (_applied_price == PRICE_MEDIAN) + return (_rates.high + _rates.low) / 2; + else if (_applied_price == PRICE_TYPICAL) + return (_rates.high + _rates.low + _rates.close) / 3; + else if (_applied_price == PRICE_WEIGHTED) + return (_rates.high + _rates.low + _rates.close + _rates.close) / 4; + + return 0.0; +} + +double RangeBarIndicator::CalcAppliedPrice(const double &o,const double &l,const double &h,const double &c, ENUM_APPLIED_PRICE _applied_price) +{ + if(_applied_price == PRICE_CLOSE) + return c; + else if (_applied_price == PRICE_OPEN) + return o; + else if (_applied_price == PRICE_HIGH) + return h; + else if (_applied_price == PRICE_LOW) + return l; + else if (_applied_price == PRICE_MEDIAN) + return (h + l) / 2; + else if (_applied_price == PRICE_TYPICAL) + return (h + l + c) / 3; + else if (_applied_price == PRICE_WEIGHTED) + return (h + l + c +c) / 4; + + return 0.0; +} + +void RangeBarIndicator::BufferShiftLeft(double &buffer[]) +{ + int size = ArraySize(buffer); + + for(int i=1; i +#define CUSTOM_CHART_NAME "Range Bars" + +#ifdef SHOW_INDICATOR_INPUTS + +input int barSizeInTicks = 100; // Range bar size (in points) +input ENUM_BOOL atrEnabled = false; // Enable ATR based bar size calculation + ENUM_TIMEFRAMES atrTimeFrame = PERIOD_D1; // Use ATR period +input int atrPeriod = 14; // ATR period +input int atrPercentage = 10; // Use percentage of ATR + ENUM_BOOL useRealVolume = false; // Use real volume ( false for FX ) + ENUM_TICK_PRICE_TYPE plotPrice = tickBid; // Build chart using +input int showNumberOfDays = 14; // Show history for number of days +input ENUM_BOOL resetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day +input double TopBottomPaddingPercentage = 0.30; // Use padding top/bottom (0.0 - 1.0) +input ENUM_PIVOT_POINTS showPivots = ppNone; // Show pivot levels +input ENUM_PIVOT_TYPE pivotPointCalculationType = ppHLC3; // Pivot point calculation method +input color RColor = clrDodgerBlue; // Resistance line color +input color PColor = clrGold; // Pivot line color +input color SColor = clrFireBrick; // Support line color +input color PDHColor = clrHotPink; // Previous day's high +input color PDLColor = clrLightSkyBlue; // Previous day's low +input color PDCColor = clrGainsboro; // Previous day's close +input ENUM_BOOL showNextBarLevels = true; // Show current bar's close projections +input color HighThresholdIndicatorColor = clrLime; // Bullish bar projection color +input color LowThresholdIndicatorColor = clrRed; // Bearish bar projection color +input ENUM_BOOL showCurrentBarOpenTime = true; // Display chart info and current bar's open time +input color InfoTextColor = clrWhite; // Current bar's open time info color +input ENUM_BOOL UseSoundSignalOnNewBar = false; // Play sound on new bar +input ENUM_BOOL OnlySignalReversalBars = false; // Only signal reversals +input ENUM_BOOL UseAlertWindow = false; // Display Alert window with new bar info +input ENUM_BOOL SendPushNotifications = false; // Send new bar info push notification to smartphone +input string SoundFileBull = "news.wav"; // Use sound file for bullish bar close +input string SoundFileBear = "timeout.wav"; // Use sound file for bearish bar close +input ENUM_BOOL MA1on = false; // Show first MA +input int MA1period = 20; // 1st MA period +input ENUM_MA_METHOD_EXT MA1method = _MODE_SMA; // 1st MA method +input ENUM_APPLIED_PRICE MA1applyTo = PRICE_CLOSE; // 1st MA apply to +input int MA1shift = 0; // 1st MA shift +input ENUM_BOOL MA2on = false; // Show second MA +input int MA2period = 50; // 2nd MA period +input ENUM_MA_METHOD_EXT MA2method = _MODE_EMA; // 2nd MA method +input ENUM_APPLIED_PRICE MA2applyTo = PRICE_CLOSE; // 2nd MA apply to +input int MA2shift = 0; // 2nd MA shift +input ENUM_BOOL MA3on = false; // Show third MA +input int MA3period = 20; // 3rd MA period +input ENUM_MA_METHOD_EXT MA3method = _VWAP_TICKVOL; // 3rd MA method +input ENUM_APPLIED_PRICE MA3applyTo = PRICE_CLOSE; // 3rd MA apply to +input int MA3shift = 0; // 3rd MA shift +input ENUM_CHANNEL_TYPE ShowChannel = None; // Show Channel +input string Channel_Settings = "-------------------"; // Channel settings +input int DonchianPeriod = 20; // Donchian Channel period +input ENUM_APPLIED_PRICE BBapplyTo = PRICE_CLOSE; // Bollinger Bands apply to +input int BollingerBandsPeriod = 20; // Bollinger Bands period +input double BollingerBandsDeviations = 2.0; // Bollinger Bands deviations +input int SuperTrendPeriod = 10; // Super Trend period +input double SuperTrendMultiplier=1.7; // Super Trend multiplier +input string Misc_Settings = "-------------------"; // Misc settings +input ENUM_BOOL DisplayAsBarChart = false; // Display as bar chart +input ENUM_BOOL UsedInEA = false; // Indicator used in EA via iCustom() + +#else + + // + // This block should always be set to the following values + // + + double TopBottomPaddingPercentage = 0; + ENUM_PIVOT_POINTS showPivots = ppNone; + ENUM_PIVOT_TYPE pivotPointCalculationType = ppHLC3; + color RColor = clrNONE; + color PColor = clrNONE; + color SColor = clrNONE; + color PDHColor = clrNONE; + color PDLColor = clrNONE; + color PDCColor = clrNONE; + ENUM_BOOL showNextBarLevels = false; + color HighThresholdIndicatorColor = clrNONE; + color LowThresholdIndicatorColor = clrNONE; + ENUM_BOOL showCurrentBarOpenTime = false; + color InfoTextColor = clrNONE; + ENUM_BOOL UseSoundSignalOnNewBar = false; + ENUM_BOOL OnlySignalReversalBars = false; + ENUM_BOOL UseAlertWindow = false; + ENUM_BOOL SendPushNotifications = false; + string SoundFileBull = ""; + string SoundFileBear = ""; + ENUM_BOOL DisplayAsBarChart = true; + ENUM_BOOL UsedInEA = true; // This should always be set to TRUE for EAs & Indicators + + // + // + // + + +#endif + +struct RANGEBAR_SETTINGS +{ + int barSizeInTicks; + ENUM_BOOL atrEnabled; + ENUM_TIMEFRAMES atrTimeFrame; + int atrPeriod; + int atrPercentage; + ENUM_BOOL useRealVolume; + ENUM_TICK_PRICE_TYPE plotPrice; + int showNumberOfDays; + ENUM_BOOL resetOpenOnNewTradingDay; +}; + +class RangeBarSettings +{ + protected: + + string settingsFileName; + string chartTypeFileName; + + RANGEBAR_SETTINGS settings; + CHART_INDICATOR_SETTINGS chartIndicatorSettings; + ALERT_INFO_SETTINGS alertInfoSettings; + + public: + + RangeBarSettings(void); + ~RangeBarSettings(void); + + RANGEBAR_SETTINGS GetRangeBarSettings(void); + ALERT_INFO_SETTINGS GetAlertInfoSettings(void); + CHART_INDICATOR_SETTINGS GetChartIndicatorSettings(void); + + void Set(void); + + void Save(void); + bool Load(void); + void Delete(void); + bool Changed(void); +}; + +void RangeBarSettings::RangeBarSettings(void) +{ + this.settingsFileName = CUSTOM_CHART_NAME+(string)ChartID()+".set"; + this.chartTypeFileName = (string)ChartID()+".id"; +} + +void RangeBarSettings::~RangeBarSettings(void) +{ + +} + +void RangeBarSettings::Save(void) +{ + if(IS_TESTING || this.chartIndicatorSettings.UsedInEA) + return; + + this.Delete(); + + // + // Store indicator settings + // + + int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_WRITE|FILE_BIN); + uint result = 0; + + result += FileWriteStruct(handle,this.settings); + result += FileWriteStruct(handle,this.chartIndicatorSettings); + //FileWriteStruct(handle,this.alertInfoSettings); + FileClose(handle); + + // + // Store chart type identifier + // + + handle = FileOpen(this.chartTypeFileName,FILE_SHARE_READ|FILE_WRITE|FILE_ANSI); + FileWriteString(handle,CUSTOM_CHART_NAME); + FileClose(handle); +} + +void RangeBarSettings::Delete(void) +{ + if(IS_TESTING || this.chartIndicatorSettings.UsedInEA) + return; + + if(FileIsExist(this.settingsFileName)) + FileDelete(this.settingsFileName); +} + +bool RangeBarSettings::Load(void) +{ +#ifdef SHOW_INDICATOR_INPUTS + Set(); + return true; +#else + + if(!FileIsExist(this.settingsFileName)) + return false; + + int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_BIN); + if(handle == INVALID_HANDLE) + return false; + + if(FileReadStruct(handle,this.settings) <= 0) + { + Print("Failed loading settings(1)!"); + FileClose(handle); + return false; + } + + if(FileReadStruct(handle,this.chartIndicatorSettings) <= 0) + { + Print("Failed loading settings(2)!"); + FileClose(handle); + return false; + } + /* + if(FileReadStruct(handle,this.alertInfoSettings) <= 0) + { + Print("Failed loading settings(3)!"); + FileClose(handle); + return false; + } + */ + + FileClose(handle); + return true; + +#endif +} + +ALERT_INFO_SETTINGS RangeBarSettings::GetAlertInfoSettings(void) +{ + return this.alertInfoSettings; +} + +CHART_INDICATOR_SETTINGS RangeBarSettings::GetChartIndicatorSettings(void) +{ + return this.chartIndicatorSettings; +} + +RANGEBAR_SETTINGS RangeBarSettings::GetRangeBarSettings(void) +{ + return this.settings; +} + +void RangeBarSettings::Set(void) +{ +#ifdef SHOW_INDICATOR_INPUTS + + settings.barSizeInTicks = barSizeInTicks; + settings.atrEnabled = atrEnabled; + settings.atrTimeFrame = atrTimeFrame; + settings.atrPeriod = atrPeriod; + settings.atrPercentage = atrPercentage; + settings.useRealVolume = useRealVolume; + settings.plotPrice = plotPrice; + settings.showNumberOfDays = showNumberOfDays; + settings.resetOpenOnNewTradingDay = resetOpenOnNewTradingDay; + + // + // + // + + chartIndicatorSettings.MA1on = MA1on; + chartIndicatorSettings.MA1period = MA1period; + chartIndicatorSettings.MA1method = MA1method; + chartIndicatorSettings.MA1applyTo = MA1applyTo; + chartIndicatorSettings.MA1shift = MA1shift; + chartIndicatorSettings.MA2on = MA2on; + chartIndicatorSettings.MA2period = MA2period; + chartIndicatorSettings.MA2method = MA2method; + chartIndicatorSettings.MA2applyTo = MA2applyTo; + chartIndicatorSettings.MA2shift = MA2shift; + /* + chartIndicatorSettings.ShowVWAP = ShowVWAP; + chartIndicatorSettings.VWAP_Period = VWAP_Period; + chartIndicatorSettings.VWAPapplyTo = VWAPapplyTo; + chartIndicatorSettings.VWAPvolume = VWAPvolume; + */ + chartIndicatorSettings.MA3on = MA3on; + chartIndicatorSettings.MA3period = MA3period; + chartIndicatorSettings.MA3method = MA3method; + chartIndicatorSettings.MA3applyTo = MA3applyTo; + chartIndicatorSettings.MA3shift = MA3shift; + chartIndicatorSettings.ShowChannel = ShowChannel; + chartIndicatorSettings.DonchianPeriod = DonchianPeriod; + chartIndicatorSettings.BBapplyTo = BBapplyTo; + chartIndicatorSettings.BollingerBandsPeriod = BollingerBandsPeriod; + chartIndicatorSettings.BollingerBandsDeviations = BollingerBandsDeviations; + chartIndicatorSettings.SuperTrendPeriod = SuperTrendPeriod; + chartIndicatorSettings.SuperTrendMultiplier = SuperTrendMultiplier; + chartIndicatorSettings.UsedInEA = UsedInEA; + + // + // + // + + alertInfoSettings.TopBottomPaddingPercentage = TopBottomPaddingPercentage; + alertInfoSettings.showPiovots = showPivots; + alertInfoSettings.pivotPointCalculationType = pivotPointCalculationType; + alertInfoSettings.Rcolor = RColor; + alertInfoSettings.Pcolor = PColor; + alertInfoSettings.Scolor = SColor; + alertInfoSettings.PDHColor = PDHColor; + alertInfoSettings.PDLColor = PDLColor; + alertInfoSettings.PDCColor = PDCColor; + alertInfoSettings.showNextBarLevels = showNextBarLevels; + alertInfoSettings.HighThresholdIndicatorColor = HighThresholdIndicatorColor; + alertInfoSettings.LowThresholdIndicatorColor = LowThresholdIndicatorColor; + alertInfoSettings.showCurrentBarOpenTime = showCurrentBarOpenTime; + alertInfoSettings.InfoTextColor = InfoTextColor; + alertInfoSettings.UseSoundSignalOnNewBar = UseSoundSignalOnNewBar; + alertInfoSettings.OnlySignalReversalBars = OnlySignalReversalBars; + alertInfoSettings.UseAlertWindow = UseAlertWindow; + alertInfoSettings.SendPushNotifications = SendPushNotifications; + alertInfoSettings.SoundFileBull = SoundFileBull; + alertInfoSettings.SoundFileBear = SoundFileBear; + alertInfoSettings.DisplayAsBarChart = DisplayAsBarChart; + +#endif +} + +bool RangeBarSettings::Changed(void) +{ + if(MQLInfoInteger((int)MQL5_TESTING)) + return false; + + static datetime prevFileTime = 0; + + if(!FileIsExist(this.settingsFileName)) + return false; + + int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_BIN); + datetime currFileTime = (datetime)FileGetInteger(handle,FILE_CREATE_DATE); + FileClose(handle); + + if(prevFileTime != currFileTime) + { + prevFileTime = currFileTime; + return true; + } + + return false; +} diff --git a/Include/RangeBars.mqh b/Include/AZ-INVEST/SDK/RangeBars.mqh similarity index 57% rename from Include/RangeBars.mqh rename to Include/AZ-INVEST/SDK/RangeBars.mqh index 007091d..8e5e853 100644 --- a/Include/RangeBars.mqh +++ b/Include/AZ-INVEST/SDK/RangeBars.mqh @@ -1,5 +1,5 @@ //+------------------------------------------------------------------+ -//| RangeBars.mqh ver:1.47.0 | +//| RangeBars.mqh ver:2.03.0 | //| Copyright 2017, AZ-iNVEST | //| http://www.az-invest.eu | //+------------------------------------------------------------------+ @@ -7,21 +7,27 @@ #property link "http://www.az-invest.eu" #define RANGEBAR_INDICATOR_NAME "Market\\Range Bars Charting" +//#define RANGEBAR_INDICATOR_NAME "RangeBars\\RangeBarsOverlay203" -#define RANGEBAR_MA1 0 -#define RANGEBAR_MA2 1 -#define RANGEBAR_CHANNEL_HIGH 2 -#define RANGEBAR_CHANNEL_MID 3 -#define RANGEBAR_CHANNEL_LOW 4 -#define RANGEBAR_OPEN 5 -#define RANGEBAR_HIGH 6 -#define RANGEBAR_LOW 7 -#define RANGEBAR_CLOSE 8 -#define RANGEBAR_COLOR_CODE 9 -#define RANGEBAR_BAR_OPEN_TIME 10 -#define RANGEBAR_TICK_VOLUME 11 +#define RANGEBAR_OPEN 00 +#define RANGEBAR_HIGH 01 +#define RANGEBAR_LOW 02 +#define RANGEBAR_CLOSE 03 +#define RANGEBAR_BAR_COLOR 04 +#define RANGEBAR_MA1 05 +#define RANGEBAR_MA2 06 +#define RANGEBAR_MA3 07 +#define RANGEBAR_CHANNEL_HIGH 08 +#define RANGEBAR_CHANNEL_MID 09 +#define RANGEBAR_CHANNEL_LOW 10 +#define RANGEBAR_BAR_OPEN_TIME 11 +#define RANGEBAR_TICK_VOLUME 12 +#define RANGEBAR_REAL_VOLUME 13 +#define RANGEBAR_BUY_VOLUME 14 +#define RANGEBAR_SELL_VOLUME 15 +#define RANGEBAR_BUYSELL_VOLUME 16 -#include +#include class RangeBars { @@ -48,15 +54,14 @@ class RangeBars int GetHandle(void) { return rangeBarsHandle; }; bool GetMqlRates(MqlRates &ratesInfoArray[], int start, int count); - int GetOLHCForIndicatorCalc(double &o[],double &l[],double &h[],double &c[], int start, int count); - int GetOLHCAndApplPriceForIndicatorCalc(double &o[],double &l[],double &h[],double &c[],double &price[],ENUM_APPLIED_PRICE applied_price, int start, int count); - double CalcAppliedPrice(const MqlRates &_rates, ENUM_APPLIED_PRICE applied_price); - double CalcAppliedPrice(const double &o,const double &l,const double &h,const double &c,ENUM_APPLIED_PRICE applied_price); + bool GetBuySellVolumeBreakdown(double &buy[], double &sell[], double &buySell[], int start, int count); bool GetMA1(double &MA[], int start, int count); bool GetMA2(double &MA[], int start, int count); + bool GetMA3(double &MA[], int start, int count); bool GetDonchian(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count); bool GetBollingerBands(double &HighArray[], double &MidArray[], double &LowArray[], int start, int count); bool GetSuperTrend(double &SuperTrendHighArray[], double &SuperTrendArray[], double &SuperTrendLowArray[], int start, int count); + bool IsNewBar(); private: @@ -67,6 +72,7 @@ class RangeBars RangeBars::RangeBars(void) { +#define CONSTRUCTOR1 rangeBarSettings = new RangeBarSettings(); rangeBarsHandle = INVALID_HANDLE; rangeBarsSymbol = _Symbol; @@ -74,6 +80,7 @@ RangeBars::RangeBars(void) RangeBars::RangeBars(string symbol) { +#define CONSTRUCTOR2 rangeBarSettings = new RangeBarSettings(); rangeBarsHandle = INVALID_HANDLE; rangeBarsSymbol = symbol; @@ -103,8 +110,7 @@ int RangeBars::Init() } else { - Print("Failed to load indicator settings."); - Alert("You need to put the Median Renko indicator on your chart first!"); + Print("Failed to load indicator settings - RangeBar indicator not on chart"); return INVALID_HANDLE; } } @@ -128,14 +134,28 @@ int RangeBars::Init() #endif } - RANGEBAR_SETTINGS s = rangeBarSettings.Get(); + RANGEBAR_SETTINGS s = rangeBarSettings.GetRangeBarSettings(); + CHART_INDICATOR_SETTINGS cis = rangeBarSettings.GetChartIndicatorSettings(); //RangeBarSettings.Debug(); - rangeBarsHandle = iCustom(this.rangeBarsSymbol,PERIOD_M1,RANGEBAR_INDICATOR_NAME, + rangeBarsHandle = iCustom(this.rangeBarsSymbol,_Period,RANGEBAR_INDICATOR_NAME, s.barSizeInTicks, - s._startFromDateTime, + s.atrEnabled, + //s.atrTimeFrame, + s.atrPeriod, + s.atrPercentage, + s.showNumberOfDays, s.resetOpenOnNewTradingDay, + TopBottomPaddingPercentage, + showPivots, + pivotPointCalculationType, + RColor, + PColor, + SColor, + PDHColor, + PDLColor, + PDCColor, showNextBarLevels, HighThresholdIndicatorColor, LowThresholdIndicatorColor, @@ -147,34 +167,41 @@ int RangeBars::Init() SendPushNotifications, SoundFileBull, SoundFileBear, - s.MA1on, - s.MA1period, - s.MA1method, - s.MA1applyTo, - s.MA1shift, - s.MA2on, - s.MA2period, - s.MA2method, - s.MA2applyTo, - s.MA2shift, - s.ShowChannel, + cis.MA1on, + cis.MA1period, + cis.MA1method, + cis.MA1applyTo, + cis.MA1shift, + cis.MA2on, + cis.MA2period, + cis.MA2method, + cis.MA2applyTo, + cis.MA2shift, + cis.MA3on, + cis.MA3period, + cis.MA3method, + cis.MA3applyTo, + cis.MA3shift, + cis.ShowChannel, "", - s.DonchianPeriod, - s.BBapplyTo, - s.BollingerBandsPeriod, - s.BollingerBandsDeviations, - s.SuperTrendPeriod, - s.SuperTrendMultiplier, + cis.DonchianPeriod, + cis.BBapplyTo, + cis.BollingerBandsPeriod, + cis.BollingerBandsDeviations, + cis.SuperTrendPeriod, + cis.SuperTrendMultiplier, "", + DisplayAsBarChart, UsedInEA); + if(rangeBarsHandle == INVALID_HANDLE) { - Print("RangeBars indicator init failed on error ",GetLastError()); + Print("RangeBar indicator init failed on error ",GetLastError()); } else { - Print("RangeBars indicator init OK"); + Print("RangeBar indicator init OK"); } return rangeBarsHandle; @@ -207,9 +234,9 @@ void RangeBars::Deinit() return; if(IndicatorRelease(rangeBarsHandle)) - Print("RangeBars indicator handle released"); + Print("RangeBar indicator handle released"); else - Print("Failed to release RangeBars indicator handle"); + Print("Failed to release RangeBar indicator handle"); } // @@ -218,25 +245,21 @@ void RangeBars::Deinit() bool RangeBars::IsNewBar() { - MqlRates currentRenko[1]; - static MqlRates prevRenko; + MqlRates currentBar[1]; + static datetime prevBarTime; - GetMqlRates(currentRenko,1,1); + GetMqlRates(currentBar,0,1); - if((prevRenko.open != currentRenko[0].open) || - (prevRenko.high != currentRenko[0].high) || - (prevRenko.low != currentRenko[0].low) || - (prevRenko.close != currentRenko[0].close)) + if(currentBar[0].time == 0) + return false; + + if(prevBarTime < currentBar[0].time) { - prevRenko.open = currentRenko[0].open; - prevRenko.high = currentRenko[0].high; - prevRenko.low = currentRenko[0].low; - prevRenko.close = currentRenko[0].close; + prevBarTime = currentBar[0].time; return true; } - - return false; -} + + return false;} // // Get "count" Renko MqlRates into "ratesInfoArray[]" array starting from "start" bar @@ -244,7 +267,7 @@ bool RangeBars::IsNewBar() bool RangeBars::GetMqlRates(MqlRates &ratesInfoArray[], int start, int count) { - double o[],l[],h[],c[],time[],tick_volume[]; + double o[],l[],h[],c[],barColor[],time[],tick_volume[],real_volume[]; if(ArrayResize(o,count) == -1) return false; @@ -254,10 +277,14 @@ bool RangeBars::GetMqlRates(MqlRates &ratesInfoArray[], int start, int count) return false; if(ArrayResize(c,count) == -1) return false; + if(ArrayResize(barColor,count) == -1) + return false; if(ArrayResize(time,count) == -1) return false; if(ArrayResize(tick_volume,count) == -1) return false; + if(ArrayResize(real_volume,count) == -1) + return false; if(CopyBuffer(rangeBarsHandle,RANGEBAR_OPEN,start,count,o) == -1) @@ -270,8 +297,12 @@ bool RangeBars::GetMqlRates(MqlRates &ratesInfoArray[], int start, int count) return false; if(CopyBuffer(rangeBarsHandle,RANGEBAR_BAR_OPEN_TIME,start,count,time) == -1) return false; + if(CopyBuffer(rangeBarsHandle,RANGEBAR_BAR_COLOR,start,count,barColor) == -1) + return false; if(CopyBuffer(rangeBarsHandle,RANGEBAR_TICK_VOLUME,start,count,tick_volume) == -1) return false; + if(CopyBuffer(rangeBarsHandle,RANGEBAR_REAL_VOLUME,start,count,real_volume) == -1) + return false; if(ArrayResize(ratesInfoArray,count) == -1) return false; @@ -285,117 +316,72 @@ bool RangeBars::GetMqlRates(MqlRates &ratesInfoArray[], int start, int count) ratesInfoArray[tempOffset-i].close = c[i]; ratesInfoArray[tempOffset-i].time = (datetime)time[i]; ratesInfoArray[tempOffset-i].tick_volume = (long)tick_volume[i]; + ratesInfoArray[tempOffset-i].real_volume = (long)real_volume[i]; + ratesInfoArray[tempOffset-i].spread = (int)barColor[i]; } ArrayFree(o); ArrayFree(l); ArrayFree(h); ArrayFree(c); + ArrayFree(barColor); ArrayFree(time); ArrayFree(tick_volume); + ArrayFree(real_volume); return true; } - -// -// Get "count" Renko MqlRates into "ratesInfoArray[]" array starting from "start" bar -// - -int RangeBars::GetOLHCForIndicatorCalc(double &o[],double &l[],double &h[],double &c[], int start, int count) +bool RangeBars::GetBuySellVolumeBreakdown(double &buy[], double &sell[], double &buySell[], int start, int count) { - if(ArrayResize(o,count) == -1) + double b[],s[],bs[]; + + if(ArrayResize(b,count) == -1) + return false; + if(ArrayResize(s,count) == -1) + return false; + if(ArrayResize(bs,count) == -1) return false; - int _count = CopyBuffer(rangeBarsHandle,RANGEBAR_OPEN,start,count,o); - if(_count == -1) - return _count; - - - if(ArrayResize(o,_count) == -1) - return -1; - if(ArrayResize(l,_count) == -1) - return -1; - if(ArrayResize(h,_count) == -1) - return -1; - if(ArrayResize(c,_count) == -1) - return -1; - - if(CopyBuffer(rangeBarsHandle,RANGEBAR_OPEN,start,_count,o) == -1) - return -1; - if(CopyBuffer(rangeBarsHandle,RANGEBAR_LOW,start,_count,l) == -1) - return -1; - if(CopyBuffer(rangeBarsHandle,RANGEBAR_HIGH,start,_count,h) == -1) - return -1; - if(CopyBuffer(rangeBarsHandle,RANGEBAR_CLOSE,start,_count,c) == -1) - return -1; - - return _count; -} - -// -// Get "count" Renko MqlRates into "ratesInfoArray[]" array starting from "start" bar -// - -int RangeBars::GetOLHCAndApplPriceForIndicatorCalc(double &o[],double &l[],double &h[],double &c[],double &price[],ENUM_APPLIED_PRICE applied_price, int start, int count) -{ - if(ArrayResize(o,count) == -1) +#ifdef P_RANGEBAR_BR + #ifdef P_RANGEBAR_BR_PRO + if(CopyBuffer(rangeBarsHandle,RANGEBAR_BUY_VOLUME,start,count,b) == -1) return false; + if(CopyBuffer(rangeBarsHandle,RANGEBAR_SELL_VOLUME,start,count,s) == -1) + return false; + if(CopyBuffer(rangeBarsHandle,RANGEBAR_BUYSELL_VOLUME,start,count,bs) == -1) + return false; + #endif +#else + if(CopyBuffer(rangeBarsHandle,RANGEBAR_BUY_VOLUME,start,count,b) == -1) + return false; + if(CopyBuffer(rangeBarsHandle,RANGEBAR_SELL_VOLUME,start,count,s) == -1) + return false; + if(CopyBuffer(rangeBarsHandle,RANGEBAR_BUYSELL_VOLUME,start,count,bs) == -1) + return false; +#endif - int _count = CopyBuffer(rangeBarsHandle,RANGEBAR_OPEN,start,count,o); - if(_count == -1) - return _count; + if(ArrayResize(buy,count) == -1) + return false; + if(ArrayResize(sell,count) == -1) + return false; + if(ArrayResize(buySell,count) == -1) + return false; - - if(ArrayResize(o,_count) == -1) - return -1; - if(ArrayResize(l,_count) == -1) - return -1; - if(ArrayResize(h,_count) == -1) - return -1; - if(ArrayResize(c,_count) == -1) - return -1; - if(ArrayResize(price,_count) == -1) - return -1; - - if(CopyBuffer(rangeBarsHandle,RANGEBAR_OPEN,start,_count,o) == -1) - return -1; - if(CopyBuffer(rangeBarsHandle,RANGEBAR_LOW,start,_count,l) == -1) - return -1; - if(CopyBuffer(rangeBarsHandle,RANGEBAR_HIGH,start,_count,h) == -1) - return -1; - if(CopyBuffer(rangeBarsHandle,RANGEBAR_CLOSE,start,_count,c) == -1) - return -1; - - if(applied_price == PRICE_CLOSE) + int tempOffset = count-1; + for(int i=0; i + +#define POSITION_TYPE_NONE -1 + +// +// Positions (market orders) +// + +struct CMarketOrderParameters +{ + bool m_async_mode; // trade mode + ulong m_magic; // expert magic number + ulong m_deviation; // deviation default + ENUM_ORDER_TYPE_FILLING m_type_filling; + + int numberOfRetries; + int busyTimeout_ms; + int requoteTimeout_ms; + +}; + +class CMarketOrder +{ + protected: + + CTrade * ctrade; + + int numberOfRetries; + int busyTimeout_ms; + int requoteTimeout_ms; + + public: + + CMarketOrder(CMarketOrderParameters ¶ms); + ~CMarketOrder(void); + + bool Long(string symbol, double lots, uint stoploss = 0, uint takeprofit = 0); + bool Long(string symbol,double lots, double priceSL=0,double priceTP=0); + bool Short(string symbol,double lots, uint stoploss = 0, uint takeprofit = 0); + bool Short(string symbol,double lots, double priceSL=0,double priceTP=0); + bool Modify(ulong ticket, uint stoploss = 0, uint takeprofit = 0); + bool Modify(ulong ticket, double priceSL=0,double priceTP=0); + bool Close(ulong ticket); + bool ClosePartial(ulong ticket, double lots); + bool Reverse(ulong ticket,double lots = 0, uint stoploss=0, uint takeprofit=0); + bool Reverse(ulong ticket,double lots = 0, double priceSL=0,double priceTP=0); + bool IsOpen(string symbol, ENUM_POSITION_TYPE type, long magicNumber = 0); + bool IsOpen(ulong &ticket, string symbol, ENUM_POSITION_TYPE type, long magicNumber = 0); + bool IsOpen(string symbol, long magicNumber = 0); + bool IsOpen(ulong &ticket, string symbol, long magicNumber = 0); + bool IsOpen(ulong &ticket, ENUM_POSITION_TYPE &type, string symbol, long magicNumber = 0); + + string PositionTypeToString(ENUM_POSITION_TYPE t); + bool RetryOrderRequest(int retryNumber); + + private: + + bool _IsOpen(ulong &ticket, string symbol, ENUM_POSITION_TYPE type, long magicNumber); + bool _IsOpen(ulong &ticket, string symbol, long magicNumber); + bool _IsNettingAccount() { return ((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE) != ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) ? true : false; }; + +}; + +CMarketOrder::CMarketOrder(CMarketOrderParameters ¶ms) +{ + ctrade = new CTrade(); + + ctrade.SetExpertMagicNumber(params.m_magic); + ctrade.SetDeviationInPoints(params.m_deviation); + ctrade.SetTypeFilling(params.m_type_filling); + ctrade.SetAsyncMode(params.m_async_mode); + + this.numberOfRetries = (params.numberOfRetries == 0) ? 25 : params.numberOfRetries; + this.busyTimeout_ms = (params.busyTimeout_ms == 0) ? 1000 : params.busyTimeout_ms; + this.requoteTimeout_ms = (params.requoteTimeout_ms == 0) ? 250 : params.requoteTimeout_ms; + +} + +CMarketOrder::~CMarketOrder(void) +{ + if(ctrade != NULL) + delete ctrade; +} + +bool CMarketOrder::Long(string symbol, double lots,uint stoploss=0,uint takeprofit=0) +{ + bool result = false; + int counter = 0; + + while(!IsStopped() && !result) + { + double price = SymbolInfoDouble(symbol,SYMBOL_ASK); + double _point = SymbolInfoDouble(symbol,SYMBOL_POINT); + + //calc SL + TP + double priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*_point) : 0.0); + double priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*_point) : 0.0); + + //attempt to buy + result = ctrade.Buy(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP); + + if(result) + { + Sleep(500); + return true; + } + else + { + if(!RetryOrderRequest(++counter)) + return false; + } + } + + return false; +} + +bool CMarketOrder::Long(string symbol, double lots,double priceSL=0,double priceTP=0) +{ + bool result = false; + int counter = 0; + + while(!IsStopped() && !result) + { + double price = SymbolInfoDouble(symbol,SYMBOL_ASK); + + //attempt to buy + result = ctrade.Buy(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP); + + if(result) + { + Sleep(500); + return true; + } + else + { + if(!RetryOrderRequest(++counter)) + return false; + } + } + + return false; +} + +bool CMarketOrder::Short(string symbol, double lots,uint stoploss=0,uint takeprofit=0) +{ + bool result = false; + int counter = 0; + + while(!IsStopped() && !result) + { + double price = SymbolInfoDouble(symbol,SYMBOL_BID); + double _point = SymbolInfoDouble(symbol,SYMBOL_POINT); + + //calc SL + TP + double priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*_point) : 0.0); + double priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*_point) : 0.0); + + //attempt to sell + result = ctrade.Sell(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP); + + if(result) + { + Sleep(500); + return true; + } + else + { + if(!RetryOrderRequest(++counter)) + return false; + } + } + + return false; +} + +bool CMarketOrder::Short(string symbol, double lots,double priceSL=0,double priceTP=0) +{ + bool result = false; + int counter = 0; + + while(!IsStopped() && !result) + { + double price = SymbolInfoDouble(symbol,SYMBOL_BID); + + //attempt to sell + result = ctrade.Sell(NormalizeLots(symbol,lots), symbol, price, priceSL, priceTP); + + if(result) + { + Sleep(500); + return true; + } + else + { + if(!RetryOrderRequest(++counter)) + return false; + } + } + + return false; +} + +bool CMarketOrder::Modify(ulong ticket, uint stoploss = 0, uint takeprofit = 0) +{ + if(!PositionSelectByTicket(ticket)) + return false; + + string symbol = PositionGetString(POSITION_SYMBOL); + double price = PositionGetDouble(POSITION_PRICE_CURRENT); + double _point = SymbolInfoDouble(symbol,SYMBOL_POINT); + double priceSL; + double priceTP; + + if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY){ + priceSL = (stoploss ? NormalizePrice(symbol,price - stoploss*_point) : PositionGetDouble(POSITION_SL)); + priceTP = (takeprofit ? NormalizePrice(symbol,price + takeprofit*_point) : PositionGetDouble(POSITION_TP)); + } + else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL){ + priceSL = (stoploss ? NormalizePrice(symbol,price + stoploss*_point) : PositionGetDouble(POSITION_SL)); + priceTP = (takeprofit ? NormalizePrice(symbol,price - takeprofit*_point) : PositionGetDouble(POSITION_TP)); + } + else + return false; + + //there's no change in SL or TP - do nothing! + if (priceSL == PositionGetDouble(POSITION_SL) + && priceTP == PositionGetDouble(POSITION_TP)) + return true; + + bool result = false; + int counter = 0; + + while(!IsStopped() && !result) + { + //attempt to modify position + result = ctrade.PositionModify(symbol,priceSL,priceTP); + + if(result) + { + Sleep(500); + return true; + } + else + { + if(!RetryOrderRequest(++counter)) + return false; + } + } + + return false; +} + +bool CMarketOrder::Modify(ulong ticket, double priceSL=0,double priceTP=0) +{ + if(!PositionSelectByTicket(ticket)) + return false; + + string symbol = PositionGetString(POSITION_SYMBOL); + double price = PositionGetDouble(POSITION_PRICE_CURRENT); + double _point = SymbolInfoDouble(symbol,SYMBOL_POINT); + + //there's no change in SL or TP - do nothing! + if (priceSL == PositionGetDouble(POSITION_SL) + && priceTP == PositionGetDouble(POSITION_TP)) + return true; + + bool result = false; + int counter = 0; + + while(!IsStopped() && !result) + { + //attempt to modify position + result = ctrade.PositionModify(symbol,priceSL,priceTP); + + if(result) + { + Sleep(500); + return true; + } + else + { + if(!RetryOrderRequest(++counter)) + return false; + } + } + + return false; +} + +bool CMarketOrder::Close(ulong ticket) +{ + if(!PositionSelectByTicket(ticket)) + return false; + + bool result = false; + int counter = 0; + + while(!IsStopped() && !result) + { + result = ctrade.PositionClose(ticket); + + if(result) + { + Sleep(500); + return true; + } + else + { + if(!RetryOrderRequest(++counter)) + return false; + } + } + + return false; +} + +bool CMarketOrder::ClosePartial(ulong ticket, double lots) +{ + if(!PositionSelectByTicket(ticket)) + return false; + + string symbol = PositionGetString(POSITION_SYMBOL); + + bool result = false; + int counter = 0; + + while(!IsStopped() && !result) + { + result = ctrade.PositionClosePartial(ticket, NormalizeLots(symbol,lots)); + + if(result) + { + Sleep(500); + return true; + } + else + { + if(!RetryOrderRequest(++counter)) + return false; + } + } + + return false; +} + +bool CMarketOrder::Reverse(ulong ticket,double lots = 0, uint stoploss=0, uint takeprofit=0) +{ + if(!PositionSelectByTicket(ticket)) + return false; + + string symbol = PositionGetString(POSITION_SYMBOL); + double positionLots = PositionGetDouble(POSITION_VOLUME); + ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); + + if(!this.Close(ticket)) + return false; + + if(type == POSITION_TYPE_BUY) + { + return this.Short(symbol,(lots ? lots : positionLots),stoploss,takeprofit); + } + else if(type == POSITION_TYPE_SELL) + { + return this.Long(symbol,(lots ? lots : positionLots),stoploss,takeprofit); + } + + return false; +} + +bool CMarketOrder::Reverse(ulong ticket,double lots = 0, double priceSL=0,double priceTP=0) +{ + if(!PositionSelectByTicket(ticket)) + return false; + + string symbol = PositionGetString(POSITION_SYMBOL); + double positionLots = PositionGetDouble(POSITION_VOLUME); + ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); + + if(!this.Close(ticket)) + return false; + + if(type == POSITION_TYPE_BUY) + { + return this.Short(symbol,(lots ? lots : positionLots),priceSL,priceTP); + } + else if(type == POSITION_TYPE_SELL) + { + return this.Long(symbol,(lots ? lots : positionLots),priceSL,priceTP); + } + + return false; +} + +bool CMarketOrder::IsOpen(string symbol, ENUM_POSITION_TYPE type, long magicNumber = 0) +{ + ulong ticket; + return this._IsOpen(ticket,symbol,type,magicNumber); +} + +bool CMarketOrder::IsOpen(ulong &ticket, string symbol, ENUM_POSITION_TYPE type, long magicNumber = 0) +{ + return this._IsOpen(ticket, symbol,type,magicNumber); +} + +bool CMarketOrder::IsOpen(string symbol, long magicNumber = 0) +{ + ulong ticket; + return this._IsOpen(ticket,symbol,magicNumber); +} + +bool CMarketOrder::IsOpen(ulong &ticket, string symbol, long magicNumber = 0) +{ + return this._IsOpen(ticket,symbol,magicNumber); +} + +bool CMarketOrder::IsOpen(ulong &ticket,ENUM_POSITION_TYPE &type,string symbol,long magicNumber=0) +{ + int positions=PositionsTotal(); + + for(int i=0;i 0) + { + if(PositionGetInteger(POSITION_MAGIC) != magicNumber) + continue; + } + + if(PositionGetString(POSITION_SYMBOL) == symbol) + { + ticket = _ticket; + type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE); + return true; + } + } + } + else + { + PrintFormat("Error when obtaining position from the list to the cache. Error code: %d",GetLastError()); + } + } + + return false; + +} + +bool CMarketOrder::_IsOpen(ulong &ticket, string symbol, ENUM_POSITION_TYPE type, long magicNumber) +{ + int positions=PositionsTotal(); + long _type; + + for(int i=0;i 0) + { + if(PositionGetInteger(POSITION_MAGIC) != magicNumber) + continue; + } + + if(!PositionGetInteger(POSITION_TYPE,_type)) + continue; + + if((_type == type) && (PositionGetString(POSITION_SYMBOL) == symbol)) + { + ticket = _ticket; + return true; + } + } + } + else + { + PrintFormat("Error when obtaining position from the list to the cache. Error code: %d",GetLastError()); + } + } + + return false; +} + +bool CMarketOrder::_IsOpen(ulong &ticket, string symbol, long magicNumber = 0) +{ + int positions=PositionsTotal(); + + + for(int i=0;i 0) + { + if(PositionGetInteger(POSITION_MAGIC) != magicNumber) + continue; + } + + if((PositionGetString(POSITION_SYMBOL) == symbol)) + { + ticket = _ticket; + return true; + } + } + } + else + { + PrintFormat("Error when obtaining position from the list to the cache. Error code: %d",GetLastError()); + } + } + + return false; +} + +string CMarketOrder::PositionTypeToString(ENUM_POSITION_TYPE t) +{ + if(t == POSITION_TYPE_BUY) + return "Buy"; + else if(t == POSITION_TYPE_SELL) + return "Sell"; + else + return "-"; +} + +bool CMarketOrder::RetryOrderRequest(int retryNumber) +{ + if(retryNumber >= this.numberOfRetries) + { + PrintFormat("Giving up on maximum number of retries (%d)",this.numberOfRetries); + return false; + } + + switch(ctrade.ResultRetcode()) + { + case TRADE_RETCODE_REQUOTE : + + Sleep(this.requoteTimeout_ms); + return true; + + break; + + case TRADE_RETCODE_REJECT : + case TRADE_RETCODE_ERROR : + case TRADE_RETCODE_TIMEOUT : + case TRADE_RETCODE_PRICE_OFF : + case TRADE_RETCODE_TOO_MANY_REQUESTS : + + Sleep(this.busyTimeout_ms); + return true; + + break; + + default: + return false; + } + +} + +//+------------------------------------------------------------------+ +//| Normalizing | +//+------------------------------------------------------------------+ + +double NormalizeLots(string symbol, double InputLots) +{ + double lotsMin = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN); + double lotsMax = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX); + int lotsDigits = (int) - MathLog10(SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP)); + + if(InputLots < lotsMin) + InputLots = lotsMin; + if(InputLots > lotsMax) + InputLots = lotsMax; + + return NormalizeDouble(InputLots, lotsDigits); +} + +double NormalizePrice(string symbol, double price, double tick = 0) +{ + double _tick = tick ? tick : SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE); + int _digits = (int)SymbolInfoInteger(symbol,SYMBOL_DIGITS); + + if (tick) + return NormalizeDouble(MathRound(price/_tick)*_tick,_digits); + else + return NormalizeDouble(price,_digits); +} + \ No newline at end of file diff --git a/Include/RangeBarIndicator.mqh b/Include/RangeBarIndicator.mqh deleted file mode 100644 index 79ad2e8..0000000 --- a/Include/RangeBarIndicator.mqh +++ /dev/null @@ -1,309 +0,0 @@ -//+------------------------------------------------------------------+ -//| RangeBarIndicator.mq5 | -//| Copyright 2017, AZ-iNVEST | -//| http://www.az-invest.eu | -//+------------------------------------------------------------------+ -#property library -#property copyright "Copyright 2017, AZ-iNVEST" -#property link "http://www.az-invest.eu" -#property version "1.10" -#include - -class RangeBarIndicator -{ - - private: - - RangeBars * rangeBars; - int rates_total; - int prev_calculated; - bool useAppliedPrice; - ENUM_APPLIED_PRICE applied_price; - - public: - - double Open[]; - double Low[]; - double High[]; - double Close[]; - double Price[]; - - RangeBarIndicator(); - ~RangeBarIndicator(); - - void SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) { this.useAppliedPrice = true; this.applied_price = _applied_price; }; - - bool OnCalculate(const int rates_total,const int prev_calculated, const datetime &Time[]); - int GetPrevCalculated() { return prev_calculated; }; - - private: - - bool CheckStatus(); - bool NeedsReload(); - int GetOLHC(int start, int count); - void OLHCShiftRight(); - void OLHCResize(); - - bool Canvas_IsNewBar(const datetime &_Time[]); - bool Canvas_IsRatesTotalChanged(int ratesTotalNow); - - ENUM_TIMEFRAMES TFMigrate(int tf); - datetime iTime(string symbol,int tf,int index); - -}; - -RangeBarIndicator::RangeBarIndicator(void) -{ - rangeBars = new RangeBars(); - if(rangeBars != NULL) - rangeBars.Init(); - - useAppliedPrice = false; -} - -RangeBarIndicator::~RangeBarIndicator(void) -{ - if(rangeBars != NULL) - { - rangeBars.Deinit(); - delete rangeBars; - } -} - -bool RangeBarIndicator::CheckStatus(void) -{ - int handle = rangeBars.GetHandle(); - - if(handle == INVALID_HANDLE) - return false; - - return true; -} - -bool RangeBarIndicator::NeedsReload(void) -{ - if(rangeBars.Reload()) - { - Print("Chart settings changed - reloading indicator with new settings"); - return true; - } - - return false; -} - -bool RangeBarIndicator::OnCalculate(const int _rates_total,const int _prev_calculated, const datetime &Time[]) -{ - static bool firstRun = true; - - if(firstRun) - { - Canvas_IsRatesTotalChanged(_rates_total); - firstRun = false; - } - - if(!CheckStatus()) - return false; - - ArraySetAsSeries(this.Open,false); - ArraySetAsSeries(this.High,false); - ArraySetAsSeries(this.Low,false); - ArraySetAsSeries(this.Close,false); - ArraySetAsSeries(this.Price,false); - - if(Canvas_IsRatesTotalChanged(_rates_total)) - { - OLHCResize(); - - this.prev_calculated = prev_calculated; - Canvas_IsNewBar(Time); - return true; - } - else if(Canvas_IsNewBar(Time)) - { - //Print("Got Canvas_IsNewBar"); - //GetOLHC(0,0); - if(ArraySize(this.Open) == 0) - { - GetOLHC(0,_rates_total); - this.prev_calculated = 0; - //Print("canvas new bar ZERO elements -> getting new : ArraySize of Open = "+ArraySize(this.Open)); - return false; - - } - - OLHCShiftRight(); - this.prev_calculated = prev_calculated; - return true; - } - - if(NeedsReload() || rangeBars.IsNewBar()) - { - GetOLHC(0,_rates_total); - this.prev_calculated = 0; - return false; - } - - // - // Recalculate lst bar - // - - GetOLHC(0,0); - this.prev_calculated = prev_calculated; - - return true; -} - -int RangeBarIndicator::GetOLHC(int start, int count) -{ - if((start == 0) && (count == 0)) - { - MqlRates tempRates[1]; - int last = ArraySize(Open)-1; - - if(last < 0) - return 0; - - rangeBars.GetMqlRates(tempRates,0,1); - this.Open[last] = tempRates[0].open; - this.Low[last] = tempRates[0].low; - this.High[last] = tempRates[0].high; - this.Close[last] = tempRates[0].close; - if(useAppliedPrice) - { - this.Price[last] = rangeBars.CalcAppliedPrice(tempRates[0],this.applied_price); - } - - return 1; - } - else - { - if(useAppliedPrice) - return rangeBars.GetOLHCAndApplPriceForIndicatorCalc(this.Open,this.Low,this.High,this.Close,this.Price,this.applied_price,0,count); - else - return rangeBars.GetOLHCForIndicatorCalc(this.Open,this.Low,this.High,this.Close,0,count); - - } -} - - -void RangeBarIndicator::OLHCShiftRight() -{ - int count = ArraySize(this.Open); - - if(count <= 0) - return; - - count--; - - for(int i=count; i>0; i--) - { - this.Open[i] = this.Open[i-1]; - this.High[i] = this.High[i-1]; - this.Low[i] = this.Low[i-1]; - this.Close[i] = this.Close[i-1]; - this.Price[i] = this.Price[i-1]; - } - - this.Open[0] = 0.0; - this.High[0] = 0.0; - this.Low[0] = 0.0; - this.Close[0] = 0.0; - this.Price[0] = 0.0; -} - -void RangeBarIndicator::OLHCResize() -{ - int count = ArraySize(this.Open); - - if(count <= 0) - return; - - ArrayResize(this.Open,count+1); - ArrayResize(this.Low,count+1); - ArrayResize(this.High,count+1); - ArrayResize(this.Close,count+1); - ArrayResize(this.Price,count+1); - - OLHCShiftRight(); -} - -bool RangeBarIndicator::Canvas_IsNewBar(const datetime &_Time[]) -{ - ArraySetAsSeries(_Time,true); - datetime now = _Time[0]; - ArraySetAsSeries(_Time,false); - - static datetime prevTime = 0; - - if(prevTime != now) - { - prevTime = now; - return true; - } - - return false; -} - -bool RangeBarIndicator::Canvas_IsRatesTotalChanged(int ratesTotalNow) -{ - static int prevRatesTotal = 0; - - if(prevRatesTotal == 0) - prevRatesTotal = ratesTotalNow; - - if(prevRatesTotal != ratesTotalNow) - { - prevRatesTotal = ratesTotalNow; - return true; - } - - return false; -} - - -ENUM_TIMEFRAMES RangeBarIndicator::TFMigrate(int tf) - { - switch(tf) - { - case 0: return(PERIOD_CURRENT); - case 1: return(PERIOD_M1); - case 5: return(PERIOD_M5); - case 15: return(PERIOD_M15); - case 30: return(PERIOD_M30); - case 60: return(PERIOD_H1); - case 240: return(PERIOD_H4); - case 1440: return(PERIOD_D1); - case 10080: return(PERIOD_W1); - case 43200: return(PERIOD_MN1); - - case 2: return(PERIOD_M2); - case 3: return(PERIOD_M3); - case 4: return(PERIOD_M4); - case 6: return(PERIOD_M6); - case 10: return(PERIOD_M10); - case 12: return(PERIOD_M12); - case 16385: return(PERIOD_H1); - case 16386: return(PERIOD_H2); - case 16387: return(PERIOD_H3); - case 16388: return(PERIOD_H4); - case 16390: return(PERIOD_H6); - case 16392: return(PERIOD_H8); - case 16396: return(PERIOD_H12); - case 16408: return(PERIOD_D1); - case 32769: return(PERIOD_W1); - case 49153: return(PERIOD_MN1); - default: return(PERIOD_CURRENT); - } - } - -datetime RangeBarIndicator::iTime(string symbol,int tf,int index) -{ - if(index < 0) return(-1); - ENUM_TIMEFRAMES timeframe=TFMigrate(tf); - datetime Arr[]; - if(CopyTime(symbol, timeframe, index, 1, Arr)>0) - return(Arr[0]); - else return(-1); -} - - diff --git a/Include/RangeBarSettings.mqh b/Include/RangeBarSettings.mqh deleted file mode 100644 index 87fdb58..0000000 --- a/Include/RangeBarSettings.mqh +++ /dev/null @@ -1,318 +0,0 @@ -//+------------------------------------------------------------------+ -//| RangeBarSettings.mqh ver 1.04 | -//| Copyright 2017, AZ-iNVEST | -//| http://www.az-invest.eu | -//+------------------------------------------------------------------+ - -#property copyright "Copyright 2017, AZ-iNVEST" -#property link "http://www.az-invest.eu" - -enum ENUM_CHANNEL_TYPE -{ - None = 0, // None - Donchian_Channel, // Donchian Channel - Bollinger_Bands, // Bollinger Bands - SuperTrend, // Super Trend -// VWAP, -}; - -#ifdef SHOW_INDICATOR_INPUTS - -input int barSizeInTicks = 100; // Range bar size (in points) - double customBarSize = barSizeInTicks * Point(); - bool useTickVolume = true; // Use tick volume (for FX) -input datetime _startFromDateTime = 0; // Start building chart from date/time - datetime startFromDateTime = 0; -input bool resetOpenOnNewTradingDay = false; // Synchronize first bar's open on new day -input bool showNextBarLevels = true; // Show current bar's close projections -input color HighThresholdIndicatorColor = clrLime; // Bullish bar projection color -input color LowThresholdIndicatorColor = clrRed; // Bearish bar projection color -input bool showCurrentBarOpenTime = true; // Display chart info and current bar's open time -input color InfoTextColor = clrWhite; // Current bar's open time info color -input bool UseSoundSignalOnNewBar = false; // Play sound on new bar -input bool OnlySignalReversalBars = false; // Only signal reversals -input bool UseAlertWindow = false; // Display Alert window with new bar info -input bool SendPushNotifications = false; // Send new bar info push notification to smartphone -input string SoundFileBull = "news.wav"; // Use sound file for bullish bar close -input string SoundFileBear = "news.wav"; // Use sound file for bearish bar close -input bool MA1on = false; // Show first MA -input int MA1period = 20; // 1st MA period -input ENUM_MA_METHOD MA1method = MODE_EMA; // 1st MA metod -input ENUM_APPLIED_PRICE MA1applyTo = PRICE_CLOSE; //1st MA apply to -input int MA1shift = 0; //1st MA shift -input bool MA2on = false; // Show second MA -input int MA2period = 50; // 2nd MA period -input ENUM_MA_METHOD MA2method = MODE_EMA; // 2nd MA method -input ENUM_APPLIED_PRICE MA2applyTo = PRICE_CLOSE; // 2nd MA apply to -input int MA2shift = 0; //2nd MA shift -input ENUM_CHANNEL_TYPE ShowChannel = None; // Show Channel -input string Channel_Settings = "--------------------------"; // Channel settings -input int DonchianPeriod = 20; // Donchian Channel period -input ENUM_APPLIED_PRICE BBapplyTo = PRICE_CLOSE; //Bollinger Bands apply to -input int BollingerBandsPeriod = 20; // Bollinger Bands period -input double BollingerBandsDeviations = 2.0; // Bollinger Bands deviations -input int SuperTrendPeriod = 10; // Super Trend period -input double SuperTrendMultiplier=1.7; // Super Trend multiplier -input string Misc_Settings = "--------------------------"; // Misc settings -input bool UsedInEA = false; // Indicator used in EA via iCustom() - -#else - - int barSizeInTicks; - bool useTickVolume = true; - datetime startFromDateTime; - datetime _startFromDateTime = 0; - bool resetOpenOnNewTradingDay; - - // - // This block should always be set to the follwong values - // - - bool showNextBarLevels = false; - color HighThresholdIndicatorColor = clrNONE; - color LowThresholdIndicatorColor = clrNONE; - bool showCurrentBarOpenTime = false; - color InfoTextColor = clrNONE; - bool UseSoundSignalOnNewBar = false; - bool OnlySignalReversalBars = false; - bool UseAlertWindow = false; - bool SendPushNotifications = false; - string SoundFileBull = ""; - string SoundFileBear = ""; - - bool UsedInEA = true; // This should always be set to TRUE for EAs & Indicators - - // - // - // - - bool MA1on; - int MA1period; - ENUM_MA_METHOD MA1method; - ENUM_APPLIED_PRICE MA1applyTo; - int MA1shift; - - bool MA2on; - int MA2period; - ENUM_MA_METHOD MA2method; - ENUM_APPLIED_PRICE MA2applyTo; - int MA2shift; - - ENUM_CHANNEL_TYPE ShowChannel; - int DonchianPeriod; - ENUM_APPLIED_PRICE BBapplyTo; - int BollingerBandsPeriod; - double BollingerBandsDeviations; - int SuperTrendPeriod = 10; - double SuperTrendMultiplier=1.7; - -#endif - -struct RANGEBAR_SETTINGS -{ - int barSizeInTicks; - bool useTickVolume; - datetime _startFromDateTime; - bool resetOpenOnNewTradingDay; - - bool MA1on; - int MA1period; - ENUM_MA_METHOD MA1method; - ENUM_APPLIED_PRICE MA1applyTo; - int MA1shift; - - bool MA2on; - int MA2period; - ENUM_MA_METHOD MA2method; - ENUM_APPLIED_PRICE MA2applyTo; - int MA2shift; - - ENUM_CHANNEL_TYPE ShowChannel; - - int DonchianPeriod; - - ENUM_APPLIED_PRICE BBapplyTo; - int BollingerBandsPeriod; - double BollingerBandsDeviations; - - int SuperTrendPeriod; - double SuperTrendMultiplier; -}; - -class RangeBarSettings -{ - protected: - - string settingsFileName; - RANGEBAR_SETTINGS settings; - - public: - - RangeBarSettings(void); - ~RangeBarSettings(void); - - void Save(void); - bool Load(void); - void Delete(void); - bool Changed(void); - - RANGEBAR_SETTINGS Get(void); - void Debug(void); -}; - -void RangeBarSettings::RangeBarSettings(void) -{ - this.settingsFileName = "RangeBars"+(string)ChartID()+".set"; - -} - -void RangeBarSettings::~RangeBarSettings(void) -{ - -} - -void RangeBarSettings::Save(void) -{ - settings.barSizeInTicks = barSizeInTicks; - settings.useTickVolume = useTickVolume; - settings._startFromDateTime = startFromDateTime; - settings.resetOpenOnNewTradingDay = resetOpenOnNewTradingDay; - settings.MA1on = MA1on; - settings.MA1period = MA1period; - settings.MA1method = MA1method; - settings.MA1applyTo = MA1applyTo; - settings.MA1shift = MA1shift; - settings.MA2on = MA2on; - settings.MA2period = MA2period; - settings.MA2method = MA2method; - settings.MA2applyTo = MA2applyTo; - settings.MA2shift = MA2shift; - settings.ShowChannel = ShowChannel; - settings.DonchianPeriod = DonchianPeriod; - settings.BBapplyTo = BBapplyTo; - settings.BollingerBandsPeriod = BollingerBandsPeriod; - settings.BollingerBandsDeviations = BollingerBandsDeviations; - settings.SuperTrendPeriod = SuperTrendPeriod; - settings.SuperTrendMultiplier = SuperTrendMultiplier; - - if(MQLInfoInteger((int)MQL5_TESTING)) - return; - - this.Delete(); - - int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_WRITE|FILE_BIN); - FileWriteStruct(handle,this.settings); - FileClose(handle); -} - -void RangeBarSettings::Delete(void) -{ - if(FileIsExist(this.settingsFileName)) - FileDelete(this.settingsFileName); -} - -bool RangeBarSettings::Load(void) -{ -#ifdef SHOW_INDICATOR_INPUTS - this.settings.barSizeInTicks = barSizeInTicks; - this.settings.useTickVolume = useTickVolume; - this.settings._startFromDateTime = _startFromDateTime; - this.settings.resetOpenOnNewTradingDay = resetOpenOnNewTradingDay; - this.settings.MA1on = MA1on; - this.settings.MA1period = MA1period; - this.settings.MA1method = MA1method; - this.settings.MA1applyTo = MA1applyTo; - this.settings.MA1shift = MA1shift; - this.settings.MA2on = MA2on; - this.settings.MA2period = MA2period; - this.settings.MA2method = MA2method; - this.settings.MA2applyTo = MA2applyTo; - this.settings.MA2shift = MA2shift; - this.settings.ShowChannel = ShowChannel; - this.settings.DonchianPeriod = DonchianPeriod; - this.settings.BBapplyTo = BBapplyTo; - this.settings.BollingerBandsPeriod = BollingerBandsPeriod; - this.settings.BollingerBandsDeviations = BollingerBandsDeviations; - this.settings.SuperTrendPeriod = SuperTrendPeriod; - this.settings.SuperTrendMultiplier = SuperTrendMultiplier; - return true; -#else - - if(!FileIsExist(this.settingsFileName)) - return false; - - int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_BIN); - if(handle == INVALID_HANDLE) - return false; - - if(FileReadStruct(handle,this.settings) <= 0) - { - Print("Failed loading settigns!"); - FileClose(handle); - return false; - } - - // this.Debug(); - FileClose(handle); - return true; - -#endif -} - -RANGEBAR_SETTINGS RangeBarSettings::Get(void) -{ - this.Debug(); - return this.settings; -} - -bool RangeBarSettings::Changed(void) -{ - if(MQLInfoInteger((int)MQL5_TESTING)) - return false; - - static datetime prevFileTime = 0; - - if(!FileIsExist(this.settingsFileName)) - return false; - - int handle = FileOpen(this.settingsFileName,FILE_SHARE_READ|FILE_BIN); - datetime currFileTime = (datetime)FileGetInteger(handle,FILE_CREATE_DATE); - FileClose(handle); - - if(prevFileTime != currFileTime) - { - prevFileTime = currFileTime; - return true; - } - - return false; -} - -void RangeBarSettings::Debug(void) -{ - Print("RangeBars settings:"); - Print("barSizeInTicks = "+(string)settings.barSizeInTicks); - Print("useTickVolume = "+(string)settings.useTickVolume); - Print("startFromDateTime = "+(string)settings._startFromDateTime); - Print("resetOpenOnNewTradingDay = "+(string)settings.resetOpenOnNewTradingDay); - Print("MA1on = "+(string)settings.MA1on); - Print("MA1period = "+(string)settings.MA1period); - Print("MA1method = "+(string)settings.MA1method); - Print("MA1applyTo = "+(string)settings.MA1applyTo); - Print("MA1shift = "+(string)settings.MA1shift); - Print("MA2on = "+(string)settings.MA2on); - Print("MA2period = "+(string)settings.MA2period); - Print("MA2method = "+(string)settings.MA2method); - Print("MA2applyTo = "+(string)settings.MA2applyTo); - Print("MA2shift = "+(string)settings.MA1shift); - Print("ShowChannel = "+(string)settings.ShowChannel); - Print("DonchianPeriod = "+(string)settings.DonchianPeriod); - Print("BBapplyTo = "+(string)settings.BBapplyTo); - Print("BBperiod = "+(string)settings.BollingerBandsPeriod); - Print("BBdeviations = "+(string)settings.BollingerBandsDeviations); - Print("SuperTrendPeriod = "+(string)settings.SuperTrendPeriod); - Print("SuperTrendMultiplier = "+(string)settings.SuperTrendMultiplier); - - Print("UsedInEA = "+(string)UsedInEA); - -} \ No newline at end of file diff --git a/Indicators/RangeBars/RangeBars_ADX.mq5 b/Indicators/RangeBars/RangeBars_ADX.mq5 new file mode 100644 index 0000000..ddfd34a --- /dev/null +++ b/Indicators/RangeBars/RangeBars_ADX.mq5 @@ -0,0 +1,203 @@ + + +//+------------------------------------------------------------------+ +//| ADX.mq5 | +//| Copyright 2009, MetaQuotes Software Corp. | +//| http://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "2009, MetaQuotes Software Corp." +#property link "http://www.mql5.com" +#property description "Average Directional Movement Index" +#include + +#property indicator_separate_window +#property indicator_buffers 6 +#property indicator_plots 3 +#property indicator_type1 DRAW_LINE +#property indicator_color1 LightSeaGreen +#property indicator_style1 STYLE_SOLID +#property indicator_width1 1 +#property indicator_type2 DRAW_LINE +#property indicator_color2 YellowGreen +#property indicator_style2 STYLE_DOT +#property indicator_width2 1 +#property indicator_type3 DRAW_LINE +#property indicator_color3 Wheat +#property indicator_style3 STYLE_DOT +#property indicator_width3 1 +#property indicator_label1 "ADX" +#property indicator_label2 "+DI" +#property indicator_label3 "-DI" +//--- input parameters +input int InpPeriodADX=14; // Period +//---- buffers +double ExtADXBuffer[]; +double ExtPDIBuffer[]; +double ExtNDIBuffer[]; +double ExtPDBuffer[]; +double ExtNDBuffer[]; +double ExtTmpBuffer[]; +//--- global variables +int ExtADXPeriod; + +// +// +// + +#include +RangeBarIndicator rangeBarsIndicator; + +// +// +// + + +//+------------------------------------------------------------------+ +//| Custom indicator initialization function | +//+------------------------------------------------------------------+ +void OnInit() + { +//--- check for input parameters + if(InpPeriodADX>=100 || InpPeriodADX<=0) + { + ExtADXPeriod=14; + printf("Incorrect value for input variable Period_ADX=%d. Indicator will use value=%d for calculations.",InpPeriodADX,ExtADXPeriod); + } + else ExtADXPeriod=InpPeriodADX; +//---- indicator buffers + SetIndexBuffer(0,ExtADXBuffer); + SetIndexBuffer(1,ExtPDIBuffer); + SetIndexBuffer(2,ExtNDIBuffer); + SetIndexBuffer(3,ExtPDBuffer,INDICATOR_CALCULATIONS); + SetIndexBuffer(4,ExtNDBuffer,INDICATOR_CALCULATIONS); + SetIndexBuffer(5,ExtTmpBuffer,INDICATOR_CALCULATIONS); +//--- indicator digits + IndicatorSetInteger(INDICATOR_DIGITS,2); +//--- set draw begin + PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtADXPeriod<<1); + PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,ExtADXPeriod); + PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,ExtADXPeriod); +//--- indicator short name + string short_name="ADX("+string(ExtADXPeriod)+")"; + IndicatorSetString(INDICATOR_SHORTNAME,short_name); +//--- change 1-st index label + PlotIndexSetString(0,PLOT_LABEL,short_name); +//---- end of initialization function + } +//+------------------------------------------------------------------+ +//| Custom indicator iteration function | +//+------------------------------------------------------------------+ +int OnCalculate(const int rates_total, + const int prev_calculated, + const datetime &Time[], + const double &Open[], + const double &High[], + const double &Low[], + const double &Close[], + const long &TickVolume[], + const long &Volume[], + const int &Spread[]) + { + // + // Process data through MedianRenko indicator + // + + if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time)) + return(0); + + // + // Make the following modifications in the code below: + // + // rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated + // + // rangeBarsIndicator.Open[] should be used instead of open[] + // rangeBarsIndicator.Low[] should be used instead of low[] + // rangeBarsIndicator.High[] should be used instead of high[] + // rangeBarsIndicator.Close[] should be used instead of close[] + // + // rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed + // + // rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time. + // (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used + // + // rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[] + // rangeBarsIndicator.Real_volume[] should be used instead of Volume[] + // (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used + // + // rangeBarsIndicator.Price[] should be used instead of Price[] + // (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used + // + + int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); + + // + // + // + +//--- checking for bars count + if(rates_total1) start=_prev_calculated-1; + else + { + start=1; + ExtPDIBuffer[0]=0.0; + ExtNDIBuffer[0]=0.0; + ExtADXBuffer[0]=0.0; + } +//--- main cycle + for(int i=start;idTmpN) dTmpN=0.0; + else + { + if(dTmpPJLzV+bp>8G({IynM9rP_OX^+V>tQ-f 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 literal 0 HcmV?d00001 diff --git a/Indicators/RangeBars/RangeBars_CCI.mq5 b/Indicators/RangeBars/RangeBars_CCI.mq5 new file mode 100644 index 0000000..7b6f5ed --- /dev/null +++ b/Indicators/RangeBars/RangeBars_CCI.mq5 @@ -0,0 +1,168 @@ + + +//+------------------------------------------------------------------+ +//| CCI.mq5 | +//| Copyright 2009, MetaQuotes Software Corp. | +//| http://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "2009, MetaQuotes Software Corp." +#property link "http://www.mql5.com" +#property description "Commodity Channel Index" +#include +//--- +#property indicator_separate_window +#property indicator_buffers 4 +#property indicator_plots 1 +#property indicator_type1 DRAW_LINE +#property indicator_color1 LightSeaGreen +#property indicator_level1 -100.0 +#property indicator_level2 100.0 +#property indicator_applied_price PRICE_TYPICAL +//--- input parametrs +input int InpCCIPeriod=14; // Period +input ENUM_APPLIED_PRICE InpApplyToPrice= PRICE_CLOSE; // Apply to +//--- global variable +int ExtCCIPeriod; +//---- indicator buffer +double ExtSPBuffer[]; +double ExtDBuffer[]; +double ExtMBuffer[]; +double ExtCCIBuffer[]; + +// +// +// + +#include +RangeBarIndicator rangeBarsIndicator; + +// +// +// + +//+------------------------------------------------------------------+ +//| Custom indicator initialization function | +//+------------------------------------------------------------------+ +void OnInit() + { + + // + // Indicator uses Price[] array for calculations so we need to set this in the MedianRenkoIndicator class + // + + rangeBarsIndicator.SetUseAppliedPriceFlag(InpApplyToPrice); + + // + // + // + +//--- check for input value of period + if(InpCCIPeriod<=0) + { + ExtCCIPeriod=14; + printf("Incorrect value for input variable InpCCIPeriod=%d. Indicator will use value=%d for calculations.",InpCCIPeriod,ExtCCIPeriod); + } + else ExtCCIPeriod=InpCCIPeriod; +//--- define buffers + SetIndexBuffer(0,ExtCCIBuffer); + SetIndexBuffer(1,ExtDBuffer,INDICATOR_CALCULATIONS); + SetIndexBuffer(2,ExtMBuffer,INDICATOR_CALCULATIONS); + SetIndexBuffer(3,ExtSPBuffer,INDICATOR_CALCULATIONS); +//--- indicator name + IndicatorSetString(INDICATOR_SHORTNAME,"CCI("+string(ExtCCIPeriod)+")"); +//--- indexes draw begin settings + PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtCCIPeriod-1); +//--- number of digits of indicator value + IndicatorSetInteger(INDICATOR_DIGITS,2); +//---- OnInit done + } +//+------------------------------------------------------------------+ +//| Custom indicator iteration function | +//+------------------------------------------------------------------+ +/* +int OnCalculate(const int rates_total, + const int prev_calculated, + const int begin, + const double &price[]) + { +*/ +int OnCalculate(const int rates_total,const int prev_calculated, + const datetime &Time[], + const double &Open[], + const double &High[], + const double &Low[], + const double &Close[], + const long &TickVolume[], + const long &Volume[], + const int &Spread[]) + { + // + // Process data through MedianRenko indicator + // + + if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time)) + return(0); + + // + // Make the following modifications in the code below: + // + // rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated + // + // rangeBarsIndicator.Open[] should be used instead of open[] + // rangeBarsIndicator.Low[] should be used instead of low[] + // rangeBarsIndicator.High[] should be used instead of high[] + // rangeBarsIndicator.Close[] should be used instead of close[] + // + // rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed + // + // rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time. + // (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used + // + // rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[] + // rangeBarsIndicator.Real_volume[] should be used instead of Volume[] + // (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used + // + // rangeBarsIndicator.Price[] should be used instead of Price[] + // (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used + // + + int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); + + // + // + // + +//--- variables + int i,j; + double dTmp,dMul=0.015/ExtCCIPeriod; +//--- start calculation + int StartCalcPosition=(ExtCCIPeriod-1);//+begin; +//--- check for bars count + if(rates_total0) PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,StartCalcPosition+(ExtCCIPeriod-1)); +//--- calculate position + int pos=_prev_calculated-1; + if(pos?YYoma)eMVT0EfSavr*D1S1^ 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 literal 0 HcmV?d00001 diff --git a/Indicators/RangeBars/RangeBars_Fractals.mq5 b/Indicators/RangeBars/RangeBars_Fractals.mq5 new file mode 100644 index 0000000..4c33d0c --- /dev/null +++ b/Indicators/RangeBars/RangeBars_Fractals.mq5 @@ -0,0 +1,134 @@ +//+------------------------------------------------------------------+ +//| Fractals.mq5 | +//| Copyright 2009, MetaQuotes Software Corp. | +//| http://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "2009, MetaQuotes Software Corp." +#property link "http://www.mql5.com" +//---- indicator settings +#property indicator_chart_window +#property indicator_buffers 2 +#property indicator_plots 2 +#property indicator_type1 DRAW_ARROW +#property indicator_type2 DRAW_ARROW +#property indicator_color1 Gray +#property indicator_color2 Gray +#property indicator_label1 "Fractal Up" +#property indicator_label2 "Fractal Down" +//---- indicator buffers +double ExtUpperBuffer[]; +double ExtLowerBuffer[]; +//--- 10 pixels upper from high price +int ExtArrowShift=-10; + +// +// +// + +#include +RangeBarIndicator rangeBarsIndicator; + +// +// +// + +//+------------------------------------------------------------------+ +//| Custom indicator initialization function | +//+------------------------------------------------------------------+ +void OnInit() + { +//---- indicator buffers mapping + SetIndexBuffer(0,ExtUpperBuffer,INDICATOR_DATA); + SetIndexBuffer(1,ExtLowerBuffer,INDICATOR_DATA); + IndicatorSetInteger(INDICATOR_DIGITS,_Digits); +//---- sets first bar from what index will be drawn + PlotIndexSetInteger(0,PLOT_ARROW,217); + PlotIndexSetInteger(1,PLOT_ARROW,218); +//---- arrow shifts when drawing + PlotIndexSetInteger(0,PLOT_ARROW_SHIFT,ExtArrowShift); + PlotIndexSetInteger(1,PLOT_ARROW_SHIFT,-ExtArrowShift); +//---- sets drawing line empty value-- + PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE); + PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE); +//---- initialization done + } +//+------------------------------------------------------------------+ +//| Accelerator/Decelerator Oscillator | +//+------------------------------------------------------------------+ +int OnCalculate(const int rates_total,const int prev_calculated, + const datetime &Time[], + const double &Open[], + const double &High[], + const double &Low[], + const double &Close[], + const long &TickVolume[], + const long &Volume[], + const int &Spread[]) + { + // + // Process data through MedianRenko indicator + // + + if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time)) + return(0); + + // + // Make the following modifications in the code below: + // + // rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated + // + // rangeBarsIndicator.Open[] should be used instead of open[] + // rangeBarsIndicator.Low[] should be used instead of low[] + // rangeBarsIndicator.High[] should be used instead of high[] + // rangeBarsIndicator.Close[] should be used instead of close[] + // + // rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed + // + // rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time. + // (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used + // + // rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[] + // rangeBarsIndicator.Real_volume[] should be used instead of Volume[] + // (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used + // + // rangeBarsIndicator.Price[] should be used instead of Price[] + // (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used + // + + int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); + + // + // + // + + int i,limit; +//--- + if(rates_total<5) + return(0); +//--- + if(_prev_calculated<7) + { + limit=2; + //--- clean up arrays + ArrayInitialize(ExtUpperBuffer,EMPTY_VALUE); + ArrayInitialize(ExtLowerBuffer,EMPTY_VALUE); + } + else limit=rates_total-5; + + for(i=limit; irangeBarsIndicator.High[i+1] && rangeBarsIndicator.High[i]>rangeBarsIndicator.High[i+2] && rangeBarsIndicator.High[i]>=rangeBarsIndicator.High[i-1] && rangeBarsIndicator.High[i]>=rangeBarsIndicator.High[i-2]) + ExtUpperBuffer[i]=rangeBarsIndicator.High[i]; + else ExtUpperBuffer[i]=EMPTY_VALUE; + + //---- Lower Fractal + if(rangeBarsIndicator.Low[i] +RangeBarIndicator rangeBarsIndicator; + +// +// +// + +//+------------------------------------------------------------------+ +//| Custom indicator initialization function | +//+------------------------------------------------------------------+ +int OnInit() + { +//--- check period + period=(int)fmax(InpPeriod,2); +//--- set buffers + SetIndexBuffer(0,GannBuffer); + SetIndexBuffer(1,ColorBuffer,INDICATOR_COLOR_INDEX); + SetIndexBuffer(2,MaHighBuffer,INDICATOR_CALCULATIONS); + SetIndexBuffer(3,MaLowBuffer,INDICATOR_CALCULATIONS); + SetIndexBuffer(4,TrendBuffer,INDICATOR_CALCULATIONS); +//--- set direction + ArraySetAsSeries(GannBuffer,true); + ArraySetAsSeries(ColorBuffer,true); + ArraySetAsSeries(MaHighBuffer,true); + ArraySetAsSeries(MaLowBuffer,true); + ArraySetAsSeries(TrendBuffer,true); +//--- get handles + ma_high_handle=iMA(NULL,0,period,0,InpMethod,PRICE_HIGH); + ma_low_handle =iMA(NULL,0,period,0,InpMethod,PRICE_LOW); + if(ma_high_handle==INVALID_HANDLE || ma_low_handle==INVALID_HANDLE) + { + Print("Unable to create handle for iMA"); + return(INIT_FAILED); + } +//--- set indicator properties + string short_name=StringFormat("Gann High-Low Activator SSL (%u, %s)",period,StringSubstr(EnumToString(InpMethod),5)); + IndicatorSetString(INDICATOR_SHORTNAME,short_name); + IndicatorSetInteger(INDICATOR_DIGITS,_Digits); +//--- set label + short_name=StringFormat("GHL (%u, %s)",period,StringSubstr(EnumToString(InpMethod),5)); + PlotIndexSetString(0,PLOT_LABEL,short_name); +//--- done + return(INIT_SUCCEEDED); + } +//+------------------------------------------------------------------+ +//| Custom indicator iteration function | +//+------------------------------------------------------------------+ +int OnCalculate(const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[]) + { + + if(rates_total=0 && !_StopFlag; i--) + { + TrendBuffer[i]=TrendBuffer[i+1]; + //--- + if(NormalizeDouble(rangeBarsIndicator.Close[i],_Digits)>NormalizeDouble(MaHighBuffer[i+1],_Digits)) TrendBuffer[i]=1; + if(NormalizeDouble(rangeBarsIndicator.Close[i],_Digits)0) + { + GannBuffer[i]=MaLowBuffer[i]; + ColorBuffer[i]=0; + } + } +//--- done + return(rates_total); + } +//+------------------------------------------------------------------+ diff --git a/Indicators/RangeBars/RangeBars_HA_Smoothed.mq5 b/Indicators/RangeBars/RangeBars_HA_Smoothed.mq5 new file mode 100644 index 0000000000000000000000000000000000000000..343f6570297869c5298c417f73c212e6620b049b GIT binary patch literal 18284 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 CYJP42 literal 0 HcmV?d00001 diff --git a/Indicators/RangeBars/RangeBars_Heiken_Ashi.mq5 b/Indicators/RangeBars/RangeBars_Heiken_Ashi.mq5 new file mode 100644 index 0000000..dd542fd --- /dev/null +++ b/Indicators/RangeBars/RangeBars_Heiken_Ashi.mq5 @@ -0,0 +1,137 @@ + +//+------------------------------------------------------------------+ +//| Heiken_Ashi.mq5 | +//| Copyright 2009-2017, MetaQuotes Software Corp. | +//| http://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "2009-2017, MetaQuotes Software Corp." +#property link "http://www.mql5.com" +//--- indicator settings +#property indicator_chart_window +#property indicator_buffers 5 +#property indicator_plots 1 +#property indicator_type1 DRAW_COLOR_CANDLES +#property indicator_color1 DodgerBlue, Red +#property indicator_label1 "Heiken Ashi Open;Heiken Ashi High;Heiken Ashi Low;Heiken Ashi Close" +//--- indicator buffers +double ExtOBuffer[]; +double ExtHBuffer[]; +double ExtLBuffer[]; +double ExtCBuffer[]; +double ExtColorBuffer[]; + +// +// +// + +#include +RangeBarIndicator rangeBarsIndicator; + +// +// +// + +//+------------------------------------------------------------------+ +//| Custom indicator initialization function | +//+------------------------------------------------------------------+ +void OnInit() + { +//--- indicator buffers mapping + SetIndexBuffer(0,ExtOBuffer,INDICATOR_DATA); + SetIndexBuffer(1,ExtHBuffer,INDICATOR_DATA); + SetIndexBuffer(2,ExtLBuffer,INDICATOR_DATA); + SetIndexBuffer(3,ExtCBuffer,INDICATOR_DATA); + SetIndexBuffer(4,ExtColorBuffer,INDICATOR_COLOR_INDEX); +//--- + IndicatorSetInteger(INDICATOR_DIGITS,_Digits); +//--- sets first bar from what index will be drawn + IndicatorSetString(INDICATOR_SHORTNAME,"Heiken Ashi"); +//--- sets drawing line empty value + PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); +//--- initialization done + } +//+------------------------------------------------------------------+ +//| Heiken Ashi | +//+------------------------------------------------------------------+ +int OnCalculate(const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[]) + { + int i,limit; + + // + // Process data through MedianRenko indicator + // + + if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time)) + return(0); + + // + // Make the following modifications in the code below: + // + // rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated + // + // rangeBarsIndicator.Open[] should be used instead of open[] + // rangeBarsIndicator.Low[] should be used instead of low[] + // rangeBarsIndicator.High[] should be used instead of high[] + // rangeBarsIndicator.Close[] should be used instead of close[] + // + // rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed + // + // rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time. + // (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used + // + // rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[] + // rangeBarsIndicator.Real_volume[] should be used instead of Volume[] + // (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used + // + // rangeBarsIndicator.Price[] should be used instead of Price[] + // (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used + // + + int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); + + // + // + // + +//--- preliminary calculations + if(_prev_calculated==0) + { + //--- set first candle + ExtLBuffer[0]=rangeBarsIndicator.Low[0]; + ExtHBuffer[0]=rangeBarsIndicator.High[0]; + ExtOBuffer[0]=rangeBarsIndicator.Open[0]; + ExtCBuffer[0]=rangeBarsIndicator.Close[0]; + limit=1; + } + else limit=_prev_calculated-1; + +//--- the main loop of calculations + for(i=limit;i +RangeBarIndicator rangeBarsIndicator; + +// +// +// + +//+------------------------------------------------------------------+ +//| Custom indicator initialization function | +//+------------------------------------------------------------------+ +void OnInit() + { +//--- indicator buffers mapping + SetIndexBuffer(0,ExtTenkanBuffer,INDICATOR_DATA); + SetIndexBuffer(1,ExtKijunBuffer,INDICATOR_DATA); + SetIndexBuffer(2,ExtSpanABuffer,INDICATOR_DATA); + SetIndexBuffer(3,ExtSpanBBuffer,INDICATOR_DATA); + SetIndexBuffer(4,ExtChikouBuffer,INDICATOR_DATA); +//--- + IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1); +//--- sets first bar from what index will be drawn + PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpTenkan); + PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,InpKijun); + PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,InpSenkou-1); +//--- lines shifts when drawing + PlotIndexSetInteger(2,PLOT_SHIFT,InpKijun); + PlotIndexSetInteger(3,PLOT_SHIFT,-InpKijun); +//--- change labels for DataWindow + PlotIndexSetString(0,PLOT_LABEL,"Tenkan-sen("+string(InpTenkan)+")"); + PlotIndexSetString(1,PLOT_LABEL,"Kijun-sen("+string(InpKijun)+")"); + PlotIndexSetString(2,PLOT_LABEL,"Senkou Span A;Senkou Span B("+string(InpSenkou)+")"); +//--- initialization done + } +//+------------------------------------------------------------------+ +//| get highest value for range | +//+------------------------------------------------------------------+ +double Highest(const double&array[],int range,int fromIndex) + { + double res=0; +//--- + res=array[fromIndex]; + for(int i=fromIndex;i>fromIndex-range && i>=0;i--) + { + if(resfromIndex-range && i>=0;i--) + { + if(res>array[i]) res=array[i]; + } +//--- + return(res); + } +//+------------------------------------------------------------------+ +//| Ichimoku Kinko Hyo | +//+------------------------------------------------------------------+ +int OnCalculate(const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[]) + { + // + // Process data through MedianRenko indicator + // + + if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time)) + return(0); + + // + // Make the following modifications in the code below: + // + // rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated + // + // rangeBarsIndicator.Open[] should be used instead of open[] + // rangeBarsIndicator.Low[] should be used instead of low[] + // rangeBarsIndicator.High[] should be used instead of high[] + // rangeBarsIndicator.Close[] should be used instead of close[] + // + // rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed + // + // rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time. + // (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used + // + // rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[] + // rangeBarsIndicator.Real_volume[] should be used instead of Volume[] + // (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used + // + // rangeBarsIndicator.Price[] should be used instead of Price[] + // (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used + // + + int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); + + // + // + // + + int limit; +//--- + if(_prev_calculated==0) limit=0; + else limit=_prev_calculated-1; +//--- + for(int i=limit;i +RangeBarIndicator rangeBarsIndicator; + +// +// +// + +//+------------------------------------------------------------------+ +//| simple moving average | +//+------------------------------------------------------------------+ +void CalculateSimpleMA(int rates_total,int prev_calculated,int begin,const double &price[]) + { + int i,limit; +//--- first calculation or number of bars was changed + if(prev_calculated==0)// first calculation + { + limit=InpMAPeriod+begin; + //--- set empty value for first limit bars + for(i=0;i +#include RangeBarIndicator rangeBarsIndicator; // // // + //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ @@ -84,7 +84,7 @@ int OnCalculate(const int rates_total,const int prev_calculated, // if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time)) - return(rangeBarsIndicator.GetPrevCalculated()); + return(0); // // Make the following modifications in the code below: diff --git a/Indicators/RangeBars/RangeBars_Momentum.mq5 b/Indicators/RangeBars/RangeBars_Momentum.mq5 new file mode 100644 index 0000000..cf0da5a --- /dev/null +++ b/Indicators/RangeBars/RangeBars_Momentum.mq5 @@ -0,0 +1,147 @@ + + +//+------------------------------------------------------------------+ +//| Momentum.mq5 | +//| Copyright 2009, MetaQuotes Software Corp. | +//| http://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "2009, MetaQuotes Software Corp." +#property link "http://www.mql5.com" +//---- indicator settings +#property indicator_separate_window +#property indicator_buffers 1 +#property indicator_plots 1 +#property indicator_type1 DRAW_LINE +#property indicator_color1 DodgerBlue +//---- input parameters +input int InpMomentumPeriod=14; // Period +input ENUM_APPLIED_PRICE InpApplyToPrice= PRICE_CLOSE; // Apply to +//---- indicator buffers +double ExtMomentumBuffer[]; +//--- global variable +int ExtMomentumPeriod; + +// +// +// + +#include +RangeBarIndicator rangeBarsIndicator; + +// +// +// +//+------------------------------------------------------------------+ +//| Custom indicator initialization function | +//+------------------------------------------------------------------+ +void OnInit() + { + // + // Indicator uses Price[] array for calculations so we need to set this in the MedianRenkoIndicator class + // + + rangeBarsIndicator.SetUseAppliedPriceFlag(InpApplyToPrice); + + // + // + // + +//--- check for input value + if(InpMomentumPeriod<0) + { + ExtMomentumPeriod=14; + Print("Input parameter InpMomentumPeriod has wrong value. Indicator will use value ",ExtMomentumPeriod); + } + else ExtMomentumPeriod=InpMomentumPeriod; +//---- buffers + SetIndexBuffer(0,ExtMomentumBuffer,INDICATOR_DATA); +//---- name for DataWindow and indicator subwindow label + IndicatorSetString(INDICATOR_SHORTNAME,"Momentum"+"("+string(ExtMomentumPeriod)+")"); +//--- sets first bar from what index will be drawn + PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtMomentumPeriod-1); +//--- sets drawing line empty value + PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); +//--- digits + IndicatorSetInteger(INDICATOR_DIGITS,2); + } +//+------------------------------------------------------------------+ +//| Momentum | +//+------------------------------------------------------------------+ +/* +int OnCalculate(const int rates_total, + const int prev_calculated, + const int begin, + const double &price[]) + { +*/ +int OnCalculate(const int rates_total,const int prev_calculated, + const datetime &Time[], + const double &Open[], + const double &High[], + const double &Low[], + const double &Close[], + const long &TickVolume[], + const long &Volume[], + const int &Spread[]) + { + + static int begin = 0; + + // + // Process data through MedianRenko indicator + // + + if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time)) + return(0); + + // + // Make the following modifications in the code below: + // + // rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated + // + // rangeBarsIndicator.Open[] should be used instead of open[] + // rangeBarsIndicator.Low[] should be used instead of low[] + // rangeBarsIndicator.High[] should be used instead of high[] + // rangeBarsIndicator.Close[] should be used instead of close[] + // + // rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed + // + // rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time. + // (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used + // + // rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[] + // rangeBarsIndicator.Real_volume[] should be used instead of Volume[] + // (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used + // + // rangeBarsIndicator.Price[] should be used instead of Price[] + // (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used + // + + int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); + + // + // + // + +//--- start calculation + int StartCalcPosition=(ExtMomentumPeriod-1)+begin; +//---- insufficient data + if(rates_total0) PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,StartCalcPosition+(ExtMomentumPeriod-1)); +//--- start working, detect position + int pos=_prev_calculated-1; + if(pos 0) + ExtMomentumBuffer[i]=rangeBarsIndicator.Price[i]*100/rangeBarsIndicator.Price[i-ExtMomentumPeriod]; + + } +//--- OnCalculate done. Return new prev_calculated. + return(rates_total); + } +//+------------------------------------------------------------------+ diff --git a/Indicators/RangeBars/RangeBars_ParabolicSAR.mq5 b/Indicators/RangeBars/RangeBars_ParabolicSAR.mq5 new file mode 100644 index 0000000..53d0e94 --- /dev/null +++ b/Indicators/RangeBars/RangeBars_ParabolicSAR.mq5 @@ -0,0 +1,248 @@ +//+------------------------------------------------------------------+ +//| ParabolicSAR.mq5 | +//| Copyright 2009-2017, MetaQuotes Software Corp. | +//| http://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "2009-2017, MetaQuotes Software Corp." +#property link "http://www.mql5.com" +//--- indicator settings +#property indicator_chart_window +#property indicator_buffers 3 +#property indicator_plots 1 +#property indicator_type1 DRAW_ARROW +#property indicator_color1 DodgerBlue +//--- External parametrs +input double InpSARStep=0.02; // Step +input double InpSARMaximum=0.2; // Maximum +//---- buffers +double ExtSARBuffer[]; +double ExtEPBuffer[]; +double ExtAFBuffer[]; +//--- global variables +int ExtLastRevPos; +bool ExtDirectionLong; +double ExtSarStep; +double ExtSarMaximum; + +// +// +// + +#include +RangeBarIndicator rangeBarsIndicator; + +// +// +// + +//+------------------------------------------------------------------+ +//| Custom indicator initialization function | +//+------------------------------------------------------------------+ +void OnInit() + { +//--- checking input data + if(InpSARStep<0.0) + { + ExtSarStep=0.02; + Print("Input parametr InpSARStep has incorrect value. Indicator will use value", + ExtSarStep,"for calculations."); + } + else ExtSarStep=InpSARStep; + if(InpSARMaximum<0.0) + { + ExtSarMaximum=0.2; + Print("Input parametr InpSARMaximum has incorrect value. Indicator will use value", + ExtSarMaximum,"for calculations."); + } + else ExtSarMaximum=InpSARMaximum; +//---- indicator buffers + SetIndexBuffer(0,ExtSARBuffer); + SetIndexBuffer(1,ExtEPBuffer,INDICATOR_CALCULATIONS); + SetIndexBuffer(2,ExtAFBuffer,INDICATOR_CALCULATIONS); +//--- set arrow symbol + PlotIndexSetInteger(0,PLOT_ARROW,159); +//--- set indicator digits + IndicatorSetInteger(INDICATOR_DIGITS,_Digits); +//--- set label name + PlotIndexSetString(0,PLOT_LABEL,"SAR("+ + DoubleToString(ExtSarStep,2)+","+ + DoubleToString(ExtSarMaximum,2)+")"); +//--- set global variables + ExtLastRevPos=0; + ExtDirectionLong=false; +//---- + } +//+------------------------------------------------------------------+ +//| Custom indicator iteration function | +//+------------------------------------------------------------------+ +int OnCalculate(const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[]) + { +//--- check for minimum rates count + if(rates_total<3) + return(0); + + // + // Process data through MedianRenko indicator + // + + if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time)) + return(0); + + // + // Make the following modifications in the code below: + // + // rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated + // + // rangeBarsIndicator.Open[] should be used instead of open[] + // rangeBarsIndicator.Low[] should be used instead of low[] + // rangeBarsIndicator.High[] should be used instead of high[] + // rangeBarsIndicator.Close[] should be used instead of close[] + // + // rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed + // + // rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time. + // (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used + // + // rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[] + // rangeBarsIndicator.Real_volume[] should be used instead of Volume[] + // (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used + // + // rangeBarsIndicator.Price[] should be used instead of Price[] + // (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used + // + + int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); + + // + // + // + +//--- detect current position + int pos=_prev_calculated-1; +//--- correct position + if(pos<1) + { + //--- first pass, set as SHORT + pos=1; + ExtAFBuffer[0]=ExtSarStep; + ExtAFBuffer[1]=ExtSarStep; + ExtSARBuffer[0]=rangeBarsIndicator.High[0]; + ExtLastRevPos=0; + ExtDirectionLong=false; + ExtSARBuffer[1]=GetHigh(pos,ExtLastRevPos,rangeBarsIndicator.High); + ExtEPBuffer[0]=rangeBarsIndicator.Low[pos]; + ExtEPBuffer[1]=rangeBarsIndicator.Low[pos]; + } +//---main cycle + for(int i=pos;irangeBarsIndicator.Low[i]) + { + //--- switch to SHORT + ExtDirectionLong=false; + ExtSARBuffer[i]=GetHigh(i,ExtLastRevPos,rangeBarsIndicator.High); + ExtEPBuffer[i]=rangeBarsIndicator.Low[i]; + ExtLastRevPos=i; + ExtAFBuffer[i]=ExtSarStep; + } + } + else + { + if(ExtSARBuffer[i]ExtEPBuffer[i-1] && i!=ExtLastRevPos) + { + ExtEPBuffer[i]=rangeBarsIndicator.High[i]; + ExtAFBuffer[i]=ExtAFBuffer[i-1]+ExtSarStep; + if(ExtAFBuffer[i]>ExtSarMaximum) + ExtAFBuffer[i]=ExtSarMaximum; + } + else + { + //--- when we haven't reversed + if(i!=ExtLastRevPos) + { + ExtAFBuffer[i]=ExtAFBuffer[i-1]; + ExtEPBuffer[i]=ExtEPBuffer[i-1]; + } + } + //--- calculate SAR for tomorrow + ExtSARBuffer[i+1]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]); + //--- check for SAR + if(ExtSARBuffer[i+1]>rangeBarsIndicator.Low[i] || ExtSARBuffer[i+1]>rangeBarsIndicator.Low[i-1]) + ExtSARBuffer[i+1]=MathMin(rangeBarsIndicator.Low[i],rangeBarsIndicator.Low[i-1]); + } + else + { + //--- check for new Low + if(rangeBarsIndicator.Low[i]ExtSarMaximum) + ExtAFBuffer[i]=ExtSarMaximum; + } + else + { + //--- when we haven't reversed + if(i!=ExtLastRevPos) + { + ExtAFBuffer[i]=ExtAFBuffer[i-1]; + ExtEPBuffer[i]=ExtEPBuffer[i-1]; + } + } + //--- calculate SAR for tomorrow + ExtSARBuffer[i+1]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]); + //--- check for SAR + if(ExtSARBuffer[i+1]LoData[i]) result=LoData[i]; + return(result); + } +//+------------------------------------------------------------------+ diff --git a/Indicators/RangeBars/RangeBars_ROC.mq5 b/Indicators/RangeBars/RangeBars_ROC.mq5 new file mode 100644 index 0000000..a328bcc --- /dev/null +++ b/Indicators/RangeBars/RangeBars_ROC.mq5 @@ -0,0 +1,136 @@ +//+------------------------------------------------------------------+ +//| ROC.mq5 | +//| Copyright 2009-2017, MetaQuotes Software Corp. | +//| http://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "2009-2017, MetaQuotes Software Corp." +#property link "http://www.mql5.com" +#property description "Rate of Change" +//--- indicator settings +#property indicator_separate_window +#property indicator_buffers 1 +#property indicator_plots 1 +#property indicator_type1 DRAW_LINE +#property indicator_color1 LightSeaGreen +//--- input parameters +input int InpRocPeriod=12; // Period +//--- indicator buffers +double ExtRocBuffer[]; +//--- global variable +int ExtRocPeriod; + +// +// +// + +#include +RangeBarIndicator rangeBarsIndicator; + +// +// +// + +//+------------------------------------------------------------------+ +//| Rate of Change initialization function | +//+------------------------------------------------------------------+ +void OnInit() + { +//--- check for input + if(InpRocPeriod<1) + { + ExtRocPeriod=12; + Print("Incorrect value for input variable InpRocPeriod =",InpRocPeriod, + "Indicator will use value =",ExtRocPeriod,"for calculations."); + } + else ExtRocPeriod=InpRocPeriod; +//--- indicator buffers mapping + SetIndexBuffer(0,ExtRocBuffer,INDICATOR_DATA); +//--- set accuracy + IndicatorSetInteger(INDICATOR_DIGITS,2); +//--- name for DataWindow and indicator subwindow label + IndicatorSetString(INDICATOR_SHORTNAME,"ROC("+string(ExtRocPeriod)+")"); +//--- sets first bar from what index will be drawn + PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtRocPeriod); +//--- initialization done + + // + // Indicator uses Price[] array for calculations so we need to set this in the MedianRenkoIndicator class + // + + rangeBarsIndicator.SetUseAppliedPriceFlag(PRICE_CLOSE); + + // + // + // + + } +//+------------------------------------------------------------------+ +//| Rate of Change | +//+------------------------------------------------------------------+ +//int OnCalculate(const int rates_total,const int prev_calculated,const int begin,const double &price[]) +int OnCalculate(const int rates_total,const int prev_calculated, + const datetime &Time[], + const double &Open[], + const double &High[], + const double &Low[], + const double &Close[], + const long &TickVolume[], + const long &Volume[], + const int &Spread[]) + + { + // + // Process data through MedianRenko indicator + // + + if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time)) + return(0); + + // + // Make the following modifications in the code below: + // + // rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated + // + // rangeBarsIndicator.Open[] should be used instead of open[] + // rangeBarsIndicator.Low[] should be used instead of low[] + // rangeBarsIndicator.High[] should be used instead of high[] + // rangeBarsIndicator.Close[] should be used instead of close[] + // + // rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed + // + // rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time. + // (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used + // + // rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[] + // rangeBarsIndicator.Real_volume[] should be used instead of Volume[] + // (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used + // + // rangeBarsIndicator.Price[] should be used instead of Price[] + // (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used + // + + int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); + + // + // + // + +//--- check for rates count + if(rates_total +#include RangeBarIndicator rangeBarsIndicator; - // // // @@ -79,26 +77,36 @@ int OnCalculate(const int rates_total,const int prev_calculated, const long &Volume[], const int &Spread[]) { - // - // Precoess data through MedianRenko indicator + // Process data through MedianRenko indicator // if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time)) - return(rates_total); - + return(0); + // // Make the following modifications in the code below: // - // medianRenkoIndicator.GetPrevCalculated() should be used instead of prev_calculated - // medianRenkoIndicator.Open[] should be used instead of open[] - // medianRenkoIndicator.Low[] should be used instead of low[] - // medianRenkoIndicator.High[] should be used instead of high[] - // medianRenkoIndicator.Close[] should be used instead of close[] - // if applied_price is used - // medianRenkoIndicator.Price[] should be used instead of price[] + // rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated // - + // rangeBarsIndicator.Open[] should be used instead of open[] + // rangeBarsIndicator.Low[] should be used instead of low[] + // rangeBarsIndicator.High[] should be used instead of high[] + // rangeBarsIndicator.Close[] should be used instead of close[] + // + // rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed + // + // rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time. + // (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used + // + // rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[] + // rangeBarsIndicator.Real_volume[] should be used instead of Volume[] + // (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used + // + // rangeBarsIndicator.Price[] should be used instead of Price[] + // (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used + // + int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); // diff --git a/Indicators/RangeBars_Stochastic.mq5 b/Indicators/RangeBars/RangeBars_Stochastic.mq5 similarity index 88% rename from Indicators/RangeBars_Stochastic.mq5 rename to Indicators/RangeBars/RangeBars_Stochastic.mq5 index 632eb34..4057eff 100644 --- a/Indicators/RangeBars_Stochastic.mq5 +++ b/Indicators/RangeBars/RangeBars_Stochastic.mq5 @@ -26,14 +26,12 @@ double ExtHighesBuffer[]; double ExtLowesBuffer[]; // -// Initialize MedianRenko indicator for data processing -// according to settings of the MedianRenko indicator already on chart +// // -#include +#include RangeBarIndicator rangeBarsIndicator; - // // // @@ -79,23 +77,14 @@ int OnCalculate(const int rates_total,const int prev_calculated, const long &Volume[], const int &Spread[]) { - + // - // Precoess data through MedianRenko indicator // - + // + if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time)) - return(rates_total); + return(0); - // - // Make the following modifications in the code below: - // - // medianRenkoIndicator.GetPrevCalculated() should be used instead of prev_calculated - // medianRenkoIndicator.Open[] should be used instead of open[] - // medianRenkoIndicator.Low[] should be used instead of low[] - // medianRenkoIndicator.High[] should be used instead of high[] - // medianRenkoIndicator.Close[] should be used instead of close[] - // int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); diff --git a/Indicators/RangeBars/RangeBars_VEMA_Wilders_DMI.mq5 b/Indicators/RangeBars/RangeBars_VEMA_Wilders_DMI.mq5 new file mode 100644 index 0000000..4ad2ff8 --- /dev/null +++ b/Indicators/RangeBars/RangeBars_VEMA_Wilders_DMI.mq5 @@ -0,0 +1,246 @@ +//------------------------------------------------------------------ + #property copyright "mladen" + #property link "www.forex-tsd.com" +//------------------------------------------------------------------ + +#property indicator_separate_window +#property indicator_buffers 5 +#property indicator_plots 4 + +#property indicator_label1 "ADX trend" +#property indicator_type1 DRAW_FILLING +#property indicator_color1 C'200,255,180',clrMistyRose +#property indicator_label2 "ADX" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrLimeGreen +#property indicator_style2 STYLE_SOLID +#property indicator_width2 2 +#property indicator_label3 "ADXR" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrGold +#property indicator_style3 STYLE_SOLID +#property indicator_width3 2 +#property indicator_label4 "Level" +#property indicator_type4 DRAW_LINE +#property indicator_color4 clrSilver +#property indicator_style4 STYLE_DOT + +// +// +// +// +// + +enum enVolume +{ + vol_noVolume, // do not use volume + vol_ticks, // use ticks + vol_real // use real volume +}; + +// +// +// +// +// + +input int AdxPeriod = 14; // ADX (DMI) period +input double AdxLevel = 20; // ADX level +input bool ShowADX = true; // ADX visible +input bool ShowADXR = false; // ADXR visible +input enVolume VolumeType = vol_ticks; // Volume to use + +// +// +// +// +// + +double DIp[]; +double DIm[]; +double ADX[]; +double ADXR[]; +double Level[]; + +// +// +// + +#include +RangeBarIndicator rangeBarsIndicator; + +// +// +// + +//------------------------------------------------------------------ +// +//------------------------------------------------------------------ +// +// +// +// +// + +int OnInit() +{ + SetIndexBuffer(0,DIp,INDICATOR_DATA); + SetIndexBuffer(1,DIm,INDICATOR_DATA); + SetIndexBuffer(2,ADX,INDICATOR_DATA); + SetIndexBuffer(3,ADXR,INDICATOR_DATA); + SetIndexBuffer(4,Level,INDICATOR_DATA); + + // + // + // + // + // + + IndicatorSetString(INDICATOR_SHORTNAME," VEMA Wilder's DMI ("+string(AdxPeriod)+")"); + + rangeBarsIndicator.SetGetVolumesFlag(); + + return(0); +} + +//------------------------------------------------------------------ +// +//------------------------------------------------------------------ +// +// +// +// +// + + +double averages[][9]; +#define _Vol 0 +#define _DIp 1 +#define _DIm 2 +#define _TR 3 +#define _Adx 4 +#define _DIpa 5 +#define _DIma 6 +#define _TRa 7 +#define _Adxa 8 + +int OnCalculate(const int rates_total, + const int prev_calculated, + const datetime& time[], + const double& open[], + const double& high[], + const double& low[], + const double& close[], + const long& tick_volume[], + const long& volume[], + const int& spread[]) +{ + // + // Process data through MedianRenko indicator + // + + if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time)) + return(0); + + // + // Make the following modifications in the code below: + // + // rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated + // + // rangeBarsIndicator.Open[] should be used instead of open[] + // rangeBarsIndicator.Low[] should be used instead of low[] + // rangeBarsIndicator.High[] should be used instead of high[] + // rangeBarsIndicator.Close[] should be used instead of close[] + // + // rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed + // + // rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time. + // (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used + // + // rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[] + // rangeBarsIndicator.Real_volume[] should be used instead of Volume[] + // (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used + // + // rangeBarsIndicator.Price[] should be used instead of Price[] + // (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used + // + + int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); + + // + // + // + + if (ArrayRange(averages,0)!=rates_total) ArrayResize(averages,rates_total); + + // + // + // + // + // + + double sf = 1.0/(double)AdxPeriod; + for (int i=(int)MathMax(_prev_calculated-1,1); i DeltaLo) && (DeltaHi > 0)) plusDM = DeltaHi; + if ((DeltaLo > DeltaHi) && (DeltaLo > 0)) minusDM = DeltaLo; + + // + // + // + // + // + + + averages[i][_Vol] = averages[i-1][_Vol] + sf*(vol - averages[i-1][_Vol]); + averages[i][_DIp] = averages[i-1][_DIp] + sf*(vol*plusDM - averages[i-1][_DIp]); + averages[i][_DIm] = averages[i-1][_DIm] + sf*(vol*minusDM - averages[i-1][_DIm]); + averages[i][_TR] = averages[i-1][_TR] + sf*(vol*currTR - averages[i-1][_TR]); + averages[i][_DIpa] = averages[i][_DIp]/MathMax(averages[i][_Vol],1); + averages[i][_DIma] = averages[i][_DIm]/MathMax(averages[i][_Vol],1); + averages[i][_TRa] = averages[i][_TR] /MathMax(averages[i][_Vol],1); + Level[i] = AdxLevel; + + // + // + // + // + // + + DIp[i] = 0.00; + DIm[i] = 0.00; + ADX[i] = EMPTY_VALUE; + ADXR[i] = EMPTY_VALUE; + if (averages[i][_TRa] > 0) + { + DIp[i] = 100.00 * averages[i][_DIpa]/averages[i][_TRa]; + DIm[i] = 100.00 * averages[i][_DIma]/averages[i][_TRa]; + } + + if(ShowADX) + { + double DX; + if((DIp[i] + DIm[i])>0) + DX = 100*MathAbs(DIp[i] - DIm[i])/(DIp[i] + DIm[i]); + else DX = 0.00; + averages[i][_Adx] = averages[i-1][_Adx]+ sf*(vol*DX - averages[i-1][_Adx]); + averages[i][_Adxa] = averages[i][_Adx]/MathMax(averages[i][_Vol],1); + ADX[i] = averages[i][_Adxa]; + if(ShowADXR && i>=AdxPeriod) + ADXR[i] = 0.5*(ADX[i] + ADX[i-AdxPeriod]); + } + } + return(rates_total); +} diff --git a/Indicators/RangeBars/RangeBars_VWAP_lite.mq5 b/Indicators/RangeBars/RangeBars_VWAP_lite.mq5 new file mode 100644 index 0000000..156b7a1 --- /dev/null +++ b/Indicators/RangeBars/RangeBars_VWAP_lite.mq5 @@ -0,0 +1,388 @@ +//+------------------------------------------------------------------+ +//| VWAP_Lite.mq5 | +//| Copyright 2016, SOL Digital Consultoria LTDA | +//| http://www.soldigitalconsultoria.com.br | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2016, SOL Digital Consultoria LTDA" +#property link "http://www.soldigitalconsultoria.com.br" +#property version "1.49" + +#property indicator_chart_window +#property indicator_buffers 3 +#property indicator_plots 3 + +#property indicator_label1 "VWAP Daily" +#property indicator_type1 DRAW_LINE +#property indicator_color1 clrRed +#property indicator_style1 STYLE_DASH +#property indicator_width1 2 + +#property indicator_label2 "VWAP Weekly" +#property indicator_type2 DRAW_LINE +#property indicator_color2 clrBlue +#property indicator_style2 STYLE_DASH +#property indicator_width2 2 + +#property indicator_label3 "VWAP Monthly" +#property indicator_type3 DRAW_LINE +#property indicator_color3 clrGreen +#property indicator_style3 STYLE_DASH +#property indicator_width3 2 +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +enum DATE_TYPE + { + DAILY, + WEEKLY, + MONTHLY + }; +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +enum PRICE_TYPE + { + OPEN, + CLOSE, + HIGH, + LOW, + OPEN_CLOSE, + HIGH_LOW, + CLOSE_HIGH_LOW, + OPEN_CLOSE_HIGH_LOW + }; +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ + + +// +// +// + +#include +RangeBarIndicator rangeBarsIndicator; + +#define VWAP_Daily "cc__VWAP_Daily" +#define VWAP_Weekly "cc__VWAP_Weekly" +#define VWAP_Monthly "cc__VWAP_Monthly" + +// +// +// + +datetime CreateDateTime(DATE_TYPE nReturnType=DAILY,datetime dtDay=D'2000.01.01 00:00:00',int pHour=0,int pMinute=0,int pSecond=0) + { + datetime dtReturnDate; + MqlDateTime timeStruct; + + TimeToStruct(dtDay,timeStruct); + timeStruct.hour = pHour; + timeStruct.min = pMinute; + timeStruct.sec = pSecond; + dtReturnDate=(StructToTime(timeStruct)); + + if(nReturnType==WEEKLY) + { + while(timeStruct.day_of_week!=0) + { + dtReturnDate=(dtReturnDate-86400); + TimeToStruct(dtReturnDate,timeStruct); + } + } + + if(nReturnType==MONTHLY) + { + timeStruct.day=1; + dtReturnDate=(StructToTime(timeStruct)); + } + + return dtReturnDate; + } + +sinput string Indicator_Name = "Volume Weighted Average Price (VWAP)"; +input PRICE_TYPE Price_Type = CLOSE_HIGH_LOW; +input bool Calc_Every_Tick = false; +input bool Enable_Daily = true; +input bool Show_Daily_Value = true; +input bool Enable_Weekly = false; +input bool Show_Weekly_Value = false; +input bool Enable_Monthly = false; +input bool Show_Monthly_Value = false; + +double VWAP_Buffer_Daily[],VWAP_Buffer_Weekly[],VWAP_Buffer_Monthly[]; +double nPriceArr[],nTotalTPV[],nTotalVol[]; +double nSumDailyTPV = 0, nSumWeeklyTPV = 0, nSumMonthlyTPV = 0; +double nSumDailyVol = 0, nSumWeeklyVol = 0, nSumMonthlyVol = 0; +int nIdxDaily=0,nIdxWeekly=0,nIdxMonthly=0,nIdx=0; +bool bIsFirstRun=true; +string sDailyStr = "", sWeeklyStr = "", sMonthlyStr = ""; +datetime dtLastDay = CreateDateTime(DAILY), dtLastWeek = CreateDateTime(WEEKLY), dtLastMonth = CreateDateTime(MONTHLY); +ENUM_TIMEFRAMES LastTimePeriod=PERIOD_MN1; +int nStringYDistance=50; +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int OnInit() + { + IndicatorSetInteger(INDICATOR_DIGITS,_Digits); + + SetIndexBuffer(0,VWAP_Buffer_Daily,INDICATOR_DATA); + SetIndexBuffer(1,VWAP_Buffer_Weekly,INDICATOR_DATA); + SetIndexBuffer(2,VWAP_Buffer_Monthly,INDICATOR_DATA); + + if(Show_Daily_Value) + { + ObjectCreate(0,VWAP_Daily,OBJ_LABEL,0,0,0); + ObjectSetInteger(0,VWAP_Daily,OBJPROP_CORNER,CORNER_LEFT_LOWER); + ObjectSetInteger(0,VWAP_Daily,OBJPROP_XDISTANCE,10);//180); + ObjectSetInteger(0,VWAP_Daily,OBJPROP_YDISTANCE,nStringYDistance); + ObjectSetInteger(0,VWAP_Daily,OBJPROP_COLOR,indicator_color1); + ObjectSetInteger(0,VWAP_Daily,OBJPROP_FONTSIZE,7); + ObjectSetString(0,VWAP_Daily,OBJPROP_FONT,"Verdana"); + ObjectSetString(0,VWAP_Daily,OBJPROP_TEXT," "); + nStringYDistance=nStringYDistance+20; + } + + if(Show_Weekly_Value) + { + ObjectCreate(0,VWAP_Weekly,OBJ_LABEL,0,0,0); + ObjectSetInteger(0,VWAP_Weekly,OBJPROP_CORNER,CORNER_LEFT_LOWER); + ObjectSetInteger(0,VWAP_Weekly,OBJPROP_XDISTANCE,10);//180); + ObjectSetInteger(0,VWAP_Weekly,OBJPROP_YDISTANCE,nStringYDistance); + ObjectSetInteger(0,VWAP_Weekly,OBJPROP_COLOR,indicator_color2); + ObjectSetInteger(0,VWAP_Weekly,OBJPROP_FONTSIZE,7); + ObjectSetString(0,VWAP_Weekly,OBJPROP_FONT,"Verdana"); + ObjectSetString(0,VWAP_Weekly,OBJPROP_TEXT," "); + nStringYDistance=nStringYDistance+20; + } + + if(Show_Monthly_Value) + { + ObjectCreate(0,VWAP_Monthly,OBJ_LABEL,0,0,0); + ObjectSetInteger(0,VWAP_Monthly,OBJPROP_CORNER,CORNER_LEFT_LOWER); + ObjectSetInteger(0,VWAP_Monthly,OBJPROP_XDISTANCE,10);//180); + ObjectSetInteger(0,VWAP_Monthly,OBJPROP_YDISTANCE,nStringYDistance); + ObjectSetInteger(0,VWAP_Monthly,OBJPROP_COLOR,indicator_color3); + ObjectSetInteger(0,VWAP_Monthly,OBJPROP_FONTSIZE,7); + ObjectSetString(0,VWAP_Monthly,OBJPROP_FONT,"Verdana"); + ObjectSetString(0,VWAP_Monthly,OBJPROP_TEXT," "); + } + + rangeBarsIndicator.SetGetVolumesFlag(); + rangeBarsIndicator.SetGetTimeFlag(); + + return(INIT_SUCCEEDED); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void OnDeinit(const int pReason) + { + if(Show_Daily_Value) ObjectDelete(0,VWAP_Daily); + if(Show_Weekly_Value) ObjectDelete(0,VWAP_Weekly); + if(Show_Monthly_Value) ObjectDelete(0,VWAP_Monthly); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int OnCalculate(const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[]) + { + + // + // Process data through MedianRenko indicator + // + + if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time)) + return(0); + + // + // Make the following modifications in the code below: + // + // rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated + // + // rangeBarsIndicator.Open[] should be used instead of open[] + // rangeBarsIndicator.Low[] should be used instead of low[] + // rangeBarsIndicator.High[] should be used instead of high[] + // rangeBarsIndicator.Close[] should be used instead of close[] + // + // rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed + // + // rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time. + // (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used + // + // rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[] + // rangeBarsIndicator.Real_volume[] should be used instead of Volume[] + // (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used + // + // rangeBarsIndicator.Price[] should be used instead of Price[] + // (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used + // + + int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); + + // + // + // + + if(PERIOD_CURRENT!=LastTimePeriod) + { + bIsFirstRun=true; + LastTimePeriod=PERIOD_CURRENT; + } + + if(rates_total>_prev_calculated || bIsFirstRun || Calc_Every_Tick || (_prev_calculated == 0) || rangeBarsIndicator.IsNewBar) + { + nIdxDaily = 0; + nIdxWeekly = 0; + nIdxMonthly = 0; + + ArrayResize(nPriceArr,rates_total); + ArrayResize(nTotalTPV,rates_total); + ArrayResize(nTotalVol,rates_total); + + if(Enable_Daily) {nIdx = nIdxDaily; nSumDailyTPV = 0; nSumDailyVol = 0;} + if(Enable_Weekly) {nIdx = nIdxWeekly; nSumWeeklyTPV = 0; nSumWeeklyVol = 0;} + if(Enable_Monthly) {nIdx = nIdxMonthly; nSumMonthlyTPV = 0; nSumMonthlyVol = 0;} + + for(; nIdx 0) && (rangeBarsIndicator.Real_volume[nIdx] == 0)) + { + // Print("tick vol = "+rangeBarsIndicator.Tick_volume[nIdx]); + nTotalTPV[nIdx] = (nPriceArr[nIdx] * rangeBarsIndicator.Tick_volume[nIdx]); + nTotalVol[nIdx] = (double)rangeBarsIndicator.Tick_volume[nIdx]; + } + else if(rangeBarsIndicator.Real_volume[nIdx] && rangeBarsIndicator.Tick_volume[nIdx] ) + { + // Print("real vol = "+rangeBarsIndicator.Real_volume[nIdx]); + nTotalTPV[nIdx] = (nPriceArr[nIdx] * rangeBarsIndicator.Real_volume[nIdx]); + nTotalVol[nIdx] = (double)rangeBarsIndicator.Real_volume[nIdx]; + } + + if(Enable_Daily && (nIdx>=nIdxDaily)) + { + nSumDailyTPV += nTotalTPV[nIdx]; + nSumDailyVol += nTotalVol[nIdx]; + + if(nSumDailyVol) + VWAP_Buffer_Daily[nIdx]=(nSumDailyTPV/nSumDailyVol); + + if((sDailyStr!="VWAP Daily: "+(string)NormalizeDouble(VWAP_Buffer_Daily[nIdx],_Digits)) && Show_Daily_Value) + { + sDailyStr="VWAP Daily: "+(string)NormalizeDouble(VWAP_Buffer_Daily[nIdx],_Digits); + ObjectSetString(0,VWAP_Daily,OBJPROP_TEXT,sDailyStr); + } + } + + if(Enable_Weekly && (nIdx>=nIdxWeekly)) + { + nSumWeeklyTPV += nTotalTPV[nIdx]; + nSumWeeklyVol += nTotalVol[nIdx]; + + if(nSumWeeklyVol) + VWAP_Buffer_Weekly[nIdx]=(nSumWeeklyTPV/nSumWeeklyVol); + + if((sWeeklyStr!="VWAP Weekly: "+(string)NormalizeDouble(VWAP_Buffer_Weekly[nIdx],_Digits)) && Show_Weekly_Value) + { + sWeeklyStr="VWAP Weekly: "+(string)NormalizeDouble(VWAP_Buffer_Weekly[nIdx],_Digits); + ObjectSetString(0,VWAP_Weekly,OBJPROP_TEXT,sWeeklyStr); + } + } + + if(Enable_Monthly && (nIdx>=nIdxMonthly)) + { + nSumMonthlyTPV += nTotalTPV[nIdx]; + nSumMonthlyVol += nTotalVol[nIdx]; + + if(nSumMonthlyVol) + VWAP_Buffer_Monthly[nIdx]=(nSumMonthlyTPV/nSumMonthlyVol); + + if((sMonthlyStr!="VWAP Monthly: "+(string)NormalizeDouble(VWAP_Buffer_Monthly[nIdx],_Digits)) && Show_Monthly_Value) + { + sMonthlyStr="VWAP Monthly: "+(string)NormalizeDouble(VWAP_Buffer_Monthly[nIdx],_Digits); + ObjectSetString(0,VWAP_Monthly,OBJPROP_TEXT,sMonthlyStr); + } + } + + dtLastDay=CreateDateTime(DAILY,rangeBarsIndicator.Time[nIdx]); + dtLastWeek=CreateDateTime(WEEKLY,rangeBarsIndicator.Time[nIdx]); + dtLastMonth=CreateDateTime(MONTHLY,rangeBarsIndicator.Time[nIdx]); + } + + bIsFirstRun=false; + } + + return(rates_total); + } +//+------------------------------------------------------------------+ diff --git a/Indicators/RangeBars/RangeBars_WPR.mq5 b/Indicators/RangeBars/RangeBars_WPR.mq5 new file mode 100644 index 0000000000000000000000000000000000000000..fe9280821de3d2c4d6ff0f8ccbc5475d29c3bfec GIT binary patch literal 12104 zcmds7ZEqVz5T4IS`~bdPT#?2kacBVnZBi+3(1t)SP1a;tR_EYamQUpqaI+@wB>E4o7jh&|r6L{q zO}@eY?{f3AEtk@h8|h0+&gDXepmJZn#PvP&%e#B>t*qeb6KUdYO@5XutQlf7z|&*g zpJ8;3H+?*dgcSRrS;2jNeu`<4d=Ihb17nM8aC1G>`DWF>zFmf9(}AB zU@pCc@6It|TkFk6#C-MtyvkQrLJb8Vx8enD!~eFI!xfWv#aXmnu1 z-?6#_3?m-sm0w#OWBoXtRd7S(%&YrTaC3%>(N9d(E1zUNqu-&oo>cPDpxuckKLLMJ*miMXdz!w@Odi$~k&abd5sV1Yihj)y38+{$jWCT)ET)`-` zb9m3Wd*+$uM#T-{OhYyx+1K(AGq{h%6n&T6J+unnH$de|PQfo@L$6)<(-7KW9^Ufo z_)=bBr;us{i5Uf_@WM9MzcGkHlvA2cB1++3x{EK1?x;K1UDAH}?2ge=-RPMJ9LYK? z`YZ5~_IwVDGS1iVcSnB0ufx_Y!y)wE{hJLcETU zKf1>1)WMRJjqgydw~08Z1KXR>1#6HqtY`kFMs1`savW-?Zd#bRlo|W$@|CxvuF!pb z&1S`!MGi)jKmQ1vkuSVKM+Yxwc!&6BwYyC#19yLZoobJLJ#ARoz9pl+G;G)I>tE33e7!z65 z8Ijemsv>YnWF)sv?@2u!W5y8JH5}RE+<3tOuxt-8xd~)D1fo?jPo?PRX8JSfE@=!@qwN6ArU=48#>his&Hgq+T*j@6yb@>`JlN31@$-7)E3taR+I zPV&eg-Z^aU>JTSimgV@|=ZibXZO1WrI)N2eZ~{v1y?W~->gnWao=}kdFiS8Z{Iktx zk*!10&NeQ7XLmQBS)ygUKy$=4;=T?1yux2SZ!KZOlOpr0;s<|OQ_yn;@L%R#b|>2K z59f2)T1%tHQ#em&RqPh$pizKsW5gdby5i#^c+`8=hxs`TE6_#A+ylp5nGLlI@Wvj{ zY^V{1u4hDxwd*D9+$>0st9j~=L@mI|q6$m%RLYa!Ea<*JH5&tqkW_uK21KPb;lB{ax~qUse-&nDQS0NS5mhP$X*5~1K6L| zZ-Wn3B9w_ImZlk#TcT?da`QdAx;%A{L&T8Za5OFVhaQ3zt) zPK)jT7`|e0w-^ULau?%aJ3!cCT!bhc@)3@v^^QIGo5WuF*_FH{RH%F zX0iIr6MNx$dkS_ZV~at=b;fcioodUXV@$dTy^?4b*=gE9Ns?4#^LuT^-SPpOKLm6{0r zZ(xAqK0gXLjS@R~f>a5z&wLTS8BB{C)74?xKbu^EI$pJ|w>2%F+jsos+wi;R07%TQ zN%TfqTqU*V0J~Q6;u7qac7|Rb)A@1~lqcq$v?|+i#%SOfgx|K=)nteCHF#qU?WkFs zw4n1zc47Z1-ig#a?)P4M*lB=$hWN+xpT8G-#VvdX$?EWFhl^U;7&|A)1>>NGb*%pD zs6tp3>DMjQ*ERArdqB+*2k92zNtIZ(fan{T?k4M8p7yn#cPB!n`qq<9pZNOMZ0vVb zluQ3xsI5YsmXuD|b7%l1_zl(0-WZKHVN>;{$!9>j)^;?L{lyh%C_JrAD--qZzRPN5 zKUpHK(z%p}qdfBH%Gpb!o!&V2dftxPVF7;1XHJs1ho}Z^&p+8keu=fOKxGwnj8k7V zI5F9>{wadg%JKywmEXkIQmMu{_R&%Kwcje@TF|!|z1gyid(Q~B-)OCF`0K|FwaNdj z(lnL4B54bAY&G7+8-9TyPVnTQu^dMmrQSk6dU@=38GmOVRU>f0Gti{-xc_~~>C2~- zh4+4}&3FG?(Z@x&#S-6wANGDe`{yA_tCkeQ{7!c`YtiIn`s~f9uS$QXH#5($vSZJR zSgcQ(Kl&y&hk4Z@jh}_Wy{w(smmC6RSPj^nv*?D=sWG>7%MCMg)=I4pTKNA7*)x0@ zAA%~YC?|>fkS~voVpa~JH0yyhihEIPPAD +RangeBarIndicator rangeBarsIndicator; + +// +// +// + +//+------------------------------------------------------------------+ +//| Custom indicator initialization function | +//+------------------------------------------------------------------+ +int OnInit() + { +//--- indicator buffers mapping + SetIndexBuffer(0,ZigzagBuffer,INDICATOR_DATA); + SetIndexBuffer(1,HighMapBuffer,INDICATOR_CALCULATIONS); + SetIndexBuffer(2,LowMapBuffer,INDICATOR_CALCULATIONS); + +//--- set short name and digits + PlotIndexSetString(0,PLOT_LABEL,"ZigZag("+(string)ExtDepth+","+(string)ExtDeviation+","+(string)ExtBackstep+")"); + IndicatorSetInteger(INDICATOR_DIGITS,_Digits); +//--- set empty value + PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); +//--- to use in cycle + deviation=ExtDeviation*_Point; +//--- + return(INIT_SUCCEEDED); + } +//+------------------------------------------------------------------+ +//| searching index of the highest bar | +//+------------------------------------------------------------------+ +int iHighest(const double &array[], + int depth, + int startPos) + { + int index=startPos; +//--- start index validation + if(startPos<0) + { + Print("Invalid parameter in the function iHighest, startPos =",startPos); + return 0; + } + int size=ArraySize(array); +//--- depth correction if need + if(startPos-depth<0) depth=startPos; + double max=array[startPos]; +//--- start searching + for(int i=startPos;i>startPos-depth;i--) + { + if(array[i]>max) + { + index=i; + max=array[i]; + } + } +//--- return index of the highest bar + return(index); + } +//+------------------------------------------------------------------+ +//| searching index of the lowest bar | +//+------------------------------------------------------------------+ +int iLowest(const double &array[], + int depth, + int startPos) + { + int index=startPos; +//--- start index validation + if(startPos<0) + { + Print("Invalid parameter in the function iLowest, startPos =",startPos); + return 0; + } + int size=ArraySize(array); +//--- depth correction if need + if(startPos-depth<0) depth=startPos; + double min=array[startPos]; +//--- start searching + for(int i=startPos;i>startPos-depth;i--) + { + if(array[i]0) + { + i=rates_total-1; + //--- searching third extremum from the last uncompleted bar + while(counterZrates_total-100) + { + res=ZigzagBuffer[i]; + if(res!=0) counterZ++; + i--; + } + i++; + limit=i; + + //--- what type of exremum we are going to find + if(LowMapBuffer[i]!=0) + { + curlow=LowMapBuffer[i]; + whatlookfor=Pike; + } + else + { + curhigh=HighMapBuffer[i]; + whatlookfor=Sill; + } + //--- chipping + for(i=limit+1;ideviation) val=0.0; + else + { + for(back=1;back<=ExtBackstep;back++) + { + res=LowMapBuffer[shift-back]; + if((res!=0) && (res>val)) LowMapBuffer[shift-back]=0.0; + } + } + } + if(rangeBarsIndicator.Low[shift]==val) LowMapBuffer[shift]=val; else LowMapBuffer[shift]=0.0; + //--- high + val=rangeBarsIndicator.High[iHighest(rangeBarsIndicator.High,ExtDepth,shift)]; + if(val==lasthigh) val=0.0; + else + { + lasthigh=val; + if((val-rangeBarsIndicator.High[shift])>deviation) val=0.0; + else + { + for(back=1;back<=ExtBackstep;back++) + { + res=HighMapBuffer[shift-back]; + if((res!=0) && (reslasthigh && LowMapBuffer[shift]==0.0) + { + ZigzagBuffer[lasthighpos]=0.0; + lasthighpos=shift; + lasthigh=HighMapBuffer[shift]; + ZigzagBuffer[shift]=lasthigh; + } + if(LowMapBuffer[shift]!=0.0 && HighMapBuffer[shift]==0.0) + { + lastlow=LowMapBuffer[shift]; + lastlowpos=shift; + ZigzagBuffer[shift]=lastlow; + whatlookfor=Pike; + } + break; + default: return(rates_total); + } + } + +//--- return value of _prev_calculated for next call + return(rates_total); + } +//+------------------------------------------------------------------+ diff --git a/Indicators/RangeBars/RangeBars_dt_oscillator.mq5 b/Indicators/RangeBars/RangeBars_dt_oscillator.mq5 new file mode 100644 index 0000000..8737b07 --- /dev/null +++ b/Indicators/RangeBars/RangeBars_dt_oscillator.mq5 @@ -0,0 +1,247 @@ + + +//+------------------------------------------------------------------+ +//| DT oscillator.mq5 | +//+------------------------------------------------------------------+ +#property copyright "www.forex-tsd.com" +#property link "www.forex-tsd.com" +#property version "1.00" + +#property indicator_separate_window +#property indicator_buffers 4 +#property indicator_plots 3 +#property indicator_level1 70 +#property indicator_level2 30 + +// +// +// +// +// + +#property indicator_type1 DRAW_FILLING +#property indicator_color1 PowderBlue,MistyRose +#property indicator_label1 "DT oscillator filling" +#property indicator_type2 DRAW_LINE +#property indicator_color2 DeepSkyBlue +#property indicator_width2 2 +#property indicator_label2 "DT oscillator" +#property indicator_type3 DRAW_LINE +#property indicator_color3 PaleVioletRed +#property indicator_width3 1 +#property indicator_label3 "DT oscillator signal" + +// +// +// +// +// + +input int RsiPeriod = 13; // Rsi period +input int StochPeriod = 8; // Stochastic period +input int SlowingPeriod = 5; // Slowing +input int SignalPeriod = 3; // Signal period +input bool TapeVisible = true; // Tape visibility + +// +// +// +// +// +// + +double dtosc[]; +double dtoss[]; +double dtosf1[]; +double dtosf2[]; + +// +// +// + +#include +RangeBarIndicator rangeBarsIndicator; + +// +// +// + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +// +// +// +// +// + +int OnInit() +{ + SetIndexBuffer( 0,dtosf1,INDICATOR_DATA); + SetIndexBuffer( 1,dtosf2,INDICATOR_DATA); + SetIndexBuffer( 2,dtosc ,INDICATOR_DATA); + SetIndexBuffer( 3,dtoss ,INDICATOR_DATA); + return(0); +} + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +// +// +// +// +// + +double rsibuf[]; +double stobuf[]; + +int OnCalculate(const int rates_total,const int prev_calculated, + const datetime &Time[], + const double &Open[], + const double &High[], + const double &Low[], + const double &Close[], + const long &TickVolume[], + const long &Volume[], + const int &Spread[]) +{ + // + // Process data through MedianRenko indicator + // + + if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,Time)) + return(0); + + // + // Make the following modifications in the code below: + // + // rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated + // + // rangeBarsIndicator.Open[] should be used instead of open[] + // rangeBarsIndicator.Low[] should be used instead of low[] + // rangeBarsIndicator.High[] should be used instead of high[] + // rangeBarsIndicator.Close[] should be used instead of close[] + // + // rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed + // + // rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time. + // (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used + // + // rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[] + // rangeBarsIndicator.Real_volume[] should be used instead of Volume[] + // (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used + // + // rangeBarsIndicator.Price[] should be used instead of Price[] + // (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used + // + + int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); + + // + // + // + // + // + + if (ArraySize(rsibuf)!=rates_total) ArrayResize(rsibuf,rates_total); + if (ArraySize(stobuf)!=rates_total) ArrayResize(stobuf,rates_total); + + // + // + // + // + // + + for (int i=(int)MathMax(_prev_calculated-1,0); i=0; k++) + { + min = MathMin(rsibuf[i-k],min); + max = MathMax(rsibuf[i-k],max); + } + if (max!=min) + stobuf[i] = 100*(rsibuf[i]-min)/(max-min); + else stobuf[i] = 0; + + // + // + // + // + // + + dtosc[i] = 0; for (int k=0; k=0; k++) dtosc[i] += stobuf[i-k]; dtosc[i] /= SlowingPeriod; + dtoss[i] = 0; for (int k=0; k=0; k++) dtoss[i] += dtosc[i-k]; dtoss[i] /= SignalPeriod; + if (TapeVisible) + { dtosf1[i] = dtosc[i]; dtosf2[i] = dtoss[i]; } + else { dtosf1[i] = EMPTY_VALUE; dtosf2[i] = EMPTY_VALUE; } + } + + // + // + // + // + // + + return(rates_total); +} + + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +// +// +// +// +// + +double rsiWork[][3]; +#define _price 0 +#define _chgAvg 1 +#define _totChg 2 + +// +// +// +// +// + +double iRsi(double price, double period, int i, int bars) +{ + if (ArrayRange(rsiWork,0)!=bars) ArrayResize(rsiWork,bars); + + // + // + // + // + // + // + + rsiWork[i][_price] = price; + if (i==0) + { + rsiWork[i][_chgAvg] = 0; + rsiWork[i][_totChg] = 0; + return(50); + } + + // + // + // + // + // + + double sf = 1.0 / period; + double change = rsiWork[i][_price]-rsiWork[i-1][_price]; + + rsiWork[i][_chgAvg] = rsiWork[i-1][_chgAvg] + sf*( change -rsiWork[i-1][_chgAvg]); + rsiWork[i][_totChg] = rsiWork[i-1][_totChg] + sf*(MathAbs(change)-rsiWork[i-1][_totChg]); + + double changeRatio = (rsiWork[i][_totChg]!=0 ? rsiWork[i][_chgAvg]/rsiWork[i][_totChg] : 0 ); + return(50.0*(changeRatio+1.0)); +} diff --git a/Indicators/RangeBars/RangeBars_gmma.mq5 b/Indicators/RangeBars/RangeBars_gmma.mq5 new file mode 100644 index 0000000000000000000000000000000000000000..c423ce328d01416d832fc9741c091eb5fc9098c1 GIT binary patch literal 23606 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 literal 0 HcmV?d00001 diff --git a/Indicators/RangeBars/RangeBars_volumes.mq5 b/Indicators/RangeBars/RangeBars_volumes.mq5 new file mode 100644 index 0000000..4b17645 --- /dev/null +++ b/Indicators/RangeBars/RangeBars_volumes.mq5 @@ -0,0 +1,139 @@ +//+------------------------------------------------------------------+ +//| Volumes.mq5 | +//| Copyright 2009-2017, MetaQuotes Software Corp. | +//| http://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "2009-2017, MetaQuotes Software Corp." +#property link "http://www.mql5.com" +//---- indicator settings +#property indicator_separate_window +#property indicator_buffers 2 +#property indicator_plots 1 +#property indicator_type1 DRAW_COLOR_HISTOGRAM +#property indicator_color1 Green,Red +#property indicator_style1 0 +#property indicator_width1 1 +#property indicator_minimum 0.0 +//--- input data +input ENUM_APPLIED_VOLUME InpVolumeType=VOLUME_TICK; // Volumes +//---- indicator buffers +double ExtVolumesBuffer[]; +double ExtColorsBuffer[]; + +// +// +// + +#include +RangeBarIndicator rangeBarsIndicator; + +// +// +// +//+------------------------------------------------------------------+ +//| Custom indicator initialization function | +//+------------------------------------------------------------------+ +void OnInit() + { +//---- buffers + SetIndexBuffer(0,ExtVolumesBuffer,INDICATOR_DATA); + SetIndexBuffer(1,ExtColorsBuffer,INDICATOR_COLOR_INDEX); +//---- name for DataWindow and indicator subwindow label + IndicatorSetString(INDICATOR_SHORTNAME,"Volumes"); +//---- indicator digits + IndicatorSetInteger(INDICATOR_DIGITS,0); + + rangeBarsIndicator.SetGetVolumesFlag(); +//---- + } +//+------------------------------------------------------------------+ +//| Volumes | +//+------------------------------------------------------------------+ +int OnCalculate(const int rates_total, + const int prev_calculated, + const datetime &time[], + const double &open[], + const double &high[], + const double &low[], + const double &close[], + const long &tick_volume[], + const long &volume[], + const int &spread[]) + { +//---check for rates total + if(rates_total<2) + return(0); + + // + // Process data through MedianRenko indicator + // + + if(!rangeBarsIndicator.OnCalculate(rates_total,prev_calculated,time)) + return(0); + + // + // Make the following modifications in the code below: + // + // rangeBarsIndicator.GetPrevCalculated() should be used instead of prev_calculated + // + // rangeBarsIndicator.Open[] should be used instead of open[] + // rangeBarsIndicator.Low[] should be used instead of low[] + // rangeBarsIndicator.High[] should be used instead of high[] + // rangeBarsIndicator.Close[] should be used instead of close[] + // + // rangeBarsIndicator.IsNewBar (true/false) informs you if a renko brick completed + // + // rangeBarsIndicator.Time[] shold be used instead of Time[] for checking the renko bar time. + // (!) rangeBarsIndicator.SetGetTimeFlag() must be called in OnInit() for rangeBarsIndicator.Time[] to be used + // + // rangeBarsIndicator.Tick_volume[] should be used instead of TickVolume[] + // rangeBarsIndicator.Real_volume[] should be used instead of Volume[] + // (!) rangeBarsIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used + // + // rangeBarsIndicator.Price[] should be used instead of Price[] + // (!) rangeBarsIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for rangeBarsIndicator.Price[] to be used + // + + int _prev_calculated = rangeBarsIndicator.GetPrevCalculated(); + + // + // + // + +//--- starting work + int start=_prev_calculated-1; +//--- correct position + if(start<1) start=1; +//--- main cycle + if(InpVolumeType==VOLUME_TICK) + CalculateVolume(start,rates_total,rangeBarsIndicator.Tick_volume); + else + CalculateVolume(start,rates_total,rangeBarsIndicator.Real_volume); +//--- OnCalculate done. Return new prev_calculated. + return(rates_total); + } +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CalculateVolume(const int nPosition, + const int nRatesCount, + const long &SrcBuffer[]) + { + ExtVolumesBuffer[0]=(double)SrcBuffer[0]; + ExtColorsBuffer[0]=0.0; +//--- + for(int i=nPosition;idPrevVolume) + ExtColorsBuffer[i]=0.0; + else + ExtColorsBuffer[i]=1.0; + } +//--- + } +//+------------------------------------------------------------------+