Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ee4a0d0cec | |||
| 419ea51fca | |||
| 380071b195 | |||
| a73e2c0713 | |||
| 3175f594f1 | |||
| 5327473eaf |
Binary file not shown.
@@ -0,0 +1,478 @@
|
|||||||
|
#property copyright "Copyright 2017-2021, Artur Zas"
|
||||||
|
// GNU General Public License v3.0 -> https://github.com/9nix6/Median-and-Turbo-Renko-indicator-bundle/blob/master/LICENSE
|
||||||
|
#property link "https://www.az-invest.eu"
|
||||||
|
#define VERSION "1.20"
|
||||||
|
#property version VERSION
|
||||||
|
#property description "Example EA: Trading based on 2 moving average crossover."
|
||||||
|
#property description "MA1 && MA2 need to be enabled on the inicator creating the chart."
|
||||||
|
#property description "MA1 - Fast moving average"
|
||||||
|
#property description "MA2 - Slow moving average"
|
||||||
|
#property description " "
|
||||||
|
#property description "GNU General Public License v3.0"
|
||||||
|
|
||||||
|
//#define RANGEBAR_LICENSE // uncomment when used on a Tick & Volume bar chart from https://www.az-invest.eu/rangebars-for-metatrader-5
|
||||||
|
//#define ULTIMATE_RENKO_LICENSE // uncomment when used on Ultimate Renko chart from https://www.az-invest.eu/ultimate-renko-indicator-generator-for-metatrader-5
|
||||||
|
//#define VOLUMECHART_LICENSE // uncomment when used on a Tick & Volume bar chart from https://www.az-invest.eu/Tick-chart-and-volume-chart-for-mt5
|
||||||
|
//#define SECONDSCHART_LICENSE // uncomment when used on a Seconds TF bar chart from https://www.az-invest.eu/seconds-timeframe-chart-for-metatrader-5
|
||||||
|
//#define LINEBREAKCHART_LICENSE // uncomment when used on a Line Break chart from https://www.az-invest.eu/linebreak-chart-for-metatrader-5
|
||||||
|
//
|
||||||
|
// Uncomment only ONE of the 5 directives listed below and recompile
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
//
|
||||||
|
#define EA_ON_RANGE_BARS // Use EA on RangeBar chart
|
||||||
|
//#define EA_ON_RENKO // Use EA on Renko charts
|
||||||
|
//#define EA_ON_XTICK_CHART // Use EA on XTick Chart (obsolete)
|
||||||
|
//#define EA_ON_TICK_VOLUME_CHART // Use EA on Tick & Volume Bar Chart
|
||||||
|
//#define EA_ON_SECONDS_CHART // Use EA on Seconds Interval chart
|
||||||
|
//#define EA_ON_LINEBREAK_CHART // Use EA on LineBreak charts
|
||||||
|
|
||||||
|
//#define DEVELOPER_VERSION // used when I develop ;) should always be commented out
|
||||||
|
|
||||||
|
// Uncomment the directive below and recompile if EA is used with P-Renko BR Ultimate
|
||||||
|
// ----------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//#define P_RENKO_BR_PRO // Use in P-Renko BR Ultimate version
|
||||||
|
|
||||||
|
//
|
||||||
|
// Uncomment the directive below and recompile for use in a backtest only
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// #define SHOW_INDICATOR_INPUTS
|
||||||
|
|
||||||
|
// Include all needed files
|
||||||
|
|
||||||
|
#ifdef EA_ON_RANGE_BARS
|
||||||
|
#include <AZ-INVEST/SDK/RangeBars.mqh>
|
||||||
|
RangeBars *customBars = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_RENKO
|
||||||
|
#include <AZ-INVEST/SDK/MedianRenko.mqh>
|
||||||
|
MedianRenko *customBars = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_XTICK_CHART
|
||||||
|
#include <AZ-INVEST/SDK/TickChart.mqh>
|
||||||
|
TickChart *customBars = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_TICK_VOLUME_CHART
|
||||||
|
#include <AZ-INVEST/SDK/VolumeBarChart.mqh>
|
||||||
|
TickChart *customBars = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_SECONDS_CHART
|
||||||
|
#include <AZ-INVEST/SDK/SecondsChart.mqh>
|
||||||
|
SecondsChart *customBars = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_LINEBREAK_CHART
|
||||||
|
#include <AZ-INVEST/SDK/LineBreakChart.mqh>
|
||||||
|
LineBreakChart *customBars = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <AZ-INVEST/SDK/TimeControl.mqh>
|
||||||
|
#include <AZ-INVEST/SDK/TradeFunctions.mqh>
|
||||||
|
#include <AZ-INVEST/SDK/TradeManager.mqh>
|
||||||
|
|
||||||
|
enum ENUM_TRADE_DIRECTION
|
||||||
|
{
|
||||||
|
TRADE_DIRECTION_BUY = POSITION_TYPE_BUY, // Buy
|
||||||
|
TRADE_DIRECTION_SELL = POSITION_TYPE_SELL, // Sell
|
||||||
|
TRADE_DIRECTION_ALL = 1000, // Buy & Sell
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef SHOW_INDICATOR_INPUTS
|
||||||
|
input group "### EA parameters"
|
||||||
|
#endif
|
||||||
|
input double Lots = 0.1; // Traded lots
|
||||||
|
input uint StopLoss = 100; // Stop Loss (in points)
|
||||||
|
input uint TakeProfit = 300; // Take profit (in points)
|
||||||
|
input ENUM_TRADE_DIRECTION ValidTradeDirection = TRADE_DIRECTION_ALL; // Valid trading type
|
||||||
|
input bool ForceSR = false; // Force Stop & Reverse
|
||||||
|
input bool ReverseOnMACrossInsideGap = true; // Reverse trade if MA cross inside a gap
|
||||||
|
input group "### Trading schedule (Non stop if start = 0 & end = 0)"
|
||||||
|
input string Start="9:00"; // Start trading at
|
||||||
|
input string End="17:55"; // End trading at
|
||||||
|
input bool CloseTradeAfterTradingHours = false; // Close trade after trading hours
|
||||||
|
input group "### Trade management";
|
||||||
|
input int InpBEPoints = 0; // BreakEven (Points) [ 0 = OFF ]
|
||||||
|
input int InpTrailByPoints = 0; // Trail by (Points) [ 0 = OFF ]
|
||||||
|
input int InpTrailStartPoints = 150; // Start trailing after (Points)
|
||||||
|
input int InpPartialCloseAtProfitPoints = 0; // Partial close at (Points) [ 0 = OFF ]
|
||||||
|
input int InpPartialClosePercentage = 50; // Partial close %
|
||||||
|
input group "### Misc";
|
||||||
|
input ulong MagicNumber=5150; // Assign trade ID
|
||||||
|
input ulong DeviationPoints = 0; // Maximum deviation (in points)
|
||||||
|
input double ManualTickSize = 0.000; // Tick Size (0 = auto detect)
|
||||||
|
input int NumberOfRetries = 50; // Maximum number of retries
|
||||||
|
input int BusyTimeout_ms = 1000; // Wait [ms] before retry on busy errors
|
||||||
|
input int RequoteTimeout_ms = 250; // Wait [ms] before retry on requotes
|
||||||
|
|
||||||
|
// Global data buffers
|
||||||
|
|
||||||
|
double MA1[]; // Buffer for moving average 1
|
||||||
|
double MA2[]; // Buffer for moving average 2
|
||||||
|
|
||||||
|
// Read 3 rates & 3 MA values starting from current (uncompleted) bar
|
||||||
|
|
||||||
|
int startAtBar = 0;
|
||||||
|
int numberOfBars = 3;
|
||||||
|
|
||||||
|
// EA variables
|
||||||
|
|
||||||
|
CMarketOrder *marketOrder = NULL;
|
||||||
|
CTimeControl *timeControl = NULL;
|
||||||
|
CTradeManager *tradeManager = NULL;
|
||||||
|
|
||||||
|
ulong currentTicket;
|
||||||
|
CTradeManagerState tradeManagerState;
|
||||||
|
ENUM_POSITION_TYPE currentPositionType;
|
||||||
|
ENUM_POSITION_TYPE signal;
|
||||||
|
ENUM_POSITION_TYPE validation;
|
||||||
|
|
||||||
|
#ifdef EA_ON_RANGE_BARS
|
||||||
|
static int _MA1 = RANGEBAR_MA1;
|
||||||
|
static int _MA2 = RANGEBAR_MA2;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_RENKO
|
||||||
|
static int _MA1 = RENKO_MA1;
|
||||||
|
static int _MA2 = RENKO_MA2;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_XTICK_CHART
|
||||||
|
static int _MA1 = TICKCHART_MA1;
|
||||||
|
static int _MA2 = TICKCHART_MA2;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_TICK_VOLUME_CHART
|
||||||
|
static int _MA1 = VOLUMECHART_MA1;
|
||||||
|
static int _MA2 = VOLUMECHART_MA2;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_SECONDS_CHART
|
||||||
|
static int _MA1 = SECONDS_MA1;
|
||||||
|
static int _MA2 = SECONDS_MA2;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_LINEBREAK_CHART
|
||||||
|
static int _MA1 = LINEBREAK_MA1;
|
||||||
|
static int _MA2 = LINEBREAK_MA2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
if(customBars == NULL)
|
||||||
|
{
|
||||||
|
#ifdef EA_ON_RANGE_BARS
|
||||||
|
customBars = new RangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_RENKO
|
||||||
|
customBars = new MedianRenko(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_XTICK_CHART
|
||||||
|
customBars = new TickChart(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_TICK_VOLUME_CHART
|
||||||
|
customBars = new TickChart(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_SECONDS_CHART
|
||||||
|
customBars = new SecondsChart(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_LINEBREAK_CHART
|
||||||
|
customBars = new LineBreakChart(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
customBars.Init();
|
||||||
|
if(customBars.GetHandle() == INVALID_HANDLE)
|
||||||
|
return(INIT_FAILED);
|
||||||
|
|
||||||
|
signal = POSITION_TYPE_NONE;
|
||||||
|
|
||||||
|
CMarketOrderParameters params;
|
||||||
|
{
|
||||||
|
params.m_async_mode = false;
|
||||||
|
params.m_magic = MagicNumber;
|
||||||
|
params.m_deviation = DeviationPoints;
|
||||||
|
params.m_type_filling = ORDER_FILLING_FOK;
|
||||||
|
|
||||||
|
params.numberOfRetries = NumberOfRetries;
|
||||||
|
params.busyTimeout_ms = BusyTimeout_ms;
|
||||||
|
params.requoteTimeout_ms = RequoteTimeout_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
marketOrder = new CMarketOrder(params);
|
||||||
|
|
||||||
|
if(timeControl == NULL)
|
||||||
|
{
|
||||||
|
timeControl = new CTimeControl();
|
||||||
|
}
|
||||||
|
|
||||||
|
timeControl.SetValidTraingHours(Start,End);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init TradeManager
|
||||||
|
//
|
||||||
|
|
||||||
|
CTradeManagerParameters params2;
|
||||||
|
{
|
||||||
|
params2.BEPoints = InpBEPoints;
|
||||||
|
params2.TrailByPoints = InpTrailByPoints;
|
||||||
|
params2.TrailStartPoints = InpTrailStartPoints;
|
||||||
|
params2.PartialCloseAtProfitPoints = InpPartialCloseAtProfitPoints;
|
||||||
|
params2.PartialClosePercentage = InpPartialClosePercentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tradeManager == NULL)
|
||||||
|
{
|
||||||
|
tradeManager = new CTradeManager(params2, marketOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
return INIT_SUCCEEDED;
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert deinitialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
customBars.Deinit();
|
||||||
|
|
||||||
|
// delete TimeControl class
|
||||||
|
|
||||||
|
if(timeControl != NULL)
|
||||||
|
{
|
||||||
|
delete timeControl;
|
||||||
|
timeControl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete MarketOrder class
|
||||||
|
|
||||||
|
if(marketOrder != NULL)
|
||||||
|
{
|
||||||
|
delete marketOrder;
|
||||||
|
marketOrder = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete MedianRenko class
|
||||||
|
|
||||||
|
if(customBars != NULL)
|
||||||
|
{
|
||||||
|
delete customBars;
|
||||||
|
customBars = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tradeManager != NULL)
|
||||||
|
{
|
||||||
|
delete tradeManager;
|
||||||
|
tradeManager = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Comment("");
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert tick function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
if(marketOrder == NULL || customBars == NULL || timeControl == NULL || tradeManager == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// trade management
|
||||||
|
|
||||||
|
if(marketOrder.IsOpen(currentTicket, _Symbol, MagicNumber))
|
||||||
|
{
|
||||||
|
// checks done on every tick
|
||||||
|
|
||||||
|
if(!timeControl.IsTradingTimeValid())
|
||||||
|
{
|
||||||
|
if(marketOrder.IsOpen(currentTicket,_Symbol,MagicNumber))
|
||||||
|
{
|
||||||
|
if(currentTicket > 0 && CloseTradeAfterTradingHours)
|
||||||
|
{
|
||||||
|
// close position outside of trading hours
|
||||||
|
marketOrder.Close(currentTicket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tradeManager.Manage(currentTicket, tradeManagerState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal handler
|
||||||
|
|
||||||
|
if(customBars.IsNewBar())
|
||||||
|
{
|
||||||
|
if(timeControl.IsScheduleEnabled())
|
||||||
|
{
|
||||||
|
Comment("EA trading schedule ON ("+Start+" to "+End+") | trading enabled = "+(string)timeControl.IsTradingTimeValid());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Comment("EA trading schedule OFF");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get moving average values for current, last completed bar and the bar before that...
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customBars.GetMA(_MA1,MA1,startAtBar,numberOfBars))
|
||||||
|
{
|
||||||
|
Print("Error getting values from MA1 - please enable MA1 on chart");
|
||||||
|
}
|
||||||
|
else if(!customBars.GetMA(_MA2,MA2,startAtBar,numberOfBars))
|
||||||
|
{
|
||||||
|
Print("Error getting values from MA2 - please enable MA2 on chart");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
signal = MovingAverageCross();
|
||||||
|
validation = MovingAverageValidation();
|
||||||
|
|
||||||
|
if(timeControl.IsScheduleEnabled())
|
||||||
|
{
|
||||||
|
Comment("EA trading schedule ("+Start+" to "+End+") | trading enabled = "+(string)timeControl.IsTradingTimeValid()+
|
||||||
|
// "\n MA1 [2]: "+DoubleToString(MA1[2],_Digits)+" [1]: "+DoubleToString(MA1[1],_Digits)+
|
||||||
|
// "\n MA2 [2]: "+DoubleToString(MA2[2],_Digits)+" [1]: "+DoubleToString(MA2[1],_Digits)+
|
||||||
|
"\n MA cross signal = "+marketOrder.PositionTypeToString(signal)+
|
||||||
|
"\n MA validation = "+marketOrder.PositionTypeToString(validation)+
|
||||||
|
"\n Trade manager: "+tradeManager.ToString()+
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Comment("EA trading schedule not used. Trading is enabled."+
|
||||||
|
// "\n MA1 [2]: "+DoubleToString(MA1[2],_Digits)+" [1]: "+DoubleToString(MA1[1],_Digits)+
|
||||||
|
// "\n MA2 [2]: "+DoubleToString(MA2[2],_Digits)+" [1]: "+DoubleToString(MA2[1],_Digits)+
|
||||||
|
"\n MA cross signal = "+marketOrder.PositionTypeToString(signal)+
|
||||||
|
"\n MA validation = "+marketOrder.PositionTypeToString(validation)+
|
||||||
|
"\n Trade manager: "+tradeManager.ToString()+
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(signal == POSITION_TYPE_BUY)
|
||||||
|
{
|
||||||
|
if(marketOrder.IsOpen(currentTicket,_Symbol,POSITION_TYPE_SELL,MagicNumber))
|
||||||
|
{
|
||||||
|
if(currentTicket > 0 && ForceSR)
|
||||||
|
{
|
||||||
|
if(IsTradeDirectionValid(POSITION_TYPE_SELL))
|
||||||
|
{
|
||||||
|
PrintFormat("Reversing %s position on Stop&Reverse condition (ticket:%d)", _Symbol, currentTicket);
|
||||||
|
marketOrder.Reverse(currentTicket,Lots,StopLoss,TakeProfit);
|
||||||
|
tradeManagerState.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(!marketOrder.IsOpen(_Symbol,POSITION_TYPE_BUY,MagicNumber))
|
||||||
|
{
|
||||||
|
if(IsTradeDirectionValid(POSITION_TYPE_BUY))
|
||||||
|
{
|
||||||
|
marketOrder.Long(_Symbol,Lots,StopLoss,TakeProfit);
|
||||||
|
tradeManagerState.Clear();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(signal == POSITION_TYPE_SELL)
|
||||||
|
{
|
||||||
|
if(marketOrder.IsOpen(currentTicket,_Symbol,POSITION_TYPE_BUY,MagicNumber))
|
||||||
|
{
|
||||||
|
if(currentTicket > 0 && ForceSR)
|
||||||
|
{
|
||||||
|
if(IsTradeDirectionValid(POSITION_TYPE_SELL))
|
||||||
|
{
|
||||||
|
PrintFormat("Reversing %s position on Stop&Reverse condition (ticket:%d)", _Symbol, currentTicket);
|
||||||
|
marketOrder.Reverse(currentTicket,Lots,StopLoss,TakeProfit);
|
||||||
|
tradeManagerState.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(!marketOrder.IsOpen(_Symbol,POSITION_TYPE_SELL,MagicNumber))
|
||||||
|
{
|
||||||
|
if(IsTradeDirectionValid(POSITION_TYPE_SELL))
|
||||||
|
{
|
||||||
|
tradeManagerState.Clear();
|
||||||
|
marketOrder.Short(_Symbol,Lots,StopLoss,TakeProfit);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Handling of crosses inside price gap
|
||||||
|
// Condition: No valid cross signal, but MA validation changed
|
||||||
|
//
|
||||||
|
|
||||||
|
if(marketOrder.IsOpen(currentTicket,currentPositionType,_Symbol,MagicNumber))
|
||||||
|
{
|
||||||
|
if(currentTicket > 0)
|
||||||
|
{
|
||||||
|
if((currentPositionType != validation) && (validation != POSITION_TYPE_NONE) && signal == POSITION_TYPE_NONE)
|
||||||
|
{
|
||||||
|
if(ReverseOnMACrossInsideGap)
|
||||||
|
{
|
||||||
|
// reverse position on signal change inside gap.
|
||||||
|
PrintFormat("Reversing %s position on signal change inside gap (ticket:%d)", _Symbol, currentTicket);
|
||||||
|
marketOrder.Reverse(currentTicket,Lots,StopLoss,TakeProfit);
|
||||||
|
tradeManagerState.Clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// close position on signal change inside gap.
|
||||||
|
PrintFormat("Closing %s position on signal change inside gap (ticket:%d)", _Symbol, currentTicket);
|
||||||
|
marketOrder.Close(currentTicket);
|
||||||
|
tradeManagerState.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Trade direction validation (Is it OK to trade in the given direction?)
|
||||||
|
//
|
||||||
|
|
||||||
|
bool IsTradeDirectionValid(ENUM_POSITION_TYPE signalDirection)
|
||||||
|
{
|
||||||
|
if(ValidTradeDirection == TRADE_DIRECTION_ALL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(signalDirection == POSITION_TYPE_BUY && ValidTradeDirection == TRADE_DIRECTION_BUY)
|
||||||
|
return true;
|
||||||
|
else if(signalDirection == POSITION_TYPE_SELL && ValidTradeDirection == TRADE_DIRECTION_SELL)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// MA cross logic
|
||||||
|
//
|
||||||
|
|
||||||
|
ENUM_POSITION_TYPE MovingAverageCross()
|
||||||
|
{
|
||||||
|
if(2 < numberOfBars-1)
|
||||||
|
{
|
||||||
|
Alert("Invalid number of MA readings defined! MA Cross cannot be determined.");
|
||||||
|
return POSITION_TYPE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((MA2[1] > MA1[1]) && (MA2[2] < MA1[2]))
|
||||||
|
return POSITION_TYPE_SELL;
|
||||||
|
else if((MA2[1] < MA1[1]) && (MA2[2] > MA1[2]))
|
||||||
|
return POSITION_TYPE_BUY;
|
||||||
|
else
|
||||||
|
return POSITION_TYPE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENUM_POSITION_TYPE MovingAverageValidation()
|
||||||
|
{
|
||||||
|
if(MA2[1] > MA1[1])
|
||||||
|
return POSITION_TYPE_SELL;
|
||||||
|
else if(MA2[1] < MA1[1])
|
||||||
|
return POSITION_TYPE_BUY;
|
||||||
|
|
||||||
|
return POSITION_TYPE_NONE;
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -0,0 +1,492 @@
|
|||||||
|
#property copyright "Copyright 2017-2021, Artur Zas"
|
||||||
|
// GNU General Public License v3.0 -> https://github.com/9nix6/Median-and-Turbo-Renko-indicator-bundle/blob/master/LICENSE
|
||||||
|
#property link "https://www.az-invest.eu"
|
||||||
|
#define VERSION "1.10"
|
||||||
|
#property version VERSION
|
||||||
|
#property description "Example EA: Trading based on moving average && price crossover."
|
||||||
|
#property description "MA1 needs to be enabled on the inicator creating the chart."
|
||||||
|
#property description " "
|
||||||
|
#property description "GNU General Public License v3.0"
|
||||||
|
|
||||||
|
//#define RANGEBAR_LICENSE // uncomment when used on a Tick & Volume bar chart from https://www.az-invest.eu/rangebars-for-metatrader-5
|
||||||
|
//#define ULTIMATE_RENKO_LICENSE // uncomment when used on Ultimate Renko chart from https://www.az-invest.eu/ultimate-renko-indicator-generator-for-metatrader-5
|
||||||
|
//#define VOLUMECHART_LICENSE // uncomment when used on a Tick & Volume bar chart from https://www.az-invest.eu/Tick-chart-and-volume-chart-for-mt5
|
||||||
|
//#define SECONDSCHART_LICENSE // uncomment when used on a Seconds TF bar chart from https://www.az-invest.eu/seconds-timeframe-chart-for-metatrader-5
|
||||||
|
//#define LINEBREAKCHART_LICENSE // uncomment when used on a Line Break chart from https://www.az-invest.eu/linebreak-chart-for-metatrader-5
|
||||||
|
|
||||||
|
//
|
||||||
|
// Uncomment only ONE of the 5 directives listed below and recompile
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
//
|
||||||
|
#define EA_ON_RANGE_BARS // Use EA on RangeBar chart
|
||||||
|
//#define EA_ON_RENKO // Use EA on Renko charts
|
||||||
|
//#define EA_ON_XTICK_CHART // Use EA on XTick Chart (obsolete)
|
||||||
|
//#define EA_ON_TICK_VOLUME_CHART // Use EA on Tick & Volume Bar Chart
|
||||||
|
//#define EA_ON_SECONDS_CHART // Use EA on Seconds Interval chart
|
||||||
|
//#define EA_ON_LINEBREAK_CHART // Use EA on LineBreak charts
|
||||||
|
|
||||||
|
//#define DEVELOPER_VERSION // used when I develop ;) should always be commented out
|
||||||
|
|
||||||
|
// Uncomment the directive below and recompile if EA is used with P-Renko BR Ultimate
|
||||||
|
// ----------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//#define P_RENKO_BR_PRO // Use in P-Renko BR Ultimate version
|
||||||
|
|
||||||
|
//
|
||||||
|
// Uncomment the directive below and recompile for use in a backtest only
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// #define SHOW_INDICATOR_INPUTS
|
||||||
|
|
||||||
|
// Include all needed files
|
||||||
|
|
||||||
|
#ifdef EA_ON_RANGE_BARS
|
||||||
|
#include <AZ-INVEST/SDK/RangeBars.mqh>
|
||||||
|
RangeBars *customBars = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_RENKO
|
||||||
|
#include <AZ-INVEST/SDK/MedianRenko.mqh>
|
||||||
|
MedianRenko *customBars = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_XTICK_CHART
|
||||||
|
#include <AZ-INVEST/SDK/TickChart.mqh>
|
||||||
|
TickChart *customBars = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_TICK_VOLUME_CHART
|
||||||
|
#include <AZ-INVEST/SDK/VolumeBarChart.mqh>
|
||||||
|
TickChart *customBars = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_SECONDS_CHART
|
||||||
|
#include <AZ-INVEST/SDK/SecondsChart.mqh>
|
||||||
|
SecondsChart *customBars = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_LINEBREAK_CHART
|
||||||
|
#include <AZ-INVEST/SDK/LineBreakChart.mqh>
|
||||||
|
LineBreakChart *customBars = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <AZ-INVEST/SDK/TimeControl.mqh>
|
||||||
|
#include <AZ-INVEST/SDK/TradeFunctions.mqh>
|
||||||
|
#include <AZ-INVEST/SDK/TradeManager.mqh>
|
||||||
|
|
||||||
|
enum ENUM_TRADE_DIRECTION
|
||||||
|
{
|
||||||
|
TRADE_DIRECTION_BUY = POSITION_TYPE_BUY, // Buy
|
||||||
|
TRADE_DIRECTION_SELL = POSITION_TYPE_SELL, // Sell
|
||||||
|
TRADE_DIRECTION_ALL = 1000, // Buy & Sell
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef SHOW_INDICATOR_INPUTS
|
||||||
|
input group "EA parameters"
|
||||||
|
#endif
|
||||||
|
input double Lots = 0.1; // Traded lots
|
||||||
|
input uint StopLoss = 0; // Stop Loss
|
||||||
|
input uint TakeProfit = 0; // Take profit
|
||||||
|
input int ConfirmationBars = 1; // Signal confirmation bars
|
||||||
|
input int PrevSignalBars = 1; // Prev. signal confirmation bars
|
||||||
|
input ENUM_TRADE_DIRECTION ValidTradeDirection = TRADE_DIRECTION_ALL; // Valid trading type
|
||||||
|
input bool CloseTradeOnSignalChange = true; // Close trade on signal change
|
||||||
|
input bool ForceSR = false; // Force Stop & Reverse
|
||||||
|
input group "### Trading schedule (Non stop if start = 0 & end = 0)"
|
||||||
|
input string Start="9:00"; // Start trading at
|
||||||
|
input string End="17:55"; // End trading at
|
||||||
|
input bool CloseTradeAfterTradingHours = true; // Close trade after trading hours
|
||||||
|
input group "### Trade management";
|
||||||
|
input int InpBEPoints = 0; // BreakEven (Points) [ 0 = OFF ]
|
||||||
|
input int InpTrailByPoints = 0; // Trail by (Points) [ 0 = OFF ]
|
||||||
|
input int InpTrailStartPoints = 150; // Start trailing after (Points)
|
||||||
|
input int InpPartialCloseAtProfitPoints = 0; // Partial close at (Points) [ 0 = OFF ]
|
||||||
|
input int InpPartialClosePercentage = 50; // Partial close %
|
||||||
|
input group "### Misc";
|
||||||
|
input ulong MagicNumber=8888; // Assign trade ID
|
||||||
|
input ulong DeviationPoints = 0; // Maximum defiation (in points)
|
||||||
|
input double ManualTickSize = 0.000; // Tick Size (0 = auto detect)
|
||||||
|
input int NumberOfRetries = 50; // Maximum number of retries
|
||||||
|
input int BusyTimeout_ms = 1000; // Wait [ms] before retry on busy errors
|
||||||
|
input int RequoteTimeout_ms = 250; // Wait [ms] before retry on requotes
|
||||||
|
|
||||||
|
// Global data buffers
|
||||||
|
|
||||||
|
MqlRates RateInfo[]; // Buffer for custom price bars
|
||||||
|
double MA1[]; // Buffer for moving average 1
|
||||||
|
|
||||||
|
// Read 4 rates MA1 values starting from current (uncompleted) bar
|
||||||
|
|
||||||
|
int startAtBar = 0;
|
||||||
|
int numberOfBars;
|
||||||
|
int _confirmationBars;
|
||||||
|
int _prevSignalBars;
|
||||||
|
|
||||||
|
// EA variables
|
||||||
|
|
||||||
|
CMarketOrder *marketOrder = NULL;
|
||||||
|
CTimeControl *timeControl = NULL;
|
||||||
|
CTradeManager *tradeManager = NULL;
|
||||||
|
|
||||||
|
ulong currentTicket;
|
||||||
|
CTradeManagerState tradeManagerState;
|
||||||
|
ENUM_POSITION_TYPE currentPositionType;
|
||||||
|
ENUM_POSITION_TYPE signal;
|
||||||
|
ENUM_POSITION_TYPE validation;
|
||||||
|
|
||||||
|
#ifdef EA_ON_RANGE_BARS
|
||||||
|
static int _MA1 = RANGEBAR_MA1;
|
||||||
|
static int _MA2 = RANGEBAR_MA2;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_RENKO
|
||||||
|
static int _MA1 = RENKO_MA1;
|
||||||
|
static int _MA2 = RENKO_MA2;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_XTICK_CHART
|
||||||
|
static int _MA1 = TICKCHART_MA1;
|
||||||
|
static int _MA2 = TICKCHART_MA2;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_TICK_VOLUME_CHART
|
||||||
|
static int _MA1 = VOLUMECHART_MA1;
|
||||||
|
static int _MA2 = VOLUMECHART_MA2;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_SECONDS_CHART
|
||||||
|
static int _MA1 = SECONDS_MA1;
|
||||||
|
static int _MA2 = SECONDS_MA2;
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_LINEBREAK_CHART
|
||||||
|
static int _MA1 = LINEBREAK_MA1;
|
||||||
|
static int _MA2 = LINEBREAK_MA2;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
if(customBars == NULL)
|
||||||
|
{
|
||||||
|
#ifdef EA_ON_RANGE_BARS
|
||||||
|
customBars = new RangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_RENKO
|
||||||
|
customBars = new MedianRenko(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_XTICK_CHART
|
||||||
|
customBars = new TickChart(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_TICK_VOLUME_CHART
|
||||||
|
customBars = new TickChart(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_SECONDS_CHART
|
||||||
|
customBars = new SecondsChart(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
#endif
|
||||||
|
#ifdef EA_ON_LINEBREAK_CHART
|
||||||
|
customBars = new LineBreakChart(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
customBars.Init();
|
||||||
|
if(customBars.GetHandle() == INVALID_HANDLE)
|
||||||
|
return(INIT_FAILED);
|
||||||
|
|
||||||
|
signal = POSITION_TYPE_NONE;
|
||||||
|
_confirmationBars = (ConfirmationBars < 1) ? 1 : ConfirmationBars;
|
||||||
|
_prevSignalBars = (PrevSignalBars < 1) ? 1 : PrevSignalBars;
|
||||||
|
numberOfBars = _confirmationBars + _prevSignalBars + 1;
|
||||||
|
|
||||||
|
CMarketOrderParameters params;
|
||||||
|
{
|
||||||
|
params.m_async_mode = false;
|
||||||
|
params.m_magic = MagicNumber;
|
||||||
|
params.m_deviation = DeviationPoints;
|
||||||
|
params.m_type_filling = ORDER_FILLING_FOK;
|
||||||
|
|
||||||
|
params.numberOfRetries = NumberOfRetries;
|
||||||
|
params.busyTimeout_ms = BusyTimeout_ms;
|
||||||
|
params.requoteTimeout_ms = RequoteTimeout_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
marketOrder = new CMarketOrder(params);
|
||||||
|
|
||||||
|
if(timeControl == NULL)
|
||||||
|
{
|
||||||
|
timeControl = new CTimeControl();
|
||||||
|
}
|
||||||
|
|
||||||
|
timeControl.SetValidTraingHours(Start,End);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Init TradeManager
|
||||||
|
//
|
||||||
|
|
||||||
|
CTradeManagerParameters params2;
|
||||||
|
{
|
||||||
|
params2.BEPoints = InpBEPoints;
|
||||||
|
params2.TrailByPoints = InpTrailByPoints;
|
||||||
|
params2.TrailStartPoints = InpTrailStartPoints;
|
||||||
|
params2.PartialCloseAtProfitPoints = InpPartialCloseAtProfitPoints;
|
||||||
|
params2.PartialClosePercentage = InpPartialClosePercentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tradeManager == NULL)
|
||||||
|
{
|
||||||
|
tradeManager = new CTradeManager(params2, marketOrder);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(INIT_SUCCEEDED);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert deinitialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
customBars.Deinit();
|
||||||
|
|
||||||
|
// delete TimeControl class
|
||||||
|
|
||||||
|
if(timeControl != NULL)
|
||||||
|
{
|
||||||
|
delete timeControl;
|
||||||
|
timeControl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete MarketOrder class
|
||||||
|
|
||||||
|
if(marketOrder != NULL)
|
||||||
|
{
|
||||||
|
delete marketOrder;
|
||||||
|
marketOrder = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete MedianRenko class
|
||||||
|
|
||||||
|
if(customBars != NULL)
|
||||||
|
{
|
||||||
|
delete customBars;
|
||||||
|
customBars = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tradeManager != NULL)
|
||||||
|
{
|
||||||
|
delete tradeManager;
|
||||||
|
tradeManager = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Comment("");
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Expert tick function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnTick()
|
||||||
|
{
|
||||||
|
if(marketOrder == NULL || customBars == NULL || timeControl == NULL || tradeManager == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// trade management
|
||||||
|
|
||||||
|
if(marketOrder.IsOpen(currentTicket, _Symbol, MagicNumber))
|
||||||
|
{
|
||||||
|
// checks done on every tick
|
||||||
|
|
||||||
|
if(!timeControl.IsTradingTimeValid())
|
||||||
|
{
|
||||||
|
if(marketOrder.IsOpen(currentTicket,_Symbol,MagicNumber))
|
||||||
|
{
|
||||||
|
if(currentTicket > 0 && CloseTradeAfterTradingHours)
|
||||||
|
{
|
||||||
|
// close position outside of trading hours
|
||||||
|
marketOrder.Close(currentTicket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tradeManager.Manage(currentTicket, tradeManagerState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signal handler
|
||||||
|
|
||||||
|
if(customBars.IsNewBar())
|
||||||
|
{
|
||||||
|
if(timeControl.IsScheduleEnabled())
|
||||||
|
{
|
||||||
|
Comment("EA trading schedule ON ("+Start+" to "+End+") | trading enabled = "+(string)timeControl.IsTradingTimeValid());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Comment("EA trading schedule OFF");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get MqlRateInfo & moving average values for current, last completed bar and the bar before that...
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customBars.GetMqlRates(RateInfo,startAtBar,numberOfBars))
|
||||||
|
{
|
||||||
|
Print("Error getting MqlRates for custom chart");
|
||||||
|
}
|
||||||
|
else if(!customBars.GetMA(_MA1, MA1, startAtBar, numberOfBars))
|
||||||
|
{
|
||||||
|
Print("Error getting values from MA1 - please enable MA1 on chart");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
signal = PriceAndMovingAverageCross(_confirmationBars, _prevSignalBars);
|
||||||
|
|
||||||
|
if(timeControl.IsScheduleEnabled())
|
||||||
|
{
|
||||||
|
Comment("EA trading schedule ("+Start+" to "+End+") | trading enabled = "+(string)timeControl.IsTradingTimeValid()+
|
||||||
|
//"\n MA_1 [2]: "+DoubleToString(MA1[2],_Digits)+" [1]: "+DoubleToString(MA1[1],_Digits)+
|
||||||
|
//"\n Close[2]: "+DoubleToString(RateInfo[2].close,_Digits)+" [1]: "+DoubleToString(RateInfo[1].close,_Digits)+
|
||||||
|
"\n Price & MA cross signal = "+marketOrder.PositionTypeToString(signal)+
|
||||||
|
"\n Trade manager: "+tradeManager.ToString()+
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Comment("EA trading schedule not used. Trading is enabled."+
|
||||||
|
//"\n MA_1 [2]: "+DoubleToString(MA1[2],_Digits)+" [1]: "+DoubleToString(MA1[1],_Digits)+
|
||||||
|
//"\n Close[2]: "+DoubleToString(RateInfo[2].close,_Digits)+" [1]: "+DoubleToString(RateInfo[1].close,_Digits)+
|
||||||
|
"\n Price & MA cross signal = "+marketOrder.PositionTypeToString(signal)+
|
||||||
|
"\n Trade manager: "+tradeManager.ToString()+
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(signal == POSITION_TYPE_BUY)
|
||||||
|
{
|
||||||
|
if(marketOrder.IsOpen(currentTicket,_Symbol,POSITION_TYPE_SELL,MagicNumber))
|
||||||
|
{
|
||||||
|
if(currentTicket > 0 && ForceSR)
|
||||||
|
{
|
||||||
|
if(IsTradeDirectionValid(POSITION_TYPE_SELL))
|
||||||
|
{
|
||||||
|
PrintFormat("Reversing %s position on Stop&Reverse condition (ticket:%d)", _Symbol, currentTicket);
|
||||||
|
marketOrder.Reverse(currentTicket,Lots,StopLoss,TakeProfit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(currentTicket > 0)
|
||||||
|
{
|
||||||
|
// close trade on signal change
|
||||||
|
if(CloseTradeOnSignalChange)
|
||||||
|
{
|
||||||
|
PrintFormat("Closing %s position on signal change (ticket:%d)", _Symbol, currentTicket);
|
||||||
|
marketOrder.Close(currentTicket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!marketOrder.IsOpen(_Symbol,POSITION_TYPE_BUY,MagicNumber))
|
||||||
|
{
|
||||||
|
if(IsTradeDirectionValid(POSITION_TYPE_BUY))
|
||||||
|
marketOrder.Long(_Symbol,Lots,StopLoss,TakeProfit);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(signal == POSITION_TYPE_SELL)
|
||||||
|
{
|
||||||
|
if(marketOrder.IsOpen(currentTicket,_Symbol,POSITION_TYPE_BUY,MagicNumber))
|
||||||
|
{
|
||||||
|
if(currentTicket > 0 && ForceSR)
|
||||||
|
{
|
||||||
|
if(IsTradeDirectionValid(POSITION_TYPE_BUY))
|
||||||
|
{
|
||||||
|
PrintFormat("Reversing %s position on Stop&Reverse condition (ticket:%d)", _Symbol, currentTicket);
|
||||||
|
marketOrder.Reverse(currentTicket,Lots,StopLoss,TakeProfit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(currentTicket > 0)
|
||||||
|
{
|
||||||
|
// close trade on signal change
|
||||||
|
if(CloseTradeOnSignalChange)
|
||||||
|
{
|
||||||
|
PrintFormat("Closing %s position on signal change (ticket:%d)", _Symbol, currentTicket);
|
||||||
|
marketOrder.Close(currentTicket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!marketOrder.IsOpen(_Symbol,POSITION_TYPE_SELL,MagicNumber))
|
||||||
|
{
|
||||||
|
if(IsTradeDirectionValid(POSITION_TYPE_SELL))
|
||||||
|
marketOrder.Short(_Symbol,Lots,StopLoss,TakeProfit);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Trade direction validation (Is it OK to trade in the given direction?)
|
||||||
|
//
|
||||||
|
|
||||||
|
bool IsTradeDirectionValid(ENUM_POSITION_TYPE signalDirection)
|
||||||
|
{
|
||||||
|
if(ValidTradeDirection == TRADE_DIRECTION_ALL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(signalDirection == POSITION_TYPE_BUY && ValidTradeDirection == TRADE_DIRECTION_BUY)
|
||||||
|
return true;
|
||||||
|
else if(signalDirection == POSITION_TYPE_SELL && ValidTradeDirection == TRADE_DIRECTION_SELL)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Price & MA cross logic
|
||||||
|
//
|
||||||
|
|
||||||
|
ENUM_POSITION_TYPE PriceAndMovingAverageCross(int confirmationBars, int prevSignalBars)
|
||||||
|
{
|
||||||
|
if(numberOfBars < confirmationBars+1)
|
||||||
|
{
|
||||||
|
Alert("Invalid number of MqlRates and MA readings defined! Crossover cannot be determined.");
|
||||||
|
return POSITION_TYPE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool confirmedSell = true;
|
||||||
|
bool confirmedBuy = true;
|
||||||
|
|
||||||
|
// check trailing bar for confirmation of previous signal
|
||||||
|
for(int i=(confirmationBars+1); i<=(confirmationBars+prevSignalBars); i++)
|
||||||
|
{
|
||||||
|
if(RateInfo[i].close > MA1[i])
|
||||||
|
{
|
||||||
|
confirmedBuy = false;
|
||||||
|
}
|
||||||
|
else if(RateInfo[i].close < MA1[i])
|
||||||
|
{
|
||||||
|
confirmedSell = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check confirmation bars for current signal
|
||||||
|
for(int i=1; i<=confirmationBars; i++)
|
||||||
|
{
|
||||||
|
if(RateInfo[i].close == MA1[i])
|
||||||
|
{
|
||||||
|
confirmedSell = false;
|
||||||
|
confirmedBuy = false;
|
||||||
|
}
|
||||||
|
else if(RateInfo[i].close < MA1[i])
|
||||||
|
{
|
||||||
|
confirmedBuy = false;
|
||||||
|
}
|
||||||
|
else if(RateInfo[i].close > MA1[i])
|
||||||
|
{
|
||||||
|
confirmedSell = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// signal aggregate
|
||||||
|
if(confirmedSell)
|
||||||
|
return POSITION_TYPE_SELL;
|
||||||
|
else if(confirmedBuy)
|
||||||
|
return POSITION_TYPE_BUY;
|
||||||
|
else
|
||||||
|
return POSITION_TYPE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
Binary file not shown.
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
input int InpRSIPeriod = 14; // RSI period
|
input int InpRSIPeriod = 14; // RSI period
|
||||||
|
|
||||||
|
//#define DEVELOPER_VERSION // used when I develop ;) should always be commented out
|
||||||
|
|
||||||
//
|
//
|
||||||
// SHOW_INDICATOR_INPUTS *NEEDS* to be defined, if the sEA needs to be *tested in MT5's backtester*
|
// SHOW_INDICATOR_INPUTS *NEEDS* to be defined, if the sEA needs to be *tested in MT5's backtester*
|
||||||
// -------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------
|
||||||
@@ -26,13 +28,18 @@ input int InpRSIPeriod = 14; // RSI period
|
|||||||
// Example shown below
|
// Example shown below
|
||||||
//
|
//
|
||||||
|
|
||||||
RangeBars rangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
RangeBars *rangeBars = NULL;
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| Expert initialization function |
|
//| Expert initialization function |
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
int OnInit()
|
int OnInit()
|
||||||
{
|
{
|
||||||
|
if(rangeBars == NULL)
|
||||||
|
{
|
||||||
|
rangeBars = new RangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
}
|
||||||
|
|
||||||
rangeBars.Init();
|
rangeBars.Init();
|
||||||
if(rangeBars.GetHandle() == INVALID_HANDLE)
|
if(rangeBars.GetHandle() == INVALID_HANDLE)
|
||||||
return(INIT_FAILED);
|
return(INIT_FAILED);
|
||||||
@@ -48,7 +55,12 @@ int OnInit()
|
|||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
void OnDeinit(const int reason)
|
void OnDeinit(const int reason)
|
||||||
{
|
{
|
||||||
rangeBars.Deinit();
|
if(rangeBars != NULL)
|
||||||
|
{
|
||||||
|
rangeBars.Deinit();
|
||||||
|
delete rangeBars;
|
||||||
|
rangeBars = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// your custom code goes here...
|
// your custom code goes here...
|
||||||
|
|||||||
Binary file not shown.
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include <AZ-INVEST/SDK/TradeFunctions.mqh>
|
#include <AZ-INVEST/SDK/TradeFunctions.mqh>
|
||||||
|
|
||||||
|
//#define DEVELOPER_VERSION // used when I develop ;) should always be commented out
|
||||||
|
|
||||||
//
|
//
|
||||||
// Inputs
|
// Inputs
|
||||||
//
|
//
|
||||||
@@ -39,7 +41,7 @@ ulong currentTicket;
|
|||||||
// the RangeBars indicator attached.
|
// 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
|
||||||
@@ -52,14 +54,19 @@ ulong currentTicket;
|
|||||||
// Example shown below
|
// Example shown below
|
||||||
//
|
//
|
||||||
|
|
||||||
RangeBars rangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
RangeBars *rangeBars = NULL;
|
||||||
CMarketOrder * marketOrder;
|
CMarketOrder *marketOrder = NULL;
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| Expert initialization function |
|
//| Expert initialization function |
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
int OnInit()
|
int OnInit()
|
||||||
{
|
{
|
||||||
|
if(rangeBars == NULL)
|
||||||
|
{
|
||||||
|
rangeBars = new RangeBars(MQLInfoInteger((int)MQL5_TESTING) ? false : true);
|
||||||
|
}
|
||||||
|
|
||||||
rangeBars.Init();
|
rangeBars.Init();
|
||||||
if(rangeBars.GetHandle() == INVALID_HANDLE)
|
if(rangeBars.GetHandle() == INVALID_HANDLE)
|
||||||
return(INIT_FAILED);
|
return(INIT_FAILED);
|
||||||
@@ -79,8 +86,12 @@ int OnInit()
|
|||||||
params.busyTimeout_ms = InpBusyTimeout_ms;
|
params.busyTimeout_ms = InpBusyTimeout_ms;
|
||||||
params.requoteTimeout_ms = InpRequoteTimeout_ms;
|
params.requoteTimeout_ms = InpRequoteTimeout_ms;
|
||||||
}
|
}
|
||||||
marketOrder = new CMarketOrder(params);
|
|
||||||
|
if(marketOrder == NULL)
|
||||||
|
{
|
||||||
|
marketOrder = new CMarketOrder(params);
|
||||||
|
}
|
||||||
|
|
||||||
return(INIT_SUCCEEDED);
|
return(INIT_SUCCEEDED);
|
||||||
}
|
}
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -88,7 +99,16 @@ int OnInit()
|
|||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
void OnDeinit(const int reason)
|
void OnDeinit(const int reason)
|
||||||
{
|
{
|
||||||
rangeBars.Deinit();
|
//
|
||||||
|
// delete RanegBars class
|
||||||
|
//
|
||||||
|
|
||||||
|
if(rangeBars != NULL)
|
||||||
|
{
|
||||||
|
rangeBars.Deinit();
|
||||||
|
delete rangeBars;
|
||||||
|
rangeBars = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// delete MarketOrder class
|
// delete MarketOrder class
|
||||||
@@ -97,6 +117,7 @@ void OnDeinit(const int reason)
|
|||||||
if(marketOrder != NULL)
|
if(marketOrder != NULL)
|
||||||
{
|
{
|
||||||
delete marketOrder;
|
delete marketOrder;
|
||||||
|
marketOrder = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
//#define DEVELOPER_VERSION
|
||||||
|
//#define DISPLAY_DEBUG_MSG
|
||||||
|
#define MQL5_MARKET_VERSION
|
||||||
|
|
||||||
|
//#define P_RENKO_BR_PRO
|
||||||
|
//#define ULTIMATE_RENKO_LICENSE
|
||||||
|
#define RANGEBAR_LICENSE
|
||||||
|
//#define SECONDSCHART_LICENSE
|
||||||
|
//#define TICKCHART_LICENSE (obsolete)
|
||||||
|
//#define VOLUMECHART_LICENSE
|
||||||
|
//#define LINEBREAKCHART_LICENSE
|
||||||
|
|
||||||
|
#ifdef P_RENKO_BR_PRO
|
||||||
|
#include <AZ-INVEST/SDK/MedianRenkoIndicator.mqh>
|
||||||
|
#define AZINVEST_CCI MedianRenkoIndicator
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TICKCHART_LICENSE
|
||||||
|
#include <AZ-INVEST/SDK/TickChartIndicator.mqh>
|
||||||
|
#define AZINVEST_CCI TickChartIndicator
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RANGEBAR_LICENSE
|
||||||
|
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
||||||
|
#define AZINVEST_CCI RangeBarIndicator
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ULTIMATE_RENKO_LICENSE
|
||||||
|
#include <AZ-INVEST/SDK/MedianRenkoIndicator.mqh>
|
||||||
|
#define AZINVEST_CCI MedianRenkoIndicator
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SECONDSCHART_LICENSE
|
||||||
|
#include <AZ-INVEST/SDK/SecondsChartIndicator.mqh>
|
||||||
|
#define AZINVEST_CCI SecondsChartIndicator
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VOLUMECHART_LICENSE
|
||||||
|
#include <AZ-INVEST/SDK/VolumeChartIndicator.mqh>
|
||||||
|
#define AZINVEST_CCI VolumeChartIndicator
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LINEBREAKCHART_LICENSE
|
||||||
|
#include <AZ-INVEST/SDK/LineBreakChartIndicator.mqh>
|
||||||
|
#define AZINVEST_CCI LineBreakChartIndicator
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef AZINVEST_CCI
|
||||||
|
AZINVEST_CCI customChartIndicator;
|
||||||
|
#endif
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -10,7 +10,8 @@ double NormalizeLots(string symbol, double InputLots)
|
|||||||
{
|
{
|
||||||
double lotsMin = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
|
double lotsMin = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
|
||||||
double lotsMax = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
|
double lotsMax = SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
|
||||||
int lotsDigits = (int) - MathLog10(SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP));
|
// int lotsDigits = (int) - MathLog10(SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP));
|
||||||
|
int lotsDigits = (int)MathAbs(MathLog10(SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP)));
|
||||||
|
|
||||||
if(InputLots < lotsMin)
|
if(InputLots < lotsMin)
|
||||||
InputLots = lotsMin;
|
InputLots = lotsMin;
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
// RSI on Buffer
|
||||||
|
|
||||||
|
int RsiOnBuffer(const int rates_total,const int prev_calculated,const int begin,
|
||||||
|
const int period,const double& price[],double& rsiBuffer[], double &posBuffer[], double &negBuffer[])
|
||||||
|
{
|
||||||
|
int i, pos;
|
||||||
|
double diff;
|
||||||
|
|
||||||
|
//--- check for data
|
||||||
|
if(period<=1 || rates_total-begin<period) return(0);
|
||||||
|
//--- save as_series flags
|
||||||
|
bool as_series_price=ArrayGetAsSeries(price);
|
||||||
|
bool as_series_rsibuffer=ArrayGetAsSeries(rsiBuffer);
|
||||||
|
bool as_series_posbuffer=ArrayGetAsSeries(posBuffer);
|
||||||
|
bool as_series_negbuffer=ArrayGetAsSeries(negBuffer);
|
||||||
|
|
||||||
|
if(as_series_price) ArraySetAsSeries(price,false);
|
||||||
|
if(as_series_rsibuffer) ArraySetAsSeries(rsiBuffer,false);
|
||||||
|
if(as_series_posbuffer) ArraySetAsSeries(posBuffer,false);
|
||||||
|
if(as_series_negbuffer) ArraySetAsSeries(negBuffer,false);
|
||||||
|
|
||||||
|
//--- preliminary calculations
|
||||||
|
pos=prev_calculated-1;
|
||||||
|
if(pos<=period)
|
||||||
|
{
|
||||||
|
//--- first RSIPeriod values of the indicator are not calculated
|
||||||
|
rsiBuffer[0]=0.0;
|
||||||
|
posBuffer[0]=0.0;
|
||||||
|
negBuffer[0]=0.0;
|
||||||
|
double sump=0.0;
|
||||||
|
double sumn=0.0;
|
||||||
|
for(i=1; i<=period; i++)
|
||||||
|
{
|
||||||
|
rsiBuffer[i]=0.0;
|
||||||
|
posBuffer[i]=0.0;
|
||||||
|
negBuffer[i]=0.0;
|
||||||
|
diff=price[i]-price[i-1];
|
||||||
|
if(diff>0)
|
||||||
|
sump+=diff;
|
||||||
|
else
|
||||||
|
sumn-=diff;
|
||||||
|
}
|
||||||
|
//--- calculate first visible value
|
||||||
|
posBuffer[period]=sump/period;
|
||||||
|
negBuffer[period]=sumn/period;
|
||||||
|
if(negBuffer[period]!=0.0)
|
||||||
|
rsiBuffer[period]=100.0-(100.0/(1.0+posBuffer[period]/negBuffer[period]));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(posBuffer[period]!=0.0)
|
||||||
|
rsiBuffer[period]=100.0;
|
||||||
|
else
|
||||||
|
rsiBuffer[period]=50.0;
|
||||||
|
}
|
||||||
|
//--- prepare the position value for main calculation
|
||||||
|
pos=period+1;
|
||||||
|
}
|
||||||
|
//--- the main loop of calculations
|
||||||
|
for(i=pos; i<rates_total && !IsStopped(); i++)
|
||||||
|
{
|
||||||
|
diff=price[i]-price[i-1];
|
||||||
|
posBuffer[i]=(posBuffer[i-1]*(period-1)+(diff>0.0?diff:0.0))/period;
|
||||||
|
negBuffer[i]=(negBuffer[i-1]*(period-1)+(diff<0.0?-diff:0.0))/period;
|
||||||
|
if(negBuffer[i]!=0.0)
|
||||||
|
rsiBuffer[i]=100.0-100.0/(1+posBuffer[i]/negBuffer[i]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(posBuffer[i]!=0.0)
|
||||||
|
rsiBuffer[i]=100.0;
|
||||||
|
else
|
||||||
|
rsiBuffer[i]=50.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--- restore as_series flags
|
||||||
|
if(as_series_price) ArraySetAsSeries(price,true);
|
||||||
|
if(as_series_rsibuffer) ArraySetAsSeries(rsiBuffer,true);
|
||||||
|
if(as_series_posbuffer) ArraySetAsSeries(posBuffer,true);
|
||||||
|
if(as_series_negbuffer) ArraySetAsSeries(negBuffer,true);
|
||||||
|
//---
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
@@ -12,35 +12,35 @@
|
|||||||
#ifdef SHOW_INDICATOR_INPUTS
|
#ifdef SHOW_INDICATOR_INPUTS
|
||||||
#ifdef MQL5_MARKET_DEMO // hardcoded values
|
#ifdef MQL5_MARKET_DEMO // hardcoded values
|
||||||
|
|
||||||
int barSizeInTicks = 180; // Range bar size (in ticks)
|
double InpBarSize = 180; // Range bar size
|
||||||
ENUM_BOOL atrEnabled = false; // Enable ATR based bar size calculation
|
ENUM_BAR_SIZE_CALC_MODE InpBarSizeCalcMode = BAR_SIZE_ABSOLUTE_TICKS; // Bar size calculation
|
||||||
ENUM_TIMEFRAMES atrTimeFrame = PERIOD_D1; // Use ATR period
|
int InpShowNumberOfDays = 7; // Show history for number of days
|
||||||
int atrPeriod = 14; // ATR period
|
datetime InpShowFromDate = 0; // Show history starting from
|
||||||
int atrPercentage = 10; // Use percentage of ATR
|
ENUM_TIMEFRAMES InpAtrTimeFrame = PERIOD_D1; // ATR timeframe setting
|
||||||
int showNumberOfDays = 7; // Show history for number of days
|
int InpAtrPeriod = 14; // ATR period setting
|
||||||
ENUM_BOOL resetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
|
ENUM_BOOL InpResetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
|
||||||
|
|
||||||
#else // user defined settings
|
#else // user defined settings
|
||||||
|
|
||||||
|
input double InpBarSize = 100; // Range bar size
|
||||||
input int barSizeInTicks = 100; // Range bar size (in ticks)
|
input ENUM_BAR_SIZE_CALC_MODE InpBarSizeCalcMode = BAR_SIZE_ABSOLUTE_TICKS;// Bar size calculation
|
||||||
input ENUM_BOOL atrEnabled = false; // Enable ATR based bar size calculation
|
input int InpShowNumberOfDays = 5; // Show history for number of days
|
||||||
ENUM_TIMEFRAMES atrTimeFrame = PERIOD_D1; // Use ATR period
|
input datetime InpShowFromDate = 0; // Show history starting from
|
||||||
input int atrPeriod = 14; // ATR period
|
input group "### ATR bar size calculation settings"
|
||||||
input int atrPercentage = 10; // Use percentage of ATR
|
input ENUM_TIMEFRAMES InpAtrTimeFrame = PERIOD_D1; // ATR timeframe setting
|
||||||
|
input int InpAtrPeriod = 14; // ATR period setting
|
||||||
input int showNumberOfDays = 5; // Show history for number of days
|
input group "### Chart synchronization"
|
||||||
input ENUM_BOOL resetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
|
input ENUM_BOOL InpResetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#else // don't SHOW_INDICATOR_INPUTS
|
#else // don't SHOW_INDICATOR_INPUTS
|
||||||
int barSizeInTicks = 180; // Range bar size (in ticks)
|
double InpBarSize = 180; // Range bar size
|
||||||
ENUM_BOOL atrEnabled = false; // Enable ATR based bar size calculation
|
ENUM_BAR_SIZE_CALC_MODE InpBarSizeCalcMode = BAR_SIZE_ABSOLUTE_TICKS;// Bar size calculation
|
||||||
ENUM_TIMEFRAMES atrTimeFrame = PERIOD_D1; // Use ATR period
|
int InpShowNumberOfDays = 7; // Show history for number of days
|
||||||
int atrPeriod = 14; // ATR period
|
datetime InpShowFromDate = 0; // Show history starting from
|
||||||
int atrPercentage = 10; // Use percentage of ATR
|
ENUM_TIMEFRAMES InpAtrTimeFrame = PERIOD_D1; // ATR timeframe setting
|
||||||
int showNumberOfDays = 7; // Show history for number of days
|
int InpAtrPeriod = 14; // ATR period setting
|
||||||
ENUM_BOOL resetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
|
ENUM_BOOL InpResetOpenOnNewTradingDay = true; // Synchronize first bar's open on new day
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -49,15 +49,19 @@
|
|||||||
//
|
//
|
||||||
#include <az-invest/sdk/CustomChartSettingsBase.mqh>
|
#include <az-invest/sdk/CustomChartSettingsBase.mqh>
|
||||||
|
|
||||||
|
#define SETNAME_BAR_SIZE_CALC_MODE "barSizeCalcMode"
|
||||||
|
#define SETNAME_ATR_TIMEFRAME "atrTimeFrame"
|
||||||
|
#define SETNAME_ATR_PERIOD "atrPeriod"
|
||||||
|
|
||||||
struct RANGEBAR_SETTINGS
|
struct RANGEBAR_SETTINGS
|
||||||
{
|
{
|
||||||
int barSizeInTicks;
|
double barSize;
|
||||||
ENUM_BOOL atrEnabled;
|
ENUM_BAR_SIZE_CALC_MODE barSizeCalcMode;
|
||||||
ENUM_TIMEFRAMES atrTimeFrame;
|
ENUM_TIMEFRAMES atrTimeFrame;
|
||||||
int atrPeriod;
|
int atrPeriod;
|
||||||
int atrPercentage;
|
int showNumberOfDays;
|
||||||
int showNumberOfDays;
|
datetime showFromDate;
|
||||||
ENUM_BOOL resetOpenOnNewTradingDay;
|
ENUM_BOOL resetOpenOnNewTradingDay;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -106,12 +110,11 @@ uint CRangeBarCustomChartSettigns::CustomChartSettingsFromFile(int file_handle)
|
|||||||
|
|
||||||
void CRangeBarCustomChartSettigns::SetCustomChartSettings()
|
void CRangeBarCustomChartSettigns::SetCustomChartSettings()
|
||||||
{
|
{
|
||||||
settings.barSizeInTicks = barSizeInTicks;
|
settings.barSize = InpBarSize;
|
||||||
|
settings.barSizeCalcMode = InpBarSizeCalcMode;
|
||||||
settings.atrEnabled = atrEnabled;
|
settings.showNumberOfDays = InpShowNumberOfDays;
|
||||||
settings.atrTimeFrame = atrTimeFrame;
|
settings.showFromDate = InpShowFromDate;
|
||||||
settings.atrPeriod = atrPeriod;
|
settings.atrTimeFrame = InpAtrTimeFrame;
|
||||||
settings.atrPercentage = atrPercentage;
|
settings.atrPeriod = InpAtrPeriod;
|
||||||
settings.showNumberOfDays = showNumberOfDays;
|
settings.resetOpenOnNewTradingDay = InpResetOpenOnNewTradingDay;
|
||||||
settings.resetOpenOnNewTradingDay = resetOpenOnNewTradingDay;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,18 @@
|
|||||||
#property copyright "Copyright 2018-2020, Level Up Software"
|
#property copyright "Copyright 2018-2021, Level Up Software"
|
||||||
#property link "http://www.az-invest.eu"
|
#property link "http://www.az-invest.eu"
|
||||||
|
|
||||||
#ifdef DEVELOPER_VERSION
|
#ifdef DEVELOPER_VERSION
|
||||||
#define RANGEBAR_INDICATOR_NAME "RangeBars\\RangeBarsOverlay300"
|
#define RANGEBAR_INDICATOR_NAME "RangeBars\\RangeBarsOverlay316"
|
||||||
#else
|
#else
|
||||||
#define RANGEBAR_INDICATOR_NAME "Market\\Range Bars Charting"
|
#ifdef RANGEBAR_LICENSE
|
||||||
|
#ifdef MQL5_MARKET_VERSION
|
||||||
|
#define RANGEBAR_INDICATOR_NAME "Market\\Range Bars Charting"
|
||||||
|
#else
|
||||||
|
#define RANGEBAR_INDICATOR_NAME "RangeBars"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define RANGEBAR_INDICATOR_NAME "Market\\Range Bars Charting"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define RANGEBAR_OPEN 00
|
#define RANGEBAR_OPEN 00
|
||||||
@@ -185,61 +193,58 @@ int RangeBars::Init()
|
|||||||
|
|
||||||
RANGEBAR_SETTINGS s = rangeBarSettings.GetCustomChartSettings();
|
RANGEBAR_SETTINGS s = rangeBarSettings.GetCustomChartSettings();
|
||||||
CHART_INDICATOR_SETTINGS cis = rangeBarSettings.GetChartIndicatorSettings();
|
CHART_INDICATOR_SETTINGS cis = rangeBarSettings.GetChartIndicatorSettings();
|
||||||
|
ALERT_INFO_SETTINGS als = rangeBarSettings.GetAlertInfoSettings();
|
||||||
|
|
||||||
rangeBarsHandle = iCustom(this.rangeBarsSymbol, _Period, RANGEBAR_INDICATOR_NAME,
|
rangeBarsHandle = iCustom(this.rangeBarsSymbol, _Period, RANGEBAR_INDICATOR_NAME,
|
||||||
s.barSizeInTicks,
|
s.barSize,
|
||||||
s.atrEnabled,
|
s.barSizeCalcMode,
|
||||||
//s.atrTimeFrame,
|
s.showNumberOfDays,
|
||||||
|
s.showFromDate,
|
||||||
|
"=",
|
||||||
|
s.atrTimeFrame,
|
||||||
s.atrPeriod,
|
s.atrPeriod,
|
||||||
s.atrPercentage,
|
"=",
|
||||||
s.showNumberOfDays, s.resetOpenOnNewTradingDay,
|
s.resetOpenOnNewTradingDay,
|
||||||
TradingSessionTime,
|
"=",
|
||||||
showPivots,
|
als.showPivots,
|
||||||
pivotPointCalculationType,
|
als.pivotPointCalculationType,
|
||||||
RColor,
|
"=",
|
||||||
PColor,
|
InpAlertMeWhen,
|
||||||
SColor,
|
InpAlertNotificationType,
|
||||||
PDHColor,
|
"=",
|
||||||
PDLColor,
|
|
||||||
PDCColor,
|
|
||||||
AlertMeWhen,
|
|
||||||
AlertNotificationType,
|
|
||||||
cis.MA1on,
|
|
||||||
cis.MA1lineType,
|
cis.MA1lineType,
|
||||||
cis.MA1period,
|
cis.MA1period,
|
||||||
cis.MA1method,
|
cis.MA1method,
|
||||||
cis.MA1applyTo,
|
cis.MA1applyTo,
|
||||||
cis.MA1shift,
|
cis.MA1shift,
|
||||||
cis.MA1priceLabel,
|
cis.MA1priceLabel,
|
||||||
cis.MA2on,
|
|
||||||
cis.MA2lineType,
|
cis.MA2lineType,
|
||||||
cis.MA2period,
|
cis.MA2period,
|
||||||
cis.MA2method,
|
cis.MA2method,
|
||||||
cis.MA2applyTo,
|
cis.MA2applyTo,
|
||||||
cis.MA2shift,
|
cis.MA2shift,
|
||||||
cis.MA2priceLabel,
|
cis.MA2priceLabel,
|
||||||
cis.MA3on,
|
|
||||||
cis.MA3lineType,
|
cis.MA3lineType,
|
||||||
cis.MA3period,
|
cis.MA3period,
|
||||||
cis.MA3method,
|
cis.MA3method,
|
||||||
cis.MA3applyTo,
|
cis.MA3applyTo,
|
||||||
cis.MA3shift,
|
cis.MA3shift,
|
||||||
cis.MA3priceLabel,
|
cis.MA3priceLabel,
|
||||||
cis.MA4on,
|
|
||||||
cis.MA4lineType,
|
cis.MA4lineType,
|
||||||
cis.MA4period,
|
cis.MA4period,
|
||||||
cis.MA4method,
|
cis.MA4method,
|
||||||
cis.MA4applyTo,
|
cis.MA4applyTo,
|
||||||
cis.MA4shift,
|
cis.MA4shift,
|
||||||
cis.MA4priceLabel,
|
cis.MA4priceLabel,
|
||||||
|
"=",
|
||||||
cis.ShowChannel,
|
cis.ShowChannel,
|
||||||
cis.ChannelPeriod,
|
cis.ChannelPeriod,
|
||||||
cis.ChannelAtrPeriod,
|
cis.ChannelAtrPeriod,
|
||||||
cis.ChannelAppliedPrice,
|
cis.ChannelAppliedPrice,
|
||||||
cis.ChannelMultiplier,
|
cis.ChannelMultiplier,
|
||||||
cis.ChannelBandsDeviations,
|
cis.ChannelBandsDeviations,
|
||||||
cis.ChannelPriceLabel,
|
cis.ChannelPriceLabels,
|
||||||
cis.ChannelMidPriceLabel,
|
"=",
|
||||||
true); // used in EA
|
true); // used in EA
|
||||||
// TopBottomPaddingPercentage,
|
// TopBottomPaddingPercentage,
|
||||||
// showCurrentBarOpenTime,
|
// showCurrentBarOpenTime,
|
||||||
|
|||||||
@@ -0,0 +1,193 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2018-2021, Artur Zas
|
||||||
|
// GNU General Public License v3.0 -> https://github.com/9nix6/Median-and-Turbo-Renko-indicator-bundle/blob/master/LICENSE
|
||||||
|
// https://www.az-invest.eu
|
||||||
|
// https://www.mql5.com/en/users/arturz
|
||||||
|
//
|
||||||
|
|
||||||
|
class CTimeControl
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
int scheduleID;
|
||||||
|
|
||||||
|
int startHH;
|
||||||
|
int startMM;
|
||||||
|
string start;
|
||||||
|
datetime startOfSession;
|
||||||
|
|
||||||
|
int endHH;
|
||||||
|
int endMM;
|
||||||
|
string end;
|
||||||
|
datetime endOfSession;
|
||||||
|
|
||||||
|
bool scheduleEnabled;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CTimeControl(int id = 0) { scheduleID = id; };
|
||||||
|
|
||||||
|
void SetValidTraingHours(string _from = "0:00", string _to = "0:00");
|
||||||
|
void SetValidTraingHours(bool _unused, string _timeSpan = "0:00-0:00");
|
||||||
|
bool IsTradingTimeValid();
|
||||||
|
bool IsScheduleEnabled() { return scheduleEnabled; };
|
||||||
|
void UpdateSessionDateTime(int addSecods = 0);
|
||||||
|
datetime GetSessionStartTime() { return startOfSession; };
|
||||||
|
datetime GetSessionEndTime() { return endOfSession; };
|
||||||
|
void MoveSessionStartToNow();
|
||||||
|
string ToString();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void StringToHHMM(string value, int &HH, int &MM);
|
||||||
|
bool StringToHHMMRange(string value, int &startHH, int &startMM, string& _start, int &endHH, int &endMM, string& _end);
|
||||||
|
void SetScheduleState();
|
||||||
|
};
|
||||||
|
|
||||||
|
void CTimeControl::SetValidTraingHours(string _from, string _to)
|
||||||
|
{
|
||||||
|
this.start = _from;
|
||||||
|
this.end = _to;
|
||||||
|
|
||||||
|
StringToHHMM(this.start, this.startHH, this.startMM);
|
||||||
|
StringToHHMM(this.end, this.endHH, this.endMM);
|
||||||
|
UpdateSessionDateTime();
|
||||||
|
|
||||||
|
SetScheduleState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTimeControl::MoveSessionStartToNow()
|
||||||
|
{
|
||||||
|
datetime now = TimeCurrent();
|
||||||
|
|
||||||
|
MqlDateTime temp;
|
||||||
|
TimeToStruct(now,temp);
|
||||||
|
|
||||||
|
startHH = temp.hour;
|
||||||
|
startMM = temp.min;
|
||||||
|
start = StringFormat("%02d:%02d", startHH, startMM);
|
||||||
|
|
||||||
|
UpdateSessionDateTime(temp.sec + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTimeControl::UpdateSessionDateTime(int addSecods = 0)
|
||||||
|
{
|
||||||
|
datetime now = TimeCurrent();
|
||||||
|
|
||||||
|
MqlDateTime temp;
|
||||||
|
TimeToStruct(now,temp);
|
||||||
|
|
||||||
|
if(addSecods > 0)
|
||||||
|
{
|
||||||
|
string startTimeTemp = StringFormat("%s:%02d", this.start, addSecods);
|
||||||
|
startOfSession = StringToTime((string)temp.year+"."+(string)temp.mon+"."+(string)temp.day+" "+startTimeTemp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startOfSession = StringToTime((string)temp.year+"."+(string)temp.mon+"."+(string)temp.day+" "+this.start);
|
||||||
|
}
|
||||||
|
|
||||||
|
endOfSession = StringToTime((string)temp.year+"."+(string)temp.mon+"."+(string)temp.day+" "+this.end);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTimeControl::SetValidTraingHours(bool _unused, string _timeSpan = "0:00-0:00")
|
||||||
|
{
|
||||||
|
if(!StringToHHMMRange(_timeSpan, this.startHH, this.startMM, this.start, this.endHH, this.endMM, this.end))
|
||||||
|
return;
|
||||||
|
|
||||||
|
UpdateSessionDateTime();
|
||||||
|
SetScheduleState();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTimeControl::IsTradingTimeValid()
|
||||||
|
{
|
||||||
|
if(scheduleEnabled == false)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
datetime now = TimeCurrent();
|
||||||
|
|
||||||
|
MqlDateTime temp;
|
||||||
|
TimeToStruct(now,temp);
|
||||||
|
|
||||||
|
datetime _start = StringToTime((string)temp.year+"."+(string)temp.mon+"."+(string)temp.day+" "+this.start);
|
||||||
|
datetime _end = StringToTime((string)temp.year+"."+(string)temp.mon+"."+(string)temp.day+" "+this.end);
|
||||||
|
|
||||||
|
if(_start <= now && now <= _end)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string CTimeControl::ToString()
|
||||||
|
{
|
||||||
|
string tradingScheduleName = "Trading schedule ";
|
||||||
|
|
||||||
|
tradingScheduleName += (scheduleID != 0)
|
||||||
|
? (string)scheduleID+" "
|
||||||
|
: "";
|
||||||
|
|
||||||
|
if(IsScheduleEnabled())
|
||||||
|
{
|
||||||
|
return tradingScheduleName+"ON ("+this.start+" to "+this.end+") | trading "+(IsTradingTimeValid()
|
||||||
|
? "enabled"
|
||||||
|
: "disabled");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return tradingScheduleName+"NOT USED";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTimeControl::StringToHHMM(string value, int &HH, int &MM)
|
||||||
|
{
|
||||||
|
MqlDateTime temp;
|
||||||
|
TimeToStruct(TimeCurrent(),temp);
|
||||||
|
|
||||||
|
datetime fullDateTime = StringToTime((string)temp.year+"."+(string)temp.mon+"."+(string)temp.day+" "+value);
|
||||||
|
TimeToStruct(fullDateTime,temp);
|
||||||
|
|
||||||
|
HH = temp.hour;
|
||||||
|
MM = temp.min;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTimeControl::StringToHHMMRange(string value, int &_startHH, int &_startMM, string& _start, int &_endHH, int &_endMM, string& _end)
|
||||||
|
{
|
||||||
|
string result[];
|
||||||
|
int count = StringSplit(value, '-', result);
|
||||||
|
if(count != 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MqlDateTime temp;
|
||||||
|
TimeToStruct(TimeCurrent(),temp);
|
||||||
|
|
||||||
|
// Start time
|
||||||
|
_start = result[0];
|
||||||
|
datetime fullDateTime = StringToTime((string)temp.year+"."+(string)temp.mon+"."+(string)temp.day+" "+_start);
|
||||||
|
TimeToStruct(fullDateTime,temp);
|
||||||
|
|
||||||
|
startHH = temp.hour;
|
||||||
|
startMM = temp.min;
|
||||||
|
|
||||||
|
// End time
|
||||||
|
TimeToStruct(TimeCurrent(),temp);
|
||||||
|
_end = result[1];
|
||||||
|
fullDateTime = StringToTime((string)temp.year+"."+(string)temp.mon+"."+(string)temp.day+" "+_end);
|
||||||
|
TimeToStruct(fullDateTime,temp);
|
||||||
|
|
||||||
|
endHH = temp.hour;
|
||||||
|
endMM = temp.min;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTimeControl::SetScheduleState()
|
||||||
|
{
|
||||||
|
if(this.startHH == 0 && this.startMM == 0 && this.endHH == 0 && this.endMM == 0)
|
||||||
|
{
|
||||||
|
scheduleEnabled = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scheduleEnabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
//
|
//
|
||||||
// Copyright 2017-2018, Artur Zas
|
// Copyright 2017-2021, Artur Zas
|
||||||
|
// GNU General Public License v3.0 -> https://github.com/9nix6/Median-and-Turbo-Renko-indicator-bundle/blob/master/LICENSE
|
||||||
// https://www.az-invest.eu
|
// https://www.az-invest.eu
|
||||||
// https://www.mql5.com/en/users/arturz
|
// https://www.mql5.com/en/users/arturz
|
||||||
//
|
//
|
||||||
@@ -732,8 +733,26 @@ bool CMarketOrder::ClosePartial(ulong ticket, double lots)
|
|||||||
|
|
||||||
while(!IsStopped() && !result)
|
while(!IsStopped() && !result)
|
||||||
{
|
{
|
||||||
result = ctrade.PositionClosePartial(ticket, NormalizeLots(symbol,lots));
|
if(_IsNettingAccount()) // Netting account type
|
||||||
|
{
|
||||||
|
// open opposite position with volume = "lots" to do a parial close
|
||||||
|
|
||||||
|
ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
|
||||||
|
|
||||||
|
if(type == POSITION_TYPE_BUY)
|
||||||
|
{
|
||||||
|
result = this.Short(symbol,lots,0,0);
|
||||||
|
}
|
||||||
|
else if(type == POSITION_TYPE_SELL)
|
||||||
|
{
|
||||||
|
result = this.Long(symbol,lots,0,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // Hedging account type
|
||||||
|
{
|
||||||
|
result = ctrade.PositionClosePartial(ticket, lots);
|
||||||
|
}
|
||||||
|
|
||||||
if(result)
|
if(result)
|
||||||
{
|
{
|
||||||
Sleep(500);
|
Sleep(500);
|
||||||
@@ -1072,5 +1091,3 @@ void CMarketOrder::SetTradeId(ulong tradeId)
|
|||||||
ctrade.SetExpertMagicNumber(tradeId);
|
ctrade.SetExpertMagicNumber(tradeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,267 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2018-2021, Artur Zas
|
||||||
|
// GNU General Public License v3.0 -> https://github.com/9nix6/Median-and-Turbo-Renko-indicator-bundle/blob/master/LICENSE
|
||||||
|
// https://www.az-invest.eu
|
||||||
|
// https://www.mql5.com/en/users/arturz
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <AZ-INVEST/SDK/TradeFunctions.mqh>
|
||||||
|
|
||||||
|
class CTradeManagerState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
void Clear() { DoneBreakEven = false; TrailStarted = false; DonePartialClose = false; };
|
||||||
|
|
||||||
|
// Break Even
|
||||||
|
bool DoneBreakEven;
|
||||||
|
|
||||||
|
// Trailing Stop
|
||||||
|
bool TrailStarted;
|
||||||
|
|
||||||
|
// Partial Close
|
||||||
|
bool DonePartialClose;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CTradeManagerParameters
|
||||||
|
{
|
||||||
|
// Break Even
|
||||||
|
int BEPoints;
|
||||||
|
|
||||||
|
// Trailing Stop
|
||||||
|
int TrailByPoints;
|
||||||
|
int TrailStartPoints;
|
||||||
|
|
||||||
|
// Partial Close
|
||||||
|
int PartialCloseAtProfitPoints;
|
||||||
|
int PartialClosePercentage;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CTradeManager
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool initialized;
|
||||||
|
CMarketOrder *orderHandler;
|
||||||
|
CTradeManagerParameters inputs;
|
||||||
|
|
||||||
|
ENUM_ORDER_TYPE __type;
|
||||||
|
double __open;
|
||||||
|
double __lots;
|
||||||
|
string __symbol;
|
||||||
|
double __tp;
|
||||||
|
double __sl;
|
||||||
|
double __bid;
|
||||||
|
double __ask;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CTradeManager();
|
||||||
|
CTradeManager(CTradeManagerParameters ¶ms, CMarketOrder *orderHalder);
|
||||||
|
~CTradeManager();
|
||||||
|
|
||||||
|
bool IsInitialized() { return this.initialized; };
|
||||||
|
bool Initialize(CTradeManagerParameters ¶ms, CMarketOrder *orderHalder);
|
||||||
|
bool Manage(ulong ticket, CTradeManagerState &_state);
|
||||||
|
string ToString();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool GetTradeInfo(ulong ticket);
|
||||||
|
bool BreakEven(ulong ticket);
|
||||||
|
bool OkToTrailTheStop(ulong ticket);
|
||||||
|
bool TrailTheStop(ulong ticket);
|
||||||
|
bool PartialClose(ulong ticket, double lots);
|
||||||
|
double GetPartialCloseLotSize();
|
||||||
|
bool IsDistanceFromOpenReached(double distancePriceDiff);
|
||||||
|
ENUM_ORDER_TYPE GetType(ulong ticket);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CTradeManager::CTradeManager(void)
|
||||||
|
{
|
||||||
|
this.orderHandler = NULL;
|
||||||
|
this.initialized = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CTradeManager::CTradeManager(CTradeManagerParameters ¶ms,CMarketOrder *_orderHandler)
|
||||||
|
{
|
||||||
|
this.orderHandler = NULL;
|
||||||
|
this.initialized = false;
|
||||||
|
Initialize(params, _orderHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
CTradeManager::~CTradeManager(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTradeManager::GetTradeInfo(ulong ticket)
|
||||||
|
{
|
||||||
|
__type = GetType(ticket);
|
||||||
|
__open = PositionGetDouble(POSITION_PRICE_OPEN);
|
||||||
|
if(__open == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
__lots = PositionGetDouble(POSITION_VOLUME);
|
||||||
|
__symbol = PositionGetString(POSITION_SYMBOL);
|
||||||
|
__tp = PositionGetDouble(POSITION_TP);
|
||||||
|
__sl = PositionGetDouble(POSITION_SL);
|
||||||
|
__bid = SymbolInfoDouble(__symbol,SYMBOL_BID);
|
||||||
|
__ask = SymbolInfoDouble(__symbol,SYMBOL_ASK);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTradeManager::Initialize(CTradeManagerParameters ¶ms, CMarketOrder *_orderHandler)
|
||||||
|
{
|
||||||
|
// Dependency injection
|
||||||
|
this.orderHandler = _orderHandler;
|
||||||
|
if(this.orderHandler == NULL)
|
||||||
|
{
|
||||||
|
Print(__FUNCTION__," failed on orderHandler == NULL");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
this.inputs = params;
|
||||||
|
|
||||||
|
// normalize inputs
|
||||||
|
this.inputs.PartialClosePercentage = MathMin(MathAbs(this.inputs.PartialClosePercentage), 100);
|
||||||
|
|
||||||
|
//
|
||||||
|
this.initialized = true;
|
||||||
|
return initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTradeManager::Manage(ulong ticket, CTradeManagerState &_state)
|
||||||
|
{
|
||||||
|
if(!GetTradeInfo(ticket))
|
||||||
|
return false; // trade info not available
|
||||||
|
|
||||||
|
if(!_state.DonePartialClose)
|
||||||
|
{
|
||||||
|
_state.DonePartialClose = PartialClose(ticket, GetPartialCloseLotSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_state.DoneBreakEven)
|
||||||
|
{
|
||||||
|
if(BreakEven(ticket))
|
||||||
|
_state.DoneBreakEven = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_state.TrailStarted)
|
||||||
|
{
|
||||||
|
_state.TrailStarted = OkToTrailTheStop(ticket);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_state.TrailStarted)
|
||||||
|
{
|
||||||
|
TrailTheStop(ticket);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTradeManager::PartialClose(ulong ticket, double lots)
|
||||||
|
{
|
||||||
|
if(this.inputs.PartialCloseAtProfitPoints == 0 || lots == 0)
|
||||||
|
return false; // nothing to do
|
||||||
|
|
||||||
|
double _partialCloseDistance = SymbolInfoDouble(__symbol,SYMBOL_POINT) * this.inputs.PartialCloseAtProfitPoints;
|
||||||
|
if(!IsDistanceFromOpenReached(_partialCloseDistance))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return orderHandler.ClosePartial(ticket, lots);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTradeManager::BreakEven(ulong ticket)
|
||||||
|
{
|
||||||
|
if(this.inputs.BEPoints == 0)
|
||||||
|
return false; // nothing to do
|
||||||
|
|
||||||
|
double _beDistance = SymbolInfoDouble(__symbol,SYMBOL_POINT) * this.inputs.BEPoints;
|
||||||
|
if(!IsDistanceFromOpenReached(_beDistance))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return orderHandler.Modify(ticket,__open,__tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTradeManager::OkToTrailTheStop(ulong ticket)
|
||||||
|
{
|
||||||
|
if(this.inputs.TrailByPoints == 0)
|
||||||
|
return false; // nothing to do
|
||||||
|
|
||||||
|
double _startDistance = SymbolInfoDouble(__symbol,SYMBOL_POINT) * this.inputs.TrailStartPoints;
|
||||||
|
if(!IsDistanceFromOpenReached(_startDistance))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTradeManager::TrailTheStop(ulong ticket)
|
||||||
|
{
|
||||||
|
if(this.inputs.TrailByPoints == 0)
|
||||||
|
return false; // nothing to do
|
||||||
|
|
||||||
|
double _trailDistance = SymbolInfoDouble(__symbol,SYMBOL_POINT) * this.inputs.TrailByPoints;
|
||||||
|
double _sl = __sl;
|
||||||
|
bool okToModify = false;
|
||||||
|
|
||||||
|
if(__type == ORDER_TYPE_BUY)
|
||||||
|
{
|
||||||
|
_sl = (__bid - _trailDistance);
|
||||||
|
if(_sl > __sl)
|
||||||
|
okToModify = true;
|
||||||
|
}
|
||||||
|
else if(__type == ORDER_TYPE_SELL)
|
||||||
|
{
|
||||||
|
_sl = (__ask + _trailDistance);
|
||||||
|
if(_sl < __sl)
|
||||||
|
okToModify = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(okToModify)
|
||||||
|
return orderHandler.Modify(ticket,_sl,__tp);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ENUM_ORDER_TYPE CTradeManager::GetType(ulong ticket)
|
||||||
|
{
|
||||||
|
ENUM_POSITION_TYPE _pType;
|
||||||
|
orderHandler.GetPositionType(ticket,_pType);
|
||||||
|
|
||||||
|
return orderHandler.TradeBias((ENUM_ORDER_TYPE)_pType);
|
||||||
|
}
|
||||||
|
|
||||||
|
double CTradeManager::GetPartialCloseLotSize()
|
||||||
|
{
|
||||||
|
double lotsToClose = (__lots * inputs.PartialClosePercentage) / 100;
|
||||||
|
return NormalizeLots(__symbol, lotsToClose);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CTradeManager::IsDistanceFromOpenReached(double distancePriceDiff)
|
||||||
|
{
|
||||||
|
if(__type == ORDER_TYPE_BUY)
|
||||||
|
{
|
||||||
|
if((__bid - distancePriceDiff) >= __open)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(__type == ORDER_TYPE_SELL)
|
||||||
|
{
|
||||||
|
if((__ask + distancePriceDiff) <= __open)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string CTradeManager::ToString()
|
||||||
|
{
|
||||||
|
string _be = (inputs.BEPoints > 0) ? "[BE ON] " : "[BE off] ";
|
||||||
|
string _trail = (inputs.TrailByPoints > 0) ? "[Trail ON] ": "[Trail off] ";
|
||||||
|
string _partial = (inputs.PartialCloseAtProfitPoints > 0) ? "[Partial "+(string)inputs.PartialClosePercentage+"%] ": "[Partial off] ";
|
||||||
|
|
||||||
|
return _be+_trail+_partial;
|
||||||
|
}
|
||||||
@@ -0,0 +1,235 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| CADXOnRingBuffer.mqh |
|
||||||
|
//| Copyright 2012, Konstantin Gruzdev |
|
||||||
|
//| https://login.mql5.com/ru/users/Lizar |
|
||||||
|
//| Revision 01 Dec 2012 |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "Copyright 2012, Konstantin Gruzdev"
|
||||||
|
#property link "https://login.mql5.com/ru/users/Lizar"
|
||||||
|
|
||||||
|
//--- Class to calculate the MA using the ring buffer:
|
||||||
|
#include <IncOnRingBuffer\CMAOnRingBuffer.mqh>
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Class CADXOnRingBuffer |
|
||||||
|
//| Appointment: class is designed for the calculation of the |
|
||||||
|
//| ADX indicator (Average Directional Movement Index, |
|
||||||
|
//| ADX) using the class for working with the ring |
|
||||||
|
//| buffer. |
|
||||||
|
//| Link: http://www.mql5.com/ru/code/1343 |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
class CADXOnRingBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CMAOnRingBuffer pdi; // positive directional index
|
||||||
|
CMAOnRingBuffer ndi; // negative directional index
|
||||||
|
private:
|
||||||
|
CMAOnRingBuffer m_adx; // average directional movement index
|
||||||
|
string m_name; // indicator name
|
||||||
|
bool m_as_series; // true, if the indexing as in time series
|
||||||
|
int m_bars_required; // number of elements required to calculate
|
||||||
|
int m_begin; // index of the first significant element
|
||||||
|
int m_start; // index of element to start the calculation
|
||||||
|
int m_index; // current element index
|
||||||
|
|
||||||
|
double m_high; // maximal value
|
||||||
|
double m_low; // minimal value
|
||||||
|
double m_close; // closing price
|
||||||
|
double m_phigh; // maximum value of the previous bar
|
||||||
|
double m_plow; // minimum value of the previous bar
|
||||||
|
double m_pclose; // closing price of the previous bar
|
||||||
|
|
||||||
|
double m_PD;
|
||||||
|
double m_ND;
|
||||||
|
public:
|
||||||
|
CADXOnRingBuffer() {}
|
||||||
|
~CADXOnRingBuffer() {}
|
||||||
|
//--- initialization method:
|
||||||
|
bool Init(int ma_period=14,
|
||||||
|
ENUM_MA_METHOD ma_method=MODE_EMA,
|
||||||
|
int size_buffer=256,
|
||||||
|
bool as_series=false);
|
||||||
|
//--- basic methods:
|
||||||
|
int MainOnArray(const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const double &high[],
|
||||||
|
const double &low[],
|
||||||
|
const double &close[]);
|
||||||
|
double MainOnValue(const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const int begin,
|
||||||
|
const double high,
|
||||||
|
const double low,
|
||||||
|
const double close,
|
||||||
|
const int index);
|
||||||
|
//--- methods to get access to private data:
|
||||||
|
int BarsRequired() { return(m_bars_required); }
|
||||||
|
string NameADX() { return("ADX"+m_name); }
|
||||||
|
string NameNDI() { return("-DI"+m_name); }
|
||||||
|
string NamePDI() { return("+DI"+m_name); }
|
||||||
|
string MAMethod() { return(m_adx.MAMethod()); }
|
||||||
|
int MAPeriod() { return(m_adx.MAPeriod()); }
|
||||||
|
int Size() { return(m_adx.Size()); }
|
||||||
|
//--- returns the value of element with the specified index:
|
||||||
|
double operator [](const int index) const { return(m_adx.At(index)); }
|
||||||
|
private:
|
||||||
|
//--- indicator calculation method:
|
||||||
|
void ADX(const int rates_total, const int prev_calculated);
|
||||||
|
};
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Initialization method |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool CADXOnRingBuffer :: Init(int ma_period=14,ENUM_MA_METHOD ma_method=MODE_EMA, int size_buffer=256, bool as_series=false)
|
||||||
|
{
|
||||||
|
//--- initialize the CMAOnRingBuffer class instances:
|
||||||
|
if(!pdi.Init(ma_period,ma_method,size_buffer)) return false;
|
||||||
|
if(!ndi.Init(ma_period,ma_method,size_buffer)) return false;
|
||||||
|
if(!m_adx.Init(ma_period,ma_method,size_buffer)) return false;
|
||||||
|
//---
|
||||||
|
m_name="("+IntegerToString(ma_period)+","+MAMethod()+")";
|
||||||
|
//---
|
||||||
|
m_as_series=as_series;
|
||||||
|
m_bars_required=m_adx.BarsRequired()+1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Indicator on array |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int CADXOnRingBuffer :: MainOnArray(const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const double &high[],
|
||||||
|
const double &low[],
|
||||||
|
const double &close[])
|
||||||
|
{
|
||||||
|
//--- save as_series flags:
|
||||||
|
bool as_series_high = ArrayGetAsSeries(high);
|
||||||
|
bool as_series_low = ArrayGetAsSeries(low);
|
||||||
|
bool as_series_close = ArrayGetAsSeries(close);
|
||||||
|
if(as_series_high) ArraySetAsSeries(high, false);
|
||||||
|
if(as_series_low) ArraySetAsSeries(low, false);
|
||||||
|
if(as_series_close) ArraySetAsSeries(close,false);
|
||||||
|
//--- first calculation:
|
||||||
|
if(prev_calculated==0)
|
||||||
|
{
|
||||||
|
for(int i=0;i<rates_total;i++)
|
||||||
|
{
|
||||||
|
if(high[i]!=0 && high[i] != EMPTY_VALUE &&
|
||||||
|
low[i]!=0 && low[i] != EMPTY_VALUE &&
|
||||||
|
close[i]!=0 && close[i]!= EMPTY_VALUE)
|
||||||
|
{
|
||||||
|
m_start=MathMax(i+1,rates_total-Size()-m_bars_required);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_begin=m_start;
|
||||||
|
}
|
||||||
|
//--- number of bars was changed:
|
||||||
|
else m_start=prev_calculated-1;
|
||||||
|
//--- main loop:
|
||||||
|
for(m_index=m_start;m_index<rates_total;m_index++)
|
||||||
|
{
|
||||||
|
//--- fill main positive and main negative buffers:
|
||||||
|
m_phigh = high [m_index-1];
|
||||||
|
m_plow = low [m_index-1];
|
||||||
|
m_pclose = close[m_index-1];
|
||||||
|
m_high = high [m_index];
|
||||||
|
m_low = low [m_index];
|
||||||
|
//--- calculation of the average directional movement index:
|
||||||
|
ADX(rates_total,prev_calculated);
|
||||||
|
}
|
||||||
|
//--- restore as_series flags
|
||||||
|
if(as_series_high) ArraySetAsSeries(high, true);
|
||||||
|
if(as_series_low) ArraySetAsSeries(low, true);
|
||||||
|
if(as_series_close) ArraySetAsSeries(close,true);
|
||||||
|
//--- return value of prev_calculated for next call:
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Indicator on value |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
double CADXOnRingBuffer:: MainOnValue(const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const int begin,
|
||||||
|
const double high,
|
||||||
|
const double low,
|
||||||
|
const double close,
|
||||||
|
const int index)
|
||||||
|
{
|
||||||
|
//--- check as_series flags:
|
||||||
|
if(m_as_series) m_index=rates_total-1-index;
|
||||||
|
else m_index=index;
|
||||||
|
//--- check begin:
|
||||||
|
if(m_index<begin) return(EMPTY_VALUE);
|
||||||
|
//--- initial calculation:
|
||||||
|
if(m_index==begin)
|
||||||
|
{
|
||||||
|
m_high=high;
|
||||||
|
m_low=low;
|
||||||
|
m_close=close;
|
||||||
|
m_begin=begin+1;
|
||||||
|
return(EMPTY_VALUE);
|
||||||
|
}
|
||||||
|
//--- remember the prices:
|
||||||
|
if(prev_calculated-1!=m_index)
|
||||||
|
{
|
||||||
|
m_phigh = m_high;
|
||||||
|
m_plow = m_low;
|
||||||
|
m_pclose = m_close;
|
||||||
|
}
|
||||||
|
m_high = high;
|
||||||
|
m_low = low;
|
||||||
|
m_close = close;
|
||||||
|
//--- calculation of the average directional movement index:
|
||||||
|
ADX(rates_total,prev_calculated);
|
||||||
|
//--- result:
|
||||||
|
return(m_adx.Last());
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Average directional movement index |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CADXOnRingBuffer:: ADX(const int rates_total, const int prev_calculated)
|
||||||
|
{
|
||||||
|
//--- fill main positive and main negative buffers
|
||||||
|
double dTmpP=m_high-m_phigh;
|
||||||
|
double dTmpN=m_plow-m_low;
|
||||||
|
if(dTmpP<0.0) dTmpP=0.0;
|
||||||
|
if(dTmpN<0.0) dTmpN=0.0;
|
||||||
|
if(dTmpP>dTmpN) dTmpN=0.0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(dTmpP<dTmpN) dTmpP=0.0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dTmpP=0.0;
|
||||||
|
dTmpN=0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--- define TR
|
||||||
|
double tr=MathMax(MathMax(MathAbs(m_high-m_low),MathAbs(m_high-m_pclose)),MathAbs(m_low-m_pclose));
|
||||||
|
//---
|
||||||
|
if(tr!=0.0)
|
||||||
|
{
|
||||||
|
m_PD=100.0*dTmpP/tr;
|
||||||
|
m_ND=100.0*dTmpN/tr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_PD=0.0;
|
||||||
|
m_ND=0.0;
|
||||||
|
}
|
||||||
|
//--- main calculation:
|
||||||
|
//--- fill smoothed positive and negative buffers
|
||||||
|
pdi.MainOnValue(rates_total,prev_calculated,m_begin,m_PD,m_index);
|
||||||
|
ndi.MainOnValue(rates_total,prev_calculated,m_begin,m_ND,m_index);
|
||||||
|
//--- fill ADXTmp buffer
|
||||||
|
double dTmp=pdi.Last()+ndi.Last();
|
||||||
|
if(dTmp!=0.0)
|
||||||
|
dTmp=100.0*MathAbs((pdi.Last()-ndi.Last())/dTmp);
|
||||||
|
else
|
||||||
|
dTmp=0.0;
|
||||||
|
//--- fill smoothed ADX buffer
|
||||||
|
m_adx.MainOnValue(rates_total,prev_calculated,m_begin,dTmp,m_index);
|
||||||
|
}
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| CArrayRing.mqh |
|
||||||
|
//| Copyright 2012, Konstantin Gruzdev |
|
||||||
|
//| https://login.mql5.com/ru/users/Lizar |
|
||||||
|
//| Revision 03 Dec 2012 |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "Copyright 2012, Konstantin Gruzdev"
|
||||||
|
#property link "https://login.mql5.com/ru/users/Lizar"
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Class CArrayRing |
|
||||||
|
//| Appointment: class is designed to work with tne finite ring |
|
||||||
|
//| buffers of data. When the buffer is crowded the oldest |
|
||||||
|
//| buffer element is replaced by the newest element. Herewith, |
|
||||||
|
//| the specified number of end elements are always |
|
||||||
|
//| available. |
|
||||||
|
//| Link: http://www.mql5.com/ru/code/1340 |
|
||||||
|
//| Remark: it should also be kept in mind that the element indexing |
|
||||||
|
//| in the ring buffer is executed as in timeseries. |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
class CArrayRing
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double m_data[]; // ring buffer of data
|
||||||
|
int m_size; // buffer size
|
||||||
|
int m_last_pos; // last buffer element position
|
||||||
|
double m_filling; // value, which used for the array filling
|
||||||
|
|
||||||
|
public:
|
||||||
|
CArrayRing();
|
||||||
|
~CArrayRing() { ArrayFree(m_data); }
|
||||||
|
//--- buffer initialization method:
|
||||||
|
bool Init(int size, double volue=EMPTY_VALUE);
|
||||||
|
//--- method returns the buffer size:
|
||||||
|
int Size() { return m_size-1; }
|
||||||
|
//--- method changes the ring buffer size:
|
||||||
|
bool Resize(const int size);
|
||||||
|
//--- method of adding a new element to the buffer:
|
||||||
|
void Add(const double element);
|
||||||
|
//--- method returns the value of element with the specified index:
|
||||||
|
double At(const int index) const;
|
||||||
|
double operator [](const int index) const { return(At(index)); }
|
||||||
|
//--- method returns the value of the last element stored in the buffer:
|
||||||
|
double Last() const { return(m_data[m_last_pos]); }
|
||||||
|
//--- method overwrites the value of the last element in the buffer:
|
||||||
|
void Last(const double element) { m_data[m_last_pos]=element; }
|
||||||
|
//--- method overwrites the value of element with the specified index:
|
||||||
|
bool Update(const double element,const int index=0);
|
||||||
|
};
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Constructor. |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
CArrayRing::CArrayRing()
|
||||||
|
{
|
||||||
|
m_last_pos=0; // last element position
|
||||||
|
m_filling=EMPTY_VALUE; // value for buffer filling
|
||||||
|
m_size=ArraySize(m_data); // get size of the ring buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Buffer initialization method. |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool CArrayRing::Init(int size, double volue=EMPTY_VALUE)
|
||||||
|
{
|
||||||
|
m_last_pos=0; // last element position
|
||||||
|
m_filling=volue; // value for buffer filling
|
||||||
|
m_size=ArraySize(m_data); // get size of the buffer
|
||||||
|
bool result=Resize(size); // create a buffer with the desired size
|
||||||
|
ArrayFill(m_data,0,m_size,m_filling); // fill the buffer with default values
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Set the new size of the array. |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool CArrayRing::Resize(const int new_size)
|
||||||
|
{
|
||||||
|
//--- check
|
||||||
|
if(new_size<0) return(false);
|
||||||
|
//--- increase array size:
|
||||||
|
if(new_size>m_size)
|
||||||
|
{
|
||||||
|
int set_size=ArrayResize(m_data,new_size);
|
||||||
|
if(set_size<0) return(false);
|
||||||
|
//--- copy elements to restore their order:
|
||||||
|
if(set_size>m_size)
|
||||||
|
{
|
||||||
|
for(int i=m_size-1,j=set_size-1;i>m_last_pos;i--,j--)
|
||||||
|
{
|
||||||
|
m_data[j]=m_data[i];
|
||||||
|
m_data[i]=m_filling;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_size=set_size;
|
||||||
|
//--- result:
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
//--- reduce array size:
|
||||||
|
//--- prepare array to reduce the size:
|
||||||
|
if(new_size>m_last_pos+1)
|
||||||
|
for(int i=m_size-1,j=new_size-1;j>m_last_pos;i--,j--) m_data[j]=m_data[i];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(int i=m_last_pos+1-new_size,j=0;i<=m_last_pos;i++,j++) m_data[j]=m_data[i];
|
||||||
|
m_last_pos=new_size-1;
|
||||||
|
}
|
||||||
|
//--- reduce the size:
|
||||||
|
m_size=new_size;
|
||||||
|
ArrayResize(m_data,new_size);
|
||||||
|
//--- result:
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Adding a new element to the buffer. |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CArrayRing::Add(const double element)
|
||||||
|
{
|
||||||
|
m_last_pos=++m_last_pos%m_size;
|
||||||
|
m_data[m_last_pos]=element;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Gets the element at the specified index. |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
double CArrayRing::At(const int index) const
|
||||||
|
{
|
||||||
|
//--- check the index correctness:
|
||||||
|
if((index/m_size)==0)
|
||||||
|
//--- return the value of element with the specified index:
|
||||||
|
return(m_data[(m_size+m_last_pos-index)%m_size]);
|
||||||
|
//--- if the index is wrong:
|
||||||
|
return(DBL_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Update the element at the specified position in the array. |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool CArrayRing::Update(const double element,const int index=0)
|
||||||
|
{
|
||||||
|
//--- check the index correctness:
|
||||||
|
if((index/m_size)==0)
|
||||||
|
{
|
||||||
|
//--- update
|
||||||
|
m_data[(m_size+m_last_pos-index)%m_size]=element;
|
||||||
|
//--- successful
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
//--- if the index is wrong:
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| CATROnRingBuffer.mqh |
|
||||||
|
//| Copyright 2012, Konstantin Gruzdev |
|
||||||
|
//| https://login.mql5.com/ru/users/Lizar |
|
||||||
|
//| Revision 01 Dec 2012 |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "Copyright 2012, Konstantin Gruzdev"
|
||||||
|
#property link "https://login.mql5.com/ru/users/Lizar"
|
||||||
|
|
||||||
|
//--- Class to calculate the MA using the ring buffer:
|
||||||
|
#include <IncOnRingBuffer\CMAOnRingBuffer.mqh>
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Class CATROnRingBuffer |
|
||||||
|
//| Appointment: class is designed for the calculation of the |
|
||||||
|
//| technical indicator Average True Range (Average |
|
||||||
|
//| True Range, ATR) using the class for working with |
|
||||||
|
//| the ring buffer. |
|
||||||
|
//| Link: http://www.mql5.com/ru/code/1344 |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
class CATROnRingBuffer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
CMAOnRingBuffer m_ma; // instance the class for MA calculation
|
||||||
|
double m_tr; // true range
|
||||||
|
double m_atr; // average true range
|
||||||
|
string m_name; // indicator name
|
||||||
|
bool m_as_series; // true, if the indexing as in time series
|
||||||
|
int m_bars_required; // number of elements required to calculate
|
||||||
|
int m_begin; // index of the first significant element
|
||||||
|
int m_start; // index of element to start the calculation
|
||||||
|
int m_index; // current element index
|
||||||
|
double m_close; // closing price of the current bar
|
||||||
|
double m_prev_close; // closing price of the previous bar
|
||||||
|
public:
|
||||||
|
CATROnRingBuffer() {}
|
||||||
|
~CATROnRingBuffer() {}
|
||||||
|
//--- initialization method:
|
||||||
|
bool Init(int ma_period=14,ENUM_MA_METHOD ma_method=MODE_SMA, int size_buffer=256, bool as_series=false);
|
||||||
|
//--- basic methods:
|
||||||
|
int MainOnArray(const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const double &high[],
|
||||||
|
const double &low[],
|
||||||
|
const double &close[]);
|
||||||
|
double MainOnValue(const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const int begin,
|
||||||
|
const double high,
|
||||||
|
const double low,
|
||||||
|
const double close,
|
||||||
|
const int index);
|
||||||
|
//--- methods to get access to private data:
|
||||||
|
int BarsRequired() { return(m_bars_required); }
|
||||||
|
string Name() { return(m_name); }
|
||||||
|
string MAMethod() { return(m_ma.MAMethod()); }
|
||||||
|
int MAPeriod() { return(m_ma.MAPeriod()); }
|
||||||
|
int Size() { return(m_ma.Size()); }
|
||||||
|
//--- returns the value of element with the specified index:
|
||||||
|
double operator [](const int index) const { return(m_ma.At(index)); }
|
||||||
|
};
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Initialization method |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool CATROnRingBuffer :: Init(int ma_period=14,ENUM_MA_METHOD ma_method=MODE_SMA, int size_buffer=256, bool as_series=false)
|
||||||
|
{
|
||||||
|
//--- Initialization for MA:
|
||||||
|
if(!m_ma.Init(ma_period,ma_method,size_buffer)) return false;
|
||||||
|
//---
|
||||||
|
m_as_series=as_series;
|
||||||
|
m_bars_required=m_ma.BarsRequired()+1;
|
||||||
|
m_name="ATR("+IntegerToString(ma_period)+","+MAMethod()+")";
|
||||||
|
//---
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Indicator on array |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int CATROnRingBuffer :: MainOnArray(const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const double &high[],
|
||||||
|
const double &low[],
|
||||||
|
const double &close[])
|
||||||
|
{
|
||||||
|
//--- save as_series flags:
|
||||||
|
bool as_series_high = ArrayGetAsSeries(high);
|
||||||
|
bool as_series_low = ArrayGetAsSeries(low);
|
||||||
|
bool as_series_close = ArrayGetAsSeries(close);
|
||||||
|
if(as_series_high) ArraySetAsSeries(high, false);
|
||||||
|
if(as_series_low) ArraySetAsSeries(low, false);
|
||||||
|
if(as_series_close) ArraySetAsSeries(close,false);
|
||||||
|
//--- first calculation:
|
||||||
|
if(prev_calculated==0)
|
||||||
|
{
|
||||||
|
for(int i=0;i<rates_total;i++)
|
||||||
|
{
|
||||||
|
if(high[i]!=0 && high[i]!=EMPTY_VALUE &&
|
||||||
|
low[i]!=0 && low[i]!=EMPTY_VALUE &&
|
||||||
|
close[i]!=0 && close[i]!=EMPTY_VALUE)
|
||||||
|
{
|
||||||
|
m_start=MathMax(i+1,rates_total-Size()-m_bars_required);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_begin=m_start;
|
||||||
|
}
|
||||||
|
//--- number of bars was changed:
|
||||||
|
else m_start=prev_calculated-1;
|
||||||
|
//--- main loop:
|
||||||
|
for(int i=m_start;i<rates_total;i++)
|
||||||
|
{
|
||||||
|
m_tr=MathMax(high[i],close[i-1])-MathMin(low[i],close[i-1]);
|
||||||
|
m_ma.MainOnValue(rates_total,prev_calculated,m_begin,m_tr,i);
|
||||||
|
}
|
||||||
|
//--- restore as_series flags:
|
||||||
|
if(as_series_high) ArraySetAsSeries(high, true);
|
||||||
|
if(as_series_low) ArraySetAsSeries(low, true);
|
||||||
|
if(as_series_close) ArraySetAsSeries(close,true);
|
||||||
|
//--- return value of prev_calculated for next call:
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Indicator on value |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
double CATROnRingBuffer:: MainOnValue(const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const int begin,
|
||||||
|
const double high,
|
||||||
|
const double low,
|
||||||
|
const double close,
|
||||||
|
const int index)
|
||||||
|
{
|
||||||
|
//--- check as_series flags:
|
||||||
|
if(m_as_series) m_index=rates_total-1-index;
|
||||||
|
else m_index=index;
|
||||||
|
//--- check begin:
|
||||||
|
if(m_index<begin) return(EMPTY_VALUE);
|
||||||
|
//--- initial calculation:
|
||||||
|
if(m_index==begin)
|
||||||
|
{
|
||||||
|
m_close=close;
|
||||||
|
return (EMPTY_VALUE);
|
||||||
|
}
|
||||||
|
//--- remember the closing price:
|
||||||
|
if(prev_calculated-1!=m_index) m_prev_close=close;
|
||||||
|
m_close=close;
|
||||||
|
//--- main calculation:
|
||||||
|
m_tr=MathMax(high,m_prev_close)-MathMin(low,m_prev_close);
|
||||||
|
m_ma.MainOnValue(rates_total,prev_calculated,begin+1,m_tr,m_index);
|
||||||
|
//--- result:
|
||||||
|
return(m_ma.Last());
|
||||||
|
}
|
||||||
@@ -0,0 +1,364 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| CMAOnRingBuffer.mqh |
|
||||||
|
//| Copyright 2012, Konstantin Gruzdev |
|
||||||
|
//| https://login.mql5.com/ru/users/Lizar |
|
||||||
|
//| Revision 30 Nov 2012 |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "Copyright 2012, Konstantin Gruzdev"
|
||||||
|
#property link "https://login.mql5.com/ru/users/Lizar"
|
||||||
|
|
||||||
|
//--- Class for working with the ring buffer of data:
|
||||||
|
#include <IncOnRingBuffer\CArrayRing.mqh>
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Class CMAOnRingBuffer |
|
||||||
|
//| Appointment: class is designed to calculate a moving averages |
|
||||||
|
//| using the class for working with the ring |
|
||||||
|
//| buffer. |
|
||||||
|
//| Link: http://www.mql5.com/ru/code/1342 |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
class CMAOnRingBuffer :public CArrayRing
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
CArrayRing *m_array_in; // ring buffer for input data
|
||||||
|
int m_ma_period; // number of elements to analyze
|
||||||
|
ENUM_MA_METHOD m_ma_method; // MA calculation method
|
||||||
|
bool m_as_series; // true, if the indexing as in time series
|
||||||
|
double m_k1,m_k2;
|
||||||
|
double m_LK[];
|
||||||
|
string m_name; // indicator name
|
||||||
|
int m_bars_required; // number of elements required to calculate
|
||||||
|
int m_start; // index of element to start the calculation
|
||||||
|
int m_index; // current element index
|
||||||
|
|
||||||
|
public:
|
||||||
|
CMAOnRingBuffer() {}
|
||||||
|
~CMAOnRingBuffer();
|
||||||
|
//--- initialization method:
|
||||||
|
bool Init(int ma_period=14,ENUM_MA_METHOD ma_method=MODE_SMA, int size_buffer=256, bool as_series=false);
|
||||||
|
//--- basic methods:
|
||||||
|
int MainOnArray(const int rates_total, const int prev_calculated,const double &array[]);
|
||||||
|
double MainOnValue(const int rates_total, const int prev_calculated, const int begin, const double value, const int index);
|
||||||
|
//--- methods to get access to private data:
|
||||||
|
int BarsRequired() { return(m_bars_required); }
|
||||||
|
string Name() { return(m_name); }
|
||||||
|
string MAMethod() { return(MethodToString(m_ma_method)); }
|
||||||
|
int MAPeriod() { return(m_ma_period); }
|
||||||
|
//--- returns the value of element with the specified index:
|
||||||
|
double operator [](const int index) const { return(At(index)); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
//--- methods of calculation based on the array of input data:
|
||||||
|
void SMAOnArray (const int rates_total, const int prev_calculated, const double &array[]);
|
||||||
|
void EMAOnArray (const int rates_total, const int prev_calculated, const double &array[]);
|
||||||
|
void LWMAOnArray(const int rates_total, const int prev_calculated, const double &array[]);
|
||||||
|
//--- methods to calculate the sequential values ??of the indicator elements:
|
||||||
|
double SMAOnValue (const int prev_calculated, const int begin, const double value, const int index);
|
||||||
|
double EMAOnValue (const int prev_calculated, const int begin, const double value, const int index);
|
||||||
|
double LWMAOnValue(const int prev_calculated, const int begin, const double value, const int index);
|
||||||
|
//--- auxiliary methods:
|
||||||
|
int Begin(const int rates_total,const double &array[]);
|
||||||
|
bool FillArrayIn(const int prev_calculated, const double value);
|
||||||
|
string MethodToString(ENUM_MA_METHOD method);
|
||||||
|
};
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Destructor |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CMAOnRingBuffer:: ~CMAOnRingBuffer()
|
||||||
|
{
|
||||||
|
if(CheckPointer(m_array_in)!=POINTER_INVALID) delete m_array_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Indicator on array |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int CMAOnRingBuffer:: MainOnArray(const int rates_total,const int prev_calculated,const double &array[])
|
||||||
|
{
|
||||||
|
//--- save as_series flags
|
||||||
|
bool as_series=ArrayGetAsSeries(array);
|
||||||
|
if(as_series) ArraySetAsSeries(array,false);
|
||||||
|
//--- main calculation:
|
||||||
|
switch(m_ma_method)
|
||||||
|
{
|
||||||
|
case MODE_SMA: SMAOnArray(rates_total,prev_calculated,array); break;
|
||||||
|
case MODE_EMA:
|
||||||
|
case MODE_SMMA: EMAOnArray(rates_total,prev_calculated,array); break;
|
||||||
|
case MODE_LWMA: LWMAOnArray(rates_total,prev_calculated,array); break;
|
||||||
|
}
|
||||||
|
//--- restore as_series flags
|
||||||
|
if(as_series) ArraySetAsSeries(array,true);
|
||||||
|
//--- return value of prev_calculated for next call
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Indicator on value |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
double CMAOnRingBuffer:: MainOnValue(const int rates_total, const int prev_calculated, const int begin, const double value, const int index)
|
||||||
|
{
|
||||||
|
//--- check as_series flags:
|
||||||
|
if(m_as_series) m_index=rates_total-1-index;
|
||||||
|
else m_index=index;
|
||||||
|
//--- check begin:
|
||||||
|
if(m_index<begin) return(EMPTY_VALUE);
|
||||||
|
//--- main calculation:
|
||||||
|
switch(m_ma_method)
|
||||||
|
{
|
||||||
|
case MODE_SMA: return(SMAOnValue(prev_calculated,begin,value,index));
|
||||||
|
case MODE_EMA:
|
||||||
|
case MODE_SMMA: return(EMAOnValue(prev_calculated,begin,value,index));
|
||||||
|
case MODE_LWMA: return(LWMAOnValue(prev_calculated,begin,value,index));
|
||||||
|
}
|
||||||
|
//--- result:
|
||||||
|
return(EMPTY_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Simple moving average on array |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CMAOnRingBuffer:: SMAOnArray(const int rates_total, const int prev_calculated, const double &array[])
|
||||||
|
{
|
||||||
|
//--- first calculation:
|
||||||
|
if(prev_calculated==0)
|
||||||
|
{
|
||||||
|
m_start=Begin(rates_total,array)+m_ma_period-1;
|
||||||
|
double sum=0.0;
|
||||||
|
for(int i=m_start;i>m_start-m_ma_period;i--) sum+=array[i];
|
||||||
|
Last(sum/m_ma_period);
|
||||||
|
}
|
||||||
|
//--- number of bars was changed:
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_start=prev_calculated-1;
|
||||||
|
Last(At(1)-(array[m_start-m_ma_period]-array[m_start])/m_ma_period);
|
||||||
|
}
|
||||||
|
//--- main loop
|
||||||
|
for(int i=m_start+1;i<rates_total && !IsStopped();i++)
|
||||||
|
Add(Last()-(array[i-m_ma_period]-array[i])/m_ma_period);
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Exponential moving average on array |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CMAOnRingBuffer:: EMAOnArray(const int rates_total,const int prev_calculated,const double &array[])
|
||||||
|
{
|
||||||
|
//--- first calculation:
|
||||||
|
if(prev_calculated==0)
|
||||||
|
{
|
||||||
|
m_start=Begin(rates_total,array);
|
||||||
|
Last(array[m_start]);
|
||||||
|
}
|
||||||
|
//--- number of bars was changed:
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_start=prev_calculated-1;
|
||||||
|
Last(m_k1*array[m_start]+m_k2*At(1));
|
||||||
|
}
|
||||||
|
//--- main loop:
|
||||||
|
for(int i=m_start+1;i<rates_total && !IsStopped();i++)
|
||||||
|
Add(m_k1*array[i]+m_k2*Last());
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Linear weighted moving average on array |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CMAOnRingBuffer:: LWMAOnArray(const int rates_total, const int prev_calculated, const double &array[])
|
||||||
|
{
|
||||||
|
//--- first calculation:
|
||||||
|
if(prev_calculated==0)
|
||||||
|
m_start=Begin(rates_total,array)+m_ma_period-1;
|
||||||
|
//--- number of bars was changed:
|
||||||
|
else m_start=prev_calculated-1;
|
||||||
|
|
||||||
|
double volue=0.0;
|
||||||
|
for(int j=0;j<m_ma_period && !IsStopped();j++)
|
||||||
|
volue+=array[m_start-j]*m_LK[j];
|
||||||
|
Last(volue);
|
||||||
|
//--- main loop
|
||||||
|
for(int i=m_start+1;i<rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
volue=0.0;
|
||||||
|
for(int j=0;j<m_ma_period && !IsStopped();j++)
|
||||||
|
volue+=array[i-j]*m_LK[j];
|
||||||
|
Add(volue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Simple moving average on value |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
double CMAOnRingBuffer:: SMAOnValue(const int prev_calculated, const int begin, const double value, const int index)
|
||||||
|
{
|
||||||
|
//--- fill the ring buffer of input data:
|
||||||
|
if(!FillArrayIn(prev_calculated,value)) return(EMPTY_VALUE);
|
||||||
|
//--- initial calculation:
|
||||||
|
m_start=begin+m_ma_period-1;
|
||||||
|
if(m_index<m_start) return (EMPTY_VALUE);
|
||||||
|
else if(m_index==m_start)
|
||||||
|
{
|
||||||
|
double sum=0.0;
|
||||||
|
for(int i=0;i<m_ma_period && !IsStopped();i++) sum+=m_array_in[i];
|
||||||
|
Last(sum/m_ma_period);
|
||||||
|
return(Last());
|
||||||
|
}
|
||||||
|
//--- main calculation:
|
||||||
|
if(prev_calculated-1==m_index)
|
||||||
|
Last(At(1)-(m_array_in[m_ma_period]-value)/m_ma_period);
|
||||||
|
else
|
||||||
|
Add(Last()-(m_array_in[m_ma_period]-value)/m_ma_period);
|
||||||
|
//--- result:
|
||||||
|
return(Last());
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Exponential moving average on value |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
double CMAOnRingBuffer:: EMAOnValue(const int prev_calculated, const int begin, const double value, const int index)
|
||||||
|
{
|
||||||
|
//--- initial calculation:
|
||||||
|
if(m_index==begin)
|
||||||
|
{
|
||||||
|
Last(value);
|
||||||
|
return(value);
|
||||||
|
}
|
||||||
|
//--- main calculation:
|
||||||
|
if(prev_calculated-1==m_index)
|
||||||
|
Last(m_k1*value+m_k2*At(1));
|
||||||
|
else
|
||||||
|
Add(m_k1*value+m_k2*Last());
|
||||||
|
//--- result:
|
||||||
|
return(Last());
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Linear weighted moving average on value |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
double CMAOnRingBuffer:: LWMAOnValue(const int prev_calculated, const int begin, const double value, const int index)
|
||||||
|
{
|
||||||
|
//--- fill the ring buffer of input data:
|
||||||
|
if(!FillArrayIn(prev_calculated,value)) return(EMPTY_VALUE);
|
||||||
|
//--- initial calculation:
|
||||||
|
if(m_index<begin+m_ma_period-1) return (EMPTY_VALUE);
|
||||||
|
//--- main calculation:
|
||||||
|
double volue=0.0;
|
||||||
|
for(int j=0;j<m_ma_period && !IsStopped();j++)
|
||||||
|
volue+=m_array_in[j]*m_LK[j];
|
||||||
|
if(prev_calculated-1==m_index) Last(volue);
|
||||||
|
else Add(volue);
|
||||||
|
//--- result:
|
||||||
|
return(Last());
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Defines the index of the first element for calculation |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int CMAOnRingBuffer:: Begin(const int rates_total,const double &array[])
|
||||||
|
{
|
||||||
|
//--- looking the start of significant data:
|
||||||
|
int i=-1;
|
||||||
|
while(++i<rates_total && !IsStopped())
|
||||||
|
{
|
||||||
|
if(array[i]!=0 && array[i]!=EMPTY_VALUE) break;
|
||||||
|
}
|
||||||
|
//--- Return the index of the element from which start calculations:
|
||||||
|
return(MathMax(i,rates_total-Size()-m_bars_required));
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Fill the ring buffer by input data |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool CMAOnRingBuffer:: FillArrayIn(const int prev_calculated, const double value)
|
||||||
|
{
|
||||||
|
//--- check pointer:
|
||||||
|
if(CheckPointer(m_array_in)==POINTER_INVALID)
|
||||||
|
{
|
||||||
|
if((m_array_in=new CArrayRing())==NULL) return false;
|
||||||
|
if(!m_array_in.Init(Size())) return false;
|
||||||
|
}
|
||||||
|
//--- fill the ring buffer of input data:
|
||||||
|
if(prev_calculated-1==m_index) m_array_in.Last(value);
|
||||||
|
else m_array_in.Add(value);
|
||||||
|
//--- successful
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Initialization method |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool CMAOnRingBuffer:: Init(int ma_period=14,ENUM_MA_METHOD ma_method=MODE_SMA, int size_buffer=256, bool as_series=false)
|
||||||
|
{
|
||||||
|
//--- check for input values
|
||||||
|
if(ma_period<=0)
|
||||||
|
{
|
||||||
|
m_ma_period=14;
|
||||||
|
printf("Input parameter ma_period has incorrect value (%d). Indicator will use value %d for calculations.",
|
||||||
|
ma_period,m_ma_period);
|
||||||
|
}
|
||||||
|
else m_ma_period=ma_period;
|
||||||
|
if(size_buffer<=m_ma_period)
|
||||||
|
{
|
||||||
|
printf("Input parameter size_buffer has incorrect value (%d). Indicator will use value %d for calculations.",
|
||||||
|
size_buffer,m_ma_period);
|
||||||
|
size_buffer=m_ma_period;
|
||||||
|
}
|
||||||
|
//--- initialization of the ring buffer for the indicator data:
|
||||||
|
if(!CArrayRing::Init(size_buffer)) return false;
|
||||||
|
//--- data initialization:
|
||||||
|
int coeff_required=10;
|
||||||
|
m_as_series=as_series;
|
||||||
|
m_ma_method=ma_method;
|
||||||
|
switch(m_ma_method)
|
||||||
|
{
|
||||||
|
case MODE_SMA:
|
||||||
|
{
|
||||||
|
m_bars_required=m_ma_period;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MODE_EMA:
|
||||||
|
{
|
||||||
|
m_k1=2.0/(m_ma_period+1.0);
|
||||||
|
m_k2=1.0-m_k1;
|
||||||
|
m_bars_required=m_ma_period*coeff_required;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MODE_SMMA:
|
||||||
|
{
|
||||||
|
m_k1=1.0/m_ma_period;
|
||||||
|
m_k2=1.0-m_k1;
|
||||||
|
m_bars_required=m_ma_period*coeff_required;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MODE_LWMA:
|
||||||
|
{
|
||||||
|
ArrayResize(m_LK,m_ma_period);
|
||||||
|
double sum=0;
|
||||||
|
for(int j=0;j<m_ma_period;j++) sum+=m_LK[j]=m_ma_period-j;
|
||||||
|
for(int j=0;j<m_ma_period;j++) m_LK[j]/=sum;
|
||||||
|
sum=0;
|
||||||
|
for(int j=0;j<m_ma_period;j++) sum+=m_LK[j];
|
||||||
|
m_bars_required=m_ma_period;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_name=MethodToString(m_ma_method)+"("+IntegerToString(m_ma_period)+")";
|
||||||
|
//--- successful
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Transformation of moving method in the text representation |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
string CMAOnRingBuffer:: MethodToString(ENUM_MA_METHOD method)
|
||||||
|
{
|
||||||
|
switch(method)
|
||||||
|
{
|
||||||
|
case MODE_SMA: return("SMA");
|
||||||
|
case MODE_EMA: return("EMA");
|
||||||
|
case MODE_LWMA: return("LWMA");
|
||||||
|
case MODE_SMMA: return("SMMA");
|
||||||
|
}
|
||||||
|
return(EnumToString(method));
|
||||||
|
}
|
||||||
|
|
||||||
Binary file not shown.
@@ -0,0 +1,175 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| ma cross.mq5 |
|
||||||
|
//| Copyright 2018, MetaQuotes Software Corp. |
|
||||||
|
//| https://www.mql5.com |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "Copyright 2018, MetaQuotes Software Corp."
|
||||||
|
#property link "https://www.mql5.com"
|
||||||
|
#property version "1.00"
|
||||||
|
#property indicator_chart_window
|
||||||
|
#property indicator_buffers 3
|
||||||
|
#property indicator_plots 2
|
||||||
|
#property indicator_type1 DRAW_ARROW
|
||||||
|
#property indicator_color1 clrLightSeaGreen
|
||||||
|
#property indicator_width1 2
|
||||||
|
#property indicator_label1 "Bull ADX Cross"
|
||||||
|
#property indicator_type2 DRAW_ARROW
|
||||||
|
#property indicator_color2 clrRed
|
||||||
|
#property indicator_width2 2
|
||||||
|
#property indicator_label2 "Bear ADX Cross"
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
|
||||||
|
input int AdxPeriod = 14; // ADX period
|
||||||
|
input bool alertsOn = true; // Turn alerts on?
|
||||||
|
input bool alertsOnCurrent = false; // Alert on current bar?
|
||||||
|
input bool alertsMessage = true; // Display messages on alerts?
|
||||||
|
input bool alertsSound = false; // Play sound on alerts?
|
||||||
|
input bool alertsEmail = false; // Send email on alerts?
|
||||||
|
input bool alertsNotify = false; // Send push notification on alerts?
|
||||||
|
input int lookback = 256; // Maximum lookback period
|
||||||
|
|
||||||
|
double crossUp[],crossDn[],cross[];
|
||||||
|
|
||||||
|
#include <IncOnRingBuffer\CATROnRingBuffer.mqh>
|
||||||
|
#include <IncOnRingBuffer\CADXOnRingBuffer.mqh>
|
||||||
|
|
||||||
|
CATROnRingBuffer atr;
|
||||||
|
CADXOnRingBuffer adx;
|
||||||
|
int _start = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize custom chart indicator for data processing
|
||||||
|
// according to settings of the custom chart indicator already on chart
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//--- indicator buffers mapping
|
||||||
|
SetIndexBuffer(0,crossUp,INDICATOR_DATA); PlotIndexSetInteger(0,PLOT_ARROW,233);
|
||||||
|
SetIndexBuffer(1,crossDn,INDICATOR_DATA); PlotIndexSetInteger(1,PLOT_ARROW,234);
|
||||||
|
SetIndexBuffer(2,cross);
|
||||||
|
|
||||||
|
if(!adx.Init(AdxPeriod,MODE_EMA,lookback)) return(INIT_FAILED);
|
||||||
|
if(!atr.Init(15,MODE_SMA,lookback)) return(INIT_FAILED);
|
||||||
|
|
||||||
|
customChartIndicator.SetGetTimeFlag();
|
||||||
|
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME,"ADX cross "+(string)AdxPeriod+")");
|
||||||
|
return(INIT_SUCCEEDED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
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(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
atr.MainOnArray(rates_total,_prev_calculated,customChartIndicator.High,customChartIndicator.Low,customChartIndicator.Close);
|
||||||
|
adx.MainOnArray(rates_total,_prev_calculated,customChartIndicator.High,customChartIndicator.Low,customChartIndicator.Close);
|
||||||
|
|
||||||
|
ArraySetAsSeries(customChartIndicator.Low, false);
|
||||||
|
ArraySetAsSeries(customChartIndicator.High, false);
|
||||||
|
|
||||||
|
if(_prev_calculated==0)
|
||||||
|
{
|
||||||
|
_start = rates_total-adx.Size()+1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_start = MathMax(_prev_calculated-1,1);
|
||||||
|
|
||||||
|
for(int i=_start;i<rates_total;i++)
|
||||||
|
{
|
||||||
|
int ix = rates_total-1-i;
|
||||||
|
|
||||||
|
cross[i] = (ix>0) ? (adx.pdi[ix]>adx.ndi[ix]) ? 1 : (adx.pdi[ix]<adx.ndi[ix]) ? 2 : cross[i-1] : 0;
|
||||||
|
crossUp[i] = EMPTY_VALUE;
|
||||||
|
crossDn[i] = EMPTY_VALUE;
|
||||||
|
|
||||||
|
if (i>0 && cross[i]!=cross[i-1])
|
||||||
|
{
|
||||||
|
if (cross[i] == 1) crossUp[i] = customChartIndicator.Low[i]-atr[ix];
|
||||||
|
if (cross[i] == 2) crossDn[i] = customChartIndicator.High[i]+atr[ix];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
manageAlerts(customChartIndicator.Time,cross,rates_total);
|
||||||
|
return (rates_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
void manageAlerts(const datetime& _time[], double& _trend[], int bars)
|
||||||
|
{
|
||||||
|
if (alertsOn)
|
||||||
|
{
|
||||||
|
int whichBar = bars-1; if (!alertsOnCurrent) whichBar = bars-2; datetime time1 = _time[whichBar];
|
||||||
|
if (_trend[whichBar] != _trend[whichBar-1])
|
||||||
|
{
|
||||||
|
if (_trend[whichBar] == 1) doAlert(time1," plus DI crossing minus DI up");
|
||||||
|
if (_trend[whichBar] == 2) doAlert(time1," plus DI crossing minus DI down");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
void doAlert(datetime forTime, string doWhat)
|
||||||
|
{
|
||||||
|
static string previousAlert="nothing";
|
||||||
|
static datetime previousTime;
|
||||||
|
|
||||||
|
if (previousAlert != doWhat || previousTime != forTime)
|
||||||
|
{
|
||||||
|
previousAlert = doWhat;
|
||||||
|
previousTime = forTime;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
string message = TimeToString(TimeLocal(),TIME_SECONDS)+" "+_Symbol+" Adx "+doWhat;
|
||||||
|
if (alertsMessage) Alert(message);
|
||||||
|
if (alertsEmail) SendMail(_Symbol+"Adx",message);
|
||||||
|
if (alertsNotify) SendNotification(message);
|
||||||
|
if (alertsSound) PlaySound("alert2.wav");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
@@ -40,17 +40,11 @@ double ExtTmpBuffer[];
|
|||||||
//--- global variables
|
//--- global variables
|
||||||
int ExtADXPeriod;
|
int ExtADXPeriod;
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| Custom indicator initialization function |
|
//| Custom indicator initialization function |
|
||||||
@@ -99,15 +93,42 @@ int OnCalculate(const int rates_total,
|
|||||||
const int &Spread[])
|
const int &Spread[])
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
// Process data through MedianRenko indicator
|
||||||
|
//
|
||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
//--- checking for bars count
|
//--- checking for bars count
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -6,7 +6,6 @@
|
|||||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||||
#property link "http://www.mql5.com"
|
#property link "http://www.mql5.com"
|
||||||
#property description "Average True Range"
|
#property description "Average True Range"
|
||||||
#property description "Adapted for use with TickChart by Artur Zas."
|
|
||||||
//--- indicator settings
|
//--- indicator settings
|
||||||
#property indicator_separate_window
|
#property indicator_separate_window
|
||||||
#property indicator_buffers 2
|
#property indicator_buffers 2
|
||||||
@@ -15,22 +14,17 @@
|
|||||||
#property indicator_color1 DodgerBlue
|
#property indicator_color1 DodgerBlue
|
||||||
#property indicator_label1 "ATR"
|
#property indicator_label1 "ATR"
|
||||||
//--- input parameters
|
//--- input parameters
|
||||||
input int InpAtrPeriod=14; // ATR period
|
input int Inp_AtrPeriod=14; // ATR period
|
||||||
//--- indicator buffers
|
//--- indicator buffers
|
||||||
double ExtATRBuffer[];
|
double ExtATRBuffer[];
|
||||||
double ExtTRBuffer[];
|
double ExtTRBuffer[];
|
||||||
//--- global variable
|
//--- global variable
|
||||||
int ExtPeriodATR;
|
int ExtPeriodATR;
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -39,19 +33,19 @@ RangeBarIndicator customChartIndicator;
|
|||||||
void OnInit()
|
void OnInit()
|
||||||
{
|
{
|
||||||
//--- check for input value
|
//--- check for input value
|
||||||
if(InpAtrPeriod<=0)
|
if(Inp_AtrPeriod<=0)
|
||||||
{
|
{
|
||||||
ExtPeriodATR=14;
|
ExtPeriodATR=14;
|
||||||
printf("Incorrect input parameter InpAtrPeriod = %d. Indicator will use value %d for calculations.",InpAtrPeriod,ExtPeriodATR);
|
printf("Incorrect input parameter InpAtrPeriod = %d. Indicator will use value %d for calculations.",Inp_AtrPeriod,ExtPeriodATR);
|
||||||
}
|
}
|
||||||
else ExtPeriodATR=InpAtrPeriod;
|
else ExtPeriodATR=Inp_AtrPeriod;
|
||||||
//--- indicator buffers mapping
|
//--- indicator buffers mapping
|
||||||
SetIndexBuffer(0,ExtATRBuffer,INDICATOR_DATA);
|
SetIndexBuffer(0,ExtATRBuffer,INDICATOR_DATA);
|
||||||
SetIndexBuffer(1,ExtTRBuffer,INDICATOR_CALCULATIONS);
|
SetIndexBuffer(1,ExtTRBuffer,INDICATOR_CALCULATIONS);
|
||||||
//---
|
//---
|
||||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||||
//--- sets first bar from what index will be drawn
|
//--- sets first bar from what index will be drawn
|
||||||
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpAtrPeriod);
|
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,Inp_AtrPeriod);
|
||||||
//--- name for DataWindow and indicator subwindow label
|
//--- name for DataWindow and indicator subwindow label
|
||||||
string short_name="ATR("+string(ExtPeriodATR)+")";
|
string short_name="ATR("+string(ExtPeriodATR)+")";
|
||||||
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
||||||
@@ -72,16 +66,44 @@ int OnCalculate(const int rates_total,
|
|||||||
const long &volume[],
|
const long &volume[],
|
||||||
const int &spread[])
|
const int &spread[])
|
||||||
{
|
{
|
||||||
//
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Process data through MedianRenko indicator
|
||||||
|
//
|
||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
int i,limit;
|
int i,limit;
|
||||||
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
+1
-2
@@ -26,8 +26,7 @@ double ExtSlowBuffer[];
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include <MovingAverages.mqh>
|
#include <MovingAverages.mqh>
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,169 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| BB.mq5 |
|
||||||
|
//| Copyright 2009-2020, MetaQuotes Software Corp. |
|
||||||
|
//| http://www.mql5.com |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "2009-2020, MetaQuotes Software Corp."
|
||||||
|
#property link "http://www.mql5.com"
|
||||||
|
#property description "Bollinger Bands"
|
||||||
|
#include <MovingAverages.mqh>
|
||||||
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
|
//---
|
||||||
|
#property indicator_chart_window
|
||||||
|
#property indicator_buffers 4
|
||||||
|
#property indicator_plots 3
|
||||||
|
#property indicator_type1 DRAW_LINE
|
||||||
|
#property indicator_color1 LightSeaGreen
|
||||||
|
#property indicator_type2 DRAW_LINE
|
||||||
|
#property indicator_color2 LightSeaGreen
|
||||||
|
#property indicator_type3 DRAW_LINE
|
||||||
|
#property indicator_color3 LightSeaGreen
|
||||||
|
#property indicator_label1 "Bands middle"
|
||||||
|
#property indicator_label2 "Bands upper"
|
||||||
|
#property indicator_label3 "Bands lower"
|
||||||
|
//--- input parametrs
|
||||||
|
input int InpBandsPeriod=20; // Period
|
||||||
|
input int InpBandsShift=0; // Shift
|
||||||
|
input double InpBandsDeviations=2.0; // Deviation
|
||||||
|
input ENUM_APPLIED_PRICE InpAppliedPrice = PRICE_CLOSE; // Applied price
|
||||||
|
//--- global variables
|
||||||
|
int ExtBandsPeriod,ExtBandsShift;
|
||||||
|
double ExtBandsDeviations;
|
||||||
|
int ExtPlotBegin=0;
|
||||||
|
//--- indicator buffer
|
||||||
|
double ExtMLBuffer[];
|
||||||
|
double ExtTLBuffer[];
|
||||||
|
double ExtBLBuffer[];
|
||||||
|
double ExtStdDevBuffer[];
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnInit()
|
||||||
|
{
|
||||||
|
//--- check for input values
|
||||||
|
if(InpBandsPeriod<2)
|
||||||
|
{
|
||||||
|
ExtBandsPeriod=20;
|
||||||
|
PrintFormat("Incorrect value for input variable InpBandsPeriod=%d. Indicator will use value=%d for calculations.",InpBandsPeriod,ExtBandsPeriod);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ExtBandsPeriod=InpBandsPeriod;
|
||||||
|
if(InpBandsShift<0)
|
||||||
|
{
|
||||||
|
ExtBandsShift=0;
|
||||||
|
PrintFormat("Incorrect value for input variable InpBandsShift=%d. Indicator will use value=%d for calculations.",InpBandsShift,ExtBandsShift);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ExtBandsShift=InpBandsShift;
|
||||||
|
if(InpBandsDeviations==0.0)
|
||||||
|
{
|
||||||
|
ExtBandsDeviations=2.0;
|
||||||
|
PrintFormat("Incorrect value for input variable InpBandsDeviations=%f. Indicator will use value=%f for calculations.",InpBandsDeviations,ExtBandsDeviations);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ExtBandsDeviations=InpBandsDeviations;
|
||||||
|
//--- define buffers
|
||||||
|
SetIndexBuffer(0,ExtMLBuffer);
|
||||||
|
SetIndexBuffer(1,ExtTLBuffer);
|
||||||
|
SetIndexBuffer(2,ExtBLBuffer);
|
||||||
|
SetIndexBuffer(3,ExtStdDevBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
//--- set index labels
|
||||||
|
PlotIndexSetString(0,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Middle");
|
||||||
|
PlotIndexSetString(1,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Upper");
|
||||||
|
PlotIndexSetString(2,PLOT_LABEL,"Bands("+string(ExtBandsPeriod)+") Lower");
|
||||||
|
//--- indicator name
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME,"Bollinger Bands");
|
||||||
|
//--- indexes draw begin settings
|
||||||
|
ExtPlotBegin=ExtBandsPeriod-1;
|
||||||
|
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtBandsPeriod);
|
||||||
|
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,ExtBandsPeriod);
|
||||||
|
PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,ExtBandsPeriod);
|
||||||
|
//--- indexes shift settings
|
||||||
|
PlotIndexSetInteger(0,PLOT_SHIFT,ExtBandsShift);
|
||||||
|
PlotIndexSetInteger(1,PLOT_SHIFT,ExtBandsShift);
|
||||||
|
PlotIndexSetInteger(2,PLOT_SHIFT,ExtBandsShift);
|
||||||
|
//--- number of digits of indicator value
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
|
||||||
|
|
||||||
|
customChartIndicator.SetUseAppliedPriceFlag(InpAppliedPrice);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Bollinger Bands |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
/*
|
||||||
|
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 &tick_volume[],
|
||||||
|
const long &volume[],
|
||||||
|
const int &spread[])
|
||||||
|
{
|
||||||
|
static int begin = 0;
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
int _rates_total = ArraySize(customChartIndicator.Close);
|
||||||
|
|
||||||
|
if(_rates_total<ExtPlotBegin)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
//--- indexes draw begin settings, when we've recieved previous begin
|
||||||
|
if(ExtPlotBegin!=ExtBandsPeriod+begin)
|
||||||
|
{
|
||||||
|
ExtPlotBegin=ExtBandsPeriod+begin;
|
||||||
|
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPlotBegin);
|
||||||
|
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,ExtPlotBegin);
|
||||||
|
PlotIndexSetInteger(2,PLOT_DRAW_BEGIN,ExtPlotBegin);
|
||||||
|
}
|
||||||
|
//--- starting calculation
|
||||||
|
int pos;
|
||||||
|
if(_prev_calculated>1)
|
||||||
|
pos=_prev_calculated-1;
|
||||||
|
else
|
||||||
|
pos=0;
|
||||||
|
//--- main cycle
|
||||||
|
for(int i=pos; i<_rates_total && !IsStopped(); i++)
|
||||||
|
{
|
||||||
|
//--- middle line
|
||||||
|
ExtMLBuffer[i]=SimpleMA(i,ExtBandsPeriod,customChartIndicator.Price);
|
||||||
|
//--- calculate and write down StdDev
|
||||||
|
ExtStdDevBuffer[i]=StdDev_Func(i,customChartIndicator.Price,ExtMLBuffer,ExtBandsPeriod);
|
||||||
|
//--- upper line
|
||||||
|
ExtTLBuffer[i]=ExtMLBuffer[i]+ExtBandsDeviations*ExtStdDevBuffer[i];
|
||||||
|
//--- lower line
|
||||||
|
ExtBLBuffer[i]=ExtMLBuffer[i]-ExtBandsDeviations*ExtStdDevBuffer[i];
|
||||||
|
}
|
||||||
|
//--- OnCalculate done. Return new prev_calculated.
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Calculate Standard Deviation |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
double StdDev_Func(const int position,const double &price[],const double &ma_price[],const int period)
|
||||||
|
{
|
||||||
|
double std_dev=0.0;
|
||||||
|
//--- calcualte StdDev
|
||||||
|
if(position>=period)
|
||||||
|
{
|
||||||
|
for(int i=0; i<period; i++)
|
||||||
|
std_dev+=MathPow(price[position-i]-ma_price[position],2.0);
|
||||||
|
std_dev=MathSqrt(std_dev/period);
|
||||||
|
}
|
||||||
|
//--- return calculated value
|
||||||
|
return(std_dev);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,83 @@
|
|||||||
|
//+------------------------------------------------------------------
|
||||||
|
#property copyright "mladen"
|
||||||
|
#property link "mladenfx@gmail.com"
|
||||||
|
#property link "https://www.mql5.com"
|
||||||
|
#property description "CCI (alternative)"
|
||||||
|
//+------------------------------------------------------------------
|
||||||
|
#property indicator_separate_window
|
||||||
|
#property indicator_buffers 3
|
||||||
|
#property indicator_plots 1
|
||||||
|
#property indicator_label1 "CCI alternative"
|
||||||
|
#property indicator_type1 DRAW_COLOR_LINE
|
||||||
|
#property indicator_color1 clrDarkGray,clrSkyBlue,clrDodgerBlue
|
||||||
|
#property indicator_width1 2
|
||||||
|
//--- input parameters
|
||||||
|
input int inpPeriod=14; // CCI period
|
||||||
|
//--- buffers and global variables declarations
|
||||||
|
double val[],valc[],prices[];
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
//--- indicator buffers mapping
|
||||||
|
SetIndexBuffer(0,val,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(1,valc,INDICATOR_COLOR_INDEX);
|
||||||
|
SetIndexBuffer(2,prices,INDICATOR_CALCULATIONS);
|
||||||
|
//---
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME,"CCI (alternative)("+(string)inpPeriod+")");
|
||||||
|
return (INIT_SUCCEEDED);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator de-initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnDeinit(const int reason)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
if(Bars(_Symbol,_Period)<rates_total) return(_prev_calculated);
|
||||||
|
|
||||||
|
int i=(int)MathMax(_prev_calculated-1,1); for(; i<rates_total && !_StopFlag; i++)
|
||||||
|
{
|
||||||
|
int _start=MathMax(i-inpPeriod+1,0);
|
||||||
|
prices[i]=(customChartIndicator.High[ArrayMaximum(customChartIndicator.High,_start,inpPeriod)]+customChartIndicator.Low[ArrayMinimum(customChartIndicator.Low,_start,inpPeriod)]+customChartIndicator.Close[i])/3;
|
||||||
|
double avg = 0; for(int k=0; k<inpPeriod && (i-k)>=0; k++) avg += prices[i-k]; avg /= inpPeriod;
|
||||||
|
double dev = 0; for(int k=0; k<inpPeriod && (i-k)>=0; k++) dev += MathAbs(prices[i-k]-avg); dev /= inpPeriod;
|
||||||
|
|
||||||
|
val[i] = (dev!=0) ? (prices[i]-avg)/(0.015*dev) : 0;
|
||||||
|
valc[i]=(i>0) ?(val[i]>val[i-1]) ? 1 :(val[i]<val[i-1]) ? 2 : valc[i-1]: 0;
|
||||||
|
}
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
Binary file not shown.
@@ -8,7 +8,6 @@
|
|||||||
#property copyright "2009, MetaQuotes Software Corp."
|
#property copyright "2009, MetaQuotes Software Corp."
|
||||||
#property link "http://www.mql5.com"
|
#property link "http://www.mql5.com"
|
||||||
#property description "Commodity Channel Index"
|
#property description "Commodity Channel Index"
|
||||||
#property description "Adapted for use with TickChart by Artur Zas."
|
|
||||||
#include <MovingAverages.mqh>
|
#include <MovingAverages.mqh>
|
||||||
//---
|
//---
|
||||||
#property indicator_separate_window
|
#property indicator_separate_window
|
||||||
@@ -30,15 +29,10 @@ double ExtDBuffer[];
|
|||||||
double ExtMBuffer[];
|
double ExtMBuffer[];
|
||||||
double ExtCCIBuffer[];
|
double ExtCCIBuffer[];
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -103,7 +97,7 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
Binary file not shown.
@@ -0,0 +1,145 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| CHV.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 "Chaikin Volatility"
|
||||||
|
#include <MovingAverages.mqh>
|
||||||
|
//--- indicator settings
|
||||||
|
#property indicator_separate_window
|
||||||
|
#property indicator_buffers 3
|
||||||
|
#property indicator_plots 1
|
||||||
|
#property indicator_type1 DRAW_LINE
|
||||||
|
#property indicator_color1 DodgerBlue
|
||||||
|
//--- enum
|
||||||
|
enum SmoothMethod
|
||||||
|
{
|
||||||
|
SMA=0,// Simple MA
|
||||||
|
EMA=1 // Exponential MA
|
||||||
|
};
|
||||||
|
//--- input parameters
|
||||||
|
input int InpSmoothPeriod=10; // Smoothing period
|
||||||
|
input int InpCHVPeriod=10; // CHV period
|
||||||
|
input SmoothMethod InpSmoothType=EMA; // Smoothing method
|
||||||
|
//---- buffers
|
||||||
|
double ExtCHVBuffer[];
|
||||||
|
double ExtHLBuffer[];
|
||||||
|
double ExtSHLBuffer[];
|
||||||
|
//--- global variables
|
||||||
|
int ExtSmoothPeriod,ExtCHVPeriod;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnInit()
|
||||||
|
{
|
||||||
|
//--- check for input variables
|
||||||
|
string MAName;
|
||||||
|
//--- set MA name
|
||||||
|
if(InpSmoothType==SMA)
|
||||||
|
MAName="SMA";
|
||||||
|
else
|
||||||
|
MAName="EMA";
|
||||||
|
//--- check inputs
|
||||||
|
if(InpSmoothPeriod<=0)
|
||||||
|
{
|
||||||
|
ExtSmoothPeriod=10;
|
||||||
|
printf("Incorrect value for input variable InpSmoothPeriod=%d. Indicator will use value=%d for calculations.",InpSmoothPeriod,ExtSmoothPeriod);
|
||||||
|
}
|
||||||
|
else ExtSmoothPeriod=InpSmoothPeriod;
|
||||||
|
if(InpCHVPeriod<=0)
|
||||||
|
{
|
||||||
|
ExtCHVPeriod=10;
|
||||||
|
printf("Incorrect value for input variable InpCHVPeriod=%d. Indicator will use value=%d for calculations.",InpCHVPeriod,ExtCHVPeriod);
|
||||||
|
}
|
||||||
|
else ExtCHVPeriod=InpCHVPeriod;
|
||||||
|
//---- define buffers
|
||||||
|
SetIndexBuffer(0,ExtCHVBuffer);
|
||||||
|
SetIndexBuffer(1,ExtHLBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
SetIndexBuffer(2,ExtSHLBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
//--- set draw begin
|
||||||
|
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtSmoothPeriod+ExtCHVPeriod-1);
|
||||||
|
//--- set index label
|
||||||
|
PlotIndexSetString(0,PLOT_LABEL,"CHV("+string(ExtSmoothPeriod)+","+MAName+")");
|
||||||
|
//--- indicator name
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME,"Chaikin Volatility("+string(ExtSmoothPeriod)+","+MAName+")");
|
||||||
|
//--- round settings
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,1);
|
||||||
|
//---- OnInit done
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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[])
|
||||||
|
{
|
||||||
|
//--- variables of indicator
|
||||||
|
int i,pos,posCHV;
|
||||||
|
//--- check for rates total
|
||||||
|
posCHV=ExtCHVPeriod+ExtSmoothPeriod-2;
|
||||||
|
if(rates_total<posCHV)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Process data through MedianRenko indicator
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//--- start working
|
||||||
|
if(_prev_calculated<1)
|
||||||
|
pos=0;
|
||||||
|
else pos=_prev_calculated-1;
|
||||||
|
//--- fill H-L(i) buffer
|
||||||
|
for(i=pos;i<rates_total && !IsStopped();i++) ExtHLBuffer[i]=customChartIndicator.High[i]-customChartIndicator.Low[i];
|
||||||
|
//--- calculate smoothed H-L(i) buffer
|
||||||
|
if(pos<ExtSmoothPeriod-1)
|
||||||
|
{
|
||||||
|
pos=ExtSmoothPeriod-1;
|
||||||
|
for(i=0;i<pos;i++) ExtSHLBuffer[i]=0.0;
|
||||||
|
}
|
||||||
|
if(InpSmoothType==SMA)
|
||||||
|
SimpleMAOnBuffer(rates_total,_prev_calculated,0,ExtSmoothPeriod,ExtHLBuffer,ExtSHLBuffer);
|
||||||
|
else
|
||||||
|
ExponentialMAOnBuffer(rates_total,_prev_calculated,0,ExtSmoothPeriod,ExtHLBuffer,ExtSHLBuffer);
|
||||||
|
//--- correct calc position
|
||||||
|
if(pos<posCHV) pos=posCHV;
|
||||||
|
//--- calculate CHV buffer
|
||||||
|
for(i=pos;i<rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
if(ExtSHLBuffer[i-ExtCHVPeriod]!=0.0)
|
||||||
|
ExtCHVBuffer[i]=100.0*(ExtSHLBuffer[i]-ExtSHLBuffer[i-ExtCHVPeriod])/ExtSHLBuffer[i-ExtCHVPeriod];
|
||||||
|
else
|
||||||
|
ExtCHVBuffer[i]=0.0;
|
||||||
|
}
|
||||||
|
//----
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2
-7
@@ -55,15 +55,10 @@ double dtoss[];
|
|||||||
double dtosf1[];
|
double dtosf1[];
|
||||||
double dtosf2[];
|
double dtosf2[];
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -112,7 +107,7 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,133 @@
|
|||||||
|
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Envelopes.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 3
|
||||||
|
#property indicator_plots 2
|
||||||
|
#property indicator_type1 DRAW_LINE
|
||||||
|
#property indicator_type2 DRAW_LINE
|
||||||
|
#property indicator_color1 Blue
|
||||||
|
#property indicator_color2 Red
|
||||||
|
#property indicator_label1 "Upper band"
|
||||||
|
#property indicator_label2 "Lower band"
|
||||||
|
//--- input parameters
|
||||||
|
input int InpMAPeriod=14; // Period
|
||||||
|
input int InpMAShift=0; // Shift
|
||||||
|
input ENUM_MA_METHOD InpMAMethod=MODE_SMA; // Method
|
||||||
|
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE; // Applied price
|
||||||
|
input double InpDeviation=0.1; // Deviation
|
||||||
|
//--- indicator buffers
|
||||||
|
double ExtUpBuffer[];
|
||||||
|
double ExtDownBuffer[];
|
||||||
|
double ExtMABuffer[];
|
||||||
|
int weightSum;
|
||||||
|
|
||||||
|
//--- MA handle
|
||||||
|
//int ExtMAHandle;
|
||||||
|
|
||||||
|
#include <MovingAverages.mqh>
|
||||||
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnInit()
|
||||||
|
{
|
||||||
|
//--- indicator buffers mapping
|
||||||
|
SetIndexBuffer(0,ExtUpBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(1,ExtDownBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(2,ExtMABuffer,INDICATOR_CALCULATIONS);
|
||||||
|
//---
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
|
||||||
|
//--- sets first bar from what index will be drawn
|
||||||
|
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpMAPeriod-1);
|
||||||
|
//--- name for DataWindow
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME,"Env("+string(InpMAPeriod)+")");
|
||||||
|
PlotIndexSetString(0,PLOT_LABEL,"Env("+string(InpMAPeriod)+")Upper");
|
||||||
|
PlotIndexSetString(1,PLOT_LABEL,"Env("+string(InpMAPeriod)+")Lower");
|
||||||
|
//---- line shifts when drawing
|
||||||
|
PlotIndexSetInteger(0,PLOT_SHIFT,InpMAShift);
|
||||||
|
PlotIndexSetInteger(1,PLOT_SHIFT,InpMAShift);
|
||||||
|
//---
|
||||||
|
|
||||||
|
customChartIndicator.SetUseAppliedPriceFlag(InpAppliedPrice);
|
||||||
|
|
||||||
|
//--- initialization done
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Envelopes |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
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[])
|
||||||
|
{
|
||||||
|
int i,limit;
|
||||||
|
//--- check for bars count
|
||||||
|
if(rates_total<InpMAPeriod)
|
||||||
|
return(0);
|
||||||
|
//--
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//--- we can copy not all data
|
||||||
|
int to_copy;
|
||||||
|
if(_prev_calculated>rates_total || _prev_calculated<0) to_copy=rates_total;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
to_copy=rates_total-_prev_calculated;
|
||||||
|
if(_prev_calculated>0) to_copy++;
|
||||||
|
}
|
||||||
|
//---- get ma buffer
|
||||||
|
if(IsStopped()) return(0); //Checking for stop flag
|
||||||
|
|
||||||
|
switch(InpMAMethod)
|
||||||
|
{
|
||||||
|
case MODE_SMA:
|
||||||
|
SimpleMAOnBuffer(rates_total,_prev_calculated,0,InpMAPeriod,customChartIndicator.Price,ExtMABuffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MODE_EMA:
|
||||||
|
ExponentialMAOnBuffer(rates_total,_prev_calculated,0,InpMAPeriod,customChartIndicator.Price,ExtMABuffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MODE_SMMA:
|
||||||
|
SmoothedMAOnBuffer(rates_total,_prev_calculated,0,InpMAPeriod,customChartIndicator.Price,ExtMABuffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MODE_LWMA:
|
||||||
|
LinearWeightedMAOnBuffer(rates_total,_prev_calculated,0,InpMAPeriod,customChartIndicator.Price,ExtMABuffer,weightSum);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--- preliminary calculations
|
||||||
|
limit=_prev_calculated-1;
|
||||||
|
if(limit<InpMAPeriod)
|
||||||
|
limit=InpMAPeriod;
|
||||||
|
//--- the main loop of calculations
|
||||||
|
for(i=limit;i<rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
ExtUpBuffer[i]=(1+InpDeviation/100.0)*ExtMABuffer[i];
|
||||||
|
ExtDownBuffer[i]=(1-InpDeviation/100.0)*ExtMABuffer[i];
|
||||||
|
}
|
||||||
|
//--- done
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
Binary file not shown.
@@ -21,15 +21,10 @@ double ExtLowerBuffer[];
|
|||||||
//--- 10 pixels upper from high price
|
//--- 10 pixels upper from high price
|
||||||
int ExtArrowShift=-10;
|
int ExtArrowShift=-10;
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -66,15 +61,42 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
const int &Spread[])
|
const int &Spread[])
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
// Process data through MedianRenko indicator
|
||||||
|
//
|
||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
int i,limit;
|
int i,limit;
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
-2
@@ -19,8 +19,7 @@
|
|||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
Binary file not shown.
+73
-29
@@ -16,10 +16,10 @@
|
|||||||
#property indicator_color1 clrDodgerBlue, clrOrangeRed
|
#property indicator_color1 clrDodgerBlue, clrOrangeRed
|
||||||
#property indicator_style1 STYLE_SOLID
|
#property indicator_style1 STYLE_SOLID
|
||||||
#property indicator_width1 2
|
#property indicator_width1 2
|
||||||
#property indicator_label1 "GHL (13, SMMA)"
|
#property indicator_label1 "GHL_SSL"
|
||||||
//--- input parameters
|
//--- input parameters
|
||||||
input uint InpPeriod=13; // Period
|
input uint InpPeriod=10; // Period
|
||||||
input ENUM_MA_METHOD InpMethod=MODE_SMMA;// Method
|
input ENUM_MA_METHOD InpMethod=MODE_SMA;// Method
|
||||||
//--- buffers
|
//--- buffers
|
||||||
double GannBuffer[];
|
double GannBuffer[];
|
||||||
double ColorBuffer[];
|
double ColorBuffer[];
|
||||||
@@ -27,19 +27,14 @@ double MaHighBuffer[];
|
|||||||
double MaLowBuffer[];
|
double MaLowBuffer[];
|
||||||
double TrendBuffer[];
|
double TrendBuffer[];
|
||||||
//--- global vars
|
//--- global vars
|
||||||
int ma_high_handle;
|
//int ma_high_handle;
|
||||||
int ma_low_handle;
|
//int ma_low_handle;
|
||||||
int period;
|
int _period;
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
#include <MovingAverages.mqh>
|
||||||
//
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -48,7 +43,7 @@ RangeBarIndicator customChartIndicator;
|
|||||||
int OnInit()
|
int OnInit()
|
||||||
{
|
{
|
||||||
//--- check period
|
//--- check period
|
||||||
period=(int)fmax(InpPeriod,2);
|
_period=(int)fmax(InpPeriod,2);
|
||||||
//--- set buffers
|
//--- set buffers
|
||||||
SetIndexBuffer(0,GannBuffer);
|
SetIndexBuffer(0,GannBuffer);
|
||||||
SetIndexBuffer(1,ColorBuffer,INDICATOR_COLOR_INDEX);
|
SetIndexBuffer(1,ColorBuffer,INDICATOR_COLOR_INDEX);
|
||||||
@@ -62,19 +57,19 @@ int OnInit()
|
|||||||
ArraySetAsSeries(MaLowBuffer,true);
|
ArraySetAsSeries(MaLowBuffer,true);
|
||||||
ArraySetAsSeries(TrendBuffer,true);
|
ArraySetAsSeries(TrendBuffer,true);
|
||||||
//--- get handles
|
//--- get handles
|
||||||
ma_high_handle=iMA(NULL,0,period,0,InpMethod,PRICE_HIGH);
|
//ma_high_handle=iMA(NULL,0,_period,0,InpMethod,PRICE_HIGH);
|
||||||
ma_low_handle =iMA(NULL,0,period,0,InpMethod,PRICE_LOW);
|
//ma_low_handle =iMA(NULL,0,_period,0,InpMethod,PRICE_LOW);
|
||||||
if(ma_high_handle==INVALID_HANDLE || ma_low_handle==INVALID_HANDLE)
|
//if(ma_high_handle==INVALID_HANDLE || ma_low_handle==INVALID_HANDLE)
|
||||||
{
|
// {
|
||||||
Print("Unable to create handle for iMA");
|
// Print("Unable to create handle for iMA");
|
||||||
return(INIT_FAILED);
|
// return(INIT_FAILED);
|
||||||
}
|
// }
|
||||||
//--- set indicator properties
|
//--- set indicator properties
|
||||||
string short_name=StringFormat("Gann High-Low Activator SSL (%u, %s)",period,StringSubstr(EnumToString(InpMethod),5));
|
string short_name=StringFormat("Gann High-Low Activator SSL (%u, %s)",_period,StringSubstr(EnumToString(InpMethod),5));
|
||||||
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
|
||||||
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||||
//--- set label
|
//--- set label
|
||||||
short_name=StringFormat("GHL (%u, %s)",period,StringSubstr(EnumToString(InpMethod),5));
|
short_name=StringFormat("GHL (%u, %s)",_period,StringSubstr(EnumToString(InpMethod),5));
|
||||||
PlotIndexSetString(0,PLOT_LABEL,short_name);
|
PlotIndexSetString(0,PLOT_LABEL,short_name);
|
||||||
//--- done
|
//--- done
|
||||||
return(INIT_SUCCEEDED);
|
return(INIT_SUCCEEDED);
|
||||||
@@ -94,18 +89,45 @@ int OnCalculate(const int rates_total,
|
|||||||
const int &spread[])
|
const int &spread[])
|
||||||
{
|
{
|
||||||
|
|
||||||
if(rates_total<period+1)return(0);
|
//if(rates_total<_period+1)return(0);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// Process data through MedianRenko indicator
|
||||||
|
//
|
||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
ArraySetAsSeries(customChartIndicator.Close,true);
|
ArraySetAsSeries(customChartIndicator.Close,true);
|
||||||
@@ -113,7 +135,7 @@ int OnCalculate(const int rates_total,
|
|||||||
int limit;
|
int limit;
|
||||||
if(rates_total<_prev_calculated || _prev_calculated<=0)
|
if(rates_total<_prev_calculated || _prev_calculated<=0)
|
||||||
{
|
{
|
||||||
limit=rates_total-period-1;
|
limit=rates_total-_period-1;
|
||||||
ArrayInitialize(GannBuffer,EMPTY_VALUE);
|
ArrayInitialize(GannBuffer,EMPTY_VALUE);
|
||||||
ArrayInitialize(ColorBuffer,0);
|
ArrayInitialize(ColorBuffer,0);
|
||||||
ArrayInitialize(MaHighBuffer,0);
|
ArrayInitialize(MaHighBuffer,0);
|
||||||
@@ -123,8 +145,30 @@ int OnCalculate(const int rates_total,
|
|||||||
else
|
else
|
||||||
limit=rates_total-_prev_calculated;
|
limit=rates_total-_prev_calculated;
|
||||||
//--- get MA
|
//--- get MA
|
||||||
if(CopyBuffer(ma_high_handle,0,0,limit+1,MaHighBuffer)!=limit+1)return(0);
|
//if(CopyBuffer(ma_high_handle,0,0,limit+1,MaHighBuffer)!=limit+1)return(0);
|
||||||
if(CopyBuffer(ma_low_handle,0,0,limit+1,MaLowBuffer)!=limit+1)return(0);
|
//if(CopyBuffer(ma_low_handle,0,0,limit+1,MaLowBuffer)!=limit+1)return(0);
|
||||||
|
|
||||||
|
switch(InpMethod)
|
||||||
|
{
|
||||||
|
case MODE_SMA:
|
||||||
|
SimpleMAOnBuffer(rates_total, _prev_calculated, 0, _period, customChartIndicator.High, MaHighBuffer);
|
||||||
|
SimpleMAOnBuffer(rates_total, _prev_calculated, 0, _period, customChartIndicator.Low, MaLowBuffer);
|
||||||
|
break;
|
||||||
|
case MODE_EMA:
|
||||||
|
ExponentialMAOnBuffer(rates_total, _prev_calculated, 0, _period, customChartIndicator.High, MaHighBuffer);
|
||||||
|
ExponentialMAOnBuffer(rates_total, _prev_calculated, 0, _period, customChartIndicator.Low, MaLowBuffer);
|
||||||
|
break;
|
||||||
|
case MODE_SMMA:
|
||||||
|
SmoothedMAOnBuffer(rates_total, _prev_calculated, 0, _period, customChartIndicator.High, MaHighBuffer);
|
||||||
|
SmoothedMAOnBuffer(rates_total, _prev_calculated, 0, _period, customChartIndicator.Low, MaLowBuffer);
|
||||||
|
break;
|
||||||
|
case MODE_LWMA:
|
||||||
|
LinearWeightedMAOnBuffer(rates_total, _prev_calculated, 0, _period, customChartIndicator.High, MaHighBuffer);
|
||||||
|
LinearWeightedMAOnBuffer(rates_total, _prev_calculated, 0, _period, customChartIndicator.Low, MaLowBuffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//--- main cycle
|
//--- main cycle
|
||||||
for(int i=limit; i>=0 && !_StopFlag; i--)
|
for(int i=limit; i>=0 && !_StopFlag; i--)
|
||||||
{
|
{
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,395 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| HalfTrend.mq5 |
|
||||||
|
//| Copyright 2020, MetaQuotes Software Corp. |
|
||||||
|
//| https://www.mql5.com |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "Copyright 2020, MetaQuotes Software Corp."
|
||||||
|
#property link "https://www.mql5.com"
|
||||||
|
#property version "1.00"
|
||||||
|
#property strict
|
||||||
|
#property indicator_chart_window
|
||||||
|
#property indicator_buffers 10
|
||||||
|
#property indicator_plots 6
|
||||||
|
//--- plot
|
||||||
|
#property indicator_label1 "UP"
|
||||||
|
#property indicator_color1 MediumOrchid // up[] DodgerBlue
|
||||||
|
#property indicator_type1 DRAW_LINE
|
||||||
|
#property indicator_width1 2
|
||||||
|
|
||||||
|
#property indicator_label2 "DN"
|
||||||
|
#property indicator_color2 Red // down[]
|
||||||
|
#property indicator_type2 DRAW_LINE
|
||||||
|
#property indicator_width2 2
|
||||||
|
|
||||||
|
#property indicator_label3 "ATR-LOW"
|
||||||
|
#property indicator_color3 Red // atrlo[],atrhi[]
|
||||||
|
#property indicator_type3 DRAW_LINE //
|
||||||
|
#property indicator_width3 1
|
||||||
|
|
||||||
|
#property indicator_label4 "ATR-HIGH"
|
||||||
|
#property indicator_color4 MediumOrchid // atrlo[],atrhi[]
|
||||||
|
#property indicator_type4 DRAW_LINE //From Histogram
|
||||||
|
#property indicator_width4 1
|
||||||
|
|
||||||
|
#property indicator_label5 "ARR-UP"
|
||||||
|
#property indicator_color5 MediumOrchid // arrdwn[]
|
||||||
|
#property indicator_type5 DRAW_ARROW
|
||||||
|
#property indicator_width5 1
|
||||||
|
|
||||||
|
#property indicator_label6 "ARR-DN"
|
||||||
|
#property indicator_color6 Red // arrup[]
|
||||||
|
#property indicator_type6 DRAW_ARROW
|
||||||
|
#property indicator_width6 1
|
||||||
|
|
||||||
|
input int Diamond = 2;
|
||||||
|
input int ChannelDeviation = 2;
|
||||||
|
input bool ShowChannels = true;
|
||||||
|
input bool ShowArrows = true;
|
||||||
|
input bool alertsOn = false;
|
||||||
|
input bool alertsOnCurrent = false;
|
||||||
|
input bool alertsMessage = true;
|
||||||
|
input bool alertsSound = true;
|
||||||
|
input bool alertsEmail = false;
|
||||||
|
input int lookback = 256; // Maximum lookback period
|
||||||
|
|
||||||
|
bool nexttrend;
|
||||||
|
double minhighprice, maxlowprice;
|
||||||
|
double up[], down[], atrlo[], atrhi[], trend[];
|
||||||
|
double arrup[], arrdwn[];
|
||||||
|
//int ind_mahi, ind_malo, ind_atr;
|
||||||
|
//double iMAHigh[], iMALow[], iATRx[];
|
||||||
|
|
||||||
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
|
#include <AZ-INVEST/SDK/IndicatorAccess.mqh>
|
||||||
|
#include <IncOnRingBuffer\CATROnRingBuffer.mqh>
|
||||||
|
#include <IncOnRingBuffer\CMAOnRingBuffer.mqh>
|
||||||
|
|
||||||
|
CIndicatorAccess iAccess;
|
||||||
|
CATROnRingBuffer atr;
|
||||||
|
CMAOnRingBuffer maHigh;
|
||||||
|
CMAOnRingBuffer maLow;
|
||||||
|
|
||||||
|
//iMAHigh, iMALow, iATRx
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
SetIndexBuffer(0, up, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(1, down, INDICATOR_DATA);
|
||||||
|
|
||||||
|
SetIndexBuffer(2, atrlo, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(3, atrhi, INDICATOR_DATA);
|
||||||
|
|
||||||
|
SetIndexBuffer(4, arrup, INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(5, arrdwn, INDICATOR_DATA);
|
||||||
|
|
||||||
|
SetIndexBuffer(6, trend, INDICATOR_CALCULATIONS);
|
||||||
|
// SetIndexBuffer(7, iMAHigh, INDICATOR_CALCULATIONS);
|
||||||
|
// SetIndexBuffer(8, iMALow, INDICATOR_CALCULATIONS);
|
||||||
|
// SetIndexBuffer(9, iATRx, INDICATOR_CALCULATIONS);
|
||||||
|
|
||||||
|
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
|
||||||
|
PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
|
||||||
|
ArraySetAsSeries(up, true);
|
||||||
|
ArraySetAsSeries(down, true);
|
||||||
|
ArraySetAsSeries(atrlo, true);
|
||||||
|
ArraySetAsSeries(atrhi, true);
|
||||||
|
ArraySetAsSeries(arrup, true);
|
||||||
|
ArraySetAsSeries(arrdwn, true);
|
||||||
|
ArraySetAsSeries(trend, true);
|
||||||
|
// ArraySetAsSeries(iMAHigh, true);
|
||||||
|
// ArraySetAsSeries(iMALow, true);
|
||||||
|
// ArraySetAsSeries(iATRx, true);
|
||||||
|
if(ShowChannels)
|
||||||
|
{
|
||||||
|
|
||||||
|
PlotIndexSetInteger(2,PLOT_LINE_COLOR,0,clrDodgerBlue);
|
||||||
|
PlotIndexSetInteger(3,PLOT_LINE_COLOR,0,clrRed);
|
||||||
|
PlotIndexSetInteger(2,PLOT_LINE_STYLE,STYLE_DOT);
|
||||||
|
PlotIndexSetInteger(3,PLOT_LINE_STYLE,STYLE_DOT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlotIndexSetInteger(2,PLOT_LINE_COLOR,0,clrNONE);
|
||||||
|
PlotIndexSetInteger(3,PLOT_LINE_COLOR,0,clrNONE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(ShowArrows)
|
||||||
|
{
|
||||||
|
|
||||||
|
bool rep5= PlotIndexSetInteger(4, PLOT_DRAW_TYPE, DRAW_ARROW);
|
||||||
|
bool rep6=PlotIndexSetInteger(5, PLOT_DRAW_TYPE, DRAW_ARROW);
|
||||||
|
PlotIndexSetInteger(4, PLOT_ARROW, 233); //233
|
||||||
|
PlotIndexSetInteger(5, PLOT_ARROW, 234); //234
|
||||||
|
//Comment(ShowArrows +"\n"+rep5 +"\n"+ rep6);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ PlotIndexSetInteger(4, PLOT_DRAW_TYPE, DRAW_NONE);
|
||||||
|
PlotIndexSetInteger(5, PLOT_DRAW_TYPE, DRAW_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//ind_mahi = iMA(NULL, 0, Diamond, 0, MODE_SMA, PRICE_HIGH);
|
||||||
|
//ind_malo = iMA(NULL, 0, Diamond, 0, MODE_SMA, PRICE_LOW);
|
||||||
|
//ind_atr = iATR(NULL, 0, 100);
|
||||||
|
//if(ind_mahi == INVALID_HANDLE || ind_mahi == INVALID_HANDLE || ind_atr == INVALID_HANDLE)
|
||||||
|
// {
|
||||||
|
// PrintFormat("Failed to create handle of the indicators, error code %d", GetLastError());
|
||||||
|
// return(INIT_FAILED);
|
||||||
|
//}
|
||||||
|
|
||||||
|
customChartIndicator.SetGetTimeFlag();
|
||||||
|
|
||||||
|
if(!atr.Init(100,MODE_SMA,lookback))
|
||||||
|
{
|
||||||
|
PrintFormat("Failed to create ATR on ring buffer");
|
||||||
|
return(INIT_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!maHigh.Init(Diamond, MODE_SMA, lookback))
|
||||||
|
{
|
||||||
|
PrintFormat("Failed to create maHigh on ring buffer");
|
||||||
|
return(INIT_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!maLow.Init(Diamond, MODE_SMA, lookback))
|
||||||
|
{
|
||||||
|
PrintFormat("Failed to create maLow on ring buffer");
|
||||||
|
return(INIT_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nexttrend = 0;
|
||||||
|
minhighprice = iHigh(NULL, 0, Bars(NULL, 0) - 1); // ?
|
||||||
|
maxlowprice = iLow(NULL, 0, Bars(NULL, 0) - 1); // ?
|
||||||
|
return (INIT_SUCCEEDED);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| |`
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnCalculate(
|
||||||
|
const int rates_total, // size of input time series
|
||||||
|
const int prev_calculated, // number of handled bars at the previous call
|
||||||
|
const datetime& time[], // Time array
|
||||||
|
const double& open[], // Open array
|
||||||
|
const double& high[], // High array
|
||||||
|
const double& low[], // Low array
|
||||||
|
const double& close[], // Close array
|
||||||
|
const long& tick_volume[], // Tick Volume array
|
||||||
|
const long& volume[], // Real Volume array
|
||||||
|
const int& spread[] // Spread array
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Process data through custom chart indicator
|
||||||
|
//
|
||||||
|
|
||||||
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
int _rates_total = ArraySize(customChartIndicator.Close);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
int i, limit, to_copy;
|
||||||
|
double _atr, lowprice_i, highprice_i, lowma, highma;
|
||||||
|
|
||||||
|
ArraySetAsSeries(customChartIndicator.Time, true);
|
||||||
|
ArraySetAsSeries(customChartIndicator.High, true);
|
||||||
|
ArraySetAsSeries(customChartIndicator.Low, true);
|
||||||
|
ArraySetAsSeries(customChartIndicator.Close, true);
|
||||||
|
|
||||||
|
if(_prev_calculated > _rates_total || _prev_calculated < 0) to_copy = _rates_total;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
to_copy = _rates_total - _prev_calculated;
|
||||||
|
if(_prev_calculated > 0)
|
||||||
|
to_copy += 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if(!RefreshBuffers(iMAHigh, iMALow, iATRx, ind_mahi, ind_malo, ind_atr, to_copy))
|
||||||
|
// return(0);
|
||||||
|
|
||||||
|
atr.MainOnArray(_rates_total,_prev_calculated,customChartIndicator.High,customChartIndicator.Low,customChartIndicator.Close);
|
||||||
|
maHigh.MainOnArray(_rates_total, _prev_calculated, customChartIndicator.High);
|
||||||
|
maLow.MainOnArray(_rates_total, _prev_calculated, customChartIndicator.Low);
|
||||||
|
//
|
||||||
|
|
||||||
|
if(_prev_calculated == 0)
|
||||||
|
limit = _rates_total - 2;
|
||||||
|
else
|
||||||
|
limit = _rates_total - _prev_calculated + 1;
|
||||||
|
|
||||||
|
for(i = limit; i >= 0; i--)
|
||||||
|
{
|
||||||
|
//lowprice_i = iLow(NULL, 0, iLowest(NULL, 0, MODE_LOW, Diamond, i));
|
||||||
|
//highprice_i = iHigh(NULL, 0, iHighest(NULL, 0, MODE_HIGH, Diamond, i));
|
||||||
|
//lowma = NormalizeDouble(iMALow[i], _Digits);
|
||||||
|
//highma = NormalizeDouble(iMAHigh[i], _Digits);
|
||||||
|
|
||||||
|
lowprice_i = customChartIndicator.Low[iAccess.Lowest(customChartIndicator.Low, Diamond, i)];
|
||||||
|
highprice_i = customChartIndicator.High[iAccess.Highest(customChartIndicator.High, Diamond, i)];
|
||||||
|
lowma = NormalizeDouble(maLow[i], _Digits);
|
||||||
|
highma = NormalizeDouble(maHigh[i], _Digits);
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
trend[i] = trend[i + 1];
|
||||||
|
|
||||||
|
//atr = iATRx[i] / 2;
|
||||||
|
_atr = atr[i] / 2;
|
||||||
|
|
||||||
|
arrup[i] = EMPTY_VALUE;
|
||||||
|
arrdwn[i] = EMPTY_VALUE;
|
||||||
|
|
||||||
|
if(trend[i + 1] != 1.0)
|
||||||
|
{
|
||||||
|
maxlowprice = MathMax(lowprice_i, maxlowprice);
|
||||||
|
if(highma < maxlowprice && customChartIndicator.Close[i] < customChartIndicator.Low[i + 1])
|
||||||
|
{
|
||||||
|
trend[i] = 1.0;
|
||||||
|
nexttrend = 0;
|
||||||
|
minhighprice = highprice_i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
minhighprice = MathMin(highprice_i, minhighprice);
|
||||||
|
if(lowma > minhighprice && customChartIndicator.Close[i] > customChartIndicator.High[i + 1])
|
||||||
|
{
|
||||||
|
trend[i] = 0.0;
|
||||||
|
nexttrend = 1;
|
||||||
|
maxlowprice = lowprice_i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//---
|
||||||
|
if(trend[i] == 0.0)
|
||||||
|
{
|
||||||
|
if(trend[i + 1] != 0.0)
|
||||||
|
{
|
||||||
|
up[i] = down[i + 1];
|
||||||
|
up[i + 1] = up[i];
|
||||||
|
arrup[i] = up[i] - 2 * _atr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
up[i] = MathMax(maxlowprice, up[i + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
atrhi[i] = up[i] + ChannelDeviation*_atr;
|
||||||
|
atrlo[i] = up[i] - ChannelDeviation*_atr;
|
||||||
|
down[i] = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(trend[i + 1] != 1.0)
|
||||||
|
{
|
||||||
|
down[i] = up[i + 1];
|
||||||
|
down[i + 1] = down[i];
|
||||||
|
arrdwn[i] = down[i] + 2 * _atr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
down[i] = MathMin(minhighprice, down[i + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
atrhi[i] = down[i] + ChannelDeviation*_atr;
|
||||||
|
atrlo[i] = down[i] - ChannelDeviation*_atr;
|
||||||
|
up[i] = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
manageAlerts();
|
||||||
|
return (rates_total);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Filling indicator buffers from the indicators |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool RefreshBuffers(double &hi_buffer[],
|
||||||
|
double &lo_buffer[],
|
||||||
|
double &atr_buffer[],
|
||||||
|
int hi_handle,
|
||||||
|
int lo_handle,
|
||||||
|
int atr_handle,
|
||||||
|
int amount
|
||||||
|
)
|
||||||
|
{
|
||||||
|
//--- reset error code
|
||||||
|
ResetLastError();
|
||||||
|
//--- fill a part of the iMACDBuffer array with values from the indicator buffer that has 0 index
|
||||||
|
if(CopyBuffer(hi_handle, 0, 0, amount, hi_buffer) < 0)
|
||||||
|
{
|
||||||
|
//--- if the copying fails, tell the error code
|
||||||
|
PrintFormat("Failed to copy data from the MaHigh indicator, error code %d", GetLastError());
|
||||||
|
//--- quit with zero result - it means that the indicator is considered as not calculated
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
//--- fill a part of the SignalBuffer array with values from the indicator buffer that has index 1
|
||||||
|
if(CopyBuffer(lo_handle, 0, 0, amount, lo_buffer) < 0)
|
||||||
|
{
|
||||||
|
//--- if the copying fails, tell the error code
|
||||||
|
PrintFormat("Failed to copy data from the MaLow indicator, error code %d", GetLastError());
|
||||||
|
//--- quit with zero result - it means that the indicator is considered as not calculated
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
//--- fill a part of the StdDevBuffer array with values from the indicator buffer
|
||||||
|
if(CopyBuffer(atr_handle, 0, 0, amount, atr_buffer) < 0)
|
||||||
|
{
|
||||||
|
//--- if the copying fails, tell the error code
|
||||||
|
PrintFormat("Failed to copy data from the ATR indicator, error code %d", GetLastError());
|
||||||
|
//--- quit with zero result - it means that the indicator is considered as not calculated
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
//--- everything is fine
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void manageAlerts()
|
||||||
|
{
|
||||||
|
int whichBar;
|
||||||
|
if (alertsOn)
|
||||||
|
{
|
||||||
|
if (alertsOnCurrent)
|
||||||
|
whichBar = 0;
|
||||||
|
else
|
||||||
|
whichBar = 1;
|
||||||
|
if (arrup[whichBar] != EMPTY_VALUE) doAlert(whichBar, "up");
|
||||||
|
if (arrdwn[whichBar] != EMPTY_VALUE) doAlert(whichBar, "down");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void doAlert(int forBar, string doWhat)
|
||||||
|
{
|
||||||
|
static string previousAlert = "nothing";
|
||||||
|
static datetime previousTime;
|
||||||
|
string message;
|
||||||
|
if (previousAlert != doWhat || previousTime != iTime(NULL, 0, forBar))
|
||||||
|
{
|
||||||
|
previousAlert = doWhat;
|
||||||
|
previousTime = iTime(NULL, 0, forBar);
|
||||||
|
message = StringFormat("%s at %s", Symbol(), TimeToString(TimeLocal(), TIME_SECONDS), " HalfTrend signal ", doWhat);
|
||||||
|
if (alertsMessage) Alert(message);
|
||||||
|
if (alertsEmail) SendMail(Symbol(), StringFormat("HalfTrend %s", message));
|
||||||
|
if (alertsSound) PlaySound("alert2.wav");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
Binary file not shown.
+28
-8
@@ -20,15 +20,10 @@ double ExtLBuffer[];
|
|||||||
double ExtCBuffer[];
|
double ExtCBuffer[];
|
||||||
double ExtColorBuffer[];
|
double ExtColorBuffer[];
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -67,13 +62,38 @@ int OnCalculate(const int rates_total,
|
|||||||
int i,limit;
|
int i,limit;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// Process data through MedianRenko indicator
|
||||||
|
//
|
||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
//
|
//
|
||||||
Binary file not shown.
@@ -6,7 +6,6 @@
|
|||||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||||
#property link "http://www.mql5.com"
|
#property link "http://www.mql5.com"
|
||||||
#property description "Ichimoku Kinko Hyo"
|
#property description "Ichimoku Kinko Hyo"
|
||||||
#property description "Adapted for use with TickChart by Artur Zas."
|
|
||||||
//--- indicator settings
|
//--- indicator settings
|
||||||
#property indicator_chart_window
|
#property indicator_chart_window
|
||||||
#property indicator_buffers 5
|
#property indicator_buffers 5
|
||||||
@@ -34,15 +33,10 @@ double ExtSpanABuffer[];
|
|||||||
double ExtSpanBBuffer[];
|
double ExtSpanBBuffer[];
|
||||||
double ExtChikouBuffer[];
|
double ExtChikouBuffer[];
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -116,13 +110,38 @@ int OnCalculate(const int rates_total,
|
|||||||
const int &spread[])
|
const int &spread[])
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
// Process data through MedianRenko indicator
|
||||||
|
//
|
||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
//
|
//
|
||||||
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+5
-2
@@ -14,8 +14,11 @@ input int LRPeriod = 20; // Bars in regression
|
|||||||
// The main buffer - drawing a line on a chart
|
// The main buffer - drawing a line on a chart
|
||||||
double ExtLRBuffer[];
|
double ExtLRBuffer[];
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
//
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
void OnInit()
|
void OnInit()
|
||||||
Binary file not shown.
@@ -21,15 +21,10 @@ input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_CLOSE;
|
|||||||
//--- indicator buffers
|
//--- indicator buffers
|
||||||
double ExtLineBuffer[];
|
double ExtLineBuffer[];
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -197,16 +192,43 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
{
|
{
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// Process data through MedianRenko indicator
|
||||||
|
//
|
||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
int _begin = 0;
|
int _begin = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
//--- check for bars count
|
//--- check for bars count
|
||||||
Binary file not shown.
@@ -6,8 +6,6 @@
|
|||||||
#property copyright "2009, MetaQuotes Software Corp."
|
#property copyright "2009, MetaQuotes Software Corp."
|
||||||
#property link "http://www.mql5.com"
|
#property link "http://www.mql5.com"
|
||||||
#property description "Moving Average Convergence/Divergence"
|
#property description "Moving Average Convergence/Divergence"
|
||||||
#property description "Adapted for use with TickChart by Artur Zas."
|
|
||||||
|
|
||||||
#include <MovingAverages.mqh>
|
#include <MovingAverages.mqh>
|
||||||
//--- indicator settings
|
//--- indicator settings
|
||||||
#property indicator_separate_window
|
#property indicator_separate_window
|
||||||
@@ -37,8 +35,11 @@ double ExtFastMaBuffer[];
|
|||||||
double ExtSlowMaBuffer[];
|
double ExtSlowMaBuffer[];
|
||||||
double ExtMacdBuffer[];
|
double ExtMacdBuffer[];
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
//
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| Custom indicator initialization function |
|
//| Custom indicator initialization function |
|
||||||
@@ -72,36 +73,62 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
const long &Volume[],
|
const long &Volume[],
|
||||||
const int &Spread[])
|
const int &Spread[])
|
||||||
{
|
{
|
||||||
|
//
|
||||||
|
// Process data through MedianRenko indicator
|
||||||
|
//
|
||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
int _rates_total = customChartIndicator.GetRatesTotal();
|
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
//--- check for data
|
//--- check for data
|
||||||
if(_rates_total<InpSignalSMA)
|
if(rates_total<InpSignalSMA)
|
||||||
return(0);
|
return(0);
|
||||||
//--- we can copy not all data
|
//--- we can copy not all data
|
||||||
int to_copy;
|
int to_copy;
|
||||||
if(_prev_calculated>_rates_total || _prev_calculated<0) to_copy=_rates_total;
|
if(_prev_calculated>rates_total || _prev_calculated<0) to_copy=rates_total;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
to_copy=_rates_total-_prev_calculated;
|
to_copy=rates_total-_prev_calculated;
|
||||||
if(_prev_calculated>0) to_copy++;
|
if(_prev_calculated>0) to_copy++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--- get Fast EMA buffer
|
//--- get Fast EMA buffer
|
||||||
if(IsStopped()) return(0); //Checking for stop flag
|
if(IsStopped()) return(0); //Checking for stop flag
|
||||||
ExponentialMAOnBuffer(_rates_total,_prev_calculated,0,InpFastEMA,customChartIndicator.Close,ExtFastMaBuffer);
|
ExponentialMAOnBuffer(rates_total,_prev_calculated,0,InpFastEMA,customChartIndicator.Close,ExtFastMaBuffer);
|
||||||
//--- get SlowSMA buffer
|
//--- get SlowSMA buffer
|
||||||
if(IsStopped()) return(0); //Checking for stop flag
|
if(IsStopped()) return(0); //Checking for stop flag
|
||||||
ExponentialMAOnBuffer(_rates_total,_prev_calculated,0,InpSlowEMA,customChartIndicator.Close,ExtSlowMaBuffer);
|
ExponentialMAOnBuffer(rates_total,_prev_calculated,0,InpSlowEMA,customChartIndicator.Close,ExtSlowMaBuffer);
|
||||||
//---
|
//---
|
||||||
int limit;
|
int limit;
|
||||||
if(_prev_calculated==0)
|
if(_prev_calculated==0)
|
||||||
@@ -109,7 +136,7 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
else limit=_prev_calculated-1;
|
else limit=_prev_calculated-1;
|
||||||
//--- calculate MACD
|
//--- calculate MACD
|
||||||
|
|
||||||
for(int i=limit;i<_rates_total && !IsStopped();i++)
|
for(int i=limit;i<rates_total && !IsStopped();i++)
|
||||||
{
|
{
|
||||||
ExtMacdBuffer[i] = ExtFastMaBuffer[i]-ExtSlowMaBuffer[i];
|
ExtMacdBuffer[i] = ExtFastMaBuffer[i]-ExtSlowMaBuffer[i];
|
||||||
if(ExtMacdBuffer[i] > 0)
|
if(ExtMacdBuffer[i] > 0)
|
||||||
@@ -124,9 +151,8 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//--- calculate Signal
|
//--- calculate Signal
|
||||||
SimpleMAOnBuffer(_rates_total,_prev_calculated,0,InpSignalSMA,ExtMacdBuffer,ExtSignalBuffer);
|
SimpleMAOnBuffer(rates_total,_prev_calculated,0,InpSignalSMA,ExtMacdBuffer,ExtSignalBuffer);
|
||||||
//--- OnCalculate done. Return new _prev_calculated.
|
//--- OnCalculate done. Return new _prev_calculated.
|
||||||
|
|
||||||
return(rates_total);
|
return(rates_total);
|
||||||
}
|
}
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
Binary file not shown.
@@ -6,8 +6,6 @@
|
|||||||
#property copyright "2009, MetaQuotes Software Corp."
|
#property copyright "2009, MetaQuotes Software Corp."
|
||||||
#property link "http://www.mql5.com"
|
#property link "http://www.mql5.com"
|
||||||
#property description "Moving Average Convergence/Divergence"
|
#property description "Moving Average Convergence/Divergence"
|
||||||
#property description "Adapted for use with TickChart by Artur Zas."
|
|
||||||
|
|
||||||
#include <MovingAverages.mqh>
|
#include <MovingAverages.mqh>
|
||||||
//--- indicator settings
|
//--- indicator settings
|
||||||
#property indicator_separate_window
|
#property indicator_separate_window
|
||||||
@@ -35,8 +33,7 @@ double ExtMacdBuffer[];
|
|||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
@@ -78,13 +75,12 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
int _rates_total = customChartIndicator.GetRatesTotal();
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -100,7 +96,6 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
to_copy=rates_total-_prev_calculated;
|
to_copy=rates_total-_prev_calculated;
|
||||||
if(_prev_calculated>0) to_copy++;
|
if(_prev_calculated>0) to_copy++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--- get Fast EMA buffer
|
//--- get Fast EMA buffer
|
||||||
if(IsStopped()) return(0); //Checking for stop flag
|
if(IsStopped()) return(0); //Checking for stop flag
|
||||||
ExponentialMAOnBuffer(rates_total,_prev_calculated,0,InpFastEMA,customChartIndicator.Close,ExtFastMaBuffer);
|
ExponentialMAOnBuffer(rates_total,_prev_calculated,0,InpFastEMA,customChartIndicator.Close,ExtFastMaBuffer);
|
||||||
Binary file not shown.
@@ -21,16 +21,12 @@ double ExtMomentumBuffer[];
|
|||||||
//--- global variable
|
//--- global variable
|
||||||
int ExtMomentumPeriod;
|
int ExtMomentumPeriod;
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
|
||||||
//
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| Custom indicator initialization function |
|
//| Custom indicator initialization function |
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -88,15 +84,42 @@ int OnCalculate(const int rates_total,const int prev_calculated,
|
|||||||
static int begin = 0;
|
static int begin = 0;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// Process data through MedianRenko indicator
|
||||||
|
//
|
||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,Time,Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
if(!customChartIndicator.BufferSynchronizationCheck(Close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
//--- start calculation
|
//--- start calculation
|
||||||
Binary file not shown.
@@ -47,15 +47,10 @@ double Trend[];
|
|||||||
double ATRBuffer[];
|
double ATRBuffer[];
|
||||||
int Handle;
|
int Handle;
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -106,13 +101,38 @@ int OnCalculate(const int rates_total,
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
// Process data through MedianRenko indicator
|
||||||
|
//
|
||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
//
|
//
|
||||||
Binary file not shown.
@@ -18,18 +18,11 @@ input ENUM_APPLIED_VOLUME InpVolumeType=VOLUME_TICK; // Volumes
|
|||||||
//---- indicator buffer
|
//---- indicator buffer
|
||||||
double ExtOBVBuffer[];
|
double ExtOBVBuffer[];
|
||||||
|
|
||||||
//
|
|
||||||
// Initialize RangeBar indicator for data processing
|
|
||||||
// according to settings of the RangeBar indicator already on chart
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
//| On Balance Volume initialization function |
|
//| On Balance Volume initialization function |
|
||||||
@@ -60,12 +53,12 @@ int OnCalculate(const int rates_total,
|
|||||||
const int &spread[])
|
const int &spread[])
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Process data through RangeBar indicator
|
// Process data through MedianRenko indicator
|
||||||
//
|
//
|
||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
Binary file not shown.
@@ -0,0 +1,679 @@
|
|||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Oscillator Candles.mq5 |
|
||||||
|
//| Copyright 2015, MetaQuotes Software Corp. |
|
||||||
|
//| https://www.mql5.com |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
#property copyright "Copyright 2015, MetaQuotes Software Corp."
|
||||||
|
#property link "https://www.mql5.com"
|
||||||
|
#property description"Oscillator Candles by pipPod"
|
||||||
|
#property version "1.00"
|
||||||
|
#property indicator_separate_window
|
||||||
|
#property indicator_buffers 7
|
||||||
|
#property indicator_plots 1
|
||||||
|
//---
|
||||||
|
#property indicator_type1 DRAW_COLOR_CANDLES
|
||||||
|
#property indicator_color1 clrLimeGreen,clrFireBrick
|
||||||
|
//---
|
||||||
|
#property indicator_levelcolor clrLightSlateGray
|
||||||
|
//---
|
||||||
|
double indicator_level1= 0;
|
||||||
|
double indicator_level2= 20;
|
||||||
|
double indicator_level3= 30;
|
||||||
|
double indicator_level4= 50;
|
||||||
|
double indicator_level5= 70;
|
||||||
|
double indicator_level6= 80;
|
||||||
|
double indicator_level7= 100;
|
||||||
|
double indicator_level8=-100;
|
||||||
|
//---
|
||||||
|
#include <MovingAverages.mqh>
|
||||||
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
enum indicators
|
||||||
|
{
|
||||||
|
INDICATOR_MACD, //Moving Average Convergence/Divergence
|
||||||
|
INDICATOR_STOCHASTIC, //Stochastic Oscillator
|
||||||
|
INDICATOR_RSI, //Relative Strength Index
|
||||||
|
INDICATOR_CCI, //Commodity Channel Index
|
||||||
|
INDICATOR_MOMENTUM, //Momentum Index
|
||||||
|
};
|
||||||
|
//--- indicator to show
|
||||||
|
input indicators Indicator=INDICATOR_MACD;
|
||||||
|
//--- indicator parameters
|
||||||
|
input string MACD;
|
||||||
|
input ushort FastEMA=12; //Fast EMA Period
|
||||||
|
input ushort SlowEMA=26; //Slow EMA Period
|
||||||
|
//---
|
||||||
|
input string Stochastic;
|
||||||
|
input ushort Kperiod=7; //K Period
|
||||||
|
input ushort Slowing=3;
|
||||||
|
input ENUM_STO_PRICE PriceField=STO_LOWHIGH; //Price Field
|
||||||
|
//---
|
||||||
|
input string RSI;
|
||||||
|
input ushort RSIPeriod=14; //RSI Period
|
||||||
|
//---
|
||||||
|
input string CCI;
|
||||||
|
input ushort CCIPeriod=14; //CCI Period
|
||||||
|
//---
|
||||||
|
input string Momentum;
|
||||||
|
input ushort MomPeriod=14; //Momentum Period
|
||||||
|
//---
|
||||||
|
input string _; //---
|
||||||
|
input bool PriceLine=true; //Horizontal Value Line
|
||||||
|
#define priceLine "priceLine"
|
||||||
|
input bool AutoColor=false;//Auto Color Candles
|
||||||
|
//---index buffers for drawing candles
|
||||||
|
double OpenBuffer[];
|
||||||
|
double HighBuffer[];
|
||||||
|
double LowBuffer[];
|
||||||
|
double CloseBuffer[];
|
||||||
|
double ColorBuffer[];
|
||||||
|
//---Stochastic buffers
|
||||||
|
double HighesBuffer[];
|
||||||
|
double LowestBuffer[];
|
||||||
|
//---CCI buffers
|
||||||
|
double PriceBuffer[];
|
||||||
|
double MovAvBuffer[];
|
||||||
|
//---
|
||||||
|
long chartID=ChartID();
|
||||||
|
short window;
|
||||||
|
#define OBJ_NONE -1
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int OnInit()
|
||||||
|
{
|
||||||
|
string shortName;
|
||||||
|
switch(Indicator)
|
||||||
|
{
|
||||||
|
case INDICATOR_MACD:
|
||||||
|
shortName=StringFormat("MACD(%d,%d)",FastEMA,SlowEMA);
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
|
||||||
|
IndicatorSetInteger(INDICATOR_LEVELS,1);
|
||||||
|
IndicatorSetDouble(INDICATOR_LEVELVALUE,0,indicator_level1);
|
||||||
|
PlotIndexSetString(0,PLOT_LABEL,"MACD Open;MACD High;MACD Low;MACD Close");
|
||||||
|
for(int i=0;i<5;i++)
|
||||||
|
PlotIndexSetInteger(i,PLOT_DRAW_BEGIN,SlowEMA-1);
|
||||||
|
break;
|
||||||
|
case INDICATOR_STOCHASTIC:
|
||||||
|
shortName=StringFormat("Stochastic(%d,%d)",Kperiod,Slowing);
|
||||||
|
SetIndexBuffer(5,HighesBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
SetIndexBuffer(6,LowestBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,0);
|
||||||
|
IndicatorSetInteger(INDICATOR_LEVELS,3);
|
||||||
|
IndicatorSetDouble(INDICATOR_LEVELVALUE,0,indicator_level2);
|
||||||
|
IndicatorSetDouble(INDICATOR_LEVELVALUE,1,indicator_level4);
|
||||||
|
IndicatorSetDouble(INDICATOR_LEVELVALUE,2,indicator_level6);
|
||||||
|
PlotIndexSetString(0,PLOT_LABEL,"Stoch Open;Stoch High;Stoch Low;Stoch Close");
|
||||||
|
for(int i=0;i<5;i++)
|
||||||
|
PlotIndexSetInteger(i,PLOT_DRAW_BEGIN,Kperiod-1+Slowing-1);
|
||||||
|
break;
|
||||||
|
case INDICATOR_RSI:
|
||||||
|
shortName=StringFormat("RSI(%d)",RSIPeriod);
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,0);
|
||||||
|
IndicatorSetInteger(INDICATOR_LEVELS,3);
|
||||||
|
IndicatorSetDouble(INDICATOR_LEVELVALUE,0,indicator_level3);
|
||||||
|
IndicatorSetDouble(INDICATOR_LEVELVALUE,1,indicator_level4);
|
||||||
|
IndicatorSetDouble(INDICATOR_LEVELVALUE,2,indicator_level5);
|
||||||
|
PlotIndexSetString(0,PLOT_LABEL,"RSI Open;RSI High;RSI Low;RSI Close");
|
||||||
|
for(int i=0;i<5;i++)
|
||||||
|
PlotIndexSetInteger(i,PLOT_DRAW_BEGIN,RSIPeriod-1);
|
||||||
|
break;
|
||||||
|
case INDICATOR_CCI:
|
||||||
|
shortName=StringFormat("CCI(%d)",CCIPeriod);
|
||||||
|
SetIndexBuffer(5,PriceBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
SetIndexBuffer(6,MovAvBuffer,INDICATOR_CALCULATIONS);
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,0);
|
||||||
|
IndicatorSetInteger(INDICATOR_LEVELS,3);
|
||||||
|
IndicatorSetDouble(INDICATOR_LEVELVALUE,0,indicator_level1);
|
||||||
|
IndicatorSetDouble(INDICATOR_LEVELVALUE,1,indicator_level7);
|
||||||
|
IndicatorSetDouble(INDICATOR_LEVELVALUE,2,indicator_level8);
|
||||||
|
PlotIndexSetString(0,PLOT_LABEL,"CCI Open;CCI High;CCI Low;CCI Close");
|
||||||
|
for(int i=0;i<5;i++)
|
||||||
|
PlotIndexSetInteger(i,PLOT_DRAW_BEGIN,CCIPeriod-1);
|
||||||
|
break;
|
||||||
|
case INDICATOR_MOMENTUM:
|
||||||
|
shortName=StringFormat("Momentum(%d)",MomPeriod);
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,2);
|
||||||
|
IndicatorSetInteger(INDICATOR_LEVELS,1);
|
||||||
|
IndicatorSetDouble(INDICATOR_LEVELVALUE,0,indicator_level7);
|
||||||
|
PlotIndexSetString(0,PLOT_LABEL,"Mom Open;Mom High;Mom Low;Mom Close");
|
||||||
|
for(int i=0;i<5;i++)
|
||||||
|
PlotIndexSetInteger(i,PLOT_DRAW_BEGIN,MomPeriod-1);
|
||||||
|
}
|
||||||
|
//---set name, get window
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME,shortName);
|
||||||
|
window=(short)ChartWindowFind(chartID,shortName);
|
||||||
|
//---index buffers
|
||||||
|
SetIndexBuffer(0,OpenBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(1,HighBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(2,LowBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(3,CloseBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(4,ColorBuffer,INDICATOR_COLOR_INDEX);
|
||||||
|
//---color bars
|
||||||
|
if(AutoColor)
|
||||||
|
SetColors();
|
||||||
|
//---delete price line
|
||||||
|
if(!PriceLine && ObjectFind(chartID,priceLine)!=OBJ_NONE)
|
||||||
|
ObjectDelete(chartID,priceLine);
|
||||||
|
//---
|
||||||
|
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(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
//---bars to count
|
||||||
|
int toFill=rates_total-_prev_calculated;
|
||||||
|
if(_prev_calculated>0)
|
||||||
|
toFill++;
|
||||||
|
//---fill OHLC buffers
|
||||||
|
switch(Indicator)
|
||||||
|
{
|
||||||
|
case INDICATOR_MACD:
|
||||||
|
if(MACD(customChartIndicator.GetRatesTotal(),_prev_calculated,customChartIndicator.High,customChartIndicator.Low,customChartIndicator.Close)!=toFill)
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
case INDICATOR_STOCHASTIC:
|
||||||
|
if(Stochastic(customChartIndicator.GetRatesTotal(),_prev_calculated,customChartIndicator.High,customChartIndicator.Low,customChartIndicator.Close)!=toFill)
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
case INDICATOR_RSI:
|
||||||
|
if(RSI(customChartIndicator.GetRatesTotal(),_prev_calculated,customChartIndicator.High,customChartIndicator.Low,customChartIndicator.Close)!=toFill)
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
case INDICATOR_CCI:
|
||||||
|
if(CCI(customChartIndicator.GetRatesTotal(),_prev_calculated,customChartIndicator.High,customChartIndicator.Low,customChartIndicator.Close)!=toFill)
|
||||||
|
return(0);
|
||||||
|
break;
|
||||||
|
case INDICATOR_MOMENTUM:
|
||||||
|
if(Momentum(customChartIndicator.GetRatesTotal(),_prev_calculated,customChartIndicator.High,customChartIndicator.Low,customChartIndicator.Close)!=toFill)
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
//--- return value of prev_calculated for next call
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Moving Average Convergence/Divergence |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int MACD(const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const double &high[],
|
||||||
|
const double &low[],
|
||||||
|
const double &close[])
|
||||||
|
{
|
||||||
|
//---check bars and input vars
|
||||||
|
if(rates_total<=SlowEMA || FastEMA<=1 || SlowEMA<FastEMA)
|
||||||
|
return(0);
|
||||||
|
//---declare vars
|
||||||
|
int begin,count=0;
|
||||||
|
double highFast,highSlow,
|
||||||
|
lowFast,lowSlow,
|
||||||
|
closeFast,closeSlow;
|
||||||
|
static double prevCloseFast,prevCloseSlow;
|
||||||
|
//--- initial zero
|
||||||
|
if(prev_calculated==0)
|
||||||
|
{
|
||||||
|
for(int i=0;i<SlowEMA && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
OpenBuffer[i]=HighBuffer[i]=LowBuffer[i]=CloseBuffer[i]=0.0;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
begin=SlowEMA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
begin=prev_calculated-1;
|
||||||
|
//--- calculate MACD
|
||||||
|
for(int i=begin;i<rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
highFast = ExponentialMA(i,FastEMA,prevCloseFast,high);
|
||||||
|
highSlow = ExponentialMA(i,SlowEMA,prevCloseSlow,high);
|
||||||
|
lowFast = ExponentialMA(i,FastEMA,prevCloseFast,low);
|
||||||
|
lowSlow = ExponentialMA(i,SlowEMA,prevCloseSlow,low);
|
||||||
|
closeFast = ExponentialMA(i,FastEMA,prevCloseFast,close);
|
||||||
|
closeSlow = ExponentialMA(i,SlowEMA,prevCloseSlow,close);
|
||||||
|
//---fill OHLC buffers
|
||||||
|
HighBuffer[i]= highFast-highSlow;
|
||||||
|
LowBuffer[i] = lowFast-lowSlow;
|
||||||
|
CloseBuffer[i]=closeFast-closeSlow;
|
||||||
|
//---check for new bar
|
||||||
|
static int k;
|
||||||
|
if(k!=i)
|
||||||
|
{
|
||||||
|
prevCloseFast = closeFast;
|
||||||
|
prevCloseSlow = closeSlow;
|
||||||
|
OpenBuffer[i] = CloseBuffer[i-1];
|
||||||
|
k=i;
|
||||||
|
}
|
||||||
|
//---set candle color
|
||||||
|
ColorBuffer[i]=(CloseBuffer[i]>OpenBuffer[i])?0:1;
|
||||||
|
//---horizontal value line
|
||||||
|
if(PriceLine)
|
||||||
|
PriceLine(CloseBuffer[i]);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
//--- macd done. return count.
|
||||||
|
return(count);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Stochastic Oscillator |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int Stochastic(const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const double &high[],
|
||||||
|
const double &low[],
|
||||||
|
const double &close[])
|
||||||
|
{
|
||||||
|
//--- check for bars count
|
||||||
|
if(rates_total<=Kperiod+Slowing || Kperiod<=1)
|
||||||
|
return(0);
|
||||||
|
//--- declare variables
|
||||||
|
int begin,count=0;
|
||||||
|
double sumLowH,sumLowL,sumLowC,sumHigh;
|
||||||
|
double min,max;
|
||||||
|
//---
|
||||||
|
begin=Kperiod-1;
|
||||||
|
if(begin<prev_calculated)
|
||||||
|
begin=prev_calculated-1;
|
||||||
|
else
|
||||||
|
for(int i=0;i<begin && !IsStopped();i++)
|
||||||
|
LowestBuffer[i]=HighesBuffer[i]=0.0;
|
||||||
|
//--- calculate HighesBuffer[] and LowestBuffer[]
|
||||||
|
for(int i=begin;i<rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
min = 1000000.0;
|
||||||
|
max =-1000000.0;
|
||||||
|
for(int k=(i-Kperiod+1);k<=i;k++)
|
||||||
|
{
|
||||||
|
switch(PriceField)
|
||||||
|
{
|
||||||
|
case STO_LOWHIGH:
|
||||||
|
if(min>low[k])
|
||||||
|
min=low[k];
|
||||||
|
if(max<high[k])
|
||||||
|
max=high[k];
|
||||||
|
break;
|
||||||
|
case STO_CLOSECLOSE:
|
||||||
|
if(min>close[k])
|
||||||
|
min=close[k];
|
||||||
|
if(max<close[k])
|
||||||
|
max=close[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LowestBuffer[i] = min;
|
||||||
|
HighesBuffer[i] = max;
|
||||||
|
}
|
||||||
|
//--- %K
|
||||||
|
begin=Kperiod-1;
|
||||||
|
if(begin<prev_calculated)
|
||||||
|
begin=prev_calculated-1;
|
||||||
|
else
|
||||||
|
for(int i=0;i<begin && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
OpenBuffer[i]=HighBuffer[i]=LowBuffer[i]=CloseBuffer[i]=0.0;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
//--- main cycle
|
||||||
|
for(int i=begin;i<rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
sumLowH=sumLowL=sumLowC=sumHigh=0.0;
|
||||||
|
for(int k=(i-Slowing+1);k<=i;k++)
|
||||||
|
{
|
||||||
|
sumLowH += (high[i]-LowestBuffer[k]);
|
||||||
|
sumLowL += (low[i]-LowestBuffer[k]);
|
||||||
|
sumLowC += (close[k]-LowestBuffer[k]);
|
||||||
|
sumHigh += (HighesBuffer[k]-LowestBuffer[k]);
|
||||||
|
}
|
||||||
|
//---check for new bar
|
||||||
|
static int k;
|
||||||
|
if(k!=i)
|
||||||
|
{
|
||||||
|
OpenBuffer[i]=CloseBuffer[i-1];
|
||||||
|
k=i;
|
||||||
|
}
|
||||||
|
//---check zero divide and fill candle buffers
|
||||||
|
if(sumHigh==0.0)
|
||||||
|
HighBuffer[i]=LowBuffer[i]=CloseBuffer[i]=50.0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HighBuffer[i]= OpenBuffer[i]+(sumLowH/sumHigh*100-OpenBuffer[i])/Slowing;
|
||||||
|
LowBuffer[i] = OpenBuffer[i]+(sumLowL/sumHigh*100-OpenBuffer[i])/Slowing;
|
||||||
|
CloseBuffer[i]=sumLowC/sumHigh*100;
|
||||||
|
}
|
||||||
|
//---set candle color
|
||||||
|
ColorBuffer[i]=(CloseBuffer[i]>OpenBuffer[i])?0:1;
|
||||||
|
//---horizontal value line
|
||||||
|
if(PriceLine)
|
||||||
|
PriceLine(CloseBuffer[i]);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
//--- stochastic done. return count.
|
||||||
|
return(count);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Relative Strength index |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int RSI(const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const double &high[],
|
||||||
|
const double &low[],
|
||||||
|
const double &close[])
|
||||||
|
{
|
||||||
|
//--- check bars and input vars
|
||||||
|
if(rates_total<=RSIPeriod || RSIPeriod<=1)
|
||||||
|
return(0);
|
||||||
|
int begin,count=0;
|
||||||
|
//--- declare vars
|
||||||
|
double diffC,
|
||||||
|
diffH,
|
||||||
|
diffL;
|
||||||
|
double currPositive = 0.0,
|
||||||
|
currNegative = 0.0;
|
||||||
|
static double prevPositive = 0.0,
|
||||||
|
prevNegative = 0.0;
|
||||||
|
//--- preliminary calculations
|
||||||
|
begin=prev_calculated-1;
|
||||||
|
if(begin<=RSIPeriod)
|
||||||
|
{
|
||||||
|
//--- first RSIPeriod values of the indicator are not calculated
|
||||||
|
OpenBuffer[0]=HighBuffer[0]=LowBuffer[0]=CloseBuffer[0]=0.0;
|
||||||
|
double sumPositive = 0.0,
|
||||||
|
sumNegative = 0.0;
|
||||||
|
count++;
|
||||||
|
for(int i=1;i<=RSIPeriod && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
OpenBuffer[i]=HighBuffer[i]=LowBuffer[i]=CloseBuffer[i]=0.0;
|
||||||
|
diffC=close[i]-close[i-1];
|
||||||
|
sumPositive += (diffC>0.0? diffC:0.0);
|
||||||
|
sumNegative += (diffC<0.0?-diffC:0.0);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
//--- calculate first visible value
|
||||||
|
currPositive = sumPositive/RSIPeriod;
|
||||||
|
currNegative = sumNegative/RSIPeriod;
|
||||||
|
//--- check zero divide, calculate first rsi and fill candle buffers
|
||||||
|
if(currNegative!=0.0)
|
||||||
|
OpenBuffer[RSIPeriod]=HighBuffer[RSIPeriod]=LowBuffer[RSIPeriod]=
|
||||||
|
CloseBuffer[RSIPeriod]=100.0-100.0/(1.0+currPositive/currNegative);
|
||||||
|
else
|
||||||
|
if(currPositive!=0.0)
|
||||||
|
OpenBuffer[RSIPeriod]=HighBuffer[RSIPeriod]=LowBuffer[RSIPeriod]=
|
||||||
|
CloseBuffer[RSIPeriod]=100.0;
|
||||||
|
else
|
||||||
|
OpenBuffer[RSIPeriod]=HighBuffer[RSIPeriod]=LowBuffer[RSIPeriod]=
|
||||||
|
CloseBuffer[RSIPeriod]=50.0;
|
||||||
|
prevPositive = currPositive;
|
||||||
|
prevNegative = currNegative;
|
||||||
|
//--- prepare the position value for main calculation
|
||||||
|
begin=RSIPeriod+1;
|
||||||
|
}
|
||||||
|
//--- the main loop of calculations
|
||||||
|
for(int i=begin;i<rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
diffC = close[i]-close[i-1];
|
||||||
|
diffH = (high[i]-close[i-1])/RSIPeriod;
|
||||||
|
diffL = (low[i]-close[i-1])/RSIPeriod;
|
||||||
|
currPositive = (prevPositive*(RSIPeriod-1)+(diffC>0.0? diffC:0.0))/RSIPeriod;
|
||||||
|
currNegative = (prevNegative*(RSIPeriod-1)+(diffC<0.0?-diffC:0.0))/RSIPeriod;
|
||||||
|
//--- check zero divide, calculate rsi and fill candle buffers
|
||||||
|
if(prevNegative!=0.0)
|
||||||
|
{
|
||||||
|
HighBuffer[i]= 100.0-100.0/(1.0+(prevPositive+diffH)/prevNegative);
|
||||||
|
LowBuffer[i] = 100.0-100.0/(1.0+prevPositive/(prevNegative-diffL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if(prevPositive!=0.0)
|
||||||
|
HighBuffer[i]= LowBuffer[i] = 100.0;
|
||||||
|
else
|
||||||
|
HighBuffer[i]=LowBuffer[i]=50.0;
|
||||||
|
if(currNegative!=0.0)
|
||||||
|
CloseBuffer[i]=100.0-100.0/(1.0+currPositive/currNegative);
|
||||||
|
else
|
||||||
|
if(currPositive!=0.0)
|
||||||
|
CloseBuffer[i]=100.0;
|
||||||
|
else
|
||||||
|
CloseBuffer[i]=50.0;
|
||||||
|
//---check for new bar
|
||||||
|
static int k;
|
||||||
|
if(k!=i)
|
||||||
|
{
|
||||||
|
prevPositive = currPositive;
|
||||||
|
prevNegative = currNegative;
|
||||||
|
OpenBuffer[i]= CloseBuffer[i-1];
|
||||||
|
k=i;
|
||||||
|
}
|
||||||
|
//---set candle color
|
||||||
|
ColorBuffer[i]=(CloseBuffer[i]>OpenBuffer[i])?0:1;
|
||||||
|
//---horizontal value line
|
||||||
|
if(PriceLine)
|
||||||
|
PriceLine(CloseBuffer[i]);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
//---rsi done.return count.
|
||||||
|
return(count);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Commodity Channel Index |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int CCI(const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const double &high[],
|
||||||
|
const double &low[],
|
||||||
|
const double &close[])
|
||||||
|
{
|
||||||
|
//--- check bars and input vars
|
||||||
|
if(rates_total<=CCIPeriod || CCIPeriod<=1)
|
||||||
|
return(0);
|
||||||
|
//--- declare vars
|
||||||
|
int begin,count=0;
|
||||||
|
double sum,mul;
|
||||||
|
//--- initial zero
|
||||||
|
if(prev_calculated<1)
|
||||||
|
{
|
||||||
|
for(int i=0;i<CCIPeriod-1 && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
OpenBuffer[i]=HighBuffer[i]=LowBuffer[i]=CloseBuffer[i]=0.0;
|
||||||
|
PriceBuffer[i] = (high[i]+low[i]+close[i])/3;
|
||||||
|
MovAvBuffer[i] = 0.0;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//--- calculate position
|
||||||
|
begin=prev_calculated-1;
|
||||||
|
if(begin<CCIPeriod-1)
|
||||||
|
begin=CCIPeriod-1;
|
||||||
|
//--- typical price and its moving average
|
||||||
|
for(int i=begin;i<rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
PriceBuffer[i] = (high[i]+low[i]+close[i])/3;
|
||||||
|
MovAvBuffer[i] = SimpleMA(i,CCIPeriod,PriceBuffer);
|
||||||
|
}
|
||||||
|
//--- standard deviations and cci counting
|
||||||
|
mul=0.015/CCIPeriod;
|
||||||
|
begin=prev_calculated-1;
|
||||||
|
if(begin<CCIPeriod-1)
|
||||||
|
begin=CCIPeriod-1;
|
||||||
|
//---
|
||||||
|
for(int i=begin;i<rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
sum=0.0;
|
||||||
|
int k=i-CCIPeriod+1;
|
||||||
|
while(k<=i)
|
||||||
|
{
|
||||||
|
sum+=MathAbs(PriceBuffer[k]-MovAvBuffer[i]);
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
sum*=mul;
|
||||||
|
//---check zero divide and fill candle buffers
|
||||||
|
if(sum==0.0)
|
||||||
|
HighBuffer[i]=LowBuffer[i]=CloseBuffer[i]=0.0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HighBuffer[i]=(high[i]-MovAvBuffer[i])/sum;
|
||||||
|
LowBuffer[i] =(low[i]-MovAvBuffer[i])/sum;
|
||||||
|
CloseBuffer[i]=(close[i]-MovAvBuffer[i])/sum;
|
||||||
|
}
|
||||||
|
//---check for new bar
|
||||||
|
static int m;
|
||||||
|
if(m!=i)
|
||||||
|
{
|
||||||
|
OpenBuffer[i]=CloseBuffer[i-1];
|
||||||
|
m=i;
|
||||||
|
}
|
||||||
|
//---set candle color
|
||||||
|
ColorBuffer[i]=(CloseBuffer[i]>OpenBuffer[i])?0:1;
|
||||||
|
//---horizontal value line
|
||||||
|
if(PriceLine)
|
||||||
|
PriceLine(CloseBuffer[i]);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
//---cci done. return count.
|
||||||
|
return(count);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Momentum |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
int Momentum(const int rates_total,
|
||||||
|
const int prev_calculated,
|
||||||
|
const double &high[],
|
||||||
|
const double &low[],
|
||||||
|
const double &close[])
|
||||||
|
{
|
||||||
|
//--- check bars and input param
|
||||||
|
if(rates_total<=MomPeriod || MomPeriod<=0)
|
||||||
|
return(0);
|
||||||
|
int begin,count=0;
|
||||||
|
//--- initial zero
|
||||||
|
if(prev_calculated<=0)
|
||||||
|
{
|
||||||
|
for(int i=0;i<MomPeriod && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
OpenBuffer[i]=HighBuffer[i]=LowBuffer[i]=CloseBuffer[i]=0.0;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
begin=MomPeriod;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
begin=prev_calculated-1;
|
||||||
|
|
||||||
|
static double closeMomPeriod;
|
||||||
|
//--- the main loop of calculations
|
||||||
|
for(int i=begin;i<rates_total && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
//---check for new bar
|
||||||
|
static int k;
|
||||||
|
if(k!=i)
|
||||||
|
{
|
||||||
|
closeMomPeriod= close[i-MomPeriod];
|
||||||
|
// if(closeMomPeriod == 0)
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
if(closeMomPeriod == 0)
|
||||||
|
closeMomPeriod = 1;
|
||||||
|
|
||||||
|
|
||||||
|
OpenBuffer[i] = CloseBuffer[i-1];
|
||||||
|
k=i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HighBuffer[i]= high[i]*100/closeMomPeriod;
|
||||||
|
LowBuffer[i] = low[i]*100/closeMomPeriod;
|
||||||
|
CloseBuffer[i]=close[i]*100/closeMomPeriod;
|
||||||
|
//---set candle color
|
||||||
|
ColorBuffer[i]=(CloseBuffer[i]>OpenBuffer[i])?0:1;
|
||||||
|
//---horizontal value line
|
||||||
|
if(PriceLine)
|
||||||
|
PriceLine(CloseBuffer[i]);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
//--- momentum done. return count
|
||||||
|
return(count);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Horizontal value line |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void PriceLine(const double &close_price)
|
||||||
|
{
|
||||||
|
if(ObjectFind(chartID,priceLine)!=OBJ_NONE)
|
||||||
|
ObjectDelete(chartID,priceLine);
|
||||||
|
if(!ObjectCreate(chartID,priceLine,OBJ_HLINE,window,0,close_price))
|
||||||
|
{
|
||||||
|
Print(__FUNCTION__,": error ",GetLastError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ObjectSetInteger(chartID,priceLine,OBJPROP_WIDTH,1);
|
||||||
|
ObjectSetInteger(chartID,priceLine,OBJPROP_STYLE,STYLE_SOLID);
|
||||||
|
ObjectSetInteger(chartID,priceLine,OBJPROP_COLOR,clrLightSlateGray);
|
||||||
|
ObjectSetInteger(chartID,priceLine,OBJPROP_HIDDEN,true);
|
||||||
|
ObjectSetInteger(chartID,priceLine,OBJPROP_SELECTABLE,false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Auto colors for candles |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
bool SetColors()
|
||||||
|
{
|
||||||
|
color colorBase=clrNONE,
|
||||||
|
colorQote=clrNONE;
|
||||||
|
string base,
|
||||||
|
qote;
|
||||||
|
string Name[9] = {"AUD","CAD","CHF","EUR","GBP","JPY","NZD","USD","XAU"};
|
||||||
|
color Color[9] =
|
||||||
|
{
|
||||||
|
clrDarkOrange,clrWhiteSmoke,clrFireBrick,clrRoyalBlue,
|
||||||
|
clrSilver,clrYellow,clrDarkViolet,clrLimeGreen,clrGold
|
||||||
|
};
|
||||||
|
base = StringSubstr(_Symbol,0,3); //Base currency name
|
||||||
|
qote = StringSubstr(_Symbol,3,3); //Quote currency name
|
||||||
|
for(int i=0;i<9;i++)
|
||||||
|
{
|
||||||
|
if(base==Name[i])
|
||||||
|
colorBase=Color[i];
|
||||||
|
if(qote==Name[i])
|
||||||
|
colorQote=Color[i];
|
||||||
|
}
|
||||||
|
if(!PlotIndexSetInteger(0,PLOT_LINE_COLOR,0,colorBase) ||
|
||||||
|
!PlotIndexSetInteger(0,PLOT_LINE_COLOR,1,colorQote))
|
||||||
|
return(false);
|
||||||
|
if(ChartGetInteger(0,CHART_COLOR_CANDLE_BULL)!=colorBase)
|
||||||
|
{
|
||||||
|
if(!ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,colorBase) ||
|
||||||
|
!ChartSetInteger(0,CHART_COLOR_CHART_UP,colorBase))
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
if(ChartGetInteger(0,CHART_COLOR_CANDLE_BEAR)!=colorQote)
|
||||||
|
{
|
||||||
|
if(!ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,colorQote) ||
|
||||||
|
!ChartSetInteger(0,CHART_COLOR_CHART_DOWN,colorQote))
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
Binary file not shown.
+30
-9
@@ -5,7 +5,6 @@
|
|||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
#property copyright "2009-2017, MetaQuotes Software Corp."
|
#property copyright "2009-2017, MetaQuotes Software Corp."
|
||||||
#property link "http://www.mql5.com"
|
#property link "http://www.mql5.com"
|
||||||
#property description "Adapted for use with TickChart by Artur Zas."
|
|
||||||
//--- indicator settings
|
//--- indicator settings
|
||||||
#property indicator_chart_window
|
#property indicator_chart_window
|
||||||
#property indicator_buffers 3
|
#property indicator_buffers 3
|
||||||
@@ -25,15 +24,10 @@ bool ExtDirectionLong;
|
|||||||
double ExtSarStep;
|
double ExtSarStep;
|
||||||
double ExtSarMaximum;
|
double ExtSarMaximum;
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <AZ-INVEST/SDK/RangeBarIndicator.mqh>
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
RangeBarIndicator customChartIndicator;
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
//
|
||||||
|
|
||||||
//+------------------------------------------------------------------+
|
//+------------------------------------------------------------------+
|
||||||
@@ -92,15 +86,42 @@ int OnCalculate(const int rates_total,
|
|||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
// Process data through MedianRenko indicator
|
||||||
|
//
|
||||||
|
|
||||||
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
if(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
//--- detect current position
|
//--- detect current position
|
||||||
Binary file not shown.
@@ -0,0 +1,245 @@
|
|||||||
|
#property copyright "2017-2020, Artur Zas"
|
||||||
|
#property link "http://www.az-invest.eu"
|
||||||
|
//---- indicator settings
|
||||||
|
#property indicator_separate_window
|
||||||
|
#property indicator_buffers 7
|
||||||
|
#property indicator_plots 5
|
||||||
|
|
||||||
|
#property indicator_label1 "Volume"
|
||||||
|
#property indicator_type1 DRAW_HISTOGRAM // volume
|
||||||
|
#property indicator_color1 Gray
|
||||||
|
#property indicator_style1 0
|
||||||
|
#property indicator_width1 2
|
||||||
|
|
||||||
|
#property indicator_label2 "Buy volume"
|
||||||
|
#property indicator_type2 DRAW_HISTOGRAM // buy volume
|
||||||
|
#property indicator_color2 clrDarkGreen
|
||||||
|
#property indicator_style2 0
|
||||||
|
#property indicator_width2 2
|
||||||
|
|
||||||
|
#property indicator_label3 "Sell volume"
|
||||||
|
#property indicator_type3 DRAW_HISTOGRAM // sell volume
|
||||||
|
#property indicator_color3 clrFireBrick
|
||||||
|
#property indicator_style3 0
|
||||||
|
#property indicator_width3 2
|
||||||
|
|
||||||
|
#property indicator_label4 "Bar volume delta"
|
||||||
|
#property indicator_type4 DRAW_COLOR_HISTOGRAM // bar delta
|
||||||
|
#property indicator_color4 Lime,Red,clrNONE
|
||||||
|
#property indicator_style4 0
|
||||||
|
#property indicator_width4 5
|
||||||
|
|
||||||
|
#property indicator_label5 "Cumulative volume delta"
|
||||||
|
#property indicator_type5 DRAW_COLOR_LINE // cumulative delta
|
||||||
|
#property indicator_color5 Green, Red, clrNONE
|
||||||
|
#property indicator_style5 STYLE_DOT
|
||||||
|
#property indicator_width5 1
|
||||||
|
|
||||||
|
|
||||||
|
//--- input data
|
||||||
|
static ENUM_APPLIED_VOLUME InpVolumeType= (SymbolInfoInteger(_Symbol,SYMBOL_VOLUME) <= 0) ? VOLUME_TICK : VOLUME_REAL; // Volumes
|
||||||
|
|
||||||
|
input bool InpShowVolume = true; // Show volume histogram
|
||||||
|
input bool InpShowBuySellVolume = true; // Show bar's buy/sell volume breakdown
|
||||||
|
input bool InpShowBarDelta = true; // Show bar's buy/sell volume delta
|
||||||
|
input bool InpShowCumulativeDelta = false; // Show cumulative volume delta
|
||||||
|
input int InpCumulativeDeltaScale = 1; // Scale down cumulative volume 1:x
|
||||||
|
|
||||||
|
//---- indicator buffers
|
||||||
|
double ExtBarDeltaBuffer[];
|
||||||
|
double ExtBarDeltaColorsBuffer[];
|
||||||
|
|
||||||
|
double ExtBuyVolumeBuffer[];
|
||||||
|
|
||||||
|
double ExtSellVolumeBuffer[];
|
||||||
|
|
||||||
|
double ExtVolumeBuffer[];
|
||||||
|
|
||||||
|
double ExtCumulativeVolumeBuffer[];
|
||||||
|
double ExtCumulativeVolumeColorBuffer[];
|
||||||
|
|
||||||
|
double cumulativeDelta = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <AZ-INVEST/CustomBarConfig.mqh>
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| Custom indicator initialization function |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void OnInit()
|
||||||
|
{
|
||||||
|
//---- buffers
|
||||||
|
SetIndexBuffer(0,ExtVolumeBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(1,ExtBuyVolumeBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(2,ExtSellVolumeBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(3,ExtBarDeltaBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(4,ExtBarDeltaColorsBuffer,INDICATOR_COLOR_INDEX);
|
||||||
|
SetIndexBuffer(5,ExtCumulativeVolumeBuffer,INDICATOR_DATA);
|
||||||
|
SetIndexBuffer(6,ExtCumulativeVolumeColorBuffer,INDICATOR_COLOR_INDEX);
|
||||||
|
|
||||||
|
//---- name for DataWindow and indicator subwindow label
|
||||||
|
IndicatorSetString(INDICATOR_SHORTNAME,"Pro Volume");
|
||||||
|
//---- indicator digits
|
||||||
|
IndicatorSetInteger(INDICATOR_DIGITS,0);
|
||||||
|
|
||||||
|
customChartIndicator.SetGetTimeFlag();
|
||||||
|
customChartIndicator.SetGetVolumesFlag();
|
||||||
|
customChartIndicator.SetGetVolumeBreakdownFlag();
|
||||||
|
//----
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| 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(!customChartIndicator.OnCalculate(rates_total,prev_calculated,time,close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
if(!customChartIndicator.BufferSynchronizationCheck(close))
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make the following modifications in the code below:
|
||||||
|
//
|
||||||
|
// customChartIndicator.GetPrevCalculated() should be used instead of prev_calculated
|
||||||
|
//
|
||||||
|
// customChartIndicator.Open[] should be used instead of open[]
|
||||||
|
// customChartIndicator.Low[] should be used instead of low[]
|
||||||
|
// customChartIndicator.High[] should be used instead of high[]
|
||||||
|
// customChartIndicator.Close[] should be used instead of close[]
|
||||||
|
//
|
||||||
|
// customChartIndicator.IsNewBar (true/false) informs you if a renko brick completed
|
||||||
|
//
|
||||||
|
// customChartIndicator.Time[] shold be used instead of Time[] for checking the renko bar time.
|
||||||
|
// (!) customChartIndicator.SetGetTimeFlag() must be called in OnInit() for customChartIndicator.Time[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Tick_volume[] should be used instead of TickVolume[]
|
||||||
|
// customChartIndicator.Real_volume[] should be used instead of Volume[]
|
||||||
|
// (!) customChartIndicator.SetGetVolumesFlag() must be called in OnInit() for Tick_volume[] & Real_volume[] to be used
|
||||||
|
//
|
||||||
|
// customChartIndicator.Price[] should be used instead of Price[]
|
||||||
|
// (!) customChartIndicator.SetUseAppliedPriceFlag(ENUM_APPLIED_PRICE _applied_price) must be called in OnInit() for customChartIndicator.Price[] to be used
|
||||||
|
//
|
||||||
|
|
||||||
|
int _prev_calculated = customChartIndicator.GetPrevCalculated();
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
//--- starting work
|
||||||
|
int start=_prev_calculated-1;
|
||||||
|
//--- correct position
|
||||||
|
// if(start<1) start=1;
|
||||||
|
if(start<0) start=0;
|
||||||
|
//--- main cycle
|
||||||
|
CalculateData(start,rates_total);
|
||||||
|
//--- OnCalculate done. Return new prev_calculated.
|
||||||
|
return(rates_total);
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
//| |
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
void CalculateData(const int nPosition,
|
||||||
|
const int nRatesCount)
|
||||||
|
{
|
||||||
|
double volume,buyVolume,sellVolume,barDelta;
|
||||||
|
|
||||||
|
for(int i=nPosition;i<nRatesCount && !IsStopped();i++)
|
||||||
|
{
|
||||||
|
//--- calculate indicator
|
||||||
|
volume = (InpVolumeType == VOLUME_TICK) ? (double)customChartIndicator.Tick_volume[i] : (double)customChartIndicator.Real_volume[i];
|
||||||
|
buyVolume = customChartIndicator.Buy_volume[i];
|
||||||
|
sellVolume = customChartIndicator.Sell_volume[i];
|
||||||
|
barDelta = buyVolume - sellVolume;
|
||||||
|
//
|
||||||
|
|
||||||
|
if(InpShowVolume)
|
||||||
|
ExtVolumeBuffer[i] = volume;
|
||||||
|
else
|
||||||
|
ExtVolumeBuffer[i] = 0;
|
||||||
|
|
||||||
|
if(InpShowBuySellVolume)
|
||||||
|
{
|
||||||
|
ExtBuyVolumeBuffer[i] = buyVolume;
|
||||||
|
ExtSellVolumeBuffer[i] = sellVolume * (-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExtBuyVolumeBuffer[i] = 0;
|
||||||
|
ExtSellVolumeBuffer[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(InpShowBarDelta)
|
||||||
|
{
|
||||||
|
ExtBarDeltaBuffer[i] = barDelta;
|
||||||
|
ExtBarDeltaColorsBuffer[i] = ( ExtBarDeltaBuffer[i] < 0 ) ? 1 : (( ExtBarDeltaBuffer[i] == 0 ) ? 2 : 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExtBarDeltaBuffer[i] = 0;
|
||||||
|
ExtBarDeltaColorsBuffer[i] = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(InpShowCumulativeDelta)
|
||||||
|
{
|
||||||
|
if((i != (nRatesCount-1)) && (i>0))
|
||||||
|
{
|
||||||
|
if(IsNewDay(customChartIndicator.Time[i-1], customChartIndicator.Time[i]))
|
||||||
|
cumulativeDelta = 0; // reset cumulative volme
|
||||||
|
|
||||||
|
cumulativeDelta += barDelta;
|
||||||
|
|
||||||
|
ExtCumulativeVolumeBuffer[i] = cumulativeDelta / InpCumulativeDeltaScale;
|
||||||
|
ExtCumulativeVolumeColorBuffer[i] = ( ExtCumulativeVolumeBuffer[i] < 0 ) ? 1 : (( ExtCumulativeVolumeBuffer[i] == 0 ) ? 2 : 0 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExtCumulativeVolumeBuffer[i] = (cumulativeDelta + barDelta) / InpCumulativeDeltaScale;
|
||||||
|
ExtCumulativeVolumeColorBuffer[i] = ( ExtCumulativeVolumeBuffer[i] < 0 ) ? 1 : (( ExtCumulativeVolumeBuffer[i] == 0 ) ? 2 : 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExtCumulativeVolumeBuffer[i] = 0;
|
||||||
|
ExtCumulativeVolumeColorBuffer[i] = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//+------------------------------------------------------------------+
|
||||||
|
|
||||||
|
bool IsNewDay(datetime prevTime,datetime currTime)
|
||||||
|
{
|
||||||
|
MqlDateTime prev;
|
||||||
|
MqlDateTime curr;
|
||||||
|
|
||||||
|
TimeToStruct(prevTime,prev);
|
||||||
|
TimeToStruct(currTime,curr);
|
||||||
|
|
||||||
|
if(prev.day_of_week != curr.day_of_week)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user