commit 407a205132cd2b52bba86987dcbc3253827b0ee4 Author: Nkondog Anselme Date: Sun Nov 14 05:36:01 2021 +0100 Initial commit diff --git a/Experts/Nkanven/EA Framework/EA_Template_1.0/EA_Template_1.0.mq5 b/Experts/Nkanven/EA Framework/EA_Template_1.0/EA_Template_1.0.mq5 new file mode 100644 index 0000000..002e70e --- /dev/null +++ b/Experts/Nkanven/EA Framework/EA_Template_1.0/EA_Template_1.0.mq5 @@ -0,0 +1,155 @@ +//+------------------------------------------------------------------+ +//| EA_Template_1.0.mq5 | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ + +#include +#include + +//Input section + + + +//Some standard inputs +input double inpVolume = 0.01; //Default order size +input string inpComment = __FILE__; //Default trade comment +input int inpMagicNumber = 12345; //Magic number + + +//Declare the Expert +#define CExpert CExpertBase +CExpert *Expert; + +//+------------------------------------------------------------------+ +//| Expert initialization function | +//+------------------------------------------------------------------+ +int OnInit() + { + + //Assign the default values to the expert +Expert = new CExpert(); + +Expert.SetVolume(inpVolume); +Expert.SetTradeComment(__FILE__); +Expert.SetMagic(inpMagicNumber); + + +//--- create timer + EventSetTimer(60); + + int result = Expert.OnInit(); + +//--- + return(result); + } +//+------------------------------------------------------------------+ +//| Expert deinitialization function | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) + { +//--- destroy timer + EventKillTimer(); + delete Expert; + return; + } +//+------------------------------------------------------------------+ +//| Expert tick function | +//+------------------------------------------------------------------+ +void OnTick() + { +//--- + Expert.OnTick(); + return; + } +//+------------------------------------------------------------------+ +//| Timer function | +//+------------------------------------------------------------------+ +void OnTimer() + { +//--- + Expert.OnTimer(); + return; + } +//+------------------------------------------------------------------+ +//| Trade function | +//+------------------------------------------------------------------+ +void OnTrade() + { +//--- + Expert.OnTrade(); + return; + } +//+------------------------------------------------------------------+ +//| TradeTransaction function | +//+------------------------------------------------------------------+ +void OnTradeTransaction(const MqlTradeTransaction& trans, + const MqlTradeRequest& request, + const MqlTradeResult& result) + { +//--- + Expert.OnTradeTransaction(trans, request, result); + return; + } +//+------------------------------------------------------------------+ +//| Tester function | +//+------------------------------------------------------------------+ +double OnTester() + { +//--- + //double ret=0.0; +//--- + +//--- + //return(ret); + return(Expert.OnTester()); + } +//+------------------------------------------------------------------+ +//| TesterInit function | +//+------------------------------------------------------------------+ +void OnTesterInit() + { +//--- + Expert.OnTesterInit(); + return; + } +//+------------------------------------------------------------------+ +//| TesterPass function | +//+------------------------------------------------------------------+ +void OnTesterPass() + { +//--- + Expert.OnTesterPass(); + return; + } +//+------------------------------------------------------------------+ +//| TesterDeinit function | +//+------------------------------------------------------------------+ +void OnTesterDeinit() + { +//--- + Expert.OnTesterDeinit(); + return; + } +//+------------------------------------------------------------------+ +//| ChartEvent function | +//+------------------------------------------------------------------+ +void OnChartEvent(const int id, + const long &lparam, + const double &dparam, + const string &sparam) + { +//--- + Expert.OnChartEvent(id, lparam, dparam, sparam); + return; + } +//+------------------------------------------------------------------+ +//| BookEvent function | +//+------------------------------------------------------------------+ +void OnBookEvent(const string &symbol) + { +//--- + Expert.OnBookEvent(); + return; + } +//+------------------------------------------------------------------+ diff --git a/Experts/Nkanven/EA Framework/EA_Template_1.0/EA_Template_1.0.mqproj b/Experts/Nkanven/EA Framework/EA_Template_1.0/EA_Template_1.0.mqproj new file mode 100644 index 0000000..2667412 Binary files /dev/null and b/Experts/Nkanven/EA Framework/EA_Template_1.0/EA_Template_1.0.mqproj differ diff --git a/Experts/Nkanven/Framework EA/EA_Template.mq4 b/Experts/Nkanven/Framework EA/EA_Template.mq4 new file mode 100644 index 0000000..2c2336e --- /dev/null +++ b/Experts/Nkanven/Framework EA/EA_Template.mq4 @@ -0,0 +1,21 @@ +/* + + EA_Template.mq4 + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + Description: Basic template for framework based MQ4 expert + Uses: framework_2.02 minimum + +*/ + +#property copyright "Copyright 2013-2020, Orchard Forex" +#property link "https://www.orchardforex.com" +#property version "1.00" +#property strict + +// +// Load the common code +// +#include "EA_Template.mqh" // Remember to change this diff --git a/Experts/Nkanven/Framework EA/EA_Template.mq5 b/Experts/Nkanven/Framework EA/EA_Template.mq5 new file mode 100644 index 0000000..473c0d0 --- /dev/null +++ b/Experts/Nkanven/Framework EA/EA_Template.mq5 @@ -0,0 +1,64 @@ +/* + + EA_Template.mq5 + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + Description: Basic template for framework based MQ4 expert + Uses: framework_2.02 minimum + +*/ + +#property copyright "Copyright 2012-2020, Orchard Forex" +#property link "https://www.orchardforex.com" +#property version "1.00" +#property strict + +// +// Load the common code +// +#include "EA_Template.mqh" // Remember to change this + +void OnTrade() { + + Expert.OnTrade(); + return; + +} + +void OnTradeTransaction(const MqlTradeTransaction& trans, + const MqlTradeRequest& request, + const MqlTradeResult& result) { + + Expert.OnTradeTransaction(trans, request, result); + return; + +} + +void OnBookEvent(const string &symbol) { + + Expert.OnBookEvent(); + return; + +} + +int OnTesterInit() { + + return(Expert.OnTesterInit()); + +} + +void OnTesterPass() { + + Expert.OnTesterPass(); + return; + +} + +void OnTesterDeinit() { + + Expert.OnTesterDeinit(); + return; + +} diff --git a/Experts/Nkanven/Framework EA/EA_Template.mqh b/Experts/Nkanven/Framework EA/EA_Template.mqh new file mode 100644 index 0000000..e0c9350 --- /dev/null +++ b/Experts/Nkanven/Framework EA/EA_Template.mqh @@ -0,0 +1,182 @@ +/* + + EA_Template.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + Description: Holds common template code between MQ4 and MQ5 + Uses: framework_2.02 minimum + +*/ + +// +// This is where we pull in the framework +// +#include + +// +// Input Section +// + +// +// Some standard inputs, +// remember to change the default magic for each EA +// +input double InpVolume = 0.01; // Default order size +input string InpComment = __FILE__; // Default trade comment +input int InpMagicNumber = 20202020; // Magic Number + +// +// Declare the expert, use the child class name +// If the base class does everything needed then it's OK to +// just use CExpertBase +// Declare the name CExpert as the actual class name. +// This allows other files to just refer to CExpert +// +#define CExpert CExpertBase +CExpert *Expert; + +// +// Indicators - use the child class name instead of CIndicatorBase +// Remove if not needed +// +CIndicatorBase *Indicator1; + +// +// Signals - use the child class name instead of CSignalBase +// Remove if not needed +// +CSignalBase *EntrySignal; +CSignalBase *ExitSignal; + +// +// TPSL - use child class names instead of CTPSLBase +// Remove if not needed +// +CTPSLBase *TPObject; +CTPSLBase *SLObject; + +// +// Indicators for TPSL - use child class names instead of CIndicatorBase +// Remove if not needed +// +CIndicatorBase *IndicatorTPSL1; +CIndicatorBase *IndicatorTPSL2; + +int OnInit() { + + // + // Instantiate the expert + // Uses the declared class name + // + Expert = new CExpert(); + + // + // Assign the default values to the expert + // + Expert.SetVolume(InpVolume); + Expert.SetTradeComment(InpComment); + Expert.SetMagic(InpMagicNumber); + + // + // Create the indicators - using your child class name + // + Indicator1 = new CIndicatorBase(); + + // + // Set up the signals - using your child class names + // + EntrySignal = new CSignalBase(); + EntrySignal.AddIndicator(Indicator1, 0); // Add as many indicators as you need + + ExitSignal = new CSignalBase(); + ExitSignal.AddIndicator(Indicator1, 0); // Add as many indicators as you need + + // + // Add the signals to the expert + // + Expert.AddEntrySignal(EntrySignal); // repeat for more signals + Expert.AddExitSignal(ExitSignal); + + // + // If using fixed tp and sl set them here in points + // + Expert.SetTakeProfitValue(0); + Expert.SetStopLossValue(0); + + // + // Set up the Take Profit and Stop Loss objects + // Remember to create child class names, not base + // + TPObject = new CTPSLBase(); // Create the object + IndicatorTPSL1 = new CIndicatorBase(); // Create an indicator for the tp object + TPObject.AddIndicator(IndicatorTPSL1, 0); // Add the indicator to tp + // Set any other properties needed + + // And for the SL object + SLObject = new CTPSLBase(); + IndicatorTPSL2 = new CIndicatorBase(); + SLObject.AddIndicator(IndicatorTPSL2, 0); + + Expert.SetTakeProfitObj(TPObject); + Expert.SetStopLossObj(SLObject); + + // + // Finish expert initialisation and check result + // + int result = Expert.OnInit(); + + return(result); + +} + +void OnDeinit(const int reason) { + + EventKillTimer(); + + + // Delete all objects created + delete Expert; + delete ExitSignal; + delete EntrySignal; + delete Indicator1; + delete TPObject; + delete SLObject; + delete IndicatorTPSL1; + delete IndicatorTPSL2; + + return; + +} + +void OnTick() { + + Expert.OnTick(); + return; + +} + +void OnTimer() { + + Expert.OnTimer(); + return; + +} + +double OnTester() { + + return(Expert.OnTester()); + +} + +void OnChartEvent(const int id, + const long &lparam, + const double &dparam, + const string &sparam) { + + Expert.OnChartEvent(id, lparam, dparam, sparam); + return; + +} + diff --git a/Experts/Nkanven/Framework EA/EA_Template_1.0.ex5 b/Experts/Nkanven/Framework EA/EA_Template_1.0.ex5 new file mode 100644 index 0000000..ff6bb62 Binary files /dev/null and b/Experts/Nkanven/Framework EA/EA_Template_1.0.ex5 differ diff --git a/Experts/Nkanven/Framework EA/EA_Template_1.0.mq4 b/Experts/Nkanven/Framework EA/EA_Template_1.0.mq4 new file mode 100644 index 0000000..29c3185 --- /dev/null +++ b/Experts/Nkanven/Framework EA/EA_Template_1.0.mq4 @@ -0,0 +1,181 @@ +/* + + EA_Template.mq4 + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + Description: + +*/ + +#property copyright "Copyright 2013-2020, Orchard Forex" +#property link "https://www.orchardforex.com" +#property version "1.00" +#property strict + +// +// This is where we pull in the framework +// +// Use the following line for the current framework +#include +// Use the following line for a specific framework (replace x.x) +//#include + +// +// Input Section +// + +// +// Some standard inputs, +// remember to change the default magic for each EA +// +input double InpVolume = 0.01; // Default order size +input string InpComment = __FILE__; // Default trade comment +input int InpMagicNumber = 20200701; // Magic Number + +// +// Declare the expert +// +#define CExpert CExpertBase +CExpert *Expert; + +// +// Indicators +// +CIndicatorBase *Indicator1; + +// +// Signals +// +CSignalBase *EntrySignal; +CSignalBase *ExitSignal; + +// +// TPSL - use child class names instead of CTPSLBase +// +CTPSLBase *TPObject; +CTPSLBase *SLObject; + +// +// Indicators for TPSL - use child class names instead of CIndicatorBase +// +CIndicatorBase *IndicatorTPSL1; +CIndicatorBase *IndicatorTPSL2; + + + +int OnInit() { + + // + // Instantiate the expert, use the child class name + // + Expert = new CExpert(); + + // + // Assign the default values to the expert + // + Expert.SetVolume(InpVolume); + Expert.SetTradeComment(InpComment); + Expert.SetMagic(InpMagicNumber); + + // + // Set up the indicators + // + Indicator1 = new CIndicatorBase(); + + // + // Set up the signals + // + EntrySignal = new CSignalBase(); + EntrySignal.AddIndicator(Indicator1, 0); + + ExitSignal = new CSignalBase(); + ExitSignal.AddIndicator(Indicator1, 0); + + // + // Add the signals to the expert + // + Expert.AddEntrySignal(EntrySignal); + Expert.AddExitSignal(ExitSignal); + + // + // If using fixed tp and sl set them here in points + // + Expert.SetTakeProfitValue(0); + Expert.SetStopLossValue(0); + + // + // Set up the Take Profit and Stop Loss objects + // Remember to create child class names, not base + // + TPObject = new CTPSLBase(); // Create the object + IndicatorTPSL1 = new CIndicatorBase(); // Create an indicator for the tp object + TPObject.AddIndicator(IndicatorTPSL1, 0); // Add the indicator to tp + // Set any other properties needed + + // And for the SL object + SLObject = new CTPSLBase(); + IndicatorTPSL2 = new CIndicatorBase(); + SLObject.AddIndicator(IndicatorTPSL2, 0); + + Expert.SetTakeProfitObj(TPObject); + Expert.SetStopLossObj(SLObject); + + // + // Finish expert initialisation and check result + // + int result = Expert.OnInit(); + + return(result); + +} + +void OnDeinit(const int reason) { + + EventKillTimer(); + + delete Expert; + delete ExitSignal; + delete EntrySignal; + delete Indicator1; + delete TPObject; + delete SLObject; + delete IndicatorTPSL1; + delete IndicatorTPSL2; + + return; + +} + +void OnTick() { + + Expert.OnTick(); + return; + +} + +void OnTimer() { + + Expert.OnTimer(); + return; + +} + +double OnTester() { + + return(Expert.OnTester()); + +} + +void OnChartEvent(const int id, + const long &lparam, + const double &dparam, + const string &sparam) { + + Expert.OnChartEvent(id, lparam, dparam, sparam); + return; + +} + + diff --git a/Experts/Nkanven/Framework EA/EA_Template_1.0.mq5 b/Experts/Nkanven/Framework EA/EA_Template_1.0.mq5 new file mode 100644 index 0000000..89eba15 --- /dev/null +++ b/Experts/Nkanven/Framework EA/EA_Template_1.0.mq5 @@ -0,0 +1,224 @@ +/* + + EA_Template.mq5 + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + Description: + +*/ + +#property copyright "Copyright 2012-2020, Orchard Forex" +#property link "https://www.orchardforex.com" +#property version "1.00" +#property strict + +// +// This is where we pull in the framework +// +// Use the following line for the current framework +#include +// Use the following line for a specific framework (replace x.x) +//#include + +// +// Input Section +// + +// +// Some standard inputs, +// remember to change the default magic for each EA +// +input double InpVolume = 0.01; // Default order size +input string InpComment = __FILE__; // Default trade comment +input int InpMagicNumber = 20200701; // Magic Number + +// +// Declare the expert +// +#define CExpert CExpertBase +CExpert *Expert; + +// +// Indicators +// +CIndicatorBase *Indicator1; + +// +// Signals +// +CSignalBase *EntrySignal; +CSignalBase *ExitSignal; + +// +// TPSL - use child class names instead of CTPSLBase +// +CTPSLBase *TPObject; +CTPSLBase *SLObject; + +// +// Indicators for TPSL - use child class names instead of CIndicatorBase +// +CIndicatorBase *IndicatorTPSL1; +CIndicatorBase *IndicatorTPSL2; + + + +int OnInit() { + + // + // Instantiate the expert, use the child class name + // + Expert = new CExpert(); + + // + // Assign the default values to the expert + // + Expert.SetVolume(InpVolume); + Expert.SetTradeComment(InpComment); + Expert.SetMagic(InpMagicNumber); + + // + // Set up the indicators + // + Indicator1 = new CIndicatorBase(); + + // + // Set up the signals + // + EntrySignal = new CSignalBase(); + EntrySignal.AddIndicator(Indicator1, 0); + + ExitSignal = new CSignalBase(); + ExitSignal.AddIndicator(Indicator1, 0); + + // + // Add the signals to the expert + // + Expert.AddEntrySignal(EntrySignal); + Expert.AddExitSignal(ExitSignal); + + // + // If using fixed tp and sl set them here in points + // + Expert.SetTakeProfitValue(0); + Expert.SetStopLossValue(0); + + // + // Set up the Take Profit and Stop Loss objects + // Remember to create child class names, not base + // + TPObject = new CTPSLBase(); // Create the object + IndicatorTPSL1 = new CIndicatorBase(); // Create an indicator for the tp object + TPObject.AddIndicator(IndicatorTPSL1, 0); // Add the indicator to tp + // Set any other properties needed + + // And for the SL object + SLObject = new CTPSLBase(); + IndicatorTPSL2 = new CIndicatorBase(); + SLObject.AddIndicator(IndicatorTPSL2, 0); + + Expert.SetTakeProfitObj(TPObject); + Expert.SetStopLossObj(SLObject); + + // + // Finish expert initialisation and check result + // + int result = Expert.OnInit(); + + return(result); + +} + +void OnDeinit(const int reason) { + + EventKillTimer(); + + delete Expert; + delete ExitSignal; + delete EntrySignal; + delete Indicator1; + delete TPObject; + delete SLObject; + delete IndicatorTPSL1; + delete IndicatorTPSL2; + + return; + +} + +void OnTick() { + + Expert.OnTick(); + return; + +} + +void OnTimer() { + + Expert.OnTimer(); + return; + +} + +void OnTrade() { + + Expert.OnTrade(); + return; + +} + +void OnTradeTransaction(const MqlTradeTransaction& trans, + const MqlTradeRequest& request, + const MqlTradeResult& result) { + + Expert.OnTradeTransaction(trans, request, result); + return; + +} + +double OnTester() { + + return(Expert.OnTester()); + +} + +void OnTesterInit() { + + Expert.OnTesterInit(); + return; + +} + +void OnTesterPass() { + + Expert.OnTesterPass(); + return; + +} + +void OnTesterDeinit() { + + Expert.OnTesterDeinit(); + return; + +} + +void OnChartEvent(const int id, + const long &lparam, + const double &dparam, + const string &sparam) { + + Expert.OnChartEvent(id, lparam, dparam, sparam); + return; + +} + +void OnBookEvent(const string &symbol) { + + Expert.OnBookEvent(); + return; + +} + diff --git a/Experts/Nkanven/Framework EA/Grid/GridEA.ex5 b/Experts/Nkanven/Framework EA/Grid/GridEA.ex5 new file mode 100644 index 0000000..72df996 Binary files /dev/null and b/Experts/Nkanven/Framework EA/Grid/GridEA.ex5 differ diff --git a/Experts/Nkanven/Framework EA/Grid/GridEA.mq5 b/Experts/Nkanven/Framework EA/Grid/GridEA.mq5 new file mode 100644 index 0000000..396696b --- /dev/null +++ b/Experts/Nkanven/Framework EA/Grid/GridEA.mq5 @@ -0,0 +1,281 @@ +//+------------------------------------------------------------------+ +//| GridEA.mq5 | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" +#property version "1.00" + + +#include + +// +// Input Section +// + +//This is where you should include the input parameters for your entry and exit signals +input string Comment_strategy="=========="; //Entry And Exit Settings +//Add in this section the parameters for the indicators used in your entry and exit + +//General input parameters +input string Comment_0="=========="; //Risk Management Settings +input ENUM_RISK_DEFAULT_SIZE InpRiskDefaultSize=RISK_DEFAULT_AUTO; //Position Size Mode +input double InpDefaultLotSize=1; //Position Size (if fixed or if no stop loss defined) +input ENUM_RISK_BASE InpRiskBase=RISK_BASE_BALANCE; //Risk Base +input double InpMaxRiskPerTrade=0.5; //Percentage To Risk Each Trade +input double InpMinLotSize=0.01; //Min Lot Size +input double InpMaxLotSize=100; //Max Lot Size + + +input string Comment_1="=========="; //Trading Hours Settings +input bool InpUseTradingHours=false; //Activate Trading Hours +input string InpTradingHourStart="01"; //Trading Start Hour (Broker Server Hour) +input string InpTradingStartMin="30"; //Trading Start minute +input string InpTradingHourEnd="23"; //Trading End Hour (Broker Server Hour) +input string InpTradingEndMin="00"; //Trading End minute +input bool InpUseTradingSession=true; +input ENUM_TRADING_SESSION InpTradingSession = LONDON_SESSION; //Trading session + +input string Comment_2="=========="; //Trading Hours Settings +input int InpGridGap = 1000; + +input double InpVolume = 0.01; // Default order size +input string InpComment = __FILE__; // Default trade comment +input int InpMagicNumber = 20200701; // Magic Number +input int InpBrokerTimeZoneGMT = 2; //Broker timezone from GMT +input int InpSlippage = 2; + + +int londonSession[] = {7, 17}; +int newyorkSession[] = {13, 23}; +int tokyoSession[] = {0, 6}; + +// +// Declare the expert +// +#define CExpert CExpertBase +CExpert *Expert; + +// +// Signals +// +CSignalGrid *EntrySignal; +CSignalGrid *ExitSignal; + +// +// TPSL - use child class names instead of CTPSLBase +// +GridTPSL *TPObject; +GridTPSL *SLObject; + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int OnInit() + { + +// +// Instantiate the expert, use the child class name +// + Expert = new CExpert(); + +// +// Assign the default values to the expert +// + Expert.SetVolume(InpVolume); + Expert.SetTradeComment(InpComment); + Expert.SetMagic(InpMagicNumber); + Expert.SetDefaultLotSize(InpDefaultLotSize); + Expert.SetGridGap(InpGridGap); + Expert.SetGridNumber(10); + Expert.SetMaxLotSize(InpMaxLotSize); + Expert.SetMaxRiskPerTrade(InpMaxRiskPerTrade); + Expert.SetMinLotSize(InpMinLotSize); + Expert.SetRiskBase(InpRiskBase); + Expert.SetRiskDefaultSize(InpRiskDefaultSize); + Expert.SetUseTradingSession(InpTradingSession); + Expert.SetSlippage(InpSlippage); + +// +// Set up the signals +// + EntrySignal = new CSignalGrid(); +//EntrySignal.AddIndicator(Indicator1, 0); + + ExitSignal = new CSignalGrid(); + ExitSignal.SetMaxRiskPerTrade(InpMaxRiskPerTrade); + ExitSignal.setMmagic(InpMagicNumber); +//ExitSignal.AddIndicator(Indicator1, 0); + +// +// Add the signals to the expert +// + Expert.AddEntrySignal(EntrySignal); + Expert.AddExitSignal(ExitSignal); + +// +// If using fixed tp and sl set them here in points +// + Expert.SetTakeProfitValue(0); + Expert.SetStopLossValue(0); + +// +// Set up the Take Profit and Stop Loss objects +// Remember to create child class names, not base +// + TPObject = new GridTPSL(); // Create the object +//IndicatorTPSL1 = new CIndicatorBase(); // Create an indicator for the tp object +//TPObject.AddIndicator(IndicatorTPSL1, 0); // Add the indicator to tp +// Set any other properties needed + +// And for the SL object + SLObject = new GridTPSL(); +//IndicatorTPSL2 = new CIndicatorBase(); +//SLObject.AddIndicator(IndicatorTPSL2, 0); + + Expert.SetTakeProfitObj(TPObject); + Expert.SetStopLossObj(SLObject); + +// +// Finish expert initialisation and check result +// + int result = Expert.OnInit(); + + return(result); + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void OnDeinit(const int reason) + { + + EventKillTimer(); + + delete Expert; + delete ExitSignal; + delete EntrySignal; + delete TPObject; + delete SLObject; + + return; + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void OnTick() + { + + Expert.OnTick(); + return; + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void OnTimer() + { + + Expert.OnTimer(); + return; + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void OnTrade() + { + + Expert.OnTrade(); + return; + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void OnTradeTransaction(const MqlTradeTransaction& trans, + const MqlTradeRequest& request, + const MqlTradeResult& result) + { + + Expert.OnTradeTransaction(trans, request, result); + return; + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +double OnTester() + { + + return(Expert.OnTester()); + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void OnTesterInit() + { + + Expert.OnTesterInit(); + return; + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void OnTesterPass() + { + + Expert.OnTesterPass(); + return; + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void OnTesterDeinit() + { + + Expert.OnTesterDeinit(); + return; + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void OnChartEvent(const int id, + const long &lparam, + const double &dparam, + const string &sparam) + { + + Expert.OnChartEvent(id, lparam, dparam, sparam); + return; + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void OnBookEvent(const string &symbol) + { + + Expert.OnBookEvent(); + return; + + } + +//+------------------------------------------------------------------+ diff --git a/Experts/Nkanven/Framework EA/MA Crossover ATR TPSL/MA Crossover ATR TPSL.mq4 b/Experts/Nkanven/Framework EA/MA Crossover ATR TPSL/MA Crossover ATR TPSL.mq4 new file mode 100644 index 0000000..11188b9 --- /dev/null +++ b/Experts/Nkanven/Framework EA/MA Crossover ATR TPSL/MA Crossover ATR TPSL.mq4 @@ -0,0 +1,176 @@ +/* + + MA Crossover ATR TPSL.mq4 + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + Description: + +*/ + +#property copyright "Copyright 2013-2020, Orchard Forex" +#property link "https://www.orchardforex.com" +#property version "1.00" +#property strict + +// +// This is where we pull in the framework +// +#include + +// +// Input Section +// +// Fast moving average +input int InpFastPeriods = 10; // Fast periods +input ENUM_MA_METHOD InpFastMethod = MODE_SMA; // Fast method +input ENUM_APPLIED_PRICE InpFastAppliedPrice = PRICE_CLOSE; // Fast price + +// Slow moving average +input int InpSlowPeriods = 20; // Slow periods +input ENUM_MA_METHOD InpSlowMethod = MODE_SMA; // Slow method +input ENUM_APPLIED_PRICE InpSlowAppliedPrice = PRICE_CLOSE; // Slow price + +// +// For ATR based TPSL +// +input int InpATRPeriods = 14; // ATR Periods +input double InpATRMultiplier = 3.0; // ATR Multiplier + +// +// Some standard inputs, +// remember to change the default magic for each EA +// +input double InpVolume = 0.01; // Default order size +input string InpComment = __FILE__; // Default trade comment +input int InpMagicNumber = 20200000; // Magic Number + +// +// Declare the expert, use the child class name +// +#define CExpert CExpertBase +CExpert *Expert; + +// +// Signals, use the child class names if applicable +// +CSignalBase *EntrySignal; + +// +// TPSL - use child class name +// +CTPSLSimple *TPSL; + +// +// Indicators - use the child class name here +// +CIndicatorMA *FastIndicator; +CIndicatorMA *SlowIndicator; +// And for the TPSL +CIndicatorATR *IndicatorATR; + +int OnInit() { + + // + // Instantiate the expert + // + Expert = new CExpert(); + + // + // Assign the default values to the expert + // + Expert.SetVolume(InpVolume); + Expert.SetTradeComment(InpComment); + Expert.SetMagic(InpMagicNumber); + + // + // Create the indicators + // + FastIndicator = new CIndicatorMA(InpFastPeriods, 0, InpFastMethod, InpFastAppliedPrice); + SlowIndicator = new CIndicatorMA(InpSlowPeriods, 0, InpSlowMethod, InpSlowAppliedPrice); + + // + // Set up the signals + // + EntrySignal = new CSignalCrossover(); + EntrySignal.AddIndicator(FastIndicator, 0); + EntrySignal.AddIndicator(SlowIndicator, 0); + + //ExitSignal = Not needed, using the same signal as entry + + // + // Add the signals to the expert + // + Expert.AddEntrySignal(EntrySignal); + Expert.AddExitSignal(EntrySignal); // Same signal + + // + // Set up the ATR TPSL + // + TPSL = new CTPSLSimple(); + IndicatorATR = new CIndicatorATR(InpATRPeriods); + TPSL.AddIndicator(IndicatorATR, 0); + TPSL.SetIndex(1); + TPSL.SetMultiplier(InpATRMultiplier); + Expert.SetTakeProfitObj(TPSL); + Expert.SetStopLossObj(TPSL); + + // + // Finish expert initialisation and check result + // + int result = Expert.OnInit(); + + return(result); + +} + +void OnDeinit(const int reason) { + + EventKillTimer(); + + delete Expert; + + delete EntrySignal; + + delete TPSL; + + delete FastIndicator; + delete SlowIndicator; + delete IndicatorATR; + + return; + +} + +void OnTick() { + + Expert.OnTick(); + return; + +} + +void OnTimer() { + + Expert.OnTimer(); + return; + +} + +double OnTester() { + + return(Expert.OnTester()); + +} + +void OnChartEvent(const int id, + const long &lparam, + const double &dparam, + const string &sparam) { + + Expert.OnChartEvent(id, lparam, dparam, sparam); + return; + +} + + diff --git a/Experts/Nkanven/Framework EA/MA Crossover ATR TPSL/MA Crossover ATR TPSL.mq5 b/Experts/Nkanven/Framework EA/MA Crossover ATR TPSL/MA Crossover ATR TPSL.mq5 new file mode 100644 index 0000000..ad81a92 --- /dev/null +++ b/Experts/Nkanven/Framework EA/MA Crossover ATR TPSL/MA Crossover ATR TPSL.mq5 @@ -0,0 +1,221 @@ +/* + + MA Crossover ATR TPSL.mq5 + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + Description: + +*/ + +#property copyright "Copyright 2013-2020, Orchard Forex" +#property link "https://www.orchardforex.com" +#property version "1.00" +#property strict + +// +// This is where we pull in the framework +// +#include + +// +// Input Section +// +// Fast moving average +input int InpFastPeriods = 10; // Fast periods +input ENUM_MA_METHOD InpFastMethod = MODE_SMA; // Fast method +input ENUM_APPLIED_PRICE InpFastAppliedPrice = PRICE_CLOSE; // Fast price + +// Slow moving average +input int InpSlowPeriods = 20; // Slow periods +input ENUM_MA_METHOD InpSlowMethod = MODE_SMA; // Slow method +input ENUM_APPLIED_PRICE InpSlowAppliedPrice = PRICE_CLOSE; // Slow price + +// +// For ATR based TPSL +// +input int InpATRPeriods = 14; // ATR Periods +input double InpATRMultiplier = 3.0; // ATR Multiplier + +// +// Some standard inputs, +// remember to change the default magic for each EA +// +input double InpVolume = 0.01; // Default order size +input string InpComment = __FILE__; // Default trade comment +input int InpMagicNumber = 20200000; // Magic Number + +// +// Declare the expert, use the child class name +// +#define CExpert CExpertBase +CExpert *Expert; + +// +// Signals, use the child class names if applicable +// +CSignalBase *EntrySignal; +CSignalBase *ExitSignal; + +// +// TPSL +// +CTPSLSimple *TPSL; + +// +// Indicators - use the child class name here +// +CIndicatorMA *FastIndicator; +CIndicatorMA *SlowIndicator; +// And for the TPSL +CIndicatorATR *IndicatorATR; + +int OnInit() { + + // + // Instantiate the expert + // + Expert = new CExpert(); + + // + // Assign the default values to the expert + // + Expert.SetVolume(InpVolume); + Expert.SetTradeComment(InpComment); + Expert.SetMagic(InpMagicNumber); + + // + // Create the indicators + // + FastIndicator = new CIndicatorMA(InpFastPeriods, 0, InpFastMethod, InpFastAppliedPrice); + SlowIndicator = new CIndicatorMA(InpSlowPeriods, 0, InpSlowMethod, InpSlowAppliedPrice); + + // + // Set up the signals + // + EntrySignal = new CSignalCrossover(); + EntrySignal.AddIndicator(FastIndicator, 0); + EntrySignal.AddIndicator(SlowIndicator, 0); + + //ExitSignal = Not needed, using the same signal as entry + + // + // Add the signals to the expert + // + Expert.AddEntrySignal(EntrySignal); + Expert.AddExitSignal(EntrySignal); // Same signal + + // + // Set up the ATR TPSL + // + TPSL = new CTPSLSimple(); + IndicatorATR = new CIndicatorATR(InpATRPeriods); + TPSL.AddIndicator(IndicatorATR, 0); + TPSL.SetIndex(1); + TPSL.SetMultiplier(InpATRMultiplier); + Expert.SetTakeProfitObj(TPSL); + Expert.SetStopLossObj(TPSL); + + // + // Finish expert initialisation and check result + // + int result = Expert.OnInit(); + + return(result); + +} + +void OnDeinit(const int reason) { + + EventKillTimer(); + + delete Expert; + + delete EntrySignal; + + delete TPSL; + + delete FastIndicator; + delete SlowIndicator; + delete IndicatorATR; + + return; + +} + +void OnTick() { + + Expert.OnTick(); + return; + +} + +void OnTimer() { + + Expert.OnTimer(); + return; + +} + +void OnTrade() { + + Expert.OnTrade(); + return; + +} + +void OnTradeTransaction(const MqlTradeTransaction& trans, + const MqlTradeRequest& request, + const MqlTradeResult& result) { + + Expert.OnTradeTransaction(trans, request, result); + return; + +} + +double OnTester() { + + return(Expert.OnTester()); + +} + +void OnTesterInit() { + + Expert.OnTesterInit(); + return; + +} + +void OnTesterPass() { + + Expert.OnTesterPass(); + return; + +} + +void OnTesterDeinit() { + + Expert.OnTesterDeinit(); + return; + +} + +void OnChartEvent(const int id, + const long &lparam, + const double &dparam, + const string &sparam) { + + Expert.OnChartEvent(id, lparam, dparam, sparam); + return; + +} + +void OnBookEvent(const string &symbol) { + + Expert.OnBookEvent(); + return; + +} + + diff --git a/Experts/Nkanven/Framework EA/MA Crossover/MA Crossover.ex5 b/Experts/Nkanven/Framework EA/MA Crossover/MA Crossover.ex5 new file mode 100644 index 0000000..9691ee2 Binary files /dev/null and b/Experts/Nkanven/Framework EA/MA Crossover/MA Crossover.ex5 differ diff --git a/Experts/Nkanven/Framework EA/MA Crossover/MA Crossover.mq4 b/Experts/Nkanven/Framework EA/MA Crossover/MA Crossover.mq4 new file mode 100644 index 0000000..4492408 --- /dev/null +++ b/Experts/Nkanven/Framework EA/MA Crossover/MA Crossover.mq4 @@ -0,0 +1,153 @@ +/* + + MA Crossover.mq4 + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + Description: + +*/ + +#property copyright "Copyright 2013-2020, Orchard Forex" +#property link "https://www.orchardforex.com" +#property version "1.00" +#property strict + +// +// This is where we pull in the framework +// +#include + +// +// Input Section +// +// Fast moving average +input int InpFastPeriods = 10; // Fast periods +input ENUM_MA_METHOD InpFastMethod = MODE_SMA; // Fast method +input ENUM_APPLIED_PRICE InpFastAppliedPrice = PRICE_CLOSE; // Fast price + +// Slow moving average +input int InpSlowPeriods = 20; // Slow periods +input ENUM_MA_METHOD InpSlowMethod = MODE_SMA; // Slow method +input ENUM_APPLIED_PRICE InpSlowAppliedPrice = PRICE_CLOSE; // Slow price + +// Bar numbers for comparison +//input int InpBar2 = 2; // Base bar number +//input int InpBar1 = 1; // Crossover bar number + +// +// Some standard inputs, +// remember to change the default magic for each EA +// +input double InpVolume = 0.01; // Default order size +input string InpComment = __FILE__; // Default trade comment +input int InpMagicNumber = 20200701; // Magic Number + +// +// Declare the expert, use the child class name +// +#define CExpert CExpertBase +CExpert *Expert; + +// +// Signals, use the child class names if applicable +// +CSignalBase *EntrySignal; +CSignalBase *ExitSignal; + +// +// Indicators - use the child class name here +// +CIndicatorMA *FastIndicator; +CIndicatorMA *SlowIndicator; + +int OnInit() { + + // + // Instantiate the expert + // + Expert = new CExpert(); + + // + // Assign the default values to the expert + // + Expert.SetVolume(InpVolume); + Expert.SetTradeComment(InpComment); + Expert.SetMagic(InpMagicNumber); + + // + // Create the indicators + // + FastIndicator = new CIndicatorMA(InpFastPeriods, 0, InpFastMethod, InpFastAppliedPrice); + SlowIndicator = new CIndicatorMA(InpSlowPeriods, 0, InpSlowMethod, InpSlowAppliedPrice); + + // + // Set up the signals + // + EntrySignal = new CSignalCrossover(); + EntrySignal.AddIndicator(FastIndicator, 0); + EntrySignal.AddIndicator(SlowIndicator, 0); + + //ExitSignal = Not needed, using the same signal as entry + + // + // Add the signals to the expert + // + Expert.AddEntrySignal(EntrySignal); + Expert.AddExitSignal(EntrySignal); // Same signal + + // + // Finish expert initialisation and check result + // + int result = Expert.OnInit(); + + return(result); + +} + +void OnDeinit(const int reason) { + + EventKillTimer(); + + delete Expert; + //delete ExitSignal; + delete EntrySignal; + delete FastIndicator; + delete SlowIndicator; + + return; + +} + +void OnTick() { + + Expert.OnTick(); + return; + +} + +void OnTimer() { + + Expert.OnTimer(); + return; + +} + +double OnTester() { + + return(Expert.OnTester()); + +} + +void OnChartEvent(const int id, + const long &lparam, + const double &dparam, + const string &sparam) { + + Expert.OnChartEvent(id, lparam, dparam, sparam); + return; + +} + + diff --git a/Experts/Nkanven/Framework EA/MA Crossover/MA Crossover.mq5 b/Experts/Nkanven/Framework EA/MA Crossover/MA Crossover.mq5 new file mode 100644 index 0000000..caec3bc --- /dev/null +++ b/Experts/Nkanven/Framework EA/MA Crossover/MA Crossover.mq5 @@ -0,0 +1,197 @@ +/* + + MA Crossover.mq5 + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + Description: + +*/ + +#property copyright "Copyright 2013-2020, Orchard Forex" +#property link "https://www.orchardforex.com" +#property version "1.00" +#property strict + +// +// This is where we pull in the framework +// +#include + +// +// Input Section +// +// Fast moving average +input int InpFastPeriods = 10; // Fast periods +input ENUM_MA_METHOD InpFastMethod = MODE_SMA; // Fast method +input ENUM_APPLIED_PRICE InpFastAppliedPrice = PRICE_CLOSE; // Fast price + +// Slow moving average +input int InpSlowPeriods = 20; // Slow periods +input ENUM_MA_METHOD InpSlowMethod = MODE_SMA; // Slow method +input ENUM_APPLIED_PRICE InpSlowAppliedPrice = PRICE_CLOSE; // Slow price + +// Bar numbers for comparison +//input int InpBar2 = 2; // Base bar number +//input int InpBar1 = 1; // Crossover bar number + +// +// Some standard inputs, +// remember to change the default magic for each EA +// +input double InpVolume = 0.01; // Default order size +input string InpComment = __FILE__; // Default trade comment +input int InpMagicNumber = 20200701; // Magic Number + +// +// Declare the expert, use the child class name +// +#define CExpert CExpertBase +CExpert *Expert; + +// +// Signals, use the child class names if applicable +// +CSignalBase *EntrySignal; +CSignalBase *ExitSignal; + +// +// Indicators - use the child class name here +// +CIndicatorMA *FastIndicator; +CIndicatorMA *SlowIndicator; + +int OnInit() { + + // + // Instantiate the expert + // + Expert = new CExpert(); + + // + // Assign the default values to the expert + // + Expert.SetVolume(InpVolume); + Expert.SetTradeComment(InpComment); + Expert.SetMagic(InpMagicNumber); + + // + // Create the indicators + // + FastIndicator = new CIndicatorMA(InpFastPeriods, 0, InpFastMethod, InpFastAppliedPrice); + SlowIndicator = new CIndicatorMA(InpSlowPeriods, 0, InpSlowMethod, InpSlowAppliedPrice); + + // + // Set up the signals + // + EntrySignal = new CSignalCrossover(); + EntrySignal.AddIndicator(FastIndicator, 0); + EntrySignal.AddIndicator(SlowIndicator, 0); + + //ExitSignal = Not needed, using the same signal as entry + + // + // Add the signals to the expert + // + Expert.AddEntrySignal(EntrySignal); + Expert.AddExitSignal(EntrySignal); // Same signal + + // + // Finish expert initialisation and check result + // + int result = Expert.OnInit(); + + return(result); + +} + +void OnDeinit(const int reason) { + + EventKillTimer(); + + delete Expert; + //delete ExitSignal; + delete EntrySignal; + delete FastIndicator; + delete SlowIndicator; + + return; + +} + +void OnTick() { + + Expert.OnTick(); + return; + +} + +void OnTimer() { + + Expert.OnTimer(); + return; + +} + +void OnTrade() { + + Expert.OnTrade(); + return; + +} + +void OnTradeTransaction(const MqlTradeTransaction& trans, + const MqlTradeRequest& request, + const MqlTradeResult& result) { + + Expert.OnTradeTransaction(trans, request, result); + return; + +} + +double OnTester() { + + return(Expert.OnTester()); + +} + +void OnTesterInit() { + + Expert.OnTesterInit(); + return; + +} + +void OnTesterPass() { + + Expert.OnTesterPass(); + return; + +} + +void OnTesterDeinit() { + + Expert.OnTesterDeinit(); + return; + +} + +void OnChartEvent(const int id, + const long &lparam, + const double &dparam, + const string &sparam) { + + Expert.OnChartEvent(id, lparam, dparam, sparam); + return; + +} + +void OnBookEvent(const string &symbol) { + + Expert.OnBookEvent(); + return; + +} + + diff --git a/Experts/Nkanven/GridEA.ex5 b/Experts/Nkanven/GridEA.ex5 new file mode 100644 index 0000000..6eadeed Binary files /dev/null and b/Experts/Nkanven/GridEA.ex5 differ diff --git a/Include/Nkanven/Frameworks/Extensions/AllExtensions.mqh b/Include/Nkanven/Frameworks/Extensions/AllExtensions.mqh new file mode 100644 index 0000000..d3081db --- /dev/null +++ b/Include/Nkanven/Frameworks/Extensions/AllExtensions.mqh @@ -0,0 +1,16 @@ +/* + All.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + Auto Generated at 2021-07-10 17:11:59 + +*/ + +// +// Extension go here +// +#include "AllIndicators.mqh" +#include "AllSignals.mqh" +#include "AllTPSL.mqh" diff --git a/Include/Nkanven/Frameworks/Extensions/AllGridExtensions.mqh b/Include/Nkanven/Frameworks/Extensions/AllGridExtensions.mqh new file mode 100644 index 0000000..ea6f4de --- /dev/null +++ b/Include/Nkanven/Frameworks/Extensions/AllGridExtensions.mqh @@ -0,0 +1,6 @@ +// +// Extension go here +// +#include "GridSignals.mqh" +#include "GridTPSL.mqh" +#include "GlobalEnumDefinitions.mqh" \ No newline at end of file diff --git a/Include/Nkanven/Frameworks/Extensions/AllIndicators.mqh b/Include/Nkanven/Frameworks/Extensions/AllIndicators.mqh new file mode 100644 index 0000000..73ef5cb --- /dev/null +++ b/Include/Nkanven/Frameworks/Extensions/AllIndicators.mqh @@ -0,0 +1,16 @@ +/* + All.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + Auto Generated at 2021-07-10 17:11:59 + +*/ + +// +// Extension go here +// +#include "Indicators/IndicatorATR.mqh" +#include "Indicators/IndicatorMA.mqh" +#include "Indicators/IndicatorTemplate.mqh" diff --git a/Include/Nkanven/Frameworks/Extensions/AllSignals.mqh b/Include/Nkanven/Frameworks/Extensions/AllSignals.mqh new file mode 100644 index 0000000..fbc665c --- /dev/null +++ b/Include/Nkanven/Frameworks/Extensions/AllSignals.mqh @@ -0,0 +1,17 @@ +/* + All.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + Auto Generated at 2021-07-10 17:11:59 + +*/ + +// +// Extension go here +// +#include "Signals/SignalCombination.mqh" +#include "Signals/SignalCrossover.mqh" +#include "Signals/SignalTemplate.mqh" +#include "Signals/SignalGrid.mqh" diff --git a/Include/Nkanven/Frameworks/Extensions/AllTPSL.mqh b/Include/Nkanven/Frameworks/Extensions/AllTPSL.mqh new file mode 100644 index 0000000..15c4d3e --- /dev/null +++ b/Include/Nkanven/Frameworks/Extensions/AllTPSL.mqh @@ -0,0 +1,15 @@ +/* + All.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + Auto Generated at 2021-07-10 17:11:59 + +*/ + +// +// Extension go here +// +#include "TPSL/TPSLSimple.mqh" +#include "TPSL/TPSLTemplate.mqh" diff --git a/Include/Nkanven/Frameworks/Extensions/GlobalEnumDefinitions.mqh b/Include/Nkanven/Frameworks/Extensions/GlobalEnumDefinitions.mqh new file mode 100644 index 0000000..fab455f --- /dev/null +++ b/Include/Nkanven/Frameworks/Extensions/GlobalEnumDefinitions.mqh @@ -0,0 +1,29 @@ +//+------------------------------------------------------------------+ +//| GlobalEnumDefinitions.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" + +enum ENUM_TRADING_SESSION + { + LONDON_SESSION=1, + NEWYORK_SESSION=2, + TOKYO_SESSION=3, + }; + +//Enumerative for the default risk size +enum ENUM_RISK_DEFAULT_SIZE + { + RISK_DEFAULT_FIXED=1, //FIXED SIZE + RISK_DEFAULT_AUTO=2, //AUTOMATIC SIZE BASED ON RISK + }; + +//Enumerative for the base used for risk calculation +enum ENUM_RISK_BASE + { + RISK_BASE_EQUITY=1, //EQUITY + RISK_BASE_BALANCE=2, //BALANCE + RISK_BASE_FREEMARGIN=3, //FREE MARGIN + }; \ No newline at end of file diff --git a/Include/Nkanven/Frameworks/Extensions/GridSignals.mqh b/Include/Nkanven/Frameworks/Extensions/GridSignals.mqh new file mode 100644 index 0000000..dac6402 --- /dev/null +++ b/Include/Nkanven/Frameworks/Extensions/GridSignals.mqh @@ -0,0 +1,5 @@ +// +// Extension go here +// + +#include "Signals/SignalGrid.mqh" \ No newline at end of file diff --git a/Include/Nkanven/Frameworks/Extensions/GridTPSL.mqh b/Include/Nkanven/Frameworks/Extensions/GridTPSL.mqh new file mode 100644 index 0000000..1682b6a --- /dev/null +++ b/Include/Nkanven/Frameworks/Extensions/GridTPSL.mqh @@ -0,0 +1,4 @@ +// +// Extension go here +// +#include "TPSL/GridTPSL.mqh" diff --git a/Include/Nkanven/Frameworks/Extensions/Indicators/IndicatorATR.mqh b/Include/Nkanven/Frameworks/Extensions/Indicators/IndicatorATR.mqh new file mode 100644 index 0000000..00822fc --- /dev/null +++ b/Include/Nkanven/Frameworks/Extensions/Indicators/IndicatorATR.mqh @@ -0,0 +1,77 @@ +/* + IndicatorATR.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +#include "../../Framework.mqh" + +class CIndicatorATR : public CIndicatorBase { + +private: + +protected: // member variables + + int mPeriods; + + +public: // constructors + + CIndicatorATR(int periods) + : CIndicatorBase() + { Init(periods); } + CIndicatorATR(string symbol, ENUM_TIMEFRAMES timeframe, + int periods) + : CIndicatorBase(symbol, timeframe) + { Init(periods); } + ~CIndicatorATR(); + + virtual int Init(int periods); + +public: + + virtual double GetData(const int buffer_num,const int index); + +}; + +CIndicatorATR::~CIndicatorATR() { + +} + +int CIndicatorATR::Init(int periods) { + + if (InitResult()!=INIT_SUCCEEDED) return(InitResult()); + + mPeriods = periods; + +#ifdef __MQL5__ + mIndicatorHandle = iATR(mSymbol, mTimeframe, mPeriods); + if (mIndicatorHandle==INVALID_HANDLE) return(InitError("Failed to create indicator handle", INIT_FAILED)); +#endif + + return(INIT_SUCCEEDED); + +} + +double CIndicatorATR::GetData(const int buffer_num,const int index) { + + double value = 0; + +#ifdef __MQL4__ + value = iATR(mSymbol, mTimeframe, mPeriods, index); +#endif + +#ifdef __MQL5__ + double bufferData[]; + ArraySetAsSeries(bufferData, true); + int cnt = CopyBuffer(mIndicatorHandle, buffer_num, index, 1, bufferData); + if (cnt>0) value = bufferData[0]; +#endif + + return(value); + +} + + diff --git a/Include/Nkanven/Frameworks/Extensions/Indicators/IndicatorMA.mqh b/Include/Nkanven/Frameworks/Extensions/Indicators/IndicatorMA.mqh new file mode 100644 index 0000000..7391f4a --- /dev/null +++ b/Include/Nkanven/Frameworks/Extensions/Indicators/IndicatorMA.mqh @@ -0,0 +1,82 @@ +/* + IndicatorMA.mqh + Updated - requires version 2.01 or later + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +#include "../../Framework.mqh" + +class CIndicatorMA : public CIndicatorBase { + +private: + +protected: // member variables + + int mPeriods; + int mShift; + ENUM_MA_METHOD mMethod; + ENUM_APPLIED_PRICE mAppliedPrice; + +public: // constructors + + CIndicatorMA(int periods, int shift, ENUM_MA_METHOD method, ENUM_APPLIED_PRICE appliedPrice) + : CIndicatorBase() + { Init(periods, shift, method, appliedPrice); } + CIndicatorMA(string symbol, ENUM_TIMEFRAMES timeframe, + int periods, int shift, ENUM_MA_METHOD method, ENUM_APPLIED_PRICE appliedPrice) + : CIndicatorBase(symbol, timeframe) + { Init(periods, shift, method, appliedPrice); } + ~CIndicatorMA(); + + virtual int Init(int periods, int shift, ENUM_MA_METHOD method, ENUM_APPLIED_PRICE appliedPrice); + +public: + + virtual double GetData(const int buffer_num,const int index); + +}; + +CIndicatorMA::~CIndicatorMA() { + +} + +int CIndicatorMA::Init(int periods, int shift, ENUM_MA_METHOD method, ENUM_APPLIED_PRICE appliedPrice) { + + if (InitResult()!=INIT_SUCCEEDED) return(InitResult()); + + mPeriods = periods; + mShift = shift; + mMethod = method; + mAppliedPrice = appliedPrice; + +#ifdef __MQL5__ + mIndicatorHandle = iMA(mSymbol, mTimeframe, mPeriods, mShift, mMethod, mAppliedPrice); + if (mIndicatorHandle==INVALID_HANDLE) return(InitError("Failed to create indicator handle", INIT_FAILED)); +#endif + + return(INIT_SUCCEEDED); + +} + +double CIndicatorMA::GetData(const int buffer_num,const int index) { + + double value = 0; +#ifdef __MQL4__ + value = iMA(mSymbol, mTimeframe, mPeriods, mShift, mMethod, mAppliedPrice, index); +#endif + +#ifdef __MQL5__ + double bufferData[]; + ArraySetAsSeries(bufferData, true); + int cnt = CopyBuffer(mIndicatorHandle, buffer_num, index, 1, bufferData); + if (cnt>0) value = bufferData[0]; +#endif + + return(value); + +} + + diff --git a/Include/Nkanven/Frameworks/Extensions/Indicators/IndicatorTemplate.mqh b/Include/Nkanven/Frameworks/Extensions/Indicators/IndicatorTemplate.mqh new file mode 100644 index 0000000..898f7e1 --- /dev/null +++ b/Include/Nkanven/Frameworks/Extensions/Indicators/IndicatorTemplate.mqh @@ -0,0 +1,91 @@ +/* + IndicatorTemplate.mqh + Updated as of framework version 2.02 + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +// Next line assumes this file is located in .../Frameworks/Extensions/someFolder +#include "../../Framework.mqh" + +class CIndicatorTemplate : public CIndicatorBase { + +private: + +protected: // member variables + +// Place any required member variables here + +public: // constructors + + // Add any required constructor arguments + // e.g. CIndicatorXYZ(int periods, double multiplier) + CIndicatorTemplate() + : CIndicatorBase() + { Init(); } + // Same constructor with symbol and timeframe added + CIndicatorTemplate(string symbol, ENUM_TIMEFRAMES timeframe) + : CIndicatorBase(symbol, timeframe) + { Init(); } + ~CIndicatorTemplate(); + + // Include all arguments to match the constructor + virtual int Init(); + +public: + + // Add this line to override the same function from the parent class + virtual double GetData(const int buffer_num,const int index); + +}; + +CIndicatorTemplate::~CIndicatorTemplate() { + + // Any destructors here + +} + +int CIndicatorTemplate::Init() { + + // Checks if init has been set to fail by any parent class already + if (InitResult()!=INIT_SUCCEEDED) return(InitResult()); + + // Assign variables and do any other initialisation here + +#ifdef __MQL5__ + // Just using iMA as an example here, replace as necessary +// mIndicatorHandle = iMA(mSymbol, mTimeframe, mPeriods, mShift, mMethod, mAppliedPrice); +// if (mIndicatorHandle==INVALID_HANDLE) return(InitError("Failed to create indicator handle", INIT_FAILED)); +#endif + + return(INIT_SUCCEEDED); + +} + +double CIndicatorTemplate::GetData(const int buffer_num,const int index) { + + double value = 0; +#ifdef __MQL4__ + // Next line is just an example using iMA + // value = iMA(mSymbol, mTimeframe, mPeriods, mShift, mMethod, mAppliedPrice, index); +#endif + +#ifdef __MQL5__ + // For MQL5 once indicator handle is set the code here should be common + // Declare a buffer to hold the data being retrieved + double bufferData[]; + // Set as series so the sequence matches the chrt + ArraySetAsSeries(bufferData, true); + // Copy indicator data into the buffer and get the count of elements + int cnt = CopyBuffer(mIndicatorHandle, buffer_num, index, 1, bufferData); + // If not enough elements came back then don't use the data + if (cnt>0) value = bufferData[0]; +#endif + + return(value); + +} + + diff --git a/Include/Nkanven/Frameworks/Extensions/Signals/SignalCombination.mqh b/Include/Nkanven/Frameworks/Extensions/Signals/SignalCombination.mqh new file mode 100644 index 0000000..ca0a7bd --- /dev/null +++ b/Include/Nkanven/Frameworks/Extensions/Signals/SignalCombination.mqh @@ -0,0 +1,86 @@ +/* + SignalCombination.mqh + For framework version 1.0 + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +#include "../../Framework.mqh" + +class CSignalCombination : public CSignalBase { + +private: + +protected: // member variables + + CSignalBase *mSignals[]; + +public: // constructors + + CSignalCombination(string symbol, ENUM_TIMEFRAMES timeframe) + : CSignalBase(symbol, timeframe) + { Init(); } + CSignalCombination() + : CSignalBase() + { Init(); } + ~CSignalCombination() { } + + int Init(); + +public: + + virtual void AddSignal(CSignalBase *signal); + virtual void UpdateSignal(); + +}; + +int CSignalCombination::Init() { + + if (InitResult()!=INIT_SUCCEEDED) return(InitResult()); + + ArrayResize(mSignals, 0); + + return(INIT_SUCCEEDED); + +} + +void CSignalCombination::UpdateSignal() { + + int index = ArraySize(mSignals); + + if (index<=0) { + + mEntrySignal = OFX_SIGNAL_NONE; + mExitSignal = OFX_SIGNAL_NONE; + + } else { + + mSignals[0].UpdateSignal(); + mEntrySignal = mSignals[0].EntrySignal(); + mExitSignal = mSignals[0].ExitSignal(); + + for (int i = 1; islow1) && !(fast2>slow2) ) { // Crossed up + mEntrySignal = OFX_SIGNAL_BUY; + mExitSignal = OFX_SIGNAL_SELL; + } else + if ( (fast10) value = bufferData[0]; +#endif + + return(value); + +} + + diff --git a/Include/Nkanven/Frameworks/Framework_1.00/Indicators/IndicatorBase.mqh b/Include/Nkanven/Frameworks/Framework_1.00/Indicators/IndicatorBase.mqh new file mode 100644 index 0000000..074800d --- /dev/null +++ b/Include/Nkanven/Frameworks/Framework_1.00/Indicators/IndicatorBase.mqh @@ -0,0 +1,44 @@ +/* + IndicatorBase.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +#include "../CommonBase.mqh" + +class CIndicatorBase : public CCommonBase { + +private: + +protected: // member variables + +public: // constructors + + CIndicatorBase() : CCommonBase() + { Init(); } + CIndicatorBase(string symbol, ENUM_TIMEFRAMES timeframe) + : CCommonBase(symbol, timeframe) + { Init(); } + ~CIndicatorBase() { } + + int Init(); + +public: + + virtual double GetData(const int index) { return(GetData(0,index)); } + virtual double GetData(const int bufferNum, const int index){ return (0); } + +}; + +int CIndicatorBase::Init() { + + if (InitResult()!=INIT_SUCCEEDED) return(InitResult()); + + return(INIT_SUCCEEDED); + +} + + + diff --git a/Include/Nkanven/Frameworks/Framework_1.00/Signals/AllSignals.mqh b/Include/Nkanven/Frameworks/Framework_1.00/Signals/AllSignals.mqh new file mode 100644 index 0000000..89bd126 --- /dev/null +++ b/Include/Nkanven/Frameworks/Framework_1.00/Signals/AllSignals.mqh @@ -0,0 +1,15 @@ +/* + AllSignals.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + +*/ + +#include "SignalBase.mqh" + +// +// Other signals go here +// +#include "Crossover/SignalCrossover.mqh" diff --git a/Include/Nkanven/Frameworks/Framework_1.00/Signals/Crossover/SignalCrossover.mqh b/Include/Nkanven/Frameworks/Framework_1.00/Signals/Crossover/SignalCrossover.mqh new file mode 100644 index 0000000..f54bad7 --- /dev/null +++ b/Include/Nkanven/Frameworks/Framework_1.00/Signals/Crossover/SignalCrossover.mqh @@ -0,0 +1,78 @@ +/* + SignalCrossover.mqh + For framework version 1.0 + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +#include "../SignalBase.mqh" + +class CSignalCrossover : public CSignalBase { + +private: + +protected: // member variables + + int mIndex1; + int mIndex2; + +public: // constructors + + CSignalCrossover(string symbol, ENUM_TIMEFRAMES timeframe, + int index1=1, int index2=2) + : CSignalBase(symbol, timeframe) + { Init(index1, index2); } + CSignalCrossover(int index1=1, int index2=2) + : CSignalBase() + { Init(index1, index2); } + ~CSignalCrossover() { } + + int Init(int index1, int index2); + +public: + + virtual void UpdateSignal(); + +}; + +int CSignalCrossover::Init(int index1, int index2) { + + if (InitResult()!=INIT_SUCCEEDED) return(InitResult()); + + mIndex1 = index1; + mIndex2 = index2; + + return(INIT_SUCCEEDED); + +} + +void CSignalCrossover::UpdateSignal() { + + double fast1 = GetIndicatorData(0, mIndex1); + double fast2 = GetIndicatorData(0, mIndex2); + double slow1 = GetIndicatorData(1, mIndex1); + double slow2 = GetIndicatorData(1, mIndex2); + + // There is a less common condition where the fast + // indicator touches the slow indicator and then + // reverses. With the conditions below this would + // appear like a cross. + if ( (fast1>slow1) && !(fast2>slow2) ) { // Crossed up + mEntrySignal = OFX_SIGNAL_BUY; + mExitSignal = OFX_SIGNAL_SELL; + } else + if ( (fast10); +} + +bool CTradeCustom::Sell(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment="") { + if (price==0.0) price = SellPrice(symbol); + int ticket = OrderSend(symbol, ORDER_TYPE_SELL, volume, price, 0, sl, tp, comment, mMagic); + return(ticket>0); +} + +bool CTradeCustom::PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType, const int deviation=ULONG_MAX) { + + int slippage = (deviation==ULONG_MAX) ? 0 : deviation; + + bool result = true; + int cnt = OrdersTotal(); + for (int i = cnt-1; i>=0; i--) { + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + if (OrderSymbol()==symbol && OrderMagicNumber()==mMagic && OrderType()==positionType) { + result &= OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slippage); + } + } + } + + return(result); + +} diff --git a/Include/Nkanven/Frameworks/Framework_1.00/Trade/Trade_mql5.mqh b/Include/Nkanven/Frameworks/Framework_1.00/Trade/Trade_mql5.mqh new file mode 100644 index 0000000..90cfcbd --- /dev/null +++ b/Include/Nkanven/Frameworks/Framework_1.00/Trade/Trade_mql5.mqh @@ -0,0 +1,44 @@ +/* + Trade.mqh + (For MQL5) + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +#include + +class CTradeCustom : public CTrade { + +private: + +protected: // member variables + +public: // constructors + +public: + + bool PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType,const ulong deviation=ULONG_MAX); + +}; + +bool CTradeCustom::PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType, const ulong deviation=ULONG_MAX) { + + bool result = true; + int cnt = PositionsTotal(); + for (int i = cnt-1; i>=0; i--) { + ulong ticket = PositionGetTicket(i); + if (PositionSelectByTicket(ticket)) { + if (PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==positionType && PositionGetInteger(POSITION_MAGIC)==m_magic) { + result &= PositionClose(ticket, deviation); + } + } else { + m_result.retcode=TRADE_RETCODE_REJECT; + result = false; + } + } + + return(result); + +} diff --git a/Include/Nkanven/Frameworks/Framework_2.04/CommonBase.mqh b/Include/Nkanven/Frameworks/Framework_2.04/CommonBase.mqh new file mode 100644 index 0000000..46edb6a --- /dev/null +++ b/Include/Nkanven/Frameworks/Framework_2.04/CommonBase.mqh @@ -0,0 +1,78 @@ +/* + CommonBase.mqh + For framework version 1.0 + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +#define _INIT_CHECK_FAIL if (mInitResult!=INIT_SUCCEEDED) return(mInitResult); +#define _INIT_ERROR(msg) return(InitError(msg, INIT_PARAMETERS_INCORRECT)); +#define _INIT_ASSERT(condition, msg) if (!condition) return(InitError(msg, INIT_FAILED)); + +class CCommonBase { + +private: + +protected: // Members + + int mDigits; + string mSymbol; + ENUM_TIMEFRAMES mTimeframe; + + string mInitMessage; + int mInitResult; + +protected: // Constructors + + // + // Constructors + // + CCommonBase() { Init(_Symbol, (ENUM_TIMEFRAMES)_Period); } + CCommonBase(string symbol) { Init(symbol, (ENUM_TIMEFRAMES)_Period); } + CCommonBase(int timeframe) { Init(_Symbol, (ENUM_TIMEFRAMES)timeframe); } + CCommonBase(ENUM_TIMEFRAMES timeframe) { Init(_Symbol, timeframe); } + CCommonBase(string symbol, int timeframe) { Init(symbol, (ENUM_TIMEFRAMES)timeframe); } + CCommonBase(string symbol, ENUM_TIMEFRAMES timeframe) { Init(symbol, timeframe); } + + // + // Destructors + // + ~CCommonBase() {}; + + int Init(string symbol, ENUM_TIMEFRAMES timeframe); + +protected: // Functions + + int InitError(string initMessage, int initResult) + { mInitMessage = initMessage; + mInitResult = initResult; + if (initMessage!="") Print(initMessage); + return(initResult); } + + double PointsToDouble(int points) { return(points*SymbolInfoDouble(mSymbol, SYMBOL_POINT)); } + +public: // Properties + + int InitResult() { return(mInitResult); } + string InitMessage() { return(mInitMessage); } + +public: // Functions + + bool TradeAllowed() { return(SymbolInfoInteger(mSymbol, SYMBOL_TRADE_MODE)!=SYMBOL_TRADE_MODE_DISABLED); } + +}; + +int CCommonBase::Init(string symbol, ENUM_TIMEFRAMES timeframe) { + + InitError("", INIT_SUCCEEDED); + + mSymbol = symbol; + mTimeframe = timeframe; + mDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); + + return(INIT_SUCCEEDED); + +} + diff --git a/Include/Nkanven/Frameworks/Framework_2.04/ExpertBase.mqh b/Include/Nkanven/Frameworks/Framework_2.04/ExpertBase.mqh new file mode 100644 index 0000000..e5afc1d --- /dev/null +++ b/Include/Nkanven/Frameworks/Framework_2.04/ExpertBase.mqh @@ -0,0 +1,380 @@ +/* + ExpertBase.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + + +#include "CommonBase.mqh" +#include "SignalBase.mqh" +#include "TPSLBase.mqh" +#include "Trade/Trade.mqh" + +class CExpertBase : public CCommonBase { + +protected: + + int mMagicNumber; + string mTradeComment; + + double mVolume; + + datetime mLastBarTime; + datetime mBarTime; + + ////Changed + // Arrays to hold the signal objects + CSignalBase *mEntrySignals[]; + CSignalBase *mExitSignals[]; + ////CSignalBase *mEntrySignal; + ////CSignalBase *mExitSignal; + + double mTakeProfitValue; + double mStopLossValue; + CTPSLBase *mTakeProfitObj; + CTPSLBase *mStopLossObj; + + CTradeCustom Trade; + +private: + +protected: + + virtual bool LoopMain(bool newBar, bool firstTime); + +protected: + + int Init(int magicNumber, string tradeComment); + +public: + + // + // Constructors + // + CExpertBase() : CCommonBase() + { Init(0, ""); } + CExpertBase(string symbol, int timeframe, int magicNumber, string tradeComment) + : CCommonBase(symbol, timeframe) + { Init(magicNumber, tradeComment); } + CExpertBase(string symbol, ENUM_TIMEFRAMES timeframe, int magicNumber, string tradeComment) + : CCommonBase(symbol, timeframe) + { Init(magicNumber, tradeComment); } + CExpertBase(int magicNumber, string tradeComment) + : CCommonBase() + { Init(magicNumber, tradeComment); } + + // + // Destructors + // + ~CExpertBase(); + +public: // Default properties + + // + // Assign the default values to the expert + // + virtual void SetVolume(double volume) { mVolume = volume; } + + virtual void SetTakeProfitValue(int takeProfitPoints) + { mTakeProfitValue = PointsToDouble(takeProfitPoints); } + virtual void SetTakeProfitObj(CTPSLBase *takeProfitObj) + { mTakeProfitObj = takeProfitObj; } + + virtual void SetStopLossValue(int stopLossPoints) + { mStopLossValue = PointsToDouble(stopLossPoints); } + virtual void SetStopLossObj(CTPSLBase *stopLossObj) + { mStopLossObj = stopLossObj; } + + virtual void SetTradeComment(string comment) { mTradeComment = comment; } + virtual void SetMagic(int magicNumber) { mMagicNumber = magicNumber; + Trade.SetExpertMagicNumber(magicNumber); } + +public: // Setup + + ////Changed + virtual void AddEntrySignal(CSignalBase *signal) { AddSignal(signal, mEntrySignals); } + virtual void AddExitSignal(CSignalBase *signal) { AddSignal(signal, mExitSignals); } + virtual void AddSignal(CSignalBase *signal, CSignalBase* &signals[]); + ////virtual void AddEntrySignal(CSignalBase *signal) { mEntrySignal=signal; } + ////virtual void AddExitSignal(CSignalBase *signal) { mExitSignal=signal; } + +public: // Event handlers + + virtual int OnInit(); + virtual void OnTick(); + virtual void OnTimer() { return; } + virtual double OnTester() { return(0.0); } + virtual void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) {}; + +#ifdef __MQL5__ + virtual void OnTrade() { return; } + virtual void OnTradeTransaction(const MqlTradeTransaction& trans, + const MqlTradeRequest& request, + const MqlTradeResult& result) + { return; } + virtual int OnTesterInit() { return(INIT_SUCCEEDED); } + virtual void OnTesterPass() { return; } + virtual void OnTesterDeinit() { return; } + virtual void OnBookEvent() { return; } +#endif + +public: // Functions + + virtual void GetMarketPrices(ENUM_ORDER_TYPE orderType, MqlTradeRequest &request); + ////New + virtual ENUM_OFX_SIGNAL_DIRECTION GetCurrentSignal(CSignalBase* &signals[], + ENUM_OFX_SIGNAL_TYPE signalType); + +}; + +CExpertBase::~CExpertBase() { + +} + +int CExpertBase::OnInit() { + + int i = 0; + for (i=ArraySize(mEntrySignals)-1; i>=0; i--) { + if (mEntrySignals[i].InitResult()!=INIT_SUCCEEDED) return(mEntrySignals[i].InitResult()); + } + for (i=ArraySize(mExitSignals)-1; i>=0; i--) { + if (mExitSignals[i].InitResult()!=INIT_SUCCEEDED) return(mExitSignals[i].InitResult()); + } + if (mTakeProfitObj!=NULL) { + if (mTakeProfitObj.InitResult()!=INIT_SUCCEEDED) return(mTakeProfitObj.InitResult()); + } + if (mStopLossObj!=NULL) { + if (mStopLossObj.InitResult()!=INIT_SUCCEEDED) return(mStopLossObj.InitResult()); + } + + return(INIT_SUCCEEDED); + +} + +int CExpertBase::Init(int magicNumber, string tradeComment) { + + if (mInitResult!=INIT_SUCCEEDED) return(mInitResult); + + mTradeComment = tradeComment; + SetMagic(magicNumber); + + mTakeProfitValue = 0.0; + mStopLossValue = 0.0; + + mLastBarTime = 0; + + ////New + ArrayResize(mEntrySignals, 0); // Just make sure these are initialised + ArrayResize(mExitSignals, 0); + + return(INIT_SUCCEEDED); + +} + +void CExpertBase::OnTick(void) { + + if (!TradeAllowed()) return; + + mBarTime = iTime(mSymbol, mTimeframe, 0); + + bool firstTime = (mLastBarTime==0); + bool newBar = (mBarTime!=mLastBarTime); + + if (LoopMain(newBar, firstTime)) { + mLastBarTime = mBarTime; + } + + return; + +} + +bool CExpertBase::LoopMain(bool newBar,bool firstTime) { + + // + // To start I will only trade on a new bar + // and not on the first bar after start + // + if (!newBar) return(true); + if (firstTime) return(true); + + // + // Update the signals + // + ////Changed + ENUM_OFX_SIGNAL_DIRECTION entrySignal = GetCurrentSignal(mEntrySignals, OFX_ENTRY_SIGNAL); + ENUM_OFX_SIGNAL_DIRECTION exitSignal = GetCurrentSignal(mExitSignals, OFX_EXIT_SIGNAL); + ////if (mEntrySignal!=NULL) mEntrySignal.UpdateSignal(); + ////if (mEntrySignal!=mExitSignal) { + //// if (mExitSignal!=NULL) mExitSignal.UpdateSignal(); + ////} + + // + // Should any trades be closed + // + ////Changed + if (exitSignal==OFX_SIGNAL_BOTH) { + Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY); + Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL); + } else + if (exitSignal==OFX_SIGNAL_BUY) { + Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY); + } else + if (exitSignal==OFX_SIGNAL_SELL) { + Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL); + } + ////if (mExitSignal!=NULL) { + //// if (mExitSignal.ExitSignal()==OFX_SIGNAL_BOTH) { + //// Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY); + //// Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL); + //// } else + //// if (mExitSignal.ExitSignal()==OFX_SIGNAL_BUY) { + //// Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY); + //// } else + //// if (mExitSignal.ExitSignal()==OFX_SIGNAL_SELL) { + //// Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL); + //// } + ////} + + // + // Should a trade be opened + // + MqlTradeRequest request = {}; // Just initialising + ////Changed + if (entrySignal==OFX_SIGNAL_BOTH) { + + GetMarketPrices(ORDER_TYPE_BUY, request); + Trade.Buy(mVolume, mSymbol, request.price, request.sl, request.tp); + + GetMarketPrices(ORDER_TYPE_SELL, request); + Trade.Sell(mVolume, mSymbol, request.price, request.sl, request.tp); + + } else + if (entrySignal==OFX_SIGNAL_BUY) { + + GetMarketPrices(ORDER_TYPE_BUY, request); + Trade.Buy(mVolume, mSymbol, request.price, request.sl, request.tp); + + } else + if (entrySignal==OFX_SIGNAL_SELL) { + + GetMarketPrices(ORDER_TYPE_SELL, request); + Trade.Sell(mVolume, mSymbol, request.price, request.sl, request.tp); + + } +//// if (mEntrySignal!=NULL) { +//// if (mEntrySignal.EntrySignal()==OFX_SIGNAL_BOTH) { +//// +//// GetMarketPrices(ORDER_TYPE_BUY, request); +//// Trade.Buy(mVolume, mSymbol, request.price, request.sl, request.tp); +//// +//// GetMarketPrices(ORDER_TYPE_SELL, request); +//// Trade.Sell(mVolume, mSymbol, request.price, request.sl, request.tp); +//// +//// } else +//// if (mEntrySignal.EntrySignal()==OFX_SIGNAL_BUY) { +//// +//// GetMarketPrices(ORDER_TYPE_BUY, request); +//// Trade.Buy(mVolume, mSymbol, request.price, request.sl, request.tp); +//// +//// } else +//// if (mEntrySignal.EntrySignal()==OFX_SIGNAL_SELL) { +//// +//// GetMarketPrices(ORDER_TYPE_SELL, request); +//// Trade.Sell(mVolume, mSymbol, request.price, request.sl, request.tp); +//// +//// } +//// } + + return(true); + +} + +void CExpertBase::GetMarketPrices(ENUM_ORDER_TYPE orderType, MqlTradeRequest &request) { + + double sl = (mStopLossObj==NULL) ? mStopLossValue : mStopLossObj.GetStopLoss(); + double tp = (mTakeProfitObj==NULL) ? mTakeProfitValue : mTakeProfitObj.GetTakeProfit(); + + if (orderType==ORDER_TYPE_BUY) { + if (request.price==0.0) request.price = SymbolInfoDouble(mSymbol, SYMBOL_ASK); + request.tp = (tp==0.0) ? 0.0 : NormalizeDouble(request.price+tp, mDigits); + request.sl = (sl==0.0) ? 0.0 : NormalizeDouble(request.price-sl, mDigits); + } + + if (orderType==ORDER_TYPE_SELL) { + if (request.price==0.0) request.price = SymbolInfoDouble(mSymbol, SYMBOL_BID); + request.tp = (tp==0.0) ? 0.0 : NormalizeDouble(request.price-tp, mDigits); + request.sl = (sl==0.0) ? 0.0 : NormalizeDouble(request.price+sl, mDigits); + } + + return; + +} + +////New +void CExpertBase::AddSignal(CSignalBase *signal, CSignalBase* &signals[]) { + + int index = ArraySize(signals); + ArrayResize(signals, index+1); + signals[index] = signal; + +} + +////New +ENUM_OFX_SIGNAL_DIRECTION CExpertBase::GetCurrentSignal(CSignalBase* &signals[], + ENUM_OFX_SIGNAL_TYPE signalType) { + + ENUM_OFX_SIGNAL_DIRECTION result = OFX_SIGNAL_NONE; + ENUM_OFX_SIGNAL_DIRECTION r2 = OFX_SIGNAL_NONE; // Just working value + int index = ArraySize(signals); + + if (index<=0) { + + return(result); + + } else { + + signals[0].UpdateSignal(); + result = signals[0].GetSignal(signalType); + + // I have chosen to update all signals in case there is some + // behavour that needs it. The penalty is some performance + // If performance is an issue just add an exit inside the loop + // as the commented line + for (int i = 1; i0); +} + +bool CTradeCustom::Sell(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment="") { + if (price==0.0) price = SellPrice(symbol); + int ticket = OrderSend(symbol, ORDER_TYPE_SELL, volume, price, 0, sl, tp, comment, mMagic); + return(ticket>0); +} + +bool CTradeCustom::PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType, const int deviation=ULONG_MAX) { + + int slippage = (deviation==ULONG_MAX) ? 0 : deviation; + + bool result = true; + int cnt = OrdersTotal(); + for (int i = cnt-1; i>=0; i--) { + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + if (OrderSymbol()==symbol && OrderMagicNumber()==mMagic && OrderType()==positionType) { + result &= OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slippage); + } + } + } + + return(result); + +} + +////New +void CTradeCustom::PositionCountByType(const string symbol, int &count[]) { + + ArrayResize(count, 6); + ArrayInitialize(count, 0); + int cnt = OrdersTotal(); + for (int i = cnt-1; i>=0; i--) { + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + if (OrderSymbol()==symbol && OrderMagicNumber()==mMagic) { + count[(int)OrderType()]++; + } + } + } + + return; + +} diff --git a/Include/Nkanven/Frameworks/Framework_2.04/Trade/Trade_mql5.mqh b/Include/Nkanven/Frameworks/Framework_2.04/Trade/Trade_mql5.mqh new file mode 100644 index 0000000..3bae1c9 --- /dev/null +++ b/Include/Nkanven/Frameworks/Framework_2.04/Trade/Trade_mql5.mqh @@ -0,0 +1,66 @@ +/* + Trade.mqh + (For MQL5) + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +#include + +class CTradeCustom : public CTrade { + +private: + +protected: // member variables + +public: // constructors + +public: + + bool PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType,const ulong deviation=ULONG_MAX); + ////New + void PositionCountByType(const string symbol, int &count[]); + +}; + +bool CTradeCustom::PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType, const ulong deviation=ULONG_MAX) { + + bool result = true; + int cnt = PositionsTotal(); + for (int i = cnt-1; i>=0; i--) { + ulong ticket = PositionGetTicket(i); + if (PositionSelectByTicket(ticket)) { + if (PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==positionType && PositionGetInteger(POSITION_MAGIC)==m_magic) { + result &= PositionClose(ticket, deviation); + } + } else { + m_result.retcode=TRADE_RETCODE_REJECT; + result = false; + } + } + + return(result); + +} + +////New +void CTradeCustom::PositionCountByType(const string symbol, int &count[]) { + + ArrayResize(count, 6); + ArrayInitialize(count, 0); + + int cnt = PositionsTotal(); + for (int i = cnt-1; i>=0; i--) { + ulong ticket = PositionGetTicket(i); + if (PositionSelectByTicket(ticket)) { + if (PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_MAGIC)==m_magic) { + count[(int)PositionGetInteger(POSITION_TYPE)]++; + } + } + } + + return; + +} diff --git a/Include/Nkanven/Frameworks/Framework_2.04/Updates.txt b/Include/Nkanven/Frameworks/Framework_2.04/Updates.txt new file mode 100644 index 0000000..281bf10 --- /dev/null +++ b/Include/Nkanven/Frameworks/Framework_2.04/Updates.txt @@ -0,0 +1,7 @@ +Version 2.03 + +Added macros to CommonBase to standardise init checking + +Moved base classes up one level and removed unnecessary folders + +Updated framework number \ No newline at end of file diff --git a/Include/Nkanven/Frameworks/GridEA/CommonBase.mqh b/Include/Nkanven/Frameworks/GridEA/CommonBase.mqh new file mode 100644 index 0000000..6ff97cf --- /dev/null +++ b/Include/Nkanven/Frameworks/GridEA/CommonBase.mqh @@ -0,0 +1,75 @@ +/* + CommonBase.mqh + For framework version 1.0 + +*/ + +#define _INIT_CHECK_FAIL if (mInitResult!=INIT_SUCCEEDED) return(mInitResult); +#define _INIT_ERROR(msg) return(InitError(msg, INIT_PARAMETERS_INCORRECT)); +#define _INIT_ASSERT(condition, msg) if (!condition) return(InitError(msg, INIT_FAILED)); + +class CCommonBase { + +private: + +protected: // Members + + int mDigits; + string mSymbol; + ENUM_TIMEFRAMES mTimeframe; + + string mInitMessage; + int mInitResult; + +protected: // Constructors + + // + // Constructors + // + CCommonBase() { Init(_Symbol, (ENUM_TIMEFRAMES)_Period); } + CCommonBase(string symbol) { Init(symbol, (ENUM_TIMEFRAMES)_Period); } + CCommonBase(int timeframe) { Init(_Symbol, (ENUM_TIMEFRAMES)timeframe); } + CCommonBase(ENUM_TIMEFRAMES timeframe) { Init(_Symbol, timeframe); } + CCommonBase(string symbol, int timeframe) { Init(symbol, (ENUM_TIMEFRAMES)timeframe); } + CCommonBase(string symbol, ENUM_TIMEFRAMES timeframe) { Init(symbol, timeframe); } + + // + // Destructors + // + ~CCommonBase() {}; + + int Init(string symbol, ENUM_TIMEFRAMES timeframe); + +protected: // Functions + + int InitError(string initMessage, int initResult) + { mInitMessage = initMessage; + mInitResult = initResult; + if (initMessage!="") Print(initMessage); + return(initResult); } + + double PointsToDouble(int points) { return(points*SymbolInfoDouble(mSymbol, SYMBOL_POINT)); } + +public: // Properties + + int InitResult() { return(mInitResult); } + string InitMessage() { return(mInitMessage); } + +public: // Functions + + bool TradeAllowed() { return(SymbolInfoInteger(mSymbol, SYMBOL_TRADE_MODE)!=SYMBOL_TRADE_MODE_DISABLED); } + +}; + +int CCommonBase::Init(string symbol, ENUM_TIMEFRAMES timeframe) { + + InitError("", INIT_SUCCEEDED); + + mSymbol = symbol; + mTimeframe = timeframe; + mDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); + + return(INIT_SUCCEEDED); + +} + diff --git a/Include/Nkanven/Frameworks/GridEA/ExpertBase.mqh b/Include/Nkanven/Frameworks/GridEA/ExpertBase.mqh new file mode 100644 index 0000000..55c8d6a --- /dev/null +++ b/Include/Nkanven/Frameworks/GridEA/ExpertBase.mqh @@ -0,0 +1,812 @@ +/* + ExpertBase.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + + +#include "CommonBase.mqh" +#include "Trade/Trade.mqh" +#include "../Extensions/AllGridExtensions.mqh" + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +class CExpertBase : public CCommonBase + { + +protected: + + int mMagicNumber; + string mTradeComment; + + double mVolume; + + int GridNumber; + int mGridGap; + int mSlippage; + double mDefaultLotSize; + double mMaxLotSize; + double mMinLotSize; + double mMaxRiskPerTrade; + + + + double lastBuyOrderPrice; + double lastSellOrderPrice; + double openedBuyPositionPrice; + double openedSellPositionPrice; + + + ENUM_TRADING_SESSION mUseTradingSession; + ENUM_RISK_DEFAULT_SIZE mRiskDefaultSize; + ENUM_RISK_BASE mRiskBase; + + enum ENUM_NAV_SIGNAL_TYPE + { + NAV_ENTRY_SIGNAL, + NAV_EXIT_SIGNAL + }; + + ENUM_NAV_SIGNAL_TYPE signalType; + + enum ENUM_NAV_SIGNAL_DIRECTION + { + NAV_SIGNAL_NONE = 0, + NAV_SIGNAL_BUY = 1, + NAV_SIGNAL_SELL = 2, + NAV_SIGNAL_BOTH = 3, + NAV_SIGNAL_ALL = 4 + }; + + ENUM_NAV_SIGNAL_DIRECTION signalDirection; + + datetime mLastBarTime; + datetime mBarTime; + + bool mResetGrid; + + ////Changed + // Arrays to hold the signal objects + CSignalGrid *mEntrySignals[]; + CSignalGrid *mExitSignals[]; + ////CSignalBase *mEntrySignal; + ////CSignalBase *mExitSignal; + + double mTakeProfitValue; + double mStopLossValue; + GridTPSL *mTakeProfitObj; + GridTPSL *mStopLossObj; + + CTradeCustom Trade; + +private: + +protected: + + virtual bool LoopMain(bool newBar, bool firstTime); + +protected: + + int Init(int magicNumber, string tradeComment); + +public: + + // + // Constructors + // + CExpertBase() : CCommonBase() + { Init(0, ""); } + CExpertBase(string symbol, int timeframe, int magicNumber, string tradeComment) + : CCommonBase(symbol, timeframe) + { Init(magicNumber, tradeComment); } + CExpertBase(string symbol, ENUM_TIMEFRAMES timeframe, int magicNumber, string tradeComment) + : CCommonBase(symbol, timeframe) + { Init(magicNumber, tradeComment); } + CExpertBase(int magicNumber, string tradeComment) + : CCommonBase() + { Init(magicNumber, tradeComment); } + + // + // Destructors + // + ~CExpertBase(); + +public: // Default properties + + // + // Assign the default values to the expert + // + virtual void SetVolume(double volume) { mVolume = volume; } + + virtual void SetTakeProfitValue(int takeProfitPoints) + { mTakeProfitValue = PointsToDouble(takeProfitPoints); } + virtual void SetTakeProfitObj(CTPSLBase *takeProfitObj) + { mTakeProfitObj = takeProfitObj; } + + virtual void SetStopLossValue(int stopLossPoints) + { mStopLossValue = PointsToDouble(stopLossPoints); } + virtual void SetStopLossObj(CTPSLBase *stopLossObj) + { mStopLossObj = stopLossObj; } + + virtual void SetTradeComment(string comment) { mTradeComment = comment; } + virtual void SetMagic(int magicNumber) + { + mMagicNumber = magicNumber; + Trade.SetExpertMagicNumber(magicNumber); + } + + virtual void SetGridNumber(int gNumber) {GridNumber = gNumber;} + virtual void SetGridGap(int gGap) {mGridGap = gGap;} + virtual void SetResetGrid() {mResetGrid = true;} + virtual void SetSlippage(int slippage) {mSlippage = slippage;} + virtual void SetDefaultLotSize(double defaultLotSize) {mDefaultLotSize = defaultLotSize;} + virtual void SetMaxLotSize(double maxLotSize) {mMaxLotSize = maxLotSize;} + virtual void SetMinLotSize(double minLotSize) {mMinLotSize = minLotSize;} + virtual void SetMaxRiskPerTrade(double maxRiskPerTrade) {mMaxRiskPerTrade = maxRiskPerTrade;} + + + virtual void SetUseTradingSession(ENUM_TRADING_SESSION useTradingSession) {mUseTradingSession = useTradingSession;} + virtual void SetRiskDefaultSize(ENUM_RISK_DEFAULT_SIZE riskDefaultSize) { mRiskDefaultSize = riskDefaultSize;} + virtual void SetRiskBase(ENUM_RISK_BASE riskBase) {mRiskBase=riskBase;} + +public: // Setup + + ////Changed + virtual void AddEntrySignal(CSignalGrid *signal) { AddSignal(signal, mEntrySignals); } + virtual void AddExitSignal(CSignalGrid *signal) { AddSignal(signal, mExitSignals); } + virtual void AddSignal(CSignalGrid *signal, CSignalGrid* &signals[]); + virtual void LotSize(double SL); + virtual void TradeWatcher(); + virtual bool IsTradingTime(); + virtual bool CheckTradingSession(); + + virtual double getLastBuyOrderPrice() {return lastBuyOrderPrice;} + virtual double getLastSellOrderPrice() {return lastSellOrderPrice;} + virtual double getOpenedBuyPositionPrice() {return openedBuyPositionPrice;} + virtual double getOpenedSellPositionPrice() {return openedSellPositionPrice;} + + ////virtual void AddEntrySignal(CSignalBase *signal) { mEntrySignal=signal; } + ////virtual void AddExitSignal(CSignalBase *signal) { mExitSignal=signal; } + +public: // Event handlers + + virtual int OnInit(); + virtual void OnTick(); + virtual void OnTimer() { return; } + virtual double OnTester() { return(0.0); } + virtual void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) {}; + +#ifdef __MQL5__ + virtual void OnTrade() { return; } + virtual void OnTradeTransaction(const MqlTradeTransaction& trans, + const MqlTradeRequest& request, + const MqlTradeResult& result) + { return; } + virtual int OnTesterInit() { return(INIT_SUCCEEDED); } + virtual void OnTesterPass() { return; } + virtual void OnTesterDeinit() { return; } + virtual void OnBookEvent() { return; } +#endif + +public: // Functions + + virtual void GetMarketPrices(ENUM_ORDER_TYPE orderType, MqlTradeRequest &request); + ////New + virtual ENUM_OFX_SIGNAL_DIRECTION GetCurrentSignal(CSignalGrid* &signals[], + ENUM_OFX_SIGNAL_TYPE signalType); + + }; + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +CExpertBase::~CExpertBase() + { + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CExpertBase::OnInit() + { + + int i = 0; + for(i=ArraySize(mEntrySignals)-1; i>=0; i--) + { + if(mEntrySignals[i].InitResult()!=INIT_SUCCEEDED) + return(mEntrySignals[i].InitResult()); + } + for(i=ArraySize(mExitSignals)-1; i>=0; i--) + { + if(mExitSignals[i].InitResult()!=INIT_SUCCEEDED) + return(mExitSignals[i].InitResult()); + } + if(mTakeProfitObj!=NULL) + { + if(mTakeProfitObj.InitResult()!=INIT_SUCCEEDED) + return(mTakeProfitObj.InitResult()); + } + if(mStopLossObj!=NULL) + { + if(mStopLossObj.InitResult()!=INIT_SUCCEEDED) + return(mStopLossObj.InitResult()); + } + + return(INIT_SUCCEEDED); + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CExpertBase::Init(int magicNumber, string tradeComment) + { + + if(mInitResult!=INIT_SUCCEEDED) + return(mInitResult); + + mTradeComment = tradeComment; + SetMagic(magicNumber); + + mTakeProfitValue = 0.0; + mStopLossValue = 0.0; + + mLastBarTime = 0; + +////New + ArrayResize(mEntrySignals, 0); // Just make sure these are initialised + ArrayResize(mExitSignals, 0); + + return(INIT_SUCCEEDED); + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CExpertBase::OnTick(void) + { + + if(!TradeAllowed()) + return; + + mBarTime = iTime(mSymbol, mTimeframe, 0); + + bool firstTime = (mLastBarTime==0); + bool newBar = (mBarTime!=mLastBarTime); + + TradeWatcher(); +Print("signalDirection after TradeWatcher ", signalDirection); + if(LoopMain(newBar, firstTime)) + { + mLastBarTime = mBarTime; + } + + return; + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CExpertBase::LoopMain(bool newBar,bool firstTime) + { + +// +// To start I will only trade on a new bar +// and not on the first bar after start +// + /*if(!newBar) + return(true); + if(firstTime) + return(true);*/ + +// +// Update the signals +// +////Changed + ENUM_OFX_SIGNAL_DIRECTION entrySignal = GetCurrentSignal(mEntrySignals, OFX_ENTRY_SIGNAL); + ENUM_OFX_SIGNAL_DIRECTION exitSignal = GetCurrentSignal(mExitSignals, OFX_EXIT_SIGNAL); + /*if(mEntrySignals[0]!=NULL) + mEntrySignals[0].UpdateSignal(); + if(mEntrySignals[0]!=mExitSignals[0]) + { + if(mEntrySignals[0]!=NULL) + mEntrySignals[0].UpdateSignal(); + }*/ + +// +// Should any trades be closed +// +////Changed +/* + if(exitSignal==OFX_SIGNAL_BOTH) + { + Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY); + Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL); + } + else + if(exitSignal==OFX_SIGNAL_BUY) + { + Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY); + } + else + if(exitSignal==OFX_SIGNAL_SELL) + { + Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL); + } + if(exitSignal==OFX_SIGNAL_ALL) + { + Trade.PositionCloseAll(); + + Trade.OrderCloseAll(); + } +*/ +////if (mExitSignal!=NULL) { +//// if (mExitSignal.ExitSignal()==OFX_SIGNAL_BOTH) { +//// Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY); +//// Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL); +//// } else +//// if (mExitSignal.ExitSignal()==OFX_SIGNAL_BUY) { +//// Trade.PositionCloseByType(mSymbol, POSITION_TYPE_BUY); +//// } else +//// if (mExitSignal.ExitSignal()==OFX_SIGNAL_SELL) { +//// Trade.PositionCloseByType(mSymbol, POSITION_TYPE_SELL); +//// } +////} + +// +// Should a trade be opened +// + MqlTradeRequest request = {}; // Just initialising + + double buyPrice, sellPrice, SLPoints=0; + int GripPips = mGridGap; + double TakeProfitPoint = GripPips*_Point; + LotSize(GripPips); +////Changed + + Print("Entry signal for Both ", NAV_SIGNAL_BOTH, " Entry for OFX_SIGNAL_BUY ", NAV_SIGNAL_BUY, " Actual ", signalDirection); + Print("signalDirection ", signalDirection); + if(signalDirection==NAV_SIGNAL_BOTH) + { + double AskPrice = SymbolInfoDouble(Symbol(),SYMBOL_ASK); + double BidPrice = SymbolInfoDouble(Symbol(),SYMBOL_BID); + + Print("m Grid pip ", GripPips, " Point ", _Point, " TP point ", TakeProfitPoint); + buyPrice = AskPrice + TakeProfitPoint; + sellPrice = BidPrice - TakeProfitPoint; + + Print("m Grid pip ", GripPips, " Point ", _Point); + + Print(" Buy price ", buyPrice, " TP normalized ", NormalizeDouble(buyPrice + TakeProfitPoint, mDigits)); + //SLPoints=MathCeil(buyPrice-GripPips); + + //GetMarketPrices(ORDER_TYPE_SELL, request); + //Trade.Sell(mVolume, mSymbol, request.price, request.sl, request.tp); + GetMarketPrices(ORDER_TYPE_BUY, request); + request.tp = NormalizeDouble(request.price + TakeProfitPoint, mDigits); + Trade.Buy(mVolume, mSymbol, request.price, request.sl); + + GetMarketPrices(ORDER_TYPE_SELL_STOP, request); + request.price = sellPrice; + request.tp = NormalizeDouble(sellPrice - TakeProfitPoint, mDigits); + Trade.SellStop(mVolume, request.price, mSymbol, request.sl); + + } + else + if(signalDirection==NAV_SIGNAL_BUY) + { + //If there's a pending order, get the last order's price else get the position price + Print("Trying to open a buy"); + buyPrice = getLastBuyOrderPrice()?getLastBuyOrderPrice():getOpenedBuyPositionPrice(); + request.price = buyPrice+TakeProfitPoint; + request.sl = 0.0; + request.tp = NormalizeDouble(buyPrice + TakeProfitPoint, mDigits); + GetMarketPrices(ORDER_TYPE_BUY_STOP, request); + Trade.BuyStop(mVolume, request.price, mSymbol, request.sl); + + } + else + if(signalDirection==NAV_SIGNAL_SELL) + { + Print("Trying to open a sell"); + sellPrice = getLastSellOrderPrice()?getLastSellOrderPrice():getOpenedSellPositionPrice(); + request.price = sellPrice-TakeProfitPoint; + request.sl = 0.0; + request.tp = NormalizeDouble(sellPrice - TakeProfitPoint, mDigits); + GetMarketPrices(ORDER_TYPE_SELL_STOP, request); + Trade.SellStop(mVolume, request.price, mSymbol, request.sl); + + } + if(signalDirection==NAV_SIGNAL_ALL) + { + Trade.OrderCloseAll(); + Trade.PositionCloseAll(); + } +//// if (mEntrySignal!=NULL) { +//// if (mEntrySignal.EntrySignal()==OFX_SIGNAL_BOTH) { +//// +//// GetMarketPrices(ORDER_TYPE_BUY, request); +//// Trade.Buy(mVolume, mSymbol, request.price, request.sl, request.tp); +//// +//// GetMarketPrices(ORDER_TYPE_SELL, request); +//// Trade.Sell(mVolume, mSymbol, request.price, request.sl, request.tp); +//// +//// } else +//// if (mEntrySignal.EntrySignal()==OFX_SIGNAL_BUY) { +//// +//// GetMarketPrices(ORDER_TYPE_BUY, request); +//// Trade.Buy(mVolume, mSymbol, request.price, request.sl, request.tp); +//// +//// } else +//// if (mEntrySignal.EntrySignal()==OFX_SIGNAL_SELL) { +//// +//// GetMarketPrices(ORDER_TYPE_SELL, request); +//// Trade.Sell(mVolume, mSymbol, request.price, request.sl, request.tp); +//// +//// } +//// } + +//mEntrySignals[0].SetSignal(OFX_ENTRY_SIGNAL, OFX_SIGNAL_NONE); +//mEntrySignals[0].SetSignal(OFX_EXIT_SIGNAL, OFX_SIGNAL_NONE); + + return(true); + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CExpertBase::GetMarketPrices(ENUM_ORDER_TYPE orderType, MqlTradeRequest &request) + { + + double sl = (mStopLossObj==NULL) ? mStopLossValue : mStopLossObj.GetStopLoss(); + double tp = (mTakeProfitObj==NULL) ? mTakeProfitValue : mTakeProfitObj.GetTakeProfit(); + Trade.SetExpertMagicNumber(mMagicNumber); + if(orderType==ORDER_TYPE_BUY) + { + if(request.price==0.0) + request.price = SymbolInfoDouble(mSymbol, SYMBOL_ASK); + request.tp = (tp==0.0) ? 0.0 : NormalizeDouble(request.price+tp, mDigits); + request.sl = (sl==0.0) ? 0.0 : NormalizeDouble(request.price-sl, mDigits); + } + + if(orderType==ORDER_TYPE_SELL) + { + if(request.price==0.0) + request.price = SymbolInfoDouble(mSymbol, SYMBOL_BID); + request.tp = (tp==0.0) ? 0.0 : NormalizeDouble(request.price-tp, mDigits); + request.sl = (sl==0.0) ? 0.0 : NormalizeDouble(request.price+sl, mDigits); + } + + return; + + } + +////New +void CExpertBase::AddSignal(CSignalGrid *signal, CSignalGrid* &signals[]) + { + + int index = ArraySize(signals); + ArrayResize(signals, index+1); + signals[index] = signal; + + } + +////New +ENUM_OFX_SIGNAL_DIRECTION CExpertBase::GetCurrentSignal(CSignalGrid* &signals[], + ENUM_OFX_SIGNAL_TYPE signalType) + { + + ENUM_OFX_SIGNAL_DIRECTION result = OFX_SIGNAL_NONE; + ENUM_OFX_SIGNAL_DIRECTION r2 = OFX_SIGNAL_NONE; // Just working value + int index = ArraySize(signals); + + if(index<=0) + { + + return(result); + + } + else + { + + signals[0].UpdateSignal(); + result = signals[0].GetSignal(signalType); + + // I have chosen to update all signals in case there is some + // behavour that needs it. The penalty is some performance + // If performance is an issue just add an exit inside the loop + // as the commented line + for(int i = 1; i= result[0]) + { + londonSession + } + return; + }*/ + return true; + } + + + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CExpertBase::IsTradingTime(void) + { + bool result = false; + + if(mUseTradingSession) + result = true; + + return result; + } +//+------------------------------------------------------------------+ + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +void CExpertBase::LotSize(double SL=0) + { + +//Lot Size Calculator + +//If the position size is dynamic + if(mRiskDefaultSize==RISK_DEFAULT_AUTO) + { + //If the stop loss is not zero then calculate the lot size + Print("Stop loss ", SL); + if(SL!=0) + { + double RiskBaseAmount=0; + //TickValue is the value of the individual price increment for 1 lot of the instrument, expressed in the account currenty + double TickValue=SymbolInfoDouble(mSymbol,SYMBOL_TRADE_TICK_VALUE); + Print("Tick value ", TickValue); + //Define the base for the risk calculation depending on the parameter chosen + if(mRiskBase==RISK_BASE_BALANCE) + RiskBaseAmount=AccountInfoDouble(ACCOUNT_BALANCE); + if(mRiskBase==RISK_BASE_EQUITY) + RiskBaseAmount=AccountInfoDouble(ACCOUNT_EQUITY); + if(mRiskBase==RISK_BASE_FREEMARGIN) + RiskBaseAmount=AccountInfoDouble(ACCOUNT_FREEMARGIN); + + //Calculate the Position Size + mVolume=((RiskBaseAmount*mMaxRiskPerTrade/100)/(SL*TickValue)); + Print("Volume ", mVolume); + } + //If the stop loss is zero then the lot size is the default one + if(SL==0) + { + mVolume=mDefaultLotSize; + } + } +//Normalize the Lot Size to satisfy the allowed lot increment and minimum and maximum position size + mVolume=MathFloor(mVolume/SymbolInfoDouble(mSymbol,SYMBOL_VOLUME_STEP))*SymbolInfoDouble(mSymbol,SYMBOL_VOLUME_STEP); + +//Limit the lot size in case it is greater than the maximum allowed by the user + if(mVolume>mMaxLotSize) + mVolume=mMaxLotSize; +//Limit the lot size in case it is greater than the maximum allowed by the broker + if(mVolume>SymbolInfoDouble(mSymbol,SYMBOL_VOLUME_MAX)) + mVolume=SymbolInfoDouble(mSymbol,SYMBOL_VOLUME_MAX); + Print("Lot ", mVolume, " Max lot ", SymbolInfoDouble(mSymbol,SYMBOL_VOLUME_MAX)); +//If the lot size is too small then set it to 0 and don't trade + if(mVolume 0) + { + //Count the opened positions by type + int cntP = PositionsTotal(); + for(int i = cntP-1; i>=0; i--) + { + ticket = PositionGetTicket(i); + if(PositionSelectByTicket(ticket)) + { + if(PositionGetString(POSITION_SYMBOL)==mSymbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY + && PositionGetInteger(POSITION_MAGIC)==mMagicNumber) + { + openedBuyPositionPrice = PositionGetDouble(POSITION_PRICE_OPEN); + pCountBuy += 1; + } + + Print("POSITION_SYMBOL ", PositionGetString(POSITION_SYMBOL), " = ", mSymbol, " POSITION_TYPE ",PositionGetInteger(POSITION_TYPE), " = ", POSITION_TYPE_SELL, " Magic ", PositionGetInteger(POSITION_MAGIC), " = ",mMagicNumber); + if(PositionGetString(POSITION_SYMBOL)==mSymbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL + && PositionGetInteger(POSITION_MAGIC)==mMagicNumber) + { + openedSellPositionPrice = PositionGetDouble(POSITION_PRICE_OPEN); + pCountSell += 1; + } + } + else + { + Print(GetLastError()); + } + } + } +//Count the orders by type + + int cntO = OrdersTotal(); + Print("Total pending orders ", cntO); + for(int i = cntO-1; i>=0; i--) + { + ticket = OrderGetTicket(i); + if(OrderSelect(ticket)) + { + if(OrderGetString(ORDER_SYMBOL)==mSymbol && OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_BUY_STOP + && OrderGetInteger(ORDER_MAGIC)==mMagicNumber) + { + oCountBuy += 1; + lastBuyOrderPrice = OrderGetDouble(ORDER_PRICE_OPEN); + } + + Print("ORDER_SYMBOL ", OrderGetString(ORDER_SYMBOL), " Real symbol ", mSymbol, " ORDER_TYPE ", OrderGetInteger(ORDER_TYPE), " Real type ", ORDER_TYPE_SELL_STOP, " Magic ", OrderGetInteger(ORDER_MAGIC), " Real magic ", mMagicNumber); + if(OrderGetString(ORDER_SYMBOL)==mSymbol && OrderGetInteger(ORDER_TYPE)==ORDER_TYPE_SELL_STOP + && OrderGetInteger(ORDER_MAGIC)==mMagicNumber) + { + oCountSell += 1; + lastSellOrderPrice = OrderGetDouble(ORDER_PRICE_OPEN); + } + } + else + { + Print(GetLastError()); + } + } + Print("openedBuyPositionPrice ", openedBuyPositionPrice, " openedSellPositionPrice ", openedSellPositionPrice); + + Print("lastBuyOrderPrice ", lastBuyOrderPrice, " lastSellOrderPrice ", lastSellOrderPrice); + + double floatingProfitPercent = ((AccountInfoDouble(ACCOUNT_EQUITY) - AccountInfoDouble(ACCOUNT_BALANCE))*100)/AccountInfoDouble(ACCOUNT_BALANCE); +// Check if profit is at least the mMaxRiskPerTrade + + Print(" MaxRiskPerTrade ",mMaxRiskPerTrade, " Floating profit percent ", floatingProfitPercent, " Account equity ", AccountInfoDouble(ACCOUNT_EQUITY), " Account balance ", AccountInfoDouble(ACCOUNT_BALANCE)); + +//The number of buy pending order should be twice the opened sell positions; and vice versa + realOCountBuy = pCountSell+1; + realOCountSell = pCountBuy*2; + totalBuy = pCountBuy+oCountBuy; + totalSell = pCountSell+oCountSell; + realTotalBuy = pCountSell+1; + realTotalSell = pCountBuy+1; + + Print("Sell order (", oCountSell, ") Real (", realOCountSell, ")"); + Print("Buy order (", oCountBuy, ") Real (", realOCountBuy, ")", " Opened sell ", pCountSell); + + + Print("oCountSell ", oCountSell, " < ", " realOCountSell ", realOCountSell, " && ", " pCountBuy ", pCountBuy," > 0"); + + if(OrdersTotal() == 0 && PositionsTotal() == 0) + { + signalDirection = NAV_SIGNAL_BOTH; + } + else + { + //If there's only one pending order left, close it. + if(OrdersTotal() >= 1 && PositionsTotal() == 0) + { + signalDirection = NAV_SIGNAL_ALL; + Print("Exit if no opened position"); + } + else + { + //When there are multiple positions, check is the account is making enough profit + if(floatingProfitPercent > mMaxRiskPerTrade) + { + signalDirection = NAV_SIGNAL_ALL; + Print("Exit on profit target"); + } + else + { + Print("realTotalSell ", realTotalSell, " <= ", " totalSell ", totalSell ," && ", " pCountBuy ",pCountBuy ," > 0"); + if(realTotalSell > totalSell && pCountBuy > 0) + { + signalType = NAV_ENTRY_SIGNAL; + signalDirection = NAV_SIGNAL_SELL; + Print("Sell order (", oCountSell, ") is less than it should be (", realOCountSell, ")"); + } + else + { + if(realTotalBuy > totalBuy && pCountSell > 0) + { + signalType = NAV_ENTRY_SIGNAL; + signalDirection = NAV_SIGNAL_BUY; + //mEntrySignals[0].SetSignal(OFX_ENTRY_SIGNAL, OFX_SIGNAL_BUY); + Print("Buy order (", oCountBuy, ") is less than it should be (", realOCountBuy, ")"); + } + } + } + } + } + } +//+------------------------------------------------------------------+ diff --git a/Include/Nkanven/Frameworks/GridEA/Framework.mqh b/Include/Nkanven/Frameworks/GridEA/Framework.mqh new file mode 100644 index 0000000..9700329 --- /dev/null +++ b/Include/Nkanven/Frameworks/GridEA/Framework.mqh @@ -0,0 +1,35 @@ +/* + Framework_2.03.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + + +*/ + +// History +// 1.00 - First version, not well version controlled +// 2.00 - Changed framework structure, functionally same as 1.00 +// 2.01 - Added TP and SL +// 2.02 - Move compound signals into expertbase +// Templates now use common files between mq4 and mq5 +// MakeMQH batch script also recreates framework.mqh +// 2.03 - Added macros to CommonBase to standardise init checking +// Moved base classes up one level and removed unnecessary folders + +#ifndef _FRAMEWORK_VERSION_ + + #define _FRAMEWORK_VERSION_ "2.03" + + #include "CommonBase.mqh" + + #include "Trade/Trade.mqh" + + #include "SignalBase.mqh" + #include "TPSLBase.mqh" + + #include "ExpertBase.mqh" + + #include "../Extensions/AllGridExtensions.mqh" + +#endif diff --git a/Include/Nkanven/Frameworks/GridEA/IndicatorBase.mqh b/Include/Nkanven/Frameworks/GridEA/IndicatorBase.mqh new file mode 100644 index 0000000..b064a1c --- /dev/null +++ b/Include/Nkanven/Frameworks/GridEA/IndicatorBase.mqh @@ -0,0 +1,59 @@ +/* + IndicatorBase.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +#include "CommonBase.mqh" + +class CIndicatorBase : public CCommonBase { + +private: + +protected: // member variables + + // Only used for MQL5 + int mIndicatorHandle; + +public: // constructors + + CIndicatorBase() : CCommonBase() + { Init(); } + CIndicatorBase(string symbol, ENUM_TIMEFRAMES timeframe) + : CCommonBase(symbol, timeframe) + { Init(); } + ~CIndicatorBase(); + + int Init(); + +public: + + virtual double GetData(const int index) { return(GetData(0,index)); } + virtual double GetData(const int bufferNum, const int index){ return (0); } + +}; + +CIndicatorBase::~CIndicatorBase() { + +#ifdef __MQL5__ + + if (mIndicatorHandle!=INVALID_HANDLE) IndicatorRelease(mIndicatorHandle); + +#endif + +} + +int CIndicatorBase::Init() { + + if (InitResult()!=INIT_SUCCEEDED) return(InitResult()); + + mIndicatorHandle = INVALID_HANDLE; + + return(INIT_SUCCEEDED); + +} + + + diff --git a/Include/Nkanven/Frameworks/GridEA/SignalBase.mqh b/Include/Nkanven/Frameworks/GridEA/SignalBase.mqh new file mode 100644 index 0000000..1e35527 --- /dev/null +++ b/Include/Nkanven/Frameworks/GridEA/SignalBase.mqh @@ -0,0 +1,95 @@ +/* + SignalBase.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +#include "CommonBase.mqh" +//#include "IndicatorBase.mqh" + +//// New +//// This is to maintain compatibility and allow sub classes to still +//// use mEntrySignal= or mExitSignal= +//// mEntrySignal and mExitSignal are effectively deprecated now +#define mEntrySignal mSignalValues[OFX_ENTRY_SIGNAL] // Deprecated +#define mExitSignal mSignalValues[OFX_EXIT_SIGNAL] // Deprecated + + +//// New +enum ENUM_OFX_SIGNAL_TYPE + { + OFX_ENTRY_SIGNAL, + OFX_EXIT_SIGNAL + }; + +enum ENUM_OFX_SIGNAL_DIRECTION + { + OFX_SIGNAL_NONE = 0, + OFX_SIGNAL_BUY = 1, + OFX_SIGNAL_SELL = 2, + OFX_SIGNAL_BOTH = 3, + OFX_SIGNAL_ALL = 4 + }; + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +class CSignalBase : public CCommonBase + { + +private: + +protected: // member variables + + //// Replaced + ENUM_OFX_SIGNAL_DIRECTION mSignalValues[2]; + double mMaxRiskPerTrade; + ////ENUM_OFX_SIGNAL_DIRECTION mEntrySignal; + ////ENUM_OFX_SIGNAL_DIRECTION mExitSignal; + +public: // constructors + + CSignalBase() : CCommonBase() + { Init(); } + CSignalBase(string symbol, ENUM_TIMEFRAMES timeframe) : CCommonBase(symbol, timeframe) + { Init(); } + ~CSignalBase() { } + + int Init(); + +public: + + virtual void UpdateSignal() { return; } + //// Changed - maintain backward compatibility + virtual ENUM_OFX_SIGNAL_DIRECTION EntrySignal() { return(mSignalValues[OFX_ENTRY_SIGNAL]); } + virtual ENUM_OFX_SIGNAL_DIRECTION ExitSignal() { return(mSignalValues[OFX_EXIT_SIGNAL]); } + //// New, and shows my lack of planning + virtual void SetSignal(ENUM_OFX_SIGNAL_TYPE type, + ENUM_OFX_SIGNAL_DIRECTION value) + { mSignalValues[type] = value; } + virtual void SetMaxRiskPerTrade(double maxRiskPerTrade) { mMaxRiskPerTrade = maxRiskPerTrade;} + + virtual ENUM_OFX_SIGNAL_DIRECTION GetSignal(ENUM_OFX_SIGNAL_TYPE type) + { return(mSignalValues[type]); } + + }; + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +int CSignalBase::Init() + { + + if(InitResult()!=INIT_SUCCEEDED) + return(InitResult()); + +//// Replaced + ArrayInitialize(mSignalValues, OFX_SIGNAL_NONE); +////mEntrySignal = OFX_SIGNAL_NONE; +////mExitSignal = OFX_SIGNAL_NONE; + + return(INIT_SUCCEEDED); + + } diff --git a/Include/Nkanven/Frameworks/GridEA/TPSLBase.mqh b/Include/Nkanven/Frameworks/GridEA/TPSLBase.mqh new file mode 100644 index 0000000..8f81776 --- /dev/null +++ b/Include/Nkanven/Frameworks/GridEA/TPSLBase.mqh @@ -0,0 +1,39 @@ +/* + TPSLBase.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +#include "Signalbase.mqh" + +class CTPSLBase : public CSignalBase { + +private: + +public: // constructors + + CTPSLBase() : CSignalBase() { Init(); } + CTPSLBase(string symbol, ENUM_TIMEFRAMES timeframe) : CSignalBase(symbol, timeframe) { Init(); } + ~CTPSLBase() { } + + int Init(); + +public: + + virtual double GetTakeProfit() { return(0.0); } + virtual double GetStopLoss() { return(0.0); } + +}; + +int CTPSLBase::Init() { + + if (InitResult()!=INIT_SUCCEEDED) return(InitResult()); + + return(INIT_SUCCEEDED); + +} + + + diff --git a/Include/Nkanven/Frameworks/GridEA/Trade/Trade.mqh b/Include/Nkanven/Frameworks/GridEA/Trade/Trade.mqh new file mode 100644 index 0000000..6323929 --- /dev/null +++ b/Include/Nkanven/Frameworks/GridEA/Trade/Trade.mqh @@ -0,0 +1,16 @@ +/* + Trade.mqh + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + + +#ifdef __MQL4__ + #include "Trade_mql4.mqh" +#endif +#ifdef __MQL5__ + #include "Trade_mql5.mqh" +#endif + diff --git a/Include/Nkanven/Frameworks/GridEA/Trade/Trade_mql4.mqh b/Include/Nkanven/Frameworks/GridEA/Trade/Trade_mql4.mqh new file mode 100644 index 0000000..c7c9bb8 --- /dev/null +++ b/Include/Nkanven/Frameworks/GridEA/Trade/Trade_mql4.mqh @@ -0,0 +1,123 @@ +/* + Trade.mqh + (For MQL4) + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +#include "..\CommonBase.mqh" + +struct MqlTradeRequest { + int action; // Trade operation type (as int here) + ulong magic; // Expert Advisor ID (magic number) + ulong order; // Order ticket + string symbol; // Trade symbol + double volume; // Requested volume for a deal in lots + double price; // Price + double stoplimit; // StopLimit level of the order + double sl; // Stop Loss level of the order + double tp; // Take Profit level of the order + ulong deviation; // Maximal possible deviation from the requested price + ENUM_ORDER_TYPE type; // Order type + int type_filling; // Order execution type (int here) + int type_time; // Order expiration type (int here) + datetime expiration; // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type) + string comment; // Order comment + ulong position; // Position ticket + ulong position_by; // The ticket of an opposite position +}; + +enum ENUM_POSITION_TYPE { + POSITION_TYPE_BUY = ORDER_TYPE_BUY, + POSITION_TYPE_SELL = ORDER_TYPE_SELL +}; + +class CTradeCustom : public CCommonBase { + +private: + +protected: // member variables + + int mMagic; // expert magic number + +public: // constructors + + CTradeCustom(); + ~CTradeCustom(); + +public: + + ulong RequestMagic() { return(mMagic); } + void SetExpertMagicNumber(const int magic) { mMagic=magic; } + + double BuyPrice(string symbol) { return(SymbolInfoDouble(symbol, SYMBOL_ASK)); } + double SellPrice(string symbol) { return(SymbolInfoDouble(symbol, SYMBOL_BID)); } + + bool Buy(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment=""); + bool Sell(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment=""); + + bool PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType,const int deviation=ULONG_MAX); + ////New + void PositionCountByType(const string symbol, int &count[]); + +}; + +CTradeCustom::CTradeCustom() { + + mMagic = 0; + +} + +CTradeCustom::~CTradeCustom() { + +} + +bool CTradeCustom::Buy(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment="") { + if (price==0.0) price = BuyPrice(symbol); + int ticket = OrderSend(symbol, ORDER_TYPE_BUY, volume, price, 0, sl, tp, comment, mMagic); + return(ticket>0); +} + +bool CTradeCustom::Sell(const double volume,const string symbol=NULL,double price=0.0,const double sl=0.0,const double tp=0.0,const string comment="") { + if (price==0.0) price = SellPrice(symbol); + int ticket = OrderSend(symbol, ORDER_TYPE_SELL, volume, price, 0, sl, tp, comment, mMagic); + return(ticket>0); +} + +bool CTradeCustom::PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType, const int deviation=ULONG_MAX) { + + int slippage = (deviation==ULONG_MAX) ? 0 : deviation; + + bool result = true; + int cnt = OrdersTotal(); + for (int i = cnt-1; i>=0; i--) { + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + if (OrderSymbol()==symbol && OrderMagicNumber()==mMagic && OrderType()==positionType) { + result &= OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slippage); + } + } + } + + return(result); + +} + +////New +void CTradeCustom::PositionCountByType(const string symbol, int &count[]) { + + ArrayResize(count, 6); + ArrayInitialize(count, 0); + int cnt = OrdersTotal(); + for (int i = cnt-1; i>=0; i--) { + if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { + if (OrderSymbol()==symbol && OrderMagicNumber()==mMagic) { + count[(int)OrderType()]++; + } + } + } + + return; + +} diff --git a/Include/Nkanven/Frameworks/GridEA/Trade/Trade_mql5.mqh b/Include/Nkanven/Frameworks/GridEA/Trade/Trade_mql5.mqh new file mode 100644 index 0000000..cfc0ed1 --- /dev/null +++ b/Include/Nkanven/Frameworks/GridEA/Trade/Trade_mql5.mqh @@ -0,0 +1,152 @@ +/* + Trade.mqh + (For MQL5) + + Copyright 2013-2020, Orchard Forex + https://www.orchardforex.com + +*/ + +#include + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +class CTradeCustom : public CTrade + { + +private: + +protected: // member variables + +public: // constructors + +public: + + bool PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType,const ulong deviation=ULONG_MAX); + bool PositionCloseByTicket(const ulong ticket,const ulong deviation=ULONG_MAX); + bool PositionCloseAll(const ulong deviation=ULONG_MAX); + bool OrderCloseAll(); + + ////New + void PositionCountByType(const string symbol, int &count[]); +}; +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CTradeCustom::PositionCloseByType(const string symbol, ENUM_POSITION_TYPE positionType, const ulong deviation=ULONG_MAX) + { + + bool result = true; + int cnt = PositionsTotal(); + for(int i = cnt-1; i>=0; i--) + { + ulong ticket = PositionGetTicket(i); + if(PositionSelectByTicket(ticket)) + { + if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==positionType && PositionGetInteger(POSITION_MAGIC)==m_magic) + { + result &= PositionClose(ticket, deviation); + } + } + else + { + m_result.retcode=TRADE_RETCODE_REJECT; + result = false; + } + } + + return(result); + + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CTradeCustom::PositionCloseByTicket(const ulong ticket,const ulong deviation=-1) + { + bool result = true; + if(PositionSelectByTicket(ticket)) + { + if(PositionGetInteger(POSITION_MAGIC)==m_magic) + { + result &= PositionClose(ticket, deviation); + } + } + else + { + m_result.retcode=TRADE_RETCODE_REJECT; + result = false; + } + return(result); + } + +//+------------------------------------------------------------------+ +//| | +//+------------------------------------------------------------------+ +bool CTradeCustom::PositionCloseAll(const ulong deviation=-1) + { + bool result = true; + int cnt = PositionsTotal(); + for(int i = cnt-1; i>=0; i--) + { + ulong ticket = PositionGetTicket(i); + if(PositionSelectByTicket(ticket)) + { + + result &= PositionClose(ticket, deviation); + } + else + { + m_result.retcode=TRADE_RETCODE_REJECT; + result = false; + } + } + + return(result); + } + +bool CTradeCustom::OrderCloseAll(){ +bool result = true; + int cnt = OrdersTotal(); + for(int i = cnt-1; i>=0; i--) + { + ulong ticket = OrderGetTicket(i); + if(OrderSelect(ticket)) + { + + result &= OrderDelete(ticket); + } + else + { + m_result.retcode=TRADE_RETCODE_REJECT; + result = false; + } + } + + return(result); +} +////New +void CTradeCustom::PositionCountByType(const string symbol, int &count[]) + { + + ArrayResize(count, 6); + ArrayInitialize(count, 0); + + int cnt = PositionsTotal(); + for(int i = cnt-1; i>=0; i--) + { + ulong ticket = PositionGetTicket(i); + if(PositionSelectByTicket(ticket)) + { + if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_MAGIC)==m_magic) + { + count[(int)PositionGetInteger(POSITION_TYPE)]++; + } + } + } + + return; + + } +//+------------------------------------------------------------------+ diff --git a/Include/Nkanven/Frameworks/GridEA/Updates.txt b/Include/Nkanven/Frameworks/GridEA/Updates.txt new file mode 100644 index 0000000..281bf10 --- /dev/null +++ b/Include/Nkanven/Frameworks/GridEA/Updates.txt @@ -0,0 +1,7 @@ +Version 2.03 + +Added macros to CommonBase to standardise init checking + +Moved base classes up one level and removed unnecessary folders + +Updated framework number \ No newline at end of file diff --git a/Include/Nkanven/Frameworks/GridFramework.mqh b/Include/Nkanven/Frameworks/GridFramework.mqh new file mode 100644 index 0000000..e565f78 --- /dev/null +++ b/Include/Nkanven/Frameworks/GridFramework.mqh @@ -0,0 +1,20 @@ +//+------------------------------------------------------------------+ +//| GridFramework.mqh | +//| Copyright 2021, Nkondog Anselme Venceslas | +//| https://www.mql5.com | +//+------------------------------------------------------------------+ +#property copyright "Copyright 2021, Nkondog Anselme Venceslas" +#property link "https://www.mql5.com" + +// +// The only purpose of this mqh file is to provide a single +// point to change the current framework version +// +// If you place an include to this file in your code you +// will get the version framework defined in this file +// unless your code has already included another +// framework file + +#ifndef _FRAMEWORK_VERSION_ + #include "GridEA/Framework.mqh" +#endif diff --git a/Include/Nkanven/Frameworks/MakeExtensionMQH.bat b/Include/Nkanven/Frameworks/MakeExtensionMQH.bat new file mode 100644 index 0000000..1c9be58 --- /dev/null +++ b/Include/Nkanven/Frameworks/MakeExtensionMQH.bat @@ -0,0 +1,114 @@ +@echo off + +: +: Get the current date and time in a format to show in the files +: +for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set ldt=%%j +set ldt=%ldt:~0,4%-%ldt:~4,2%-%ldt:~6,2% %ldt:~8,2%:%ldt:~10,2%:%ldt:~12,2% + +: +: Make sure there is an Extensions folder here +: +if not exist Extensions\ goto :quit + +: +: Move into the extensions folder to start +: +cd Extensions + +: +: Remove any existing mqh files +: +del *.mqh + +: +: Step through the directories here and build up mqh files for each +: +for /D %%f in (*) do ( + call :makemqh %%f +) + +: +: Build the AllExtensions file +: +call :makemqh . + +: +: Move back up to the frameworks folder +: +cd .. + +: +: Step through the framework files and build up the new framework.mqh +: +set framework_version= +for /f "tokens=*" %%f in ('dir /b /a:d /o:n "Framework_*"') do ( + set framework_version=%%f +) +call :makeframework1 %framework_version% + + +goto :quit + +:makeframework1 + +set file=Framework.mqh + +echo /* > %file% +echo Framework.mqh >> %file% +echo. >> %file% +echo Copyright 2013-2020, Orchard Forex >> %file% +echo https://www.orchardforex.com >> %file% +echo. >> %file% +echo. >> %file% +echo */ >> %file% +echo. >> %file% +echo // >> %file% +echo // The only purpose of this mqh file is to provide a single >> %file% +echo // point to change the current framework version >> %file% +echo // >> %file% +echo // If you place an include to this file in your code you >> %file% +echo // will get the version framework defined in this file >> %file% +echo // unless your code has already included another >> %file% +echo // framework file >> %file% +echo. >> %file% +echo #ifndef _FRAMEWORK_VERSION_ >> %file% +echo #include "%1/Framework.mqh" >> %file% +echo #endif >> %file% + +goto :eof + +:makemqh + +set mcurrent=%cd% +set mpath1=%~f1 +for %%f in ("%mpath1%") do set mpath=%%~nxf +set msub=%mpath%/ +if "%mcurrent%"=="%mpath1%" set msub= +set mfile=All%mpath%.mqh + +echo /* > %mfile% +echo All%mn2%.mqh >> %mfile% +echo. >> %mfile% +echo Copyright 2013-2020, Orchard Forex >> %mfile% +echo https://www.orchardforex.com >> %mfile% +echo. >> %mfile% +echo Auto Generated at %ldt% >> %mfile% +echo. >> %mfile% +echo */ >> %mfile% +echo. >> %mfile% +echo // >> %mfile% +echo // Extension %mn2% go here >> %mfile% +echo // >> %mfile% + +for %%f in (%1\*.mqh) do ( + if not "%%~nxf"=="%mfile%" echo #include "%msub%%%~nxf" >> %mfile% +) +echo Built include file %mfile% + +goto :eof + +:quit +echo Finished +pause +goto :eof \ No newline at end of file