Author: Roberto Jacobs (3rjfx)
Master our Multi-Currency Expert Advisor MT5. Learn how our MA Crossover and Price Typical Percent Range (PTPR) strategy automates Forex trading for consistent results.
- Introduction
- 1. The Strategic Foundation: MA Crossover and Multi-Pair Dynamics
- 2. Comprehensive Input Properties: Tailoring the Engine to Our Needs
- 3. Multi-Currency Array Management and Symbol Handling
- 4. The Signal Generation Matrix: Deconstructing GetOpenPosition
- 5. Intelligent Exit Strategies: GetCloseInWeakSignal and PartialCloseOrder
- 6. Advanced Risk Management and Trade Execution Protocols
- Frequently Asked Questions (FAQ)
- Conclusion
Introduction
Welcome back to Forex Home Expert, our dedicated hub for advanced trading education and sophisticated market solutions. Today, we are thrilled to present a deep, comprehensive technical and strategic breakdown of one of our most robust algorithmic creations: the Exp_MAxx5_MCEA.mq5.
As the lead developer and architect behind this system, we have designed this tool from the ground up to address the most significant limitations faced by retail traders in the modern financial markets. When we trade manually, or even when we rely on simplistic, single-pair automated systems, we are inherently constrained by time, attention, and emotional fatigue.
The market, however, operates continuously across dozens of currency pairs and global sessions. To truly capitalize on Automated Forex Trading, we must deploy systems capable of monitoring, analyzing, and executing trades across a broad spectrum of opportunities simultaneously.
This is the foundational philosophy behind our Multi-currency Expert Advisor. In this extensive article, we will dissect the core mechanics of this system, explaining not just what the code does, but why we built it that way. We will explore the intricate synergy between classic Moving Average Indicators and our proprietary Price Typical Percent Range (PTPR) logic, forming a highly refined Moving Average Crossover strategy.
Whether you are a seasoned MQL5 programmer looking to understand advanced architecture, or a trader seeking to comprehend the inner workings of the Expert Advisor MT5 you trust with your capital, this guide is meticulously crafted for you.
We invite you to join us on this deep dive into the engine room of professional-grade Algorithmic Trading, where precision, risk management, and multi-asset diversification converge to create a formidable edge in the Forex market.
1. The Strategic Foundation: MA Crossover and Multi-Pair Dynamics
Before we delve into the specific lines of code, we must first establish the strategic bedrock upon which the Exp_MAxx5_MCEA.mq5 is built. The concept of a Moving Average Crossover is a timeless staple in technical analysis, revered for its ability to filter out market noise and identify the underlying directional momentum of an asset.
However, a naive implementation of a simple moving average cross is notoriously prone to whipsaws, especially in ranging or choppy market conditions. Recognizing this inherent vulnerability, we engineered a more sophisticated, multi-layered confirmation system.
Our EA does not merely look for two lines crossing; it evaluates the velocity of the price movement, the alignment of the trend across multiple timeframes, and the statistical probability of the current price action relative to its recent historical range.
This is where our custom PTPR (Price Typical Percent Range) calculation comes into play, acting as a dynamic volatility and momentum filter that works in tandem with an Exponential Moving Average (EMA). By requiring confluence between the PTPR trend, the EMA alignment, and the raw directional momentum of the candlestick itself, we drastically reduce the frequency of false signals.
Furthermore, the true power of this strategy is unlocked only when applied through Multi-Pair Trading.
A single currency pair might be trapped in a prolonged, untradeable consolidation phase, but across a basket of thirty different Forex and Metal pairs, high-probability setups are constantly emerging.
By automating this multi-asset surveillance, we ensure that our capital is always deployed where the market is offering the clearest, most statistically favorable Forex trading strategies, rather than forcing trades in stagnant environments.
This holistic approach transforms a basic indicator concept into a robust, institutional-grade Algorithmic Trading solution.
2. Comprehensive Input Properties: Tailoring the Engine to Our Needs
//+------------------------------------------------------------------+
//| Exp_MAxx5_MCEA.mq5 |
//| Copyright 2026, Roberto Jacobs (3rjfx) ~ Date: 2026-08-12 |
//| https://www.mql5.com/en/users/3rjfx |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Roberto Jacobs (3rjfx) ~ Date: 2026-08-12"
#property link "https://www.mql5.com/en/users/3rjfx"
#property version "1.00"
#property strict
#property description "The Expert Exp_MAxx5_MCEA is the Automated Trading Multi Currency Forex Expert Advisor for MetaTrader 5"
#property description "by calculation of price movement percentage in Multi Timeframes and trade Multiple Pairs (30) in one Chart."
#property description "version: 1.00 ~ Update number: 1 ~ Last update: 2026/08/14 @ 12:08 (PM) WIT (Western Indonesian Time)"
//#property icon "\\Images\\Exp_MAxx5_MCEA.ico";
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Indicators\Indicator.mqh>
#include <MovingAverages.mqh>
//--
CTrade mc_trade;
CSymbolInfo mc_symbol;
CPositionInfo mc_position;
CAccountInfo mc_account;
CIndicator mc_indicator;
//---
//--
enum tm_zone
{
Cus_Session, // Trading on Custom Session
New_Zealand, // Trading on New Zealand Session
Australia, // Trading on Autralia Sydney Session
Asia_Tokyo, // Trading on Asia Tokyo Session
Europe_London, // Trading on Europe London Session
US_New_York // Trading on US New York Session
};
//--
enum swhour
{
hr_00=0, // 00:00
hr_01=1, // 01:00
hr_02=2, // 02:00
hr_03=3, // 03:00
hr_04=4, // 04:00
hr_05=5, // 05:00
hr_06=6, // 06:00
hr_07=7, // 07:00
hr_08=8, // 08:00
hr_09=9, // 09:00
hr_10=10, // 10:00
hr_11=11, // 11:00
hr_12=12, // 12:00
hr_13=13, // 13:00
hr_14=14, // 14:00
hr_15=15, // 15:00
hr_16=16, // 16:00
hr_17=17, // 17:00
hr_18=18, // 18:00
hr_19=19, // 19:00
hr_20=20, // 20:00
hr_21=21, // 21:00
hr_22=22, // 22:00
hr_23=23 // 23:00
};
//--
enum inmnt
{
mn_00=0, // Minute 0
mn_05=5, // Minute 5
mn_10=10, // Minute 10
mn_15=15, // Minute 15
mn_20=20, // Minute 20
mn_25=25, // Minute 25
mn_30=30, // Minute 30
mn_35=35, // Minute 35
mn_40=40, // Minute 40
mn_45=45, // Minute 45
mn_50=50, // Minute 50
mn_55=55 // Minute 55
};
//--
enum PairsTrade
{
All30, // All Forex 30 Pairs
TrdWi, // Trader Wishes Pairs
Usds, // Forex USD Pairs
Eurs, // Forex EUR Pairs
Gbps, // Forex GBP Pairs
Auds, // Forex AUD Pairs
Nzds, // Forex NZD Pairs
Cads, // Forex CDD Pairs
Chfs, // Forex CHF Pairs
Jpys, // Forex JPY Pairs
Metal // Metal Pairs
};
//--
enum YN
{
No,
Yes
};
//--
enum mmt
{
FixedLot, // Fixed Lot Size
DynamLot // Dynamic Lot Size
};
//--
enum TFUSE
{
TFM15, // PERIOD_M15
TFM30, // PERIOD_M30
TFH1, // PERIOD_H1
TFH2, // PERIOD_H2
TFH3, // PERIOD_H3
TFH4, // PERIOD_H4
TFH6, // PERIOD_H6
TFH8, // PERIOD_H8
TFH12, // PERIOD_H12
TFD1 // PERIOD_D1
};
//--
enum TrType
{
byprice, // Trailing Stop by Price
byindi, // Trailing Stop by Indicator
byHiLo // Trailing Stop in HIGH or LOW bar
};
//--
enum MS
{
SP, // Single Pair
MP // Multi Pairs
};
//--
enum SignalX
{
AD, // Aligned with the Direction
CD // Change of Direction
};
//--
//---
input group "=== Global Strategy EA Parameter ==="; // Global Strategy EA Parameter
input TFUSE tfinuse = TFH4; // Select Expert TimeFrame, default PERIOD_H4
input SignalX siguse = AD; // Select the Signal to be Used
//---
input group "=== Select Pairs to Trade ==="; // Selected Pairs to trading
input MS trademode = MP; // Select Trading Pairs Mode (Multi or Single)
input PairsTrade usepairs = All30; // Select Pairs to Use
input string traderwishes = "eg. eurusd,usdchf"; // If Use Trader Wishes Pairs, input pair name here, separate by comma
//--
input group "=== Money Management Lot Size Parameter ==="; // Money Management Lot Size Parameter
input mmt mmlot = DynamLot; // Money Management Type
input double Risk = 5.0; // Percent Equity Risk per Trade (Min=1.0% / Max=10.0%)
input double Lots = 0.01; // Input Manual Lot Size FixedLot
input double maxmrgn = 80.0; // Input Maximum Free Margin from Equity to Trade (in Percent)
//--Trade on Specific Time
input group "=== Trade on Specific Time ==="; // Trade on Specific Time
input YN trd_time_zone = Yes; // Select If You Like to Trade on Specific Time Zone
input tm_zone session = Cus_Session; // Select Trading Time Zone
input swhour stsescuh = hr_00; // Time Hour to Start Trading Custom Session (0-23)
input inmnt stsescum = mn_15; // Time Minute to Start Trading Custom Session (0-55)
input swhour clsescuh = hr_23; // Time Hour to Stop Trading Custom Session (0-23)
input inmnt clsescum = mn_55; // Time Minute to Stop Trading Custom Session (0-55)
//--Day Trading On/Off
input group "=== Day Trading On/Off ==="; // Day Trading On/Off
input YN ttd0 = No; // Select Trading on Sunday (Yes) or (No)
input YN ttd1 = Yes; // Select Trading on Monday (Yes) or (No)
input YN ttd2 = Yes; // Select Trading on Tuesday (Yes) or (No)
input YN ttd3 = Yes; // Select Trading on Wednesday (Yes) or (No)
input YN ttd4 = Yes; // Select Trading on Thursday (Yes) or (No)
input YN ttd5 = Yes; // Select Trading on Friday (Yes) or (No)
input YN ttd6 = No; // Select Trading on Saturday (Yes) or (No)
//--Trade & Order management Parameter
input group "=== Trade & Order management Parameter ==="; // Trade & Order management Parameter
input YN use_sl = No; // Use Order Stop Loss (Yes) or (No)
input YN autosl = Yes; // Use Automatic Calculation Stop Loss (Yes) or (No)
input double SLval = 30.0; // If Not Use Automatic SL - Input SL value in Pips
input YN use_tp = Yes; // Use Order Take Profit (Yes) or (No)
input YN autotp = Yes; // Use Automatic Calculation Take Profit (Yes) or (No)
input double TPval = 60.0; // If Not Use Automatic TP - Input TP value in Pips
input YN PartialClose = Yes; // Use Partial Close Profit (Yes) or (No)
input double profitinpips = 15.0; // Input Profit in Pips for Partial Close, default 10 Pips
input double percentlots = 50.0; // Percentage Lot Size to Partial Close
input YN TrailingSL = Yes; // Use Trailing Stop Loss (Yes) or (No)
input TrType trlby = byindi; // Select Trailing Stop Type
input double TSval = 10.0; // If Use Trailing Stop by Price Input value in Pips
input double TSmin = 5.0; // Minimum Pips to start Trailing Stop
input YN TrailingTP = Yes; // Use Trailing Take Profit (Yes) or (No)
input double TPmin = 25.0; // Input Trailing Profit Value in Pips
input YN Close_by_Opps = Yes; // Close Trade By Opposite Signal (Yes) or (No)
input YN SaveOnRev = No; // Close Trade and Save profit due to weak signal (Yes) or (No)
input YN CheckVSLTP = No; // Check Virtual SL/TP & Close Loss Trade (Yes) or (No)
//--Others Expert Advisor Parameter
input group "=== Others Expert Advisor Parameter ==="; // Others EA Parameter
input YN alerts = Yes; // Display Alerts / Messages (Yes) or (No)
input YN UseEmailAlert = No; // Email Alert (Yes) or (No)
input YN UseSendnotify = No; // Send Notification (Yes) or (No)
input YN trade_info_display = Yes; // Select Display Trading Info on Chart (Yes) or (No)
input ulong magicEA = 20260812; // Expert ID (Magic Number)
//---
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
A truly professional Expert Advisor MT5 must be highly adaptable, allowing us to fine-tune its behavior to match our specific risk tolerance, broker conditions, and trading preferences.
The Exp_MAxx5_MCEA.mq5 features an extensive, meticulously organized set of input properties, divided into logical groups for ease of use.
The "Global Strategy EA Parameter" group allows us to select the primary timeframe for calculations (defaulting to H4 for stability) and choose the signal logic: "AD" (Aligned with the Direction) for trend-following, or "CD" (Change of Direction) for catching early reversals.
The "Select Pairs to Trade" section is where the Multi-currency Expert Advisor truly shines.
We can choose to trade all 30 predefined pairs, focus on specific currency baskets (like USD, EUR, GBP, AUD, NZD, CAD, CHF, JPY, or Metals), or input a custom list of "Trader Wishes" pairs, separated by commas. This flexibility is paramount for effective Multi-Pair Trading.
In the "Money Management Lot Size Parameter" group, we have implemented a crucial choice between "FixedLot" and "DynamLot". When DynamLot is selected, the EA calculates the position size based on a percentage of our free equity and account leverage, ensuring that our risk scales proportionally with our account growth while strictly adhering to our predefined risk percentage (e.g., 5.0%).
The "Trade on Specific Time" and "Day Trading On/Off" sections provide granular control over when the EA is permitted to execute trades. We can restrict trading to specific global sessions (New Zealand, Sydney, Tokyo, London, New York) or a custom time window, and we can individually toggle trading on or off for each day of the week.
This is vital for avoiding low-liquidity periods or days with historically unfavorable volatility.
Finally, the "Trade & Order management Parameter" group houses our advanced risk controls, including options for automatic or manual Stop Loss and Take Profit values, Partial Close functionality, and three distinct types of Trailing Stops (by Price, by Indicator, or by High/Low bar).
This level of customization ensures that the Automated Forex Trading experience is perfectly aligned with our personal trading philosophy.
3. Multi-Currency Array Management and Symbol Handling
One of the most complex challenges in developing a Multi-currency Expert Advisor is ensuring that the system can seamlessly interact with the diverse naming conventions of different Forex brokers.
A currency pair known as "EURUSD" on one broker might be prefixed or suffixed on another (e.g., "EURUSDpro" or "EURUSD.m").
If the EA cannot dynamically resolve these naming discrepancies, it will fail to execute trades or, worse, attempt to trade invalid symbols.
To solve this, we implemented a robust symbol handling architecture, primarily governed by the HandlingSymbolArrays() and SetSymbolNamePS() functions.
When the EA initializes, it first populates internal arrays with the standard 30 pairs we intend to monitor.
The SetSymbolNamePS() function then meticulously analyzes the chart symbol on which the EA is currently attached.
It searches for known currency codes (EUR, GBP, AUD, NZD, USD, CAD, CHF) and isolates the core six-character pair name.
By comparing the length and composition of the chart symbol to this core name, the function dynamically detects and extracts any prefix or suffix characters.
Once identified, the HandlingSymbolArrays() function iterates through all predefined pair arrays (USDs, EURs, GBP pairs, etc.) and programmatically prepends and appends the detected prefix and suffix to every single symbol.
This ensures that when the EA calls SymbolSelect() or requests market data, it is always using the exact, broker-specific symbol name.
Furthermore, this function dynamically resizes the internal trading arrays based on the user's "PairsTrade" selection. If we choose to trade only "EUR Pairs", the array is resized to hold only those specific instruments, optimizing memory usage and processing speed.
This elegant, automated symbol resolution is the invisible backbone that makes reliable, large-scale Multi-Pair Trading possible without requiring manual code edits for every new broker we encounter.
void MCEA::HandlingSymbolArrays(void)
{
//---
string All30[]={"EURUSD","GBPUSD","AUDUSD","NZDUSD","USDCAD","USDCHF","USDJPY","EURGBP",
"EURAUD","EURNZD","EURCAD","EURCHF","EURJPY","GBPAUD","GBPNZD","GBPCAD",
"GBPCHF","GBPJPY","AUDNZD","AUDCAD","AUDCHF","AUDJPY","NZDCAD","NZDCHF",
"NZDJPY","CADCHF","CADJPY","CHFJPY","XAUUSD","XAGUSD"}; // 30 pairs
string USDs[]={"USDCAD","USDCHF","USDJPY","AUDUSD","EURUSD","GBPUSD","NZDUSD","XAUUSD","XAGUSD"}; // USD pairs
string EURs[]={"EURAUD","EURCAD","EURCHF","EURGBP","EURJPY","EURNZD","EURUSD"}; // EUR pairs
string GBPs[]={"GBPAUD","GBPCAD","GBPCHF","EURGBP","GBPJPY","GBPNZD","GBPUSD"}; // GBP pairs
string AUDs[]={"AUDCAD","AUDCHF","EURAUD","GBPAUD","AUDJPY","AUDNZD","AUDUSD"}; // AUD pairs
string NZDs[]={"AUDNZD","NZDCAD","NZDCHF","EURNZD","GBPNZD","NZDJPY","NZDUSD"}; // NZD pairs
string CADs[]={"AUDCAD","CADCHF","EURCAD","GBPCAD","CADJPY","NZDCAD","USDCAD"}; // CAD pairs
string CHFs[]={"AUDCHF","CADCHF","EURCHF","GBPCHF","NZDCHF","CHFJPY","USDCHF"}; // CHF pairs
string JPYs[]={"AUDJPY","CADJPY","CHFJPY","EURJPY","GBPJPY","NZDJPY","USDJPY"}; // JPY pairs
string MTLs[]={"XAUUSD","XAGUSD"}; // METAL pairs
//--
sall=ArraySize(All30);
arusd=ArraySize(USDs);
areur=ArraySize(EURs);
aretc=ArraySize(JPYs);
armet=ArraySize(MTLs);
ArrayResize(VSym,sall,sall);
ArrayCopy(VSym,All30,0,0,WHOLE_ARRAY);
//--
if(usepairs==TrdWi && StringFind(traderwishes,"eg.",0)<0)
{
string to_split=traderwishes; // A string to split into substrings pairs name
string sep=","; // A separator as a character
ushort u_sep; // The code of the separator character
//--- Get the separator code
u_sep=StringGetCharacter(sep,0);
//--- Split the string to substrings
int p=StringSplit(to_split,u_sep,SPC);
if(p>0)
{
for(int i=0; i<p; i++) StringToUpper(SPC[i]);
//--
for(int i=0; i<p; i++)
{
if(ValidatePairs(SPC[i])<0) ArrayRemove(SPC,i,1);
}
}
arspc=ArraySize(SPC);
}
//--
SetSymbolNamePS(); // With this function we will detect whether the Symbol Name has a prefix and/or suffix
//--
if(inpre>0 || insuf>0)
{
if(usepairs==TrdWi && arspc>0)
{
for(int t=0; t<arspc; t++)
{
SPC[t]=pre+SPC[t]+suf;
}
}
//--
for(int t=0; t<sall; t++)
{
All30[t]=pre+All30[t]+suf;
}
for(int t=0; t<arusd; t++)
{
USDs[t]=pre+USDs[t]+suf;
}
for(int t=0; t<areur; t++)
{
EURs[t]=pre+EURs[t]+suf;
}
for(int t=0; t<aretc; t++)
{
GBPs[t]=pre+GBPs[t]+suf;
}
for(int t=0; t<aretc; t++)
{
AUDs[t]=pre+AUDs[t]+suf;
}
for(int t=0; t<aretc; t++)
{
NZDs[t]=pre+NZDs[t]+suf;
}
for(int t=0; t<aretc; t++)
{
CADs[t]=pre+CADs[t]+suf;
}
for(int t=0; t<aretc; t++)
{
CHFs[t]=pre+CHFs[t]+suf;
}
for(int t=0; t<aretc; t++)
{
JPYs[t]=pre+JPYs[t]+suf;
}
}
//--
ArrayCopy(VSym,All30,0,0,WHOLE_ARRAY);
ArrayResize(AS30,sall,sall);
ArrayCopy(AS30,All30,0,0,WHOLE_ARRAY);
for(int x=0; x<sall; x++) {SymbolSelect(AS30[x],true);}
if(ValidatePairs(Symbol())>=0) symbfix=true;
if(!symbfix)
{
Alert("Expert Advisors will not trade on pairs "+Symbol());
Alert("-- "+expname+" -- ",Symbol()," -- expert advisor will be Remove from the chart.");
ExpertRemove();
}
//--
switch(usepairs)
{
case 0: // All Forex & Metal 30 Pairs
{
ArrayResize(DIRI,sall,sall);
arrsymbx=sall;
ArraySymbolResize();
ArrayCopy(DIRI,All30,0,0,WHOLE_ARRAY);
pairs="Multi Currency "+string(sall)+" Pairs";
//--
break;
}
case 1: // Trader wishes pairs
{
ArrayResize(DIRI,arspc,arspc);
arrsymbx=arspc;
ArraySymbolResize();
ArrayCopy(DIRI,SPC,0,0,WHOLE_ARRAY);
pairs="("+string(arspc)+") Trader Wishes Pairs";
//--
break;
}
case 2: // USD pairs
{
ArrayResize(DIRI,arusd,arusd);
arrsymbx=arusd;
ArraySymbolResize();
ArrayCopy(DIRI,USDs,0,0,WHOLE_ARRAY);
pairs="("+string(arusd)+") Multi Currency USD Pairs";
//--
break;
}
case 3: // EUR pairs
{
ArrayResize(DIRI,areur,areur);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,EURs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex EUR Pairs";
//--
break;
}
case 4: // GBP pairs
{
ArrayResize(DIRI,aretc,aretc);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,GBPs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex GBP Pairs";
//--
break;
}
case 5: // AUD pairs
{
ArrayResize(DIRI,aretc,aretc);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,AUDs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex AUD Pairs";
//--
break;
}
case 6: // NZD pairs
{
ArrayResize(DIRI,aretc,aretc);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,NZDs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex NZD Pairs";
//--
break;
}
case 7: // CAD pairs
{
ArrayResize(DIRI,aretc,aretc);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,CADs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex CAD Pairs";
//--
break;
}
case 8: // CHF pairs
{
ArrayResize(DIRI,aretc,aretc);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,CHFs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex CHF Pairs";
//--
break;
}
case 9: // JPY pairs
{
ArrayResize(DIRI,aretc,aretc);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,JPYs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex JPY Pairs";
//--
break;
}
case 10: // Metal pairs
{
ArrayResize(DIRI,armet,armet);
arrsymbx=armet;
ArraySymbolResize();
ArrayCopy(DIRI,MTLs,0,0,WHOLE_ARRAY);
pairs="("+string(armet)+") Metal Pairs";
//--
break;
}
}
//--
return;
//---
} //-end HandlingSymbolArrays()
//---------//
//---------//
void MCEA::SetSymbolNamePS(void)
{
//---
int sym_Lenpre=0;
int sym_Lensuf=0;
string sym_pre="";
string sym_suf="";
SymbolSelect(Symbol(),true);
string insymbol=Symbol();
int inlen=StringLen(insymbol);
int toseek=-1;
string dep="";
string bel="";
string sym_use ="";
int pairx=-1;
string xcur[]={"EUR","GBP","AUD","NZD","USD","CAD","CHF"}; // 7 major currency
int xcar=ArraySize(xcur);
//--
for(int x=0; x<xcar; x++)
{
toseek=StringFind(insymbol,xcur[x],0);
if(toseek>=0)
{
pairx=x;
break;
}
}
if(pairx>=0)
{
int awl=toseek-3 <0 ? 0 : toseek-3;
int sd=StringFind(insymbol,"SD",0);
if(toseek==0 && sd<4)
{
dep=StringSubstr(insymbol,toseek,3);
bel=StringSubstr(insymbol,toseek+3,3);
sym_use=dep+bel;
}
else
if(toseek>0)
{
dep=StringSubstr(insymbol,toseek,3);
bel=StringSubstr(insymbol,toseek+3,3);
sym_use=dep+bel;
}
else
{
dep=StringSubstr(insymbol,awl,3);
bel=StringSubstr(insymbol,awl+3,3);
sym_use=dep+bel;
}
}
//--
string sym_nmx=sym_use;
int lensx=StringLen(sym_nmx);
//--
if(inlen>lensx && lensx==6)
{
sym_Lenpre=StringFind(insymbol,sym_nmx,0);
sym_Lensuf=inlen-lensx-sym_Lenpre;
//--
if(sym_Lenpre>0)
{
sym_pre=StringSubstr(insymbol,0,sym_Lenpre);
for(int i=0; i<xcar; i++)
if(StringFind(sym_pre,xcur[i],0)>=0) sym_pre="";
}
if(sym_Lensuf>0)
{
sym_suf=StringSubstr(insymbol,sym_Lenpre+lensx,sym_Lensuf);
for(int i=0; i<xcar; i++)
if(StringFind(sym_suf,xcur[i],0)>=0) sym_suf="";
}
}
//--
pre=sym_pre;
suf=sym_suf;
inpre=StringLen(pre);
insuf=StringLen(suf);
posCur1=inpre;
posCur2=posCur1+3;
//--
return;
//---
} //-end SetSymbolNamePS()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
4. The Signal Generation Matrix: Deconstructing GetOpenPosition
The heart of any Algorithmic Trading system is its decision-making engine.
In our EA, the primary gateway for initiating a new trade is the int MCEA::GetOpenPosition(const string symbol) function.
This function does not operate in isolation; it acts as a master conductor, calling upon three specialized sub-functions to validate a trade signal with extreme prejudice.
Let us break down this critical matrix.
int MCEA::GetOpenPosition(const string symbol) // Signal Open Position
{
//---
int ret=0;
int rise=1,
down=-1;
//--
int GetSignal=GetSignalMAxPTPRx(symbol);
//--
if(GetSignal==rise) ret=rise;
if(GetSignal==down) ret=down;
//--
return(ret);
//---
} //-end GetOpenPosition()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
a) int MCEA::PTPRMAx(const string symbol, const ENUM_TIMEFRAMES stf): This function calculates the Price Typical Percent Range, a custom volatility and momentum oscillator. It first determines the highest high and lowest low over a 14-period lookback. It then calculates the "Typical Price" of the current bar ((High + Low + Close) / 3) and measures its position relative to the total range. This generates a raw percentage value indicating where the current price sits within its recent volatility envelope.
Crucially, this raw data is then smoothed using an Exponential Moving Average (specifically, a 9-period EMA applied to the PTPR buffer).
This smoothing process is essential; it filters out the erratic, jagged noise of raw price data, providing a clean, continuous line that clearly illustrates the underlying momentum trend.
The function stores these values in global arrays (PTPRx and EMA9OAx) for immediate access by the signal logic.
void MCEA::PTPRMAx(const string symbol,const ENUM_TIMEFRAMES stf) // Price Typical Percent Range
{
//---
int ret=0;
int rise=1,
down=-1;
int tperiod=14;
int emaperiod=9;
//--
UpdatePrice(symbol,stf);
//--
double PTPR[],
RANGEPT[],
EMA9TOA[];
//--
ArrayResize(PTPRx,arper,arper);
ArrayResize(EMA9OAx,arper,arper);
ArrayInitialize(PTPRx,0.0);
ArrayInitialize(EMA9OAx,0.0);
ArraySetAsSeries(PTPRx,true);
ArraySetAsSeries(EMA9OAx,true);
//--
ArrayResize(PTPR,arper,arper);
ArrayResize(RANGEPT,arper,arper);
ArrayResize(EMA9TOA,arper,arper);;
ArraySetAsSeries(PTPR,true);
ArraySetAsSeries(RANGEPT,true);
ArraySetAsSeries(EMA9TOA,true);
//--
for(int i=arper-2; i>=0; i--)
{
double TRHigh = HIGH[ArrayMaximum(HIGH,i,tperiod)];
double TRLow = LOW[ArrayMinimum(LOW,i,tperiod)];
RANGEPT[i]=NonZeroDiv((TRHigh-((HIGH[i]+LOW[i]+CLOSE[i])/3.0)),(TRHigh-TRLow))*100;
PTPR[i]=100-fabs(RANGEPT[i]);
}
//--
ExponentialMAOnBuffer(arper,0,0,emaperiod,PTPR,EMA9TOA);
//--
ArrayCopy(PTPRx,PTPR,0,0,WHOLE_ARRAY);
ArrayCopy(EMA9OAx,EMA9TOA,0,0,WHOLE_ARRAY);
//--
return;
//---
} //-end PTPRMAx()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
b) int MCEA::GetSignalMAxPTPRx(const string symbol): This is the core logic hub that interprets the data generated by PTPRMAx. It evaluates two primary conditions based on the user's selected signal type.
If "AD" (Aligned with Direction) is chosen, it checks if the current PTPR value is strictly greater than its 9-period EMA, and if the PTPR is actively rising (for a buy) or falling (for a sell).
If "CD" (Change of Direction) is selected, it looks for a crossover event: the PTPR was previously below the EMA and has now crossed above it (or vice versa), while also confirming that the PTPR is moving in the correct direction.
Additionally, it applies boundary filters, ensuring that a buy signal is only generated if the PTPR is below 85.00 (avoiding overbought exhaustion), and a sell signal only if it is above 15.00 (avoiding oversold exhaustion).
This function returns a "rise" (1) or "down" (-1) bias based purely on this sophisticated indicator confluence.
int MCEA::GetSignalMAxPTPRx(const string symbol)
{
//---
int ret=0;
int rise=1,
down=-1;
int tprx=0;
int emax=0;
tprpos=0.0;
//--
PTPRMAx(symbol,TFt);
//--
tprpos=NormalizeDouble(PTPRx[0],2);
if(PTPRx[0]>PTPRx[1] && tprpos<85.00) tprx=rise;
if(PTPRx[0]<PTPRx[1] && tprpos>15.00) tprx=down;
//--
switch(siguse)
{
case AD:
{
if(PTPRx[0]>EMA9OAx[0] && PTPRx[0]>PTPRx[1]) emax=rise;
if(PTPRx[0]<EMA9OAx[0] && PTPRx[0]<PTPRx[1]) emax=down;
//--
break;
}
case CD:
{
if(PTPRx[2]<=EMA9OAx[2] && PTPRx[1]>EMA9OAx[1] && PTPRx[0]>PTPRx[1]) emax=rise;
if(PTPRx[2]>=EMA9OAx[2] && PTPRx[1]<EMA9OAx[1] && PTPRx[0]<PTPRx[1]) emax=down;
//--
break;
}
}
//--
int DirMove=DirectionMove(symbol,TFt);
//--
if(DirMove==rise && emax==rise && tprx==rise) ret=rise;
if(DirMove==down && emax==down && tprx==down) ret=down;
//--
//Print("Symbol: "+symbol+" tprx: "+string(tprx)+" emax: "+string(emax)+" DirMove: "+string(DirMove));
//--
return(ret);
//---
} //-end GetSignalMAxPTPRx()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
c) int MCEA::DirectionMove(const string symbol, const ENUM_TIMEFRAMES stf): Indicator confluence alone is not enough; we must also verify raw price action. The DirectionMove function fetches the Open and Close prices of the current bar. It calculates a dynamic threshold based on the current pair's pip value. For a valid buy signal, the Close price must be definitively higher than the Open price plus this threshold. For a sell, the Close must be definitively lower than the Open minus the threshold. This ensures that the candlestick itself demonstrates strong, committed momentum in the direction of the indicator signal, filtering out weak, indecisive doji or spinning top candles.
int MCEA::DirectionMove(const string symbol,const ENUM_TIMEFRAMES stf) // Bar Price Direction
{
//---
int ret=0;
int rise=1,
down=-1;
//--
Pips(symbol);
double difud=mc_symbol.NormalizePrice(2.6*pip);
UpdatePrice(symbol,stf,2);
//--
if(CLOSE[0]>OPEN[0]+difud) ret=rise;
if(CLOSE[0]<OPEN[0]-difud) ret=down;
//--
return(ret);
//---
} //-end DirectionMove()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
Finally, GetOpenPosition aggregates these results.
A valid Buy signal requires DirectionMove to be "rise", GetSignalMAxPTPRx to be "rise", and the PTPR momentum to be "rise".
Only when all three independent checks align does the function return a definitive "1" (Buy) or "-1" (Sell), authorizing the EA to proceed with order execution.
This multi-layered validation is what makes our Forex trading strategies so resilient against market noise.
5. Intelligent Exit Strategies: GetCloseInWeakSignal and PartialCloseOrder
Entering a trade is only half the battle in Automated Forex Trading; knowing when and how to exit is what ultimately determines long-term profitability.
We have implemented two sophisticated exit mechanisms to protect our gains and minimize our losses.
The first is the int MCEA::GetCloseInWeakSignal(const string symbol, int exis) function, which is activated when the "SaveOnRev" input parameter is set to "Yes".
This function acts as an early warning system. It calls the int MCEA::GetClosePosition(const string symbol, int exis) function, which continuously monitors the PTPR indicator for signs of momentum exhaustion or reversal.
For example, if we are in a Buy position (exis = -1), GetClosePosition checks if the PTPR has started to rise sharply, indicating that the downward momentum of a potential reversal is beginning, or more accurately, it checks if the PTPR trend has inverted against our position.
If GetCloseInWeakSignal detects that the indicator has flipped against our open trade, and the trade is currently in profit (greater than the minprofit threshold), it immediately triggers a market close.
This allows us to "save" our profits before a full trend reversal can erode our gains, effectively acting as a dynamic, indicator-based breakeven or profit-lock mechanism.
It is a brilliant way to let profits run while cutting them short the moment the underlying statistical edge disappears.
int MCEA::GetClosePosition(const string symbol,int exis) // Signal Close Position
{
//---
int ret=0;
int rise=1,
down=-1;
//--
PTPRMAx(symbol,TFt);
//--
if(exis==down && PTPRx[0]>PTPRx[1]) ret=rise;
if(exis==rise && PTPRx[0]<PTPRx[1]) ret=down;
//--
return(ret);
//---
} //-end GetClosePosition()
//---------//
int MCEA::GetCloseInWeakSignal(const string symbol,int exis) // Signal Indicator Position Close in profit
{
//---
int ret=0;
int rise=1,
down=-1;
//--
int GCP=GetClosePosition(symbol,exis);
//--
if(exis==down && GCP==rise) ret=rise;
if(exis==rise && GCP==down) ret=down;
//--
return(ret);
//---
} //-end GetCloseInWeakSignal()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
The second exit mechanism is the bool MCEA::PartialCloseOrder(const string symbx) function. This is a cornerstone of professional risk management.
When "PartialClose" is enabled, the EA continuously monitors the floating profit of all open positions. Once a trade reaches the predefined profitinpips target (e.g., 15 pips), the function calculates a specific volume to close based on the percentlots parameter (e.g., 50%).
It then executes a partial close, securing a guaranteed chunk of profit and returning it to our account balance. The remaining volume is left to run, often with its Stop Loss automatically moved to breakeven by the Trailing Stop logic. This strategy psychologically relieves the pressure of the trade, as we have already "banked" a win, while still allowing us to participate in any extended, runaway trends.
By systematically reducing our exposure as a trade moves in our favor, we dramatically improve our risk-to-reward profile and ensure that a single sudden market spike cannot turn a winning trade into a loser.
This elegant combination of indicator-based weak signal detection and mechanical partial profit taking is what elevates this Expert Advisor MT5 from a simple bot to a comprehensive trading manager.
bool MCEA::PartialCloseOrder(const string symbx)
{
//---
ResetLastError();
//--
double partClsB=0.0;
double partClsS=0.0;
bool partcls=false;
//--
int x=PairsIdxArray(symbx);
Pips(symbx);
//--
int total=PositionsTotal();
//--
for(int i=total-1; i>=0; i--)
{
string symbol=PositionGetSymbol(i);
if(symbol==symbx && mc_position.Magic()==magicEA)
{
ENUM_POSITION_TYPE opstype = mc_position.PositionType();
if(opstype==POSITION_TYPE_BUY)
{
RefreshTick(symbol);
double price = mc_position.PriceCurrent();
double pos_open = mc_position.PriceOpen();
pcbpos[x] = mc_symbol.NormalizePrice(pos_open+(profitinpips*pip));
double pos_vol = mc_position.Volume();
double part_vol = NormalizeDouble((pos_vol*(percentlots/100.0)),LotDig(symbx));
bool close_comp = (pos_vol-part_vol)<mc_symbol.LotsMin();
//--
double vol_close = pos_vol==mc_symbol.LotsMin() ? pos_vol : (pos_vol-part_vol)>mc_symbol.LotsMin() ?
part_vol : (pos_vol-part_vol)<mc_symbol.LotsMin() ? pos_vol : (pos_vol-mc_symbol.LotsMin());
vol_close=NormalizeDouble(vol_close,LotDig(symbx));
//--
bool closePartBuy = (price>pcbpos[x]);
//--
if(closePartBuy) partcls=mc_trade.PositionClosePartial(symbx,vol_close,slip);
if(partcls)
{
//--
string remvol=pos_vol-part_vol > 0.0 ? "\n ~ Remaining Vol: "+DoubleToString(pos_vol-part_vol,LotDig(symbx)) : "";
Do_Alerts(symbol, DoubleToString(percentlots,2)+ "% Volume Cut for "+symbx+" Success!"+remvol);
//--
break;
}
}
if(opstype==POSITION_TYPE_SELL)
{
RefreshTick(symbol);
double price = mc_position.PriceCurrent();
double pos_open = mc_position.PriceOpen();
pcspos[x] = mc_symbol.NormalizePrice(pos_open-(profitinpips*pip));
double pos_vol = mc_position.Volume();
double part_vol = NormalizeDouble((pos_vol*(percentlots/100.0)),LotDig(symbx));
bool close_comp = (pos_vol-part_vol)<mc_symbol.LotsMin();
//--
double vol_close = pos_vol==mc_symbol.LotsMin() ? pos_vol : (pos_vol-part_vol)>mc_symbol.LotsMin() ?
part_vol : (pos_vol-part_vol)<mc_symbol.LotsMin() ? pos_vol : (pos_vol-mc_symbol.LotsMin());
vol_close=NormalizeDouble(vol_close,LotDig(symbx));
//--
bool closePartSell = (price<pcspos[x]);
//--
if(closePartSell) partcls=mc_trade.PositionClosePartial(symbx,vol_close,slip);
if(partcls)
{
//--
string remvol=pos_vol-part_vol > 0.0 ? "\n ~ Remaining Vol: "+DoubleToString(pos_vol-part_vol,LotDig(symbx)) : "";
Do_Alerts(symbol, DoubleToString(percentlots,2)+ "% Volume Cut for "+symbx+" Success!"+remvol);
//--
break;
}
}
}
}
//--
return(partcls);
//---
} //-end PartialCloseOrder()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
6. Advanced Risk Management and Trade Execution Protocols
No discussion of a Multi-currency Expert Advisor is complete without a thorough examination of its risk management protocols. In Algorithmic Trading, capital preservation is always our highest priority.
The EA employs a multi-tiered approach to safeguard our equity.
First, the MLots function provides dynamic position sizing.
Instead of using a static lot size, it calculates the maximum allowable volume based on our account's free margin, leverage, and the specific contract size of the target pair.
It then applies our predefined risk percentage, ensuring that no single trade can catastrophically damage our account, even in a Multi-Pair Trading environment where multiple positions might be open simultaneously.
Second, the EA features a robust "Good Margin Trade" check (GoodMarginTrade) that prevents the EA from opening new positions if the account's free margin falls below the maxmrgn threshold (e.g., 80% of equity).
This prevents margin calls and forced liquidations during periods of high drawdown. Third, the Trailing Stop functionality (ModifyOrdersSL) is highly versatile.
We can choose to trail by a fixed pip distance, by the custom SMA indicator we discussed earlier, or by the recent High/Low of the bars.
This ensures that our Stop Loss dynamically follows the price, locking in profits as the trend progresses.
bool MCEA::GoodMarginTrade(const string symbol,ENUM_ORDER_TYPE _cmd,double lotsz,double atprice)
{
//---
bool goodmrgn=true;
//--
if((mc_account.FreeMarginCheck(symbol,_cmd,lotsz,atprice)<=0.0)||(mc_account.FreeMargin()<(mc_account.Equity()*maxmrgn/100))) goodmrgn=false;
//--
if(!goodmrgn)
{
string nomargn="Account Free Margin minimum has reached the specified limit, Order will not opened";
Do_Alerts(symbol,nomargn);
}
//--
return(goodmrgn);
//---
} //-end GoodMarginTrade()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
Additionally, the CheckEquityBalance function acts as a final circuit breaker. If our overall equity drops below a critical threshold relative to our balance, the EA can be configured to aggressively close losing positions to prevent total account blowout.
Every single line of code in the execution phase is wrapped in rigorous error handling, retry logic, and slippage protection, ensuring that our Automated Forex Trading operates with the precision and reliability we demand.
bool MCEA::CheckEquityBalance(void)
{
//---
bool isgood=false;
if((mc_account.Equity()/mc_account.Balance()*100) > (100.00-Risk)) isgood=true;
//--
return(isgood);
//---
} //-end CheckEquityBalance()
//---------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***
Frequently Asked Questions (FAQ)
Q: Can this Multi-currency Expert Advisor run efficiently on a standard home computer, or do I need a VPS?
A: While the EA is highly optimized for memory and processing efficiency, we strongly recommend using a Virtual Private Server (VPS) for any serious Algorithmic Trading. A VPS ensures 24/7 uptime, zero latency to the broker's server, and protection against local internet or power outages, which is critical when managing up to 30 pairs simultaneously in Multi-Pair Trading.
Q: How does the EA handle broker symbols with unusual prefixes or suffixes?
A: We have specifically engineered the SetSymbolNamePS() and HandlingSymbolArrays() functions to automatically detect and adapt to any prefix or suffix. As long as the core six-character currency code (e.g., EURUSD) is present, the EA will dynamically adjust its internal arrays to match your broker's exact naming convention.
Q: Is the Moving Average Crossover strategy prone to whipsaws in ranging markets?
A: A standard crossover is, but our implementation is not. By requiring confluence with the PTPR momentum oscillator, the DirectionMove candle validation, and strict overbought/oversold boundary filters, the EA actively filters out the low-volatility, choppy conditions that typically cause whipsaws in basic Moving Average Indicators.
Q: Can I use this EA on a cent account or a micro account?
A: Absolutely. The dynamic lot sizing algorithm (MLots) automatically reads the broker's minimum and maximum volume steps (SYMBOL_VOLUME_STEP). It will scale the position size down to the absolute minimum allowed (e.g., 0.01 lots or 0.1 micro lots) to ensure compatibility with smaller account balances while maintaining the correct risk percentage.
Conclusion
The development of the Exp_MAxx5_MCEA.mq5 represents our unwavering commitment to providing the trading community with transparent, robust, and highly effective Automated Forex Trading solutions.
We have moved far beyond the simplistic, easily defeated strategies of the past. By synthesizing the classic reliability of a Moving Average Crossover with the dynamic, volatility-adjusted insights of our custom PTPR indicator, we have created a signal generation matrix that demands absolute confluence before committing capital.
Coupled with institutional-grade features like dynamic multi-currency symbol resolution, intelligent partial profit-taking, weak-signal detection, and multi-layered risk management, this Expert Advisor MT5 is not just a tool; it is a comprehensive, autonomous trading partner.
We built this system to embody the discipline, patience, and strategic foresight that we believe are the true hallmarks of long-term market success.
As we continue to refine and expand our suite of Forex trading strategies, our core mission remains unchanged: to empower us, the traders, with the technological edge required to navigate the complexities of the global financial markets with confidence and consistency.
We invite you to study this code, test it rigorously in your demo environment, and experience firsthand the transformative power of professional Algorithmic Trading.
The future of trading is automated, diversified, and meticulously managed, and we are proud to lead the way in making that future accessible to all of us.
Vital Records
We hope that this article and the Exp_MAxx5_MCEA - MQL5 Multi-Currency Expert Advisor program will be useful for traders in learning and generating new ideas, thereby will be able improving your trading performance.
We hope you find our content useful and thank you for visiting the Forex Home Expert.
See you in the next article on Expert Advisor programs or indicators for MetaTrader 4, MetaTrader 5 or Python program and trading psychology.
Explore more algorithmic trading resources:
Note: This program is shared under a Copyleft/Creative Commons License (CCL) for educational purposes. There is no direct download link available. Before obtaining the source code, if you wish to support our algorithmic trading operations, you can check out something interesting for you. Then, please follow the detailed steps below to manually install it in your MQL4/MQL5 MetaEditor.
π How to Install This Program (Manual Copy-Paste Guide)
Step-by-Step Instructions:
- Open your MQL5 MetaEditor (press F4 in MT5).
- Click "New" (or File > New) to create a new document.
- Select the program type:
- Choose Expert Advisor (template) if this is an EA.
- Choose Custom Indicator if this is an indicator.
- Enter the Name (e.g., ECN) and click "Next" twice.
- Click "Finish". A blank template page will be created.
- Scroll down and click the "Full Source Code Preview (CCL)" button below.
- Click the View Code button at the bottom left, and click the Copy Code button at the top right.
- Return to the blank MetaEditor page, Paste the code (Ctrl+V), replacing any default text.
- Click "Compile" (F7). Check the Toolbox panel: if there are 0 errors, your program is ready!
Summary: This section provides a manual copy-paste installation guide for MQL4/MQL5 Expert Advisors and Custom Indicators shared under CCL license. Users must open MetaEditor, create a new file, copy the source code from the preview section below, paste it into the editor, and compile the program to use it on MetaTrader 4/5 charts.
☕ Support the Developer: Click here to view something interesting for you..
//+------------------------------------------------------------------+
//| Exp_MAxx5_MCEA.mq5 |
//| Copyright 2026, Roberto Jacobs (3rjfx) ~ Date: 2026-08-12 |
//| https://www.mql5.com/en/users/3rjfx |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Roberto Jacobs (3rjfx) ~ Date: 2026-08-12"
#property link "https://www.mql5.com/en/users/3rjfx"
#property version "1.00"
#property strict
#property description "The Expert Exp_MAxx5_MCEA is the Automated Trading Multi Currency Forex Expert Advisor for MetaTrader 5"
#property description "by calculation of price movement percentage in Multi Timeframes and trade Multiple Pairs (30) in one Chart."
#property description "version: 1.00 ~ Update number: 1 ~ Last update: 2026/08/14 @ 12:08 (PM) WIT (Western Indonesian Time)"
//#property icon "\\Images\\Exp_MAxx5_MCEA.ico";
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Indicators\Indicator.mqh>
#include <MovingAverages.mqh>
//--
CTrade mc_trade;
CSymbolInfo mc_symbol;
CPositionInfo mc_position;
CAccountInfo mc_account;
CIndicator mc_indicator;
//---
//--
enum tm_zone
{
Cus_Session, // Trading on Custom Session
New_Zealand, // Trading on New Zealand Session
Australia, // Trading on Autralia Sydney Session
Asia_Tokyo, // Trading on Asia Tokyo Session
Europe_London, // Trading on Europe London Session
US_New_York // Trading on US New York Session
};
//--
enum swhour
{
hr_00=0, // 00:00
hr_01=1, // 01:00
hr_02=2, // 02:00
hr_03=3, // 03:00
hr_04=4, // 04:00
hr_05=5, // 05:00
hr_06=6, // 06:00
hr_07=7, // 07:00
hr_08=8, // 08:00
hr_09=9, // 09:00
hr_10=10, // 10:00
hr_11=11, // 11:00
hr_12=12, // 12:00
hr_13=13, // 13:00
hr_14=14, // 14:00
hr_15=15, // 15:00
hr_16=16, // 16:00
hr_17=17, // 17:00
hr_18=18, // 18:00
hr_19=19, // 19:00
hr_20=20, // 20:00
hr_21=21, // 21:00
hr_22=22, // 22:00
hr_23=23 // 23:00
};
//--
enum inmnt
{
mn_00=0, // Minute 0
mn_05=5, // Minute 5
mn_10=10, // Minute 10
mn_15=15, // Minute 15
mn_20=20, // Minute 20
mn_25=25, // Minute 25
mn_30=30, // Minute 30
mn_35=35, // Minute 35
mn_40=40, // Minute 40
mn_45=45, // Minute 45
mn_50=50, // Minute 50
mn_55=55 // Minute 55
};
//--
enum PairsTrade
{
All30, // All Forex 30 Pairs
TrdWi, // Trader Wishes Pairs
Usds, // Forex USD Pairs
Eurs, // Forex EUR Pairs
Gbps, // Forex GBP Pairs
Auds, // Forex AUD Pairs
Nzds, // Forex NZD Pairs
Cads, // Forex CDD Pairs
Chfs, // Forex CHF Pairs
Jpys, // Forex JPY Pairs
Metal // Metal Pairs
};
//--
enum YN
{
No,
Yes
};
//--
enum mmt
{
FixedLot, // Fixed Lot Size
DynamLot // Dynamic Lot Size
};
//--
enum TFUSE
{
TFM15, // PERIOD_M15
TFM30, // PERIOD_M30
TFH1, // PERIOD_H1
TFH2, // PERIOD_H2
TFH3, // PERIOD_H3
TFH4, // PERIOD_H4
TFH6, // PERIOD_H6
TFH8, // PERIOD_H8
TFH12, // PERIOD_H12
TFD1 // PERIOD_D1
};
//--
enum TrType
{
byprice, // Trailing Stop by Price
byindi, // Trailing Stop by Indicator
byHiLo // Trailing Stop in HIGH or LOW bar
};
//--
enum MS
{
SP, // Single Pair
MP // Multi Pairs
};
//--
enum SignalX
{
AD, // Aligned with the Direction
CD // Change of Direction
};
//--
//---
input group "=== Global Strategy EA Parameter ==="; // Global Strategy EA Parameter
input TFUSE tfinuse = TFH4; // Select Expert TimeFrame, default PERIOD_H4
input SignalX siguse = AD; // Select the Signal to be Used
//---
input group "=== Select Pairs to Trade ==="; // Selected Pairs to trading
input MS trademode = MP; // Select Trading Pairs Mode (Multi or Single)
input PairsTrade usepairs = All30; // Select Pairs to Use
input string traderwishes = "eg. eurusd,usdchf"; // If Use Trader Wishes Pairs, input pair name here, separate by comma
//--
input group "=== Money Management Lot Size Parameter ==="; // Money Management Lot Size Parameter
input mmt mmlot = DynamLot; // Money Management Type
input double Risk = 5.0; // Percent Equity Risk per Trade (Min=1.0% / Max=10.0%)
input double Lots = 0.01; // Input Manual Lot Size FixedLot
input double maxmrgn = 80.0; // Input Maximum Free Margin from Equity to Trade (in Percent)
//--Trade on Specific Time
input group "=== Trade on Specific Time ==="; // Trade on Specific Time
input YN trd_time_zone = Yes; // Select If You Like to Trade on Specific Time Zone
input tm_zone session = Cus_Session; // Select Trading Time Zone
input swhour stsescuh = hr_00; // Time Hour to Start Trading Custom Session (0-23)
input inmnt stsescum = mn_15; // Time Minute to Start Trading Custom Session (0-55)
input swhour clsescuh = hr_23; // Time Hour to Stop Trading Custom Session (0-23)
input inmnt clsescum = mn_55; // Time Minute to Stop Trading Custom Session (0-55)
//--Day Trading On/Off
input group "=== Day Trading On/Off ==="; // Day Trading On/Off
input YN ttd0 = No; // Select Trading on Sunday (Yes) or (No)
input YN ttd1 = Yes; // Select Trading on Monday (Yes) or (No)
input YN ttd2 = Yes; // Select Trading on Tuesday (Yes) or (No)
input YN ttd3 = Yes; // Select Trading on Wednesday (Yes) or (No)
input YN ttd4 = Yes; // Select Trading on Thursday (Yes) or (No)
input YN ttd5 = Yes; // Select Trading on Friday (Yes) or (No)
input YN ttd6 = No; // Select Trading on Saturday (Yes) or (No)
//--Trade & Order management Parameter
input group "=== Trade & Order management Parameter ==="; // Trade & Order management Parameter
input YN use_sl = No; // Use Order Stop Loss (Yes) or (No)
input YN autosl = Yes; // Use Automatic Calculation Stop Loss (Yes) or (No)
input double SLval = 30.0; // If Not Use Automatic SL - Input SL value in Pips
input YN use_tp = Yes; // Use Order Take Profit (Yes) or (No)
input YN autotp = Yes; // Use Automatic Calculation Take Profit (Yes) or (No)
input double TPval = 60.0; // If Not Use Automatic TP - Input TP value in Pips
input YN PartialClose = Yes; // Use Partial Close Profit (Yes) or (No)
input double profitinpips = 15.0; // Input Profit in Pips for Partial Close, default 10 Pips
input double percentlots = 50.0; // Percentage Lot Size to Partial Close
input YN TrailingSL = Yes; // Use Trailing Stop Loss (Yes) or (No)
input TrType trlby = byindi; // Select Trailing Stop Type
input double TSval = 10.0; // If Use Trailing Stop by Price Input value in Pips
input double TSmin = 5.0; // Minimum Pips to start Trailing Stop
input YN TrailingTP = Yes; // Use Trailing Take Profit (Yes) or (No)
input double TPmin = 25.0; // Input Trailing Profit Value in Pips
input YN Close_by_Opps = Yes; // Close Trade By Opposite Signal (Yes) or (No)
input YN SaveOnRev = No; // Close Trade and Save profit due to weak signal (Yes) or (No)
input YN CheckVSLTP = No; // Check Virtual SL/TP & Close Loss Trade (Yes) or (No)
//--Others Expert Advisor Parameter
input group "=== Others Expert Advisor Parameter ==="; // Others EA Parameter
input YN alerts = Yes; // Display Alerts / Messages (Yes) or (No)
input YN UseEmailAlert = No; // Email Alert (Yes) or (No)
input YN UseSendnotify = No; // Send Notification (Yes) or (No)
input YN trade_info_display = Yes; // Select Display Trading Info on Chart (Yes) or (No)
input ulong magicEA = 20260812; // Expert ID (Magic Number)
//---
//---------//
//+------------------------------------------------------------------+
//| Class for working Expert Advisor |
//+------------------------------------------------------------------+
class MCEA
{
//---
private:
//----
int x_year; // Year
int x_mon; // Month
int x_day; // Day of the month
int x_hour; // Hour in a day
int x_min; // Minutes
int x_sec; // Seconds
//--
int oBm,
oSm,
ldig;
//--- Variables used in prefix and suffix symbols
int posCur1,
posCur2;
int inpre,
insuf;
bool symbfix;
string pre,suf;
string prefix,suffix;
//--- Variables are used in Trading Time Zone
int ishour,
onhour;
int tftrlst,
tfcinws;
datetime rem,
znop,
zncl,
zntm;
datetime SesCuOp,
SesCuCl,
Ses01Op,
Ses01Cl,
Ses02Op,
Ses02Cl,
Ses03Op,
Ses03Cl,
Ses04Op,
Ses04Cl,
Ses05Op,
Ses05Cl,
SesNoOp,
SesNoCl;
//--
string tz_ses,
tz_opn,
tz_cls;
//--
string tmopcu,
tmclcu,
tmop01,
tmcl01,
tmop02,
tmcl02,
tmop03,
tmcl03,
tmop04,
tmcl04,
tmop05,
tmcl05,
tmopno,
tmclno;
//----------------------
//--
string pairs,
hariini,
daytrade,
trade_mode;
//--
double LotPS;
double point;
double slv,
tpv,
pip,
xpip;
double pcbpos[];
double pcspos[];
double floatprofit,
fixclprofit;
//--
double tprpos;
double PTPRx[],
EMA9OAx[];
double OPEN[],
HIGH[],
LOW[],
CLOSE[];
datetime TIME[];
datetime closetime;
//--
//------------
//------------
void SetSymbolNamePS(void);
void HandlingSymbolArrays(void);
void Set_Time_Zone(void);
void Time_Zone(void);
void PTPRMAx(const string symbol,const ENUM_TIMEFRAMES stf);
//--
bool Trade_session(void);
//--
int ReqTime(datetime reqtime,const int reqmode);
int DirectionMove(const string symbol,const ENUM_TIMEFRAMES stf);
int LotDig(const string symbol);
//--
double MLots(const string symbx);
double NonZeroDiv(double val1,double val2);
double OrderSLSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice);
double OrderTPSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice);
double SetOrderSL(const string xsymb,ENUM_POSITION_TYPE type,double atprice);
double SetOrderTP(const string xsymb,ENUM_POSITION_TYPE type,double atprice);
double TSPrice(const string xsymb,ENUM_POSITION_TYPE ptype,int TS_type);
//--
string PosTimeZone(void);
string ReqDate(int d,int h,int m);
string TF2Str(ENUM_TIMEFRAMES period);
string timehr(int hr,int mn);
string TradingDay(void);
string AccountMode();
string GetCommentForOrder(void) { return(expname); }
//------------
public:
//---
//-- Exp_MAxx5_MCEA Config --
string DIRI[],
AS30[],
VSym[];
string SPC[];
string USD[];
string EUR[];
string GBP[];
string AUD[];
string NZD[];
string CAD[];
string CHF[];
string JPY[];
//--
string expname;
//--- Indicators Handle
int hSMA20[];
//--
int ALO,
dgts,
arrsar,
arrsymbx;
int sall,
arusd,
areur,
aretc,
armet,
arspc,
arper;
ulong slip;
//--
double profitb[],
profits[];
double minprofit;
//--
int Buy,
Sell;
int ccur,
psec,
xtto,
TFOBV,
TFArrays,
checktml;
int OpOr[],xob[],xos[];
//--
int year, // Year
mon, // Month
day, // Day
hour, // Hour
min, // Minutes
sec, // Seconds
dow, // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday)
doy; // Day number of the year (January 1st is assigned the number value of zero)
//--
ENUM_TIMEFRAMES TFI[],
TFs[],
TFt;
//--
datetime PbarB[],
TbarB[],
PbarS[],
TbarS[];
datetime WMinx[];
//--
bool PanelExtra;
//------------
MCEA(void);
~MCEA(void);
//------------
//--
virtual void Exp_MAxx5_MCEA_Config(void);
virtual void ExpertActionTrade(void);
//--
void ArraySymbolResize(void);
void CurrentSymbolSet(const string symbol);
void Pips(const string symbol);
void TradeInfo(void);
void Do_Alerts(const string symbx,string msgText);
void CheckOpenPMx(const string symbx);
void SetSLTPOrders(void);
void CloseAllOrders(void);
void CheckClose(const string symbx);
void TodayOrders(void);
void UpdatePrice(const string symbol,ENUM_TIMEFRAMES xtf,int bars=0);
void RefreshPrice(const string symbx,ENUM_TIMEFRAMES xtf,int bars);
//--
bool CheckEquityBalance(void);
bool RefreshTick(const string symbx);
bool TradingToday(void);
bool OpenBuy(const string symbol);
bool OpenSell(const string symbol);
bool ModifyOrdersSL(const string symbx,int TS_type);
bool ModifyOrdersTP(const string symbx);
bool PartialCloseOrder(const string symbol);
bool CloseAllProfit(void);
bool CloseAllLoss(void);
bool ManualCloseAllProfit(void);
bool CheckProfitLoss(const string symbol);
bool CloseBuyPositions(const string symbol);
bool CloseSellPositions(const string symbol);
bool CheckProfit(const string symbol,ENUM_POSITION_TYPE intype);
bool CheckLoss(const string symbol,ENUM_POSITION_TYPE intype,double slc=0.0);
bool IFNewBarsB(const string symbol);
bool IFNewBarsS(const string symbol);
bool CheckMinutes(const string symbol);
bool GoodMarginTrade(const string symbol,ENUM_ORDER_TYPE _cmd,double lotsz,double atprice);
//--
int PairsIdxArray(const string symbol);
int TFIndexArray(ENUM_TIMEFRAMES TF);
int ValidatePairs(const string symbol);
int GetOpenPosition(const string symbol);
int GetSignalMAxPTPRx(const string symbol);
int GetClosePosition(const string symbol,int exis);
int GetCloseInWeakSignal(const string symbol,int exis);
int ThisTime(const int reqmode);
//--
string getUninitReasonText(int reasonCode);
//--
//------------
//---
}; //-end class MCEA
//---------//
MCEA mc;
//---------//
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
MCEA::MCEA(void): x_year(0),
x_mon(0),
x_day(0),
x_hour(0),
x_min(0),
x_sec(0),
year(0),
mon(1),
day(2),
hour(3),
min(4),
sec(5),
dow(6),
doy(7),
psec(0),
Buy(1),
Sell(-1),
slip(16),
arper(369),
checktml(0),
expname("Exp_MAxx5_MCEA"),
closetime(TimeCurrent())
{
}
//---------//
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
MCEA::~MCEA(void)
{
}
//---------//
//+------------------------------------------------------------------+
//| Expert Configuration |
//+------------------------------------------------------------------+
void MCEA::Exp_MAxx5_MCEA_Config(void)
{
//---
//--
HandlingSymbolArrays(); // With this function we will handle all pairs that will be traded
//--
ENUM_TIMEFRAMES TFx[]={PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1};
ArrayCopy(TFs,TFx,0,0,WHOLE_ARRAY);
TFArrays=ArraySize(TFs);
for(int x=0; x<TFArrays; x++) if(tfinuse==x) { TFt=TFs[x]; break; } // TF for calculation order
//--
for(int x=0; x<arrsymbx; x++)
hSMA20[x] = iMA(DIRI[x],TFt,20,0,MODE_SMA,PRICE_MEDIAN); //-- Handle for the SMA 20 indicator for Trailing Stop
//--
TesterHideIndicators(true);
minprofit=NormalizeDouble(TSmin/100.0,2);
//--
ALO=(int)mc_account.LimitOrders()>arrsymbx ? arrsymbx : (int)mc_account.LimitOrders();
//--
LotPS=(double)ALO;
//--
mc_trade.SetExpertMagicNumber(magicEA);
mc_trade.SetDeviationInPoints(slip);
mc_trade.SetMarginMode();
//--
return;
//---
} //-end Exp_MAxx5_MCEA_Config()
//---------//
void MCEA::HandlingSymbolArrays(void)
{
//---
string All30[]={"EURUSD","GBPUSD","AUDUSD","NZDUSD","USDCAD","USDCHF","USDJPY","EURGBP",
"EURAUD","EURNZD","EURCAD","EURCHF","EURJPY","GBPAUD","GBPNZD","GBPCAD",
"GBPCHF","GBPJPY","AUDNZD","AUDCAD","AUDCHF","AUDJPY","NZDCAD","NZDCHF",
"NZDJPY","CADCHF","CADJPY","CHFJPY","XAUUSD","XAGUSD"}; // 30 pairs
string USDs[]={"USDCAD","USDCHF","USDJPY","AUDUSD","EURUSD","GBPUSD","NZDUSD","XAUUSD","XAGUSD"}; // USD pairs
string EURs[]={"EURAUD","EURCAD","EURCHF","EURGBP","EURJPY","EURNZD","EURUSD"}; // EUR pairs
string GBPs[]={"GBPAUD","GBPCAD","GBPCHF","EURGBP","GBPJPY","GBPNZD","GBPUSD"}; // GBP pairs
string AUDs[]={"AUDCAD","AUDCHF","EURAUD","GBPAUD","AUDJPY","AUDNZD","AUDUSD"}; // AUD pairs
string NZDs[]={"AUDNZD","NZDCAD","NZDCHF","EURNZD","GBPNZD","NZDJPY","NZDUSD"}; // NZD pairs
string CADs[]={"AUDCAD","CADCHF","EURCAD","GBPCAD","CADJPY","NZDCAD","USDCAD"}; // CAD pairs
string CHFs[]={"AUDCHF","CADCHF","EURCHF","GBPCHF","NZDCHF","CHFJPY","USDCHF"}; // CHF pairs
string JPYs[]={"AUDJPY","CADJPY","CHFJPY","EURJPY","GBPJPY","NZDJPY","USDJPY"}; // JPY pairs
string MTLs[]={"XAUUSD","XAGUSD"}; // METAL pairs
//--
sall=ArraySize(All30);
arusd=ArraySize(USDs);
areur=ArraySize(EURs);
aretc=ArraySize(JPYs);
armet=ArraySize(MTLs);
ArrayResize(VSym,sall,sall);
ArrayCopy(VSym,All30,0,0,WHOLE_ARRAY);
//--
if(usepairs==TrdWi && StringFind(traderwishes,"eg.",0)<0)
{
string to_split=traderwishes; // A string to split into substrings pairs name
string sep=","; // A separator as a character
ushort u_sep; // The code of the separator character
//--- Get the separator code
u_sep=StringGetCharacter(sep,0);
//--- Split the string to substrings
int p=StringSplit(to_split,u_sep,SPC);
if(p>0)
{
for(int i=0; i<p; i++) StringToUpper(SPC[i]);
//--
for(int i=0; i<p; i++)
{
if(ValidatePairs(SPC[i])<0) ArrayRemove(SPC,i,1);
}
}
arspc=ArraySize(SPC);
}
//--
SetSymbolNamePS(); // With this function we will detect whether the Symbol Name has a prefix and/or suffix
//--
if(inpre>0 || insuf>0)
{
if(usepairs==TrdWi && arspc>0)
{
for(int t=0; t<arspc; t++)
{
SPC[t]=pre+SPC[t]+suf;
}
}
//--
for(int t=0; t<sall; t++)
{
All30[t]=pre+All30[t]+suf;
}
for(int t=0; t<arusd; t++)
{
USDs[t]=pre+USDs[t]+suf;
}
for(int t=0; t<areur; t++)
{
EURs[t]=pre+EURs[t]+suf;
}
for(int t=0; t<aretc; t++)
{
GBPs[t]=pre+GBPs[t]+suf;
}
for(int t=0; t<aretc; t++)
{
AUDs[t]=pre+AUDs[t]+suf;
}
for(int t=0; t<aretc; t++)
{
NZDs[t]=pre+NZDs[t]+suf;
}
for(int t=0; t<aretc; t++)
{
CADs[t]=pre+CADs[t]+suf;
}
for(int t=0; t<aretc; t++)
{
CHFs[t]=pre+CHFs[t]+suf;
}
for(int t=0; t<aretc; t++)
{
JPYs[t]=pre+JPYs[t]+suf;
}
}
//--
ArrayCopy(VSym,All30,0,0,WHOLE_ARRAY);
ArrayResize(AS30,sall,sall);
ArrayCopy(AS30,All30,0,0,WHOLE_ARRAY);
for(int x=0; x<sall; x++) {SymbolSelect(AS30[x],true);}
if(ValidatePairs(Symbol())>=0) symbfix=true;
if(!symbfix)
{
Alert("Expert Advisors will not trade on pairs "+Symbol());
Alert("-- "+expname+" -- ",Symbol()," -- expert advisor will be Remove from the chart.");
ExpertRemove();
}
//--
switch(usepairs)
{
case 0: // All Forex & Metal 30 Pairs
{
ArrayResize(DIRI,sall,sall);
arrsymbx=sall;
ArraySymbolResize();
ArrayCopy(DIRI,All30,0,0,WHOLE_ARRAY);
pairs="Multi Currency "+string(sall)+" Pairs";
//--
break;
}
case 1: // Trader wishes pairs
{
ArrayResize(DIRI,arspc,arspc);
arrsymbx=arspc;
ArraySymbolResize();
ArrayCopy(DIRI,SPC,0,0,WHOLE_ARRAY);
pairs="("+string(arspc)+") Trader Wishes Pairs";
//--
break;
}
case 2: // USD pairs
{
ArrayResize(DIRI,arusd,arusd);
arrsymbx=arusd;
ArraySymbolResize();
ArrayCopy(DIRI,USDs,0,0,WHOLE_ARRAY);
pairs="("+string(arusd)+") Multi Currency USD Pairs";
//--
break;
}
case 3: // EUR pairs
{
ArrayResize(DIRI,areur,areur);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,EURs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex EUR Pairs";
//--
break;
}
case 4: // GBP pairs
{
ArrayResize(DIRI,aretc,aretc);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,GBPs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex GBP Pairs";
//--
break;
}
case 5: // AUD pairs
{
ArrayResize(DIRI,aretc,aretc);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,AUDs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex AUD Pairs";
//--
break;
}
case 6: // NZD pairs
{
ArrayResize(DIRI,aretc,aretc);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,NZDs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex NZD Pairs";
//--
break;
}
case 7: // CAD pairs
{
ArrayResize(DIRI,aretc,aretc);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,CADs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex CAD Pairs";
//--
break;
}
case 8: // CHF pairs
{
ArrayResize(DIRI,aretc,aretc);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,CHFs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex CHF Pairs";
//--
break;
}
case 9: // JPY pairs
{
ArrayResize(DIRI,aretc,aretc);
arrsymbx=aretc;
ArraySymbolResize();
ArrayCopy(DIRI,JPYs,0,0,WHOLE_ARRAY);
pairs="("+string(aretc)+") Forex JPY Pairs";
//--
break;
}
case 10: // Metal pairs
{
ArrayResize(DIRI,armet,armet);
arrsymbx=armet;
ArraySymbolResize();
ArrayCopy(DIRI,MTLs,0,0,WHOLE_ARRAY);
pairs="("+string(armet)+") Metal Pairs";
//--
break;
}
}
//--
return;
//---
} //-end HandlingSymbolArrays()
//---------//
void MCEA::SetSymbolNamePS(void)
{
//---
int sym_Lenpre=0;
int sym_Lensuf=0;
string sym_pre="";
string sym_suf="";
SymbolSelect(Symbol(),true);
string insymbol=Symbol();
int inlen=StringLen(insymbol);
int toseek=-1;
string dep="";
string bel="";
string sym_use ="";
int pairx=-1;
string xcur[]={"EUR","GBP","AUD","NZD","USD","CAD","CHF"}; // 7 major currency
int xcar=ArraySize(xcur);
//--
for(int x=0; x<xcar; x++)
{
toseek=StringFind(insymbol,xcur[x],0);
if(toseek>=0)
{
pairx=x;
break;
}
}
if(pairx>=0)
{
int awl=toseek-3 <0 ? 0 : toseek-3;
int sd=StringFind(insymbol,"SD",0);
if(toseek==0 && sd<4)
{
dep=StringSubstr(insymbol,toseek,3);
bel=StringSubstr(insymbol,toseek+3,3);
sym_use=dep+bel;
}
else
if(toseek>0)
{
dep=StringSubstr(insymbol,toseek,3);
bel=StringSubstr(insymbol,toseek+3,3);
sym_use=dep+bel;
}
else
{
dep=StringSubstr(insymbol,awl,3);
bel=StringSubstr(insymbol,awl+3,3);
sym_use=dep+bel;
}
}
//--
string sym_nmx=sym_use;
int lensx=StringLen(sym_nmx);
//--
if(inlen>lensx && lensx==6)
{
sym_Lenpre=StringFind(insymbol,sym_nmx,0);
sym_Lensuf=inlen-lensx-sym_Lenpre;
//--
if(sym_Lenpre>0)
{
sym_pre=StringSubstr(insymbol,0,sym_Lenpre);
for(int i=0; i<xcar; i++)
if(StringFind(sym_pre,xcur[i],0)>=0) sym_pre="";
}
if(sym_Lensuf>0)
{
sym_suf=StringSubstr(insymbol,sym_Lenpre+lensx,sym_Lensuf);
for(int i=0; i<xcar; i++)
if(StringFind(sym_suf,xcur[i],0)>=0) sym_suf="";
}
}
//--
pre=sym_pre;
suf=sym_suf;
inpre=StringLen(pre);
insuf=StringLen(suf);
posCur1=inpre;
posCur2=posCur1+3;
//--
return;
//---
} //-end SetSymbolNamePS()
//---------//
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit(void)
{
//---
mc.Exp_MAxx5_MCEA_Config();
//--
return(INIT_SUCCEEDED);
//---
} //-end OnInit()
//---------//
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
Comment("");
//--
for(int x=0; x<mc.arrsymbx; x++)
IndicatorRelease(mc.hSMA20[x]);
//--
PrintFormat("%s: Deinitialization reason code=%d",__FUNCTION__,reason);
Print(mc.getUninitReasonText(reason));
ObjectsDeleteAll(0,0,OBJ_BUTTON);
ObjectsDeleteAll(0,0,OBJ_LABEL);
ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL);
//--
return;
//---
} //-end OnDeinit()
//---------//
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick(void)
{
//---
mc.ExpertActionTrade();
//--
return;
//---
} //-end OnTick()
//---------//
//+------------------------------------------------------------------+
void MCEA::ExpertActionTrade(void)
{
//---
//Check Trading Terminal
ResetLastError();
//--
if(!MQLInfoInteger(MQL_TRADE_ALLOWED) && mc.checktml==0) //-- Check whether MT5 Algorithmic trading is Allow or Prohibit
{
mc.Do_Alerts(Symbol(),"Trading Expert at "+Symbol()+" are NOT Allowed by Setting.");
mc.checktml=1; //-- Variable checktml is given a value of 1, so that the alert is only done once.
return;
}
//--
if(!DisplayManualButton("M","C","R")) DisplayManualButton(); //-- Show the expert manual button panel
//--
if(trade_info_display==Yes) mc.TradeInfo(); //-- Displayed Trading Info on Chart
//---
//--
int mcsec=mc.ThisTime(mc.sec);
//--
if(fmod((double)mcsec,5.0)==0) mc.ccur=mcsec;
//--
if(mc.ccur!=mc.psec)
{
string symbol;
//-- Here we start with the rotation of the name of all symbol or pairs to be traded
for(int x=0; x<mc.arrsymbx && !IsStopped(); x++)
{
//--
switch(trademode)
{
case SP:
{
if(mc.DIRI[x]!=Symbol()) continue;
symbol=Symbol();
mc.pairs="Single Pair"+" ("+symbol+")";
break;
}
case MP:
{
if(mc.DIRI[x]==Symbol()) symbol=Symbol();
else symbol=mc.DIRI[x];
break;
}
}
//--
mc.CurrentSymbolSet(symbol);
//--
if(mc.TradingToday() && mc.Trade_session())
{
//--
mc.OpOr[x]=mc.GetOpenPosition(symbol); //-- Get trading signals to open positions
//-- //-- and store in the variable OpOr[x]
if(mc.OpOr[x]==mc.Buy) //-- If variable OpOr[x] get result of GetOpenPosition(symbol) as "Buy" (value=1)
{
//--
mc.CheckOpenPMx(symbol);
//--
if(Close_by_Opps==Yes && mc.xos[x]>0) { mc.CloseSellPositions(symbol); mc.OpenBuy(symbol); }
//--
if(mc.xob[x]==0 && mc.xtto<mc.ALO && mc.IFNewBarsB(symbol)) mc.OpenBuy(symbol);
else
if(mc.xtto>=mc.ALO)
{
//--
mc.Do_Alerts(symbol,"Maximum amount of open positions and active pending orders has reached"+
"\n the limit = "+string(mc.ALO)+" Orders ");
//--
mc.CheckOpenPMx(symbol);
//--
if(mc.xos[x]>0 && mc.profits[x]<-1.02 && mc.xob[x]==0) { mc.CloseSellPositions(symbol); mc.OpenBuy(symbol); }
else
mc.CloseAllProfit();
//--
}
}
if(mc.OpOr[x]==mc.Sell) //-- If variable OpOr[x] get result of GetOpenPosition(symbol) as "Sell" (value=-1)
{
//--
mc.CheckOpenPMx(symbol);
//--
if(Close_by_Opps==Yes && mc.xob[x]>0) { mc.CloseBuyPositions(symbol); mc.OpenSell(symbol); }
//--
if(mc.xos[x]==0 && mc.xtto<mc.ALO && mc.IFNewBarsS(symbol)) mc.OpenSell(symbol);
else
if(mc.xtto>=mc.ALO)
{
//--
mc.Do_Alerts(symbol,"Maximum amount of open positions and active pending orders has reached"+
"\n the limit = "+string(mc.ALO)+" Orders ");
//--
mc.CheckOpenPMx(symbol);
//--
if(mc.xob[x]>0 && mc.profitb[x]<-1.02 && mc.xos[x]==0) { mc.CloseBuyPositions(symbol); mc.OpenSell(symbol); }
else
mc.CloseAllProfit();
//--
}
}
}
//--
mc.CheckOpenPMx(symbol);
//--
if(mc.xtto>0)
{
//--
if(PartialClose==Yes) //-- Partial Close Order (Yes)
{
PartialCloseOrder(symbol);
}
//--
if(SaveOnRev==Yes) //-- Close Trade and Save profit due to weak signal (Yes)
{
mc.CheckOpenPMx(symbol);
if(mc.profitb[x]>mc.minprofit && mc.xob[x]>0 && mc.GetCloseInWeakSignal(symbol,mc.Buy)==mc.Sell)
{
mc.CloseBuyPositions(symbol);
mc.Do_Alerts(symbol,"Close BUY order "+symbol+" to save profit due to weak signal.");
}
if(mc.profits[x]>mc.minprofit && mc.xos[x]>0 && mc.GetCloseInWeakSignal(symbol,mc.Sell)==mc.Buy)
{
mc.CloseSellPositions(symbol);
mc.Do_Alerts(symbol,"Close SELL order "+symbol+" to save profit due to weak signal.");
}
}
//--
if(TrailingSL==Yes) mc.ModifyOrdersSL(symbol,trlby); //-- Use Trailing Stop Loss (Yes)
if(TrailingTP==Yes) mc.ModifyOrdersTP(symbol); //-- Use Trailing Take Profit (Yes)
}
//--
mc.CheckOpenPMx(symbol);
if(Close_by_Opps==No && (mc.xob[x]+mc.xos[x]>1))
{
mc.CheckProfitLoss(symbol);
mc.Do_Alerts(symbol,"Close order due stop in loss.");
}
//--
if(use_sl==No && CheckVSLTP==Yes)
{
if(!mc.CheckEquityBalance())
if(mc.CloseAllLoss())
mc.Do_Alerts(symbol,"Close order due stop in loss to secure equity.");
}
//--
mc.CheckClose(symbol);
}
//--
mc.psec=mc.ccur;
}
//--
return;
//---
} //-end ExpertActionTrade()
//---------//
int MCEA::PairsIdxArray(const string symbol)
{
//---
int pidx=0;
//--
for(int x=0; x<arrsymbx; x++)
{
if(DIRI[x]==symbol)
{
pidx=x;
break;
}
}
//--
return(pidx);
//---
} //-end PairsIdxArray()
//---------//
int MCEA::TFIndexArray(ENUM_TIMEFRAMES TF)
{
//---
int res=-1;
//--
for(int x=0; x<TFArrays; x++)
{
if(TF==TFI[x])
{
res=x;
break;
}
}
//--
return(res);
//---
} //-end TFIndexArray()
//---------//
int MCEA::ValidatePairs(const string symbol)
{
//---
int pidx=-1;
//--
for(int x=0; x<sall; x++)
{
if(VSym[x]==symbol)
{
pidx=x;
break;
}
}
//--
return(pidx);
//---
} //-end ValidatePairs()
//---------//
void MCEA::ArraySymbolResize(void)
{
//---
ArrayFree(DIRI);
ArrayFree(xob);
ArrayFree(xos);
ArrayFree(OpOr);
ArrayFree(hSMA20);
ArrayFree(profitb);
ArrayFree(profits);
ArrayFree(PbarB);
ArrayFree(TbarB);
ArrayFree(PbarS);
ArrayFree(TbarS);
ArrayFree(WMinx);
ArrayFree(pcbpos);
ArrayFree(pcspos);
//--
ArrayResize(DIRI,arrsymbx,arrsymbx);
ArrayResize(xob,arrsymbx,arrsymbx);
ArrayResize(xos,arrsymbx,arrsymbx);
ArrayResize(OpOr,arrsymbx,arrsymbx);
ArrayResize(hSMA20,arrsymbx,arrsymbx);
ArrayResize(profitb,arrsymbx,arrsymbx);
ArrayResize(profits,arrsymbx,arrsymbx);
ArrayResize(PbarB,arrsymbx,arrsymbx);
ArrayResize(TbarB,arrsymbx,arrsymbx);
ArrayResize(PbarS,arrsymbx,arrsymbx);
ArrayResize(TbarS,arrsymbx,arrsymbx);
ArrayResize(WMinx,arrsymbx,arrsymbx);
ArrayResize(pcbpos,arrsymbx,arrsymbx);
ArrayResize(pcspos,arrsymbx,arrsymbx);
//--
return;
//---
} //-end ArraySymbolResize()
//---------//
void MCEA::UpdatePrice(const string symbol,ENUM_TIMEFRAMES xtf,int bars=0)
{
//---
int xbar=bars==0 ? arper : bars;
//--
ArrayFree(OPEN);
ArrayFree(HIGH);
ArrayFree(LOW);
ArrayFree(CLOSE);
ArrayFree(TIME);
//--
ArrayResize(OPEN,xbar,xbar);
ArrayResize(HIGH,xbar,xbar);
ArrayResize(LOW,xbar,xbar);
ArrayResize(CLOSE,xbar,xbar);
ArrayResize(TIME,xbar,xbar);
//--
ArraySetAsSeries(OPEN,true);
ArraySetAsSeries(HIGH,true);
ArraySetAsSeries(LOW,true);
ArraySetAsSeries(CLOSE,true);
ArraySetAsSeries(TIME,true);
//--
ArrayInitialize(OPEN,0.0);
ArrayInitialize(HIGH,0.0);
ArrayInitialize(LOW,0.0);
ArrayInitialize(CLOSE,0.0);
ArrayInitialize(TIME,0);
//--
RefreshPrice(symbol,xtf,bars);
//--
int co=CopyOpen(symbol,xtf,0,xbar,OPEN);
int ch=CopyHigh(symbol,xtf,0,xbar,HIGH);
int cl=CopyLow(symbol,xtf,0,xbar,LOW);
int cc=CopyClose(symbol,xtf,0,xbar,CLOSE);
int ct=CopyTime(symbol,xtf,0,xbar,TIME);
//--
return;
//---
} //-end UpdatePrice()
//---------//
void MCEA::RefreshPrice(const string symbx,ENUM_TIMEFRAMES xtf,int bars)
{
//---
MqlRates parray[];
ArraySetAsSeries(parray,true);
int copied=CopyRates(symbx,xtf,0,bars,parray);
//--
return;
//---
} //-end RefreshPrice()
//---------//
bool MCEA::RefreshTick(const string symbx)
{
//---
mc_symbol.Name(symbx);
if(mc_symbol.RefreshRates()) return(true);
//--
return(false);
//---
} //-end RefreshTick()
//---------//
void MCEA::CurrentSymbolSet(const string symbol)
{
//---
mc_symbol.Name(symbol);
mc_symbol.CheckMarketWatch();
mc_symbol.IsSynchronized();
mc_trade.SetTypeFillingBySymbol(symbol);
mc_symbol.Refresh();
mc_symbol.RefreshRates();
//--
return;
//---
} //-end CurrentSymbolSet()
//---------//
void MCEA::Pips(const string symbol)
{
//---
CurrentSymbolSet(symbol);
//--
point=mc_symbol.Point();
dgts=(int)mc_symbol.Digits();
//--
xpip=10.0;
pip=point*xpip;
//--
return;
//---
} //-end Pips()
//---------//
bool MCEA::IFNewBarsB(const string symbol) // New bar check buy order
{
//---
bool Nb=false;
int xs=PairsIdxArray(symbol);
//--
TbarB[xs]=iTime(symbol,TFt,0);
if(TbarB[xs]!=PbarB[xs]) Nb=true;
//--
if(Nb && CheckMinutes(symbol)) return(true);
//--
return(false);
//---
} //-end IFNewBarsB()
//---------//
bool MCEA::IFNewBarsS(const string symbol) // New bar check sell order
{
//---
bool Nb=false;
int xs=PairsIdxArray(symbol);
//--
TbarS[xs]=iTime(symbol,TFt,0);
if(TbarS[xs]!=PbarS[xs]) Nb=true;
//--
if(Nb && CheckMinutes(symbol)) return(true);
//--
return(false);
//---
} //-end IFNewBarsS()
//---------//
bool MCEA::CheckMinutes(const string symbol) // Wait 10 Minutes Check for open order
{
//---
bool CM=false;
int xs=PairsIdxArray(symbol);
if(WMinx[xs]==0 && TimeCurrent()>iTime(symbol,TFt,0)+PeriodSeconds(PERIOD_M6))
WMinx[xs]=TimeCurrent()+PeriodSeconds(PERIOD_M6);
else
if(TimeCurrent()<iTime(symbol,TFt,0)+PeriodSeconds(PERIOD_M6))
WMinx[xs]=iTime(symbol,TFt,0)+PeriodSeconds(PERIOD_M6);
//--
if(TimeCurrent()>WMinx[xs]) CM=true;
//--
return(CM);
//---
} //-end CheckMinutes()
//---------//
bool MCEA::GoodMarginTrade(const string symbol,ENUM_ORDER_TYPE _cmd,double lotsz,double atprice)
{
//---
bool goodmrgn=true;
//--
if((mc_account.FreeMarginCheck(symbol,_cmd,lotsz,atprice)<=0.0)||(mc_account.FreeMargin()<(mc_account.Equity()*maxmrgn/100))) goodmrgn=false;
//--
if(!goodmrgn)
{
string nomargn="Account Free Margin minimum has reached the specified limit, Order will not opened";
Do_Alerts(symbol,nomargn);
}
//--
return(goodmrgn);
//---
} //-end GoodMarginTrade()
//---------//
int MCEA::DirectionMove(const string symbol,const ENUM_TIMEFRAMES stf) // Bar Price Direction
{
//---
int ret=0;
int rise=1,
down=-1;
//--
Pips(symbol);
double difud=mc_symbol.NormalizePrice(2.6*pip);
UpdatePrice(symbol,stf,2);
//--
if(CLOSE[0]>OPEN[0]+difud) ret=rise;
if(CLOSE[0]<OPEN[0]-difud) ret=down;
//--
return(ret);
//---
} //-end DirectionMove()
//---------//
void MCEA::PTPRMAx(const string symbol,const ENUM_TIMEFRAMES stf) // Price Typical Percent Range
{
//---
int ret=0;
int rise=1,
down=-1;
int tperiod=14;
int emaperiod=9;
//--
UpdatePrice(symbol,stf);
//--
double PTPR[],
RANGEPT[],
EMA9TOA[];
//--
ArrayResize(PTPRx,arper,arper);
ArrayResize(EMA9OAx,arper,arper);
ArrayInitialize(PTPRx,0.0);
ArrayInitialize(EMA9OAx,0.0);
ArraySetAsSeries(PTPRx,true);
ArraySetAsSeries(EMA9OAx,true);
//--
ArrayResize(PTPR,arper,arper);
ArrayResize(RANGEPT,arper,arper);
ArrayResize(EMA9TOA,arper,arper);;
ArraySetAsSeries(PTPR,true);
ArraySetAsSeries(RANGEPT,true);
ArraySetAsSeries(EMA9TOA,true);
//--
for(int i=arper-2; i>=0; i--)
{
double TRHigh = HIGH[ArrayMaximum(HIGH,i,tperiod)];
double TRLow = LOW[ArrayMinimum(LOW,i,tperiod)];
RANGEPT[i]=NonZeroDiv((TRHigh-((HIGH[i]+LOW[i]+CLOSE[i])/3.0)),(TRHigh-TRLow))*100;
PTPR[i]=100-fabs(RANGEPT[i]);
}
//--
ExponentialMAOnBuffer(arper,0,0,emaperiod,PTPR,EMA9TOA);
//--
ArrayCopy(PTPRx,PTPR,0,0,WHOLE_ARRAY);
ArrayCopy(EMA9OAx,EMA9TOA,0,0,WHOLE_ARRAY);
//--
return;
//---
} //-end PTPRMAx()
//---------//
int MCEA::GetSignalMAxPTPRx(const string symbol)
{
//---
int ret=0;
int rise=1,
down=-1;
int tprx=0;
int emax=0;
tprpos=0.0;
//--
PTPRMAx(symbol,TFt);
//--
tprpos=NormalizeDouble(PTPRx[0],2);
if(PTPRx[0]>PTPRx[1] && tprpos<85.00) tprx=rise;
if(PTPRx[0]<PTPRx[1] && tprpos>15.00) tprx=down;
//--
switch(siguse)
{
case AD:
{
if(PTPRx[0]>EMA9OAx[0] && PTPRx[0]>PTPRx[1]) emax=rise;
if(PTPRx[0]<EMA9OAx[0] && PTPRx[0]<PTPRx[1]) emax=down;
//--
break;
}
case CD:
{
if(PTPRx[2]<=EMA9OAx[2] && PTPRx[1]>EMA9OAx[1] && PTPRx[0]>PTPRx[1]) emax=rise;
if(PTPRx[2]>=EMA9OAx[2] && PTPRx[1]<EMA9OAx[1] && PTPRx[0]<PTPRx[1]) emax=down;
//--
break;
}
}
//--
int DirMove=DirectionMove(symbol,TFt);
//--
if(DirMove==rise && emax==rise && tprx==rise) ret=rise;
if(DirMove==down && emax==down && tprx==down) ret=down;
//--
//Print("Symbol: "+symbol+" tprx: "+string(tprx)+" emax: "+string(emax)+" DirMove: "+string(DirMove));
//--
return(ret);
//---
} //-end GetSignalMAxPTPRx()
//---------//
int MCEA::GetOpenPosition(const string symbol) // Signal Open Position
{
//---
int ret=0;
int rise=1,
down=-1;
//--
int GetSignal=GetSignalMAxPTPRx(symbol);
//--
if(GetSignal==rise) ret=rise;
if(GetSignal==down) ret=down;
//--
return(ret);
//---
} //-end GetOpenPosition()
//---------//
int MCEA::GetClosePosition(const string symbol,int exis) // Signal Close Position
{
//---
int ret=0;
int rise=1,
down=-1;
//--
PTPRMAx(symbol,TFt);
//--
if(exis==down && PTPRx[0]>PTPRx[1]) ret=rise;
if(exis==rise && PTPRx[0]<PTPRx[1]) ret=down;
//--
return(ret);
//---
} //-end GetClosePosition()
//---------//
int MCEA::GetCloseInWeakSignal(const string symbol,int exis) // Signal Indicator Position Close in profit
{
//---
int ret=0;
int rise=1,
down=-1;
//--
int GCP=GetClosePosition(symbol,exis);
//--
if(exis==down && GCP==rise) ret=rise;
if(exis==rise && GCP==down) ret=down;
//--
return(ret);
//---
} //-end GetCloseInWeakSignal()
//---------//
bool MCEA::OpenBuy(const string symbol)
{
//---
ResetLastError();
//--
bool buyopen = false;
string ldComm = GetCommentForOrder()+"_Buy";
double ldLot = MLots(symbol);
ENUM_ORDER_TYPE type_req = ORDER_TYPE_BUY;
//--
if(!GoodMarginTrade(symbol,type_req,ldLot,mc_symbol.Ask())) return(false);
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//-- structure is set to zero
ZeroMemory(req);
ZeroMemory(res);
ZeroMemory(check);
//--
CurrentSymbolSet(symbol);
double SL=OrderSLSet(symbol,type_req,mc_symbol.Bid());
double TP=OrderTPSet(symbol,type_req,mc_symbol.Ask());
//--
if(RefreshTick(symbol))
buyopen=mc_trade.Buy(ldLot,symbol,mc_symbol.Ask(),SL,TP,ldComm);
//--
int error=GetLastError();
if(buyopen||error==0)
{
string bsopen="Open BUY Order for "+symbol+" ~ Ticket= ["+(string)mc_trade.ResultOrder()+"] successfully..!";
Do_Alerts(symbol,bsopen);
int xi=PairsIdxArray(symbol);
PbarB[xi]=iTime(symbol,TFt,0);
}
else
{
mc_trade.CheckResult(check);
Do_Alerts(Symbol(),"Open BUY order for "+symbol+" FAILED!!. Return code= "+
(string)mc_trade.ResultRetcode()+". Code description: ["+mc_trade.ResultRetcodeDescription()+"]");
return(false);
}
//--
return(buyopen);
//--
//---
} //-end OpenBuy
//---------//
bool MCEA::OpenSell(const string symbol)
{
//---
ResetLastError();
//--
bool selopen = false;
string sdComm = GetCommentForOrder()+"_Sell";
double sdLot = MLots(symbol);
ENUM_ORDER_TYPE type_req = ORDER_TYPE_SELL;
//--
if(!GoodMarginTrade(symbol,type_req,sdLot,mc_symbol.Ask())) return(false);
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//-- structure is set to zero
ZeroMemory(req);
ZeroMemory(res);
ZeroMemory(check);
//--
CurrentSymbolSet(symbol);
double SL=OrderSLSet(symbol,type_req,mc_symbol.Ask());
double TP=OrderTPSet(symbol,type_req,mc_symbol.Bid());
//--
if(RefreshTick(symbol))
selopen=mc_trade.Sell(sdLot,symbol,mc_symbol.Bid(),SL,TP,sdComm);
//--
int error=GetLastError();
if(selopen||error==0)
{
string bsopen="Open SELL Order for "+symbol+" ~ Ticket= ["+(string)mc_trade.ResultOrder()+"] successfully..!";
Do_Alerts(symbol,bsopen);
int xi=PairsIdxArray(symbol);
PbarS[xi]=iTime(symbol,TFt,0);
}
else
{
mc_trade.CheckResult(check);
Do_Alerts(Symbol(),"Open SELL order for "+symbol+" FAILED!!. Return code= "+
(string)mc_trade.ResultRetcode()+". Code description: ["+mc_trade.ResultRetcodeDescription()+"]");
return(false);
}
//--
return(selopen);
//--
//---
} //-end OpenSell
//---------//
double MCEA::OrderSLSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice)
{
//---
slv=0.0;
int x=PairsIdxArray(xsymb);
Pips(xsymb);
RefreshTick(xsymb);
//--
switch(type)
{
case (ORDER_TYPE_BUY):
{
if(use_sl==Yes && autosl==Yes) slv=mc_symbol.NormalizePrice(atprice-38*pip);
else
if(use_sl==Yes && autosl==No) slv=mc_symbol.NormalizePrice(atprice-SLval*pip);
else slv=0.0;
//--
break;
}
case (ORDER_TYPE_SELL):
{
if(use_sl==Yes && autosl==Yes) slv=mc_symbol.NormalizePrice(atprice+38*pip);
else
if(use_sl==Yes && autosl==No) slv=mc_symbol.NormalizePrice(atprice+SLval*pip);
else slv=0.0;
}
}
//---
return(slv);
//---
} //-end OrderSLSet()
//---------//
double MCEA::OrderTPSet(const string xsymb,ENUM_ORDER_TYPE type,double atprice)
{
//---
tpv=0.0;
int x=PairsIdxArray(xsymb);
Pips(xsymb);
RefreshTick(xsymb);
//--
switch(type)
{
case (ORDER_TYPE_BUY):
{
if(use_tp==Yes && autotp==Yes) tpv=mc_symbol.NormalizePrice(atprice+50*pip);
else
if(use_tp==Yes && autotp==No) tpv=mc_symbol.NormalizePrice(atprice+TPval*pip);
else tpv=0.0;
//--
break;
}
case (ORDER_TYPE_SELL):
{
if(use_tp==Yes && autotp==Yes) tpv=mc_symbol.NormalizePrice(atprice-50*pip);
else
if(use_tp==Yes && autotp==No) tpv=mc_symbol.NormalizePrice(atprice-TPval*pip);
else tpv=0.0;
}
}
//---
return(tpv);
//---
} //-end OrderTPSet()
//---------//
void MCEA::CheckOpenPMx(const string symbx) //-- function: CheckOpenTrade.
{
//---
int totalorder=PositionsTotal();
xtto=totalorder;
//--
int xi=PairsIdxArray(symbx);
xob[xi]=0;
xos[xi]=0;
profitb[xi]=0;
profits[xi]=0;
double pos_profit = 0.0;
double pos_swap = 0.0;
double pos_comm = 0.0;
//--
for(int i=0; i<totalorder && !IsStopped(); i++)
{
string position_symbol=PositionGetSymbol(i);
long magic = mc_position.Magic();
if(position_symbol==symbx && magic==magicEA)
{
//--
ENUM_POSITION_TYPE opstype = mc_position.PositionType();
if(opstype == POSITION_TYPE_BUY)
{
xob[xi]++;
pos_profit = mc_position.Profit();
pos_swap = mc_position.Swap();
pos_comm = mc_position.Commission();
profitb[xi] += NormalizeDouble(pos_profit+pos_swap+pos_comm,2);
PbarB[xi] = iTime(symbx,TFt,0);
}
if(opstype == POSITION_TYPE_SELL)
{
xos[xi]++;
pos_profit = mc_position.Profit();
pos_swap = mc_position.Swap();
pos_comm = mc_position.Commission();
profits[xi] += NormalizeDouble(pos_profit+pos_swap+pos_comm,2);
PbarS[xi] = iTime(symbx,TFt,0);
}
//--
}
}
//---
return;
//---
} //-end CheckOpenPMx()
//---------//
bool MCEA::PartialCloseOrder(const string symbx)
{
//---
ResetLastError();
//--
double partClsB=0.0;
double partClsS=0.0;
bool partcls=false;
//--
int x=PairsIdxArray(symbx);
Pips(symbx);
//--
int total=PositionsTotal();
//--
for(int i=total-1; i>=0; i--)
{
string symbol=PositionGetSymbol(i);
if(symbol==symbx && mc_position.Magic()==magicEA)
{
ENUM_POSITION_TYPE opstype = mc_position.PositionType();
if(opstype==POSITION_TYPE_BUY)
{
RefreshTick(symbol);
double price = mc_position.PriceCurrent();
double pos_open = mc_position.PriceOpen();
pcbpos[x] = mc_symbol.NormalizePrice(pos_open+(profitinpips*pip));
double pos_vol = mc_position.Volume();
double part_vol = NormalizeDouble((pos_vol*(percentlots/100.0)),LotDig(symbx));
bool close_comp = (pos_vol-part_vol)<mc_symbol.LotsMin();
//--
double vol_close = pos_vol==mc_symbol.LotsMin() ? pos_vol : (pos_vol-part_vol)>mc_symbol.LotsMin() ?
part_vol : (pos_vol-part_vol)<mc_symbol.LotsMin() ? pos_vol : (pos_vol-mc_symbol.LotsMin());
vol_close=NormalizeDouble(vol_close,LotDig(symbx));
//--
bool closePartBuy = (price>pcbpos[x]);
//--
if(closePartBuy) partcls=mc_trade.PositionClosePartial(symbx,vol_close,slip);
if(partcls)
{
//--
string remvol=pos_vol-part_vol > 0.0 ? "\n ~ Remaining Vol: "+DoubleToString(pos_vol-part_vol,LotDig(symbx)) : "";
Do_Alerts(symbol, DoubleToString(percentlots,2)+ "% Volume Cut for "+symbx+" Success!"+remvol);
//--
break;
}
}
if(opstype==POSITION_TYPE_SELL)
{
RefreshTick(symbol);
double price = mc_position.PriceCurrent();
double pos_open = mc_position.PriceOpen();
pcspos[x] = mc_symbol.NormalizePrice(pos_open-(profitinpips*pip));
double pos_vol = mc_position.Volume();
double part_vol = NormalizeDouble((pos_vol*(percentlots/100.0)),LotDig(symbx));
bool close_comp = (pos_vol-part_vol)<mc_symbol.LotsMin();
//--
double vol_close = pos_vol==mc_symbol.LotsMin() ? pos_vol : (pos_vol-part_vol)>mc_symbol.LotsMin() ?
part_vol : (pos_vol-part_vol)<mc_symbol.LotsMin() ? pos_vol : (pos_vol-mc_symbol.LotsMin());
vol_close=NormalizeDouble(vol_close,LotDig(symbx));
//--
bool closePartSell = (price<pcspos[x]);
//--
if(closePartSell) partcls=mc_trade.PositionClosePartial(symbx,vol_close,slip);
if(partcls)
{
//--
string remvol=pos_vol-part_vol > 0.0 ? "\n ~ Remaining Vol: "+DoubleToString(pos_vol-part_vol,LotDig(symbx)) : "";
Do_Alerts(symbol, DoubleToString(percentlots,2)+ "% Volume Cut for "+symbx+" Success!"+remvol);
//--
break;
}
}
}
}
//--
return(partcls);
//---
} //-end PartialCloseOrder()
//---------//
double MCEA::TSPrice(const string xsymb,ENUM_POSITION_TYPE ptype,int TS_type)
{
//---
int br=2;
double pval=0.0;
int x=PairsIdxArray(xsymb);
Pips(xsymb);
//--
switch(TS_type)
{
case byprice:
{
RefreshTick(xsymb);
if(ptype==POSITION_TYPE_BUY) pval=mc_symbol.NormalizePrice(mc_symbol.Bid()-TSval*pip);
if(ptype==POSITION_TYPE_SELL) pval=mc_symbol.NormalizePrice(mc_symbol.Ask()+TSval*pip);
break;
}
case byindi:
{
double SMAML[];
ArrayResize(SMAML,br,br);
ArraySetAsSeries(SMAML,true);
CopyBuffer(hSMA20[x],0,0,br,SMAML);
RefreshPrice(xsymb,TFt,br);
//--
if(ptype==POSITION_TYPE_BUY && (SMAML[0]<mc_symbol.NormalizePrice(mc_symbol.Bid()-TSval*pip)))
pval=SMAML[0];
if(ptype==POSITION_TYPE_SELL && (SMAML[0]>mc_symbol.NormalizePrice(mc_symbol.Ask()+TSval*pip)))
pval=SMAML[0];
break;
}
case byHiLo:
{
UpdatePrice(xsymb,TFt,2);
//--
if(ptype==POSITION_TYPE_BUY && (HIGH[0]>HIGH[1]))
pval=LOW[1];
if(ptype==POSITION_TYPE_SELL && (LOW[0]<LOW[1]))
pval=HIGH[1];
break;
}
}
//--
return(pval);
//---
} //-end TSPrice()
//---------//
bool MCEA::ModifyOrdersSL(const string symbx,int TS_type)
{
//---
ResetLastError();
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
int TRSP=TS_type;
bool modist=false;
int x=PairsIdxArray(symbx);
Pips(symbx);
//--
int total=PositionsTotal();
//--
for(int i=total-1; i>=0; i--)
{
string symbol=PositionGetSymbol(i);
if(symbol==symbx && mc_position.Magic()==magicEA)
{
ENUM_POSITION_TYPE opstype = mc_position.PositionType();
if(opstype==POSITION_TYPE_BUY)
{
RefreshTick(symbol);
double price = mc_position.PriceCurrent();
double vtrsb = mc_symbol.NormalizePrice(TSPrice(symbx,opstype,TRSP));
double pos_open = mc_position.PriceOpen();
double pos_stop = mc_position.StopLoss();
double pos_tp = mc_position.TakeProfit();
double pos_profit = mc_position.Profit();
double pos_swap = mc_position.Swap();
double pos_comm = mc_position.Commission();
double netp=pos_profit+pos_swap+pos_comm;
double modstart=mc_symbol.NormalizePrice(pos_open+TSmin*pip);
double modminsl=mc_symbol.NormalizePrice(vtrsb+((TSmin-1.0)*pip));
double modbuysl=vtrsb;
bool modbuy = (price>modminsl && modbuysl>modstart && (pos_stop==0.0||modbuysl>pos_stop));
//--
if(modbuy && netp>minprofit)
{
modist=mc_trade.PositionModify(symbol,modbuysl,pos_tp);
}
}
if(opstype==POSITION_TYPE_SELL)
{
RefreshTick(symbol);
double price = mc_position.PriceCurrent();
double vtrss = mc_symbol.NormalizePrice(TSPrice(symbx,opstype,TRSP));
double pos_open = mc_position.PriceOpen();
double pos_stop = mc_position.StopLoss();
double pos_tp = mc_position.TakeProfit();
double pos_profit = mc_position.Profit();
double pos_swap = mc_position.Swap();
double pos_comm = mc_position.Commission();
double netp=pos_profit+pos_swap+pos_comm;
double modstart=mc_symbol.NormalizePrice(pos_open-TSmin*pip);
double modminsl=mc_symbol.NormalizePrice(vtrss-((TSmin+1.0)*pip));
double modselsl=vtrss;
bool modsel = (price<modminsl && modselsl<modstart && (pos_stop==0.0||modselsl<pos_stop));
//--
if(modsel && netp>minprofit)
{
modist=mc_trade.PositionModify(symbol,modselsl,pos_tp);
}
}
}
}
//--
return(modist);
//---
} //-end ModifyOrdersSL()
//---------//
bool MCEA::ModifyOrdersTP(const string symbx)
{
//---
ResetLastError();
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
bool modist=false;
int x=PairsIdxArray(symbx);
Pips(symbx);
//--
int total=PositionsTotal();
//--
for(int i=total-1; i>=0; i--)
{
string symbol=PositionGetSymbol(i);
if(symbol==symbx && mc_position.Magic()==magicEA)
{
ENUM_POSITION_TYPE opstype = mc_position.PositionType();
if(opstype==POSITION_TYPE_BUY)
{
RefreshTick(symbol);
double price = mc_position.PriceCurrent();
double pos_open = mc_position.PriceOpen();
double pos_stop = mc_position.StopLoss();
double pos_tp = mc_position.TakeProfit();
double modbuytp = pos_tp==0.0 ? mc_symbol.NormalizePrice(pos_open+TPmin*pip) : pos_tp;
double modpostp = mc_symbol.NormalizePrice(price+TPmin*pip);
bool modtpb = (price>pos_open && modbuytp-price<TPmin*pip && pos_tp<modpostp);
//--
if(modtpb)
{
modist=mc_trade.PositionModify(symbol,pos_stop,modpostp);
}
}
if(opstype==POSITION_TYPE_SELL)
{
RefreshTick(symbol);
double price = mc_position.PriceCurrent();
double pos_open = mc_position.PriceOpen();
double pos_stop = mc_position.StopLoss();
double pos_tp = mc_position.TakeProfit();
double modseltp = pos_tp==0.0 ? mc_symbol.NormalizePrice(pos_open-TPmin*pip) : pos_tp;
double modpostp = mc_symbol.NormalizePrice(price-TPmin*pip);
bool modtps = (price<pos_open && price-modseltp<TPmin*pip && pos_tp>modpostp);
//--
if(modtps)
{
modist=mc_trade.PositionModify(symbol,pos_stop,modpostp);
}
}
}
}
//--
return(modist);
//---
} //-end ModifyOrdersTP()
//---------//
void MCEA::SetSLTPOrders(void)
{
//---
ResetLastError();
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
double modbuysl=0;
double modselsl=0;
double modbuytp=0;
double modseltp=0;
string position_symbol;
int totalorder=PositionsTotal();
//--
for(int i=totalorder-1; i>=0; i--)
{
string symbol=PositionGetSymbol(i);
position_symbol=symbol;
if(mc_position.Magic()==magicEA)
{
ENUM_POSITION_TYPE opstype = mc_position.PositionType();
if(opstype==POSITION_TYPE_BUY)
{
Pips(symbol);
RefreshTick(symbol);
double price = mc_position.PriceCurrent();
double pos_open = mc_position.PriceOpen();
double pos_stop = mc_position.StopLoss();
double pos_take = mc_position.TakeProfit();
modbuysl=SetOrderSL(symbol,opstype,pos_open);
if(price<modbuysl) modbuysl=mc_symbol.NormalizePrice(price-slip*pip);
modbuytp=SetOrderTP(symbol,opstype,pos_open);
if(price>modbuytp) modbuytp=mc_symbol.NormalizePrice(price+slip*pip);
//--
if(pos_stop==0.0 || pos_take==0.0)
{
if(!mc_trade.PositionModify(position_symbol,modbuysl,modbuytp))
{
mc_trade.CheckResult(check);
Do_Alerts(symbol,"Set SL and TP for "+EnumToString(opstype)+" on "+symbol+" FAILED!!. Return code= "+
(string)mc_trade.ResultRetcode()+". Code description: ["+mc_trade.ResultRetcodeDescription()+"]");
}
}
}
if(opstype==POSITION_TYPE_SELL)
{
Pips(symbol);
RefreshTick(symbol);
double price = mc_position.PriceCurrent();
double pos_open = mc_position.PriceOpen();
double pos_stop = mc_position.StopLoss();
double pos_take = mc_position.TakeProfit();
modselsl=SetOrderSL(symbol,opstype,pos_open);
if(price>modselsl) modselsl=mc_symbol.NormalizePrice(price+slip*pip);
modseltp=SetOrderTP(symbol,opstype,pos_open);
if(price<modseltp) modseltp=mc_symbol.NormalizePrice(price-slip*pip);
//--
if(pos_stop==0.0 || pos_take==0.0)
{
if(!mc_trade.PositionModify(position_symbol,modselsl,modseltp))
{
mc_trade.CheckResult(check);
Do_Alerts(symbol,"Set SL and TP for "+EnumToString(opstype)+" on "+symbol+" FAILED!!. Return code= "+
(string)mc_trade.ResultRetcode()+". Code description: ["+mc_trade.ResultRetcodeDescription()+"]");
}
}
}
}
}
//--
return;
//---
} //-end SetSLTPOrders
//---------//
double MCEA::SetOrderSL(const string xsymb,ENUM_POSITION_TYPE type,double atprice)
{
//---
slv=0.0;
int x=PairsIdxArray(xsymb);
Pips(xsymb);
RefreshTick(xsymb);
//--
switch(type)
{
case (POSITION_TYPE_BUY):
{
slv=mc_symbol.NormalizePrice(atprice-SLval*pip);
//--
break;
}
case (POSITION_TYPE_SELL):
{
slv=mc_symbol.NormalizePrice(atprice+SLval*pip);
//--
break;
}
}
//---
return(slv);
//---
} //-end SetOrderSL()
//---------//
double MCEA::SetOrderTP(const string xsymb,ENUM_POSITION_TYPE type,double atprice)
{
//---
tpv=0.0;
int x=PairsIdxArray(xsymb);
Pips(xsymb);
RefreshTick(xsymb);
//--
switch(type)
{
case (POSITION_TYPE_BUY):
{
tpv=mc_symbol.NormalizePrice(atprice+TPval*pip);
//--
break;
}
case (POSITION_TYPE_SELL):
{
tpv=mc_symbol.NormalizePrice(atprice-TPval*pip);
}
}
//---
return(tpv);
//---
} //-end SetOrderTP()
//---------//
bool MCEA::CloseBuyPositions(const string symbol)
{
//---
//--
ResetLastError();
bool buyclose=false;
int total=PositionsTotal(); // number of open positions
ENUM_POSITION_TYPE closetype = POSITION_TYPE_BUY;
ENUM_ORDER_TYPE type_req = ORDER_TYPE_SELL;
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
int x=PairsIdxArray(symbol);
//--- iterate over all open positions
for(int i=total-1; i>=0; i--)
{
if(mc_position.SelectByIndex(i))
{
//--- Parameters of the order
string position_Symbol = PositionGetSymbol(i);
ulong position_ticket = PositionGetTicket(i);
ENUM_POSITION_TYPE type = mc_position.PositionType();
//--- if the MagicNumber matches
if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
{
//--
if(type==closetype)
{
RefreshTick(position_Symbol);
buyclose=mc_trade.PositionClose(position_Symbol,slip);
//--- output information about the closure
PrintFormat("Close Buy #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
if(buyclose) PbarB[x]=iTime(symbol,TFt,0);
}
}
}
}
//---
return(buyclose);
//----
} //-end CloseBuyPositions()
//---------//
bool MCEA::CloseSellPositions(const string symbol)
{
//---
ResetLastError();
bool sellclose=false;
int total=PositionsTotal(); // number of open positions
ENUM_POSITION_TYPE closetype = POSITION_TYPE_SELL;
ENUM_ORDER_TYPE type_req = ORDER_TYPE_BUY;
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
int x=PairsIdxArray(symbol);
//--- iterate over all open positions
for(int i=total-1; i>=0; i--)
{
if(mc_position.SelectByIndex(i))
{
//--- Parameters of the order
string position_Symbol = PositionGetSymbol(i);
ulong position_ticket = PositionGetTicket(i);
ENUM_POSITION_TYPE type = mc_position.PositionType();
//--- if the MagicNumber matches
if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
{
//--
if(type==closetype)
{
RefreshTick(position_Symbol);
sellclose=mc_trade.PositionClose(position_Symbol,slip);
//--- output information about the closure
PrintFormat("Close Sell #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
if(sellclose) PbarS[x]=iTime(symbol,TFt,0);
}
}
}
}
//---
return(sellclose);
//----
} //-end CloseSellPositions()
//---------//
bool MCEA::CloseAllLoss(void)
{
//----
ResetLastError();
//--
bool orclose=false;
string isloss="due stop in loss.";
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
int ttlorder=PositionsTotal(); // number of open positions
//--
for(int x=0; x<arrsymbx; x++)
{
string symbol=DIRI[x];
Pips(symbol);
double posloss=mc_symbol.NormalizePrice(SLval*pip);
orclose=false;
//--
for(int i=ttlorder-1; i>=0; i--)
{
string position_Symbol = PositionGetSymbol(i);
ENUM_POSITION_TYPE type = mc_position.PositionType();
if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
{
double price = mc_position.PriceCurrent();
double pos_open = mc_position.PriceOpen();
double posloss = mc_symbol.NormalizePrice(SLval*pip);
double pricegab = mc_symbol.NormalizePrice(fabs(price-pos_open));
ulong position_ticket = PositionGetTicket(i);
//---
if(type==POSITION_TYPE_BUY && pricegab>posloss)
{
RefreshTick(position_Symbol);
orclose = mc_trade.PositionClose(position_Symbol,slip);
//--- output information about the closure
PrintFormat("Close Buy %s %s %s",symbol,EnumToString(POSITION_TYPE_BUY),isloss);
}
if(type==POSITION_TYPE_SELL && pricegab>posloss)
{
RefreshTick(position_Symbol);
orclose = mc_trade.PositionClose(position_Symbol,slip);
//--- output information about the closure
PrintFormat("Close Sell %s %s %s",symbol,EnumToString(POSITION_TYPE_BUY),isloss);
}
}
}
}
//--
return(orclose);
//----
} //-end CloseAllLoss()
//---------//
bool MCEA::CloseAllProfit(void)
{
//----
ResetLastError();
//--
bool orclose=false;
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
int ttlorder=PositionsTotal(); // number of open positions
//--
for(int x=0; x<arrsymbx; x++)
{
string symbol=DIRI[x];
orclose=false;
//--
for(int i=ttlorder-1; i>=0; i--)
{
string position_Symbol = PositionGetSymbol(i);
ENUM_POSITION_TYPE type = mc_position.PositionType();
if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
{
double pos_profit = mc_position.Profit();
double pos_swap = mc_position.Swap();
double pos_comm = mc_position.Commission();
double cur_profit = NormalizeDouble(pos_profit+pos_swap+pos_comm,2);
ulong position_ticket = PositionGetTicket(i);
//---
if(type==POSITION_TYPE_BUY && cur_profit>minprofit)
{
RefreshTick(position_Symbol);
orclose = mc_trade.PositionClose(position_Symbol,slip);
//--- output information about the closure
PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
if(orclose) PbarB[x]=iTime(symbol,TFt,0);
}
if(type==POSITION_TYPE_SELL && cur_profit>minprofit)
{
RefreshTick(position_Symbol);
orclose = mc_trade.PositionClose(position_Symbol,slip);
//--- output information about the closure
PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
if(orclose) PbarS[x]=iTime(symbol,TFt,0);
}
}
}
}
//--
return(orclose);
//----
} //-end CloseAllProfit()
//---------//
bool MCEA::ManualCloseAllProfit(void)
{
//----
ResetLastError();
//--
bool orclose=false;
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
int ttlorder=PositionsTotal(); // number of open positions
//--
for(int x=0; x<arrsymbx; x++)
{
string symbol=DIRI[x];
orclose=false;
//--
for(int i=ttlorder-1; i>=0; i--)
{
string position_Symbol = PositionGetSymbol(i);
ENUM_POSITION_TYPE type = mc_position.PositionType();
if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
{
double pos_profit = mc_position.Profit();
double pos_swap = mc_position.Swap();
double pos_comm = mc_position.Commission();
double cur_profit = NormalizeDouble(pos_profit+pos_swap+pos_comm,2);
ulong position_ticket = PositionGetTicket(i);
//---
if(type==POSITION_TYPE_BUY && cur_profit>0.02)
{
RefreshTick(position_Symbol);
orclose = mc_trade.PositionClose(position_Symbol,slip);
//--- output information about the closure
PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
if(orclose) PbarB[x]=iTime(symbol,TFt,0);
}
if(type==POSITION_TYPE_SELL && cur_profit>0.02)
{
RefreshTick(position_Symbol);
orclose = mc_trade.PositionClose(position_Symbol,slip);
//--- output information about the closure
PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
if(orclose) PbarS[x]=iTime(symbol,TFt,0);
}
}
}
}
//--
return(orclose);
//----
} //-end ManualCloseAllProfit()
//---------//
bool MCEA::CheckProfit(const string symbol,ENUM_POSITION_TYPE intype)
{
//---
Pips(symbol);
double posprofit=mc_symbol.NormalizePrice((TPval*0.5)*pip);
bool inprofit=false;
//--
int ttlorder=PositionsTotal(); // number of open positions
//--
for(int x=0; x<arrsymbx; x++)
{
string symbol=DIRI[x];
//--
for(int i=ttlorder-1; i>=0; i--)
{
string position_Symbol = PositionGetSymbol(i);
ENUM_POSITION_TYPE type = mc_position.PositionType();
if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
{
double price = mc_position.PriceCurrent();
double pos_open = mc_position.PriceOpen();
double posprofit = mc_symbol.NormalizePrice((TPval*0.5)*pip);
double pricegab = mc_symbol.NormalizePrice(fabs(price-pos_open));
//---
if(type==intype && posprofit<pricegab) inprofit=true;
}
}
}
//--
return(inprofit);
//----
} //-end CheckProfit()
//---------//
bool MCEA::CheckLoss(const string symbol,ENUM_POSITION_TYPE intype,double slc=0.0)
{
//---
Pips(symbol);
bool inloss=false;
double lossval=slc==0.0 ? (SLval*0.5) : slc;
double posloss = mc_symbol.NormalizePrice(slc*pip);
int ttlorder=PositionsTotal(); // number of open positions
//--
for(int x=0; x<arrsymbx; x++)
{
string symbol=DIRI[x];
//--
for(int i=ttlorder-1; i>=0; i--)
{
string position_Symbol = PositionGetSymbol(i);
ENUM_POSITION_TYPE type = mc_position.PositionType();
if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
{
double price = mc_position.PriceCurrent();
double pos_open = mc_position.PriceOpen();
double posloss = mc_symbol.NormalizePrice(lossval*pip);
double pricegab = mc_symbol.NormalizePrice(fabs(price-pos_open));
//---
if(type==intype && pricegab>posloss) inloss=true;
}
}
}
//--
return(inloss);
//----
} //-end CheckLoss()
//---------//
bool MCEA::CheckProfitLoss(const string symbol)
{
//----
ResetLastError();
//--
bool closeinloss=false;
string isloss="due stop in loss.";
//--
int xx=PairsIdxArray(symbol);
//--
bool BuyProfitSellLoss=(xob[xx]>0 && CheckProfit(symbol,POSITION_TYPE_BUY)) && (xos[xx]>0 && CheckLoss(symbol,POSITION_TYPE_SELL,0.0));
bool SellProfitBuyLoss=(xos[xx]>0 && CheckProfit(symbol,POSITION_TYPE_SELL)) && (xob[xx]>0 && CheckLoss(symbol,POSITION_TYPE_BUY,0.0));
//--
if(BuyProfitSellLoss && !SellProfitBuyLoss)
{
if(CloseSellPositions(symbol))
{
PrintFormat("Close Sell %s %s %s",symbol,EnumToString(POSITION_TYPE_BUY),isloss);
closeinloss=true;
}
}
if(SellProfitBuyLoss && !BuyProfitSellLoss)
{
if(CloseBuyPositions(symbol))
{
PrintFormat("Close Buy %s %s %s",symbol,EnumToString(POSITION_TYPE_SELL),isloss);
closeinloss=true;
}
}
//--
return(closeinloss);
//----
} //-end CheckProfitLoss()
//---------//
void MCEA::CloseAllOrders(void) //-- function: close all order
{
//----
ResetLastError();
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
int total=PositionsTotal(); // number of open positions
//--- iterate over all open positions
for(int i=total-1; i>=0; i--)
{
//--- if the MagicNumber matches
if(mc_position.Magic()==magicEA)
{
//--
string position_Symbol = PositionGetSymbol(i); // symbol of the position
ulong position_ticket = PositionGetTicket(i); // ticket of the the opposite position
ENUM_POSITION_TYPE type = mc_position.PositionType();
RefreshTick(position_Symbol);
bool closepos = mc_trade.PositionClose(position_Symbol,slip);
if(closepos && type==POSITION_TYPE_BUY) PbarB[i]=iTime(position_Symbol,TFt,0);
if(closepos && type==POSITION_TYPE_SELL) PbarS[i]=iTime(position_Symbol,TFt,0);
//--- output information about the closure
PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
//---
}
}
//---
return;
//----
} //-end CloseAllOrders()
//---------//
void MCEA::CheckClose(const string symbx)
{
//---
//--
ResetLastError();
Pips(symbx);
//--
datetime to=TimeCurrent();
datetime from=to-(60);
closetime=TimeCurrent()-(3); // 3 seconds ago
//--- request the entire history
HistorySelect(from,to);
//--- total number in the list of deals
int deals=HistoryDealsTotal();
//--
datetime deal_time =0; // time of a deal execution
ulong deal_ticket =0; // deal ticket
long deal_magic =0; // deal magic number
long deal_type =0; // Order Type
double deal_price =0.0; // deal/order CLOSE price
double deal_profit =0.0; // deal profit
double deal_swap =0.0; // position swap
double deal_comm =0.0; // position commission
string deal_symbol =""; // symbol of the deal
ENUM_DEAL_ENTRY deal_entry =0; // enum deal entry
double profit_loss =0.0; // Order profit or loss
//--
//--- go through deals in a loop
for(int z=deals-1; z>=0 && !IsStopped(); z--)
{
deal_ticket = HistoryDealGetTicket(z);
deal_symbol = HistoryDealGetString(deal_ticket,DEAL_SYMBOL);
deal_magic = HistoryDealGetInteger(deal_ticket,DEAL_MAGIC);
deal_entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
deal_type = (ENUM_DEAL_TYPE)HistoryDealGetInteger(deal_ticket,DEAL_TYPE);
//--
if(deal_symbol==symbx && deal_magic==magicEA)
{
if((deal_entry==DEAL_ENTRY_OUT)||(deal_entry==DEAL_ENTRY_OUT_BY))
{
deal_time = (datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);
if((deal_time>0) && (deal_time>=closetime))
{
deal_price = HistoryDealGetDouble(deal_ticket,DEAL_PRICE);
deal_profit = HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);
deal_swap = HistoryDealGetDouble(deal_ticket,DEAL_SWAP);
deal_comm = HistoryDealGetDouble(deal_ticket,DEAL_COMMISSION);
profit_loss = NormalizeDouble(deal_profit+deal_swap+deal_comm,2);
string xtype = deal_type==DEAL_TYPE_BUY ? "SELL" : deal_type==DEAL_TYPE_SELL ? "BUY": "";
//--
if(profit_loss>0)
{
string ckclose="Close "+xtype+" Position on "+symbx+" at price : "+DoubleToString(deal_price,dgts)+
" OrderCloseTime(): "+TimeToString(deal_time,TIME_DATE|TIME_MINUTES)+
" in profit : "+DoubleToString(profit_loss,2);
Do_Alerts(symbx,ckclose);
}
if(profit_loss<=0)
{
string ckclose="Close "+xtype+" Position on "+symbx+" at price : "+DoubleToString(deal_price,dgts)+
" OrderCloseTime(): "+TimeToString(deal_time,TIME_DATE|TIME_MINUTES)+
" in loss : "+DoubleToString(profit_loss,2);
Do_Alerts(symbx,ckclose);
}
//--
break;
}
}
}
}
//---
return;
//----
} //-end CheckClose()
//---------//
void MCEA::TodayOrders(void)
{
//---
//--
ResetLastError();
//--
datetime from=StringToTime(ReqDate(ThisTime(day),0,0));
datetime to=TimeCurrent();
//--- request the entire history
HistorySelect(from,to);
//--- total number in the list of deals
int deals=HistoryDealsTotal();
//--
datetime deal_time =0; // time of a deal execution
ulong deal_ticket =0; // deal ticket
long deal_magic =0; // deal magic number
long deal_type =0; // Order Type
double deal_price =0.0; // deal/order CLOSE price
double deal_profit =0.0; // deal profit
double deal_swap =0.0; // position swap
double deal_comm =0.0; // position commission
ENUM_DEAL_ENTRY deal_entry =0; // enum deal entry
//--
string pos_symbol =""; // Position symbol
fixclprofit =0.0; // Order Close profit
floatprofit =0.0; // float position profit
oBm=0; // Order buy
oSm=0; // Order sell
//--
int totalorder=PositionsTotal();
//--
for(int i=0; i<totalorder && !IsStopped(); i++)
{
pos_symbol = PositionGetSymbol(i);
long magic = mc_position.Magic();
if(mc_position.Symbol() == pos_symbol && magic==magicEA)
{
//--
ENUM_POSITION_TYPE opstype = mc_position.PositionType();
if(opstype == POSITION_TYPE_BUY) {oBm++; floatprofit += mc_position.Profit();}
if(opstype == POSITION_TYPE_SELL) {oSm++; floatprofit += mc_position.Profit();}
//--
}
}
xtto=oBm+oSm;
//--
//--- go through deals in a loop
for(int z=0; z<deals && !IsStopped(); z++)
{
deal_ticket = HistoryDealGetTicket(z);
deal_magic = HistoryDealGetInteger(deal_ticket,DEAL_MAGIC);
deal_entry = (ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
deal_type = (ENUM_DEAL_TYPE)HistoryDealGetInteger(deal_ticket,DEAL_TYPE);
if(deal_magic==magicEA)
{
if((deal_entry==DEAL_ENTRY_OUT)||(deal_entry==DEAL_ENTRY_OUT_BY))
{
deal_time = (datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);
//--
if((deal_time>0) && (deal_time>=from))
{
deal_profit = HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);
deal_swap = HistoryDealGetDouble(deal_ticket,DEAL_SWAP);
deal_comm = HistoryDealGetDouble(deal_ticket,DEAL_COMMISSION);
//--
fixclprofit += NormalizeDouble(deal_profit+deal_swap+deal_comm,2);
}
}
}
}
//---
return;
//----
} //-end TodayOrders()
//---------//
double MCEA::MLots(const string symbx) // function: calculation lots size
{
//----
double Lsize=0.0;
double sym_Lm=0.0;
string sym_use ="";
int pil;
int Lpair;
int xsym=-1;
//--
string sCur1=StringSubstr(symbx,posCur1,3);
string sCur2=StringSubstr(symbx,posCur2,3);
//--
if(sCur1=="EUR"||sCur1=="GBP"||sCur1=="AUD"||sCur1=="NZD") pil=0;
if(sCur1=="CAD"||sCur1=="CHF") pil=1;
if(sCur1=="XAU"||sCur1=="XAG") pil=2;
if(sCur1=="USD") pil=3;
//--
switch(pil)
{
case 0: sym_use=sCur1+"USD"; break;
case 1: sym_use="USD"+sCur1; break;
case 2: sym_use=symbx; break;
case 3: sym_use=symbx; break;
}
//--
xsym=PairsIdxArray(sym_use);
if(xsym!=-1) sym_use=DIRI[xsym];
Lpair = StringFind(sym_use,"USD",0);
//--
CurrentSymbolSet(sym_use);
double csize = mc_symbol.ContractSize();
double AFMar = mc_account.FreeMargin();
double AFLev = (double)mc_account.Leverage();
double symbid = mc_symbol.Bid();
//--
double Lmaxs = SymbolInfoDouble(symbx,SYMBOL_VOLUME_MAX);
double Lmins = SymbolInfoDouble(symbx,SYMBOL_VOLUME_MIN);
//--
double useRisk = (Risk/100.0);
double PctUse = ((100.0-Risk)/100.0);
//--
double NZ1=NonZeroDiv(AFMar*AFLev,csize);
double NZ2=NonZeroDiv(AFMar*AFLev,symbid);
//--
if(Lpair>=0 && Lpair<posCur2) {sym_Lm = fmin(Lmaxs,NZ1);}
else {sym_Lm = fmin(Lmaxs,NonZeroDiv(NZ2,csize));}
//--
double sym_Lc = NormalizeDouble(sym_Lm*useRisk,LotDig(symbx));
double asize = NormalizeDouble(sym_Lc/(double)LotPS,LotDig(symbx));
//--
if(mmlot==DynamLot)
{
Lsize = NormalizeDouble(asize*PctUse,LotDig(symbx));
}
else {Lsize = Lots;}
//--
if(Lsize < Lmins) Lsize = Lmins;
if(Lsize > Lmaxs) Lsize = Lmaxs;
//--
double lotsize=NormalizeDouble(Lsize,LotDig(symbx));
//--
return(lotsize);
//----
} //-end MLots()
//---------//
int MCEA::LotDig(const string symbx)
{
//---
double lots_step=SymbolInfoDouble(symbx,SYMBOL_VOLUME_STEP);
//--
if(lots_step==0.01)
ldig=2;
//--
if(lots_step==0.1)
ldig=1;
//--
if(lots_step==1.0)
ldig=0;
//---
return(ldig);
//----
} //-end LotDig()
//---------//
double MCEA::NonZeroDiv(double val1,double val2)
{
//---
double resval=0;
if(val1==0 || val2==0) resval=0.00;
else
resval=val1/val2;
//--
return(resval);
//---
} //-end NonZeroDiv()
//---------//
bool MCEA::CheckEquityBalance(void)
{
//---
bool isgood=false;
if((mc_account.Equity()/mc_account.Balance()*100) > (100.00-Risk)) isgood=true;
//--
return(isgood);
//---
} //-end CheckEquityBalance()
//---------//
void MCEA::TradeInfo(void) // function: write comments on the chart
{
//----
Pips(Symbol());
double spread=SymbolInfoInteger(Symbol(),SYMBOL_SPREAD)/xpip;
rem=zntm-TimeCurrent();
string postime=PosTimeZone();
string eawait=" - Waiting for active time..!";
//--
string comm="";
TodayOrders();
//--
comm="\n :: Server Date Time : "+string(ThisTime(year))+"."+string(ThisTime(mon))+"."+string(ThisTime(day))+ " "+TimeToString(TimeCurrent(),TIME_SECONDS)+
"\n ------------------------------------------------------------"+
"\n :: Broker : "+ TerminalInfoString(TERMINAL_COMPANY)+
"\n :: Expert Name : "+ expname+
"\n :: Acc. Name : "+ mc_account.Name()+
"\n :: Acc. Number : "+ (string)mc_account.Login()+
"\n :: Acc. TradeMode : "+ AccountMode()+
"\n :: Acc. Leverage : 1 : "+ (string)mc_account.Leverage()+
"\n :: Acc. Equity : "+ DoubleToString(mc_account.Equity(),2)+
"\n :: Margin Mode : "+ (string)mc_account.MarginModeDescription()+
"\n :: Magic Number : "+ string(magicEA)+
"\n :: Trade on TF : "+ EnumToString(TFt)+
"\n :: Today Trading : "+ TradingDay()+" : "+hariini+
"\n :: Trading Session : "+ tz_ses+
"\n :: Trading Time : "+ postime;
if(TimeCurrent()<zntm)
{
comm=comm+
"\n :: Time Remaining : "+(string)ReqTime(rem,hour)+":"+(string)ReqTime(rem,min)+":"+(string)ReqTime(rem,sec) + eawait;
}
comm=comm+
"\n ------------------------------------------------------------"+
"\n :: Trading Pairs : "+pairs+
"\n :: BUY Market : "+string(oBm)+
"\n :: SELL Market : "+string(oSm)+
"\n :: Total Order : "+string(oBm+oSm)+
"\n :: Order Profit : "+DoubleToString(floatprofit,2)+
"\n :: Fixed Profit : "+DoubleToString(fixclprofit,2)+
"\n :: Float Money : "+DoubleToString(floatprofit,2)+
"\n :: Nett Profit : "+DoubleToString(floatprofit+fixclprofit,2);
//--
Comment(comm);
ChartRedraw(0);
return;
//----
} //-end TradeInfo()
//---------//
string MCEA::PosTimeZone(void)
{
//---
string tzpos="";
//--
if(ReqTime(zntm,day)>ThisTime(day))
{
tzpos=tz_opn+ " Next day to " +tz_cls + " Next day";
}
else
if(TimeCurrent()<znop)
{
if(ThisTime(day)==ReqTime(znop,day) && ThisTime(day)==ReqTime(zncl,day))
tzpos=tz_opn+" to " +tz_cls+ " Today";
//else
if(ThisTime(day)==ReqTime(znop,day) && ThisTime(day)<ReqTime(zncl,day))
tzpos=tz_opn+ " Today to " +tz_cls+ " Next day";
}
else
if(TimeCurrent()>=znop && TimeCurrent()<zncl)
{
if(ThisTime(day)<ReqTime(zncl,day))
tzpos=tz_opn+ " Today to " +tz_cls+ " Next day";
else
if(ThisTime(day)==ReqTime(zncl,day))
tzpos=tz_opn+" to " +tz_cls+ " Today";
}
else
if(ThisTime(day)==ReqTime(znop,day) && ThisTime(day)<ReqTime(zncl,day))
{
tzpos=tz_opn+" Today to " +tz_cls+ " Next day";
}
//--
return(tzpos);
//----
} //-end PosTimeZone()
//---------//
void MCEA::Set_Time_Zone(void)
{
//---
//-- Server Time==TimeCurrent()
datetime TTS=TimeTradeServer();
datetime GMT=TimeGMT();
//--
MqlDateTime svrtm,gmttm;
TimeToStruct(TTS,svrtm);
TimeToStruct(GMT,gmttm);
int svrhr=svrtm.hour; // Server time hour
int gmthr=gmttm.hour; // GMT time hour
int difhr=svrhr-gmthr; // Time difference Server time to GMT time
//--
int NZSGMT=12; // New Zealand Session GMT/UTC+12
int AUSGMT=10; // Australia Sydney Session GMT/UTC+10
int TOKGMT=9; // Asia Tokyo Session GMT/UTC+9
int EURGMT=0; // Europe London Session GMT/UTC 0
int USNGMT=-5; // US New York Session GMT/UTC-5
//--
int NZSStm=8; // New Zealand Session time start: 08:00 Local Time
int NZSCtm=17; // New Zealand Session time close: 17:00 Local Time
int AUSStm=7; // Australia Sydney Session time start: 07:00 Local Time
int AUSCtm=17; // Australia Sydney Session time close: 17:00 Local Time
int TOKStm=9; // Asia Tokyo Session time start: 09:00 Local Time
int TOKCtm=18; // Asia Tokyo Session time close: 18:00 Local Time
int EURStm=9; // Europe London Session time start: 09:00 Local Time
int EURCtm=19; // Europe London Session time close: 19:00 Local Time
int USNStm=8; // US New York Session time start: 08:00 Local Time
int USNCtm=17; // US New York Session time close: 17:00 Local Time
//--
int nzo = (NZSStm+difhr-NZSGMT)<0 ? 24+(NZSStm+difhr-NZSGMT) : (NZSStm+difhr-NZSGMT);
int nzc = (NZSCtm+difhr-NZSGMT)<0 ? 24+(NZSCtm+difhr-NZSGMT) : (NZSCtm+difhr-NZSGMT);
//--
int auo = (AUSStm+difhr-AUSGMT)<0 ? 24+(AUSStm+difhr-AUSGMT) : (AUSStm+difhr-AUSGMT);
int auc = (AUSCtm+difhr-AUSGMT)<0 ? 24+(AUSCtm+difhr-AUSGMT) : (AUSCtm+difhr-AUSGMT);
//--
int tko = (TOKStm+difhr-TOKGMT)<0 ? 24+(TOKStm+difhr-TOKGMT) : (TOKStm+difhr-TOKGMT);
int tkc = (TOKCtm+difhr-TOKGMT)<0 ? 24+(TOKCtm+difhr-TOKGMT) : (TOKCtm+difhr-TOKGMT);
//--
int euo = (EURStm+difhr-EURGMT)<0 ? 24+(EURStm+difhr-EURGMT) : (EURStm+difhr-EURGMT);
int euc = (EURCtm+difhr-EURGMT)<0 ? 24+(EURCtm+difhr-EURGMT) : (EURCtm+difhr-EURGMT);
//--
int uso = (USNStm+difhr-USNGMT)<0 ? 24+(USNStm+difhr-USNGMT) : (USNStm+difhr-USNGMT);
int usc = (USNCtm+difhr-USNGMT)<0 ? 24+(USNCtm+difhr-USNGMT) : (USNCtm+difhr-USNGMT);
if(usc==0||usc==24) usc=23;
//--
//---Trading on Custom Session
int _days00=ThisTime(day);
int _days10=ThisTime(day);
if(stsescuh>clsescuh) _days10=ThisTime(day)+1;
tmopcu=ReqDate(_days00,stsescuh,stsescum);
tmclcu=ReqDate(_days10,clsescuh,clsescum);
//--
//--Trading on New Zealand Session GMT/UTC+12
int _days01=ThisTime(hour)<nzc ? ThisTime(day)-1 : ThisTime(day);
int _days11=ThisTime(hour)<nzc ? ThisTime(day) : ThisTime(day)+1;
tmop01=ReqDate(_days01,nzo,0); // start: 08:00 Local Time == 20:00 GMT/UTC
tmcl01=ReqDate(_days11,nzc-1,59); // close: 17:00 Local Time == 05:00 GMT/UTC
//--
//--Trading on Australia Sydney Session GMT/UTC+10
int _days02=ThisTime(hour)<auc ? ThisTime(day)-1 : ThisTime(day);
int _days12=ThisTime(hour)<auc ? ThisTime(day) : ThisTime(day)+1;
tmop02=ReqDate(_days02,auo,0); // start: 07:00 Local Time == 21:00 GMT/UTC
tmcl02=ReqDate(_days12,auc-1,59); // close: 17:00 Local Time == 07:00 GMT/UTC
//--
//--Trading on Asia Tokyo Session GMT/UTC+9
int _days03=ThisTime(hour)<tkc ? ThisTime(day) : ThisTime(day)+1;
int _days13=ThisTime(hour)<tkc ? ThisTime(day) : ThisTime(day)+1;
tmop03=ReqDate(_days03,tko,0); // start: 09:00 Local Time == 00:00 GMT/UTC
tmcl03=ReqDate(_days13,tkc-1,59); // close: 18:00 Local Time == 09:00 GMT/UTC
//--
//--Trading on Europe London Session GMT/UTC 00:00
int _days04=ThisTime(hour)<euc ? ThisTime(day) : ThisTime(day)+1;
int _days14=ThisTime(hour)<euc ? ThisTime(day) : ThisTime(day)+1;
tmop04=ReqDate(_days04,euo,0); // start: 09:00 Local Time == 09:00 GMT/UTC
tmcl04=ReqDate(_days14,euc-1,59); // close: 19:00 Local Time == 19:00 GMT/UTC
//--
//--Trading on US New York Session GMT/UTC-5
int _days05=ThisTime(hour)<usc ? ThisTime(day) : ThisTime(day)+1;
int _days15=ThisTime(hour)<=usc ? ThisTime(day) : ThisTime(day)+1;
tmop05=ReqDate(_days05,uso,0); // start: 08:00 Local Time == 13:00 GMT/UTC
tmcl05=ReqDate(_days15,usc,59); // close: 17:00 Local Time == 22:00 GMT/UTC
//--
//--Not Use Trading Time Zone
if(trd_time_zone==No)
{
tmopno=ReqDate(ThisTime(day),0,15);
tmclno=ReqDate(ThisTime(day),23,59);
}
//--
Time_Zone();
//--
return;
//---
} //-end Set_Time_Zone()
//---------//
void MCEA::Time_Zone(void)
{
//---
//--
tz_ses="";
//--
switch(session)
{
case Cus_Session:
{
SesCuOp=StringToTime(tmopcu);
SesCuCl=StringToTime(tmclcu);
zntm=SesCuOp;
znop=SesCuOp;
zncl=SesCuCl;
tz_ses="Custom_Session";
tz_opn=timehr(stsescuh,stsescum);
tz_cls=timehr(clsescuh,clsescum);
break;
}
case New_Zealand:
{
Ses01Op=StringToTime(tmop01);
Ses01Cl=StringToTime(tmcl01);
zntm=Ses01Op;
znop=Ses01Op;
zncl=Ses01Cl;
tz_ses="New_Zealand/Oceania";
tz_opn=timehr(ReqTime(Ses01Op,hour),ReqTime(Ses01Op,min));
tz_cls=timehr(ReqTime(Ses01Cl,hour),ReqTime(Ses01Cl,min));
break;
}
case Australia:
{
Ses02Op=StringToTime(tmop02);
Ses02Cl=StringToTime(tmcl02);
zntm=Ses02Op;
znop=Ses02Op;
zncl=Ses02Cl;
tz_ses="Australia Sydney";
tz_opn=timehr(ReqTime(Ses02Op,hour),ReqTime(Ses02Op,min));
tz_cls=timehr(ReqTime(Ses02Cl,hour),ReqTime(Ses02Cl,min));
break;
}
case Asia_Tokyo:
{
Ses03Op=StringToTime(tmop03);
Ses03Cl=StringToTime(tmcl03);
zntm=Ses03Op;
znop=Ses03Op;
zncl=Ses03Cl;
tz_ses="Asia/Tokyo";
tz_opn=timehr(ReqTime(Ses03Op,hour),ReqTime(Ses03Op,min));
tz_cls=timehr(ReqTime(Ses03Cl,hour),ReqTime(Ses03Cl,min));
break;
}
case Europe_London:
{
Ses04Op=StringToTime(tmop04);
Ses04Cl=StringToTime(tmcl04);
zntm=Ses04Op;
znop=Ses04Op;
zncl=Ses04Cl;
tz_ses="Europe/London";
tz_opn=timehr(ReqTime(Ses04Op,hour),ReqTime(Ses04Op,min));
tz_cls=timehr(ReqTime(Ses04Cl,hour),ReqTime(Ses04Cl,min));
break;
}
case US_New_York:
{
Ses05Op=StringToTime(tmop05);
Ses05Cl=StringToTime(tmcl05);
zntm=Ses05Op;
znop=Ses05Op;
zncl=Ses05Cl;
tz_ses="US/New_York";
tz_opn=timehr(ReqTime(Ses05Op,hour),ReqTime(Ses05Op,min));
tz_cls=timehr(ReqTime(Ses05Cl,hour),ReqTime(Ses05Cl,min));
break;
}
}
//--
if(trd_time_zone==No)
{
SesNoOp=StringToTime(tmopno);
SesNoCl=StringToTime(tmclno);
zntm=SesNoOp;
znop=SesNoOp;
zncl=SesNoCl;
tz_ses="Not Use Time Zone";
tz_opn=timehr(ReqTime(SesNoOp,hour),ReqTime(SesNoOp,min));
tz_cls=timehr(ReqTime(SesNoCl,hour),ReqTime(SesNoCl,min));
}
//--
return;
//---
} //-end Time_Zone()
//---------//
bool MCEA::Trade_session(void)
{
//---
bool trd_ses=false;
ishour=ThisTime(hour);
if(ishour!=onhour) Set_Time_Zone();
datetime tcurr=TimeCurrent(); // Server Time
//--
switch(session)
{
case Cus_Session:
{
if(tcurr>=SesCuOp && tcurr<=SesCuCl) trd_ses=true;
break;
}
case New_Zealand:
{
if(tcurr>=Ses01Op && tcurr<=Ses01Cl) trd_ses=true;
break;
}
case Australia:
{
if(tcurr>=Ses02Op && tcurr<=Ses02Cl) trd_ses=true;
break;
}
case Asia_Tokyo:
{
if(tcurr>=Ses03Op && tcurr<=Ses03Cl) trd_ses=true;
break;
}
case Europe_London:
{
if(tcurr>=Ses04Op && tcurr<=Ses04Cl) trd_ses=true;
break;
}
case US_New_York:
{
if(tcurr>=Ses05Op && tcurr<=Ses05Cl) trd_ses=true;
break;
}
}
//--
if(trd_time_zone==No)
{
if(tcurr>=SesNoOp && tcurr<=SesNoCl) trd_ses=true;
}
//--
onhour=ishour;
//--
return(trd_ses);
//---
} //-end Trade_session()
//---------//
string MCEA::TradingDay(void)
{
//---
int trdday=ThisTime(dow);
switch(trdday)
{
case 0: daytrade="Sunday"; break;
case 1: daytrade="Monday"; break;
case 2: daytrade="Tuesday"; break;
case 3: daytrade="Wednesday"; break;
case 4: daytrade="Thursday"; break;
case 5: daytrade="Friday"; break;
case 6: daytrade="Saturday"; break;
}
return(daytrade);
//---
} //-end TradingDay()
//---------//
string MCEA::timehr(int hr,int mn)
{
//---
string scon="";
string men=mn==0 ? "00" : string(mn);
int shr=hr==24 ? 0 : hr;
if(shr<10) scon="0"+string(shr)+":"+men;
else scon=string(shr)+":"+men;
//--
return(scon);
//---
} //-end timehr()
//---------//
bool MCEA::TradingToday(void)
{
//---
bool tradetoday=false;
int trdday=ThisTime(dow);
hariini="No";
//--
int ttd[];
ArrayResize(ttd,7);
ttd[0]=ttd0;
ttd[1]=ttd1;
ttd[2]=ttd2;
ttd[3]=ttd3;
ttd[4]=ttd4;
ttd[5]=ttd5;
ttd[6]=ttd6;
//--
if(ttd[trdday]==Yes) {tradetoday=true; hariini="Yes";}
//--
return(tradetoday);
//---
} //-end TradingToday()
//---------//
string MCEA::ReqDate(int d,int h,int m)
{
//---
MqlDateTime mdt;
datetime t=TimeCurrent(mdt);
x_year=mdt.year;
x_mon=mdt.mon;
x_day=d;
x_hour=h;
x_min=m;
x_sec=mdt.sec;
//--
string mdr=string(x_year)+"."+string(x_mon)+"."+string(x_day)+" "+timehr(x_hour,x_min);
return(mdr);
//---
} //-end ReqDate()
//---------//
int MCEA::ThisTime(const int reqmode)
{
//---
MqlDateTime tm;
TimeCurrent(tm);
int valtm=0;
//--
switch(reqmode)
{
case 0: valtm=tm.year; break; // Return Year
case 1: valtm=tm.mon; break; // Return Month
case 2: valtm=tm.day; break; // Return Day
case 3: valtm=tm.hour; break; // Return Hour
case 4: valtm=tm.min; break; // Return Minutes
case 5: valtm=tm.sec; break; // Return Seconds
case 6: valtm=tm.day_of_week; break; // Return Day of week (0-Sunday, 1-Monday, ... ,6-Saturday)
case 7: valtm=tm.day_of_year; break; // Return Day number of the year (January 1st is assigned the number value of zero)
}
//--
return(valtm);
//---
} //-end ThisTime()
//---------//
int MCEA::ReqTime(datetime reqtime,
const int reqmode)
{
MqlDateTime tm;
TimeToStruct(reqtime,tm);
int valtm=0;
//--
switch(reqmode)
{
case 0: valtm=tm.year; break; // Return Year
case 1: valtm=tm.mon; break; // Return Month
case 2: valtm=tm.day; break; // Return Day
case 3: valtm=tm.hour; break; // Return Hour
case 4: valtm=tm.min; break; // Return Minutes
case 5: valtm=tm.sec; break; // Return Seconds
case 6: valtm=tm.day_of_week; break; // Return Day of week (0-Sunday, 1-Monday, ... ,6-Saturday)
case 7: valtm=tm.day_of_year; break; // Return Day number of the year (January 1st is assigned the number value of zero)
}
//--
return(valtm);
//---
} //-end ReqTime()
//---------//
string MCEA::AccountMode() // function: to known account trade mode
{
//----
//--- Demo, Contest or Real account
ENUM_ACCOUNT_TRADE_MODE account_type=(ENUM_ACCOUNT_TRADE_MODE)AccountInfoInteger(ACCOUNT_TRADE_MODE);
//---
trade_mode="";
//--
switch(account_type)
{
case ACCOUNT_TRADE_MODE_DEMO:
trade_mode="Demo";
break;
case ACCOUNT_TRADE_MODE_CONTEST:
trade_mode="Contest";
break;
default:
trade_mode="Real";
break;
}
//--
return(trade_mode);
//----
} //-end AccountMode()
//---------//
void MCEA::Do_Alerts(const string symbol,string msgText)
{
//---
//--
Print("--- "+symbol+": "+msgText+
"\n--- at: ",TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES));
//--
if(alerts==Yes)
{
Alert("--- "+symbol+": "+msgText+
"--- at: ",TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES));
}
//--
if(UseEmailAlert==Yes)
SendMail(expname,"--- "+symbol+" "+TF2Str(PERIOD_CURRENT)+": "+msgText+
"\n--- at: "+TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES));
//--
if(UseSendnotify==Yes)
SendNotification(expname+"--- "+symbol+" "+TF2Str(PERIOD_CURRENT)+": "+msgText+
"\n--- at: "+TimeToString(iTime(symbol,0,0),TIME_DATE|TIME_MINUTES));
//--
return;
//--
//---
} //-end Do_Alerts()
//---------//
string MCEA::TF2Str(ENUM_TIMEFRAMES period)
{
//---
switch(period)
{
//--
case PERIOD_M1: return("M1");
case PERIOD_M2: return("M2");
case PERIOD_M3: return("M3");
case PERIOD_M4: return("M4");
case PERIOD_M5: return("M5");
case PERIOD_M6: return("M6");
case PERIOD_M10: return("M10");
case PERIOD_M12: return("M12");
case PERIOD_M15: return("M15");
case PERIOD_M20: return("M20");
case PERIOD_M30: return("M30");
case PERIOD_H1: return("H1");
case PERIOD_H2: return("H2");
case PERIOD_H3: return("H3");
case PERIOD_H4: return("H4");
case PERIOD_H6: return("H6");
case PERIOD_H8: return("H8");
case PERIOD_H12: return("H12");
case PERIOD_D1: return("D1");
case PERIOD_W1: return("W1");
case PERIOD_MN1: return("MN1");
//--
}
return(string(period));
//---
} //-end TF2Str()
//---------//
string MCEA::getUninitReasonText(int reasonCode)
{
//---
string text="";
//---
switch(reasonCode)
{
case REASON_PROGRAM:
text="The EA has stopped working calling by remove function."; break;
case REASON_REMOVE:
text="Program "+__FILE__+" was removed from chart"; break;
case REASON_RECOMPILE:
text="Program recompiled."; break;
case REASON_CHARTCHANGE:
text="Symbol or timeframe was changed"; break;
case REASON_CHARTCLOSE:
text="Chart was closed"; break;
case REASON_PARAMETERS:
text="Input-parameter was changed"; break;
case REASON_ACCOUNT:
text="Account was changed"; break;
case REASON_TEMPLATE:
text="New template was applied to chart"; break;
case REASON_INITFAILED:
text="The OnInit() handler returned a non-zero value."; break;
case REASON_CLOSE:
text="Terminal closed."; break;
default: text="Another reason"; break;
}
//--
return text;
//---
} //-end getUninitReasonText()
//---------//
//+------------------------------------------------------------------+
//| ChartEvent function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//---
//--- handling CHARTEVENT_CLICK event ("Clicking the chart")
ResetLastError();
//--
ENUM_TIMEFRAMES CCS=Period();
//--
if(id==CHARTEVENT_OBJECT_CLICK)
{
int lensymbol=StringLen(Symbol());
int lensparam=StringLen(sparam);
//--
//--- if "Set SL All Orders" button is click
if(sparam=="Set SL/TP All Orders")
{
mc.SetSLTPOrders();
Alert("-- "+mc.expname+" -- ",Symbol()," -- Set SL/TP All Orders");
//--- unpress the button
ObjectSetInteger(0,"Set SL/TP All Orders",OBJPROP_STATE,false);
ObjectSetInteger(0,"Set SL/TP All Orders",OBJPROP_ZORDER,0);
CreateManualPanel();
}
//--- if "Close All Order" button is click
if(sparam=="Close All Order")
{
mc.CloseAllOrders();
Alert("-- "+mc.expname+" -- ",Symbol()," -- Close All Orders");
//--- unpress the button
ObjectSetInteger(0,"Close All Order",OBJPROP_STATE,false);
ObjectSetInteger(0,"Close All Order",OBJPROP_ZORDER,0);
CreateManualPanel();
}
//--- if "Close All Profit" button is click
if(sparam=="Close All Profit")
{
mc.ManualCloseAllProfit();
Alert("-- "+mc.expname+" -- ",Symbol()," -- Close All Profit");
//--- unpress the button
ObjectSetInteger(0,"Close All Profit",OBJPROP_STATE,false);
ObjectSetInteger(0,"Close All Profit",OBJPROP_ZORDER,0);
CreateManualPanel();
}
//--- if "X" button is click
if(sparam=="X")
{
ObjectsDeleteAll(0,0,OBJ_BUTTON);
ObjectsDeleteAll(0,0,OBJ_LABEL);
ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL);
//--- unpress the button
ObjectSetInteger(0,"X",OBJPROP_STATE,false);
ObjectSetInteger(0,"X",OBJPROP_ZORDER,0);
//--
DeleteButtonX();
mc.PanelExtra=false;
DisplayManualButton();
}
//--- if "M" button is click
if(sparam=="M")
{
//--- unpress the button
ObjectSetInteger(0,"M",OBJPROP_STATE,false);
ObjectSetInteger(0,"M",OBJPROP_ZORDER,0);
mc.PanelExtra=true;
CreateManualPanel();
}
//--- if "C" button is click
if(sparam=="C")
{
//--- unpress the button
ObjectSetInteger(0,"C",OBJPROP_STATE,false);
ObjectSetInteger(0,"C",OBJPROP_ZORDER,0);
mc.PanelExtra=true;
CreateSymbolPanel();
}
//--- if "R" button is click
if(sparam=="R")
{
Alert("-- "+mc.expname+" -- ",Symbol()," -- expert advisor will be Remove from the chart.");
ExpertRemove();
//--- unpress the button
ObjectSetInteger(0,"R",OBJPROP_STATE,false);
ObjectSetInteger(0,"R",OBJPROP_ZORDER,0);
if(!ChartSetSymbolPeriod(0,Symbol(),Period()))
ChartSetSymbolPeriod(0,Symbol(),Period());
DeletePanelButton();
ChartRedraw(0);
}
//--- if Symbol button is click
if(lensparam==lensymbol)
{
int sx=mc.PairsIdxArray(sparam);
ChangeChartSymbol(mc.AS30[sx],CCS);
mc.PanelExtra=false;
}
//--
}
//--
return;
//---
} //-end OnChartEvent()
//---------//
void ChangeChartSymbol(string c_symbol,ENUM_TIMEFRAMES cstf)
{
//---
//--- unpress the button
ObjectSetInteger(0,c_symbol,OBJPROP_STATE,false);
ObjectSetInteger(0,c_symbol,OBJPROP_ZORDER,0);
ObjectsDeleteAll(0,0,OBJ_BUTTON);
ObjectsDeleteAll(0,0,OBJ_LABEL);
ObjectsDeleteAll(0,0,OBJ_RECTANGLE_LABEL);
//--
ChartSetSymbolPeriod(0,c_symbol,cstf);
//--
ChartRedraw(0);
//--
return;
//---
} //-end ChangeChartSymbol()
//---------//
int WS(int width) // Width Scaling factor wide button
{
//---
int res=0;
int reswidth=0;
//--- Calculating the scaling factor wide button on a screen
int scale_factor=(TerminalInfoInteger(TERMINAL_SCREEN_DPI));
//--- Use of the scaling factor
reswidth=(width * scale_factor) / 96;
double res1=NormalizeDouble(reswidth*1.25,0);
res=int(res1);
//--
return(res);
//---
} //-end WS()
//---------//
void CreateManualPanel()
{
//---
//--
CreateButtonTemplate(0,"TemplateSL",160,35,STYLE_SOLID,5,BORDER_RAISED,clrNONE,clrBurlyWood,clrWhite,CORNER_RIGHT_UPPER,170,45,true);
CreateButtonTemplate(0,"TempStatSL",154,30,STYLE_SOLID,3,BORDER_RAISED,clrNONE,clrGreen,clrWhite,CORNER_RIGHT_UPPER,167,48,true);
CreateButtonClick(0,"Set SL/TP All Orders",143,21,"Bodoni MT Black",10,BORDER_RAISED,"Set SL/TP All Orders",clrNONE,clrRed,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,162,56,true,"Set SL/TP All Orders");
//--
CreateButtonTemplate(0,"TemplateS",160,35,STYLE_SOLID,5,BORDER_RAISED,clrNONE,clrBurlyWood,clrWhite,CORNER_RIGHT_UPPER,170,77,true);
CreateButtonTemplate(0,"TempStats",154,30,STYLE_SOLID,3,BORDER_RAISED,clrNONE,clrGreen,clrWhite,CORNER_RIGHT_UPPER,167,79,true);
CreateButtonClick(0,"Close All Order",143,21,"Bodoni MT Black",10,BORDER_RAISED,"Close All Order",clrNONE,clrRed,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,162,88,true,"Close All Order");
//--
CreateButtonTemplate(0,"TemplateC",160,35,STYLE_SOLID,5,BORDER_RAISED,clrNONE,clrBurlyWood,clrWhite,CORNER_RIGHT_UPPER,170,109,true);
CreateButtonTemplate(0,"TempStatC",154,30,STYLE_SOLID,3,BORDER_RAISED,clrNONE,clrGreen,clrWhite,CORNER_RIGHT_UPPER,167,111,true);
CreateButtonClick(0,"Close All Profit",143,21,"Bodoni MT Black",10,BORDER_RAISED,"Close All Profit",clrNONE,clrRed,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,162,120,true,"Close All Profit");
//--
DeletePanelButton();
CreateButtonClick(0,"X",17,15,"Arial Black",12,BORDER_RAISED,"X",clrNONE,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,27,31,true,"Close panel");
//--
ChartRedraw(0);
//--
return;
//---
} //-end CreateManualPanel()
//---------//
void DisplayManualButton(void)
{
//--
DeleteButtonX();
CreateButtonClick(0,"M",17,16,"Arial Black",11,BORDER_FLAT,"M",clrWhite,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,61,21,true,"Open Manual Panel");
CreateButtonClick(0,"C",17,16,"Arial Black",11,BORDER_FLAT,"C",clrWhite,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,41,21,true,"Change Chart Symbol");
CreateButtonClick(0,"R",17,16,"Arial Black",11,BORDER_FLAT,"R",clrWhite,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,21,21,true,"Expert Remove");
ChartRedraw(0);
//--
return;
//--
} //-end DisplayManualButton()
//---------//
bool DisplayManualButton(string a,string b,string c)
{
//--
if(ObjectFind(0,a)<0 && ObjectFind(0,b)<0 && ObjectFind(0,c)<0 && !mc.PanelExtra)
return(false);
return(true);
//--
} //-end DisplayManualButton()
//---------//
void DeleteButtonX(void)
{
//--
ObjectDelete(0,"X");
//--
ChartRedraw(0);
//--
return;
//--
} //-end DeleteButtonX()
//---------//
void DeletePanelButton(void)
{
//--
ObjectDelete(0,"M");
ObjectDelete(0,"C");
ObjectDelete(0,"R");
//--
return;
//--
} //-end DeletePanelButton()
//---------//
void CreateSymbolPanel()
{
//---
//--
ResetLastError();
DeletePanelButton();
int sydis=83;
int tsatu=int(mc.sall/2);
//--
CreateButtonTemplate(0,"Template",180,367,STYLE_SOLID,5,BORDER_RAISED,clrYellow,clrBurlyWood,clrWhite,CORNER_RIGHT_UPPER,187,45,true);
CreateButtonTemplate(0,"TempCCS",167,25,STYLE_SOLID,5,BORDER_RAISED,clrYellow,clrBlue,clrWhite,CORNER_RIGHT_UPPER,181,50,true);
CreateButtonClick(0,"X",14,14,"Arial Black",10,BORDER_FLAT,"X",clrWhite,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,22,48,true,"Close Symbol Panel");
//--
string chsym="Change SYMBOL";
int cspos=int(181/2)+int(StringLen(chsym)/2);
CreateButtontLable(0,"CCS","Bodoni MT Black",chsym,11,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,cspos,62,true,"Change Chart Symbol");
//--
for(int i=0; i<tsatu; i++)
CreateButtonClick(0,mc.AS30[i],80,17,"Bodoni MT Black",8,BORDER_RAISED,mc.AS30[i],clrYellow,clrBlue,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,180,sydis+(i*22),true,"Change to "+mc.AS30[i]);
//--
for(int i=tsatu; i<mc.sall; i++)
CreateButtonClick(0,mc.AS30[i],80,17,"Bodoni MT Black",8,BORDER_RAISED,mc.AS30[i],clrYellow,clrBlue,clrWhite,ANCHOR_CENTER,CORNER_RIGHT_UPPER,94,sydis+((i-15)*22),true,"Change to "+mc.AS30[i]);
//--
ChartRedraw(0);
//--
return;
//---
} //-end CreateSymbolPanel()
//---------//
void CreateButtonClick(long chartid,
string button_name,
int button_x_size,
int button_y_size,
string button_font_model,
int button_font_size,
int button_border,
string button_name_text,
color button_bord_color,
color button_bg_color,
color button_color,
int button_anchor,
int button_corner,
int button_xdist,
int button_ydist,
bool button_hidden,
string tooltip)
{
//---
ObjectCreate(chartid,button_name,OBJ_BUTTON,0,0,0); // create button
ObjectSetInteger(chartid,button_name,OBJPROP_XSIZE,WS(button_x_size));
ObjectSetInteger(chartid,button_name,OBJPROP_YSIZE,button_y_size);
ObjectSetString(chartid,button_name,OBJPROP_TEXT,button_name_text);
ObjectSetString(chartid,button_name,OBJPROP_FONT,button_font_model);
ObjectSetInteger(chartid,button_name,OBJPROP_FONTSIZE,button_font_size);
ObjectSetInteger(chartid,button_name,OBJPROP_BORDER_TYPE,button_border);
ObjectSetInteger(chartid,button_name,OBJPROP_BORDER_COLOR,button_bord_color);
ObjectSetInteger(chartid,button_name,OBJPROP_BGCOLOR,button_bg_color);
ObjectSetInteger(chartid,button_name,OBJPROP_COLOR,button_color);
ObjectSetInteger(chartid,button_name,OBJPROP_ANCHOR,button_anchor);
ObjectSetInteger(chartid,button_name,OBJPROP_CORNER,button_corner);
ObjectSetInteger(chartid,button_name,OBJPROP_XDISTANCE,WS(button_xdist));
ObjectSetInteger(chartid,button_name,OBJPROP_YDISTANCE,button_ydist);
ObjectSetInteger(chartid,button_name,OBJPROP_HIDDEN,button_hidden);
ObjectSetString(chartid,button_name,OBJPROP_TOOLTIP,tooltip);
ChartRedraw(0);
//--
return;
//---
} //-end CreateButtonClick()
//---------//
void CreateButtonTemplate(long chartid,
string obj_name,
int x_size,
int y_size,
int style,
int width,
int border,
color bordcolor,
color bgcolor,
color objcolor,
int corner,
int x_dist,
int y_dist,
bool hidden)
{
//---
ObjectCreate(chartid,obj_name,OBJ_RECTANGLE_LABEL,0,0,0); // create Rectangle Label
ObjectSetInteger(chartid,obj_name,OBJPROP_XSIZE,WS(x_size));
ObjectSetInteger(chartid,obj_name,OBJPROP_YSIZE,y_size);
ObjectSetInteger(chartid,obj_name,OBJPROP_STYLE,style);
ObjectSetInteger(chartid,obj_name,OBJPROP_WIDTH,width);
ObjectSetInteger(chartid,obj_name,OBJPROP_BORDER_TYPE,border);
ObjectSetInteger(chartid,obj_name,OBJPROP_BORDER_COLOR,bordcolor);
ObjectSetInteger(chartid,obj_name,OBJPROP_BGCOLOR,bgcolor);
ObjectSetInteger(chartid,obj_name,OBJPROP_COLOR,objcolor);
ObjectSetInteger(chartid,obj_name,OBJPROP_CORNER,corner);
ObjectSetInteger(chartid,obj_name,OBJPROP_XDISTANCE,WS(x_dist));
ObjectSetInteger(chartid,obj_name,OBJPROP_YDISTANCE,y_dist);
ObjectSetInteger(chartid,obj_name,OBJPROP_HIDDEN,hidden);
ChartRedraw(0);
//--
return;
//---
} //-end CreateButtonTemplate()
//---------//
void CreateButtontLable(long chartid,
string lable_name,
string lable_font_model,
string lable_obj_text,
int lable_font_size,
color lable_color,
int lable_anchor,
int lable_corner,
int lable_xdist,
int lable_ydist,
bool lable_hidden,
string tooltip)
{
//---
ObjectDelete(chartid,lable_name);
ObjectCreate(chartid,lable_name,OBJ_LABEL,0,0,0,0,0); // create Lable
ObjectSetInteger(chartid,lable_name,OBJPROP_FONTSIZE,lable_font_size);
ObjectSetString(chartid,lable_name,OBJPROP_FONT,lable_font_model);
ObjectSetString(chartid,lable_name,OBJPROP_TEXT,lable_obj_text);
ObjectSetInteger(chartid,lable_name,OBJPROP_COLOR,lable_color);
ObjectSetInteger(chartid,lable_name,OBJPROP_ANCHOR,lable_anchor);
ObjectSetInteger(chartid,lable_name,OBJPROP_CORNER,lable_corner);
ObjectSetInteger(chartid,lable_name,OBJPROP_XDISTANCE,WS(lable_xdist));
ObjectSetInteger(chartid,lable_name,OBJPROP_YDISTANCE,lable_ydist);
ObjectSetInteger(chartid,lable_name,OBJPROP_HIDDEN,lable_hidden);
ObjectSetString(chartid,lable_name,OBJPROP_TOOLTIP,tooltip);
ChartRedraw(0);
//--
return;
//---
} //-end CreateButtontLable()
//---------//
//--------------------------------------------------------------------//
***Copyright © 2026 3rjfx ~ For educational purposes only.***

No comments :
Post a Comment
Leave A Comment...