Introduction
The Expert Advisor discussed in this article is a multi-currency trading robot that uses the Zigzag and RSI indicators. It follows a strategy of opening Buy trades when the price dips below the RSI oversold line and Sell trades when the price rises above the RSI overbought line. It also includes pending limit orders and a lot size multiplier Martingale system.
The multi-currency Expert Advisor is a trading robot capable of executing trades (opening, closing, and managing orders, including Trailing Stop Loss and Trailing Profit) for multiple currency pairs on a single chart. In this article, the Expert Advisor will trade 30 pairs.
This article will explore a strategy that combines the Zigzag and RSI indicators. Buy trades will be initiated when the price dips below the RSI oversold line, and Sell trades will be opened when the price rises above the RSI overbought line. Additionally, pending limit orders will be employed.
To mitigate potential losses, a lot size multiplier with a staged Martingale system will be utilized. For each market order opened, the Expert Advisor will open a maximum of 4pending limit orders, progressively increasing the lot size with each subsequent order.
1. Trading Currency Pairs
The Multi-Currency Expert Advisor is designed to trade the following 30 pairs:
For Forex:
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 = 28 pairs
Plus 2 Metal pairs: XAUUSD (Gold) and XAGUSD (Silver)
Total is 30 pairs.
To ensure compatibility with various MetaTrader 5 brokers and their specific symbol naming conventions, the Expert Advisor employs a function that automatically manages symbol names with prefixes and/or suffixes. This allows for seamless operation regardless of any broker-specific symbol variations.
2.1. Single and Multi-Currency Expert Advisor
Single Currency Mode allows the Expert Advisor to focus on trading a single currency pair, providing a more targeted and potentially less complex trading strategy.
By selecting this mode, the trader can choose a specific pair from the list of available pairs and configure the Expert Advisor's parameters to optimize performance for that particular pair.
This approach can be beneficial for traders who prefer to specialize in a few specific pairs or who want to minimize the risk associated with trading multiple pairs simultaneously.
In the Select Trading Pairs Mode (Multi or Single) options, there are 2 options which in this option trader can choose trading pair conditions, whether to trade on single-currency or trade on multi-currency:
- 1. Single Pair (single-currency)
- 2. Multi Pairs (multi-currency)
The Expert Input Parameters need to be set as shown in the following figure.
1. Single Pair Mode
When the "Single Pair" option is selected, the Expert Advisor will be restricted to trading solely on the specific currency pair where it is attached. For example, if the EA is placed on the EURUSD chart, it will exclusively trade the EURUSD pair.
This mode is ideal for traders who want to focus on a particular pair and fine-tune the EA's settings to optimize performance for that specific market.
2. Multi-Pair Mode
When the "Multi-Pair" option is selected, the Expert Advisor will trade a maximum of 10 currency pairs simultaneously, chosen from the predefined list of 30 pairs.
Trader's Choice:
The ten predefined pairs: The Expert Advisor can be configured to trade a fixed set of 10 pairs from the list. Custom Pair Selection: Alternatively, traders can manually input up to 10 desired pairs in the Expert Advisor's input parameters. These pairs must be selected from the 30 available pairs. This mode is suitable for traders who want to diversify their trading across multiple pairs while still maintaining a manageable level of risk. By carefully selecting the pairs to trade, traders can potentially increase their overall profitability.
Trader's Wishes Pairs:
The "Trader's Wishes Pairs" option provides flexibility to focus the Expert Advisor on a specific currency pair or operate independently. By manually entering the desired pair name (e.g., "XAUUSD"), the EA will prioritize trading that particular pair, disregarding the other 29 pairs. This allows for tailored trading strategies and risk management.
2.2. Trade on Specific Time
The "Trade on Specific Time" feature allows traders to align their trading activities with specific time zones. This is particularly useful for traders who want to focus on particular trading sessions, such as the London, New York, or Tokyo sessions.
By enabling this feature, the Expert Advisor can be configured to trade only during specific time frames, potentially reducing exposure to market volatility during less active periods.
No Specific Time:
If "Trade on Specific Time Zone" is set to "No," the Expert Advisor will trade 24/5, from 00:15 to 23:59, based on the MT5 server time.
Specific Time Zones:
If "Trade on Specific Time Zone" is set to "Yes," the trader can select from the following options:
Custom Session:
- Traders can specify custom start and end times for the trading session.
- The EA will only execute trades within this specified time.
Predefined Sessions:
- New Zealand Session: Trades during New Zealand trading hours.
- Australia Sydney Session: Trades during Australian trading hours.
- Asia Tokyo Session: Trades during Asian trading hours.
- Europe London Session: Trades during European trading hours.
- America New York Session: Trades during US trading hours.
Trading Session Duration Calculation:
For trades initiated during the New Zealand to New York session, the Expert Advisor calculates the duration of the trade, which can be useful for various trading strategies and analysis.
2.3. Martingale system
The Expert Advisor employs a staged Martingale system to manage risk and potentially increase profits. Here's how it works:
- Initial Trade: When a trading signal is identified, the EA opens an initial market order (either a Buy or Sell).
- Pending Limit Orders: Simultaneously, the EA places up to 4 pending limit orders in the same direction as the initial market order. These limit orders are placed at progressively wider price levels.
- Lot Size Multiplier: Each subsequent pending limit order has a larger lot size than the previous one. This lot size increase is calculated using a predefined multiplier factor.
- Martingale Principle: The goal of this strategy is to recover potential losses from previous trades by increasing the position size of subsequent trades. If the initial market order and the first few pending orders result in losses, the larger subsequent orders have a higher chance of recouping those losses.
Important Considerations:
- 1. Risk Management: While the Martingale system can be effective in certain market conditions, it's essential to use it with caution. It's a high-risk strategy that can lead to significant losses if a series of consecutive losing trades occurs.
- 2. Account Balance: It's crucial to have sufficient funds in your trading account to cover potential losses from multiple consecutive losing trades.
- 3. Market Conditions: The Martingale system may not be suitable for all market conditions. It's important to consider market volatility and trends when using this strategy.
- 4. Proper Risk Management: It's recommended to use appropriate stop-loss and take-profit orders to limit potential losses and secure profits.
- 5. Remember: Martingale strategies are inherently risky, and it's essential to conduct thorough back testing and risk assessment before using them in live trading.
Note:
Because this expert advisor will open multiple orders, by default we set the lot size when opening market order with a minimum lot size of 0.01.
This note indicates that the Expert Advisor will use a minimum lot size of 0.01 for the initial market order. This is a common practice to minimize risk and avoid excessive exposure to market volatility.
This note indicates that the Expert Advisor will use a minimum lot size of 0.01 for the initial market order. This is a common practice to minimize risk and avoid excessive exposure to market volatility.
The subsequent pending limit orders will have larger lot sizes, determined by the Martingale system. This means that as the number of open orders increases, the potential risk also increases.
It's important to note that while the Martingale system can potentially increase profits, it also carries significant risks. It's crucial to use this strategy with caution and to have a solid understanding of risk management principles.
2.4. Expiration Time for Pending Orders.
The Expert Advisor offers flexibility in setting expiration times for pending orders. This feature allows traders to control the duration of open positions and limit potential risk.
Here are the available expiration time options:
- No Expiration: Pending orders will remain open indefinitely until manually closed or triggered by a market event.
Time-Based Expiration: Pending orders will expire after a specific time period, which can be set to:
- H1: 1 hour
- H4: 4 hours
- H8: 8 hours
- H12: 12 hours
- D1: 1 day
- D5: 5 days
The SetPOExpiry() function is responsible for calculating and setting the expiration time for pending orders based on the selected time frame and the current symbol. The function determines whether a specified expiration time or a daily expiration is more appropriate and sets the expiration time accordingly.
By using this feature, traders can implement risk management strategies and avoid potential losses from unforeseen market events or prolonged periods of adverse price movements.
The IsExpirationTypeAllowed() function is a crucial component of the Expert Advisor, as it ensures that the expiration time settings are compatible with the specific symbol being traded.
Function Purpose:
- Symbol Compatibility: The function checks if the desired expiration type (e.g., H1, H4, D1) is allowed for the current symbol.
- Expiration Mode: Different symbols may have different expiration mode settings, such as allowing only specific expiration types or no expiration at all.
- Validating Settings: The function helps to prevent invalid settings and ensures that the Expert Advisor operates correctly.
How it Works:
- Retrieves Expiration Mode: The function obtains the current symbol's expiration mode setting.
- Compares Expiration Types: It compares the specified expiration type with the allowed expiration modes for the symbol.
- Returns Result: If the specified expiration type is allowed, the function returns true; otherwise, it returns false.
By using this function, the Expert Advisor can dynamically adjust its behavior based on the specific symbol being traded, ensuring that the expiration time settings are appropriate and effective.
2.5. Check Free Margin from Equity to Trade (in Percent)
The GoodMarginTrade() function is a crucial component of the Expert Advisor's risk management system. It ensures that there is sufficient free margin in the trading account to open a new trade.
How it Works:
- Calculates Required Margin: The function calculates the required margin for the proposed trade, taking into account factors like the lot size, leverage, and current market price.
- Checks Available Margin: It compares the calculated required margin with the available free margin in the trading account.
- Margin Check: If there is enough free margin, the function returns true, allowing the trade to proceed. If there is insufficient free margin, the function returns false and generates an alert message to notify the trader.
- Default Margin Equity Setting: By default, the Expert Advisor is set to use a maximum of 80% of the account's equity for trading. This helps to maintain a healthy risk-reward ratio and avoid excessive risk exposure.
- Margin Checks at Key Points: The GoodMarginTrade() function is called before opening both market orders and pending limit orders. This ensures that there is sufficient margin available at the time of order placement, reducing the risk of margin calls and account liquidation.
By implementing this robust margin check, the Expert Advisor helps to protect the trader's account balance and maintain a disciplined trading approach.
2.6. Check Maximum Pair's Spread to Trade.
The CheckSpread() function is another essential component of the Expert Advisor's risk management system. It ensures that the spread for a particular trading pair is within acceptable limits.
- Retrieves Spread: The function retrieves the current spread for the specified symbol.
- Compares to Maximum Spread: It compares the retrieved spread to the maximum allowed spread, which is typically set to 9 pips or 90 points.
- Spread Check: If the spread is within the limit, the function returns true, allowing the trade to proceed. If the spread exceeds the limit, the function returns false and generates an alert message to notify the trader.
Why Check Spread?
- 1. Trading Costs: A high spread can significantly impact profitability, especially for short-term trading strategies.
- 2. Market Conditions: Wide spreads often occur during periods of high volatility or low liquidity.
- 3. Risk Management: By avoiding trades with excessive spreads, traders can reduce the risk of adverse price movements.
By implementing this spread check, the Expert Advisor helps to filter out unfavorable trading opportunities and improve overall trading performance.
3.1. Zigzag Indicator.
Understanding the Zigzag Indicator.
The Zigzag indicator is a valuable tool for technical analysis, helping traders identify significant price swings and potential trend reversals. By filtering out minor price fluctuations, it provides a clearer view of the underlying trend.
How the Zigzag Indicator Works?
- 1. Identifying Extrema: The indicator identifies significant highs and lows in the price chart.
- 2. Connecting the Dots: It connects these extreme points with straight lines, creating a series of peaks and troughs.
- 3. Filtering Noise: By focusing on these major price swings, the Zigzag indicator reduces the impact of noise and random price fluctuations.
Key Benefits of the Zigzag Indicator:
- Trend Identification: It helps to identify the overall trend direction, whether it's uptrend, downtrend, or sideways.
- Potential Reversal Points: It can signal potential trend reversals by forming distinct tops and bottoms.
- Clear Price Structure: It simplifies the complex price chart, making it easier to analyze.
Limitations of the Zigzag Indicator:
- Lag: The Zigzag indicator can lag behind price movements, especially in fast-moving markets.
- Subjectivity: The indicator's parameters (Depth, Deviation, and Backstep) can influence its sensitivity and accuracy.
- False Signals: In choppy markets, the Zigzag indicator may generate false signals, leading to incorrect trading decisions.
Optimizing Zigzag Indicator Settings.
The three primary parameters of the Zigzag indicator are:
- Depth: with default value 12. This setting determines the minimum number of bars required to form a new extreme point. A higher Depth value can filter out more noise but may also introduce more lag.
- Deviation: with default value 5. This setting defines the percentage price change required to identify a new extreme point. A higher Deviation value can make the indicator less sensitive to minor price fluctuations.
- Backstep: with default value 3. This setting specifies the minimum number of bars between two consecutive extreme points. The minimal number of bars between swing highs and lows. A higher Backstep value can reduce the frequency of false signals but may also delay the identification of trend changes.
In conclusion, the Zigzag indicator is a useful tool for technical analysis, but it's essential to use it in conjunction with other indicators and confirmation signals to make informed trading decisions. By understanding its strengths and limitations, traders can effectively leverage this indicator to improve their trading strategies.
The Zigzag indicator formula is a bit more complex than the simplified explanation provided earlier. It involves a recursive calculation to identify significant price swings.
Here's a breakdown of the Zigzag indicator formula:
- Zigzag (HL, %change=X, retrace=FALSE, LastExtreme=TRUE)
- If %change>=X,plot ZigZag
- where: HL = High-Low price series or Closing price series
- %change = Minimum price movement, in percentage
- Retrace = Is change a retracement of the previous move or an absolute change from peak to trough?
- Last Extreme = If the extreme price is the same over multiple periods, is the extreme price the first or last observation?
- A Boolean value indicating whether to consider the last extreme point in the calculation.
Calculation:
Initial Extreme Point: The first extreme point is identified based on the initial price data. Subsequent Extreme Points for each subsequent price bar:
- Calculate the price difference between the current bar's high/low and the previous extreme point.
- If the price difference exceeds the specified percentage change (%change), a new extreme point is identified.
- If the retracement option (retrace) is enabled, the indicator will consider potential retracements and adjust the extreme point accordingly.
- The LastExtreme option determines whether the last identified extreme point is considered in the calculation.
Visualization:
The Zigzag indicator plots a series of line segments connecting these significant high and low points. The resulting chart pattern can help identify trends, potential reversals, and support and resistance levels.
Important Note:
While the formula provides a mathematical basis for the Zigzag indicator, the actual implementation in trading platforms may involve additional optimizations and adjustments to improve performance and accuracy.
3.2. The Relative Strength Index (RSI) Indicator
Understanding the RSI.
The Relative Strength Index (RSI) was developed by J. Welles Wilder and first introduced in his 1978 book, "New Concepts in Technical Trading Systems," as well as in the June 1978 issue of Commodities magazine (now Modern Trader magazine). Over time, it has emerged as one of the most widely used oscillator indices.
The Relative Strength Index (RSI) is a momentum oscillator that measures the speed and change of price movements. It oscillates between 0 and 100.
The RSI is a technical indicator employed in financial market analysis to assess the current and historical strength or weakness of a stock or market based on recent closing prices. It operates as a price-following oscillator that fluctuates between 0 and 100. Initially, Wilder recommended using a 14-period RSI, but variations such as the 9-period and 25-period RSI have also gained popularity since then.
- Overbought: When the RSI is above 70, it suggests the asset is overbought, and a potential price decline may occur.
- Oversold: When the RSI is below 30, it suggests the asset is oversold, and a potential price increase may occur.
Furthermore, in the technical analysis MQL5 it is stated that the RSI signal is used for chart analysis:
- Tops and Bottoms
- Chart Formations
- Failure Swing (Support or Resistance breakout)
- Support and Resistance levels
- Divergences
Combining RSI with Zigzag for Trading Signals.
In this article we will use the RSI indicator signal Tops and Bottoms combined with the Zigzag indicator, with period 7 bars and High levels (overbought) 76.0 and Low levels (oversold) 24.0.
By combining the RSI with the Zigzag indicator, we can create a powerful trading strategy:
- 1. Identifying Trend Direction: Use the Zigzag indicator to determine the overall trend direction.
- 2. Generating Buy Signals:
- RSI Oversold: When the RSI falls below 24.0, indicating an oversold condition.
- Zigzag Bottom: The Zigzag indicator forms a bottom, suggesting a potential reversal to the upside.
- 3. Generating Sell Signals:
- RSI Overbought: When the RSI rises above 76.0, indicating an overbought condition.
- Zigzag Top: The Zigzag indicator forms a top, suggesting a potential reversal to the downside.
Additional Considerations:
- Divergences:
- Bullish Divergence: The price makes a lower low, but the RSI forms a higher low. This suggests potential buying opportunity.
- Bearish Divergence: The price makes a higher high, but the RSI forms a lower high. This suggests potential selling opportunity.
- Time Frame: The choice of timeframe can significantly impact the effectiveness of the strategy. Shorter timeframes can be used for day trading, while longer timeframes can be used for swing trading or position trading.
- Risk Management: Always use stop-loss and take-profit orders to manage risk.
- Backtesting: Backtest your strategy on historical data to evaluate its performance and optimize parameters.
Remember:
While this combination of indicators can be a powerful tool, it's essential to use it in conjunction with other technical analysis tools and fundamental analysis to make informed trading decisions.
3.3. The Strategy.
- Strategy Overview.
- The strategy implemented by the Expert Advisor involves a combination of RSI and Zigzag indicators to identify potential entry points.
- Buy Signal:
- RSI Oversold: The RSI dips below the oversold level (24.0).
- Zigzag Bottom: The Zigzag indicator forms a bottom, suggesting a potential uptrend.
- Sell Signal:
- RSI Overbought: The RSI rises above the overbought level (76.0).
- Zigzag Top: The Zigzag indicator forms a top, suggesting a potential downtrend.
The strategy employed with the Expert Advisors in this article involves opening Buy positions below the RSI oversold line and Sell positions above the RSI overbought line. This strategy includes additional pending limit orders and a lot size multiplier using the Martingale system to help mitigate losses.
It is important to note that the most recent Zigzag line may not remain fixed, as it may repaint when the price changes direction. Similarly, the Tops and Bottom RSI indicator may not always accurately indicate overbought conditions when the RSI line is above 76.0 or oversold conditions when the RSI line is below 24.0.
To address ongoing price movements in either direction, we implement a strategy involving the placement of Buy Limit pending orders for upward price trends and Sell Limit pending orders for downward price trends.
If an Expert Advisor initiates a Buy market order and the price subsequently declines, the Buy market order in curs a loss. Similarly, if a Sell market order is executed by the Expert Advisor and the price continues to increase, the Sell market order experiences a loss.
As mentioned earlier, to mitigate larger losses, we implement a lot size multiplier with the Martingale system in stages for each open limit pending order. For every market order opened, the Expert Advisor will also open a maximum of 4 limit pending orders.
Additionally, we configure an option to determine whether the triggering of a pending limit order will result in the closure of the previous market order that is already at a loss. By default, the setting is configured to close market orders in a loss condition if the pending limit order is triggered.
In the meantime, we have configured an option to determine whether triggered limit pending orders will result in the closure of previous market orders that are already in a loss condition. By default, the setting is configured to close market orders in a loss condition if the pending limit order is triggered.
Risk Management:
- Pending Limit Orders: To mitigate potential losses, the Expert Advisor places pending limit orders in the direction of the expected trend.
- Martingale System: A lot size multiplier is used to increase position size after consecutive losses, aiming to recover losses with larger profits.
Important Considerations:
- Market Dynamics: The effectiveness of this strategy can vary depending on market conditions. It may perform better in trending markets and less effectively in range-bound markets.
- Indicator Lag: Both the RSI and Zigzag indicators can lag behind price movements, which may lead to delayed entry or exit signals.
- Risk Management: It's crucial to implement robust risk management techniques, such as stop-loss and take-profit orders, to limit potential losses.
- Back testing: Thorough back testing is essential to evaluate the strategy's historical performance and optimize its parameters.
Note:
The dynamic nature of the market and the potential for indicator repainting highlights the importance of careful monitoring and adjustments to the strategy. It's recommended to use this strategy in conjunction with other technical analysis tools and fundamental analysis to make informed trading decisions.
3.4. Martingale System and Loss Mitigation.
The Expert Advisor incorporates a Martingale system to manage risk and potential losses. This involves increasing the position size of subsequent trades to recover previous losses.
Key Points:
- Limit Pending Orders: The EA opens up to 4 pending limit orders for each market order, with increasing lot sizes.
- Loss Mitigation: The EA is configured to close existing losing market orders when a pending limit order is triggered. This helps to limit potential losses from multiple consecutive losing trades.
- Martingale Risk: While the Martingale system can be effective in certain market conditions, it's important to use it with caution. It's a high-risk strategy that can lead to significant losses if a series of consecutive losing trades occurs.
Important Considerations:
- Risk Management: Implement robust risk management techniques, such as stop-loss and take-profit orders, to limit potential losses.
- Account Balance: Ensure that your trading account has sufficient funds to cover potential losses from multiple consecutive losing trades.
- Market Conditions: The Martingale system may not be suitable for all market conditions. It's essential to consider market volatility and trends when using this strategy.
- Psychological Impact: The Martingale system can be emotionally draining, as it requires disciplined adherence to the strategy, even during periods of consecutive losses.
- Remember: It's crucial to conduct thorough back testing and risk assessment before using the Martingale system in live trading. Always be aware of the inherent risks and adjust your strategy accordingly.
Lastly, the image below illustrates the signal generated by the Zigzag indicator in conjunction with the RSI indicator when the Expert Advisor is about to open a market order for the first time.
By understanding the interplay between the Zigzag and RSI indicators, you can make informed trading decisions and potentially improve your trading outcomes.
4.1. The Challenge of Multi-Currency Trading
The Challenge of Multi-Currency Trading.
When dealing with a multi-currency Expert Advisor that trades multiple pairs on a single chart, managing and monitoring individual pair performance can be cumbersome.
The Solution: A Dedicated Button Panel.
A well-designed button panel can significantly enhance the trading experience. By providing quick access to different chart symbols and timeframes, traders can:
- Monitor Individual Pair Performance: Easily switch between charts to assess the accuracy of entry and exit signals.
- React to Market Changes: Quickly identify opportunities and risks in specific pairs.
- Optimize Trading Strategies: Fine-tune strategies based on real-time market data.
Key Features of an Effective Button Panel:
- Symbol Selection: A dropdown menu or a list of buttons to quickly switch between different currency pairs.
- Timeframe Selection: Options to adjust the timeframe for each symbol, allowing for different time-frame analysis.
- Chart Navigation: Buttons to navigate between charts.
- Order Management: A clear overview of open and closed orders, including profit and loss information on that currency.
4.2. Manual Order Management.
Several manual buttons have been incorporated into this multi-currency expert advisor to enhance efficiency and effectiveness for traders in monitoring the advisor's operations.
- 4.2.1. Set SL / TP All Orders
- This button is beneficial if the trader has initially set the parameters to Use Order Stop Loss (No)and/or Use Order Take Profit (No), but later decides to apply Stop Loss or Take Profit to all orders. By clicking the "Set SL / TP All Orders" button, all orders will be adjusted, and a Stop Loss and/or Take Profit will be implemented across the board.
- 4.2.2. Close All Orders
- If a trader wants to close all orders, they can simply click on the "Close All Orders" button to close all open orders.
- 4.2.3. Close All Orders Profit
- If a trader wishes to close all orders that are currently profitable, they can click on the "Close All Orders Profit" button to close all open orders that have generated profit.
4.3. Managing Orders and Chart Symbols.
For multi-currency expert advisors that trade 30 pairs using only one chart symbol, having a button panel for all symbols would be highly beneficial and convenient. This feature would allow traders to switch between chart timeframes or symbols with a single click, enabling them to quickly assess the accuracy of the indicator signal when the expert advisor opens or closes an order.
4.4. Expert Timeframe, Pair Selection, and Symbol Management
- Expert Timeframe.
- The Expert Timeframe setting determines the timeframe on which the Expert Advisor will calculate indicators and generate trading signals. By default, it's set to PERIOD_H1, meaning the EA will analyze hourly data.
- Adjusting this setting can influence the sensitivity of the strategy to market movements. A shorter timeframe, like PERIOD_M15 or PERIOD_M30, can lead to more frequent signals, while a longer timeframe, like PERIOD_H4 or PERIOD_D1, can produce fewer, but potentially more reliable signals.
- Pair Selection.
- The Select Pairs to Trade property allows traders to choose from a predefined list of currency pairs. The default option is typically to trade all 30 pairs, but traders can customize this selection based on their preferences and risk tolerance.
- Symbol Management with HandlingSymbolArrays()
- The HandlingSymbolArrays() function plays a crucial role in managing the symbols that the Expert Advisor will trade.
- It performs the following tasks:
- Symbol Initialization: Initializes an array to store the selected symbols.
- Symbol Filtering: Filters the selected symbols based on market conditions or other criteria.
- Symbol Validation: Ensures that the selected symbols are valid and supported by the trading platform.
- Symbol Assignment: Assigns the selected symbols to the Expert Advisor's internal variables.
- By effectively managing symbols, the EA can optimize its performance and reduce the risk of errors.
- Validating Pair Names and Error Handling.
- The Expert Advisor's ability to validate pair names is a critical feature to ensure smooth operation and prevent potential errors.
- Here's a breakdown of how this process might work:
- User Input: The trader enters a list of desired pairs in the Expert Advisor's input parameters.
- Symbol Check: The EA iterates through each pair name and checks its validity
- Symbol Existence: The EA verifies if the specified symbol exists in the trading platform's symbol list.
- Symbol Format: The EA ensures that the symbol adheres to the correct format (e.g., EURUSD, GBPUSD, XAUUSD).
- Error Handling:
- If a symbol is invalid, the EA generates a warning message in the journal or displays an alert to the trader and the EA will removed from the chart.
- By incorporating robust symbol validation and error handling, the Expert Advisor can maintain its reliability and prevent unexpected issues.
- Trade Info.
- In the "Other Expert Advisor Parameters" group of input properties, traders can choose whether to display trading information on the chart by selecting either "Yes" or "No". If the option "Yes" is chosen, trade information will be shown on the chart where the Expert Advisor is applied by using the TradeInfo() function. Additionally, we have included a function within the TradeInfo() function to provide a description of the time based on the trading time zone conditions.
- The TradeInfo() function that displays various trading-related information on the chart. It includes details such asserver date and time, broker information, account details, trading parameters, current trading pairs, order statistics, and profit information.
- Within the TradeInfo() function, there is a call to the TodayOrders() function. The TodayOrders() function is responsible for fetching and analyzing trading data for the current day. It computes the overall count of deals, orders, positions, and their categories (buy/sell). It also determines the total count of active market and pending orders. Furthermore, it calculates the cumulative profit by factoring in profits from deals, swaps, and commissions.
In order to enhance the effectiveness and efficiency of using Multi-Currency Expert Advisors, it is advisable to create one or more manual buttons for managing orders and changing chart timeframes or symbols. The OnChartEvent() function that handles various events on a trading chart. It checks for different button clicks on the chart and performs corresponding actions such as setting stop loss/take profit, closing orders, removing expert advisor, changing symbol, and creating manual panels.
The interface of the Multi-Currency Expert Advisor Zigzag RSI MCEA is depicted in the figure below.
There are buttons labeled "M", "C", and "R" under the Expert Advisor named ZigZag_RSI_MCEA.
When the M button is clicked, a panel of manual clicking buttons will be displayed as shown below.
The trader can manually manage orders when the manual click button panel is displayed:
- 5.1. Set SL/TP All Orders
- Set Stop Loss/Take Profit for All Orders: If the trader has set the parameters to not use stop loss or take profit for individual orders but later decides to apply stop loss or take profit to all orders, they can do so by clicking the "Set SL/TP All Orders" button. This action will modify all orders accordingly.
- The SetSLTPOrders() function it iterates through all open positions with a specific magic number, sets stop loss and take profit levels based on current price and position open price, and modifies the position if stop loss or take profit levels are not set.
- 5.2. Close All Orders
- If the trader wants to close all orders, they can do so by clicking the "Close All Orders" button. The CloseAllOrders() function that closes all open positions and orders. It iterates through all positions and orders, closes positions with a specific magic number, and deletes pending orders of specific types.
- 5.3. Close All Profits
- If a trader wants to close all orders that are currently profitable, they can do so by clicking the "Close All Profits" button.
- The ManualCloseAllProfit() function it iterates through open positions with a specific magic number, calculates the total profit including swap and commission, and closes positions with a profit greater than 0.02.
Moreover, when the C button is clicked, a panel displaying 30 symbol names or pairs will appear, allowing traders to select one by clicking on it.
The function code for creating a panel with 30 pairs of symbols is as follows. The CreateSymbolPanel() function it creates a symbol panel with buttons to change the chart symbol. The function sets button styles, labels, positions, and actions for each symbol in the panel. Finally, it redraws the chart.
Clicking on a pair or symbol name will promptly change the chart symbol to the selected one. In this scenario, the OnChartEvent() function will call the ChangeChartSymbol() function when one of the symbol names is clicked.
//+------------------------------------------------------------------+
//| 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=mc.TFt;
//--
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.ValidatePairs(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()
//---------//
This code snippet checks if a chart object click event (CHARTEVENT_OBJECT_CLICK) has occurred. It compares the lengths of the current symbol and the parameter "sparam". If the lengths match, it validates the symbol and changes the chart symbol to the validated symbol from the arrays predefined list "mc.AS30".
The ChangeChartSymbol() function it un-presses the button associated with the symbol, deletes all objects related to buttons, labels, and rectangles, changes the chart symbol and timeframe, redraws the chart.
Lastly, clicking on the R button will remove the Multi-Currency Expert Advisor ZigZag_RSI_MCEA from the chart, eliminating the need for traders to manually remove the experts.
This code snippet checks if a chart object click event (CHARTEVENT_OBJECT_CLICK) has occurred. If the parameter "sparam" is equal to "R", it displays an alert message, removes the expert advisor from the chart, un-presses the "R" button, resets its z-order, sets the chart symbol and period back to the original values, deletes panel buttons, and redraws the chart.
6. Strategy Tester
The advantage of MetaTrader5 Strategy Tester is that it supports and enables us to test strategies that can tradeon multiple currencies symbols, test automated trading for all available currencies symbols, and across allavailable timeframes.
Therefore, on the MetaTrader5 Strategy Tester platform, we will test the ZigZag_RSI_MCEA Multi-Currency ExpertAdvisor on a single pair (single currency) as well as on multiple pairs (multi-currency).
Because this expert advisor will open multiple orders, by default we set the lot size when opening a market orderwith a minimum lot size of 0.01.
First, we will test the MetaTrader5 Strategy Tester in single pair mode using the EURUSD pair on the H1 timeframe from January 1, 2024, to April 13, 2024.
The results are as shown in the images below:
Our second test involves using multiple pairs in the PairsTrade option, specifically using Forex USD Pairs (9 pairs)which include USDCAD, USDCHF, USDJPY, AUDUSD, EURUSD, GBPUSD, NZDUSD, XAUUSD, and XAGUSD.
The results are as shown in the images below:
Key Parameters to Monitor:
- Net Profit: The overall profit or loss generated during the testing period.
- Profit Factor: The ratio of gross profit to gross loss.
- Drawdown: The maximum peak-to-trough decline in equity.
- Sharpe Ratio: A measure of risk-adjusted return.
- Recovery Factor: The ratio of gross profit to maximum drawdown.
Interpreting the Results:
- Positive Net Profit: Indicates a profitable strategy during the testing period.
- High Profit Factor: Suggests that the strategy generates significant profits relative to losses.
- Low Drawdown: Implies that the strategy minimizes risk and avoids large drawdowns.
- High Sharpe Ratio: Indicates a strong risk-adjusted return.
- High Recovery Factor: Shows the strategy's ability to recover from losses.
Multi-Pair Testing.
Key Considerations for Multi-Pair Testing:
- Correlation: Consider the correlation between different pairs to avoid overexposure to specific market movements.
- Diversification: Diversifying across multiple pairs can help reduce overall risk.
- Risk Management: Implement robust risk management strategies, such as position sizing and stop-loss orders, to manage risk effectively.
- Monitoring and Adjustment: Continuously monitor the performance of the strategy and make necessary adjustments to adapt to changing market conditions.
By carefully testing the ZigZag_RSI_MCEA strategy on both single-pair and multi-pair setups, you can gain valuable insights into its performance and identify potential areas for improvement.
The conclusion of creating a Multi-Currency Expert Advisor with signals from the Zigzag indicator in conjunction with the RSI indicator for forex trading using MQL5 is as follows:
- 1. Creating a multi-currency Expert Advisor in MQL5 is straightforward and not significantly different from creating a single-currency Expert Advisor.
- 2. Creating a Multi-Currency Expert Advisor will enhance traders' efficiency and effectiveness by eliminating the need to open multiple chart symbols for trading.
- 3. Applying the right trading strategy will increase the probability of profit compared to using a single-currency Expert Advisor. This is because losses in one pair will be covered by profits in other pairs.
- 4. The Zigzag_RSI_MCEA Multi-Currency Expert Advisor is provided as a sample for learning and idea generation. The test results on the Strategy Tester have not been satisfactory. Therefore, it is possible to improve the strategy and achieve more profitable results by experimenting with different timeframes, indicator period calculations, and signal selections.
- 5. Further research should be conducted on the Multi-Currency Expert Advisor that utilizes signals from the Zigzag indicator and the RSI indicator for forex trading. This research should include exploring the "limit pending order" strategy and the lot size multiplier. Various experiments should be carried out, starting from analyzing different timeframes to adjusting the differentiation value of the Zigzag indicator input parameters.
- 6. Applying the lot size multiplier with the Martingale system, when done wisely, carefully, and based on the right indicator signals rather than speculation, can effectively reduce losses and potentially increase profits, based on my observations.
Here are some additional points to consider for further improvement:
Additional Considerations:
- Risk Management:
- Emphasize the importance of robust risk management techniques, such as stop-loss and take-profit orders, to protect capital.
- Discuss the role of position sizing and money management strategies in optimizing risk-reward ratios.
- Backtesting and Optimization:
- Highlight the significance of thorough backtesting to evaluate the strategy's historical performance and identify optimal parameters.
- Encourage the use of optimization techniques to fine-tune the strategy's settings.
- Forward Testing:
- Stress the importance of forward testing to assess the strategy's performance in real-time market conditions.
- Consider using a demo account to test the strategy before risking real capital.
- Continuous Learning:
- Encourage continuous learning and adaptation to evolving market conditions.
- Stay updated on the latest trading techniques and technological advancements.
- Potential Future Directions:
- Advanced Trading Strategies: Explore more complex strategies, such as trend-following, mean-reversion, or volatility-based approaches.
- Machine Learning: Incorporate machine learning techniques to improve prediction accuracy and optimize trading parameters.
- AI-Powered Trading: Utilize artificial intelligence to automate decision-making processes and adapt to changing market conditions.
By combining technical analysis, risk management, and continuous learning, traders can enhance trading strategies and improve overall performance.
Final Words
We hope that this article and the MQL5 Multi-Currency Expert Advisor program will be beneficial for traders in learning and generating new ideas, which can ultimately make money from forex trading.
Please download the Expert Advisor from My Google Drive: ZigZag_RSI_MCEA
If you have any ideas for developing this EA program, please leave your comments below this article.
Thanks for reading this article.
//+------------------------------------------------------------------+
//| ZigZag_RSI_MCEA.mq5 |
//| Copyright 2024, Roberto Jacobs (3rjfx) ~ Date: 2024-04-03 |
//| https://www.mql5.com/en/users/3rjfx |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Roberto Jacobs (3rjfx) ~ Date: 2024-04-03"
#property link "https://www.mql5.com/en/users/3rjfx"
#property version "1.00"
#property strict
#property description "The Expert ZigZag_RSI_MCEA is the Automated Trading Multi Currency Forex Expert Advisor for MetaTrader 5"
#property description "by using ZigZag and Relative Strength Index indicators signal which trade Multiple Pairs in one Chart."
#property description "version: 1.00 ~ Update number: 1 ~ Last update: 2024/04/19 @11:35 (AM) WIT (Western Indonesian Time)"
//#property icon "\\Images\\ZigZag_RSI_MCEA.ico";
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
//--
CTrade mc_trade;
CSymbolInfo mc_symbol;
COrderInfo mc_order;
CPositionInfo mc_position;
CAccountInfo mc_account;
//---
//--
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
};
//--
enum YN
{
No,
Yes
};
//--
enum mmt
{
FixedLot, // Fixed Lot Size
DynamLot // Dynamic Lot Size
};
//--
enum TFUSE
{
TFM15, // 01_PERIOD_M15
TFM30, // 02_PERIOD_M30
TFH1, // 03_PERIOD_H1
TFH2, // 04_PERIOD_H2
TFH3, // 05_PERIOD_H3
TFH4, // 06_PERIOD_H4
TFH6, // 07_PERIOD_H6
TFH8, // 08_PERIOD_H8
TFH12, // 09_PERIOD_H12
TFD1 // 10_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 poexp
{
eoh01, // Expiration at the end of H1 Timeframe
eoh04, // Expiration at the end of H4 Timeframe
eoh08, // Expiration at the end of H8 Timeframe
eoh12, // Expiration at the end of H12 Timeframe
eod01, // Expiration at the end of Current day
eod02, // Expiration at the end of the Second day
eod03, // Expiration at the end of the Third day
eod04, // Expiration at the end of the Fourth day
eod05, // Expiration at the end of the Fifth day
eono // Not Use the Expiration
};
//--
//---
input group "=== Global Strategy EA Parameter ==="; // Global Strategy EA Parameter
input TFUSE tfinuse = TFH1; // Select Expert TimeFrame, default PERIOD_H4
//--- ZigZag Indicator Input Properties
input group "=== ZigZag Indicator Input Properties ==="; // ZigZag Indicator Input Properties
input int zzDepth = 12; // Input ZigZag Depth, default 12
input int zzDevia = 5; // Input ZigZag Deviation, default 5
input int zzBackS = 3; // Input ZigZag Back Step, default 3
//-- Relative Strength Index (RSI) Indicator
input group "=== RSI Indicator Input Properties ==="; // RSI Indicator Input Properties
input int RSIper = 7; // Input RSI Indicator period
input ENUM_APPLIED_PRICE RSIapp = PRICE_MEDIAN; // Select RSI Indicator Applied Price
input double RSIoverBo = 76.0; // Input RSI Overbought Level (default 76.0)
input double RSIoverSo = 24.0; // Input RSI Oversold Level (default 24.0)
//---
input group "=== Selected 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 = FixedLot; // Money Management Type
input double Risk = 10.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)
input double lotmp2 = 2.00; // Input Martingale 2nd Lot (2nd x Lots) Multiplier
input double lotmp3 = 2.00; // Input Martingale 3rd Lot (3rd x 2nd) Multiplier
input double lotmp4 = 2.00; // Input Martingale 4th Lot (4th x 3rd) Multiplier
input double lotmp5 = 2.00; // Input Martingale 5th Lot (5th x 4th) Multiplier
//--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 int mxoop = 30; // Select Maximum Open Order on Trade
input YN use_po = Yes; // Use Limit Pending Order (Yes) or (No)
input int maxlpo = 3; // Maximum Open Limit PO per pair
input double MxDp = 35.0; // Input Minimum Entry Distance per Limit PO (in pips)
input poexp use_expi = eod03; // Select Pending Order Expiry Time
input YN trgdpo = Yes; // If PO Limit is triggered, delete the loss order (Yes) or (No)
input double maxsprd = 9.0; // Input Maximum Pair's Spread to Trade (in Pips)
//-- Order Stop Loss
input group "=== Order Stop Loss ==="; // Order Stop Loss
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
//-- Trailing Stop Loss
input group "=== Trailing Stop Loss ==="; // Trailing Stop Loss
input YN TrailingSL = No; // Use Trailing Stop Loss (Yes) or (No)
input TrType trlby = byHiLo; // 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
//-- Order Take Profit
input group "=== Order Take Profit ==="; // Order Take Profit
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
//-- Trailing Take Profit
input group "=== Trailing Take Profit ==="; // Trailing Take Profit
input YN TrailingTP = Yes; // Use Trailing Take Profit (Yes) or (No)
input double TPmin = 25.0; // Input Trailing Profit Value in Pips
//-- Options to Close Orders
input group "=== Options to Close Orders ==="; // Options to Close Orders
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)
//--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 = 20240414; // 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,
oBl,
oSl,
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;
//----------------------
//--
double LotPS;
double point;
double slv,
tpv,
pip,
xpip;
double valSL,
valTP,
minSL,
minTP;
double floatprofit,
fixclprofit;
double OPBuyx[],
OPSelx[];
double Lotmpx[4];
double LastLotB[],
LastLotS[];
//--
string pairs,
hariini,
daytrade,
trade_mode;
//--
double OPEN[],
HIGH[],
LOW[],
CLOSE[];
datetime TIME[];
datetime POExpiry[];
datetime closetime;
//--
//------------
//------------
void SetSymbolNamePS(void);
void HandlingSymbolArrays(void);
void Set_Time_Zone(void);
void Time_Zone(void);
bool Trade_session(void);
bool IsExpirationTypeAllowed(const string symbol,int exp_type);
int ThisTime(const int reqmode);
int ReqTime(datetime reqtime,const int reqmode);
string PosTimeZone(void);
//--
int DirectionMove(const string symbol,const ENUM_TIMEFRAMES stf);
int GetIndiSignals(const string symbol);
int ZigZagSignal(const string symbol);
int RSISignal(const string symbol);
int LotDig(const string symbol);
//--
double MLots(const string symbol);
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 ReqDate(int d,int h,int m);
string TF2Str(ENUM_TIMEFRAMES period);
string timehr(int hr,int mn);
string TradingDay(void);
string AccountMode();
string ReturnsOrderType(ENUM_ORDER_TYPE ordtype);
string GetCommentForOrder(void) { return(expname); }
//------------
public:
//---
//-- ZigZag_RSI_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;
string indiname1,
indiname2;
//--
//--- Indicators Handle
int hZigZag[],
hRSI[];
int hVIDyAv[];
//---
int ALO,
dgts,
arrsar,
arrsymbx;
int sall,
arusd,
areur,
aretc,
arspc,
arper;
ulong slip;
//--
double profitb[],
profits[];
double minprofit;
double spreadx[];
double maxSpread;
//--
int Buy,
Sell;
int ccur,
psec,
xtto,
mxtt0,
checktml;
int maxpol,
maxpolimit;
int OpOr[],
xob[],xos[],
xobl[],xosl[];
//--
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 TFt;
ENUM_ORDER_TYPE_TIME OTT;
//--
bool PanelExtra;
//------------
MCEA(void);
~MCEA(void);
//------------
//--
virtual void ZigZag_RSI_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 symbol,string msgText);
void CheckOpenPMx(const string symbol);
void CheckMarketOrder(const string symbol);
void SetSLTPOrders(void);
void CloseAllOrders(void);
void CloseBuyPendingOrders(const string symbol);
void CloseSellPendingOrders(const string symbol);
void CheckClose(const string symbol);
void TodayOrders(void);
void UpdatePrice(const string symbol,ENUM_TIMEFRAMES xtf,int bars=0);
void RefreshPrice(const string symbol,ENUM_TIMEFRAMES xtf,int bars);
//--
bool CheckSpread(const string symbol);
bool GoodMarginTrade(const string symbol,ENUM_ORDER_TYPE _cmd,double lotsz,double atprice);
bool CheckEquityBalance(void);
bool RefreshTick(const string symbol);
bool TradingToday(void);
bool OpenBuy(const string symbol);
bool OpenSell(const string symbol);
bool OpenPendingBuy(const string symbol,int px);
bool OpenPendingSell(const string symbol,int px);
bool ModifyOrderSLTP(double mStop,double ordtp);
bool ModifyOrdersSL(const string symbol,int TS_type);
bool ModifyOrdersTP(const string symbol);
bool CloseAllProfit(void);
bool CloseAllLoss(void);
bool ManualCloseAllProfit(void);
bool CloseBuyPositions(const string symbol);
bool CloseSellPositions(const string symbol);
//--
int PairsIdxArray(const string symbol);
int ValidatePairs(const string symbol);
int GetOpenPosition(const string symbol);
int GetCloseInWeakSignal(const string symbol,int exis);
//--
datetime SetPOExpiry(const string symbol);
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(125),
checktml(0),
maxpolimit(4),
expname("ZigZag_RSI_MCEA"),
indiname1("Examples\\ZigZag.ex5"),
indiname2("Examples\\RSI.ex5"),
closetime(TimeCurrent())
{
}
//---------//
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
MCEA::~MCEA(void)
{
}
//---------//
//+------------------------------------------------------------------+
//| Expert Configuration |
//+------------------------------------------------------------------+
void MCEA::ZigZag_RSI_MCEA_Config(void)
{
//---
//--
HandlingSymbolArrays(); // With this function we will handle all pairs that will be traded
//--
maxpol=maxlpo;
if(maxpol>maxpolimit)
{
maxpol=maxpolimit;
Alert("Maximum Limit Pending Orders allowed is only "+string(maxpolimit)+" orders.");
}
//--
ENUM_TIMEFRAMES TFs[]={PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1};
int arTFs=ArraySize(TFs);
//--
for(int x=0; x<arTFs; x++) if(tfinuse==x) TFt=TFs[x]; // TF for calculation signal
//--
//-- Indicators handle for all symbol
for(int x=0; x<arrsymbx; x++)
{
hZigZag[x] = iCustom(DIRI[x],TFt,indiname1,zzDepth,zzDevia,zzBackS); //-- Handle for the ZigZag indicator
hRSI[x] = iRSI(DIRI[x],TFt,RSIper,RSIapp); //-- Handle for the RSI indicator
hVIDyAv[x] = iVIDyA(DIRI[x],TFt,9,12,0,PRICE_WEIGHTED); //-- Handle for the VIDYA indicator for Trailing Stop
}
//--
TesterHideIndicators(true);
minprofit=NormalizeDouble(5.0/100.0,2);
//--
ALO=(int)mc_account.LimitOrders()>sall ? sall : (int)mc_account.LimitOrders();
if(Close_by_Opps==No)
{
if((int)mc_account.LimitOrders()>=(sall*2)) ALO=sall*2;
else
ALO=(int)(mc_account.LimitOrders()/2);
}
//--
mxtt0=ALO>mxoop ? mxoop : ALO;
LotPS=(double)mxtt0;
Lotmpx[0]=lotmp2;
Lotmpx[1]=lotmp3;
Lotmpx[2]=lotmp4;
Lotmpx[3]=lotmp5;
maxSpread=maxsprd;
if(MQLInfoInteger(MQL_TESTER))
maxSpread=(int)SymbolInfoInteger(Symbol(),SYMBOL_SPREAD);
//--
valSL=TSval==0.0 ? 38.0 : TSval;
valTP=TPval==0.0 ? 50.0 : TPval;
minSL=TSmin==0.0 ? 5.0 : TSmin;
minTP=TPmin==0.0 ? 25.0 : TPmin;
//--
mc_trade.SetExpertMagicNumber(magicEA);
mc_trade.SetDeviationInPoints(slip);
mc_trade.SetMarginMode();
Set_Time_Zone();
//--
return;
//---
} //-end ZigZag_RSI_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
//--
sall=ArraySize(All30);
arusd=ArraySize(USDs);
areur=ArraySize(EURs);
aretc=ArraySize(JPYs);
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;
}
}
//--
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.ZigZag_RSI_MCEA_Config();
//--
return(INIT_SUCCEEDED);
//---
} //-end OnInit()
//---------//
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
Comment("");
//-- Release all handle indicators for all symbols
for(int x=0; x<mc.arrsymbx; x++)
{
IndicatorRelease(mc.hZigZag[x]);
IndicatorRelease(mc.hRSI[x]);
IndicatorRelease(mc.hVIDyAv[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=mc.pairs+" ("+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.CloseSellPendingOrders(symbol);
}
//--
if(mc.xob[x]==0 && mc.xtto<mc.mxtt0)
{
mc.OpenBuy(symbol);
if(use_po==Yes)
{
for(int i=0,j=1; i<mc.maxpol; i++,j++)
mc.OpenPendingBuy(symbol,j);
}
}
else
if(mc.xtto>=mc.mxtt0)
{
//--
mc.Do_Alerts(symbol,"Maximum amount of open positions and active pending orders has reached"+
"\n the limit = "+string(mc.mxtt0)+" Orders ");
//--
mc.CheckOpenPMx(symbol);
//--
if(mc.xos[x]>0 && mc.profits[x]<-1.02 && mc.xob[x]==0)
{ mc.CloseSellPositions(symbol); mc.CloseSellPendingOrders(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.CloseBuyPendingOrders(symbol);
}
//--
if(mc.xos[x]==0 && mc.xtto<mc.mxtt0)
{
mc.OpenSell(symbol);
if(use_po==Yes)
{
for(int i=0,j=1; i<mc.maxpol; i++,j++)
mc.OpenPendingSell(symbol,j);
}
}
else
if(mc.xtto>=mc.mxtt0)
{
//--
mc.Do_Alerts(symbol,"Maximum amount of open positions and active pending orders has reached"+
"\n the limit = "+string(mc.mxtt0)+" Orders ");
//--
mc.CheckOpenPMx(symbol);
//--
if(mc.xob[x]>0 && mc.profitb[x]<-1.02 && mc.xos[x]==0)
{ mc.CloseBuyPositions(symbol); mc.CloseBuyPendingOrders(symbol); mc.OpenSell(symbol); }
else
mc.CloseAllProfit();
}
}
}
//--
mc.CheckOpenPMx(symbol);
//--
if(mc.xtto>0)
{
//--
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(trgdpo==Yes) // If PO Limit is triggered, delete the loss order (Yes)
{
mc.CheckOpenPMx(symbol);
if(mc.xob[x]>1) CheckMarketOrder(symbol);
if(mc.xos[x]>1) CheckMarketOrder(symbol);
}
//--
if(TrailingSL==Yes) mc.ModifyOrdersSL(symbol,trlby); //-- Use Trailing Stop Loss (Yes)
if(TrailingTP==Yes) mc.ModifyOrdersTP(symbol); //-- Use Trailing Take Profit (Yes)
//--
if((use_sl==No||Close_by_Opps==No) && !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=-1;
//--
for(int x=0; x<arrsymbx; x++)
{
if(DIRI[x]==symbol)
{
pidx=x;
break;
}
}
//--
return(pidx);
//---
} //-end PairsIdxArray()
//---------//
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(xobl);
ArrayFree(xosl);
ArrayFree(OpOr);
ArrayFree(profitb);
ArrayFree(profits);
ArrayFree(hZigZag);
ArrayFree(hRSI);
ArrayFree(hVIDyAv);
ArrayFree(POExpiry);
ArrayFree(OPBuyx);
ArrayFree(OPSelx);
ArrayFree(LastLotB);
ArrayFree(LastLotS);
ArrayFree(spreadx);
//--
ArrayResize(DIRI,arrsymbx,arrsymbx);
ArrayResize(xob,arrsymbx,arrsymbx);
ArrayResize(xos,arrsymbx,arrsymbx);
ArrayResize(xobl,arrsymbx,arrsymbx);
ArrayResize(xosl,arrsymbx,arrsymbx);
ArrayResize(OpOr,arrsymbx,arrsymbx);
ArrayResize(profitb,arrsymbx,arrsymbx);
ArrayResize(profits,arrsymbx,arrsymbx);
ArrayResize(hZigZag,arrsymbx,arrsymbx);
ArrayResize(hRSI,arrsymbx,arrsymbx);
ArrayResize(hVIDyAv,arrsymbx,arrsymbx);
ArrayResize(POExpiry,arrsymbx,arrsymbx);
ArrayResize(OPBuyx,arrsymbx,arrsymbx);
ArrayResize(OPSelx,arrsymbx,arrsymbx);
ArrayResize(LastLotB,arrsymbx,arrsymbx);
ArrayResize(LastLotS,arrsymbx,arrsymbx);
ArrayResize(spreadx,arrsymbx,arrsymbx);
//--
return;
//---
} //-end ArraySymbolResize()
//---------//
datetime MCEA::SetPOExpiry(const string symbol) //-- Function to Set Order Pending Expiration for each pairs
{
//---
int expiration=0;
datetime until=0;
datetime untiltd=0;
int x=PairsIdxArray(symbol);
ENUM_TIMEFRAMES TFExpi=0;
//--
switch(use_expi)
{
case eoh01: expiration=PeriodSeconds(PERIOD_H1); TFExpi=PERIOD_H1; break;
case eoh04: expiration=PeriodSeconds(PERIOD_H4); TFExpi=PERIOD_H4; break;
case eoh08: expiration=PeriodSeconds(PERIOD_H8); TFExpi=PERIOD_H8; break;
case eoh12: expiration=PeriodSeconds(PERIOD_H12); TFExpi=PERIOD_H12; break;
case eod01: expiration=PeriodSeconds(PERIOD_D1); TFExpi=PERIOD_D1; break;
case eod02: expiration=PeriodSeconds(PERIOD_D1)*2; TFExpi=PERIOD_D1; break;
case eod03: expiration=PeriodSeconds(PERIOD_D1)*3; TFExpi=PERIOD_D1; break;
case eod04: expiration=PeriodSeconds(PERIOD_D1)*4; TFExpi=PERIOD_D1; break;
case eod05: expiration=PeriodSeconds(PERIOD_D1)*5; TFExpi=PERIOD_D1; break;
case eono: expiration=0; TFExpi=TFt; break;
}
//--
RefreshPrice(DIRI[x],TFExpi,2);
untiltd=iTime(DIRI[x],TFExpi,0)+PeriodSeconds(PERIOD_D1)-PeriodSeconds(PERIOD_M1);
until=iTime(DIRI[x],TFExpi,0)+expiration-PeriodSeconds(PERIOD_M1);
//--
if(use_expi!=eono && IsExpirationTypeAllowed(symbol,SYMBOL_EXPIRATION_SPECIFIED))
{ OTT=ORDER_TIME_SPECIFIED; POExpiry[x]=until; }
if(use_expi!=eono && !IsExpirationTypeAllowed(symbol,SYMBOL_EXPIRATION_SPECIFIED))
{ OTT=ORDER_TIME_DAY; POExpiry[x]=untiltd; }
if(use_expi==eono) POExpiry[x]=0;
//--
return(POExpiry[x]);
//---
} //- end SetPOExpiry()
//---------//
bool MCEA::IsExpirationTypeAllowed(const string symbol,int exp_type)
{
//--- Obtain the value of the property that describes allowed expiration modes
int expiration=(int)SymbolInfoInteger(symbol,SYMBOL_EXPIRATION_MODE);
//--- Return true, if mode exp_type is allowed
return((expiration&exp_type)==exp_type);
//---
} //- end IsExpirationTypeAllowed()
//---------//
bool MCEA::CheckSpread(const string symbol)
{
//---
bool allow_spread=false;
int x=PairsIdxArray(symbol);
//--
CurrentSymbolSet(symbol);
spreadx[x]=mc_symbol.NormalizePrice(mc_symbol.Ask()-mc_symbol.Bid());
//--
allow_spread=spreadx[x] <= maxSpread*pip;
//--
if(!allow_spread)
{
string bigspread="Spread in "+symbol+" is greater than maximum spread limit.";
Do_Alerts(symbol,bigspread);
}
//--
return(allow_spread);
//---
} //- end CheckSpread()
//---------//
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()
//---------//
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);
//--
int barx=PeriodSeconds(xtf)/60*xbar;
RefreshPrice(symbol,PERIOD_M1,xbar);
RefreshPrice(symbol,xtf,barx);
//--
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 symbol,ENUM_TIMEFRAMES xtf,int bars)
{
//---
MqlRates parray[];
ArraySetAsSeries(parray,true);
int copied=CopyRates(symbol,xtf,0,bars,parray);
//--
return;
//---
} //-end RefreshPrice()
//---------//
bool MCEA::RefreshTick(const string symbol)
{
//---
mc_symbol.Name(symbol);
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()
//---------//
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(1.5*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()
//---------//
int MCEA::ZigZagSignal(const string symbol) // ZigZag Signal for Open Position
{
//---
int ret=0;
int rise=1,
down=-1;
int ZH=-1,
ZL=-1;
int barcalc=arper;
bool ZZrise=false;
bool ZZdown=false;
//--
double ZZBuffer[];
ArrayResize(ZZBuffer,barcalc,barcalc);
ArraySetAsSeries(ZZBuffer,true);
//--
int x=PairsIdxArray(symbol);
UpdatePrice(symbol,TFt,0);
//--
CopyBuffer(hZigZag[x],0,0,barcalc,ZZBuffer);
//--
for(int i=barcalc-1; i>=0; i--)
{
if(ZZBuffer[i]==HIGH[i]) ZH=i;
if(ZZBuffer[i]==LOW[i]) ZL=i;
}
//--
ZZrise=(ZL<ZH && ZL>=0);
ZZdown=(ZH<ZL && ZH>=0);
//--
if(ZZrise) ret=rise; // for open Buy order
if(ZZdown) ret=down; // for open Sell order
//--
return(ret);
//---
} //-end ZigZagSignal()
//---------//
int MCEA::RSISignal(const string symbol) // Signal RSI Indicator
{
//---
int ret=0;
int rise=1,
down=-1;
int barcnt=5;
int cRsiLo=-1,
cRsiHi=-1;
int barcalc=arper;
//--
double RSILine[];
ArrayResize(RSILine,barcalc,barcalc);
ArraySetAsSeries(RSILine,true);
//--
int x=PairsIdxArray(symbol);
UpdatePrice(symbol,TFt,0);
//--
CopyBuffer(hRSI[x],0,0,barcalc,RSILine);
//--
for(int i=barcalc-1; i>=0; i--)
{
if(RSILine[i]<=RSIoverSo) cRsiLo=i;
if(RSILine[i]>=RSIoverBo) cRsiHi=i;
}
//--
if((cRsiLo<cRsiHi) && (cRsiLo<barcnt) && (RSILine[1]<=RSIoverSo && RSILine[0]>RSIoverSo)) ret=rise; // for open Buy order
if((cRsiHi<cRsiLo) && (cRsiHi<barcnt) && (RSILine[1]>=RSIoverBo && RSILine[0]<RSIoverBo)) ret=down; // for open Sell order
//--
return(ret);
//---
} //-end RSISignal()
//---------//
int MCEA::GetIndiSignals(const string symbol) // Get Signal for Open Position
{
//---
int ret=0;
int rise=1,
down=-1;
int sigrise=2;
int sigdown=-2;
//--
int ZZSignal=ZigZagSignal(symbol);
int RMSignal=RSISignal(symbol);
//Print(symbol+" = ZZ="+string(ZZSignal)+" RSI="+string(RMSignal)+" Signal="+string(ZZSignal+RMSignal));
//--
if(ZZSignal+RMSignal==sigrise) ret=rise;
if(ZZSignal+RMSignal==sigdown) ret=down;
//--
return(ret);
//---
} //-end GetIndiSignals()
//---------//
int MCEA::GetOpenPosition(const string symbol) // Signal Open Position
{
//---
int ret=0;
int rise=1,
down=-1;
//--
int ZZRSISignal=GetIndiSignals(symbol);
int dirmove=DirectionMove(symbol,TFt);
//--
if(ZZRSISignal==rise && dirmove==rise) ret=rise;
if(ZZRSISignal==down && dirmove==down) ret=down;
//--
return(ret);
//---
} //-end GetOpenPosition()
//---------//
int MCEA::GetCloseInWeakSignal(const string symbol,int exis) // Signal Indicator Position Close in profit
{
//---
int ret=0;
int rise=1,
down=-1;
//--
int RSIdir=RSISignal(symbol);
int ZZDir=ZigZagSignal(symbol);
//--
if(exis==down && (RSIdir==rise||ZZDir==rise)) ret=rise;
if(exis==rise && (RSIdir==down||ZZDir==down)) ret=down;
//--
return(ret);
//---
} //-end GetCloseInWeakSignal()
//---------//
bool MCEA::OpenBuy(const string symbol)
{
//---
ResetLastError();
//--
CurrentSymbolSet(symbol);
bool buyopen = false;
double ldLot = MLots(symbol);
ENUM_ORDER_TYPE type_req = ORDER_TYPE_BUY;
string ordertype = ReturnsOrderType(type_req);
string ldComm = GetCommentForOrder()+"_"+ordertype;
if(!CheckSpread(symbol)) return(false);
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);
//--
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);
}
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();
//--
CurrentSymbolSet(symbol);
bool selopen = false;
double sdLot = MLots(symbol);
ENUM_ORDER_TYPE type_req = ORDER_TYPE_SELL;
string ordertype = ReturnsOrderType(type_req);
string sdComm = GetCommentForOrder()+"_"+ordertype;
if(!CheckSpread(symbol)) return(false);
if(!GoodMarginTrade(symbol,type_req,sdLot,mc_symbol.Bid())) return(false);
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//-- structure is set to zero
ZeroMemory(req);
ZeroMemory(res);
ZeroMemory(check);
//--
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);
}
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
//---------//
bool MCEA::OpenPendingBuy(const string symbol,int px)
{
//---
ResetLastError();
//--
int x=PairsIdxArray(symbol);
Pips(symbol);
CheckOpenPMx(symbol);
//--
bool openpo = false;
ENUM_ORDER_TYPE type_req = ORDER_TYPE_BUY_LIMIT;
string ordertype = ReturnsOrderType(type_req);
string poComm = GetCommentForOrder()+"_"+ordertype;
if(!CheckSpread(symbol)) return(false);
double poLot=NormalizeDouble(LastLotB[x]*Lotmpx[px-1],LotDig(symbol));
if(!GoodMarginTrade(symbol,ORDER_TYPE_BUY,poLot,mc_symbol.Ask())) return(false);
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//-- structure is set to zero
ZeroMemory(req);
ZeroMemory(res);
ZeroMemory(check);
//--
// The distance is specified according to the input properties in pips
double POD=mc_symbol.NormalizePrice(MxDp*pip);
// Calculation of the distance from the open market order price minus the distance multiplication
double POBLprice=mc_symbol.NormalizePrice(OPBuyx[x]-(px*POD));
//--
SetPOExpiry(symbol);
//Print("SetPOExpiry="+symbol+"~"+TimeToString(SetPOExpiry(symbol),TIME_DATE|TIME_SECONDS));
double SL=OrderSLSet(symbol,type_req,POBLprice);
double TP=OrderTPSet(symbol,type_req,POBLprice);
//--
if(RefreshTick(symbol))
openpo=mc_trade.OrderOpen(symbol,type_req,poLot,0.0,POBLprice,SL,TP,OTT,POExpiry[x],poComm);
//--
int error=GetLastError();
if(openpo||error==0)
{
string bsopen="Open "+ordertype+" Order for "+symbol+" ~ Ticket= ["+(string)mc_trade.ResultOrder()+"] successfully..!";
Do_Alerts(symbol,bsopen);
}
else
{
mc_trade.CheckResult(check);
Do_Alerts(Symbol(),"Open "+ordertype+" order for "+symbol+" FAILED!!. Return code= "+
(string)mc_trade.ResultRetcode()+". Code description: ["+mc_trade.ResultRetcodeDescription()+"]");
return(false);
}
//--
return(openpo);
//--
//---
} //-end OpenPendingBuy
//---------//
bool MCEA::OpenPendingSell(const string symbol,int px)
{
//---
ResetLastError();
//--
int x=PairsIdxArray(symbol);
Pips(symbol);
CheckOpenPMx(symbol);
//--
bool openpo = false;
ENUM_ORDER_TYPE type_req = ORDER_TYPE_SELL_LIMIT;
string ordertype = ReturnsOrderType(type_req);
string poComm = GetCommentForOrder()+"_"+ordertype;
if(!CheckSpread(symbol)) return(false);
double poLot=NormalizeDouble(LastLotS[x]*Lotmpx[px-1],LotDig(symbol));
if(!GoodMarginTrade(symbol,ORDER_TYPE_SELL,poLot,mc_symbol.Bid())) return(false);
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//-- structure is set to zero
ZeroMemory(req);
ZeroMemory(res);
ZeroMemory(check);
//--
// The distance is specified according to the input properties in pips
double POD=mc_symbol.NormalizePrice(MxDp*pip);
// Calculation of the distance from the open market order price plus the distance multiplication
double POSLprice=mc_symbol.NormalizePrice(OPSelx[x]+(px*POD));
//--
SetPOExpiry(symbol);
//Print("SetPOExpiry="+symbol+"~"+TimeToString(SetPOExpiry(symbol),TIME_DATE|TIME_SECONDS));
double SL=OrderSLSet(symbol,type_req,POSLprice);
double TP=OrderTPSet(symbol,type_req,POSLprice);
//--
if(RefreshTick(symbol))
openpo=mc_trade.OrderOpen(symbol,type_req,poLot,0.0,POSLprice,SL,TP,OTT,POExpiry[x],poComm);
//--
int error=GetLastError();
if(openpo||error==0)
{
string bsopen="Open "+ordertype+" Order for "+symbol+" ~ Ticket= ["+(string)mc_trade.ResultOrder()+"] successfully..!";
Do_Alerts(symbol,bsopen);
}
else
{
mc_trade.CheckResult(check);
Do_Alerts(Symbol(),"Open "+ordertype+" order for "+symbol+" FAILED!!. Return code= "+
(string)mc_trade.ResultRetcode()+". Code description: ["+mc_trade.ResultRetcodeDescription()+"]");
return(false);
}
//--
return(openpo);
//--
//---
} //-end OpenPendingSell
//---------//
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:
case ORDER_TYPE_BUY_LIMIT:
{
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-(valSL*pip));
else slv=0.0;
//--
break;
}
case ORDER_TYPE_SELL:
case ORDER_TYPE_SELL_LIMIT:
{
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+(valSL*pip));
else slv=0.0;
//--
break;
}
}
//---
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:
case ORDER_TYPE_BUY_LIMIT:
{
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+(valTP*pip));
else tpv=0.0;
//--
break;
}
case ORDER_TYPE_SELL:
case ORDER_TYPE_SELL_LIMIT:
{
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-(valTP*pip));
else tpv=0.0;
//--
break;
}
}
//---
return(tpv);
//---
} //-end OrderTPSet()
//---------//
void MCEA::CheckOpenPMx(const string symbol) //-- function: CheckOpenTrade.
{
//---
datetime to=TimeCurrent();
datetime from=to-PeriodSeconds(PERIOD_W1);
//--- request the entire history
HistorySelect(from,to);
int totalposition=PositionsTotal();
xtto=totalposition;
//--
int xi=PairsIdxArray(symbol);
xob[xi]=0;
xos[xi]=0;
xobl[xi]=0;
xosl[xi]=0;
profitb[xi]=0.0;
profits[xi]=0.0;
LastLotB[xi]=0.0;
LastLotS[xi]=0.0;
double pos_profit = 0.0;
double pos_swap = 0.0;
double pos_comm = 0.0;
//--
for(int i=0; i<totalposition && !IsStopped(); i++)
{
string position_symbol=PositionGetSymbol(i);
long magic = mc_position.Magic();
if(position_symbol==symbol && magic==magicEA)
{
//--
ENUM_POSITION_TYPE opstype = mc_position.PositionType();
if(opstype == POSITION_TYPE_BUY)
{
xob[xi]++;
OPBuyx[xi] = mc_position.PriceOpen();
LastLotB[xi] = mc_position.Volume();
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);
}
if(opstype == POSITION_TYPE_SELL)
{
xos[xi]++;
OPSelx[xi] = mc_position.PriceOpen();
LastLotS[xi] = mc_position.Volume();
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);
}
//--
}
}
//--
int totalorder=OrdersTotal(); // number of open orders
//--- iterate over all open trades
for(int i=0; i<totalorder && !IsStopped(); i++)
{
ulong ticket=OrderGetTicket(i);
if(ticket>0)
{
if(OrderSelect(ticket))
{
string orders_symbol = mc_order.Symbol();
if(orders_symbol==symbol)
{
//--
long mgcn = mc_order.Magic();
//--- if the MagicNumber matches
if(mgcn==magicEA)
{
ENUM_ORDER_TYPE ordtype = mc_order.OrderType();
//--
if(ordtype == ORDER_TYPE_BUY_LIMIT) { xobl[xi]++; LastLotB[xi]=mc_order.VolumeInitial(); }
if(ordtype == ORDER_TYPE_SELL_LIMIT) { xosl[xi]++; LastLotS[xi]=mc_order.VolumeInitial(); }
//--
}
}
}
}
}
//---
return;
//---
} //-end CheckOpenPMx()
//---------//
void MCEA::CheckMarketOrder(const string symbol) //-- function: Check Market Orders and Close the previous Orders.
{
//---
datetime to=TimeCurrent();
datetime from=to-PeriodSeconds(PERIOD_W1);
//--- request the entire history
HistorySelect(from,to);
int totalposition=PositionsTotal();
//--
Pips(symbol);
//--
bool closebuy = false;
bool closesel = false;
ulong cticket = 0;
ulong pticket = 0;
datetime cTopen = 0;
datetime pTopen = 0;
double Oprice = 0.0;
double Cprice = 0.0;
double sPOD = mc_symbol.NormalizePrice(MxDp/2.0*pip);
//---
for(int i=totalposition-1; i>=0 && !IsStopped(); i--)
{
string position_symbol=PositionGetSymbol(i);
long magic = mc_position.Magic();
if(position_symbol==symbol && magic==magicEA)
{
//--
ENUM_POSITION_TYPE opstype = mc_position.PositionType();
if(opstype == POSITION_TYPE_BUY)
{
cticket = mc_position.Ticket();
Oprice = mc_position.PriceOpen();
Cprice = mc_position.PriceCurrent();
cTopen = mc_position.TimeUpdate();
//--
if(cticket!=pticket && cTopen<pTopen)
{
if(Cprice<Oprice-sPOD)
closebuy=mc_trade.PositionClose(cticket,slip);
if(closebuy) PrintFormat("Close Buy order #%I64d %s %s",cticket,symbol,EnumToString(opstype));
}
//--
pTopen = cTopen;
pticket = cticket;
}
if(opstype == POSITION_TYPE_SELL)
{
cticket = mc_position.Ticket();
Oprice = mc_position.PriceOpen();
Cprice = mc_position.PriceCurrent();
cTopen = mc_position.TimeUpdate();
//--
if(cticket!=pticket && cTopen<pTopen)
{
if(Cprice>Oprice+sPOD)
closesel=mc_trade.PositionClose(cticket,slip);
if(closesel) PrintFormat("Close Sell order #%I64d %s %s",cticket,symbol,EnumToString(opstype));
}
//--
pTopen = cTopen;
pticket = cticket;
}
//--
}
}
//---
return;
//---
} //-end CheckMarketOrder()
//---------//
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()-valSL*pip);
if(ptype==POSITION_TYPE_SELL) pval=mc_symbol.NormalizePrice(mc_symbol.Ask()+valSL*pip);
break;
}
case byindi:
{
double VIDyAv[];
ArrayResize(VIDyAv,br,br);
ArraySetAsSeries(VIDyAv,true);
CopyBuffer(hVIDyAv[x],0,0,br,VIDyAv);
RefreshPrice(xsymb,TFt,br);
//--
if(ptype==POSITION_TYPE_BUY && (VIDyAv[0]<mc_symbol.NormalizePrice(mc_symbol.Bid()-(valSL*pip))))
pval=VIDyAv[0];
if(ptype==POSITION_TYPE_SELL && (VIDyAv[0]>mc_symbol.NormalizePrice(mc_symbol.Ask()+(valSL*pip))))
pval=VIDyAv[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 symbol,int TS_type)
{
//---
ResetLastError();
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
int TRSP=TS_type;
bool modist=false;
int x=PairsIdxArray(symbol);
Pips(symbol);
//--
ulong pos_ticket = 0;
double price = 0.0;
double pos_open = 0.0;
double pos_stop = 0.0;
double pos_tp = 0.0;
double pos_profit = 0.0;
double pos_swap = 0.0;
double pos_comm = 0.0;
double netp = 0.0;
double modstart = 0.0;
double modminsl = 0.0;
//--
int total=PositionsTotal();
//--
for(int i=0; i<total; i++)
{
string symbolx=PositionGetSymbol(i);
if(mc_position.Select(symbolx) && symbolx==symbol && mc_position.Magic()==magicEA)
{
ENUM_POSITION_TYPE opstype = mc_position.PositionType();
if(opstype==POSITION_TYPE_BUY)
{
RefreshTick(symbol);
pos_ticket = mc_position.Ticket();
price = mc_position.PriceCurrent();
double vtrsb = mc_symbol.NormalizePrice(TSPrice(symbol,opstype,TRSP));
pos_open = mc_position.PriceOpen();
pos_stop = mc_position.StopLoss();
pos_tp = mc_position.TakeProfit();
pos_profit = mc_position.Profit();
pos_swap = mc_position.Swap();
pos_comm = mc_position.Commission();
netp = pos_profit+pos_swap+pos_comm;
modstart = mc_symbol.NormalizePrice(pos_open+(minSL*pip));
modminsl = mc_symbol.NormalizePrice(vtrsb+((minSL-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(pos_ticket,modbuysl,pos_tp);
if(modist) PrintFormat("Position modified SL: #%I64d %s %s",pos_ticket,symbol,EnumToString(opstype));
else break;
}
}
if(opstype==POSITION_TYPE_SELL)
{
RefreshTick(symbol);
pos_ticket = mc_position.Ticket();
price = mc_position.PriceCurrent();
double vtrss = mc_symbol.NormalizePrice(TSPrice(symbol,opstype,TRSP));
pos_open = mc_position.PriceOpen();
pos_stop = mc_position.StopLoss();
pos_tp = mc_position.TakeProfit();
pos_profit = mc_position.Profit();
pos_swap = mc_position.Swap();
pos_comm = mc_position.Commission();
netp = pos_profit+pos_swap+pos_comm;
modstart = mc_symbol.NormalizePrice(pos_open-(minSL*pip));
modminsl = mc_symbol.NormalizePrice(vtrss-((minSL+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(pos_ticket,modselsl,pos_tp);
if(modist) PrintFormat("Position modified SL: #%I64d %s %s",pos_ticket,symbol,EnumToString(opstype));
else break;
}
}
}
}
//--
return(modist);
//---
} //-end ModifyOrdersSL()
//---------//
bool MCEA::ModifyOrdersTP(const string symbol)
{
//---
ResetLastError();
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
bool modist=false;
int x=PairsIdxArray(symbol);
Pips(symbol);
//--
double price = 0.0;
double pos_open = 0.0;
double pos_stop = 0.0;
double pos_tp = 0.0;
double buytp = 0.0;
double selltp = 0.0;
double precision = 0.0;
double modpostp = 0.0;
double freezeLvl = 0.0;
//--
int total=PositionsTotal();
//--
for(int i=0; i<total; i++)
{
string symbolx=PositionGetSymbol(i);
if(mc_position.Select(symbolx) && symbolx==symbol && mc_position.Magic()==magicEA)
{
ENUM_POSITION_TYPE opstype = mc_position.PositionType();
if(opstype==POSITION_TYPE_BUY)
{
RefreshTick(symbol);
ulong pos_ticket = mc_position.Ticket();
if(mc_position.SelectByTicket(pos_ticket))
{
int freeze = mc_symbol.FreezeLevel();
price = mc_position.PriceCurrent();
pos_open = mc_position.PriceOpen();
pos_stop = mc_position.StopLoss();
pos_tp = mc_position.TakeProfit();
buytp = pos_tp==0.0 ? mc_symbol.NormalizePrice(pos_open+(valTP*pip)) : pos_tp;
freezeLvl = mc_symbol.NormalizePrice(buytp-freeze);
precision = mc_symbol.NormalizePrice(price+(minTP*pip));
modpostp = mc_symbol.NormalizePrice(buytp+(minTP*pip));
bool modtpb = (price>pos_open && price<freezeLvl && precision>buytp && (pos_tp==0.0||modpostp>pos_tp));
//--
if(modtpb)
{
modist=mc_trade.PositionModify(pos_ticket,pos_stop,modpostp);
if(modist) PrintFormat("Position modified TP: #%I64d %s %s",pos_ticket,symbol,EnumToString(opstype));
else break;
}
}
}
if(opstype==POSITION_TYPE_SELL)
{
RefreshTick(symbol);
ulong pos_ticket = mc_position.Ticket();
if(mc_position.SelectByTicket(pos_ticket))
{
int freeze = mc_symbol.FreezeLevel();
price = mc_position.PriceCurrent();
pos_open = mc_position.PriceOpen();
pos_stop = mc_position.StopLoss();
pos_tp = mc_position.TakeProfit();
selltp = pos_tp==0.0 ? mc_symbol.NormalizePrice(pos_open-(valTP*pip)) : pos_tp;
freezeLvl = mc_symbol.NormalizePrice(selltp+freeze);
precision = mc_symbol.NormalizePrice(price-(minTP*pip));
modpostp = mc_symbol.NormalizePrice(selltp-(minTP*pip));
bool modtps = (price<pos_open && price>freezeLvl && precision<selltp && (pos_tp==0.0||modpostp<pos_tp));
//--
if(modtps)
{
modist=mc_trade.PositionModify(pos_ticket,pos_stop,modpostp);
if(modist) PrintFormat("Position modified TP: #%I64d %s %s",pos_ticket,symbol,EnumToString(opstype));
else break;
}
}
}
}
}
//--
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;
//--
int totalorder=PositionsTotal();
//--
for(int i=0; i<totalorder; i++)
{
string symbol=PositionGetSymbol(i);
if(mc_position.Select(symbol) && mc_position.Magic()==magicEA)
{
ulong pos_ticket = mc_position.Ticket();
if(mc_position.SelectByTicket(pos_ticket))
{
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(pos_ticket,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(pos_ticket,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));
//--
break;
}
}
//---
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;
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
int x=PairsIdxArray(symbol);
//--- iterate over all open positions
for(int i=0; i<total; i++)
{
if(mc_position.SelectByIndex(i))
{
//--- Parameters of the order
string position_Symbol = PositionGetSymbol(i);
ulong position_ticket = PositionGetTicket(i);
//--- if the MagicNumber matches
if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
{
ENUM_POSITION_TYPE type = mc_position.PositionType();
//--
if(type==closetype)
{
RefreshTick(position_Symbol);
buyclose=mc_trade.PositionClose(position_ticket,slip);
//--- output information about the closure
PrintFormat("Close Buy #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
}
}
}
}
//---
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;
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
int x=PairsIdxArray(symbol);
//--- iterate over all open positions
for(int i=0; i<total; i++)
{
if(mc_position.SelectByIndex(i))
{
//--- Parameters of the order
string position_Symbol = PositionGetSymbol(i);
ulong position_ticket = PositionGetTicket(i);
//--- if the MagicNumber matches
if((position_Symbol==symbol) && (mc_position.Magic()==magicEA))
{
ENUM_POSITION_TYPE type = mc_position.PositionType();
//--
if(type==closetype)
{
RefreshTick(position_Symbol);
sellclose=mc_trade.PositionClose(position_ticket,slip);
//--- output information about the closure
PrintFormat("Close Sell #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
}
}
}
}
//---
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=0; i<ttlorder; i++)
{
string position_Symbol = PositionGetSymbol(i);
long magic = mc_position.Magic();
if(mc_position.Select(position_Symbol) && magic==magicEA)
{
ENUM_POSITION_TYPE type = mc_position.PositionType();
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_ticket,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_ticket,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;
string isfailed="close order failed";
//--
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=0; i<ttlorder; i++)
{
string position_Symbol = PositionGetSymbol(i);
long magic = mc_position.Magic();
if(mc_position.Select(position_Symbol) && magic==magicEA)
{
ENUM_POSITION_TYPE type = mc_position.PositionType();
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_ticket,slip);
//--- output information about the closure
PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
}
else PrintFormat("Not Closed yet #%I64d %s %s",position_ticket,position_Symbol,isfailed);
if(type==POSITION_TYPE_SELL && cur_profit>minprofit)
{
RefreshTick(position_Symbol);
orclose = mc_trade.PositionClose(position_ticket,slip);
//--- output information about the closure
PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
}
else PrintFormat("Not Closed yet #%I64d %s %s",position_ticket,position_Symbol,isfailed);
}
}
}
//--
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=0; i<ttlorder; i++)
{
string position_Symbol = PositionGetSymbol(i);
long magic = mc_position.Magic();
if(mc_position.Select(position_Symbol) && magic==magicEA)
{
ENUM_POSITION_TYPE type = mc_position.PositionType();
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_ticket,slip);
//--- output information about the closure
PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
}
if(type==POSITION_TYPE_SELL && cur_profit>0.02)
{
RefreshTick(position_Symbol);
orclose = mc_trade.PositionClose(position_ticket,slip);
//--- output information about the closure
PrintFormat("Close #%I64d %s %s",position_ticket,position_Symbol,EnumToString(type));
}
}
}
}
//--
return(orclose);
//----
} //-end ManualCloseAllProfit()
//---------//
void MCEA::CloseBuyPendingOrders(const string symbol) //-- function: Close all Buy order due to Opposite Signal
{
//---
ResetLastError();
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
bool closeorder=false;
int totalorder=OrdersTotal(); // number of open orders
//--- iterate over all open trades
for(int i=totalorder; i>=0 && !IsStopped(); i--)
{
string orders_symbol = mc_order.Symbol();
long mgcn = mc_order.Magic();
//--- if the MagicNumber matches
if(orders_symbol==symbol && mgcn==magicEA)
{
//--
ulong ticket=OrderGetTicket(i);
if(ticket>0)
{
if(OrderSelect(ticket))
{
ENUM_ORDER_TYPE ordtype = mc_order.OrderType();
//--
switch(ordtype)
{
case ORDER_TYPE_BUY_LIMIT:
case ORDER_TYPE_BUY_STOP:
{ closeorder=mc_trade.OrderDelete(ticket); break; }
}
//--- output information about the closure
PrintFormat("Close #%I64d %s %s",ticket,orders_symbol,EnumToString(ordtype));
//--
}
}
}
}
//--
return;
//----
} //-end CloseBuyPendingOrders()
//---------//
void MCEA::CloseSellPendingOrders(const string symbol) //-- function: Close all Sell order due to Opposite Signal
{
//---
ResetLastError();
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
bool closeorder=false;
int totalorder=OrdersTotal(); // number of open orders
//--- iterate over all open trades
for(int i=totalorder; i>=0 && !IsStopped(); i--)
{
string orders_symbol = mc_order.Symbol();
long mgcn = mc_order.Magic();
//--- if the MagicNumber matches
if(orders_symbol==symbol && mgcn==magicEA)
{
//--
ulong ticket=OrderGetTicket(i);
if(ticket>0)
{
if(OrderSelect(ticket))
{
ENUM_ORDER_TYPE ordtype = mc_order.OrderType();
//--
switch(ordtype)
{
case ORDER_TYPE_SELL_LIMIT:
case ORDER_TYPE_SELL_STOP:
{ closeorder=mc_trade.OrderDelete(ticket); break; }
}
//--- output information about the closure
PrintFormat("Close #%I64d %s %s",ticket,orders_symbol,EnumToString(ordtype));
//--
}
}
}
}
//--
return;
//----
} //-end CloseSellPendingOrders()
//---------//
void MCEA::CloseAllOrders(void) //-- function: close all order
{
//----
ResetLastError();
//--
MqlTradeRequest req={};
MqlTradeResult res={};
MqlTradeCheckResult check={};
//--
bool closeorder=false;
int totalposition=PositionsTotal();
//--
for(int i=0; i<totalposition && !IsStopped(); i++)
{
string pos_symbol = PositionGetSymbol(i);
long magic = mc_position.Magic();
if(mc_position.Select(pos_symbol) && magic==magicEA)
{
ulong position_ticket = PositionGetTicket(i);
closeorder=mc_trade.PositionClose(position_ticket,slip);
//--
}
}
//--
int totalorder=OrdersTotal(); // number of open orders
//--- iterate over all open trades
for(int i=0; i<totalorder && !IsStopped(); i++)
{
string orders_symbol = mc_order.Symbol();
long mgcn = mc_order.Magic();
//--- if the MagicNumber matches
if(mgcn==magicEA)
{
//--
ulong ticket=OrderGetTicket(i);
if(ticket>0)
{
if(OrderSelect(ticket))
{
ENUM_ORDER_TYPE ordtype = mc_order.OrderType();
//--
switch(ordtype)
{
case ORDER_TYPE_BUY_LIMIT:
case ORDER_TYPE_SELL_LIMIT:
case ORDER_TYPE_BUY_STOP:
case ORDER_TYPE_SELL_STOP:
{ closeorder=mc_trade.OrderDelete(ticket); break; }
}
//--- output information about the closure
PrintFormat("Close #%I64d %s %s",ticket,orders_symbol,EnumToString(ordtype));
//--
}
}
}
}
//---
return;
//----
} //-end CloseAllOrders()
//---------//
void MCEA::CheckClose(const string symbol)
{
//---
//--
ResetLastError();
int x=PairsIdxArray(symbol);
Pips(symbol);
//--
datetime to=TimeCurrent();
datetime from=to-PeriodSeconds(PERIOD_M1);
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; // deal swap
double deal_comm =0.0; // deal commission
double deal_vol =0.0; // deal volume
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==symbol && 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_vol = HistoryDealGetDouble(deal_ticket,DEAL_VOLUME);
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)
{
//--
if(deal_type==DEAL_TYPE_BUY && xosl[x]>0) CloseSellPendingOrders(symbol);
if(deal_type==DEAL_TYPE_SELL && xobl[x]>0) CloseBuyPendingOrders(symbol);
//--
string ckclose="Close "+xtype+" Position on "+symbol+" at price : "+DoubleToString(deal_price,dgts)+
" OrderCloseTime(): "+TimeToString(deal_time,TIME_DATE|TIME_MINUTES)+
" in profit : "+DoubleToString(profit_loss,2);
Do_Alerts(symbol,ckclose);
}
if(profit_loss<=0)
{
string ckclose="Close "+xtype+" Position on "+symbol+" at price : "+DoubleToString(deal_price,dgts)+
" OrderCloseTime(): "+TimeToString(deal_time,TIME_DATE|TIME_MINUTES)+
" in loss : "+DoubleToString(profit_loss,2);
Do_Alerts(symbol,ckclose);
}
//--
break;
}
}
}
}
//---
return;
//----
} //-end CheckClose()
//---------//
void MCEA::TodayOrders(void)
{
//---
//--
ResetLastError();
//--
datetime to=TimeCurrent();
datetime from=to-PeriodSeconds(PERIOD_W1);
//--- request the entire history
HistorySelect(from,to);
//--- total number in the list of deals
int deals=HistoryDealsTotal();
int order=OrdersTotal();
//--
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; // deal swap
double deal_comm =0.0; // deal 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; // Market Buy order
oSm=0; // Market Sell order
oBl=0; // Buy Limit pending order
oSl=0; // Sell Limit pending order
//--
int totalposition=PositionsTotal();
//--
for(int i=0; i<totalposition && !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();}
//--
}
}
//--
//--- iterate over all open trades
for(int i=0; i<order && !IsStopped(); i++)
{
ulong ticket=OrderGetTicket(i);
if(ticket>0)
{
if(OrderSelect(ticket))
{
long mgcn = mc_order.Magic();
//--- if the MagicNumber matches
if(mgcn==magicEA)
{
ENUM_ORDER_TYPE ordtype = mc_order.OrderType();
//--
if(ordtype == ORDER_TYPE_BUY_LIMIT) oBl++;
if(ordtype == ORDER_TYPE_SELL_LIMIT) oSl++;
//--
}
}
}
}
//--
xtto=oBm+oSm+oBl+oSl;
//--
//--- 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 symbol) // 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(symbol,posCur1,3);
string sCur2=StringSubstr(symbol,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=symbol; break;
case 3: sym_use=symbol; 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(symbol,SYMBOL_VOLUME_MAX);
double Lmins = SymbolInfoDouble(symbol,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(symbol));
double asize = NormalizeDouble(sym_Lc/(double)LotPS,LotDig(symbol));
//--
if(mmlot==DynamLot)
{
Lsize = NormalizeDouble(asize*PctUse,LotDig(symbol));
}
else {Lsize = Lots;}
//--
if(Lsize < Lmins) Lsize = Lmins;
if(Lsize > Lmaxs) Lsize = Lmaxs;
//--
double lotsize=NormalizeDouble(Lsize,LotDig(symbol));
//--
return(lotsize);
//----
} //-end MLots()
//---------//
int MCEA::LotDig(const string symbol)
{
//---
double lots_step=SymbolInfoDouble(symbol,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.0;
if(val1==0.0 || val2==0.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()
//---------//
string MCEA::ReturnsOrderType(ENUM_ORDER_TYPE ordtype)
{
//---
string str_type;
//--
switch(ordtype)
{
case 0: str_type="BUY"; break;
case 1: str_type="SELL"; break;
case 2: str_type="BUY LIMIT"; break;
case 3: str_type="SELL LIMIT"; break;
case 4: str_type="BUY STOP"; break;
case 5: str_type="SELL STOP"; break;
}
//--
return(str_type);
//----
} //-end ReturnsOrderType()
//---------//
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 :: BUY Limit : "+string(oBl)+
"\n :: SELL Limit : "+string(oSl)+
"\n :: Total Order : "+string(xtto)+
"\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()
//---------//
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::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()
//---------//
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=mc.TFt;
//--
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.ValidatePairs(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=54;
int tsatu=int(mc.sall/2);
//--
CreateButtonTemplate(0,"Template",180,321,STYLE_SOLID,5,BORDER_RAISED,clrYellow,clrBurlyWood,clrWhite,CORNER_RIGHT_UPPER,187,21,true);
CreateButtonTemplate(0,"TempCCS",167,25,STYLE_SOLID,5,BORDER_RAISED,clrYellow,clrBlue,clrWhite,CORNER_RIGHT_UPPER,181,26,true);
CreateButtonClick(0,"X",14,14,"Arial Black",10,BORDER_FLAT,"X",clrWhite,clrWhite,clrRed,ANCHOR_CENTER,CORNER_RIGHT_UPPER,22,24,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,38,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*19),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-tsatu)*19),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()
//---------//
//--------------------------------------------------------------------//






















0 comments:
Post a Comment