From 6c92d9ade332eb20da4a69204720d40395b14d9f Mon Sep 17 00:00:00 2001 From: Hadi Khazaee Asl Date: Thu, 1 Feb 2024 13:47:33 +0330 Subject: [PATCH] cleanup workspace ... --- Classes/x-saherelm.class.lib.mq5 | 10316 -------------------------- Experts/x-saherelm.xtest.ea.mq5 | 572 -- Libraries/x-saherelm.alert.lib.mq5 | 200 - Libraries/x-saherelm.common.lib.mq5 | 4429 ----------- Libraries/x-saherelm.draw.lib.mq5 | 2345 ------ Libraries/x-saherelm.http.lib.mq5 | 177 - Libraries/x-saherelm.log.lib.mq5 | 261 - Libraries/x-saherelm.models.lib.mq5 | 438 -- 8 files changed, 18738 deletions(-) delete mode 100644 Classes/x-saherelm.class.lib.mq5 delete mode 100644 Experts/x-saherelm.xtest.ea.mq5 delete mode 100644 Libraries/x-saherelm.alert.lib.mq5 delete mode 100644 Libraries/x-saherelm.common.lib.mq5 delete mode 100644 Libraries/x-saherelm.draw.lib.mq5 delete mode 100644 Libraries/x-saherelm.http.lib.mq5 delete mode 100644 Libraries/x-saherelm.log.lib.mq5 delete mode 100644 Libraries/x-saherelm.models.lib.mq5 diff --git a/Classes/x-saherelm.class.lib.mq5 b/Classes/x-saherelm.class.lib.mq5 deleted file mode 100644 index 68f48471..00000000 --- a/Classes/x-saherelm.class.lib.mq5 +++ /dev/null @@ -1,10316 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Class Library -// -------------------------------------- -// Name: XClass -// Description: provides all classes for use ... -// -// -// Maintainer: -// ------------ -// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) -// -////////////////////////////////////////////////////// -// -// Global Properties ... -#property library -#property copyright "Copyright 2023, SaherElm IT Center" -#property link "https://www.saherelm.ir" -#property version "1.00" -#property strict - -// -#include -#include -#include -#include -#include -#include -// -#include "../Libraries/x-saherelm.draw.lib.mq5" -#include "../Libraries/x-saherelm.alert.lib.mq5" -#include "../Libraries/x-saherelm.models.lib.mq5" -#include "../Libraries/x-saherelm.common.lib.mq5" - -// -// START Constant Definitions ... -// - -static uchar _md5_PADDING[64] = - { - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - -#define _md5_F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define _md5_G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define _md5_H(x, y, z) ((x) ^ (y) ^ (z)) -#define _md5_I(x, y, z) ((y) ^ ((x) | (~z))) -#define _md5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - -#define _md5_FF(a, b, c, d, x, s, ac) \ - { \ - (a) += _md5_F((b), (c), (d)) + (x) + (uint)(ac); \ - (a) = _md5_ROTATE_LEFT((a), (s)); \ - (a) += (b); \ - } -#define _md5_GG(a, b, c, d, x, s, ac) \ - { \ - (a) += _md5_G((b), (c), (d)) + (x) + (uint)(ac); \ - (a) = _md5_ROTATE_LEFT((a), (s)); \ - (a) += (b); \ - } -#define _md5_HH(a, b, c, d, x, s, ac) \ - { \ - (a) += _md5_H((b), (c), (d)) + (x) + (uint)(ac); \ - (a) = _md5_ROTATE_LEFT((a), (s)); \ - (a) += (b); \ - } -#define _md5_II(a, b, c, d, x, s, ac) \ - { \ - (a) += _md5_I((b), (c), (d)) + (x) + (uint)(ac); \ - (a) = _md5_ROTATE_LEFT((a), (s)); \ - (a) += (b); \ - } - -#define _md5_INIT_STATE_0 0x67452301 -#define _md5_INIT_STATE_1 0xefcdab89 -#define _md5_INIT_STATE_2 0x98badcfe -#define _md5_INIT_STATE_3 0x10325476 - -#define _md5_S11 7 -#define _md5_S12 12 -#define _md5_S13 17 -#define _md5_S14 22 - -#define _md5_S21 5 -#define _md5_S22 9 -#define _md5_S23 14 -#define _md5_S24 20 - -#define _md5_S31 4 -#define _md5_S32 11 -#define _md5_S33 16 -#define _md5_S34 23 - -#define _md5_S41 6 -#define _md5_S42 10 -#define _md5_S43 15 -#define _md5_S44 21 - -// -// END Constant Definitions ... -// - -// -// START Model Definitions ... -// - -// -string X_SIGNAL_TP = "TP"; -string X_SIGNAL_SL = "SL"; -string X_SIGNAL_TYPE = "TY"; -string X_SIGNAL_TICKET = "T"; -string X_SIGNAL_RISKFREE_STEP = "RFS"; -string X_SIGNAL_RISKFREE_RATE = "RFR"; - -// -// Model Signal Handler Result on XCTrade Class ... -struct XTraderHandlerResult -{ - // - // List Of Closed On SL Signals ... - XSignal sl[]; - - // - // List Of Closed On TP Signals ... - XSignal tp[]; - - // - // List Of Risk Free Signals ... - XSignal rf[]; -}; - -// -// Model OnTrade Event Handler Result on XCTrade Class ... -struct XOnTradeHandlerResult -{ - // - bool hasNewDeal; - int newDeals; - - // - bool hasNewOrder; - int newOrders; - - // - bool hasNewPosition; - int newPositions; - - // - bool hasNewHistoryOrder; - int newHistoryOrders; -}; - -// -// Model Guard Action Applied Signals ... -struct XGuardHandlerResult -{ - // - // Critical Guard ... - XSignal criticals[]; - - // - // Max Guard ... - XSignal maxes[]; - - // - // Old ... - XSignal olds[]; - - // - // Determines Stopout Action Cals or not ... - bool isStopOut; -}; - -// -// Define Volume States ... -struct XVolumeInfo -{ - // - // Current Available Static Volume ... - double staticVolume; - - // - // Static Volume Calculation Method ... - string staticVolumeCalculationMethod; - - // - // Current Maximum Appliable Volume ... - double maxAllowedVolume; - - // - // Static Volume Increase Multiplier ... - double volumeIncreaseMultiplier; - - // - // Multiply Volume Based On Balance Growing ... - double balanceGowingToApplyMultiplier; - - // - // Where to Increase MaxAllowed Volume ... - double balanceGrowingToIncreaseMaxAllowedVolume; -}; - -// -// Model a Simple Provider Status ... -struct XSignallerInfo -{ - // - // Provider Name ... - string name; - - // - // Number of Longs ... - int longs; - - // - // Number of Shorts ... - int shorts; -}; - -// -// Model Some of Usefull Signals and Market Data ... -struct XSummaryInfo -{ - // - // Define Max Signal Volume ... - double maxSignalVolume; - - // - // Max DrawDown ... - double maxDrawDown; - - // - // Max DrawUp ... - double maxDrawUp; - - // - // Max Number of Same Time Signals ... - int maxSameTimeSignals; - - // - // Number of Long Trades ... - int longSignals; - - // - // Number of Short Trades ... - int shortSignals; - - // - // Number of TPs Attached ... - int numberOfTPs; - - // - // Number of SLs Attached ... - int numberOfSLs; -}; - -// -// Model Account info ... -struct XAccountInfo -{ - // - // User Account ... - string user; - - // - // Name of Client ... - string name; - - // - // Trade Server Name ... - string server; - - // - // Broker Name ... - string broker; - - // - // Account Trade Mode ... - ENUM_ACCOUNT_TRADE_MODE mode; - - // - // Account Leverage ... - long leverage; - - // - // Currency ... - string currency; - - // - // Deposit ... - double deposit; - - // - // Balance ... - double balance; - - // - // Min Balance for Open Trades ... - double minBalanceForOpenTrades; -}; - -// -// this is a Model Which holds Reports for Specific Time Periods ... -struct XReport -{ - // - datetime start; - - // - datetime end; - - // - XAccountInfo accountInfo; - - // - XVolumeInfo volumeInfo; - - // - XSignallerInfo signallersInfo[]; - - // - XSummaryInfo summaryInfo; -}; - -// -// an Enumeration Object which determines Report Type ... -enum ENUM_XREPORT_TYPES -{ - // - // Main Report ... - XREPORT_MAIN, - // - // Daily Report ... - XREPORT_DAILY, - // - // Weekly Report ... - XREPORT_WEEKLY, - // - // Monthly Report ... - XREPORT_MONTHLY, -}; - -// -// a Signal Protection Structure ... -struct XProtectedSignal -{ - // - ulong ticket; - - // - datetime time[]; - - // - double profit[]; -}; - -// -// Represent Collector State Based on Time ... -struct XCollector -{ - // - // time in checking ... - datetime time; - - // - // Signal Volume ... - double volume; - - // - // Max DrawDown in Check Time ... - double maxDrawDown; - - // - // Max Allowed Volume in Check Time ... - double maxAllowedVolume; - - // - // Minimum required Balance for Opening Trades at Check Time ... - double minBalanceForOpenTrade; -}; - -// -// Cross Signals Methods ... -enum ENUM_X_CROSS_SIGNAL_METHOD -{ - // - // Do Nothing and Ignore them ... - X_CROSS_SIGNAL_DO_NOTHING, - // - // Accept all Cross Signals and Act Usually ... - X_CROSS_SIGNAL_REGULAR, - // - // Accept all Cross Signals and for Directional Act Usually and for Indirectional Ac Important ... - X_CROSS_SIGNAL_DIRECTION_REGULAR_INDIRECTION_IMPORTANT, - // - // Accept all Cross Signals and for Directional Act Important and for Indirectional Ac Usually ... - X_CROSS_SIGNAL_DIRECTION_IMPORTANT_INDIRECTION_REGULAR, - // - // Accept Only Indirectional Signals and Act Usually ... - X_CROSS_SIGNAL_INDIRECTION_REGULAR, - // - // Accept Only Directional Signals and Act Usually ... - X_CROSS_SIGNAL_DIRECTION_REGULAR, - // - // Accept Only Indirectional Signals and Act Important ... - X_CROSS_SIGNAL_INDIRECTION_IMPORTANT, - // - // Accept Only Directional Signals and Act Important ... - X_CROSS_SIGNAL_DIRECTION_IMPORTANT, -}; - -// -// the Action which Guard Handler Can Done when Attacked ... -enum ENUM_X_GUARD_ACTIONS -{ - // - // Do Nothing ... - X_GUARD_DO_NOTHING, - // - // Close All Open Positions ... - X_GUARD_CLOSE_ALL, - // - // Close Max In Drawdown Position ... - X_GUARD_CLOSE_MAX_IN_DD, - // - // Partial Close Max In Drawdown Position by 1% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_1, - // - // Partial Close Max In Drawdown Position by 2% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_2, - // - // Partial Close Max In Drawdown Position by 3% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_3, - // - // Partial Close Max In Drawdown Position by 5% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_5, - // - // Partial Close Max In Drawdown Position by 10% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_10, - // - // Partial Close Max In Drawdown Position by 15% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_15, - // - // Partial Close Max In Drawdown Position by 20% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_20, - // - // Partial Close Max In Drawdown Position by 25% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_25, - // - // Partial Close Max In Drawdown Position by 30% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_30, - // - // Partial Close Max In Drawdown Position by 40% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_40, - // - // Partial Close Max In Drawdown Position by 50% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_50, - // - // Partial Close Max In Drawdown Position by 60% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_60, - // - // Partial Close Max In Drawdown Position by 70% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_70, - // - // Partial Close Max In Drawdown Position by 75% of Volume ... - X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_75, -}; - -// -// Guard Reason ... -enum ENUM_X_GUARD_REASONS -{ - // - // Critical ... - X_GUARDED_CRITICAL, - // - // Max ... - X_GUARDED_MAX, - // - // Old ... - X_GUARDED_OLD -}; - -// -// All Suuported Support Positions Guard ... -enum ENUM_X_GUARD_SUPPORT_METHODS -{ - // - // Ignore Supporting ... - X_SUPPORT_DO_NOTHING, - // - // Full Both Side Support ... - X_SUPPORT_FULL, - // - // Indirectional Supports On Drawing Down ... - X_SUPPORT_IN_DRAWDOWN_INDIRECTIONAL, - // - // Directional Supports On Drawing Up ... - X_SUPPORT_IN_DRAWUP_DIRECTIONAL, -}; - -// -// END Model Definitions ... -// - -// -// START Overrides ... -// - -// -// XBase Class ... -class XCBase -{ - // - // Public ... -public: - // - // Protected ... -protected: - // - void AddItemToBuffer( - double item, // Specified Item - double &buffer[] // Specified Buffer - ) - { - // - int bufferSize = ArraySize(buffer); - - // - ArrayResize( - buffer, - bufferSize + 1); - - // - buffer[bufferSize] = item; - } - void AddItemToBuffer( - datetime item, // Specified Item - datetime &buffer[] // Specified Buffer - ) - { - // - int bufferSize = ArraySize(buffer); - - // - ArrayResize( - buffer, - bufferSize + 1); - - // - buffer[bufferSize] = item; - } - void AddItemToBuffer( - XSignal &item, - XSignal &buffer[]) - { - // - ArrayResize( - buffer, - ArraySize(buffer) + 1); - - // - buffer[ArraySize(buffer) - 1] = item; - } - void AddItemToBuffer( - XCollector &item, // Specified Item - XCollector &buffer[] // Specified Buffer - ) - { - // - int bufferSize = ArraySize(buffer); - - // - ArrayResize( - buffer, - bufferSize + 1); - - // - buffer[bufferSize] = item; - } - void AddItemToBuffer( - XSignallerInfo &item, - XSignallerInfo &buffer[]) - { - // - ArrayResize( - buffer, - ArraySize(buffer) + 1); - - // - buffer[ArraySize(buffer) - 1] = item; - } - void AddItemToBuffer( - XProtectedSignal &item, // Item ... - XProtectedSignal &buffer[] // Buffer ... - ) - { - // - int bufferSize = ArraySize(buffer); - - // - ArrayResize( - buffer, - bufferSize + 1); - buffer[bufferSize] = item; - } - - // - void CleanBuffer(double &buffer[]) - { - // - ArrayFree(buffer); - ArrayResize(buffer, 0); - } - void CleanBuffer(XDeal &buffer[]) - { - // - ArrayFree(buffer); - ArrayResize(buffer, 0); - } - void CleanBuffer(XOrder &buffer[]) - { - // - ArrayFree(buffer); - ArrayResize(buffer, 0); - } - void CleanBuffer(XSignal &buffer[]) - { - // - ArrayFree(buffer); - ArrayResize(buffer, 0); - } - void CleanBuffer(XCollector &buffer[]) - { - // - ArrayFree(buffer); - ArrayResize(buffer, 0); - } - void CleanBuffer(XSignallerInfo &buffer[]) - { - // - ArrayFree(buffer); - ArrayResize(buffer, 0); - } - void CleanBuffer(XProtectedSignal &buffer[]) - { - // - ArrayFree(buffer); - ArrayResize(buffer, 0); - } - - // - void CopyBuffer( - const XSignallerInfo &source[], // Source Buffer ... - XSignallerInfo &dest[] // Dest Buffer ... - ) - { - // - CleanBuffer(dest); - - // - int sourceCount = ArraySize(source); - if (sourceCount <= 0) - { - return; - } - - // - // Loop ... - for (int i = 0; i < sourceCount; i++) - { - // - XSignallerInfo iInfo = source[i]; - - // - AddItemToBuffer( - iInfo, - dest); - } - } - void CopyBuffer( - XProtectedSignal &source[], // Source Buffer to Copy - XProtectedSignal &dest[] // Fill this buffer using source - ) - { - // - CleanBuffer(dest); - - // - int sourceCount = ArraySize(source); - if (sourceCount <= 0) - { - return; - } - - // - for (int i = 0; i < sourceCount; i++) - { - // - XProtectedSignal iItem = source[i]; - - // - AddItemToBuffer( - iItem, - dest); - } - } - - // - // Private ... -private: -}; - -// -// XCTrade Base Class ... -class XSCTrade : public CTrade -{ -public: - // - // Modify Specific Position, by Specific Comment ... - bool PositionModify( - const string symbol, // Symbol - const double sl, // Stop Loss - const double tp, // Take Profit - const string comment = "" // Comment For Modify - ) - { - // - // check stopped - if (IsStopped(__FUNCTION__)) - { - return (false); - } - - // - // check position existence - if (!SelectPosition(symbol)) - { - return (false); - } - - // - // clean - ClearStructures(); - - // - // setting request - m_request.action = TRADE_ACTION_SLTP; - m_request.symbol = symbol; - m_request.magic = m_magic; - m_request.sl = sl; - m_request.tp = tp; - m_request.position = PositionGetInteger(POSITION_TICKET); - - // - // Specified Comment ... - if (StringLen(comment) > 0) - { - m_request.comment = comment; - } - - // - // action and return the result - return (OrderSend(m_request, m_result)); - } - bool PositionModify( - const ulong ticket, // Position Ticket - const double sl, // Stop Loss - const double tp, // Take Profit - const string comment = "" // Comment For Modify - ) - { - // - // check stopped - if (IsStopped(__FUNCTION__)) - { - return (false); - } - - // - // check position existence - if (!PositionSelectByTicket(ticket)) - { - return (false); - } - - // - // clean - ClearStructures(); - - // - // setting request - m_request.action = TRADE_ACTION_SLTP; - m_request.position = ticket; - m_request.symbol = PositionGetString(POSITION_SYMBOL); - m_request.magic = m_magic; - m_request.sl = sl; - m_request.tp = tp; - - // - // Specified Comment ... - if (StringLen(comment) > 0) - { - m_request.comment = comment; - } - - // - // action and return the result - return (OrderSend(m_request, m_result)); - } - - // - // Close Specific Position, by Specific Comment ... - bool PositionClose( - const string symbol, // Symbol - const ulong deviation, // Deviation - const string comment = "" // Comment For Close - ) - { - // - bool partial_close = false; - int retry_count = 10; - uint retcode = TRADE_RETCODE_REJECT; - - // - // check stopped - if (IsStopped(__FUNCTION__)) - { - return (false); - } - - // - // clean - ClearStructures(); - - // - // check filling - if (!FillingCheck(symbol)) - { - return (false); - } - - // - do - { - // - // check - if (SelectPosition(symbol)) - { - // - if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) - { - // - // prepare request for close BUY position - m_request.type = ORDER_TYPE_SELL; - m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); - } - else - { - // - // prepare request for close SELL position - m_request.type = ORDER_TYPE_BUY; - m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); - } - } - else - { - // - // position not found - m_result.retcode = retcode; - return (false); - } - - // - // setting request - m_request.action = TRADE_ACTION_DEAL; - m_request.symbol = symbol; - m_request.volume = PositionGetDouble(POSITION_VOLUME); - m_request.magic = m_magic; - m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; - m_request.position = PositionGetInteger(POSITION_TICKET); - - // - // Specify Comment ... - m_request.comment = comment; - - // - // check volume - double max_volume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); - if (m_request.volume > max_volume) - { - // - m_request.volume = max_volume; - partial_close = true; - } - else - { - partial_close = false; - } - - // - // hedging? just send order - if (IsHedging()) - { - return (OrderSend(m_request, m_result)); - } - - // - // order send - if (!OrderSend(m_request, m_result)) - { - // - if (--retry_count != 0) - { - continue; - } - - // - if (retcode == TRADE_RETCODE_DONE_PARTIAL) - { - m_result.retcode = retcode; - } - - // - return (false); - } - - // - //--- WARNING. If position volume exceeds the maximum volume allowed for deal, - //--- and when the asynchronous trade mode is on, for safety reasons, position is closed not completely, - //--- but partially. It is decreased by the maximum volume allowed for deal. - if (m_async_mode) - { - break; - } - - // - retcode = TRADE_RETCODE_DONE_PARTIAL; - if (partial_close) - { - Sleep(1000); - } - } while (partial_close); - - // - // succeed - return (true); - } - bool PositionClose( - const ulong ticket, // Position Ticket - const ulong deviation, // Deviation - const string comment = "" // Comment For Close - ) - { - // - // check stopped - if (IsStopped(__FUNCTION__)) - { - return (false); - } - - // - // check position existence - if (!PositionSelectByTicket(ticket)) - { - return (false); - } - - // - string symbol = PositionGetString(POSITION_SYMBOL); - - // - // clean - ClearStructures(); - - // - // check filling - if (!FillingCheck(symbol)) - { - return (false); - } - - // - // check - if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) - { - // - // prepare request for close BUY position - m_request.type = ORDER_TYPE_SELL; - m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); - } - else - { - // - // prepare request for close SELL position - m_request.type = ORDER_TYPE_BUY; - m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); - } - - // - // setting request - m_request.action = TRADE_ACTION_DEAL; - m_request.position = ticket; - m_request.symbol = symbol; - m_request.volume = PositionGetDouble(POSITION_VOLUME); - m_request.magic = m_magic; - m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; - - // - // Specify Comment ... - m_request.comment = comment; - - // - // close position - return (OrderSend(m_request, m_result)); - } - - // - // Partial Close Specific Position, by Specific Comment ... - bool PositionClosePartial( - const string symbol, // Symbol - const double volume, // Partial Closing Volume - const ulong deviation, // Deviation - const string comment = "" // Comment For Close - ) - { - // - uint retcode = TRADE_RETCODE_REJECT; - - // - // check stopped - if (IsStopped(__FUNCTION__)) - { - return (false); - } - - // - // for hedging mode only - if (!IsHedging()) - { - return (false); - } - - // - // clean - ClearStructures(); - - // - // check filling - if (!FillingCheck(symbol)) - { - return (false); - } - - // - // check - if (SelectPosition(symbol)) - { - // - if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) - { - // - // prepare request for close BUY position - m_request.type = ORDER_TYPE_SELL; - m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); - } - else - { - // - // prepare request for close SELL position - m_request.type = ORDER_TYPE_BUY; - m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); - } - } - else - { - // - // position not found - m_result.retcode = retcode; - return (false); - } - - // - // check volume - double position_volume = PositionGetDouble(POSITION_VOLUME); - if (position_volume > volume) - { - position_volume = volume; - } - - // - // setting request - m_request.action = TRADE_ACTION_DEAL; - m_request.symbol = symbol; - m_request.volume = position_volume; - m_request.magic = m_magic; - m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; - m_request.position = PositionGetInteger(POSITION_TICKET); - - // - // Specifieng Comment ... - m_request.comment = comment; - - // - // hedging? just send order - return (OrderSend(m_request, m_result)); - } - bool PositionClosePartial( - const ulong ticket, // Position Ticket - const double volume, // Partial Closing Volume - const ulong deviation, // Deviation - const string comment = "" // Comment For Close - ) - { - // - // check stopped - if (IsStopped(__FUNCTION__)) - { - return (false); - } - - // - // for hedging mode only - if (!IsHedging()) - { - return (false); - } - - // - // check position existence - if (!PositionSelectByTicket(ticket)) - { - return (false); - } - - // - string symbol = PositionGetString(POSITION_SYMBOL); - - // - // clean - ClearStructures(); - - // - // check filling - if (!FillingCheck(symbol)) - { - return (false); - } - - // - // check - if ((ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) - { - // - // prepare request for close BUY position - m_request.type = ORDER_TYPE_SELL; - m_request.price = SymbolInfoDouble(symbol, SYMBOL_BID); - } - else - { - // - // prepare request for close SELL position - m_request.type = ORDER_TYPE_BUY; - m_request.price = SymbolInfoDouble(symbol, SYMBOL_ASK); - } - - // - // check volume - double position_volume = PositionGetDouble(POSITION_VOLUME); - if (position_volume > volume) - { - position_volume = volume; - } - - // - // setting request - m_request.action = TRADE_ACTION_DEAL; - m_request.position = ticket; - m_request.symbol = symbol; - m_request.volume = position_volume; - m_request.magic = m_magic; - m_request.deviation = (deviation == ULONG_MAX) ? m_deviation : deviation; - - // - // Specifieng Comment ... - m_request.comment = comment; - - // - // close position - return (OrderSend(m_request, m_result)); - } -}; -// -// END Overrides ... -// - -// -// START Global Definitions: Variables, Properties and etc ... -// - -// -// XCMD5 a library for Hashing ... -class XCMD5 : public XCBase -{ - // - // Public Provides ... -public: - // - // Protected Provides ... - - // - // Constructor ... - XCMD5(void) {} - - // - // Deconstructor ... - ~XCMD5(void) {} - - // - // Hash Specified Char Array ... - string Hash( - uchar &source[], // Specify Char Array to Hash - int length = 0 // Specify Length of Char Array which required to hash - ) - { - // - string result = ""; - - // - int sourceCount = ArraySize(source); - - // - // Validate Args ... - if ( - sourceCount <= 0 || - (sourceCount > 0 && length > sourceCount)) - { - return result; - } - - // - // Normalize Args ... - if (length == 0) - { - length = sourceCount; - } - - // - // Init MD5 ... - MD5Init(); - - // - // Update Buffer ... - MD5Update(source, length); - - // - // Calculate Result ... - result = MD5Final(); - - // - return result; - } - - // - // Hash Specified String ... - string Hash( - string source // Specified String - ) - { - // - string result = ""; - - // - // Converts String to Char Array ... - uchar bytes[]; - StringToCharArray( - source, - bytes, - 0, - StringLen(source)); - - // - result = Hash( - bytes, - ArraySize(bytes)); - - // - return result; - } - -protected: - // - // Private Provides ... -private: - // - uint m_lMD5[4]; - uint m_nCount[2]; - uchar m_lpszBuffer[64]; - - // - // Convert Byte to DWord ... - void ByteToDWord(int &out[], uint &in[], uint len) - { - // - uint i = 0; - uint j = 0; - - // - for (; j < len; i++, j += 4) - { - out[i] = (int)in[j] | (int)in[j + 1] << 8 | (int)in[j + 2] << 16 | (int)in[j + 3] << 24; - } - } - - // - // Convert DWord to Byte ... - void DWordToByte(uchar &out[], int &in[], uint len) - { - // - uint i = 0; - uint j = 0; - - // - for (; j < len; i++, j += 4) - { - // - out[j] = (uchar)(in[i] & 0xff); - out[j + 1] = (uchar)((in[i] >> 8) & 0xff); - out[j + 2] = (uchar)((in[i] >> 16) & 0xff); - out[j + 3] = (uchar)((in[i] >> 24) & 0xff); - } - } - - // - // Init MD5 Array ... - void MD5Init() - { - // - ArrayInitialize(m_lpszBuffer, 64); - - // - m_nCount[0] = m_nCount[1] = 0; - m_lMD5[0] = _md5_INIT_STATE_0; - m_lMD5[1] = _md5_INIT_STATE_1; - m_lMD5[2] = _md5_INIT_STATE_2; - m_lMD5[3] = _md5_INIT_STATE_3; - } - - // - // Update MD5 ... - void MD5Update(uchar &inBuf[], uint inLen) - { - // - int i, ii; - int mdi; - - // - uint in[16]; - int i0 = 0; - - // - mdi = (int)((m_nCount[0] >> 3) & 0x3F); - - // - if ((m_nCount[0] + ((uint)inLen << 3)) < m_nCount[0]) - { - m_nCount[1]++; - } - - // - m_nCount[0] += ((uint)inLen << 3); - m_nCount[1] += ((uint)inLen >> 29); - - // - while ((inLen--) > 0) - { - // - m_lpszBuffer[mdi++] = inBuf[i0++]; - if (mdi == 0x40) - { - // - for (i = 0, ii = 0; i < 16; i++, ii += 4) - { - in[i] = (((uint)m_lpszBuffer[ii + 3]) << 24) | (((uint)m_lpszBuffer[ii + 2]) << 16) | (((uint)m_lpszBuffer[ii + 1]) << 8) | ((uint)m_lpszBuffer[ii]); - } - - // - Transform(m_lMD5, in); - - // - mdi = 0; - } - } - } - - // - // Finalize an MD5 Expression ... - string MD5Final() - { - // - uchar bits[8]; - int nIndex; - uint nPadLen; - const int nMD5Size = 16; - uchar lpszMD5[16]; - string temp; - string out = ""; - int i; - - // - DWordToByte(bits, m_nCount, 8); - nIndex = (int)((m_nCount[0] >> 3) & 0x3f); - nPadLen = (nIndex < 56) ? (56 - nIndex) : (120 - nIndex); - MD5Update(_md5_PADDING, nPadLen); - MD5Update(bits, 8); - DWordToByte(lpszMD5, m_lMD5, nMD5Size); - - // - for (i = 0; i < nMD5Size; i++) - { - // - if (lpszMD5[i] == 0) - { - temp = "00"; - } - else if (lpszMD5[i] <= 15) - { - temp = StringFormat("0%x", lpszMD5[i]); - } - else - { - temp = StringFormat("%x", lpszMD5[i]); - } - - // - out += temp; - } - - // - lpszMD5[0] = '\0'; - - // - return (out); - } - - // - // Transform Buffers ... - void Transform(uint &buf[], uint &in[]) - { - // - uint a = buf[0], b = buf[1], c = buf[2], d = buf[3]; - - // - _md5_FF(a, b, c, d, in[0], _md5_S11, 0xD76AA478); - _md5_FF(d, a, b, c, in[1], _md5_S12, 0xE8C7B756); - _md5_FF(c, d, a, b, in[2], _md5_S13, 0x242070DB); - _md5_FF(b, c, d, a, in[3], _md5_S14, 0xC1BDCEEE); - _md5_FF(a, b, c, d, in[4], _md5_S11, 0xF57C0FAF); - _md5_FF(d, a, b, c, in[5], _md5_S12, 0x4787C62A); - _md5_FF(c, d, a, b, in[6], _md5_S13, 0xA8304613); - _md5_FF(b, c, d, a, in[7], _md5_S14, 0xFD469501); - _md5_FF(a, b, c, d, in[8], _md5_S11, 0x698098D8); - _md5_FF(d, a, b, c, in[9], _md5_S12, 0x8B44F7AF); - _md5_FF(c, d, a, b, in[10], _md5_S13, 0xFFFF5BB1); - _md5_FF(b, c, d, a, in[11], _md5_S14, 0x895CD7BE); - _md5_FF(a, b, c, d, in[12], _md5_S11, 0x6B901122); - _md5_FF(d, a, b, c, in[13], _md5_S12, 0xFD987193); - _md5_FF(c, d, a, b, in[14], _md5_S13, 0xA679438E); - _md5_FF(b, c, d, a, in[15], _md5_S14, 0x49B40821); - - // - _md5_GG(a, b, c, d, in[1], _md5_S21, 0xF61E2562); - _md5_GG(d, a, b, c, in[6], _md5_S22, 0xC040B340); - _md5_GG(c, d, a, b, in[11], _md5_S23, 0x265E5A51); - _md5_GG(b, c, d, a, in[0], _md5_S24, 0xE9B6C7AA); - _md5_GG(a, b, c, d, in[5], _md5_S21, 0xD62F105D); - _md5_GG(d, a, b, c, in[10], _md5_S22, 0x02441453); - _md5_GG(c, d, a, b, in[15], _md5_S23, 0xD8A1E681); - _md5_GG(b, c, d, a, in[4], _md5_S24, 0xE7D3FBC8); - _md5_GG(a, b, c, d, in[9], _md5_S21, 0x21E1CDE6); - _md5_GG(d, a, b, c, in[14], _md5_S22, 0xC33707D6); - _md5_GG(c, d, a, b, in[3], _md5_S23, 0xF4D50D87); - _md5_GG(b, c, d, a, in[8], _md5_S24, 0x455A14ED); - _md5_GG(a, b, c, d, in[13], _md5_S21, 0xA9E3E905); - _md5_GG(d, a, b, c, in[2], _md5_S22, 0xFCEFA3F8); - _md5_GG(c, d, a, b, in[7], _md5_S23, 0x676F02D9); - _md5_GG(b, c, d, a, in[12], _md5_S24, 0x8D2A4C8A); - - // - _md5_HH(a, b, c, d, in[5], _md5_S31, 0xFFFA3942); - _md5_HH(d, a, b, c, in[8], _md5_S32, 0x8771F681); - _md5_HH(c, d, a, b, in[11], _md5_S33, 0x6D9D6122); - _md5_HH(b, c, d, a, in[14], _md5_S34, 0xFDE5380C); - _md5_HH(a, b, c, d, in[1], _md5_S31, 0xA4BEEA44); - _md5_HH(d, a, b, c, in[4], _md5_S32, 0x4BDECFA9); - _md5_HH(c, d, a, b, in[7], _md5_S33, 0xF6BB4B60); - _md5_HH(b, c, d, a, in[10], _md5_S34, 0xBEBFBC70); - _md5_HH(a, b, c, d, in[13], _md5_S31, 0x289B7EC6); - _md5_HH(d, a, b, c, in[0], _md5_S32, 0xEAA127FA); - _md5_HH(c, d, a, b, in[3], _md5_S33, 0xD4EF3085); - _md5_HH(b, c, d, a, in[6], _md5_S34, 0x04881D05); - _md5_HH(a, b, c, d, in[9], _md5_S31, 0xD9D4D039); - _md5_HH(d, a, b, c, in[12], _md5_S32, 0xE6DB99E5); - _md5_HH(c, d, a, b, in[15], _md5_S33, 0x1FA27CF8); - _md5_HH(b, c, d, a, in[2], _md5_S34, 0xC4AC5665); - - // - _md5_II(a, b, c, d, in[0], _md5_S41, 0xF4292244); - _md5_II(d, a, b, c, in[7], _md5_S42, 0x432AFF97); - _md5_II(c, d, a, b, in[14], _md5_S43, 0xAB9423A7); - _md5_II(b, c, d, a, in[5], _md5_S44, 0xFC93A039); - _md5_II(a, b, c, d, in[12], _md5_S41, 0x655B59C3); - _md5_II(d, a, b, c, in[3], _md5_S42, 0x8F0CCC92); - _md5_II(c, d, a, b, in[10], _md5_S43, 0xFFEFF47D); - _md5_II(b, c, d, a, in[1], _md5_S44, 0x85845DD1); - _md5_II(a, b, c, d, in[8], _md5_S41, 0x6FA87E4F); - _md5_II(d, a, b, c, in[15], _md5_S42, 0xFE2CE6E0); - _md5_II(c, d, a, b, in[6], _md5_S43, 0xA3014314); - _md5_II(b, c, d, a, in[13], _md5_S44, 0x4E0811A1); - _md5_II(a, b, c, d, in[4], _md5_S41, 0xF7537E82); - _md5_II(d, a, b, c, in[11], _md5_S42, 0xBD3AF235); - _md5_II(c, d, a, b, in[2], _md5_S43, 0x2AD7D2BB); - _md5_II(b, c, d, a, in[9], _md5_S44, 0xEB86D391); - - // - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; - } -}; - -// -// XSaherElm Account Info Class ... -class XCAccountInfo : public XCBase -{ - // - // Public properties ... -public: - // - // Constructro ... - void XCAccountInfo() - { - // - mAccountInfo = new CAccountInfo(); - - // - mInitialBalance = mAccountInfo.Balance(); - } - - // - // Deconstructor ... - void ~XCAccountInfo() - { - // - mInitialBalance = 0; - } - - // - // User Account ... - long GetUserAccount() - { - return mAccountInfo.Login(); - } - - // - // Account Leverage ... - long GetLeverage() - { - return mAccountInfo.Leverage(); - } - - // - // Get Trade Expert State ... - bool CanExpertTrade() - { - return mAccountInfo.TradeExpert(); - } - - // - // User Account Trade Mopde (ENUM_ACCOUNT_TRADE_MODE) ... - // -------------------------- - // ACCOUNT_TRADE_MODE_DEMO - // ACCOUNT_TRADE_MODE_CONTEST - // ACCOUNT_TRADE_MODE_REAL - ENUM_ACCOUNT_TRADE_MODE GetTradeMode() - { - return mAccountInfo.TradeMode(); - } - - // - // Get Account Balance ... - double GetBalance() - { - return mAccountInfo.Balance(); - } - - // - // Get Initial Deposit Balance ... - double GetInitialBalance() - { - return mInitialBalance; - } - - // - // Get the amount of give Credit ... - double GetCredit() - { - return mAccountInfo.Credit(); - } - - // - // Get the amount of current Profit on account ... - double GetProfit() - { - return mAccountInfo.Profit(); - } - - // - // Get the amount of current Equity on account ... - double GetEquity() - { - return mAccountInfo.Equity(); - } - - // - // Get the amount of reserved Margin ... - double GetMargin() - { - return mAccountInfo.Margin(); - } - - // - // Get the amount of free Margin ... - double GetFreeMargin() - { - return mAccountInfo.FreeMargin(); - } - - // - // Get the Level of Margin ... - double GetMarginLevel() - { - return mAccountInfo.MarginLevel(); - } - - // - // Get the Level Of Margin for a Deposit ... - double GetMarginCall() - { - return mAccountInfo.MarginCall(); - } - - // - // Get the Level of Margin for Stop out ... - double GetMarginStopOut() - { - return mAccountInfo.MarginStopOut(); - } - - // - // Get the Client Name ... - string GetName() - { - return mAccountInfo.Name(); - } - - // - // Get the Trade Server Name ... - string GetServerName() - { - return mAccountInfo.Server(); - } - - // - // Get deposit Currency Name ... - string GetCurrency() - { - return mAccountInfo.Currency(); - } - - // - // Get the Company Name that serves an Account ... - string GetCompany() - { - return mAccountInfo.Company(); - } - - // - // Calculate Profits for the current account based on passed parameters ... - double CalculateTradeProfit( - const string symbol, // trading symbol - ENUM_ORDER_TYPE type, // order type - double volume, // volume - double entry, // open price - double exit // close price - ) - { - // - double result = mAccountInfo.OrderProfitCheck( - symbol, - type, - volume, - entry, - exit); - - // - return result; - } - - // - // Calculate amount of margin which required for trade operation ... - double CalculateMarging( - const string symbol, // trading symbol - ENUM_ORDER_TYPE type, // order type - double volume, // volume - double entry // open price - ) - { - // - double result = mAccountInfo.MarginCheck( - symbol, - type, - volume, - entry); - - // - return result; - } - - // - // Calculate amount of free margin left after trade operation ... - double CalculateFreeMarging( - const string symbol, // trading symbol - ENUM_ORDER_TYPE type, // order type - double volume, // volume - double entry // open price - ) - { - // - double result = mAccountInfo.FreeMarginCheck( - symbol, - type, - volume, - entry); - - // - return result; - } - - // - // Calculate the Maximum possible volume of trade operation ... - double CalculateMaxVolume( - const string symbol, // trading symbol - ENUM_ORDER_TYPE type, // order type - double entry, // open price - double percent = 100 // percent of available margin - ) - { - // - double result = mAccountInfo.MaxLotCheck( - symbol, - type, - entry, - percent); - - // - return result; - } - - // - // Protected properties ... -protected: - // - // Private properties ... -private: - // - // Initial Account Balance ... - double mInitialBalance; - - // - // Account Info ... - CAccountInfo mAccountInfo; -}; - -// -// XSaherElm Report Info Class ... -class XCReporter : public XCBase -{ - // - // Public Provided ... -public: - // - // Constructro ... - void XCReporter() - { - // - mAccountInfo = new XCAccountInfo(); - - // - Reset(); - } - - // - // Deconstructor ... - void ~XCReporter() - { - } - - // - // Reset Specific Report ... - void Reset( - ENUM_XREPORT_TYPES type // Specify Report Type - ) - { - CleanReport(type); - } - - // - // Reset All Reports ... - void Reset() - { - // - CleanReport(XREPORT_MAIN); - CleanReport(XREPORT_MONTHLY); - CleanReport(XREPORT_WEEKLY); - CleanReport(XREPORT_DAILY); - } - - // - // Update Volume Info ... - void UpdateReportVolumeInfo( - ENUM_XREPORT_TYPES type, // Specified Report Type - // - double staticVolume, // Current Available Static Volume - string staticVolumeCalculationMethod, // Static Volume Calculation Method - double maxAllowedVolume, // Current Maximum Appliable Volume - double volumeIncreaseMultiplier, // Static Volume Increase Multiplier - double balanceGowingToApplyMultiplier, // Multiply Volume Based On Balance Growing - double balanceGrowingToIncreaseMaxAllowedVolume // Where to Increase MaxAllowed Volume - ) - { - // - // Filling Account Info ... - FillReportAccountInfo(type); - - // - switch (type) - { - // - // Main ... - case XREPORT_MAIN: - // - FillingVolumeInfo( - mMainReport, - staticVolume, - staticVolumeCalculationMethod, - maxAllowedVolume, - volumeIncreaseMultiplier, - balanceGowingToApplyMultiplier, - balanceGrowingToIncreaseMaxAllowedVolume); - break; - - // - // Monthly ... - case XREPORT_MONTHLY: - // - FillingVolumeInfo( - mMonthlyReport, - staticVolume, - staticVolumeCalculationMethod, - maxAllowedVolume, - volumeIncreaseMultiplier, - balanceGowingToApplyMultiplier, - balanceGrowingToIncreaseMaxAllowedVolume); - break; - - // - // Weekly ... - case XREPORT_WEEKLY: - // - FillingVolumeInfo( - mWeeklyReport, - staticVolume, - staticVolumeCalculationMethod, - maxAllowedVolume, - volumeIncreaseMultiplier, - balanceGowingToApplyMultiplier, - balanceGrowingToIncreaseMaxAllowedVolume); - break; - - // - // Daily ... - case XREPORT_DAILY: - // - FillingVolumeInfo( - mDailyReport, - staticVolume, - staticVolumeCalculationMethod, - maxAllowedVolume, - volumeIncreaseMultiplier, - balanceGowingToApplyMultiplier, - balanceGrowingToIncreaseMaxAllowedVolume); - break; - } - } - - // - // Update Volume Info on All Reports ... - void UpdateReportsVolumeInfo( - double staticVolume, // Current Available Static Volume - string staticVolumeCalculationMethod, // Static Volume Calculation Method - double maxAllowedVolume, // Current Maximum Appliable Volume - double volumeIncreaseMultiplier, // Static Volume Increase Multiplier - double balanceGowingToApplyMultiplier, // Multiply Volume Based On Balance Growing - double balanceGrowingToIncreaseMaxAllowedVolume // Where to Increase MaxAllowed Volume - ) - { - // - // Main ... - UpdateReportVolumeInfo( - XREPORT_MAIN, - staticVolume, - staticVolumeCalculationMethod, - maxAllowedVolume, - volumeIncreaseMultiplier, - balanceGowingToApplyMultiplier, - balanceGrowingToIncreaseMaxAllowedVolume); - - // - // Monthly ... - UpdateReportVolumeInfo( - XREPORT_MONTHLY, - staticVolume, - staticVolumeCalculationMethod, - maxAllowedVolume, - volumeIncreaseMultiplier, - balanceGowingToApplyMultiplier, - balanceGrowingToIncreaseMaxAllowedVolume); - - // - // Weekly ... - UpdateReportVolumeInfo( - XREPORT_WEEKLY, - staticVolume, - staticVolumeCalculationMethod, - maxAllowedVolume, - volumeIncreaseMultiplier, - balanceGowingToApplyMultiplier, - balanceGrowingToIncreaseMaxAllowedVolume); - - // - // Daily ... - UpdateReportVolumeInfo( - XREPORT_DAILY, - staticVolume, - staticVolumeCalculationMethod, - maxAllowedVolume, - volumeIncreaseMultiplier, - balanceGowingToApplyMultiplier, - balanceGrowingToIncreaseMaxAllowedVolume); - } - - // - // Add Specific Signal to Report ... - void AddSignalToReport( - ENUM_XREPORT_TYPES type, // Specified Report Type - const XSignal &signal, // Specified Signal - const string &providers[] // Specified Signal Providers - ) - { - // - // - // Filling Account Info ... - FillReportAccountInfo(type); - - // - switch (type) - { - // - // Main ... - case XREPORT_MAIN: - AddSignalToReport( - mMainReport, - signal, - providers); - break; - - // - // Monthly ... - case XREPORT_MONTHLY: - AddSignalToReport( - mMonthlyReport, - signal, - providers); - break; - - // - // Weekly ... - case XREPORT_WEEKLY: - AddSignalToReport( - mWeeklyReport, - signal, - providers); - break; - - // - // Daily ... - case XREPORT_DAILY: - AddSignalToReport( - mDailyReport, - signal, - providers); - break; - } - } - - // - // Add Specific Signal to All Reports ... - void AddSignalToReports( - const XSignal &signal, // Specified Signal - const string &providers[] // Specified Signal Providers - ) - { - // - // Main ... - AddSignalToReport( - XREPORT_MAIN, - signal, - providers); - - // - // Monthly ... - AddSignalToReport( - XREPORT_MONTHLY, - signal, - providers); - - // - // Weekly ... - AddSignalToReport( - XREPORT_WEEKLY, - signal, - providers); - - // - // Daily ... - AddSignalToReport( - XREPORT_DAILY, - signal, - providers); - } - - // - // Report a TP for Specific Report ... - void AddTradeTPInReport( - ENUM_XREPORT_TYPES type // Specified Report Type - ) - { - // - switch (type) - { - // - // Main ... - case XREPORT_MAIN: - AddTradeTPInReport(mMainReport); - break; - - // - // Monthly ... - case XREPORT_MONTHLY: - AddTradeTPInReport(mMonthlyReport); - break; - - // - // Weekly ... - case XREPORT_WEEKLY: - AddTradeTPInReport(mWeeklyReport); - break; - - // - // Daily ... - case XREPORT_DAILY: - AddTradeTPInReport(mDailyReport); - break; - } - } - - // - // Report a TP for All Reports ... - void AddTradeTPInReports() - { - // - // Main ... - AddTradeTPInReport(XREPORT_MAIN); - - // - // Monthly ... - AddTradeTPInReport(XREPORT_MONTHLY); - - // - // Weekly ... - AddTradeTPInReport(XREPORT_WEEKLY); - - // - // Daily ... - AddTradeTPInReport(XREPORT_DAILY); - } - - // - // Report a SL for Specific Report ... - void AddTradeSLInReport( - ENUM_XREPORT_TYPES type // Specified Report Type - ) - { - // - switch (type) - { - // - // Main ... - case XREPORT_MAIN: - AddTradeSLInReport(mMainReport); - break; - - // - // Monthly ... - case XREPORT_MONTHLY: - AddTradeSLInReport(mMonthlyReport); - break; - - // - // Weekly ... - case XREPORT_WEEKLY: - AddTradeSLInReport(mWeeklyReport); - break; - - // - // Daily ... - case XREPORT_DAILY: - AddTradeSLInReport(mDailyReport); - break; - } - } - - // - // Report a SL for All Reports ... - void AddTradeSLInReports() - { - // - // Main ... - AddTradeSLInReport(XREPORT_MAIN); - - // - // Monthly ... - AddTradeSLInReport(XREPORT_MONTHLY); - - // - // Weekly ... - AddTradeSLInReport(XREPORT_WEEKLY); - - // - // Daily ... - AddTradeSLInReport(XREPORT_DAILY); - } - - // - // Update Number of Same Time Trades in Specific Report ... - void UpdateMaxSameTimeTradesInReport( - ENUM_XREPORT_TYPES type, // Specified Report Type - int value // number of same time trades - ) - { - // - switch (type) - { - // - // Main ... - case XREPORT_MAIN: - UpdateMaxSameTimeTradesInReport( - mMainReport, - value); - break; - - // - // Monthly ... - case XREPORT_MONTHLY: - UpdateMaxSameTimeTradesInReport( - mMonthlyReport, - value); - break; - - // - // Weekly ... - case XREPORT_WEEKLY: - UpdateMaxSameTimeTradesInReport( - mWeeklyReport, - value); - break; - - // - // Daily ... - case XREPORT_DAILY: - UpdateMaxSameTimeTradesInReport( - mDailyReport, - value); - break; - } - } - - // - // Update Number of Same Time Trades in All Report ... - void UpdateMaxSameTimeTradesInReports( - int value // number of same time trades - ) - { - // - // Main ... - UpdateMaxSameTimeTradesInReport( - XREPORT_MAIN, - value); - - // - // Monthly ... - UpdateMaxSameTimeTradesInReport( - XREPORT_MONTHLY, - value); - - // - // Weekly ... - UpdateMaxSameTimeTradesInReport( - XREPORT_WEEKLY, - value); - - // - // Daily ... - UpdateMaxSameTimeTradesInReport( - XREPORT_DAILY, - value); - } - - // - // Update Max DrawDown in Specific Report ... - void UpdateMaxDrawDownInReport( - ENUM_XREPORT_TYPES type, // Specified Report Type - double value // draw down value - ) - { - // - switch (type) - { - // - // Main ... - case XREPORT_MAIN: - UpdateMaxDrawDownInReport( - mMainReport, - value); - break; - - // - // Monthly ... - case XREPORT_MONTHLY: - UpdateMaxDrawDownInReport( - mMonthlyReport, - value); - break; - - // - // Weekly ... - case XREPORT_WEEKLY: - UpdateMaxDrawDownInReport( - mWeeklyReport, - value); - break; - - // - // Daily ... - case XREPORT_DAILY: - UpdateMaxDrawDownInReport( - mDailyReport, - value); - break; - } - } - - // - // Update Max DrawDown in All Report ... - void UpdateMaxDrawDownInReports( - double value // draw down value - ) - { - // - // Main ... - UpdateMaxDrawDownInReport( - XREPORT_MAIN, - value); - - // - // Monthly ... - UpdateMaxDrawDownInReport( - XREPORT_MONTHLY, - value); - - // - // Weekly ... - UpdateMaxDrawDownInReport( - XREPORT_WEEKLY, - value); - - // - // Daily ... - UpdateMaxDrawDownInReport( - XREPORT_DAILY, - value); - } - - // - // Update Max DrawUp in Specific Report ... - void UpdateMaxDrawUpInReport( - ENUM_XREPORT_TYPES type, // Specified Report Type - double value // draw up value - ) - { - // - switch (type) - { - // - // Main ... - case XREPORT_MAIN: - UpdateMaxDrawUpInReport( - mMainReport, - value); - break; - - // - // Monthly ... - case XREPORT_MONTHLY: - UpdateMaxDrawUpInReport( - mMonthlyReport, - value); - break; - - // - // Weekly ... - case XREPORT_WEEKLY: - UpdateMaxDrawUpInReport( - mWeeklyReport, - value); - break; - - // - // Daily ... - case XREPORT_DAILY: - UpdateMaxDrawUpInReport( - mDailyReport, - value); - break; - } - } - - // - // Update Max DrawUp in All Report ... - void UpdateMaxDrawUpInReports( - double value // draw up value - ) - { - // - // Main ... - UpdateMaxDrawUpInReport( - XREPORT_MAIN, - value); - - // - // Monthly ... - UpdateMaxDrawUpInReport( - XREPORT_MONTHLY, - value); - - // - // Weekly ... - UpdateMaxDrawUpInReport( - XREPORT_WEEKLY, - value); - - // - // Daily ... - UpdateMaxDrawUpInReport( - XREPORT_DAILY, - value); - } - - // - // Update Min Balance for Open Trades in Specific Report ... - void UpdateMinBalanceForOpenTradesInReport( - ENUM_XREPORT_TYPES type, // Specified Report Type - double value // min balance for open trades - ) - { - // - switch (type) - { - // - // Main ... - case XREPORT_MAIN: - UpdateMinBalanceForOpenTradesInReport( - mMainReport, - value); - break; - - // - // Monthly ... - case XREPORT_MONTHLY: - UpdateMinBalanceForOpenTradesInReport( - mMonthlyReport, - value); - break; - - // - // Weekly ... - case XREPORT_WEEKLY: - UpdateMinBalanceForOpenTradesInReport( - mWeeklyReport, - value); - break; - - // - // Daily ... - case XREPORT_DAILY: - UpdateMinBalanceForOpenTradesInReport( - mDailyReport, - value); - break; - } - } - - // - // Update Min Balance for Open Trades in All Report ... - void UpdateMinBalanceForOpenTradesInReports( - double value // min balance for open trades - ) - { - // - // Main ... - UpdateMinBalanceForOpenTradesInReport( - XREPORT_MAIN, - value); - - // - // Monthly ... - UpdateMinBalanceForOpenTradesInReport( - XREPORT_MONTHLY, - value); - - // - // Weekly ... - UpdateMinBalanceForOpenTradesInReport( - XREPORT_WEEKLY, - value); - - // - // Daily ... - UpdateMinBalanceForOpenTradesInReport( - XREPORT_DAILY, - value); - } - - // - // Gnerate Specific Type Of Report String Representation ... - string GenerateReportString( - ENUM_XREPORT_TYPES type, // Specified Report Type - string separator = "\n" // Separator - ) - { - // - string result = ""; - - // - switch (type) - { - // - // Main ... - case XREPORT_MAIN: - result = GenerateReportString( - mMainReport, - separator); - break; - - // - // Monthly ... - case XREPORT_MONTHLY: - result = GenerateReportString( - mMonthlyReport, - separator); - break; - - // - // Weekly ... - case XREPORT_WEEKLY: - result = GenerateReportString( - mWeeklyReport, - separator); - break; - - // - // Daily ... - case XREPORT_DAILY: - result = GenerateReportString( - mDailyReport, - separator); - break; - } - - // - return result; - } - - // - // Protected Provided ... -protected: - // - // Private Provided ... -private: - // - // Account Info Instance ... - XCAccountInfo mAccountInfo; - - // - // Main Report ... - XReport mMainReport; - - // - // Monthly Report ... - XReport mMonthlyReport; - - // - // Weekly Report ... - XReport mWeeklyReport; - - // - // Daily Report ... - XReport mDailyReport; - - // - // Clean Specific Report ... - void CleanReport( - XReport &report // Specified Report - ) - { - // - datetime time = TimeCurrent(); - - // - // Reset Times ... - report.start = time; - report.end = -1; - - // - // Reset Account Info ... - FillReportAccountInfo(report); - - // - // Reset Summary Info ... - report.summaryInfo.maxDrawUp = 0; - report.summaryInfo.maxDrawDown = 0; - report.summaryInfo.longSignals = 0; - report.summaryInfo.numberOfTPs = 0; - report.summaryInfo.numberOfSLs = 0; - report.summaryInfo.shortSignals = 0; - report.summaryInfo.maxSignalVolume = 0; - report.summaryInfo.maxSameTimeSignals = 0; - - // - // Reset Volume Info ... - report.volumeInfo.staticVolume = 0; - report.volumeInfo.maxAllowedVolume = 0; - report.volumeInfo.volumeIncreaseMultiplier = 0; - report.volumeInfo.balanceGowingToApplyMultiplier = 0; - report.volumeInfo.staticVolumeCalculationMethod = NULL; - report.volumeInfo.balanceGrowingToIncreaseMaxAllowedVolume = 0; - - // - // Reset Signallers Info ... - CleanBuffer(report.signallersInfo); - } - void CleanReport( - ENUM_XREPORT_TYPES type // Specify Report Type - ) - { - // - switch (type) - { - // - // Main ... - case XREPORT_MAIN: - CleanReport(mMainReport); - break; - - // - // Monthly ... - case XREPORT_MONTHLY: - CleanReport(mMonthlyReport); - break; - - // - // Weekly ... - case XREPORT_WEEKLY: - CleanReport(mWeeklyReport); - break; - - // - // Daily ... - case XREPORT_DAILY: - CleanReport(mDailyReport); - break; - } - } - - // - // Update Specific Reports End Time ... - void FillReportEndTime( - XReport &report // Specified Report - ) - { - // - datetime time = TimeCurrent(); - report.end = time; - } - - // - // Filleing Report Account Info ... - void FillReportAccountInfo( - XReport &report // Specified Report - ) - { - // - FillReportEndTime(report); - - // - report.accountInfo.user = (string)mAccountInfo.GetUserAccount(); - report.accountInfo.name = mAccountInfo.GetName(); - report.accountInfo.server = mAccountInfo.GetServerName(); - report.accountInfo.broker = mAccountInfo.GetCompany(); - report.accountInfo.mode = mAccountInfo.GetTradeMode(); - report.accountInfo.leverage = mAccountInfo.GetLeverage(); - report.accountInfo.currency = mAccountInfo.GetCurrency(); - report.accountInfo.deposit = mAccountInfo.GetInitialBalance(); - report.accountInfo.balance = mAccountInfo.GetBalance(); - } - void FillReportAccountInfo( - ENUM_XREPORT_TYPES type // Specify Report Type - ) - { - // - switch (type) - { - // - // Main ... - case XREPORT_MAIN: - FillReportAccountInfo(mMainReport); - break; - - // - // Monthly ... - case XREPORT_MONTHLY: - FillReportAccountInfo(mMonthlyReport); - break; - - // - // Weekly ... - case XREPORT_WEEKLY: - FillReportAccountInfo(mWeeklyReport); - break; - - // - // Daily ... - case XREPORT_DAILY: - FillReportAccountInfo(mDailyReport); - break; - } - } - - // - // Filling Volume Info ... - void FillingVolumeInfo( - XReport &report, // Specified Report - // - double staticVolume, // Current Available Static Volume - string staticVolumeCalculationMethod, // Static Volume Calculation Method - double maxAllowedVolume, // Current Maximum Appliable Volume - double volumeIncreaseMultiplier, // Static Volume Increase Multiplier - double balanceGowingToApplyMultiplier, // Multiply Volume Based On Balance Growing - double balanceGrowingToIncreaseMaxAllowedVolume // Where to Increase MaxAllowed Volume - ) - { - // - FillReportEndTime(report); - - // - report.volumeInfo.staticVolume = staticVolume; - report.volumeInfo.maxAllowedVolume = maxAllowedVolume; - report.volumeInfo.volumeIncreaseMultiplier = volumeIncreaseMultiplier; - report.volumeInfo.staticVolumeCalculationMethod = staticVolumeCalculationMethod; - report.volumeInfo.balanceGowingToApplyMultiplier = balanceGowingToApplyMultiplier; - report.volumeInfo.balanceGrowingToIncreaseMaxAllowedVolume = balanceGrowingToIncreaseMaxAllowedVolume; - } - - // - // Add Signal to Report ... - void AddSignalToReport( - XReport &report, // Specified Report - const XSignal &signal, // Specified Signal - const string &providers[] // Specified Signal Providers - ) - { - // - FillReportEndTime(report); - - // - double volume = signal.volume; - bool isLong = signal.type == X_SIGNAL_LONG; - - // - // Update Longs and Shorts ... - if (isLong) - { - report.summaryInfo.longSignals++; - } - else - { - report.summaryInfo.shortSignals++; - } - - // - // Chack Max Volume ... - if (volume > report.summaryInfo.maxSignalVolume) - { - report.summaryInfo.maxSignalVolume = volume; - } - - // - // Update Signallers Info ... - for (int i = 0; i < ArraySize(providers); i++) - { - // - string iProvider = providers[i]; - - // - AddOrUpdateSignaller( - report, - iProvider, - signal); - } - } - - // - // Add or Update Signaller Info of Specific Report ... - void AddOrUpdateSignaller( - XReport &report, // Specified Report - const string provider, // Signal Provider name - const XSignal &signal // Specified Signal - ) - { - // - int providerIdx = -1; - int signallersInfoCount = 0; - bool isLong = signal.type == X_SIGNAL_LONG; - - // - // Prepare New One Provider ... - XSignallerInfo info = {}; - info.name = provider; - if (isLong) - { - info.longs = 1; - } - else - { - info.shorts = 1; - } - - // - // Find Provider idx if Exists ... - providerIdx = FindProviderInSignallersInfo( - provider, - report.signallersInfo); - - // - // Check IDX ... - if (providerIdx > -1) - { - // - // Update Exists ... - if (isLong) - { - report.signallersInfo[providerIdx].longs++; - } - else - { - report.signallersInfo[providerIdx].shorts++; - } - } - else - { - // - // Add New One ... - AddItemToBuffer( - info, - report.signallersInfo); - } - } - - // - // Add TP in Report ... - void AddTradeTPInReport( - XReport &report // Specified Report - ) - { - // - FillReportEndTime(report); - - // - report.summaryInfo.numberOfTPs++; - } - - // - // Add SL in Report ... - void AddTradeSLInReport( - XReport &report // Specified Report - ) - { - // - FillReportEndTime(report); - - // - report.summaryInfo.numberOfSLs++; - } - - // - // Update Number of Same Time Trades in Report ... - void UpdateMaxSameTimeTradesInReport( - XReport &report, // Specified Report - int value // number of same time trades - ) - { - // - // Validate Args ... - if (value <= report.summaryInfo.maxSameTimeSignals) - { - return; - } - - // - FillReportEndTime(report); - - // - report.summaryInfo.maxSameTimeSignals = value; - } - - // - // Update Number of Same Time Trades in Report ... - void UpdateMaxDrawUpInReport( - XReport &report, // Specified Report - double value // draw up value - ) - { - // - // Validate Args ... - if (value <= report.summaryInfo.maxDrawUp) - { - return; - } - - // - FillReportEndTime(report); - - // - report.summaryInfo.maxDrawUp = value; - } - - // - // Update Number of Same Time Trades in Report ... - void UpdateMaxDrawDownInReport( - XReport &report, // Specified Report - double value // draw down value - ) - { - // - // Validate Args ... - if (value <= report.summaryInfo.maxDrawDown) - { - return; - } - - // - FillReportEndTime(report); - - // - report.summaryInfo.maxDrawDown = value; - } - - // - // Update Min Balance for Open Trades Value in Report ... - void UpdateMinBalanceForOpenTradesInReport( - XReport &report, // Specified Report - double value // min balance for open trades - ) - { - // - // Validate Arg ... - if (value <= 0) - { - return; - } - - // - FillReportEndTime(report); - - // - report.accountInfo.minBalanceForOpenTrades = value; - } - - // - // Generate Specific Report String Representation ... - string GenerateReportString( - XReport &report, // Specified Report - string separator = "\n" // Separator - ) - { - // - string result = ""; - - // - // Start and End Date ... - result += "Start: " + (string)report.start + separator; - result += "End: " + (string)report.end + separator; - - // - // Account Info ... - string accountStr = GenerateAccountInfoReportString(report.accountInfo); - result += "Account: " + separator + accountStr + separator; - - // - // Summary Info ... - string summaryStr = GenerateSummaryInfoReportString(report.summaryInfo); - result += "Summary: " + separator + summaryStr + separator; - - // - // Volume Info ... - string volumeStr = GenerateVolumeInfoReportString(report.volumeInfo); - result += "Volume: " + separator + volumeStr + separator; - - // - // Signallers Info ... - string signallersStr = GenerateSignallersInfoReportString(report.signallersInfo); - result += "Signallers: " + separator + signallersStr + separator; - - // - return result; - } - - // - // Generate Account info String Representation ... - string GenerateAccountInfoReportString( - XAccountInfo &info, // Specified Account Info - string separator = "\n" // Separator - ) - { - // - string result = ""; - - // - // Generate Report ... - result += "user: " + info.user + separator; - result += "name: " + info.name + separator; - result += "server: " + info.server + separator; - result += "broker: " + info.broker + separator; - result += "mode: " + EnumToString(info.mode) + separator; - result += "leverage: " + (string)info.leverage + separator; - result += "currency: " + info.currency + separator; - result += "deposit: " + (string)info.deposit + separator; - result += "balance: " + (string)info.balance + separator; - result += "minBalanceForTrading: " + (string)info.minBalanceForOpenTrades + separator; - - // - return result; - } - - // - // Generate Summary info String Representation ... - string GenerateSummaryInfoReportString( - XSummaryInfo &info, // Specified Summary Info - string separator = "\n" // Separator - ) - { - // - string result = ""; - - // - // Generate Report ... - result += "longSignals: " + (string)info.longSignals + separator; - result += "shortSignals: " + (string)info.shortSignals + separator; - result += "numberOfTps: " + (string)info.numberOfTPs + separator; - result += "numberOfSLs: " + (string)info.numberOfSLs + separator; - result += "maxDrawUp: " + (string)info.maxDrawUp + separator; - result += "maxDrawDown: " + (string)info.maxDrawDown + separator; - result += "maxSignalVolume: " + (string)info.maxSignalVolume + separator; - result += "maxSameTimeSignals: " + (string)info.maxSameTimeSignals + separator; - - // - return result; - } - - // - // Generate Volume info String Representation ... - string GenerateVolumeInfoReportString( - XVolumeInfo &info, // Specified Volume Info - string separator = "\n" // Separator - ) - { - // - string result = ""; - - // - // Generate Report ... - result += "staticVolume: " + (string)info.staticVolume + separator; - result += "staticVolumeCalculationMethod: " + info.staticVolumeCalculationMethod + separator; - result += "maxAllowedVolume: " + (string)info.maxAllowedVolume + separator; - result += "volumeIncreaseMultiplier: " + (string)info.volumeIncreaseMultiplier + separator; - result += "balanceGowingToApplyMultiplier: " + (string)info.balanceGowingToApplyMultiplier + separator; - result += "balanceGrowingToIncreaseMaxAllowedVolume: " + (string)info.balanceGrowingToIncreaseMaxAllowedVolume + separator; - - // - return result; - } - - // - // Generate Signallers info String Representation ... - string GenerateSignallersInfoReportString( - XSignallerInfo &infos[], // Specified Signallers Info - string separator = "\n" // Separator - ) - { - // - string result = ""; - - // - // Validate Signallers Array Size ... - int signallersCount = ArraySize(infos); - if (signallersCount <= 0) - { - // - result += "EMPTY" + separator; - return result; - } - - // - // Generate Report ... - for (int i = 0; i < signallersCount; i++) - { - // - XSignallerInfo iSignaller = infos[i]; - - // - result += "name: " + iSignaller.name + separator; - result += "longs: " + (string)iSignaller.longs + separator; - result += "shorts: " + (string)iSignaller.shorts + separator; - - // - if (i < signallersCount - 1) - { - result += separator; - } - } - // - return result; - } - - // - // Find a Provider Index in SignallersInfo ... - int FindProviderInSignallersInfo( - string provider, // Specified Provider Name ... - XSignallerInfo &infoBuffer[] // Specified XSignallerInfo Buffer ... - ) - { - // - int result = -1; - - // - int bufferSize = ArraySize(infoBuffer); - if (bufferSize <= 0) - { - return result; - } - - // - // Loop through buffer to find provider index ... - for (int i = 0; i < bufferSize; i++) - { - // - XSignallerInfo iInfo = infoBuffer[i]; - - // - if (iInfo.name != provider) - { - continue; - } - - // - result = i; - } - - // - return result; - } -}; - -// -// a Class For Collectiong Info ... -class XCCollector : public XCBase -{ - // - // Public ... -public: - // - // Constructor ... - XCCollector() - { - Reset(); - } - - // - // Deconstructor ... - ~XCCollector() {} - - // - // Reset All Collectors ... - void Reset() - { - Clean(); - } - - // - // Count Data ... - int Count() - { - // - int result = 0; - - // - result = ArraySize(mTimes); - - // - return result; - } - - // - // TODO: Implement Business Logic here ... - - // - // Add Specific item to Collection ... - bool Add( - XCollector &item // Specified Info - ) - { - // - bool result = false; - - // - // Validate Args ... - result = IsValid( - item, - false); - if (!result) - { - return result; - } - - // - // Add Items Values to Buffers ... - // - AddItemToBuffer( - item.time, - mTimes); - - // - AddItemToBuffer( - item.volume, - mVolumes); - - // - AddItemToBuffer( - item.maxDrawDown, - mMaxDrawDowns); - - // - AddItemToBuffer( - item.maxAllowedVolume, - mMaxAllowedVolumes); - - // - AddItemToBuffer( - item.minBalanceForOpenTrade, - mMinBalanceForTradePrices); - - // - return result; - } - - // - // Retrieve Specific Item ... - bool Get( - XCollector &item, // Hold's Result - int index = 0 // Specified Index to Retrieve - ) - { - // - bool result = false; - - // - result = IsValidIndex(index); - if (!result) - { - return result; - } - - // - // Filling Item ... - item.time = mTimes[index]; - item.volume = mVolumes[index]; - item.maxDrawDown = mMaxDrawDowns[index]; - item.maxAllowedVolume = mMaxAllowedVolumes[index]; - item.minBalanceForOpenTrade = mMinBalanceForTradePrices[index]; - - // - return result; - } - XCollector Get( - int index = 0 // Specified Index to Retrieve - ) - { - // - XCollector result = {}; - - // - bool isValidIndex = IsValidIndex(index); - if (!isValidIndex) - { - return result; - } - - // - // Filling Item ... - result.time = mTimes[index]; - result.volume = mVolumes[index]; - result.maxDrawDown = mMaxDrawDowns[index]; - result.maxAllowedVolume = mMaxAllowedVolumes[index]; - result.minBalanceForOpenTrade = mMinBalanceForTradePrices[index]; - - // - return result; - } - bool Get( - XCollector &item, // Hold's Result - datetime time // Specified Index to Retrieve - ) - { - // - bool result = false; - - // - if (time <= 0) - { - return result; - } - - // - int timesCount = ArraySize(mTimes); - result = timesCount > 0; - if (!result) - { - return result; - } - - // - int index = -1; - for (int i = 0; i < timesCount; i++) - { - // - datetime iTime = mTimes[i]; - - // - if (iTime == time) - { - // - index = i; - break; - } - } - - // - result = index >= 0; - if (!result) - { - return result; - } - - // - result = Get( - item, - index); - - // - return result; - } - XCollector Get( - datetime time // Specified Index to Retrieve - ) - { - // - XCollector result = {}; - - // - if (time <= 0) - { - return result; - } - - // - int timesCount = ArraySize(mTimes); - if (timesCount <= 0) - { - return result; - } - - // - int index = -1; - for (int i = 0; i < timesCount; i++) - { - // - datetime iTime = mTimes[i]; - - // - if (iTime == time) - { - // - index = i; - break; - } - } - - // - if (index <= -1) - { - return result; - } - - // - result = Get( - index); - - // - return result; - } - - // - // Retrieve All ... - void GetAll( - XCollector &result[], // Hold's Result - bool reversal = false // Extract Direction - ) - { - // - CleanBuffer(result); - - // - int timesCount = ArraySize(mTimes); - if (timesCount <= 0) - { - return; - } - - // - if (!reversal) - { - // - for (int i = 0; i < timesCount; i++) - { - // - XCollector iCollector = Get(i); - - // - AddItemToBuffer( - iCollector, - result); - } - } - else - { - // - for (int i = timesCount - 1; i >= 0; i--) - { - // - XCollector iCollector = Get(i); - - // - AddItemToBuffer( - iCollector, - result); - } - } - } - - // - // Extract History ... - void Extract( - XCollector &result[], // Hold's Result - int start, // Start Index - int end // End Index - ) - { - // - CleanBuffer(result); - - // - // Validate Args ... - if ( - end < 0 || - start < 0 || - (start == 0 && end == 0) || - MathAbs(start - end == 0)) - { - return; - } - - // - // Validate Start and End Index ... - bool isValidEnd = IsValidIndex(end); - bool isValidStart = IsValidIndex(start); - if (!isValidEnd || !isValidStart) - { - return; - } - - // - bool direction = end > start; - if (direction) - { - // - for (int i = start; i < end - 1; i++) - { - // - XCollector iCollect = Get(i); - - // - AddItemToBuffer( - iCollect, - result); - } - } - else - { - // - for (int i = end - 1; i >= start; i--) - { - // - XCollector iCollect = Get(i); - - // - AddItemToBuffer( - iCollect, - result); - } - } - } - - // - // Validate an Item ... - bool IsValid( - XCollector &item, // Specified Info - bool ignoreTime = true // Ignore Times Checking ... - ) - { - // - bool result = false; - - // - // Check Each Items contains Correct Value ... - // - result = item.volume >= 0; - if (!result) - { - return result; - } - - // - result = item.maxDrawDown >= 0; - if (!result) - { - return result; - } - - // - result = item.maxAllowedVolume >= 0; - if (!result) - { - return result; - } - - // - result = item.minBalanceForOpenTrade >= 0; - if (!result) - { - return result; - } - - // - // Check Time has Proper Value ... - result = item.time > 0; - if (!result) - { - return result; - } - - // - // Check time bigger than last Time ... - int timesCount = ArraySize(mTimes); - if ( - !ignoreTime && - timesCount >= 0) - { - // - // Retrieve Last Added Times ... - datetime lastTime; - result = GetLastItem(lastTime, mTimes); - if (!result) - { - return result; - } - - // - // Compare Last Time by current Time ... - result = item.time > lastTime; - if (!result) - { - return result; - } - } - - // - return result; - } - - // - // Generate Logging String Representation ... - string GenerateString( - XCollector &item, // Specified Info - string separator = "\n" // Separator Character - ) - { - // - string result = ""; - - // - result += "time: " + (string)item.time + separator; - result += "volume: " + (string)item.volume + separator; - result += "maxDrawDown: " + (string)item.maxDrawDown + separator; - result += "maxAllowedVolume: " + (string)item.maxAllowedVolume + separator; - result += "minBalanceForOpenTrade: " + (string)item.minBalanceForOpenTrade + separator; - - // - return result; - } - - // - // Protected ... -protected: - // - // Private ... -private: - // - // Max Draw Up touched till now ... - double mMaxDrawUp; - - // - // Max Draw Down touched till now ... - double mMaxDrawDown; - - // - // Last Time for Checks ... - datetime mTimes[]; - - // - // Volume at the Check Time ... - double mVolumes[]; - - // - // DrawDown for each Check ... - double mMaxDrawDowns[]; - - // - // Max Allowed Volume for each check ... - double mMaxAllowedVolumes[]; - - // - // Min Balance for Open Trades for Each Check ... - double mMinBalanceForTradePrices[]; - - // - // Reset ... - void Clean() - { - // - mMaxDrawUp = 0; - mMaxDrawDown = 0; - - // - CleanBuffer(mTimes); - CleanBuffer(mVolumes); - CleanBuffer(mMaxDrawDowns); - CleanBuffer(mMaxAllowedVolumes); - CleanBuffer(mMinBalanceForTradePrices); - } - - // - // Validate Index ... - bool IsValidIndex( - int index // Specified Index - ) - { - // - bool result = false; - - // - int bufferSize = ArraySize(mTimes); - if (bufferSize <= 0) - { - return result; - } - - // - result = index <= bufferSize - 1; - - // - return result; - } -}; - -// -// a Class for Managing Volumes ... -class XCVolumeManager : public XCBase -{ - // - // Public ... -public: - // - // Constructor ... - XCVolumeManager( - double staticVolumeRate, // Static Volume Calculation Mutiplier - ENUM_STATIC_VOLUME_METHODS volumeMethod = X_STATIC_VOLUME_BASED_ON_DEPOSIT, // How to Calculate Static Volume - double volumeMultiplier = 0, // Volume Multiplier - double volumeMultiplierAppliedRate = 0, // Apply Volume Multiplier when Balance Increased by this rate - double maxAllowedVolume = 0, // Max Allowed Volume - double increaseMaxAllowedVolumeRate = 0 // Increase Max Allowed Volumes when Balance Increased by this rate - ) - { - // - mAccountInfo = new XCAccountInfo(); - - // - ResetForceVolumeMultiplier(); - - // - mVolumeMethod = volumeMethod; - mStaticVoluemRate = staticVolumeRate; - mVolumeMultiplier = volumeMultiplier; - mMaxAllowedVolume = maxAllowedVolume; - mVolumeMultiplierAppliedRate = volumeMultiplierAppliedRate; - mIncreaseMaxAllowedVolumeRate = increaseMaxAllowedVolumeRate; - } - - // - // Deconstructor ... - ~XCVolumeManager(void) {} - - // - // Check Volume Multiplier ... - bool CanUseVolumeMultiplier() - { - // - bool result = false; - - // - result = - mVolumeMultiplier > 0 && - mVolumeMultiplierAppliedRate > 0; - - // - return result; - } - - // - // Check Max Volume ... - bool CanUseMaxVolume() - { - // - bool result = false; - - // - result = - mMaxAllowedVolume > 0; - - // - return result; - } - - // - // Calculate Volume for Position ... - double CalculateVolume( - int numberOfOpenPositions = 0, // Number Of Open Signals - string symbol = NULL // Specify Symbol - ) - { - // - double result = 0; - - // - // Normalize Symbol ... - if (StringLen(symbol) == 0) - { - symbol = _Symbol; - } - - // - // Static Volume ... - result = GetStaticVolume(); - - // - double multiplier = GetVolumeMultiplier(); - result *= multiplier; - - // - // Check Max Allowed Volume Exists ... - double maxAllowedVolume = GetMaxAllowedVolume(); - if (maxAllowedVolume > 0) - { - // - result = - result > maxAllowedVolume - ? maxAllowedVolume - : result; - } - - // - // Check Number of Open Positions ... - if (numberOfOpenPositions >= 0) - { - // - // Decrease Volume ... - result /= (1 + numberOfOpenPositions); - } - - // - // Apply Force Volume Multiplier ... - result *= mForceVolumeMultiplier; - - // - // Retrieve Symbol Volume Info ... - result = NormalizeVolume(result, symbol, 2); - - // - return result; - } - - // - // Calculate Volume Multiplier ... - double GetVolumeMultiplier() - { - // - double result = 1; - - // - double deposit = mAccountInfo.GetInitialBalance(); - double balance = mAccountInfo.GetBalance(); - bool canUseVolumeMultiplier = CanUseVolumeMultiplier(); - if ( - balance < deposit || - !canUseVolumeMultiplier) - { - return result; - } - - // - // Apply Multiplier to Volume ... - double baseGrowBalance = deposit * mVolumeMultiplierAppliedRate; - double balanceGrows = balance - deposit; - if (balanceGrows < baseGrowBalance) - { - return result; - } - - // - double applyMultiplierTimes = balanceGrows / baseGrowBalance; - double roundedApplyMultiplierTimes = MathRound(applyMultiplierTimes); - - // - if (applyMultiplierTimes < roundedApplyMultiplierTimes) - { - applyMultiplierTimes -= (1 - (roundedApplyMultiplierTimes - applyMultiplierTimes)); - } - - // - // Calculate result ... - result = applyMultiplierTimes * mVolumeMultiplier; - - // - return result; - } - - // - // Retrieve Required Balance Grows for Increase Max Allowed Volume ... - double GetIncreaseMaxAllowedVolumeBalance() - { - // - double result = 0; - - // - if ( - mMaxAllowedVolume <= 0 || - mIncreaseMaxAllowedVolumeRate <= 0) - { - return result; - } - - // - result = mAccountInfo.GetInitialBalance() * mIncreaseMaxAllowedVolumeRate; - - // - return result; - } - - // - // Calculate Max Allowed Volume ... - double GetMaxAllowedVolume() - { - // - double result = 0; - - // - // Validate Args ... - result = - mMaxAllowedVolume <= 0 - ? 0 - : mMaxAllowedVolume; - - // - double deposit = mAccountInfo.GetInitialBalance(); - double balance = mAccountInfo.GetBalance(); - bool canUseMaxAllowedVolume = CanUseMaxVolume(); - if ( - balance <= deposit || - !canUseMaxAllowedVolume || - mIncreaseMaxAllowedVolumeRate <= 0) - { - // - return result; - } - - // - // Apply Multiplier to Volume ... - double baseGrowBalance = GetIncreaseMaxAllowedVolumeBalance(); - double balanceGrows = balance - deposit; - if (balanceGrows < baseGrowBalance) - { - return result; - } - - // - double applyMultiplierTimes = balanceGrows / baseGrowBalance; - double roundedApplyMultiplierTimes = MathRound(applyMultiplierTimes); - - // - if (applyMultiplierTimes < roundedApplyMultiplierTimes) - { - applyMultiplierTimes -= (1 - (roundedApplyMultiplierTimes - applyMultiplierTimes)); - } - - // - result *= applyMultiplierTimes; - - // - return result; - } - - // - // Get Static Volume ... - double GetStaticVolume() - { - // - double result = 0; - - // - double deposit = mAccountInfo.GetInitialBalance(); - double balance = mAccountInfo.GetBalance(); - - // - switch (mVolumeMethod) - { - // - case X_STATIC_VOLUME_BASED_ON_DEPOSIT: - result = mStaticVoluemRate * deposit; - break; - - // - case X_STATIC_VOLUME_BASED_ON_BALANCE: - result = mStaticVoluemRate * balance; - break; - } - - // - return result; - } - - // - // Reset Froce Volume Multiplier ... - void ResetForceVolumeMultiplier() - { - mForceVolumeMultiplier = 1; - } - - // - // Retrieve Current Force Volume Multiplier ... - double GetCurrentForceVolumeMultiplier() - { - return mForceVolumeMultiplier; - } - - // - // Retrieve Next Increase Multiplier Price ... - double GetIncreaseMultiplierBalance() - { - return mAccountInfo.GetInitialBalance() * mVolumeMultiplierAppliedRate; - } - - // - // Change Force Volume Multiplier ... - void ChangeForceVolumeMultiplier( - double rate // Change rate - ) - { - // - // Normalize rate ... - if (rate <= 1) - { - rate = 1; - } - - // - mForceVolumeMultiplier = rate; - } - - // - // Increase Force Volume Multiplier ... - void IncreaseForceVolumeMultiplier() - { - mForceVolumeMultiplier += 0.5; - } - - // - // Decrease Force Volume Multiplier ... - void DecreaseForceVolumeMultiplier() - { - // - if (mForceVolumeMultiplier <= 1) - { - return; - } - - // - mForceVolumeMultiplier -= 0.5; - } - - // - // Generate Current State Log String ... - string GenerateStateString( - string separator = "\n" // Log Separator ... - ) - { - // - string result = ""; - - // - // Normallize Separator ... - if (StringLen(separator) == 0) - { - separator = "\n"; - } - - // - result += "ForceVolumeMultiplier: " + (string)mForceVolumeMultiplier + separator; - // - result += "StaticVoluemRate: " + (string)mStaticVoluemRate + separator; - result += "StaticVoluem: " + (string)GetStaticVolume() + separator; - result += "VolumeMethod: " + EnumToString(mVolumeMethod) + separator; - // - result += "VolumeMultiplier: " + (string)mVolumeMultiplier + separator; - result += "VolumeMultiplierAppliedRate: " + (string)mVolumeMultiplierAppliedRate + separator; - // - result += "MaxAllowedVolume: " + (string)mMaxAllowedVolume + separator; - result += "IncreaseMaxAllowedVolumeRate: " + (string)mIncreaseMaxAllowedVolumeRate + separator; - - // - return result; - } - - // - // Protected ... -protected: - // - // Private ... -private: - // - // an Instance of Account Info for reading Balance and Deposit and etc ... - XCAccountInfo mAccountInfo; - - // - // Force Volume Rate Multiplier ... - double mForceVolumeMultiplier; - - // - // Static Volume Calculation Mutiplier ... - double mStaticVoluemRate; - - // - // How to Calculate Static Volume ... - ENUM_STATIC_VOLUME_METHODS mVolumeMethod; - - // - // Volume Multiplier ... - double mVolumeMultiplier; - - // - // Apply Volume Multiplier when Balance Increased by this rate ... - double mVolumeMultiplierAppliedRate; - - // - // Max Allowed Volume - double mMaxAllowedVolume; - - // - // Increase Max Allowed Volumes when Balance Increased by this rate - double mIncreaseMaxAllowedVolumeRate; -}; - -// -// a Class For Managing Signals Additional Data ... -class XCSignalManager : public XCBase -{ - // - // Public ... -public: - // - // Constructor ... - XCSignalManager(void) - { - CleanData(); - } - - // - // Deconstructor ... - ~XCSignalManager(void) {} - - // - void Reset() - { - CleanData(); - } - - // - // Retrieve All Signals ... - void GetAll( - XSignal &result[] // Hold's Result - ) - { - // - CleanBuffer(result); - - // - int signalsCount = ArraySize(mSignals); - if (signalsCount <= 0) - { - return; - } - - // - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = mSignals[i]; - - // - AddItemToBuffer( - iSignal, - result); - } - } - - // - // Count Items ... - int Count() - { - return ArraySize(mSignals); - } - - // - // Retrieve Specific Signal by Ticket ... - XSignal Get( - ulong ticket // Signals Ticket ... - ) - { - // - XSignal result = {}; - - // - // Check Exists ... - bool isExists = IsExists(ticket); - if (!isExists) - { - return result; - } - - // - int signalsCount = ArraySize(mSignals); - if (signalsCount <= 0) - { - return result; - } - - // - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = mSignals[i]; - - // - if (iSignal.ticket == ticket) - { - // - result = iSignal; - break; - } - } - - // - return result; - } - - // - // Check Signal Exists or not ... - bool IsExists( - ulong ticket // Specified Signal Ticket - ) - { - // - bool result = false; - - // - int signalsCount = ArraySize(mSignals); - if (signalsCount <= 0) - { - return result; - } - - // - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = mSignals[i]; - - // - if (iSignal.ticket == ticket) - { - // - result = true; - break; - } - } - - // - return result; - } - bool IsExists( - XSignal &signal // Specified Signal - ) - { - // - bool result = false; - - // - int signalsCount = ArraySize(mSignals); - if (signalsCount <= 0) - { - return result; - } - - // - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = mSignals[i]; - - // - if (iSignal.ticket == signal.ticket) - { - // - result = true; - break; - } - } - - // - return result; - } - - // - // Add Signal ... - bool Add( - XSignal &signal // Specified Signal - ) - { - // - bool result = false; - - // - // Validate Args ... - if (signal.ticket <= 0) - { - return result; - } - - // - // Chekc Signal Exists ... - bool isExists = IsExists(signal); - if (isExists) - { - return result; - } - - // - AddItemToBuffer( - signal, - mSignals); - result = true; - - // - return result; - } - - // - // Update Specific Buffer ... - bool Update( - XSignal &signal // Specified Signal - ) - { - // - bool result = false; - - // - // Validate Args ... - if (signal.ticket <= 0) - { - return result; - } - - // - // Chekc Signal Exists ... - bool isExists = IsExists(signal); - if (!isExists) - { - return result; - } - - // - // Remove Signal ... - Remove(signal); - - // - // Add new One ... - AddItemToBuffer( - signal, - mSignals); - - // - result = true; - - // - return result; - } - - // - // Remove Signal ... - bool Remove( - ulong ticket // Specified Signal Ticket - ) - { - // - bool result = false; - - // - // Check Signal Exists ... - bool isExists = IsExists(ticket); - if (!isExists) - { - return result; - } - - // - int signalsCount = ArraySize(mSignals); - if (signalsCount <= 0) - { - return result; - } - - // - XSignal signals[]; - - // - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = mSignals[i]; - - // - if (iSignal.ticket != ticket) - { - AddItemToBuffer( - iSignal, - signals); - } - } - - // - // Now we have to Clean All Signals and Replace them by signals[] buffer ... - UpdateData(signals); - - // - result = true; - return result; - } - bool Remove( - XSignal &signal // Specified Signal - ) - { - // - bool result = false; - - // - // Check Signal Exists ... - bool isExists = IsExists(signal); - if (!isExists) - { - return result; - } - - // - int signalsCount = ArraySize(mSignals); - if (signalsCount <= 0) - { - return result; - } - - // - XSignal signals[]; - - // - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = mSignals[i]; - - // - if (iSignal.ticket != signal.ticket) - { - AddItemToBuffer( - iSignal, - signals); - } - } - - // - // Now we have to Clean All Signals and Replace them by signals[] buffer ... - UpdateData(signals); - - // - result = true; - return result; - } - - // - // Add Or Update ... - bool AddOrUpdate( - XSignal &signal // Specified Signal - ) - { - // - bool result = false; - - // - // Validate Args ... - if (signal.ticket <= 0) - { - return result; - } - - // - // Chekc Signal Exists ... - bool isExists = IsExists(signal); - if (!isExists) - { - result = Add(signal); - } - else - { - result = Update(signal); - } - - // - return result; - } - - // - // Protected ... -protected: - // - // Private ... -private: - // - // Holds Signals ... - XSignal mSignals[]; - - // - // Clean All Exists Data ... - void CleanData() - { - CleanBuffer(mSignals); - } - - // - // Update Data ... - void UpdateData( - XSignal &source[] // a Buffer which needs to Replace ... - ) - { - // - CleanData(); - - // - int sourceCount = ArraySize(source); - if (sourceCount <= 0) - { - return; - } - - // - for (int i = 0; i < sourceCount; i++) - { - // - XSignal iSignal = source[i]; - - // - AddItemToBuffer( - iSignal, - mSignals); - } - } -}; - -// -// XSaherElm Trade Class ... -class XCTrade : public XCBase -{ - // - // all public features ... -public: - // - // Constructor ... - void XCTrade( - string tag, // Specify a Tag for Trader instance - string symbol, // Specify Trader Symbol - int slippage, // Specify Slippage - ulong magicNumber, // Specify Magic Number - bool useVirtualTPSL, // Use Virtual TP SL - int maxAllowedTrades, // Specify Max Allowed Trades - double minBallanceForOpenTrades, // Specify Minimum Balance for Open Trades - double minAllowedFreeMarginForOpenTrades, // Specify Minimum Free Marging for Open Trades - bool useSignalProtector = true // Specify Use Signal Protector or not - ) - { - // - mTag = tag; - mSymbol = symbol; - mSlippage = slippage; - mMagicNumber = magicNumber; - mUseVirtualTPSL = useVirtualTPSL; - mMaxAllowedTrades = maxAllowedTrades; - mMinBallanceForOpenTrades = minBallanceForOpenTrades; - mMinAllowedFreeMarginForOpenTrades = minAllowedFreeMarginForOpenTrades; - - // - mTrader = new XSCTrade(); - - // - mTrader.SetAsyncMode(false); - mTrader.SetDeviationInPoints(mSlippage); - mTrader.SetExpertMagicNumber(mMagicNumber); - - // - // Setting Log Level ... - mTrader.LogLevel(LOG_LEVEL_ERRORS); - - // - mSignalManager = new XCSignalManager(); - - // - Reset(); - } - - // - // Deconstructor ... - void ~XCTrade() - { - } - - // - // START Configuring Class Functions ... - // - - // - // Reset all Variables ... - void Reset() - { - // - mSignalManager.Reset(); - - // - mDaysForRead = 1; - mScanStarted = false; - - // - // Reset On Trade Counter ... - ResetOnTradeContext(); - - // - // Init On Trade Context ... - InitOnTradeContext(); - } - - // - // END Configuring Class Functions ... - // - - // - // START Count ... - // - - // - // Count Open Positions ... - int Count() - { - // - int result = 0; - - // - int total = PositionsTotal(); - for (int i = 0; i < total; i++) - { - // - if (!mPositionInfo.SelectByIndex(i)) - { - continue; - } - - // - if (mPositionInfo.Magic() != mMagicNumber) - { - continue; - } - - // - if (mPositionInfo.Symbol() != mSymbol) - { - continue; - } - - // - result++; - } - - // - return result; - } - - // - // Count Longs ... - int CountLongs() - { - int result = CountByType(X_SIGNAL_LONG); - return result; - } - - // - // Count Shorts ... - int CountShorts() - { - int result = CountByType(X_SIGNAL_SHORT); - return result; - } - - // - // Count Specific Type Of Positions ... - int CountByType(ENUM_POSITION_TYPE type) - { - // - int result = 0; - - // - int total = PositionsTotal(); - for (int i = 0; i < total; i++) - { - // - if (!mPositionInfo.SelectByIndex(i)) - { - continue; - } - - // - if (mPositionInfo.Symbol() != mSymbol) - { - continue; - } - - // - if (mPositionInfo.PositionType() != type) - { - continue; - } - - // - result++; - } - - // - return result; - } - - // - // Count By Type ... - int CountByType(ENUM_X_SIGNAL_TYPE type) - { - // - // Validate Args ... - ENUM_POSITION_TYPE mType = POSITION_TYPE_BUY; - if (type == X_SIGNAL_LONG) - { - mType = POSITION_TYPE_BUY; - } - else if (type == X_SIGNAL_SHORT) - { - mType = POSITION_TYPE_SELL; - } - - // - int result = CountByType(mType); - return result; - } - - // - // END Count ... - // - - // - // START Retrieve ... - // - - // - // Retrieve Specified Position by it's Ticket ... - XSignal GetSignal( - ulong ticket // Specified Ticket - ) - { - // - XSignal result = {}; - - // - result = PositionToSignal(ticket); - - // - return result; - } - - // - // Get Last Signal ... - XSignal GetLastSignal() - { - // - XSignal result = {}; - - // - XSignal signals[]; - GetSignals(signals); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return result; - } - - // - result = signals[0]; - - // - return result; - } - - // - // Retrieve Last Executed Signal ... - bool GetLastSignal(XSignal &signal) - { - // - bool result = false; - - // - XSignal signals[]; - GetSignals(signals); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return result; - } - - // - signal = signals[0]; - result = true; - - // - return result; - } - - // - // Retrieve All Positions ... - void GetSignals( - XSignal &result[] // Holds Result ... - ) - { - // - CleanBuffer(result); - - // - int totalPositions = PositionsTotal(); - for (int i = 0; i < totalPositions; i++) - { - // - if (!mPositionInfo.SelectByIndex(i)) - { - continue; - } - - // - if (mPositionInfo.Magic() != mMagicNumber) - { - continue; - } - - // - if (mPositionInfo.Symbol() != mSymbol) - { - continue; - } - - // - // Position to Signal ... - XSignal signal = PositionToSignal(i); - Add( - signal, - result); - } - } - - // - // Retrieve Type Specific Signals ... - void GetSignals( - XSignal &result[], // Holds Result ... - ENUM_X_SIGNAL_TYPE type // Specified Sginal Type ... - ) - { - // - CleanBuffer(result); - - // - XSignal signals[]; - GetSignals(signals); - - // - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return; - } - - // - // Loop ... - for (int i = signalsCount - 1; i >= 0; i--) - { - // - XSignal iSignal = signals[i]; - - // - if (type == X_SIGNAL_UNKNOWN) - { - Add( - iSignal, - result); - } - else if (iSignal.type == type) - { - Add( - iSignal, - result); - } - } - } - - // - // Filter Signals By Searching Comments ... - void FilterSignals( - XSignal &result[], // Holds Result ... - const string query, // Search in Comment Qeury ... - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specified Sginal Type ... - ) - { - // - CleanBuffer(result); - - // - XSignal signals[]; - GetSignals( - signals, - type); - int signalsCount = ArraySize(signals); - - // - // Validate Args ... - if ( - StringLen(query) <= 0 || - signalsCount <= 0) - { - return; - } - - // - // Loop ... - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - int queryPos = StringFind( - iSignal.comment, - query); - bool isContains = queryPos > -1; - if (!isContains) - { - continue; - } - - // - Add( - iSignal, - result); - } - } - - // - // Get All Trades Which Candle Passed after Open ... - void GetOldSignals( - XSignal &result[], // Holds Result - int life, // Max Candle Passed after Trades Open - ENUM_TIMEFRAMES period = NULL, // Calculate Candles based on time frame - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions - ) - { - // - CleanBuffer(result); - - // - // Normalize Period ... - if (period == NULL) - { - period = _Period; - } - - // - XSignal signals[]; - GetSignals( - signals, - type); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return; - } - - // - // Current Time Frame Candle Index ... - int currentBarIndex = 0; - - // - // Loop through Positions ... - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - // Retrieve Trade Open Bar Index based on Current Period ... - int tradeOpenBarIndex = iBarShift( - mSymbol, - period, - iSignal.time); - - // - // Calculate Trade Life ... - int diff = MathAbs(currentBarIndex - tradeOpenBarIndex); - - // - bool isPassed = diff >= life; - if (isPassed) - { - // - Add( - iSignal, - result); - } - } - } - - // - // Get In Profit Signals ... - void GetInProfitSignals( - XSignal &result[], // Holds Result - double minProfit = 0, // Minimum Profit To Close Trades - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions - ) - { - // - CleanBuffer(result); - - // - XSignal signals[]; - GetSignals( - signals, - type); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return; - } - - // - // Loop ... - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - bool isPassed = minProfit <= 0 && iSignal.profit > 0 - ? true - : iSignal.profit >= minProfit; - if (isPassed) - { - Add( - iSignal, - result); - } - } - } - - // - // Get In Drawdown Signals ... - void GetInDrawdownSignals( - XSignal &result[], // Holds Result - double maxDrawDown = 0, // Minimum Profit To Close Trades - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions - ) - { - // - CleanBuffer(result); - - // - XSignal signals[]; - GetSignals( - signals, - type); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return; - } - - // - // Loop ... - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - bool isPassed = maxDrawDown <= 0 && iSignal.profit < 0 - ? true - : iSignal.profit >= (-1 * maxDrawDown); - if (isPassed) - { - Add( - iSignal, - result); - } - } - } - - // - // Retrieve Max In Draw Down Trade ... - XSignal GetMaxInDrawdownSignal( - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions - ) - { - // - XSignal result = {}; - - // - XSignal signals[]; - GetInDrawdownSignals( - signals, - 0, - type); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return result; - } - - // - // Loop ... - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - result = - (result.ticket <= 0 && - result.profit == 0) || - result.profit > iSignal.profit - ? iSignal - : result; - } - - // - return result; - } - - // - // Calculate Profits Of all Open Signals ... - double GetSignalsProfit( - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions - ) - { - // - double result = 0; - - // - XSignal signals[]; - GetSignals(signals, type); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return result; - } - - // - // Loop ... - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - result += iSignal.profit; - } - - // - return result; - } - - // - // END Retrieve ... - // - - // - // START Signal Execution Actions ... - // - - // - // Execute a Signal in Market ... - ENUM_EXECUTION_SIGNAL_RESULT ExecuteSignal( - XSignal &signal, // Specified Signal - bool ignoreNumberOfTraes = false, // Ignore Number of Trades - bool checkAccountConditions = true // Check Account Balance, Equity and Free Margin for Signal Execution - ) - { - // - ENUM_EXECUTION_SIGNAL_RESULT result = X_TRADER_UNKNOWN_ERROR; - - // - // Validate Signal ... - bool isValid = IsValidSignal(signal); - if (!isValid) - { - // - result = X_TRADER_INVALID_SIGNAL_ERROR; - return result; - } - - // - // Check Account Equity ... - bool isEquityPassed = !checkAccountConditions - ? true - : IsEquityReadyForTrade(); - if (!isEquityPassed) - { - // - result = X_TRADER_NOT_ENOUGH_EQUITY_ERROR; - return result; - } - - // - // Check Account Balance ... - bool isBalancePassed = !checkAccountConditions - ? true - : IsBalanceReadyForTrade(); - if (!isBalancePassed) - { - // - result = X_TRADER_NOT_ENOUGH_BALANCE_ERROR; - return result; - } - - // - // Check Account FreeMargin ... - bool isFreeMarginPassed = !checkAccountConditions - ? true - : IsFreeMarginReadyForTrade(); - if (!isFreeMarginPassed) - { - // - result = X_TRADER_NOT_ENOUGH_MARIGIN_ERROR; - return result; - } - - // - // Check Number of Open Trades ... - int openTradesCount = Count(); - bool isTradeCountPassed = ignoreNumberOfTraes - ? true - : openTradesCount < mMaxAllowedTrades; - if (!isTradeCountPassed) - { - // - result = X_TRADER_MAX_TRADES_REACHED_ERROR; - return result; - } - - // - bool isExecuted = - signal.type == X_SIGNAL_LONG - ? Buy( - signal.volume, - signal.entry, - mUseVirtualTPSL - ? 0 - : signal.sl, - mUseVirtualTPSL - ? 0 - : signal.tp, - signal.comment) - : signal.type == X_SIGNAL_SHORT - ? Sell( - signal.volume, - signal.entry, - mUseVirtualTPSL - ? 0 - : signal.sl, - mUseVirtualTPSL - ? 0 - : signal.tp, - signal.comment) - : false; - if (isExecuted) - { - // - ulong ticket = PositionGetTicket(PositionsTotal() - 1); - - // - signal.id = ticket; - signal.ticket = ticket; - - // - AddOrUpdateSignalInfo(signal); - - // - result = X_TRADER_SUCCEED_EXECUTION; - } - - // - return result; - } - - // - // This Function, Handling Following Works on Open Positions: - // - Close On SL if Reached ... - // - Close On TP if Reached ... - // - Make Risk Free Trades ... - bool HandleSignals( - XTraderHandlerResult &handlerResult, // Holds Result - bool ignoreRiskFree = false // Ignore Risk Free Trdaes - ) - { - // - bool result = false; - - // - // Cleanup Result ... - CleanBuffer(handlerResult.sl); - CleanBuffer(handlerResult.tp); - CleanBuffer(handlerResult.rf); - - // - // Reading Open Positions ... - XSignal signals[]; - GetSignals(signals); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return result; - } - - // - double deviation = mSlippage * GetPoints(mSymbol); - - // - // Loop ... - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - bool isLong = iSignal.type == X_SIGNAL_LONG; - double entry = GetEntry(iSignal.symbol, iSignal.type); - double exit = GetExit(iSignal.symbol, iSignal.type); - double spread = GetSpread(iSignal.symbol); - double appliedTPPrice = - iSignal.tp > 0 - ? isLong - ? iSignal.tp - deviation - : iSignal.tp + deviation - : 0; - double appliedSLPrice = - iSignal.sl > 0 - ? isLong - ? iSignal.sl + deviation - : iSignal.sl - deviation - : 0; - - // - double usedPrice = exit; - - // - bool isSLTouched = - isLong - ? usedPrice <= appliedSLPrice - : usedPrice >= appliedSLPrice; - - // - bool isTPTouched = - isLong - ? usedPrice >= appliedTPPrice - : usedPrice <= appliedTPPrice; - - // - // Handle SL ... - if ( - // - iSignal.sl > 0 - // - && - // - isSLTouched - // - && - // - mUseVirtualTPSL) - { - // - string comment = GenerateSignalSLComment(iSignal); - - // - bool isClosed = Close( - iSignal.ticket, - comment); - if (isClosed) - { - AddItemToBuffer( - iSignal, - handlerResult.sl); - } - } - - // - // Handle TP ... - if ( - // - iSignal.tp > 0 - // - && - // - isTPTouched - // - && - // - mUseVirtualTPSL) - { - // - string comment = GenerateSignalTPComment(iSignal); - - // - bool isClosed = Close( - iSignal.ticket, - comment); - if (isClosed) - { - AddItemToBuffer( - iSignal, - handlerResult.tp); - } - } - - // - // Handle Risk Free ... - if ( - // - !ignoreRiskFree - // - && - // - iSignal.riskFreeStep > 0 - // - && - // - iSignal.riskFreeRate > 0 - // - ) - { - // - // Make Signals Risk Free Only if Signal In Profit ... - if (iSignal.profit <= 0) - { - continue; - } - - // - // Base Price is ENTRY, then Last Level, in each level SL is Last Level ... - // - // Calculate Risk Free Level/Multiplier ... - double level = 0; - double roundedLevel = 0; - double rStepPrice = PipsToPrice(iSignal.riskFreeStep); - double rBasePrice = - iSignal.sl > 0 && - iSignal.sl > iSignal.entry - ? iSignal.sl - : iSignal.entry; - - // - double exit = GetExit(iSignal.type); - - // - // Check Base Price for Signal reached with Exit Price ... - bool isExitPriceReachedBasePrice = - isLong - ? exit > rBasePrice - : exit < rBasePrice; - if (!isExitPriceReachedBasePrice) - { - continue; - } - - // - // Calculate Risk Free Step Multiplier ... - level = MathAbs(exit - rBasePrice) / rStepPrice; - - // - // Check Level Must Bigger than 1 ... - if (level < 1) - { - continue; - } - - // - // Normalize Level ... - roundedLevel = MathRound(level); - if (level < roundedLevel) - { - level -= (1 - (roundedLevel - level)); - } - else if (level > roundedLevel) - { - level -= (level - roundedLevel); - } - - // - // Generate Comment ... - string comment = GenerateSignalRFComment(iSignal, (int)level); - - // - // Calculate SL ... - double slDistance = spread; - double sl = - isLong - ? exit - slDistance - : exit + slDistance; - - // - // Increase TP One Level if Exists ... - double tp = iSignal.tp; - if (iSignal.tp > 0 && (isLong - ? iSignal.tp < rBasePrice + rStepPrice - : iSignal.tp > rBasePrice - rStepPrice)) - { - // - tp = - isLong - ? iSignal.tp + rStepPrice - : iSignal.tp - rStepPrice; - } - - // - double rVolume = NormalizeVolume((iSignal.volume * iSignal.riskFreeRate), iSignal.symbol); - - // - // Update Signal Volume ... - double volume = iSignal.volume - rVolume; - - // - bool isClosedPartial = - ClosePartial( - iSignal.ticket, - rVolume, - comment); - if (isClosedPartial) - { - // - bool isModified = true; - if (!mUseVirtualTPSL) - { - // - isModified = Modify( - iSignal.ticket, - sl, - tp, - comment); - } - - // - if (isModified) - { - // - // Try to Update Signal ... - XSignal s = mSignalManager.Get(iSignal.ticket); - - // - // Apply Changes on Signal ... - s.sl = sl; - s.tp = tp; - s.volume = volume; - - // - // Update Signal ... - bool isUpdated = false; - bool isRemoved = false; - if (volume == 0) - { - isRemoved = mSignalManager.Remove(s); - } - else if (volume > 0) - { - isUpdated = mSignalManager.AddOrUpdate(s); - } - if ( - isUpdated || - isRemoved) - { - // - AddItemToBuffer( - s, - handlerResult.rf); - } - } - } - else - { - mSignalManager.Remove(iSignal.ticket); - } - } - } - - // - result = - ArraySize(handlerResult.tp) > 0 || - ArraySize(handlerResult.sl) > 0 || - ArraySize(handlerResult.rf) > 0; - - // - return result; - } - - // - // Close All Trades ... - void CloseSignals( - XSignal &result[], // Holds Result - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions - ) - { - // - CleanBuffer(result); - - // - XSignal signals[]; - GetSignals( - signals, - type); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return; - } - - // - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - string comment = GenerateSignalForceCloseComment(iSignal); - - // - bool isClosed = Close( - iSignal.ticket, - comment); - if (isClosed) - { - Add( - iSignal, - result); - } - } - } - - // - // Close Pyramid Signals ... - void CloseInPyramidSignals( - XSignal &result[], // Holds Result - double pyramid = 0, // Close Pyramid Profit - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions - ) - { - // - CleanBuffer(result); - - // - XSignal signals[]; - GetSignals( - signals, - type); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return; - } - - // - double profit = 0; - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - profit += iSignal.profit; - } - - // - // Normalize Pyramid ... - if (pyramid < 0) - { - pyramid = 0; - } - - // - if (profit > pyramid) - { - CloseSignals(result); - } - } - - // - // Close All Trades Which Candle Passed after Open ... - void CloseOldSignals( - XSignal &result[], // Holds Result - int life, // Max Candle Passed after Trades Open - ENUM_TIMEFRAMES period = NULL, // Calculate Candles based on time frame - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions - ) - { - // - CleanBuffer(result); - - // - XSignal signals[]; - GetOldSignals( - signals, - life, - period, - type); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return; - } - - // - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - string comment = GenerateSignalAgeComment(iSignal); - - // - bool isClosed = Close( - iSignal.ticket, - comment); - if (isClosed) - { - Add( - iSignal, - result); - } - } - } - - // - // Close In Profit Signals ... - void CloseInProfitSignals( - XSignal &result[], // Holds Result - double minProfit = 0, // Minimum Profit To Close Trades - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions - ) - { - // - CleanBuffer(result); - - // - XSignal signals[]; - GetInProfitSignals( - signals, - minProfit, - type); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return; - } - - // - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - string comment = GenerateSignalProfitComment(iSignal); - - // - bool isClosed = Close( - iSignal.ticket, - comment); - if (isClosed) - { - Add( - iSignal, - result); - } - } - } - - // - // Close In Drawdown Signals ... - void CloseInDrawdownSignals( - XSignal &result[], // Holds Result - double maxDrawDown = 0, // Minimum Profit To Close Trades - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Specify Type of Positions - ) - { - // - CleanBuffer(result); - - // - XSignal signals[]; - GetInDrawdownSignals( - signals, - maxDrawDown, - type); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return; - } - - // - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - string comment = GenerateSignalProfitComment(iSignal); - - // - bool isClosed = Close( - iSignal.ticket, - comment); - if (isClosed) - { - Add( - iSignal, - result); - } - } - } - - // - // END Signal Execution Actions ... - // - - // - // START Actions ... - // - - // - // Force Open a Buy/Long Position ... - bool Buy( - double volume, // position volume - double price, // execution price - double sl = 0, // stop loss price - double tp = 0, // take profit price - const string comment = "" // comment - ) - { - // - bool result = false; - - // - result = mTrader.Buy( - volume, - mSymbol, - price, - sl, - tp, - comment); - - // - return result; - } - - // - // Send BUY LIMIT order ... - bool BuyLimit( - double volume, // order volume - double price, // order price - double sl = 0.0, // stop loss price - double tp = 0.0, // take profit price - ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime - datetime expiration = 0, // order expiration time - string comment = "" // comment - ) - { - // - bool result = false; - - // - result = mTrader.BuyLimit( - volume, - price, - mSymbol, - sl, - tp, - typeTime, - expiration, - comment); - - // - return result; - } - - // - // Send BUY STOP order ... - bool BuyStop( - double volume, // order volume - double price, // order price - double sl = 0.0, // stop loss price - double tp = 0.0, // take profit price - ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime - datetime expiration = 0, // order expiration time - string comment = "" // comment - ) - { - // - bool result = false; - - // - result = mTrader.BuyStop( - volume, - price, - mSymbol, - sl, - tp, - typeTime, - expiration, - comment); - - // - return result; - } - - // - // Force Open a Sell/Short Position ... - bool Sell( - double volume, // position volume - double price, // execution price - double sl = 0, // stop loss price - double tp = 0, // take profit price - const string comment = "" // comment - ) - { - // - bool result = false; - - // - result = mTrader.Sell( - volume, - mSymbol, - price, - sl, - tp, - comment); - - // - return result; - } - - // - // Send SELL LIMIT order ... - bool SellLimit( - double volume, // order volume - double price, // order price - double sl = 0.0, // stop loss price - double tp = 0.0, // take profit price - ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime - datetime expiration = 0, // order expiration time - string comment = "" // comment - ) - { - // - bool result = false; - - // - result = mTrader.SellLimit( - volume, - price, - mSymbol, - sl, - tp, - typeTime, - expiration, - comment); - - // - return result; - } - - // - // Send SELL STOP order ... - bool SellStop( - double volume, // order volume - double price, // order price - double sl = 0.0, // stop loss price - double tp = 0.0, // take profit price - ENUM_ORDER_TYPE_TIME typeTime = ORDER_TIME_GTC, // order lifetime - datetime expiration = 0, // order expiration time - string comment = "" // comment - ) - { - // - bool result = false; - - // - result = mTrader.SellStop( - volume, - price, - mSymbol, - sl, - tp, - typeTime, - expiration, - comment); - - // - return result; - } - - // - // Modify Position ... - bool Modify( - const ulong ticket, // position ticket - double sl = 0, // stop loss price - double tp = 0, // take profit - const string comment = "" // comment - ) - { - // - bool result = false; - - // - // Validate Args ... - if (tp <= 0 && sl <= 0) - { - result = false; - return result; - } - - // - result = mTrader.PositionModify( - ticket, - sl, - tp, - comment); - if (result) - { - // - if (mSignalManager.IsExists(ticket)) - { - // - XSignal signal = GetSignal(ticket); - - // - mSignalManager.Update(signal); - } - } - - // - return result; - } - - // - // Close Position By Ticket ... - bool Close( - ulong ticket, // Position Ticket - string comment = "" // Close Position By Specific Comment - ) - { - // - bool result = false; - - // - // Try to Select Position ... - if (!mPositionInfo.SelectByTicket(ticket)) - { - return result; - } - - // - // Close Position By Specific Comment ... - result = mTrader.PositionClose( - ticket, - mSlippage, - comment); - if (result) - { - // - if (mSignalManager.IsExists(ticket)) - { - mSignalManager.Remove(ticket); - } - } - - // - return result; - } - - // - // Close Partial By Ticket ... - bool ClosePartial( - ulong ticket, // Position Ticket - double volume, // Volume Size for Partial Closing - string comment = "" // Close Position By Specific Comment - ) - { - // - bool result = false; - - // - if (!mPositionInfo.SelectByTicket(ticket)) - { - return result; - } - - // - result = mTrader.PositionClosePartial( - ticket, - volume, - mSlippage, - comment); - if (result) - { - // - if (mSignalManager.IsExists(ticket)) - { - // - XSignal signal = GetSignal(ticket); - - // - mSignalManager.Update(signal); - } - } - - // - return result; - } - - // - // END Actions ... - // - - // - // START Account Related ... - // - - // - // Retrieve Minimum Balance For Open Trades ... - double GetMinBalanceForOpenTrades() - { - // - double result = mMinBallanceForOpenTrades; - - // - double balance = mAccountInfo.GetBalance(); - double deposit = mAccountInfo.GetInitialBalance(); - if (balance > deposit) - { - // - double rate = mMinBallanceForOpenTrades / deposit; - - // - double ratedBalance = balance * rate; - - // - result = MathMax(mMinBallanceForOpenTrades, ratedBalance); - } - - // - return result; - } - - // - // Check Account Has Minimum Balance For Trade ... - bool IsBalanceReadyForTrade() - { - // - bool result = false; - - // - double minBalance = GetMinBalanceForOpenTrades(); - result = mAccountInfo.GetBalance() >= minBalance; - - // - return result; - } - - // - // Check Free Margin Has Enough For Trade ... - bool IsFreeMarginReadyForTrade() - { - // - bool result = false; - - // - double freeMargin = mAccountInfo.GetFreeMargin(); - - // - result = freeMargin >= mMinAllowedFreeMarginForOpenTrades; - - // - return result; - } - - // - // Check Equity Has Enough For Trade ... - bool IsEquityReadyForTrade() - { - // - bool result = false; - - // - double equity = mAccountInfo.GetEquity(); - - // - result = equity >= mMinAllowedFreeMarginForOpenTrades; - - // - return result; - } - - // - // END Account Related ... - // - - // - // START Signal Related ... - // - - // - // Validate Signal ... - bool IsValidSignal( - XSignal &signal // Specified Signal for Execution - ) - { - // - bool result = false; - - // - // Validate Signal Type ... - result = signal.type != X_SIGNAL_UNKNOWN; - if (!result) - { - return result; - } - - // - // Check Symbol ... - result = StringLen(signal.symbol) == 0 ? true : signal.symbol == mSymbol; - if (!result) - { - return result; - } - - // - // Check magic number ... - result = signal.magicNumber <= 0 ? true : signal.magicNumber == mMagicNumber; - if (!result) - { - return result; - } - - // - // Check Entry ... - result = signal.entry > 0; - if (!result) - { - return result; - } - - // // - // // Check SL ... - // // For Fix RiskFree Issues Ignore this ... - // result = signal.sl == 0 ? true : signal.type == X_SIGNAL_LONG ? signal.sl < signal.entry - // : signal.sl > signal.entry; - // if (!result) - // { - // return result; - // } - - // - // Check TP ... - result = signal.tp == 0 ? true : signal.type == X_SIGNAL_LONG ? signal.tp > signal.entry - : signal.tp < signal.entry; - if (!result) - { - return result; - } - - // - // Check Volume ... - result = signal.volume > 0; - if (!result) - { - return result; - } - - // - // Check Time ... - result = signal.time > 0; - if (!result) - { - return result; - } - - // - return result; - } - - // - // Get Signal InDirection (Reversal) Type ... - ENUM_X_SIGNAL_TYPE GetSignalIndirectionType( - XSignal &signal // Specified Signal - ) - { - // - ENUM_X_SIGNAL_TYPE result = X_SIGNAL_UNKNOWN; - - // - switch (signal.type) - { - // - case X_SIGNAL_LONG: - result = X_SIGNAL_SHORT; - break; - - // - case X_SIGNAL_SHORT: - result = X_SIGNAL_LONG; - break; - } - - // - return result; - } - - // - // Get Signal InDirection (Reversal) Type ... - ENUM_X_SIGNAL_TYPE GetIndirectionSignalType( - ENUM_X_SIGNAL_TYPE type // Specified Type - ) - { - // - ENUM_X_SIGNAL_TYPE result = X_SIGNAL_UNKNOWN; - - // - switch (type) - { - // - case X_SIGNAL_LONG: - result = X_SIGNAL_SHORT; - break; - - // - case X_SIGNAL_SHORT: - result = X_SIGNAL_LONG; - break; - } - - // - return result; - } - - // - // Calculate SignalAge ... - int GetSignalAge( - datetime time // Signal Execution Time - ) - { - // - int result = 0; - - // - // Validate Arg ... - if (time <= 0) - { - return result; - } - - // - int sIndex = iBarShift( - mSymbol, - _Period, - time); - - // - datetime cTime = iTime( - mSymbol, - _Period, - 0); - int cIndex = iBarShift( - mSymbol, - _Period, - cTime); - - // - result = MathAbs(cIndex - sIndex); - - // - return result; - } - int GetSignalAge( - datetime time, // Signal Execution Time - ENUM_TIMEFRAMES period // Specify Time Frame - ) - { - // - int result = 0; - - // - // Validate Arg ... - if (time <= 0) - { - return result; - } - - // - int sIndex = iBarShift( - mSymbol, - period, - time); - - // - datetime cTime = iTime( - mSymbol, - period, - 0); - int cIndex = iBarShift( - mSymbol, - _Period, - cTime); - - // - result = MathAbs(cIndex - sIndex); - - // - return result; - } - int GetSignalAge( - XSignal &signal // Specified Signal - ) - { - // - int result = 0; - - // - // Validate Arg ... - if ( - signal.time <= 0 || - !IsValid(signal, mMagicNumber)) - { - return result; - } - - // - result = GetSignalAge(signal.time); - - // - return result; - } - int GetSignalAge( - XSignal &signal, // Specify Signal - ENUM_TIMEFRAMES period // Specify Time Frame - ) - { - // - int result = 0; - - // - // Validate Arg ... - if ( - signal.time <= 0 || - !IsValid(signal, mMagicNumber)) - { - return result; - } - - // - result = GetSignalAge( - signal.time, - period); - - // - return result; - } - - // - // Prepare a Signall ... - XSignal GenerateSignal( - ENUM_X_SIGNAL_TYPE type, // Signal Type - double tp = 0, // Take Profit - double sl = 0, // Stop Loss - double volume = 0, // Volume - double riskFreeStep = 0, // Risk Free Step Price - double riskFreeRate = 0 // Risk Free Rate - ) - { - // - XSignal result = {}; - - // - // Validate Arg ... - if (type == X_SIGNAL_UNKNOWN) - { - return result; - } - - // - // Check Signal Type ... - bool isLong = type == X_SIGNAL_LONG; - - // - // Retrieve entry Price ... - double entry = GetEntry(mSymbol, type); - double spread = GetSpread(mSymbol); - - // - result.tp = tp; - result.sl = sl; - result.type = type; - result.entry = entry; - result.symbol = mSymbol; - result.magicNumber = mMagicNumber; - result.riskFreeStep = riskFreeStep; - result.riskFreeRate = riskFreeRate; - result.time = iTime(mSymbol, _Period, 0); - result.volume = NormalizeVolume(volume, mSymbol); - - // - // Since we Use signal instance to Generate Comment, this must be at the end ... - result.comment = GenerateSignalComment(result); - - // - return result; - } - - // - // Convert a Signal to String Representation ... - string ToString( - XSignal &signal // Specified Signal - ) - { - // - string result = ""; - - // - if (!IsValid(signal, mMagicNumber) || signal.ticket <= 0) - { - return result; - } - - // - // TICKET ... - // it is very importants since they hold position info ... - result += X_SIGNAL_TICKET + "(" + (string)signal.ticket + ")"; - - // - // TYPE ... - string typeStr = GetSignalType(signal.type); - result += "_" + X_SIGNAL_TYPE + "(" + typeStr + ")"; - - // - // TP ... - result += "_" + X_SIGNAL_TP + "(" + (string)signal.tp + ")"; - - // - // SL ... - result += "_" + X_SIGNAL_SL + "(" + (string)signal.sl + ")"; - - // - // RFS ... - result += "_" + X_SIGNAL_RISKFREE_STEP + "(" + (string)signal.riskFreeStep + ")"; - - // - // RFR ... - result += "_" + X_SIGNAL_RISKFREE_RATE + "(" + (string)signal.riskFreeRate + ")"; - - // - return result; - } - - // - // Generate Comments for Specific Signal ... - string GenerateSignalComment( - ENUM_X_SIGNAL_TYPE type, // Specify Kind Signal Type - double volume, // Signal Volume - bool isCrossSignal = false // Specify Signal Cross - ) - { - // - string result = ""; - - // - string typeStr = GetSignalType(type); - if ( - volume <= 0 || - StringLen(typeStr) == 0) - { - return result; - } - - // - volume = NormalizeVolume(volume, mSymbol); - - // - result = mTag + (!isCrossSignal ? "" : "_Cross_") + "_" + typeStr; - - // - return result; - } - string GenerateSignalComment( - XSignal &signal, // Specified Signal - bool isCrossSignal = false // Specify Signal Cross - ) - { - // - string result = GenerateSignalComment( - signal.type, - signal.volume, - isCrossSignal - // - ); - - // - return result; - } - - // - // Generate Signal RF TP Comment ... - string GenerateSignalRFComment( - XSignal &signal, // Specified Signal - int level // Which Step of RFS - ) - { - // - string result = ""; - - // - // Validate Signal and it's Ticket ... - if (!IsValidSignal(signal) || signal.ticket <= 0) - { - return result; - } - - // - double exit = NormalizePrice(GetExit(signal.symbol, signal.type), signal.symbol); - - // - string prefix = X_SIGNAL_RISKFREE_STEP + "(" + (string)signal.ticket + ")"; - // - result = - // - level > 0 - ? prefix + "_" + (string)level + ": " + (string)exit - : prefix + ": " + (string)exit; - // - ; - - // - return result; - } - - // - // Generate Signal TP Comment ... - string GenerateSignalTPComment( - XSignal &signal // Specified Signal - ) - { - // - string result = ""; - - // - // Validate Signal and it's Ticket ... - if (!IsValidSignal(signal) || signal.ticket <= 0) - { - return result; - } - - // - double exit = NormalizePrice(GetExit(signal.symbol, signal.type), signal.symbol); - - // - result = - // - X_SIGNAL_TP + "(" + (string)signal.ticket + "): " + (string)exit; - // - ; - - // - return result; - } - - // - // Generate Signal SL Comment ... - string GenerateSignalSLComment( - XSignal &signal // Specified Signal - ) - { - // - string result = ""; - - // - // Validate Signal and it's Ticket ... - if (!IsValidSignal(signal) || signal.ticket <= 0) - { - return result; - } - - // - double exit = NormalizePrice(GetExit(signal.symbol, signal.type), signal.symbol); - - // - result = - // - X_SIGNAL_SL + "(" + (string)signal.ticket + "): " + (string)exit; - // - ; - - // - return result; - } - - // - // Generate Signal Profit Comment ... - string GenerateSignalProfitComment( - XSignal &signal // Specified Signal - ) - { - // - string result = ""; - - // - // Validate Signal and it's Ticket ... - if (!IsValidSignal(signal) || signal.ticket <= 0) - { - return result; - } - - // - result = - // - "Profit(" + (string)signal.ticket + "): " + (string)signal.profit; - // - ; - - // - return result; - } - - // - // Generate Signal Force Close Comment ... - string GenerateSignalForceCloseComment( - XSignal &signal // Specified Signal - ) - { - // - string result = ""; - - // - // Validate Signal and it's Ticket ... - if (!IsValidSignal(signal) || signal.ticket <= 0) - { - return result; - } - - // - result = - // - "FC(" + (string)signal.ticket + "): " + (string)signal.profit; - // - ; - - // - return result; - } - - // - // Generate Signal Age Comment ... - string GenerateSignalAgeComment( - XSignal &signal // Specified Signal - ) - { - // - string result = ""; - - // - // Validate Signal and it's Ticket ... - if (!IsValidSignal(signal) || signal.ticket <= 0) - { - return result; - } - - // - int age = GetSignalAge(signal); - - // - result = - // - "(" + (string)signal.ticket + ") A: " + (string)age + ", P:" + (string)signal.profit; - // - ; - - // - return result; - } - - // - // Generate a Signal Object name for Draw Events On Chart ... - string GenerateSignalObjectName( - ulong ticket // Specify Ticket - ) - { - // - string result = ""; - - // - // Validate Arg ... - if (ticket <= 0) - { - return result; - } - - // - // TICKET ... - // it is very importants since they hold position info ... - result += "T(" + (string)ticket + ")"; - - // - return result; - } - string GenerateSignalObjectName( - XSignal &signal // Specified Signal - ) - { - // - string result = ""; - - // - // Validate Arg ... - if (!IsValid(signal, mMagicNumber)) - { - return result; - } - - // - result = GenerateSignalObjectName(signal.ticket); - - // - return result; - } - - // - // Genrate a Signal Event Object Name ... - string GenerateSignalEventObjectName( - ulong ticket // Specify Ticket - ) - { - // - string result = ""; - - // - result = GenerateSignalObjectName(ticket) + "_Event"; - - // - return result; - } - string GenerateSignalEventObjectName( - XSignal &signal // Specified Signal - ) - { - // - string result = ""; - - // - result = GenerateSignalEventObjectName(signal.ticket); - - // - return result; - } - - // - // END Signal Related ... - // - - // - // START Deals ... - // - - // - // Count Deals ... - int DealsCount( - datetime start = -1, // Start Date - datetime end = -1 // End Date - ) - { - // - int result = 0; - - // - XDeal deals[]; - GetDeals( - deals, - start, - end); - result = ArraySize(deals); - - // - return result; - } - - // - // Retrieve All Deals ... - void GetDeals( - XDeal &result[], // Hold's Result - datetime start = -1, // Start Date - datetime end = -1 // End Date - ) - { - // - CleanBuffer(result); - - // - // Select History if Start and End date provided ... - if (start > -1) - { - // - // Normalize End date ... - if (end == -1) - { - end = TimeCurrent(); - } - - // - bool isSelect = HistorySelect(start, end); - if (!isSelect) - { - return; - } - } - - // - int total = HistoryDealsTotal(); - if (total <= 0) - { - return; - } - - // - // Loop ... - for (int i = total - 1; i >= 0; i--) - { - // - // Select by Index ... - bool isSelect = mDealInfo.SelectByIndex(i); - if (!isSelect) - { - continue; - } - - // - // Check Magic ... - ulong magic = mDealInfo.Magic(); - bool isMagicSame = magic == mMagicNumber; - if (!isMagicSame) - { - continue; - } - - // - // Check Symbol ... - string symbol = mDealInfo.Symbol(); - bool isSymbolSame = symbol == mSymbol; - if (!isSymbolSame) - { - continue; - } - - // - XDeal deal = ToXDealByIndex(i); - - // - Add( - deal, - result); - } - } - - // - // Retrieve Last Deal ... - XDeal GetLastDeal() - { - // - XDeal result = {}; - - // - XDeal deals[]; - GetDeals(deals); - int dealsCount = ArraySize(deals); - if (dealsCount <= 0) - { - return result; - } - - // - result = deals[0]; - - // - return result; - } - - // - // END Deals ... - // - - // - // START Orders ... - // - - // - // Count Orders ... - int OrdersCount( - datetime start = -1, // Start Date - datetime end = -1 // End Date - ) - { - // - int result = 0; - - // - XOrder orders[]; - GetOrders( - orders, - start, - end); - result = ArraySize(orders); - - // - return result; - } - - // - // Retrieve Orders ... - void GetOrders( - XOrder &result[], // Hold's Result - datetime start = -1, // Start Date - datetime end = -1 // End Date - ) - { - // - CleanBuffer(result); - - // - // Select History if Start and End date provided ... - if (start > -1) - { - // - // Normalize End date ... - if (end == -1) - { - end = TimeCurrent(); - } - - // - bool isSelect = HistorySelect(start, end); - if (!isSelect) - { - return; - } - } - - // - int total = HistoryOrdersTotal(); - if (total <= 0) - { - return; - } - - // - // Loop ... - for (int i = total - 1; i >= 0; i--) - { - // - // Select by Index ... - bool isSelect = mOrderInfo.SelectByIndex(i); - if (!isSelect) - { - continue; - } - - // - // Check Magic ... - ulong magic = mOrderInfo.Magic(); - bool isMagicSame = magic == mMagicNumber; - if (!isMagicSame) - { - continue; - } - - // - // Check Symbol ... - string symbol = mOrderInfo.Symbol(); - bool isSymbolSame = symbol == mSymbol; - if (!isSymbolSame) - { - continue; - } - - // - XOrder order = ToXOrderByIndex(i); - - // - Add( - order, - result); - } - } - - // - // Retrieve Last Order ... - XOrder GetLastOrder() - { - // - XOrder result = {}; - - // - XOrder orders[]; - GetOrders(orders); - int ordersCount = ArraySize(orders); - if (ordersCount <= 0) - { - return result; - } - - // - result = orders[0]; - - // - return result; - } - - // - // END Orders ... - // - - // - // START OnTrade Handlers ... - // - - // - // Handle OnTrade Event ... - void HandleOnTradeEvent( - XOnTradeHandlerResult &result // Hold's Result - ) - { - // - if (mScanStarted) - { - ProcessOnTradeContext(result); - } - else - { - InitOnTradeContext(); - } - } - - // - // END OnTrade Handlers ... - // - - // - // Retrieve Magic Number ... - ulong GetMagicNumber() - { - return mMagicNumber; - } - - // - // all protected features ... -protected: - // - // all private features ... -private: - // - // Specified Unique Tag ... - string mTag; - - // - // which Symbol ... - string mSymbol; - - // - // using deviation, it must be in Point ... - int mSlippage; - - // - // using magic number ... - ulong mMagicNumber; - - // - // Detect Using Virtual TP or SL ... - bool mUseVirtualTPSL; - - // - // Specify Max Allowed Trades - int mMaxAllowedTrades; - - // - // Minimum Free Marging for Open Trades - double mMinAllowedFreeMarginForOpenTrades; - - // - // Minimum Balance for Open Trades - double mMinBallanceForOpenTrades; - - // - // using CTrade instance ... - XSCTrade mTrader; - - // - // Deals Info ... - CDealInfo mDealInfo; - - // - // Order Info ... - COrderInfo mOrderInfo; - - // - // An Instance Of XCAccount Info for Handling Account Related Actions ... - XCAccountInfo mAccountInfo; - - // - // using PositionInfo instance ... - CPositionInfo mPositionInfo; - - // - // Signal Manager ... - XCSignalManager mSignalManager; - - // - // START OnTrade Handlers ... - // - - // - int mDaysForRead; - - // - // set the limits of the trade history on the global scope ... - - // - // // start date for trade history in cache ... - datetime mStartDate; - - // - // end date for trade history in cache ... - datetime mEndDate; - - // - // global OnTrade counters ... - - // - // number of active orders ... - int mOrdersCount; - - // - // number of open positions ... - int mPositionsCount; - - // - // number of deals in the trade history cache ... - int mDealsCount; - - // - // number of orders in the trade history cache ... - int mHistoryOrdersCount; - - // - // flag of counter relevance ... - bool mScanStarted; - - // - // Check Statrt Date In Trade History ... - void CheckStartDateInTradeHistory() - { - // - // initial interval, if we were to start working right now .. - datetime currStart = TimeCurrent() - (mDaysForRead * PeriodSeconds(PERIOD_D1)); - - // - // make sure that the start limit of the trade history has not gone - // more than 1 day over the intended date ... - if (currStart - mStartDate > PeriodSeconds(PERIOD_D1)) - { - // - // correct the start date of history to be loaded in the cache ... - mStartDate = currStart; - - // - // now reload the trade history for the updated interval ... - HistorySelect(mStartDate, mEndDate); - - // - // correct the deal and order counters in history for further comparison - mHistoryOrdersCount = HistoryOrdersTotal(); - mDealsCount = HistoryDealsTotal(); - } - } - - // - // Process On Trade Context ... - void ProcessOnTradeContext( - XOnTradeHandlerResult &result // Hold's Result - ) - { - // - mEndDate = TimeCurrent(); - - // - ResetLastError(); - - // - // download trading history from the specified interval to the program cache ... - bool selected = HistorySelect(mStartDate, mEndDate); - if (!selected) - { - // - LogMessage("Failed to Load OnTrade Context History ..."); - - // - return; - } - - // - // get the current values ... - int currOrders = OrdersTotal(); - int currPositions = PositionsTotal(); - int currDeals = HistoryDealsTotal(); - int currHistoryOrders = HistoryOrdersTotal(); - - // - // Orders ... - // check if the number of active orders has been changed ... - if (currOrders != mOrdersCount) - { - // - // number of active orders has been changed ... - result.hasNewOrder = true; - result.newOrders = currOrders - mOrdersCount; - - // - // update the value ... - mOrdersCount = currOrders; - } - - // - // Positions ... - // changes in the number of open positions ... - if (currPositions != mPositionsCount) - { - // - // number of open positions has been changed ... - result.hasNewPosition = true; - result.newPositions = currPositions - mPositionsCount; - - // - // update the value ... - mPositionsCount = currPositions; - } - - // - // Deals ... - // changes in the number of deals in the trade history cache ... - if (currDeals != mDealsCount) - { - // - // number of deals in the trade history cache has been changed ... - result.hasNewDeal = true; - result.newDeals = currDeals - mDealsCount; - - // - // update the value ... - mDealsCount = currDeals; - } - - // - // History Orders ... - // changes in the number of history orders in the trade history cache ... - if (currHistoryOrders != mHistoryOrdersCount) - { - // - // number of history orders in the trade history cache has been changed ... - result.hasNewHistoryOrder = true; - result.newHistoryOrders = currHistoryOrders - mHistoryOrdersCount; - - // - // update the value ... - mHistoryOrdersCount = currHistoryOrders; - } - - // - // checking if it is necessary to change the limits of the trade history to be requested in cache ... - CheckStartDateInTradeHistory(); - } - - // - // Reset On Trade Scanner Context ... - void ResetOnTradeContext() - { - // - mEndDate = TimeCurrent(); - mStartDate = mEndDate - (mDaysForRead * PeriodSeconds(PERIOD_D1)); - } - - // - // Initial Context Of Trade Scanner ... - void InitOnTradeContext() - { - // - ResetLastError(); - - // - // load history ... - bool selected = HistorySelect(mStartDate, mEndDate); - if (!selected) - { - // - LogMessage("Failed to Load OnTrade Context History ..."); - - // - return; - } - - // - // get the current value ... - mOrdersCount = OrdersTotal(); - mPositionsCount = PositionsTotal(); - mDealsCount = HistoryDealsTotal(); - mHistoryOrdersCount = HistoryOrdersTotal(); - - // - mScanStarted = true; - } - - // - // END OnTrade Handlers ... - // - - // - // START Signal Private ... - // - - // - // Add Or Update Signal ... - void AddOrUpdateSignalInfo( - XSignal &signal // Specified Signal - ) - { - // - bool isExists = mSignalManager.IsExists(signal); - if (isExists) - { - mSignalManager.Remove(signal.ticket); - } - - // - bool isAddOrUpdated = mSignalManager.AddOrUpdate(signal); - if (isAddOrUpdated) - { - // - color longColor = clrAqua; - color shortColor = clrFuchsia; - - // - DrawSignalShape( - signal, - longColor, - shortColor); - } - } - - // - // Retrieve Signal String From Chart Event ... - XSignal RetrieveSignal( - ulong ticket // Specify Position Ticket - ) - { - // - XSignal result = {}; - - // - if (ticket <= 0) - { - return result; - } - - // - result = mSignalManager.Get(ticket); - - // - return result; - } - void RetrieveSignal( - XSignal &signal // Specified Signal - ) - { - - // - XSignal tSignal = mSignalManager.Get(signal.ticket); - - // - // Fill signal by tSignal Data ... - // since tese properties may change in signal manipulation times ... - signal.tp = tSignal.tp; - signal.sl = tSignal.sl; - signal.riskFreeStep = tSignal.riskFreeStep; - signal.riskFreeRate = tSignal.riskFreeRate; - } - - // - // Convert Position to Signal by Index ... - XSignal PositionToSignal(int index) - { - // - XSignal result = {}; - - // - if (!mPositionInfo.SelectByIndex(index)) - { - return result; - } - - // - ulong ticket = mPositionInfo.Ticket(); - result = PositionToSignal(ticket); - - // - return result; - } - - // - // Position To Signal by Ticket ... - XSignal PositionToSignal(ulong ticket) - { - // - XSignal result = {}; - - // - if (!mPositionInfo.SelectByTicket(ticket)) - { - return result; - } - - // - bool isExists = mSignalManager.IsExists(ticket); - if (isExists) - { - result = RetrieveSignal(ticket); - } - - // - // Ticket ... - result.ticket = mPositionInfo.Ticket(); - - // - // ID ... - result.id = mPositionInfo.Identifier(); - - // - // Symbol ... - result.symbol = mPositionInfo.Symbol(); - - // - // Type ... - ENUM_POSITION_TYPE pType = (ENUM_POSITION_TYPE)mPositionInfo.PositionType(); - ENUM_X_SIGNAL_TYPE type = pType == POSITION_TYPE_BUY ? X_SIGNAL_LONG : X_SIGNAL_SHORT; - result.type = type; - - // - // MagicNumber ... - result.magicNumber = mPositionInfo.Magic(); - - // - // Entry/Open Price ... - result.entry = mPositionInfo.PriceOpen(); - - // - // Take Profit ... - result.tp = result.tp <= 0 && mPositionInfo.TakeProfit() > 0 - ? mPositionInfo.TakeProfit() - : result.tp; - - // - // Stop Loss ... - result.sl = result.sl <= 0 && mPositionInfo.StopLoss() > 0 - ? mPositionInfo.StopLoss() - : result.sl; - - // - // Profit ... - result.profit = mPositionInfo.Profit(); - - // - // Time ... - result.time = mPositionInfo.Time(); - - // - // Volume ... - result.volume = mPositionInfo.Volume(); - - // - // Comment ... - result.comment = mPositionInfo.Comment(); - - // - return result; - } - - // - // Converts a Deal to XDeal by Index ... - XDeal ToXDealByIndex(int index) - { - // - XDeal result = {}; - - // - bool isSelect = mDealInfo.SelectByIndex(index); - if (!isSelect) - { - return result; - } - - // - // Read Deal Ticket ... - ulong ticket = mDealInfo.Ticket(); - result = ToXDealByTicket(ticket); - - // - return result; - } - - // - // Converts a Deal to XDeal by Ticket ... - XDeal ToXDealByTicket(ulong ticket) - { - // - XDeal result = {}; - - // - mDealInfo.Ticket(ticket); - - // - result.time = mDealInfo.Time(); - result.swap = mDealInfo.Swap(); - result.magic = mDealInfo.Magic(); - result.order = mDealInfo.Order(); - result.entry = mDealInfo.Entry(); - result.price = mDealInfo.Price(); - result.ticket = mDealInfo.Ticket(); - result.symbol = mDealInfo.Symbol(); - result.type = mDealInfo.DealType(); - result.profit = mDealInfo.Profit(); - result.volume = mDealInfo.Volume(); - result.comment = mDealInfo.Comment(); - result.positionId = mDealInfo.PositionId(); - result.commission = mDealInfo.Commission(); - result.reason = (ENUM_DEAL_REASON)HistoryDealGetInteger( - ticket, - DEAL_REASON); - - // - return result; - } - - // - // Convert an Order to XOrder by Index ... - XOrder ToXOrderByIndex(int index) - { - // - XOrder result = {}; - - // - bool isSelect = mOrderInfo.SelectByIndex(index); - if (!isSelect) - { - return result; - } - - // - ulong ticket = mOrderInfo.Ticket(); - result = ToXOrderByTicket(ticket); - - // - return result; - } - - // - // Convert an Order to XOrder by Ticket ... - XOrder ToXOrderByTicket(ulong ticket) - { - // - XOrder result = {}; - - // - bool isSelect = mOrderInfo.Select(ticket); - if (!isSelect) - { - return result; - } - - // - result.state = mOrderInfo.State(); - result.magic = mOrderInfo.Magic(); - result.ticket = mOrderInfo.Ticket(); - result.symbol = mOrderInfo.Symbol(); - result.type = mOrderInfo.OrderType(); - result.comment = mOrderInfo.Comment(); - result.stopLoss = mOrderInfo.StopLoss(); - result.typeTime = mOrderInfo.TypeTime(); - result.timeDone = mOrderInfo.TimeDone(); - result.timeSetup = mOrderInfo.TimeSetup(); - result.positionId = mOrderInfo.PositionId(); - result.priceOpen = mOrderInfo.PriceOpen(); - result.takeProfit = mOrderInfo.TakeProfit(); - result.typeFilling = mOrderInfo.TypeFilling(); - result.priceCurrent = mOrderInfo.PriceCurrent(); - result.volumeInitial = mOrderInfo.VolumeInitial(); - result.volumeCurrent = mOrderInfo.VolumeCurrent(); - result.timeExpiration = mOrderInfo.TimeExpiration(); - result.priceStopLimit = mOrderInfo.PriceStopLimit(); - result.reason = (ENUM_ORDER_REASON)HistoryOrderGetInteger( - ticket, - ORDER_REASON); - - // - return result; - } - // - // END Signal Private ... - // -}; - -// -// a Class For Guard Account ... -class XCGuard : public XCBase -{ - // - // Public ... -public: - // - // Constructor ... - XCGuard( - int oldAge, // Age for Old Trades - ENUM_X_GUARD_ACTIONS oldGuardAction, // Guard Action for Too Old State - double criticalFactor, // Critical DrawDown Factor based On Balance - ENUM_X_GUARD_ACTIONS criticalAction, // Guard Action for Critical State - double maxFactor, // Max DrawDown Factor based on Balance - ENUM_X_GUARD_ACTIONS maxAction, // Guard Action for Max State - int GuardStopoutFiredAfterTouches, // Guard Stopout if Max State touched - ENUM_X_GUARD_SUPPORT_METHODS supportMethod // How to Support Signals - ) - { - // - mSupportPrefix = "SPT"; - mDirectional = "SPD"; - mInDirectional = "SPIND"; - - // - mOldAge = oldAge; - mOldGuardAction = oldGuardAction; - - // - mMaxFactor = maxFactor; - mMaxAction = maxAction; - mCriticalFactor = criticalFactor; - mCriticalAction = criticalAction; - mGuardStopoutFiredAfterTouches = GuardStopoutFiredAfterTouches; - - // - mSupportMethod = supportMethod; - - // - mAccountInfo = new XCAccountInfo(); - - // - double deposit = mAccountInfo.GetInitialBalance(); - - // - if ( - maxFactor > 0 && - maxFactor < 1) - { - mMaxValue = maxFactor * deposit; - } - - // - if ( - criticalFactor > 0 && - criticalFactor < 1) - { - mCriticalValue = criticalFactor * deposit; - } - - // - Reset(); - ResetMaxDrawDownTouches(); - } - - // - // Deconstructor ... - ~XCGuard() {} - - // - // Reset List ... - void Reset() - { - // - CleanBuffer(mGuardedSignals); - CleanBuffer(mSupportedSignals); - } - - // - // Reset Consecutive Max DrawDown Touches ... - void ResetMaxDrawDownTouches() - { - mOccuredconsecutiveMaxDraDownTouches = 0; - } - - // - // Calculate and Retrieve Critical DrawDown Value ... - double GetCriticalValue() - { - // - double result = mCriticalValue; - if (mCriticalFactor <= 0) - { - return result; - } - - // - double deposit = mAccountInfo.GetInitialBalance(); - double balance = mAccountInfo.GetBalance(); - - // - if (balance > deposit) - { - // - double balanceBasedCriticalDrawDown = mCriticalFactor * balance; - - // - result = MathMax( - mCriticalValue, - balanceBasedCriticalDrawDown); - } - - // - return result; - } - - // - // Calculate and Retrieve Max Allowed DrawDown Value ... - double GetMaxValue() - { - // - double result = mMaxValue; - if (mMaxValue <= 0) - { - return result; - } - - // - double deposit = mAccountInfo.GetInitialBalance(); - double balance = mAccountInfo.GetBalance(); - - // - if (balance > deposit) - { - // - double balanceBasedMaxAllwedDrawDown = mMaxFactor * balance; - - // - result = MathMax( - mMaxValue, - balanceBasedMaxAllwedDrawDown); - } - - // - return result; - } - - // - // Guard Account Protection ... - bool Guard( - XGuardHandlerResult &guardResult, // Hold's Message - string &message, // Hold's Message - XCTrade &trader, // Specified Trader - ENUM_TIMEFRAMES period = NULL // Specified Time Frame for Detecting Signal Ages - ) - { - // - message = ""; - - // - // Clean Result of Guard ... - CleanBuffer(guardResult.olds); - CleanBuffer(guardResult.maxes); - CleanBuffer(guardResult.criticals); - - // - bool result = false; - - // - // So Important is to Guard DrawDowns ... - result = GuardDrawDown( - guardResult, - message, - trader); - if (result) - { - return result; - } - - // - // Then we have to Guard Old Trades ... - result = GuardOlds( - guardResult, - message, - trader); - - // - return result; - } - - // - // Handle Guard Old Trades ... - bool GuardOlds( - XGuardHandlerResult &guardResult, // Hold's Message - string &message, // Hold's Message - XCTrade &trader, // Specified Trader - ENUM_TIMEFRAMES period = NULL // Specified Time Frame for Detecting Signal Ages - ) - { - // - // Cleanup Message ... - message = ""; - - // - // Clean Result of Guard ... - CleanBuffer(guardResult.olds); - - // - bool result = false; - - // - // Validate Args ... - if ( - mOldAge <= 0 || - mOldGuardAction == X_GUARD_DO_NOTHING) - { - return result; - } - - // - // Normalize Args ... - if (period == NULL) - { - period = _Period; - } - - // - // Retrieve Old Trades ... - XSignal oldSignals[]; - trader.GetOldSignals( - oldSignals, - mOldAge, - period); - int oldSignalsCount = ArraySize(oldSignals); - if (oldSignalsCount <= 0) - { - return result; - } - - // - result = DoGuardAction( - guardResult, - message, - trader, - mOldGuardAction, - X_GUARDED_OLD, // Specify Guard Reason - period // Specified Running Time Frame for Signal Age Calculations - ); - - // - return result; - } - - // - // Hnadle Guard DrawDown ... - bool GuardDrawDown( - XGuardHandlerResult &guardResult, // Hold's Message - string &message, // Hold's Message - XCTrade &trader // Specified Trader - ) - { - // - message = ""; - - // - // Clean Result of Guard ... - CleanBuffer(guardResult.maxes); - CleanBuffer(guardResult.criticals); - - // - bool result = false; - - // - // Check State for Guard ... - bool isCriticalGuardEnabled = mCriticalFactor > 0; - bool isMaxGuardEnabled = mMaxFactor > 0; - bool isGuardEnabled = - isMaxGuardEnabled; - - // - if (!isGuardEnabled) - { - return result; - } - - // - double maxValue = GetMaxValue(); - double criticalValue = GetCriticalValue(); - - // - double profitSums = trader.GetSignalsProfit(); - - // - bool isMaxReached = - profitSums < 0 && - isMaxGuardEnabled && - MathAbs(profitSums) >= maxValue; - bool isCriticalReached = - profitSums < 0 && - isCriticalGuardEnabled && - MathAbs(profitSums) >= criticalValue; - - // - if (!isMaxReached && !isCriticalReached) - { - // - // Reset Consecutive Max DrawDown Touches ... - ResetMaxDrawDownTouches(); - - // - return result; - } - - // - // Check For Critical Guard ... - if (isCriticalReached && !isMaxReached) - { - // - result = DoGuardAction( - guardResult, - message, - trader, - mCriticalAction, - X_GUARDED_CRITICAL); - } - else if (isMaxReached) - { - // - result = DoGuardAction( - guardResult, - message, - trader, - mMaxAction, - X_GUARDED_MAX); - - // - // Handle Guard StopOut Action ... - mOccuredconsecutiveMaxDraDownTouches++; - if ( - mMaxAction != X_GUARD_DO_NOTHING && - mMaxAction != X_GUARD_CLOSE_ALL && - mGuardStopoutFiredAfterTouches > 0 && - mOccuredconsecutiveMaxDraDownTouches >= mGuardStopoutFiredAfterTouches) - { - // - XSignal closed[]; - trader.CloseSignals(closed); - int closedCount = ArraySize(closed); - if (closedCount > 0) - { - // - for (int i = 0; i < closedCount; i++) - { - // - XSignal iSignal = closed[i]; - - // - AddItemToBuffer( - iSignal, - guardResult.maxes); - } - - // - message = "Guard StopOut Action Closed (" + (string)closedCount + ") Signals and Release Account ..."; - - // - guardResult.isStopOut = true; - - // - result = true; - } - } - } - - // - return result; - } - - // - // Do Signal Protections and apply Support ... - bool ProtectSignals( - XSignal &mResult[], // Hold's Result - XCTrade &trader, // Specified Trader - int numberOfItemsCheck = 30 // Number of Items to check - ) - { - // - bool result = false; - - // - CleanBuffer(mResult); - - // - // Check Supports Enabled ... - result = IsSupportEnabled(); - if (!result) - { - return result; - } - - // - // Update Supports ... - XSignal signals[]; - trader.GetSignals(signals); - int signalsCount = ArraySize(signals); - if (signalsCount > 0) - { - // - for (int i = 0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - bool isExists = IsSupportExists(iSignal.ticket); - if (isExists) - { - UpdateSupport(iSignal); - } - } - } - - // - // Count Supporteds ... - XProtectedSignal supporteds[]; - GetAllSupports(supporteds); - int supportedCount = ArraySize(supporteds); - result = supportedCount > 0; - if (!result) - { - return result; - } - - // - // Loop through ... - for (int i = 0; i < supportedCount; i++) - { - // - XProtectedSignal iP = supporteds[i]; - - // - bool canDoDirectional = CanDoDirectionalSupport( - trader, - iP.ticket, - numberOfItemsCheck); - bool canDoInDirectional = CanDoInDirectionalSupport( - trader, - iP.ticket, - numberOfItemsCheck); - - // - if ( - !canDoDirectional && - !canDoInDirectional) - { - continue; - } - - // - // Do Directional ... - if (canDoDirectional) - { - // - // Generate Propper Signal ... - XSignal sdSignal = GenerateDirectionalSupportSignal( - iP.ticket, - trader); - - // - ENUM_EXECUTION_SIGNAL_RESULT executionResult = trader.ExecuteSignal( - sdSignal, - true, - false); - bool isExecuted = executionResult == X_TRADER_SUCCEED_EXECUTION; - if (isExecuted) - { - // - XSignal eSignal = trader.GetSignal(sdSignal.ticket); - - // - AddItemToBuffer( - eSignal, - mResult); - } - } - // - // Do Indirectional ... - else if (canDoInDirectional) - { - // - // Generate Propper Signal ... - XSignal sindSignal = GenerateDirectionalSupportSignal( - iP.ticket, - trader); - - // - ENUM_EXECUTION_SIGNAL_RESULT executionResult = trader.ExecuteSignal( - sindSignal, - true, - false); - bool isExecuted = executionResult == X_TRADER_SUCCEED_EXECUTION; - if (isExecuted) - { - // - XSignal eSignal = trader.GetSignal(sindSignal.ticket); - - // - AddItemToBuffer( - eSignal, - mResult); - } - } - } - - // - result = ArraySize(mResult) > 0; - - // - return result; - } - - // - // Validate State ... - bool Validate() - { - // - bool result = false; - - // - result = - mMaxFactor > 0 && - (mCriticalFactor > 0 - ? mCriticalFactor < mMaxFactor - : true); - - // - return result; - } - - // - // START Guarded Signals Functions ... - // - - // - // Add new Protecte Signal ... - bool Add( - XSignal &signal // Specified Signal - ) - { - // - bool result = false; - - // - bool isExists = IsExists(signal.ticket); - if (isExists) - { - return result; - } - - // - XProtectedSignal item; - - // - datetime time = TimeCurrent(); - - // - item.ticket = signal.ticket; - - // - AddItemToBuffer( - time, - item.time); - - // - AddItemToBuffer( - signal.profit, - item.profit); - - // - AddItemToBuffer( - item, - mGuardedSignals); - - // - return result; - } - - // - // Get All ... - void GetAll( - XProtectedSignal &result[] // Hold's Result - ) - { - // - CopyBuffer( - mGuardedSignals, - result); - } - - // - // Get ... - XProtectedSignal Get( - ulong ticket // Specified Signal Ticket - ) - { - // - XProtectedSignal result; - - // - bool isExists = IsExists(ticket); - if (!isExists) - { - return result; - } - - // - int protectedCounts = ArraySize(mGuardedSignals); - if (protectedCounts <= 0) - { - return result; - } - - // - for (int i = 0; i < protectedCounts; i++) - { - // - XProtectedSignal iProtected = mGuardedSignals[i]; - - // - if (iProtected.ticket == ticket) - { - // - result = iProtected; - break; - } - } - - // - return result; - } - - // - // Remove ... - bool Remove( - ulong ticket // Specified Signal Ticket - ) - { - // - bool result = false; - - // - result = IsExists(ticket); - if (!result) - { - return result; - } - - // - int protectedCounts = ArraySize(mGuardedSignals); - result = protectedCounts > 0; - if (!result) - { - return result; - } - - // - XProtectedSignal cleared[]; - for (int i = 0; i < protectedCounts; i++) - { - // - XProtectedSignal iProtected = mGuardedSignals[i]; - - // - if (iProtected.ticket != ticket) - { - AddItemToBuffer( - iProtected, - cleared); - } - } - - // - // Update Source by Cleared ... - CopyBuffer( - cleared, - mGuardedSignals); - - // - result = true; - - // - return result; - } - - // - // Update ... - bool Update( - ulong ticket, // Specified Signal Ticket - datetime time, // Specified Last Checked time - double profit // Specified Signal Profit - // XProtectedSignal &item // Specified which object to Update - ) - { - // - bool result = false; - - // - int protectedCounts = ArraySize(mGuardedSignals); - result = protectedCounts > 0; - if (!result) - { - return result; - } - - // - result = IsExists(ticket); - if (!result) - { - return result; - } - - // - // Retrieve Struct ... - XProtectedSignal item = Get(ticket); - AddItemToBuffer( - time, - item.time); - AddItemToBuffer( - profit, - item.profit); - - // - result = Remove(ticket); - if (!result) - { - return result; - } - - // - AddItemToBuffer( - item, - mGuardedSignals); - result = true; - - // - return result; - } - bool Update( - XProtectedSignal &item // Specified Protected Item - ) - { - // - bool result = false; - - // - datetime time; - result = GetLastItem( - time, - item.time); - if (!result) - { - return result; - } - - // - double profit; - result = GetLastItem( - profit, - item.profit); - if (!result) - { - return result; - } - - // - result = Update( - item.ticket, time, profit); - - // - return result; - } - bool Update( - XSignal &signal // Specified Signal - ) - { - // - bool result = false; - - // - ulong ticket = signal.ticket; - datetime time = TimeCurrent(); - double profit = signal.profit; - - // - result = Update( - ticket, - time, - profit); - - // - return result; - } - - // - // Add Or Update ... - bool AddOrUpdate( - XSignal &signal // Specified Signal - ) - { - // - bool result = false; - - // - bool isExists = IsExists(signal.ticket); - if (!isExists) - { - result = Add(signal); - } - else - { - result = Update(signal); - } - - // - return result; - } - - // - // Check Exists ... - bool IsExists( - ulong ticket // Specified Signal Ticket - ) - { - // - bool result = false; - - // - // Validate Args ... - if (ticket <= 0) - { - return result; - } - - // - int protectedCounts = ArraySize(mGuardedSignals); - if (protectedCounts <= 0) - { - return result; - } - - // - for (int i = 0; i < protectedCounts; i++) - { - // - XProtectedSignal iProtected = mGuardedSignals[i]; - - // - if (iProtected.ticket == ticket) - { - // - result = true; - break; - } - } - - // - return result; - } - - // - // Count Protecteds ... - int Count() - { - // - int result = 0; - - // - result = ArraySize(mGuardedSignals); - - // - return result; - } - - // - // END Guarded Signals Functions ... - // - - // - // START Supported Signals Functions ... - // - - // - // Check can Handle Support Signals or not ... - bool IsSupportEnabled() - { - // - bool result = false; - - // - result = - mSupportMethod != X_SUPPORT_DO_NOTHING; - - // - return result; - } - - // - // Retrieve List Of Supported Signals ... - void GetSupportSignals( - XSignal &result[], // Hold's Result ... - XCTrade &trader // Specified Trader class Instance ... - ) - { - // - CleanBuffer(result); - - // - XSignal signals[]; - trader.GetSignals(signals); - int signalsCount = ArraySize(signals); - if (signalsCount <= 0) - { - return; - } - - // - for (int i = -0; i < signalsCount; i++) - { - // - XSignal iSignal = signals[i]; - - // - bool isSupport = IsSupport(iSignal.comment); - if (isSupport) - { - AddItemToBuffer( - iSignal, - result); - } - } - } - - // - // Retrieve List Of Specific Signals Supported Signals ... - void GetSignalSupports( - XSignal &result[], // Hold's Result ... - XCTrade &trader, // Specified Trader class Instance ... - ulong ticket // Specified Signal Ticket ... - ) - { - // - CleanBuffer(result); - - // - // Validate Args ... - if (ticket <= 0) - { - return; - } - - // - // Check Signal Exists using Trader ... - XSignal parentSignal = trader.GetSignal(ticket); - bool isValid = - parentSignal.ticket > 0 && - parentSignal.ticket == ticket && - StringLen(parentSignal.comment) > 0; - if (!isValid) - { - return; - } - - // - XSignal supportSignals[]; - GetSupportSignals( - supportSignals, - trader); - int supportSignalsCount = ArraySize(supportSignals); - if (supportSignalsCount <= 0) - { - return; - } - - // - for (int i = 0; i < supportSignalsCount; i++) - { - // - XSignal iSignal = supportSignals[i]; - - // - bool isBelongsToParent = IsBelongsToParent( - ticket, - iSignal.comment); - if (isBelongsToParent) - { - AddItemToBuffer( - iSignal, - result); - } - } - } - - // - // Check Specific Support Conditions for Opening Directional Support ... - bool CanDoDirectionalSupport( - XCTrade &trader, // Specified Trader class Instance ... - ulong ticket, // Specified Signal Ticket ... - int numberOfItemsCheck = 30 // Number of Items to check ... - ) - { - // - bool result = false; - - // - // Check Supports Enabled ... - result = IsSupportEnabled(); - if (!result) - { - return result; - } - - // - // Check Support Method Allows Directional ... - result = - mSupportMethod == X_SUPPORT_FULL || - mSupportMethod == X_SUPPORT_IN_DRAWUP_DIRECTIONAL; - if (!result) - { - return result; - } - - // - // Validate Ticket ... - result = ticket > 0; - if (!result) - { - return result; - } - - // - // Check Supports Count ... - int supportedCount = ArraySize(mSupportedSignals); - result = supportedCount > 0; - if (!result) - { - return result; - } - - // - // Check Ticket Exists in Supports ... - result = IsSupportExists(ticket); - if (!result) - { - return result; - } - - // - // Check signal Doesn't have any Support ... - XSignal supports[]; - GetSignalSupports( - supports, - trader, - ticket); - int supportsCount = ArraySize(supports); - result = supportsCount <= 0; - if (!result) - { - return result; - } - - // - // Retrieve Support Model ... - XProtectedSignal sInfo = GetSupport(ticket); - - // - // Validate Model ... - int sTimesCount = ArraySize(sInfo.time); - int sProfitsCount = ArraySize(sInfo.profit); - result = - sInfo.ticket == ticket && - sTimesCount == sProfitsCount && - sTimesCount >= numberOfItemsCheck && - sProfitsCount >= numberOfItemsCheck; - if (!result) - { - return result; - } - - // - // Validate Signal Age ... - XSignal sSignal = trader.GetSignal(ticket); - int sSignalAge = trader.GetSignalAge(sSignal.time); - result = sSignalAge >= numberOfItemsCheck; - if (!result) - { - return result; - } - - // - // Extrat Profits ... - double lastProfits[]; - for (int i = sProfitsCount - 1; i >= (sProfitsCount - numberOfItemsCheck); i++) - { - // - double iProfit = sInfo.profit[i]; - - // - AddItemToBuffer( - iProfit, - lastProfits); - } - - // - string logMsg = ToString(lastProfits); - LogMessage("" + (string)ticket + " lastProfits: \n" + logMsg); - - // - result = false; - - // - // Now implement Business Logics ... - - // - return result; - } - - // - // Check Specific Support Conditions for Opening InDirectional Support ... - bool CanDoInDirectionalSupport( - XCTrade &trader, // Specified Trader class Instance ... - ulong ticket, // Specified Signal Ticket ... - int numberOfItemsCheck = 30 // Number of Items to check ... - ) - { - // - bool result = false; - - // - // Check Supports Enabled ... - result = IsSupportEnabled(); - if (!result) - { - return result; - } - - // - // Check Support Method Allows Directional ... - result = - mSupportMethod == X_SUPPORT_FULL || - mSupportMethod == X_SUPPORT_IN_DRAWDOWN_INDIRECTIONAL; - if (!result) - { - return result; - } - - // - // Validate Ticket ... - result = ticket > 0; - if (!result) - { - return result; - } - - // - // Check Supports Count ... - int supportedCount = ArraySize(mSupportedSignals); - result = supportedCount > 0; - if (!result) - { - return result; - } - - // - // Check Ticket Exists in Supports ... - result = IsSupportExists(ticket); - if (!result) - { - return result; - } - - // - // Check signal Doesn't have any Support ... - XSignal supports[]; - GetSignalSupports( - supports, - trader, - ticket); - int supportsCount = ArraySize(supports); - result = supportsCount <= 0; - if (!result) - { - return result; - } - - // - // Retrieve Support Model ... - XProtectedSignal sInfo = GetSupport(ticket); - - // - // Validate Model ... - int sTimesCount = ArraySize(sInfo.time); - int sProfitsCount = ArraySize(sInfo.profit); - result = - sInfo.ticket == ticket && - sTimesCount == sProfitsCount && - sTimesCount >= numberOfItemsCheck && - sProfitsCount >= numberOfItemsCheck; - if (!result) - { - return result; - } - - // - // Validate Signal Age ... - XSignal sSignal = trader.GetSignal(ticket); - int sSignalAge = trader.GetSignalAge(sSignal.time); - result = sSignalAge >= numberOfItemsCheck; - if (!result) - { - return result; - } - - // - // Extrat Profits ... - double lastProfits[]; - for (int i = sProfitsCount - 1; i >= (sProfitsCount - numberOfItemsCheck); i++) - { - // - double iProfit = sInfo.profit[i]; - - // - AddItemToBuffer( - iProfit, - lastProfits); - } - - // - string logMsg = ToString(lastProfits); - LogMessage("" + (string)ticket + " lastProfits: \n" + logMsg); - - // - result = false; - - // - // Now implement Business Logics ... - - // - return result; - } - - // - // Generate Directional Support Signal for Parent Signal ... - XSignal GenerateDirectionalSupportSignal( - ulong ticket, // Specified Parent Signal Ticket ... - XCTrade &trader // Specified Trader Class ... - ) - { - // - XSignal result = {}; - - // - // Validate Args ... - if (ticket <= 0) - { - return result; - } - - // - XSignal pSignal = trader.GetSignal(ticket); - bool isValidParent = - pSignal.ticket > 0 && - pSignal.ticket == ticket && - StringLen(pSignal.comment) > 0; - if (!isValidParent) - { - return result; - } - - // - ENUM_X_SIGNAL_TYPE type = pSignal.type; - bool isLong = IsLong(type); - - // - double entry = GetEntry( - pSignal.symbol, - type); - double exit = GetExit( - pSignal.symbol, - type); - - // - double reward = PipsToPrice( - pSignal.symbol, - 6); - double risk = PipsToPrice( - pSignal.symbol, - 1); - - // - double tp = - isLong - ? entry + reward - : entry - reward; - - // - double sl = - isLong - ? exit - risk - : exit + risk; - - // - double rfStep = 2; - double rfRate = 0.5; - - // - double volume = NormalizeVolume( - pSignal.volume / 2, - pSignal.symbol, - 2); - - // - // Generate Signal using Trader Class Instance ... - result = trader.GenerateSignal( - // - type, - tp, - sl, - volume, - rfStep, - rfRate - // - ); - - // - return result; - } - - // - // Generate InDirectional Support Signal for Parent Signal ... - XSignal GenerateInDirectionalSupportSignal( - ulong ticket, // Specified Parent Signal Ticket ... - XCTrade &trader // Specified Trader Class ... - ) - { - // - XSignal result = {}; - - // - // Validate Args ... - if (ticket <= 0) - { - return result; - } - - // - XSignal pSignal = trader.GetSignal(ticket); - bool isValidParent = - pSignal.ticket > 0 && - pSignal.ticket == ticket && - StringLen(pSignal.comment) > 0; - if (!isValidParent) - { - return result; - } - - // - ENUM_X_SIGNAL_TYPE type = trader - .GetIndirectionSignalType(pSignal.type); - bool isLong = IsLong(type); - - // - double entry = GetEntry( - pSignal.symbol, - type); - double exit = GetExit( - pSignal.symbol, - type); - - // - double reward = PipsToPrice( - pSignal.symbol, - 6); - double risk = PipsToPrice( - pSignal.symbol, - 1); - - // - double tp = - isLong - ? entry + reward - : entry - reward; - - // - double sl = - isLong - ? exit - risk - : exit + risk; - - // - double rfStep = 2; - double rfRate = 0.5; - - // - double volume = NormalizeVolume( - pSignal.volume / 2, - pSignal.symbol, - 2); - - // - // Generate Signal using Trader Class Instance ... - result = trader.GenerateSignal( - // - type, - tp, - sl, - volume, - rfStep, - rfRate - // - ); - - // - return result; - } - - // - // Generate Specific Signals Support Signal Comment ... - string GenerateSupportSignalComment( - ulong ticket, // Specified Parent Signal Ticket - ENUM_X_SIGNAL_TYPE type, // Specified Support Signal Type - bool isInDirectional = false // Specified Support Signal Direction - ) - { - // - string result = ""; - - // - if (ticket <= 0) - { - return result; - } - - // - string typeString = GetSignalType(type); - string directionStr = GenerateSupportDirection(isInDirectional); - - // - result = - mSupportPrefix + "(" + (string)ticket + ")_" + - X_SIGNAL_TYPE + "(" + typeString + ")_" + - directionStr; - - // - return result; - } - - // - // Get Support Direction String Representation ... - string GenerateSupportDirection( - bool isInDirectional = false // Specified Support Signal Direction - ) - { - // - string result = ""; - - // - result = - isInDirectional - ? mInDirectional - : mDirectional; - - // - return result; - } - - // - // Check an String Is Directional Or not ... - bool IsDirectionalSupport( - string comment // Specified Comment ... - ) - { - // - bool result = false; - - // - result = IsSupport(comment); - if (!result) - { - return result; - } - - // - int sPos = StringFind( - comment, - mDirectional); - result = sPos >= 0; - - // - return result; - } - - // - // Check an String Is In Directional Or not ... - bool IsInDirectionalSupport( - string comment // Specified Comment ... - ) - { - // - bool result = false; - - // - result = IsSupport(comment); - if (!result) - { - return result; - } - - // - int sPos = StringFind( - comment, - mInDirectional); - result = sPos >= 0; - - // - return result; - } - - // - // Check an String Is Support or not ... - bool IsSupport( - string comment // Specified Comment ... - ) - { - // - bool result = false; - - // - int sPos = StringFind( - comment, - mSupportPrefix); - result = sPos >= 0; - - // - return result; - } - - // - // Extract Parent of Support Signal Ticket from a comment ... - ulong ExtractParentTicket( - string comment // Specified Comment ... - ) - { - // - ulong result = 0; - - // - bool isSupport = IsSupport(comment); - if (!isSupport) - { - return result; - } - - // - // TICKET ... - string ticketStr = ExtractString( - comment, - mSupportPrefix + "(", - ")"); - if (StringLen(ticketStr) > 0) - { - result = (ulong)ticketStr; - } - - // - return result; - } - - // - // Check a Comment belongs to Support Signal or not ... - bool IsBelongsToParent( - ulong ticket, // Specified Parent Signal Ticket - string comment // Specified Support Signal Comment - ) - { - // - bool result = false; - - // - // Validate Arg ... - if (ticket <= 0) - { - return result; - } - - // - result = IsSupport(comment); - if (!result) - { - return result; - } - - // - ulong spTicket = ExtractParentTicket(comment); - result = spTicket == ticket; - - // - return result; - } - - // - // Add new Protecte Signal ... - bool AddSupport( - XSignal &signal // Specified Signal - ) - { - // - bool result = false; - - // - bool isExists = IsSupportExists(signal.ticket); - if (isExists) - { - return result; - } - - // - XProtectedSignal item; - - // - datetime time = TimeCurrent(); - - // - item.ticket = signal.ticket; - - // - AddItemToBuffer( - time, - item.time); - - // - AddItemToBuffer( - signal.profit, - item.profit); - - // - AddItemToBuffer( - item, - mSupportedSignals); - - // - return result; - } - - // - // Get All ... - void GetAllSupports( - XProtectedSignal &result[] // Hold's Result - ) - { - // - CopyBuffer( - mSupportedSignals, - result); - } - - // - // Get ... - XProtectedSignal GetSupport( - ulong ticket // Specified Signal Ticket - ) - { - // - XProtectedSignal result; - - // - bool isExists = IsSupportExists(ticket); - if (!isExists) - { - return result; - } - - // - int protectedCounts = ArraySize(mSupportedSignals); - if (protectedCounts <= 0) - { - return result; - } - - // - for (int i = 0; i < protectedCounts; i++) - { - // - XProtectedSignal iProtected = mSupportedSignals[i]; - - // - if (iProtected.ticket == ticket) - { - // - result = iProtected; - break; - } - } - - // - return result; - } - - // - // Remove ... - bool RemoveSupport( - ulong ticket // Specified Signal Ticket - ) - { - // - bool result = false; - - // - result = IsSupportExists(ticket); - if (!result) - { - return result; - } - - // - int protectedCounts = ArraySize(mSupportedSignals); - result = protectedCounts > 0; - if (!result) - { - return result; - } - - // - XProtectedSignal cleared[]; - for (int i = 0; i < protectedCounts; i++) - { - // - XProtectedSignal iProtected = mSupportedSignals[i]; - - // - if (iProtected.ticket != ticket) - { - AddItemToBuffer( - iProtected, - cleared); - } - } - - // - // Update Source by Cleared ... - CopyBuffer( - cleared, - mSupportedSignals); - - // - result = true; - - // - return result; - } - - // - // Update ... - bool UpdateSupport( - ulong ticket, // Specified Signal Ticket - datetime time, // Specified Last Checked time - double profit // Specified Signal Profit - ) - { - // - bool result = false; - - // - int protectedCounts = ArraySize(mSupportedSignals); - result = protectedCounts > 0; - if (!result) - { - return result; - } - - // - result = IsSupportExists(ticket); - if (!result) - { - return result; - } - - // - // Retrieve Struct ... - XProtectedSignal item = GetSupport(ticket); - AddItemToBuffer( - time, - item.time); - AddItemToBuffer( - profit, - item.profit); - - // - result = RemoveSupport(ticket); - if (!result) - { - return result; - } - - // - AddItemToBuffer( - item, - mSupportedSignals); - result = true; - - // - return result; - } - bool UpdateSupport( - XProtectedSignal &item // Specified Protected Item - ) - { - // - bool result = false; - - // - datetime time; - result = GetLastItem( - time, - item.time); - if (!result) - { - return result; - } - - // - double profit; - result = GetLastItem( - profit, - item.profit); - if (!result) - { - return result; - } - - // - result = UpdateSupport( - item.ticket, time, profit); - - // - return result; - } - bool UpdateSupport( - XSignal &signal // Specified Signal - ) - { - // - bool result = false; - - // - ulong ticket = signal.ticket; - datetime time = TimeCurrent(); - double profit = signal.profit; - - // - result = UpdateSupport( - ticket, - time, - profit); - - // - return result; - } - - // - // Add Or Update ... - bool AddOrUpdateSupport( - XSignal &signal // Specified Signal - ) - { - // - bool result = false; - - // - bool isExists = IsSupportExists(signal.ticket); - if (!isExists) - { - result = Add(signal); - } - else - { - result = Update(signal); - } - - // - return result; - } - - // - // Check Exists ... - bool IsSupportExists( - ulong ticket // Specified Signal Ticket - ) - { - // - bool result = false; - - // - // Validate Args ... - if (ticket <= 0) - { - return result; - } - - // - int protectedCounts = ArraySize(mSupportedSignals); - if (protectedCounts <= 0) - { - return result; - } - - // - for (int i = 0; i < protectedCounts; i++) - { - // - XProtectedSignal iProtected = mSupportedSignals[i]; - - // - if (iProtected.ticket == ticket) - { - // - result = true; - break; - } - } - - // - return result; - } - - // - // Count Protecteds ... - int CountSupports() - { - // - int result = 0; - - // - result = ArraySize(mSupportedSignals); - - // - return result; - } - - // - // END Suppoprted Signals Functions ... - // - - // - // START Getter/Setter(s) ... - // - - // - int GetOldAge() - { - return mOldAge; - } - - // - bool SetOldAge(int value) - { - // - bool result = false; - - // - result = - value > 0 && - mOldAge != value; - if (!result) - { - return result; - } - - // - mOldAge = value; - - // - return result; - } - - // - ENUM_X_GUARD_ACTIONS GetOldGuardAction() - { - return mOldGuardAction; - } - - // - bool SetOldGuardAction(ENUM_X_GUARD_ACTIONS value) - { - // - bool result = false; - - // - result = value != mOldGuardAction; - if (!result) - { - return result; - } - - // - mOldGuardAction = value; - - // - return result; - } - - // - double GetCriticalFactor() - { - return mCriticalFactor; - } - - // - bool SetCriticalFactor(bool value) - { - // - bool result = false; - - // - result = - value > 0 && - value < 1 && - mCriticalFactor != value; - if (!result) - { - return result; - } - - // - mCriticalFactor = value; - - // - double deposit = mAccountInfo.GetInitialBalance(); - mCriticalValue = deposit * value; - - // - return result; - } - - // - ENUM_X_GUARD_ACTIONS GetCriticalAction() - { - return mCriticalAction; - } - - // - bool SetCriticalAction(ENUM_X_GUARD_ACTIONS value) - { - // - bool result = false; - - // - result = - value != mCriticalAction; - if (!result) - { - return result; - } - - // - mCriticalAction = value; - - // - return result; - } - - // - double GetMaxFactor() - { - return mMaxFactor; - } - - // - bool SetMaxFactor(bool value) - { - // - bool result = false; - - // - result = - value > 0 && - value < 1 && - mMaxFactor != value; - if (!result) - { - return result; - } - - // - mMaxFactor = value; - - // - double deposit = mAccountInfo.GetInitialBalance(); - mMaxValue = deposit * value; - - // - return result; - } - - // - ENUM_X_GUARD_ACTIONS GetMaxAction() - { - return mMaxAction; - } - - // - bool SetMaxAction(ENUM_X_GUARD_ACTIONS value) - { - // - bool result = false; - - // - result = - value != mMaxAction; - if (!result) - { - return result; - } - - // - mMaxAction = value; - - // - return result; - } - - // - ENUM_X_GUARD_SUPPORT_METHODS GetSupportMethod() - { - return mSupportMethod; - } - - // - bool SetSupportMethod(ENUM_X_GUARD_SUPPORT_METHODS value) - { - // - bool result = false; - - // - result = - value != mSupportMethod; - if (!result) - { - return result; - } - - // - mSupportMethod = value; - - // - return result; - } - - // - // END Getter/Setter(s) ... - // - - // - // Generate Signal Guard Attacked Message ... - string GenerateGuardedSignalComment( - XSignal &signal, // Specified Signal - ENUM_X_GUARD_REASONS reason // Specified Guard Reason - ) - { - // - string result = ""; - - // - string reasonMessage = - ( - // - reason == X_GUARDED_OLD - ? "Because of Old Issue" - : reason == X_GUARDED_CRITICAL - ? "Because Of Crtical Drawdown Isuue" - : reason == X_GUARDED_MAX - ? "Because of Max Drawdown Issue" - : "" - // - ) + - " On Profit: " + (string)signal.profit; - - // - result += "Guard Attacked (" + (string)signal.ticket + "), " + reasonMessage + " ..."; - - // - return result; - } - - // - // Protected ... -protected: - // - // Private ... -private: - // - string mSupportPrefix; - string mDirectional; - string mInDirectional; - - // - XProtectedSignal mGuardedSignals[]; - XProtectedSignal mSupportedSignals[]; - - // - int mOldAge; - ENUM_X_GUARD_ACTIONS mOldGuardAction; - - // - // Critical DrawDown Factor based On Balance ... - double mCriticalFactor; - double mCriticalValue; - - // - // Guard Action for Critical State ... - ENUM_X_GUARD_ACTIONS mCriticalAction; - - // - // Max DrawDown Factor based on Balance ... - double mMaxFactor; - double mMaxValue; - // - // Guard Stopout if Max State touched ... - int mOccuredconsecutiveMaxDraDownTouches; - int mGuardStopoutFiredAfterTouches; - - // - // Guard Action for Max State ... - ENUM_X_GUARD_ACTIONS mMaxAction; - - // - // How to Support Signals ... - ENUM_X_GUARD_SUPPORT_METHODS mSupportMethod; - - // - // Account Info Instance ... - XCAccountInfo mAccountInfo; - - // - // Get Volume Multiplier for Specified Guard Action ... - double GetGuardActionVolumeMultiplier( - ENUM_X_GUARD_ACTIONS action = X_GUARD_DO_NOTHING // Specified Action - ) - { - // - // Partial Close Max In Drawdown Trade ... - double result = 0.0; - if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_1) - { - result = 0.01; - } - else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_2) - { - result = 0.02; - } - else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_3) - { - result = 0.03; - } - else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_5) - { - result = 0.05; - } - else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_10) - { - result = 0.10; - } - else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_15) - { - result = 0.15; - } - else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_20) - { - result = 0.20; - } - else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_25) - { - result = 0.25; - } - else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_30) - { - result = 0.30; - } - else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_40) - { - result = 0.40; - } - else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_50) - { - result = 0.50; - } - else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_60) - { - result = 0.60; - } - else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_70) - { - result = 0.70; - } - else if (action == X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_75) - { - result = 0.75; - } - - // - return result; - } - - // - // Do Specified Guard Action ... - bool DoGuardAction( - XGuardHandlerResult &guardResult, // Hold's Result ... - string &message, // Hold's Message ... - XCTrade &trader, // Specified Trader Class ... - ENUM_X_GUARD_ACTIONS action, // Specified Which Action to Do ... - ENUM_X_GUARD_REASONS reason, // Specified Guard Reason ... - ENUM_TIMEFRAMES period = NULL // Specified Time Frame for Detecting Signal Ages ... - ) - { - // - bool result = false; - - // - message = ""; - - // - string reasonString = - reason == X_GUARDED_OLD - ? "Because of Age Issue" - : "Because of DD " + ( - // - reason == X_GUARDED_CRITICAL ? "Critical" : "Max" - // - ) + - " Issue"; - - // - // Validate Args ... - if (action == X_GUARD_DO_NOTHING) - { - // - message = "Max Allowed Drawdown Reached, but nothing Happens ..."; - - // - return result; - } - - // - // Normalize Period ... - if (period == NULL) - { - period = _Period; - } - - // - // Close All Signals ... - XSignal closed[]; - XSignal maxInDDSignal; - - // - // Handle Perform Guard Action ... - switch (action) - { - // - // Close All ... - case X_GUARD_CLOSE_ALL: - { - // - trader.CloseSignals(closed); - int closedCount = ArraySize(closed); - result = closedCount > 0; - if (!result) - { - break; - } - - // - message = "Closed (" + (string)closedCount + ") Trades by Guard, " + reasonString + " ..."; - } - break; - - // - case X_GUARD_CLOSE_MAX_IN_DD: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_1: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_2: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_3: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_5: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_10: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_15: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_20: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_25: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_30: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_40: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_50: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_60: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_70: - case X_GUARD_PARTIAL_CLOSE_MAX_IN_DD_75: - { - // - // Retrieve Max In Drawdown Trade ... - maxInDDSignal = trader.GetMaxInDrawdownSignal(); - bool isValid = IsValid(maxInDDSignal, trader.GetMagicNumber()) && maxInDDSignal.ticket > 0; - if (!isValid) - { - break; - } - - // - // Close Max In Drawdown Trade ... - if (action == X_GUARD_CLOSE_MAX_IN_DD) - { - // - string comment = "Signal (" + (string)maxInDDSignal.ticket + ") Closed by Guard ..."; - result = trader.Close( - maxInDDSignal.ticket, - comment); - if (result) - { - message = comment; - } - - // - break; - } - - // - int signalAge = 0; - bool canGuard = true; - bool isGuardedBefore = false; - - // - // Do Some Additional Verifications if Guard for Olds Trades ... - if (reason == X_GUARDED_OLD) - { - // - // Retrieve Signal Age ... - signalAge = trader.GetSignalAge( - maxInDDSignal, - period); - - // - // Check Guarded Before Or Not ... - isGuardedBefore = IsExists(maxInDDSignal.ticket); - if (isGuardedBefore) - { - // - // Now We Have to Check Signal Age growse required times to apply Guard Action again ... - // First Calculate Guard Grow Step ... - int ageGrowStep = mOldAge / 10; - - // - XProtectedSignal guardItem = Get(maxInDDSignal.ticket); - datetime lastGuardTime = 0; - if (GetLastItem(lastGuardTime, guardItem.time)) - { - // - int lastGuardIndex = iBarShift( - maxInDDSignal.symbol, - period, - lastGuardTime); - - // - canGuard = - MathAbs(lastGuardIndex) >= ageGrowStep; - } - } - else - { - // - // Check Signal age ... - canGuard = signalAge >= mOldAge; - } - } - - // - // Prevent Moving Forward ... - if (!canGuard) - { - // - result = false; - break; - } - - // - // Partial Close Max In Drawdown Trade ... - double volumeRate = GetGuardActionVolumeMultiplier(action); - - // - double volume = NormalizeVolume( - maxInDDSignal.volume * volumeRate, - maxInDDSignal.symbol); - - // - string commentPrefix = "Signal (" + (string)maxInDDSignal.ticket + ") Partial Closed (" + (string)volumeRate + ") by Guard"; - string comment = commentPrefix + " ..."; - - // - result = trader.ClosePartial( - maxInDDSignal.ticket, - volume, - comment); - if (result) - { - // - reasonString = - reasonString + - (reason == X_GUARDED_OLD - ? " (" + (string)signalAge + ")" - : " (" + (string)maxInDDSignal.profit + ")"); - - // - // Update Guarded Signals ... - if (isGuardedBefore) - { - // - XSignal tSignal = trader.GetSignal(maxInDDSignal.ticket); - - // - if (tSignal.ticket > 0 && tSignal.volume > 0) - { - // - // Update In Guardeds ... - Update(tSignal); - } - else - { - // - // Remove From Guardeds ... - Remove(tSignal.ticket); - } - } - else if (reason == X_GUARDED_OLD) - { - // - // Added to Guardeds ... - Add(maxInDDSignal); - } - - // - message = commentPrefix + reasonString + " ..."; - } - } - break; - - // - // Nothing ... - // Default ... - default: - message = "Max Allowed Drawdown Reached ..."; - break; - } - - // - result = StringLen(message) > 0; - if (!result) - { - return result; - } - - // - if (result) - { - // - if (reason == X_GUARDED_OLD) - { - // - int closedCount = ArraySize(closed); - if (closedCount > 0) - { - // - for (int i = 0; i < closedCount; i++) - { - AddItemToBuffer( - closed[i], - guardResult.olds); - } - } - - // - if (maxInDDSignal.ticket > 0) - { - AddItemToBuffer( - maxInDDSignal, - guardResult.olds); - } - } - else if (reason == X_GUARDED_CRITICAL) - { - // - int closedCount = ArraySize(closed); - if (closedCount > 0) - { - // - for (int i = 0; i < closedCount; i++) - { - AddItemToBuffer( - closed[i], - guardResult.criticals); - } - } - - // - if (maxInDDSignal.ticket > 0) - { - AddItemToBuffer( - maxInDDSignal, - guardResult.criticals); - } - } - else if (reason == X_GUARDED_MAX) - { - // - int closedCount = ArraySize(closed); - if (closedCount > 0) - { - // - for (int i = 0; i < closedCount; i++) - { - AddItemToBuffer( - closed[i], - guardResult.maxes); - } - } - - // - if (maxInDDSignal.ticket > 0) - { - AddItemToBuffer( - maxInDDSignal, - guardResult.maxes); - } - } - } - - // - return result; - } -}; - -// -// END Global Definitions: Variables, Properties and etc ... -// diff --git a/Experts/x-saherelm.xtest.ea.mq5 b/Experts/x-saherelm.xtest.ea.mq5 deleted file mode 100644 index cf246c7c..00000000 --- a/Experts/x-saherelm.xtest.ea.mq5 +++ /dev/null @@ -1,572 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Expert Advisor -// ---------------------------------------- -// Name: XAUUSD -// Description: this is an expert controller -// advisors which provides a mechanism for use them ... -// -// -// Maintainer: -// ------------ -// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) -// -////////////////////////////////////////////////////// -// -// Global Properties ... -#property copyright "Copyright 2023, SaherElm IT Center" -#property link "https://saherelm.ir" -#property version "1.00" -#property description "SaherElm XTEST EA" -#property strict - -// -#include - -// -// START Inputs ... -// -// -input group "Commons"; - -// -input double staticVolume = 0.01; // Static Volume - -// -// FAST ... -input int fastLength = 9; // Fast Ma Length -input ENUM_MA_METHOD fastMethod = MODE_SMA; // fast Ma Method -input ENUM_APPLIED_PRICE fastAppliedTo = PRICE_CLOSE; // fast Ma Applied To - -// -// SLOW ... -input int slowLength = 18; // Slow Ma Length -input ENUM_MA_METHOD slowMethod = MODE_SMA; // slow Ma Method -input ENUM_APPLIED_PRICE slowAppliedTo = PRICE_CLOSE; // slow Ma Applied To -// -// END Inputs ... -// - -// -// START Including Providers ... -// - -// -// Logger Library ... -#include "../Libraries/x-saherelm.log.lib.mq5" - -// -// Common Library ... -#include "../Libraries/x-saherelm.common.lib.mq5" - -// -// Alert Library ... -#include "../Libraries/x-saherelm.alert.lib.mq5" - -// -// Draw Library ... -#include "../Libraries/x-saherelm.draw.lib.mq5" - -// -// END Including Providers ... -// - -// -// START Global Definitions: Variables, Properties and etc ... -// -// -ulong magicNumber = 169405612; - -// -int xMAFastHandler = INVALID_HANDLE; -double xMAFastBuffer[]; - -// -int xMASlowHandler = INVALID_HANDLE; -double xMASlowBuffer[]; - -// -int ticksCount; -int signalTicksCount; - -// -CPositionInfo mPositionInfo; -// -// END Global Definitions: Variables, Properties and etc ... -// - -// -// START Event Handlers ... -// - -// -// Initialization ... -int OnInit() -{ - // - logTag = "XTESTEA"; - drawPrefix = logTag; - alertPrefix = logTag; - - // - // Apply default Chart Style for EA ... - ApplyChartStyle(); - - // - // Reset Timings ... - ResetTiming(); - - // - // Validate Inputs ... - if (!ValidateInputs()) - { - return INIT_PARAMETERS_INCORRECT; - } - - // - // Define Handlers ... - if (!DefineHandlers()) - { - return INIT_FAILED; - } - - // - // Init Succeed ... - return INIT_SUCCEEDED; -} - -// -// DeInitialization ... -void OnDeinit(const int reason) -{ - // - // REASON_PROGRAM 0 The EA has stopped working calling the ExpertRemove() function - // REASON_REMOVE 1 Program removed from a chart - // REASON_RECOMPILE 2 Program recompiled - // REASON_CHARTCHANGE 3 A symbol or a chart period is changed - // REASON_CHARTCLOSE 4 Chart closed - // REASON_PARAMETERS 5 Inputs changed by a user - // REASON_ACCOUNT 6 Another account has been activated or reconnection to the trade server has occurred due to changes in the account settings - // REASON_TEMPLATE 7 Another chart template applied - // REASON_INITFAILED 8 The OnInit() handler returned a non-zero value - // REASON_CLOSE 9 Terminal closed - - // - // Here we can handle De Initialization Reasons ... - ReleaseHandlers(); -} - -// -// On Tick Handler ... -void OnTick() -{ - // - if (!IsNewCandle()) - { - ticksCount++; - } - - // - HandleTick(); -} - -// -// Handle Trade Events ... -void OnTrade() -{ -} - -// -// END Event Handlers ... -// - -// -// START Functions ... -// - -// -// Validate Input Args for Initialization ... -bool ValidateInputs() -{ - // - bool result = false; - - // - // Validate Args ... - - // - // Validate XTEST Provider Inputs ... - result = true; - if (!result) - { - return false; - } - - // - // Logging State ... - string message = "Validation of (" + logTag + ") Inputs " + (result ? "Succeeded" : "Failed") + " ..."; - LogMessage(message); - - // - return result; -} - -bool DefineHandlers() -{ - // - bool result = true; - - // - // FAST ... - xMAFastHandler = iMA( - _Symbol, - _Period, - fastLength, - 0, - fastMethod, - fastAppliedTo); - - // - if (xMAFastHandler == INVALID_HANDLE) - { - // - result = false; - return result; - } - - // - // SLOW ... - xMASlowHandler = iMA( - _Symbol, - _Period, - slowLength, - 0, - fastMethod, - fastAppliedTo); - - // - if (xMASlowHandler == INVALID_HANDLE) - { - // - result = false; - return result; - } - - // - return result; -} - -void ReadBuffers(int bar_index) -{ - // - // Reading Fast Buffer ... - int readedFastItems = CopyBuffer( - xMAFastHandler, - 0, - bar_index, - 5, - xMAFastBuffer); - - // - // Reading Slow Buffer ... - int readedSlowItems = CopyBuffer( - xMASlowHandler, - 0, - bar_index, - 5, - xMASlowBuffer); -} - -void ReleaseHandlers() -{ - // - IndicatorRelease(xMAFastHandler); - IndicatorRelease(xMASlowHandler); -} - -void HandleTick() -{ - // - HandleControlState(); - - // - ReadBuffers(1); - - // - XOHCL cl0 = GetCandle(0); - XOHCL cl1 = GetCandle(1); - XOHCL cl2 = GetCandle(2); - - // - bool hasLong = - // - // Base Condition ... - ( - // - xMAFastBuffer[0] > xMASlowBuffer[0] - // - && - // - xMAFastBuffer[1] > xMASlowBuffer[1] - // - && - // - xMAFastBuffer[2] > xMASlowBuffer[2] - // - ) - // - && - // - cl1.close > cl2.close - // - && - // - cl0.close > cl1.close - // - ; - if (hasLong && signalTicksCount < 3) - { - // - signalTicksCount++; - - // - if (signalTicksCount == 3) - { - // - signalTicksCount = 0; - - // - double entry = GetEntry(X_SIGNAL_LONG); - double sl = GetLowestLow(3, 0); - double tp = entry + (150 * _Point); - double volume = staticVolume; - - // - // declare and initialize the trade request and result of trade request - MqlTradeRequest request = {}; - MqlTradeResult result = {}; - - // - // parameters of request - request.tp = tp; - request.sl = sl; - request.deviation = 5; - request.price = entry; - request.volume = volume; - request.symbol = _Symbol; - request.magic = magicNumber; - request.type = ORDER_TYPE_BUY; - request.action = TRADE_ACTION_DEAL; - - // - ResetLastError(); - string signalType = EnumToString(request.type); - - // - bool isExecuted = OrderSend( - request, - result); - if (!isExecuted) - { - // - string errMsg = GetErrorDescription(GetLastError()); - LogMessage("Signal " + signalType + " Execution Failed: " + errMsg); - } - else - { - LogMessage("Signal " + signalType + " Executed Successfully ..."); - } - } - } - - // - bool hasShort = - // - // Base Condition ... - ( - // - xMAFastBuffer[0] < xMASlowBuffer[0] - // - && - // - xMAFastBuffer[1] < xMASlowBuffer[1] - // - && - // - xMAFastBuffer[2] < xMASlowBuffer[2] - // - ) - // - && - // - cl1.close < cl2.close - // - && - // - cl0.close < cl1.close - // - ; - if (hasShort && signalTicksCount < 3) - { - // - signalTicksCount++; - - // - if (signalTicksCount == 3) - { - // - signalTicksCount = 0; - - // - double entry = GetEntry(X_SIGNAL_SHORT); - double sl = GetHighestHigh(3, 0); - double tp = entry - (150 * _Point); - double volume = staticVolume; - - // - // declare and initialize the trade request and result of trade request - MqlTradeRequest request = {}; - MqlTradeResult result = {}; - - // - // parameters of request - request.tp = tp; - request.sl = sl; - request.deviation = 5; - request.price = entry; - request.volume = volume; - request.symbol = _Symbol; - request.magic = magicNumber; - request.type = ORDER_TYPE_SELL; - request.action = TRADE_ACTION_DEAL; - - // - ResetLastError(); - string signalType = EnumToString(request.type); - - // - bool isExecuted = OrderSend( - request, - result); - if (!isExecuted) - { - // - string errMsg = GetErrorDescription(GetLastError()); - LogMessage("Signal " + signalType + " Execution Failed: " + errMsg); - } - else - { - LogMessage("Signal " + signalType + " Executed Successfully ..."); - } - } - } -} - -void HandleControlState() -{ - // - int count = PositionsTotal(); - if (count <= 0) - { - return; - } - - // - double totalProfit = 0; - - // - // Loop through Positions ... - for (int index = count - 1; index >= 0; index--) - { - // - int isSelected = mPositionInfo.SelectByIndex(index); - if (!isSelected) - { - continue; - } - - // - string symbol = mPositionInfo.Symbol(); - if (symbol != _Symbol) - { - continue; - } - - // - ulong pMagic = mPositionInfo.Magic(); - if (pMagic != magicNumber) - { - continue; - } - - // - double pProfit = mPositionInfo.Profit(); - totalProfit += pProfit; - } - - // - // Handle Hedging Positions ... - if (count > 1 && totalProfit > 0) - { - // - // Loop through Positions and Close All of Them ... - for (int index = count - 1; index >= 0; index--) - { - // - int isSelected = mPositionInfo.SelectByIndex(index); - if (!isSelected) - { - continue; - } - - // - string symbol = mPositionInfo.Symbol(); - if (symbol != _Symbol) - { - continue; - } - - // - ulong pMagic = mPositionInfo.Magic(); - if (pMagic != magicNumber) - { - continue; - } - - // - ulong ticket = mPositionInfo.Ticket(); - double volume = mPositionInfo.Volume(); - ENUM_POSITION_TYPE pType = (ENUM_POSITION_TYPE)mPositionInfo.PositionType(); - - // - double entry = GetEntry(pType == POSITION_TYPE_BUY ? X_SIGNAL_SHORT : X_SIGNAL_LONG); - - // - // - // declare and initialize the trade request and result of trade request - MqlTradeRequest request = {}; - MqlTradeResult result = {}; - - // - // parameters of request - request.deviation = 5; - request.price = entry; - request.volume = volume; - request.symbol = _Symbol; - request.magic = magicNumber; - request.type = pType == POSITION_TYPE_BUY ? ORDER_TYPE_SELL : ORDER_TYPE_BUY; - request.action = TRADE_ACTION_DEAL; - - // - ResetLastError(); - - // - bool isExecuted = OrderSend( - request, - result); - } - } -} -// -// END Functions ... -// diff --git a/Libraries/x-saherelm.alert.lib.mq5 b/Libraries/x-saherelm.alert.lib.mq5 deleted file mode 100644 index 10790632..00000000 --- a/Libraries/x-saherelm.alert.lib.mq5 +++ /dev/null @@ -1,200 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Alert Library -// -------------------------------------- -// Name: XAlert -// Description: provides Alerts abilities ... -// -// -// Maintainer: -// ------------ -// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) -// -////////////////////////////////////////////////////// -// -// Global Properties ... -#property library -#property copyright "Copyright 2023, SaherElm IT Center" -#property link "https://www.saherelm.ir" -#property version "1.00" -#property strict - -// -// START Inputs ... -// -input group "Alerts"; -input bool enableAlerts = true; // Enable Alerts -input bool logAlerts = true; // Log Alerts -input bool terminalAlerts = false; // Terminal Alerts -input bool mailAlerts = false; // Mail Alerts -input bool pushAlerts = false; // Push Alerts -// -// END Inputs ... -// - -// -#include "x-saherelm.log.lib.mq5" - -// -// START Global Definitions: Variables, Properties and etc ... -// -string alertPrefix = "X-Alert"; -// -// END Global Definitions: Variables, Properties and etc ... -// - -// -// START Provided Functions ... -// -// -// Initial Library if required ... -bool OnInInitAlertLibrary() -{ - return false; -} - -// -// DeInitial Library if required ... -void OnDeinitAlertLibrary() -{ -} - -// -// Attach Alert Prefix to Message ... -string PrepareAlertMessage(string message) -{ - // - StringReplace(message, "\n", " | "); - - // - StringConcatenate(message, alertPrefix, " > ", message); - - // - return message; -} - -// -// Logging an Alert ... -void LogAlert(string message) -{ - // - // Validate Args ... - if (!enableAlerts || !logAlerts) - { - return; - } - - // - LogMessage(alertPrefix, message); -} - -// -// Terminal Alert ... -void TerminalAlert(string message) -{ - // - // Validate Args ... - if (!enableAlerts || !terminalAlerts) - { - return; - } - - // - // Prepare Message ... - message = PrepareAlertMessage(message); - - // Send Terminal Alert ... - Alert(message); -} - -// -// Mail Alert ... -void MailAlert(string message) -{ - // - // Validate Args ... - if (!enableAlerts || !mailAlerts) - { - return; - } - - // - // Send Mail Alert ... - SendMail(alertPrefix, message); -} - -// -// Send Push Notification ... -void PushAlert(string message) -{ - // - // Validate Args ... - if (!enableAlerts || !pushAlerts) - { - return; - } - - // - // Prepare Message ... - message = PrepareAlertMessage(message); - - // - // Send Push Notification Alert ... - SendNotification(message); -} - -// -// Alert Sending ... -void SendAlert(string message) -{ - // - // Validate Args ... - if (!enableAlerts) - { - return; - } - - // - // Log ... - if (logAlerts) - { - LogAlert(message); - } - - // - // Terminal ... - if (terminalAlerts) - { - TerminalAlert(message); - } - - // - // Mail ... - if (mailAlerts) - { - MailAlert(message); - } - - // - // Push ... - if (pushAlerts) - { - PushAlert(message); - } -} -void SendAlert( - XSignal &signal, // the Signal Object which requred to Alert - bool asExecuted = true // determines Alert Signal as Executed Signal or not -) -{ - // - // Prepare Message ... - string message = asExecuted ? ExecutedSignalToString(signal) : SignalToString(signal); - - // - // Do Alerting ... - SendAlert(message); -} -// -// END Provided Functions ... -// diff --git a/Libraries/x-saherelm.common.lib.mq5 b/Libraries/x-saherelm.common.lib.mq5 deleted file mode 100644 index 290dde9b..00000000 --- a/Libraries/x-saherelm.common.lib.mq5 +++ /dev/null @@ -1,4429 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Common Library -// -------------------------------------- -// Name: XCommon -// Description: provide all commonly used functions ... -// -// -// Maintainer: -// ------------ -// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) -// -////////////////////////////////////////////////////// -// -// Global Properties ... -#property library -#property copyright "Copyright 2023, SaherElm IT Center" -#property link "https://www.saherelm.ir" -#property version "1.00" -#property strict - -// -// START Inputs ... -// - -// -// END Inputs ... -// - -// -// Include Models Library ... -#include "x-saherelm.models.lib.mq5" - -// -// START Global Definitions: Variables, Properties and etc ... -// -// -// END Global Definitions: Variables, Properties and etc ... -// - -// -// START Provided Functions ... -// - -// -// Detect is new Candle or not ... -bool IsNewCandle() -{ - // - bool result = false; - - // - static int barsOnChart = 0; - int currentBarsOnChart = Bars(_Symbol, _Period); - result = currentBarsOnChart > barsOnChart; - if (!result) - { - return result; - } - - // - barsOnChart = currentBarsOnChart; - result = true; - - // - return result; -} - -// -// Retrive Ask Price ... -double GetAsk() -{ - return SymbolInfoDouble(_Symbol, SYMBOL_ASK); -} -double GetAsk( - string symbol // selected symbol for calculations -) -{ - // - double result = SymbolInfoDouble(symbol, SYMBOL_ASK); - - // - return result; -} - -// -// Retrieve Bid Price ... -double GetBid() -{ - return SymbolInfoDouble(_Symbol, SYMBOL_BID); -} -double GetBid( - string symbol // selected symbol for calculations -) -{ - // - double result = SymbolInfoDouble(symbol, SYMBOL_BID); - - // - return result; -} - -// -// Calculate and Retrieve Spread Price ... -double GetSpread() -{ - // - double ask = GetAsk(); - double bid = GetBid(); - double result = MathAbs(ask - bid); - - // - return result; -} -double GetSpread( - string symbol // selected symbol for calculations -) -{ - // - double ask = GetAsk(symbol); - double bid = GetBid(symbol); - double result = MathAbs(ask - bid); - - // - return result; -} - -// -// Get Points ... -double GetPoints() -{ - return _Point; -} -double GetPoints( - string symbol // selected symbol for calculations -) -{ - // - double result = SymbolInfoDouble(symbol, SYMBOL_POINT); - - // - return result; -} - -// -// Get Digits ... -int GetDigits() -{ - return _Digits; -} -int GetDigits( - string symbol // selected symbol for calculations -) -{ - // - int result = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS); - - // - return result; -} - -// -// Get Signal Entry ... -double GetEntry( - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... -) -{ - // - double result = 0; - - // - // Validate Arg ... - if (type == X_SIGNAL_UNKNOWN) - { - return result; - } - - // - bool isLong = type == X_SIGNAL_LONG; - result = isLong ? GetAsk() : GetBid(); - result = NormalizePrice(result); - - // - return result; -} -double GetEntry( - string symbol, // Specified Symbol - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... -) -{ - // - double result = 0; - - // - // Validate Arg ... - if (type == X_SIGNAL_UNKNOWN) - { - return result; - } - - // - bool isLong = type == X_SIGNAL_LONG; - result = isLong ? GetAsk(symbol) : GetBid(symbol); - result = NormalizePrice(result, symbol); - - // - return result; -} - -// -// Get Signal Exit ... -double GetExit( - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... -) -{ - // - double result = 0; - - // - // Validate Arg ... - if (type == X_SIGNAL_UNKNOWN) - { - return result; - } - - // - bool isLong = type == X_SIGNAL_LONG; - result = isLong ? GetBid() : GetAsk(); - result = NormalizePrice(result); - - // - return result; -} -double GetExit( - string symbol, // Specified Symbol - ENUM_X_SIGNAL_TYPE type = X_SIGNAL_UNKNOWN // Get entry price for Which direction trade ... -) -{ - // - double result = 0; - - // - // Validate Arg ... - if (type == X_SIGNAL_UNKNOWN) - { - return result; - } - - // - bool isLong = type == X_SIGNAL_LONG; - result = isLong ? GetBid(symbol) : GetAsk(symbol); - result = NormalizePrice(result, symbol); - - // - return result; -} - -// -// Get 1 Pip in Price Value ... -double GetPipPrice() -{ - // - double result = _Point; - if (_Digits == 3 || _Digits == 5) - { - result *= 10; - } - - // - return result; -} -double GetPipPrice( - string symbol // selected symbol for calculations -) -{ - // - double symbolPoint = GetPoints(symbol); - int symbolDigits = GetDigits(symbol); - - // - double result = symbolPoint; - if (symbolDigits == 3 || symbolDigits == 5) - { - result *= 10; - } - - // - return result; -} - -// -// Converts Pips To Price ... -double PipsToPrice( - int pips // pips amount -) -{ - // - int digits = GetDigits(); - double pipValue = GetPipPrice(); - double result = pips * pipValue; - - // - result = NormalizeDouble(result, digits); - - // - return result; -} -double PipsToPrice( - double pips // pips amount -) -{ - // - int digits = GetDigits(); - double pipValue = GetPipPrice(); - double result = pips * pipValue; - - // - result = NormalizeDouble(result, digits); - - // - return result; -} -double PipsToPrice( - string symbol, // selected symbol for calculation - int pips // pips amount -) -{ - // - int digits = GetDigits(symbol); - double pipValue = GetPipPrice(symbol); - double result = pips * pipValue; - - // - result = NormalizeDouble(result, digits); - - // - return result; -} -double PipsToPrice( - string symbol, // selected symbol for calculation - double pips // pips amount -) -{ - // - int digits = GetDigits(symbol); - double pipValue = GetPipPrice(symbol); - double result = pips * pipValue; - - // - result = NormalizeDouble(result, digits); - - // - return result; -} - -// -// Converts Price to Pips ... -double PriceToPips( - double price // the price amount which required to calculate -) -{ - // - int digits = GetDigits(); - double pipPrice = GetPipPrice(); - - // - double result = price / pipPrice; - - // - result = NormalizeDouble(result, digits); - - // - return result; -} -double PriceToPips( - string symbol, // Selected Symbol - double price // the price amount which required to calculate -) -{ - // - int digits = GetDigits(symbol); - double pipPrice = GetPipPrice(symbol); - - // - double result = price / pipPrice; - - // - result = NormalizeDouble(result, digits); - - // - return result; -} - -// -// Get a Candle Body ... -double GetCandleBody( - XOHCL &candle // specified candle -) -{ - // - double result = MathAbs(candle.open - candle.close); - - // - return result; -} - -// -// Get a Candle Range ... -double GetCandleRange( - XOHCL &candle // specified candle -) -{ - // - double result = MathAbs(candle.high - candle.low); - - // - return result; -} - -// -// Get a Candle Shadow ... -double GetCandleShadow( - XOHCL &candle // specified candle -) -{ - // - double range = GetCandleRange(candle); - double body = GetCandleBody(candle); - - // - double result = MathAbs(range - body); - - // - return result; -} - -// -// Retrieve Applied Price at Specific Candle ... -double GetAppliedPrice( - XOHCL &candle, // specified candle - ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To -) -{ - // - double result = EMPTY_VALUE; - - // - switch (source) - { - // - // Open ... - case PRICE_OPEN: - result = candle.open; - break; - - // - // High ... - case PRICE_HIGH: - result = candle.high; - break; - - // - // Low ... - case PRICE_LOW: - result = candle.low; - break; - - // - // Median ((High + Low) / 2) ... - case PRICE_MEDIAN: - result = (candle.high + candle.low) / 2; - break; - - // - // Typical ((High + Low + Close)/3) ... - case PRICE_TYPICAL: - result = (candle.high + candle.low + candle.close) / 3; - break; - - // - // Weighted ((High + Low + Close + Close)/4) ... - case PRICE_WEIGHTED: - result = (candle.high + candle.low + (candle.close * 2)) / 4; - break; - - // - // Close ... - default: - case PRICE_CLOSE: - result = candle.close; - break; - } - - // - return result; -} -double GetAppliedPrice( - int bar_index, // specify candle index - ENUM_APPLIED_PRICE source = PRICE_CLOSE // specified Applied To -) -{ - // - double result = EMPTY_VALUE; - - // - XOHCL candle = GetCandle(bar_index); - result = GetAppliedPrice(candle, source); - - // - return result; -} -double GetAppliedPrice( - int bar_index, // specify candle index - ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... -) -{ - // - double result = 0; - - // - ENUM_APPLIED_PRICE mAppliedTo = To(mode); - result = GetAppliedPrice( - bar_index, - mAppliedTo); - - // - return result; -} - -// -// Converts ... -ENUM_APPLIED_PRICE To( - ENUM_SERIESMODE mode // converts Series Mode to Applied Price ... -) -{ - // - ENUM_APPLIED_PRICE result = PRICE_CLOSE; - - // - switch (mode) - { - // - // High ... - case MODE_HIGH: - result = PRICE_HIGH; - break; - - // - // Open ... - case MODE_OPEN: - result = PRICE_OPEN; - break; - - // - // Low ... - case MODE_LOW: - result = PRICE_LOW; - break; - - // - // Close ... - // Default ... - case MODE_CLOSE: - default: - result = PRICE_CLOSE; - break; - } - - // - return result; -} - -// -// Retrieve a Candel Data ... -XOHCL GetCandle(int bar_index) -{ - // - XOHCL result = {}; - - // - double open = iOpen(_Symbol, _Period, bar_index); - double high = iHigh(_Symbol, _Period, bar_index); - double close = iClose(_Symbol, _Period, bar_index); - double low = iLow(_Symbol, _Period, bar_index); - - // - result.low = low; - result.open = open; - result.high = high; - result.close = close; - - // - return result; -} -XOHCL GetCandle( - ENUM_TIMEFRAMES mPeriod, // specify timeframe - int bar_index // specify candle index -) -{ - // - XOHCL result = {}; - - // - double open = iOpen(_Symbol, mPeriod, bar_index); - double high = iHigh(_Symbol, mPeriod, bar_index); - double close = iClose(_Symbol, mPeriod, bar_index); - double low = iLow(_Symbol, mPeriod, bar_index); - - // - result.low = low; - result.open = open; - result.high = high; - result.close = close; - - // - return result; -} -XOHCL GetCandle( - string symbol, // specify symbol - ENUM_TIMEFRAMES mPeriod, // specify timeframe - int bar_index // specify candle index -) -{ - // - XOHCL result = {}; - - // - double open = iOpen(symbol, mPeriod, bar_index); - double high = iHigh(symbol, mPeriod, bar_index); - double close = iClose(symbol, mPeriod, bar_index); - double low = iLow(symbol, mPeriod, bar_index); - - // - result.low = low; - result.open = open; - result.high = high; - result.close = close; - - // - return result; -} - -// -// Retrieve a candle index in current timeframe inside another timeframe ... -int GetCandleBarIndex( - int bar_index, // Specify Candle index in current timeframe - ENUM_TIMEFRAMES destPeriod // Specify destination timeframe -) -{ - // - int result = -1; - - // - datetime barTime = iTime(_Symbol, _Period, bar_index); - result = iBarShift(_Symbol, destPeriod, barTime); - - // - return result; -} - -// -// Retrieve a symbol candle index in source time frame inside dest timeframe ... -int GetCandleBarIndex( - int bar_index, // Specify Candle index in current timeframe - string symbol, // Specify desired Symbol - ENUM_TIMEFRAMES sourcePeriod, // Specify bar_index timeframe - ENUM_TIMEFRAMES destPeriod // Specify destination timeframe -) -{ - // - int result = -1; - - // - datetime barTime = iTime(symbol, sourcePeriod, bar_index); - result = iBarShift(symbol, destPeriod, barTime); - - // - return result; -} - -// -// Check a Candle is Bullish or not ... -bool IsBullishCandle( - XOHCL &candle // specified candle -) -{ - // - bool result = false; - - // - result = candle.open < candle.close; - - // - return result; -} -bool IsBullishCandle( - int bar_index // candle index -) -{ - // - bool result = false; - - // - XOHCL candle = GetCandle(bar_index); - - // - result = IsBullishCandle(candle); - - // - return result; -} -bool IsBullishCandle( - string symbol, // specify symbol - ENUM_TIMEFRAMES mPeriod, // specify timeframe - int bar_index // candle index -) -{ - // - bool result = false; - - // - XOHCL candle = GetCandle( - symbol, - mPeriod, - bar_index); - - // - result = IsBullishCandle(candle); - - // - return result; -} - -// -// Check a Candle is Bullish or not ... -bool IsBearishCandle( - XOHCL &candle // specified candle -) -{ - // - bool result = false; - - // - result = candle.open > candle.close; - - // - return result; -} -bool IsBearishCandle( - int bar_index // candle index -) -{ - // - bool result = false; - - // - XOHCL candle = GetCandle(bar_index); - - // - result = IsBearishCandle(candle); - - // - return result; -} -bool IsBearishCandle( - string symbol, // specify symbol - ENUM_TIMEFRAMES mPeriod, // specify timeframe - int bar_index // candle index -) -{ - // - bool result = false; - - // - XOHCL candle = GetCandle( - symbol, - mPeriod, - bar_index); - - // - result = IsBearishCandle(candle); - - // - return result; -} - -// -// Check Candle Body Bigger Than it's Shadow ... -bool HasStrongBody(XOHCL &candle) -{ - // - double bodySize = MathAbs(candle.open - candle.close); - double shadowSize = MathAbs(candle.high - candle.low) - bodySize; - - // - bool result = bodySize > (shadowSize * 1.5); - - // - return result; -} - -// -// Determines a cnadle is Swing High -// or Swing Low order block ... -ENUM_X_SWING_TYPE GetCandleSwing(int bar_index) -{ - // - ENUM_X_SWING_TYPE result = X_NO_SWING; - - // - // Reading Candle Models ... - XOHCL candles[3]; - candles[0] = GetCandle(bar_index + 1); - candles[1] = GetCandle(bar_index + 2); - candles[2] = GetCandle(bar_index + 3); - - // - // Check Swing Start Candle has Strong Body ... - bool isStrongBodyCandle = HasStrongBody(candles[2]); - if (!isStrongBodyCandle) - { - return result; - } - - // - // Check Swing Low Conditions ... - bool isSwingLowOrderBlock = - candles[2].low < candles[1].low && - candles[1].low < candles[0].low && - candles[2].low < candles[0].low; - if (isSwingLowOrderBlock) - { - result = X_SWING_LOW; - } - - // - // Check Swing High Conditions ... - bool isSwingHighOrderBlock = - candles[2].high > candles[1].high && - candles[1].high > candles[0].high && - candles[2].high > candles[0].high; - if (isSwingHighOrderBlock) - { - result = X_SWING_HIGH; - } - - // - return result; -} -ENUM_X_SWING_TYPE GetCandleSwing( - ENUM_TIMEFRAMES mPeriod, // specify timeframe - int bar_index // specify candle index -) -{ - // - ENUM_X_SWING_TYPE result = X_NO_SWING; - - // - // Reading Candle Models ... - XOHCL candles[3]; - candles[0] = GetCandle(mPeriod, bar_index + 1); - candles[1] = GetCandle(mPeriod, bar_index + 2); - candles[2] = GetCandle(mPeriod, bar_index + 3); - - // - // Check Swing Start Candle has Strong Body ... - bool isStrongBodyCandle = HasStrongBody(candles[2]); - if (!isStrongBodyCandle) - { - return result; - } - - // - // Check Swing Low Conditions ... - bool isSwingLowOrderBlock = - candles[2].low < candles[1].low && - candles[1].low < candles[0].low && - candles[2].low < candles[0].low; - if (isSwingLowOrderBlock) - { - result = X_SWING_LOW; - } - - // - // Check Swing High Conditions ... - bool isSwingHighOrderBlock = - candles[2].high > candles[1].high && - candles[1].high > candles[0].high && - candles[2].high > candles[0].high; - if (isSwingHighOrderBlock) - { - result = X_SWING_HIGH; - } - - // - return result; -} -ENUM_X_SWING_TYPE GetCandleSwing( - string symbol, // specify symbol - ENUM_TIMEFRAMES mPeriod, // specify timeframe - int bar_index // specify candle index -) -{ - // - ENUM_X_SWING_TYPE result = X_NO_SWING; - - // - // Reading Candle Models ... - XOHCL candles[3]; - candles[0] = GetCandle(symbol, mPeriod, bar_index + 1); - candles[1] = GetCandle(symbol, mPeriod, bar_index + 2); - candles[2] = GetCandle(symbol, mPeriod, bar_index + 3); - - // - // Check Swing Start Candle has Strong Body ... - bool isStrongBodyCandle = HasStrongBody(candles[2]); - if (!isStrongBodyCandle) - { - return result; - } - - // - // Check Swing Low Conditions ... - bool isSwingLowOrderBlock = - candles[2].low < candles[1].low && - candles[1].low < candles[0].low && - candles[2].low < candles[0].low; - if (isSwingLowOrderBlock) - { - result = X_SWING_LOW; - } - - // - // Check Swing High Conditions ... - bool isSwingHighOrderBlock = - candles[2].high > candles[1].high && - candles[1].high > candles[0].high && - candles[2].high > candles[0].high; - if (isSwingHighOrderBlock) - { - result = X_SWING_HIGH; - } - - // - return result; -} - -// -// Retrieve Market Highest High ... -double GetHighestHigh( - int mLength, // Which market Length use - int bar_index // bar index -) -{ - // - double result = -1; - - // - int rIdx = iHighest( - _Symbol, - _Period, - MODE_HIGH, - mLength, - bar_index); - - // - result = iHigh( - _Symbol, - _Period, - rIdx); - - // - return result; -} -double GetHighestHigh( - int mLength, // Which market Length use - int bar_index, // bar index - ENUM_SERIESMODE mode // Calculation mode -) -{ - // - double result = -1; - - // - int rIdx = iHighest( - _Symbol, - _Period, - mode, - mLength, - bar_index); - - // - result = iHigh( - _Symbol, - _Period, - rIdx); - - // - return result; -} -double GetHighestHigh( - string symbol, // Specified Symbol - ENUM_TIMEFRAMES mPeriod, // Specified Period - int mLength, // Which market Length use - int bar_index // bar index -) -{ - // - double result = -1; - - // - int rIdx = iHighest( - symbol, - mPeriod, - MODE_HIGH, - mLength, - bar_index); - - // - result = iHigh( - symbol, - mPeriod, - rIdx); - - // - return result; -} -double GetHighestHigh( - string symbol, // Specified Symbol - ENUM_TIMEFRAMES mPeriod, // Specified Period - ENUM_SERIESMODE mode, // Calculation mode - int mLength, // Which market Length use - int bar_index // bar index -) -{ - // - double result = -1; - - // - int rIdx = iHighest( - symbol, - mPeriod, - mode, - mLength, - bar_index); - - // - result = iHigh( - symbol, - mPeriod, - rIdx); - - // - return result; -} - -// -// Retrieve Market Lowest Low ... -double GetLowestLow( - int mLength, // Which market Length use - int bar_index // bar index -) -{ - // - double result = -1; - - // - int rIdx = iLowest( - _Symbol, - _Period, - MODE_LOW, - mLength, - bar_index); - - // - result = iLow( - _Symbol, - _Period, - rIdx); - - // - return result; -} -double GetLowestLow( - int mLength, // Which market Length use - int bar_index, // bar index - ENUM_SERIESMODE mode // Calculation mode -) -{ - // - double result = -1; - - // - int rIdx = iLowest( - _Symbol, - _Period, - mode, - mLength, - bar_index); - - // - result = iLow( - _Symbol, - _Period, - rIdx); - - // - return result; -} -double GetLowestLow( - string symbol, // Specified Symbol - ENUM_TIMEFRAMES mPeriod, // Specified Period - int mLength, // Which market Length use - int bar_index // bar index -) -{ - // - double result = -1; - - // - int rIdx = iLowest( - symbol, - mPeriod, - MODE_LOW, - mLength, - bar_index); - - // - result = iLow( - symbol, - mPeriod, - rIdx); - - // - return result; -} -double GetLowestLow( - string symbol, // Specified Symbol - ENUM_TIMEFRAMES mPeriod, // Specified Period - ENUM_SERIESMODE mode, // Calculation mode - int mLength, // Which market Length use - int bar_index // bar index -) -{ - // - double result = -1; - - // - int rIdx = iLowest( - symbol, - mPeriod, - mode, - mLength, - bar_index); - - // - result = iLow( - symbol, - mPeriod, - rIdx); - - // - return result; -} - -// -// Calculate Fib Level ... -double GetFibonacciLevel( - double upPrice, - double downPrice, - double level, - int direction) -{ - // - double ling = upPrice - downPrice; - double pLevel = (ling / 100) * (level * 100); - - // - double result = direction > 0 ? upPrice - pLevel : downPrice + pLevel; - result = NormalizeDouble(result, _Digits); - - // - return result; -} - -// -// Check first Cross Over second at bar_index ... -bool IsCrossOver( - const double &first[], // the buffer which check crossing over second buffer - const double &second[], // first buffer checks based on this buffer - const int bar_index // check crosses in specific index -) -{ - // - bool result = false; - - // - ArraySetAsSeries(first, true); - ArraySetAsSeries(second, true); - - // - // Validate Args ... - if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) - { - return result; - } - - // - result = first[bar_index] > second[bar_index] && - !(first[bar_index + 1] > second[bar_index + 1]); - - // - return result; -} - -// -// Check first is Over second at bar_index ... -bool IsOver( - const double &first[], // the buffer which check over second buffer - const double &second[], // first buffer checks based on this buffer - const int bar_index // check crosses in specific index -) -{ - // - bool result = false; - - // - ArraySetAsSeries(first, true); - ArraySetAsSeries(second, true); - - // - // Validate Args ... - if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) - { - return result; - } - - // - result = first[bar_index] > second[bar_index] && - first[bar_index + 1] > second[bar_index + 1]; - - // - return result; -} - -// -// Check first Cross Under second at bar_index ... -bool IsCrossUnder( - const double &first[], // the buffer which check crossing under second buffer - const double &second[], // first buffer checks based on this buffer - const int bar_index // check crosses in specific index -) -{ - // - bool result = false; - - // - ArraySetAsSeries(first, true); - ArraySetAsSeries(second, true); - - // - // Validate Args ... - if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) - { - return result; - } - - // - result = first[bar_index] < second[bar_index] && - !(first[bar_index + 1] < second[bar_index + 1]); - - // - return result; -} - -// -// Check first is Under second at bar_index ... -bool IsUnder( - const double &first[], // the buffer which check under second buffer - const double &second[], // first buffer checks based on this buffer - const int bar_index // check crosses in specific index -) -{ - // - bool result = false; - - // - ArraySetAsSeries(first, true); - ArraySetAsSeries(second, true); - - // - // Validate Args ... - if (ArraySize(first) < bar_index + 1 || ArraySize(second) < bar_index + 1) - { - return result; - } - - // - result = first[bar_index] < second[bar_index] && - first[bar_index + 1] < second[bar_index + 1]; - - // - return result; -} - -// -// Calculate Slope of Specified Buffer at Specified Index ... -double GetSlope( - int from, // In Past Index ... - int to, // In Past Index ... - double &buffer[]) -{ - // - double result = 0; - - // - double toValue = buffer[to]; - double fromValue = buffer[from]; - double deltaValue = toValue - fromValue; - double deltaTime = from - to; - - // - result = deltaValue / deltaTime; - - // - return result; -} - -// -// Check if a Value Increasing in Loopback ... -bool IsIncreasing( - int from, // Last Time Index - int to, // Fisr Tima Index - double &buffer[] // the Buffer which required to search -) -{ - // - bool result = false; - - // - // Validate Args ... - if ( - from <= to || - ArraySize(buffer) < from + 1) - { - return result; - } - - // - // Loop through Items ... - double toValue = buffer[to]; - double fromValue = buffer[from]; - result = toValue > fromValue; - for (int i = to + 1; i <= from - 1; i++) - { - // - double iValue = buffer[i]; - bool isPassed = toValue >= iValue; - - // - bool isIIncreasing = IsIncreasing( - from, - i, - buffer); - - // - // Check Result ... - result = result && isPassed && isIIncreasing; - if (!result) - { - break; - } - } - - // - return result; -} - -// -// Check if a Value Decreasing in Loopback ... -bool IsDecreasing( - int from, // Last Time Index - int to, // Fisr Tima Index - double &buffer[] // the Buffer which required to search -) -{ - // - bool result = false; - - // - // Validate Args ... - if ( - from <= to || - ArraySize(buffer) < from + 1) - { - return result; - } - - // - // Loop through Items ... - double toValue = buffer[to]; - double fromValue = buffer[from]; - result = toValue < fromValue; - for (int i = to + 1; i <= from - 1; i++) - { - // - double iValue = buffer[i]; - bool isPassed = toValue <= iValue; - - // - bool isIDecreasing = IsDecreasing( - from, - i, - buffer); - - // - // Check Result ... - result = result && isPassed && isIDecreasing; - if (!result) - { - break; - } - } - - // - return result; -} - -// -// Get Max Value of Specific Loopback of a Buffer ... -double GetMaxValue( - int mLoopback, // loopback length - double &buffer[] // the Buffer which required to search -) -{ - // - double result = 0; - - // - // Validate Args ... - if ( - mLoopback < 2 || - ArraySize(buffer) < mLoopback) - { - return result; - } - - // - // Loop Through LoopBack ... - for (int i = 0; i < mLoopback; i++) - { - // - double iValue = buffer[i]; - - // - result = - // - result == 0 || result < iValue - // - ? iValue - // - : result - // - ; - } - - // - return result; -} - -// -// Get Min Value of Specific Loopback of a Buffer ... -double GetMinValue( - int mLoopback, // loopback length - double &buffer[] // the Buffer which required to search -) -{ - // - double result = 0; - - // - // Validate Args ... - if ( - mLoopback < 2 || - ArraySize(buffer) < mLoopback) - { - return result; - } - - // - // Loop Through LoopBack ... - for (int i = 0; i < mLoopback; i++) - { - // - double iValue = buffer[i]; - - // - result = - // - result == 0 || result > iValue - // - ? iValue - // - : result - // - ; - } - - // - return result; -} - -// -bool IsInPeak( - int mLoopback, // loopback length - double &buffer[] // the Buffer which required to search -) -{ - // - bool result = false; - - // - // Validate Args ... - if ( - mLoopback < 2 || - ArraySize(buffer) < mLoopback + 1) - { - return result; - } - - // - int q1Length = mLoopback / 4; - int halfLength = mLoopback / 2; - int q2Length = halfLength + q1Length; - - // - double firstValue = buffer[1]; - double q1Value = buffer[q1Length]; - double q2Value = buffer[q2Length]; - double halfValue = buffer[halfLength]; - double lastValue = buffer[ArraySize(buffer) - 1]; - - // - // Peak ... - result = - // - firstValue > lastValue - // - && - // - ( - firstValue > q1Value && - firstValue > halfValue) - // - ; - - // - return result; -} - -// -bool IsInVale( - int mLoopback, // loopback length - double &buffer[] // the Buffer which required to search -) -{ - // - bool result = false; - - // - // Validate Args ... - if ( - mLoopback < 2 || - ArraySize(buffer) < mLoopback + 1) - { - return result; - } - - // - int q1Length = mLoopback / 4; - int halfLength = mLoopback / 2; - int q2Length = halfLength + q1Length; - - // - double firstValue = buffer[1]; - double q1Value = buffer[q1Length]; - double q2Value = buffer[q2Length]; - double halfValue = buffer[halfLength]; - double lastValue = buffer[ArraySize(buffer) - 1]; - - // - // Peak ... - result = - // - firstValue < lastValue - // - && - // - ( - firstValue < q1Value && - firstValue < halfValue) - // - ; - - // - return result; -} - -// -// Check Sharp Happens or not ... -bool IsSharpChanged( - double fromValue, // Past Value - double toValue, // Present Value - double maxValue, // Max in Range Value - double minValue // Min in Range Value -) -{ - // - bool result = false; - - // - // This Used In Increased or Decreased Sharp Detection ... - bool isIncreased = toValue > fromValue; - - // - double toFromDelta = MathAbs(toValue - fromValue); - double minMaxDelta = maxValue - minValue; - - // - result = toFromDelta >= (minMaxDelta / 3); - - // - return result; -} -bool IsSharpChanged( - int from, // Past Index in Series - int to, // Present Index in Series - double &buffer[] // the Buffer which required to search -) -{ - // - bool result = false; - - // - // Validate Args ... - if ( - from <= to || - ArraySize(buffer) < from + 1) - { - return result; - } - - // - // Loop through Items ... - double toValue = buffer[to]; - double fromValue = buffer[from]; - - // - // This Used In Increased or Decreased Sharp Detection ... - bool isIncreased = toValue > fromValue; - - // - double minValue = GetMinValue( - ArraySize(buffer) - 1, - buffer); - double maxValue = GetMaxValue( - ArraySize(buffer) - 1, - buffer); - double minMaxDelta = maxValue - minValue; - - // - // Sharp Detection ... - result = IsSharpChanged( - fromValue, - toValue, - maxValue, - minValue); - - // - return result; -} -bool IsSharpChanged( - int from, // Past Bar Index - int to, // Present Bar Index - ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To -) -{ - // - bool result = false; - - // - double toValue = GetAppliedPrice( - to, - appliedPrice); - double fromValue = GetAppliedPrice( - from, - appliedPrice); - - // - int hIdx = iHighest( - _Symbol, - _Period, - MODE_HIGH, - from, - to); - double maxValue = iHigh( - _Symbol, - _Period, - hIdx); - - // - int lIdx = iLowest( - _Symbol, - _Period, - MODE_LOW, - from, - to); - double minValue = iLow( - _Symbol, - _Period, - lIdx); - - // - result = IsSharpChanged( - fromValue, - toValue, - maxValue, - minValue); - - // - return result; -} - -// -// Check InCreased Sharp Happens or not ... -bool IsSharpIncreasedChanged( - double fromValue, // Past Value - double toValue, // Present Value - double maxValue, // Max in Range Value - double minValue // Min in Range Value -) -{ - // - bool result = false; - - // - // This Used In Increased or Decreased Sharp Detection ... - bool isIncreased = toValue > fromValue; - - // - double toFromDelta = MathAbs(toValue - fromValue); - double minMaxDelta = maxValue - minValue; - - // - result = - isIncreased && - toFromDelta >= (minMaxDelta / 3); - - // - return result; -} -bool IsSharpIncreasedChanged( - int from, // Past Index in Series - int to, // Present Index in Series - double &buffer[] // the Buffer which required to search -) -{ - // - bool result = false; - - // - // Validate Args ... - if ( - from <= to || - ArraySize(buffer) < from + 1) - { - return result; - } - - // - // Loop through Items ... - double toValue = buffer[to]; - double fromValue = buffer[from]; - - // - double minValue = GetMinValue( - ArraySize(buffer) - 1, - buffer); - double maxValue = GetMaxValue( - ArraySize(buffer) - 1, - buffer); - double minMaxDelta = maxValue - minValue; - - // - // Sharp Detection ... - result = IsSharpIncreasedChanged( - fromValue, - toValue, - maxValue, - minValue); - - // - return result; -} -bool IsSharpIncreasedChanged( - int from, // Past Bar Index - int to, // Present Bar Index - ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To -) -{ - // - bool result = false; - - // - double toValue = GetAppliedPrice( - to, - appliedPrice); - double fromValue = GetAppliedPrice( - from, - appliedPrice); - - // - int hIdx = iHighest( - _Symbol, - _Period, - MODE_HIGH, - from, - to); - double maxValue = iHigh( - _Symbol, - _Period, - hIdx); - - // - int lIdx = iLowest( - _Symbol, - _Period, - MODE_LOW, - from, - to); - double minValue = iLow( - _Symbol, - _Period, - lIdx); - - // - result = IsSharpIncreasedChanged( - fromValue, - toValue, - maxValue, - minValue); - - // - return result; -} - -// -// Check Decreased Sharp Happens or not ... -bool IsSharpDecreasedChanged( - double fromValue, // Past Value - double toValue, // Present Value - double maxValue, // Max in Range Value - double minValue // Min in Range Value -) -{ - // - bool result = false; - - // - // This Used In Increased or Decreased Sharp Detection ... - bool isIncreased = toValue > fromValue; - - // - double toFromDelta = MathAbs(toValue - fromValue); - double minMaxDelta = maxValue - minValue; - - // - result = - !isIncreased && - toFromDelta >= (minMaxDelta / 3); - - // - return result; -} -bool IsSharpDecreasedChanged( - int from, // Past Index in Series - int to, // Present Index in Series - double &buffer[] // the Buffer which required to search -) -{ - // - bool result = false; - - // - // Validate Args ... - if ( - from <= to || - ArraySize(buffer) < from + 1) - { - return result; - } - - // - // Loop through Items ... - double toValue = buffer[to]; - double fromValue = buffer[from]; - - // - double minValue = GetMinValue( - ArraySize(buffer) - 1, - buffer); - double maxValue = GetMaxValue( - ArraySize(buffer) - 1, - buffer); - double minMaxDelta = maxValue - minValue; - - // - // Sharp Detection ... - result = IsSharpDecreasedChanged( - fromValue, - toValue, - maxValue, - minValue); - - // - return result; -} -bool IsSharpDecreasedChanged( - int from, // Past Bar Index - int to, // Present Bar Index - ENUM_APPLIED_PRICE appliedPrice // Which Price Choose in From or To -) -{ - // - bool result = false; - - // - double toValue = GetAppliedPrice( - to, - appliedPrice); - double fromValue = GetAppliedPrice( - from, - appliedPrice); - - // - int hIdx = iHighest( - _Symbol, - _Period, - MODE_HIGH, - from, - to); - double maxValue = iHigh( - _Symbol, - _Period, - hIdx); - - // - int lIdx = iLowest( - _Symbol, - _Period, - MODE_LOW, - from, - to); - double minValue = iLow( - _Symbol, - _Period, - lIdx); - - // - result = IsSharpDecreasedChanged( - fromValue, - toValue, - maxValue, - minValue); - - // - return result; -} - -// -// Validate Struct ... -bool IsValid(XSignal &model, ulong magicNumber) -{ - // - bool result = false; - - // - // Validate Signal Type ... - result = model.type != X_SIGNAL_UNKNOWN; - if (!result) - { - return result; - } - - // - // Check Symbol ... - result = StringLen(model.symbol) == 0 ? true : model.symbol == _Symbol; - if (!result) - { - return result; - } - - // - // Check magic number ... - result = model.magicNumber <= 0 ? true : model.magicNumber == magicNumber; - if (!result) - { - return result; - } - - // - // Check Entry ... - result = model.entry > 0; - if (!result) - { - return result; - } - - // - // Check SL ... - result = model.sl == 0 ? true : model.type == X_SIGNAL_LONG ? model.sl < model.entry - : model.sl > model.entry; - if (!result) - { - return result; - } - - // - // Check TP ... - result = model.tp == 0 ? true : model.type == X_SIGNAL_LONG ? model.tp > model.entry - : model.tp < model.entry; - if (!result) - { - return result; - } - - // - // Check Volume ... - result = model.volume > 0; - if (!result) - { - return result; - } - - // - // Check Time ... - result = model.time > 0; - if (!result) - { - return result; - } - - // - return result; -} - -// -void CleanBuffer(int &buffer[]) -{ - // - ArrayFree(buffer); - ArrayResize(buffer, 0); -} -void CleanBuffer(ulong &buffer[]) -{ - // - ArrayFree(buffer); - ArrayResize(buffer, 0); -} -void CleanBuffer(double &buffer[]) -{ - // - ArrayFree(buffer); - ArrayResize(buffer, 0); -} -void CleanBuffer(XSignal &buffer[]) -{ - // - ArrayFree(buffer); - ArrayResize(buffer, 0); -} -void CleanBuffer(XDeal &buffer[]) -{ - // - ArrayFree(buffer); - ArrayResize(buffer, 0); -} -void CleanBuffer(XOrder &buffer[]) -{ - // - ArrayFree(buffer); - ArrayResize(buffer, 0); -} - -// -bool GetLastItem( - double &item, // Holds Result - double &buffer[] // Specified Buffer -) -{ - // - bool result = false; - - // - int bufferSize = ArraySize(buffer); - if (bufferSize <= 0) - { - return result; - } - - // - item = buffer[bufferSize - 1]; - - // - result = true; - return result; -} -bool GetLastItem( - datetime &item, // Holds Result - datetime &buffer[] // Specified Buffer -) -{ - // - bool result = false; - - // - int bufferSize = ArraySize(buffer); - if (bufferSize <= 0) - { - return result; - } - - // - item = buffer[bufferSize - 1]; - - // - result = true; - return result; -} - -// -void Add( - int item, // item want to add - int &buffer[] // Destination buffer -) -{ - // - ArrayResize( - buffer, - ArraySize(buffer) + 1); - - // - buffer[ArraySize(buffer) - 1] = item; -} -void Add( - ulong item, // item want to add - ulong &buffer[] // Destination buffer -) -{ - // - ArrayResize( - buffer, - ArraySize(buffer) + 1); - - // - buffer[ArraySize(buffer) - 1] = item; -} -void Add( - string item, // item want to add - string &buffer[] // Destination buffer -) -{ - // - ArrayResize( - buffer, - ArraySize(buffer) + 1); - - // - buffer[ArraySize(buffer) - 1] = item; -} -void Add( - double item, // item want to add - double &buffer[] // Destination buffer -) -{ - // - ArrayResize( - buffer, - ArraySize(buffer) + 1); - - // - buffer[ArraySize(buffer) - 1] = item; -} -void Add( - XOHCL &item, // item want to add - XOHCL &buffer[] // Destination buffer -) -{ - // - ArrayResize( - buffer, - ArraySize(buffer) + 1); - - // - buffer[ArraySize(buffer) - 1] = item; -} -void Add( - datetime &item, // item want to add - datetime &buffer[] // Destination buffer -) -{ - // - ArrayResize( - buffer, - ArraySize(buffer) + 1); - - // - buffer[ArraySize(buffer) - 1] = item; -} -void Add( - XSignal &item, // item want to add - XSignal &buffer[] // Destination buffer -) -{ - // - ArrayResize( - buffer, - ArraySize(buffer) + 1); - - // - buffer[ArraySize(buffer) - 1] = item; -} -void Add( - XDeal &item, // item want to add - XDeal &buffer[] // Destination buffer -) -{ - // - ArrayResize( - buffer, - ArraySize(buffer) + 1); - - // - buffer[ArraySize(buffer) - 1] = item; -} -void Add( - XOrder &item, // item want to add - XOrder &buffer[] // Destination buffer -) -{ - // - ArrayResize( - buffer, - ArraySize(buffer) + 1); - - // - buffer[ArraySize(buffer) - 1] = item; -} - -// -// Converts a Buffer to String Representation ... -string ToString( - const int &buffer[], // Specified Buffer - string separator = ",", // Specified Separator - bool addIndex = false, // Specified Add Items Indexes or Not - string indexLabel = "i:", // Specified Index Label - string indexSeparator = ">" // Specified Index Separator - -) -{ - // - string result = ""; - - // - int bufferSize = ArraySize(buffer); - if (bufferSize <= 0) - { - return result; - } - - // - for (int i = 0; i < bufferSize; i++) - { - // - if (addIndex) - { - // - if (StringLen(indexLabel) > 0) - { - result += indexLabel + " "; - } - - // - result += (string)i + " "; - - // - if (StringLen(indexSeparator) > 0) - { - result += indexSeparator + " "; - } - } - - // - string iItemString = (string)buffer[i]; - - // - result += iItemString; - - // - if (i < bufferSize - 1) - { - result += separator; - } - } - - // - return result; -} -string ToString( - const double &buffer[], // Specified Buffer - string separator = ",", // Specified Separator - bool addIndex = false, // Specified Add Items Indexes or Not - string indexLabel = "i:", // Specified Index Label - string indexSeparator = ">" // Specified Index Separator - -) -{ - // - string result = ""; - - // - int bufferSize = ArraySize(buffer); - if (bufferSize <= 0) - { - return result; - } - - // - for (int i = 0; i < bufferSize; i++) - { - // - if (addIndex) - { - // - if (StringLen(indexLabel) > 0) - { - result += indexLabel + " "; - } - - // - result += (string)i + " "; - - // - if (StringLen(indexSeparator) > 0) - { - result += indexSeparator + " "; - } - } - - // - string iItemString = (string)buffer[i]; - - // - result += iItemString; - - // - if (i < bufferSize - 1) - { - result += separator; - } - } - - // - return result; -} -string ToString( - const string &buffer[], // Specified Buffer - string separator = ",", // Specified Separator - bool addIndex = false, // Specified Add Items Indexes or Not - string indexLabel = "i:", // Specified Index Label - string indexSeparator = ">" // Specified Index Separator - -) -{ - // - string result = ""; - - // - int bufferSize = ArraySize(buffer); - if (bufferSize <= 0) - { - return result; - } - - // - for (int i = 0; i < bufferSize; i++) - { - // - if (addIndex) - { - // - if (StringLen(indexLabel) > 0) - { - result += indexLabel + " "; - } - - // - result += (string)i + " "; - - // - if (StringLen(indexSeparator) > 0) - { - result += indexSeparator + " "; - } - } - - // - string iItemString = (string)buffer[i]; - - // - result += iItemString; - - // - if (i < bufferSize - 1) - { - result += separator; - } - } - - // - return result; -} -string ToString( - const datetime &buffer[], // Specified Buffer - string separator = ",", // Specified Separator - bool addIndex = false, // Specified Add Items Indexes or Not - string indexLabel = "i:", // Specified Index Label - string indexSeparator = ">" // Specified Index Separator - -) -{ - // - string result = ""; - - // - int bufferSize = ArraySize(buffer); - if (bufferSize <= 0) - { - return result; - } - - // - for (int i = 0; i < bufferSize; i++) - { - // - if (addIndex) - { - // - if (StringLen(indexLabel) > 0) - { - result += indexLabel + " "; - } - - // - result += (string)i + " "; - - // - if (StringLen(indexSeparator) > 0) - { - result += indexSeparator + " "; - } - } - - // - string iItemString = (string)buffer[i]; - - // - result += iItemString; - - // - if (i < bufferSize - 1) - { - result += separator; - } - } - - // - return result; -} - -// -// Check a Signal is Long or not ... -bool IsLong(ENUM_X_SIGNAL_TYPE type) -{ - return type == X_SIGNAL_LONG; -} -bool IsLong(XSignal &signal) -{ - // - bool result = IsLong(signal.type); - - // - return result; -} - -// -// Check a Signal is Short or not ... -bool IsShort(ENUM_X_SIGNAL_TYPE type) -{ - return type == X_SIGNAL_SHORT; -} -bool IsShort(XSignal &signal) -{ - // - bool result = IsShort(signal.type); - - // - return result; -} - -// -// Retrieve a Signal Type String Value ... -string GetSignalType(ENUM_X_SIGNAL_TYPE type) -{ - // - string result = ""; - - // - if (type == X_SIGNAL_UNKNOWN) - { - return result; - } - - // - result = type == X_SIGNAL_LONG ? "Long" : "Short"; - - // - return result; -} -string GetSignalType(XSignal &signal) -{ - // - string result = ""; - - // - result = GetSignalType(signal.type); - - // - return result; -} -ENUM_X_SIGNAL_TYPE GetSignalType(string typeStr) -{ - // - ENUM_X_SIGNAL_TYPE result = X_SIGNAL_UNKNOWN; - - // - if (typeStr == GetSignalType(X_SIGNAL_LONG)) - { - result = X_SIGNAL_LONG; - } - else if (typeStr == GetSignalType(X_SIGNAL_SHORT)) - { - result = X_SIGNAL_SHORT; - } - - // - return result; -} - -// -// Retrieve Signal Execution String ... -string GetSignalExecutionError(int error) -{ - // - string result = ""; - - // - switch (error) - { - // - case X_TRADER_INVALID_SIGNAL_ERROR: - result = "Invalid Signal ..."; - break; - - // - case X_TRADER_NOT_ENOUGH_EQUITY_ERROR: - result = "Not Enough Equity for Trade ..."; - break; - - // - case X_TRADER_NOT_ENOUGH_BALANCE_ERROR: - result = "Not Enough Balance for Trade ..."; - break; - - // - case X_TRADER_NOT_ENOUGH_MARIGIN_ERROR: - result = "Not Enough Marigin For Trade ..."; - break; - - // - case X_TRADER_MAX_TRADES_REACHED_ERROR: - result = "Max Allowed Trade Reached ..."; - break; - - // - case X_TRADER_UNKNOWN_ERROR: - default: - result = "Unknown Issue ..."; - break; - } - - // - return result; -} - -// -// Extract Data from String ... -string ExtractString( - const string source, // Source String used for Extracting - const string startString, // Expression Start String must be Unique - const string endString // Where to End Extraction, usually a Sign -) -{ - // - string result = ""; - - // - // Validate String ... - if ( - StringLen(source) == 0 || - StringLen(endString) == 0 || - StringLen(startString) == 0) - { - return result; - } - - // - // Find Start String Position ... - int sPos = StringFind( - source, - startString); - if (sPos < 0) - { - return result; - } - - // - // Find End String Position after Start String ... - int searchEndFromPos = sPos + StringLen(startString); - int ePos = StringFind( - source, - endString, - searchEndFromPos); - if (ePos < 0) - { - return result; - } - - // - // Extract Data from Source ... - int dLength = ePos - searchEndFromPos; - result = StringSubstr( - source, - searchEndFromPos, - dLength); - - // - return result; -} - -// -// Normalize a give Volume ... -double NormalizeVolume( - double volume, // desired volume to normalize - string symbol = NULL, // Specified Symbol for Normalization - int mLength = 2 // Length of Digits -) -{ - // - double result = volume; - - // - // Normalize Symbol ... - if (StringLen(symbol) == 0) - { - symbol = _Symbol; - } - - // - // Normalize Digits ... - int digits = GetDigits(symbol); - mLength = - mLength == 0 || mLength > digits - ? digits - : MathMin(mLength, digits); - - // - // Normalize Volume ... - result = NormalizeDouble(result, mLength); - - // - double maxAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX); - double minAvailableVolume = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN); - - // - // Validate Result ... - if (result > maxAvailableVolume) - { - result = maxAvailableVolume; - } - else if (result < minAvailableVolume) - { - result = minAvailableVolume; - } - - // - return result; -} - -// -// Normallize Price ... -double NormalizePrice( - double price, // desired Price for normalization - string symbol = NULL // Specified Symbol for Normalization -) -{ - // - double result = 0; - - // - // Mormalize Symbol ... - if (StringLen(symbol) == 0) - { - symbol = _Symbol; - } - - // - int digits = GetDigits(symbol); - result = NormalizeDouble(price, digits); - - // - return result; -} - -// -// Error Descriptions Functions ... -// - -// -// Retrieve Specified Error Code Description ... -string GetErrorDescription(int err_code) -{ - // - string result = ""; - - // - switch (err_code) - { - // - //--- Constant Description - - // - case ERR_SUCCESS: - result = "The operation completed successfully"; - break; - - // - case ERR_INTERNAL_ERROR: - result = "Unexpected internal error"; - break; - - // - case ERR_WRONG_INTERNAL_PARAMETER: - result = "Wrong parameter in the inner call of the client terminal function"; - break; - - // - case ERR_INVALID_PARAMETER: - result = "Wrong parameter when calling the system function"; - break; - - // - case ERR_NOT_ENOUGH_MEMORY: - result = "Not enough memory to perform the system function"; - break; - - // - case ERR_STRUCT_WITHOBJECTS_ORCLASS: - result = "The structure contains objects of strings and/or dynamic arrays and/or structure of such objects and/or classes"; - break; - - // - case ERR_INVALID_ARRAY: - result = "Array of a wrong type, wrong size, or a damaged object of a dynamic array"; - break; - - // - case ERR_ARRAY_RESIZE_ERROR: - result = "Not enough memory for the relocation of an array, or an attempt to change the size of a static array"; - break; - - // - case ERR_STRING_RESIZE_ERROR: - result = "Not enough memory for the relocation of string"; - break; - - // - case ERR_NOTINITIALIZED_STRING: - result = "Not initialized string"; - break; - - // - case ERR_INVALID_DATETIME: - result = "Invalid date and/or time"; - break; - - // - case ERR_ARRAY_BAD_SIZE: - result = "Requested array size exceeds 2 GB"; - break; - - // - case ERR_INVALID_POINTER: - result = "Wrong pointer"; - break; - - // - case ERR_INVALID_POINTER_TYPE: - result = "Wrong type of pointer"; - break; - - // - case ERR_FUNCTION_NOT_ALLOWED: - result = "System function is not allowed to call"; - break; - - // - //--- Charts - - // - case ERR_CHART_WRONG_ID: - result = "Wrong chart ID"; - break; - - // - case ERR_CHART_NO_REPLY: - result = "Chart does not respond"; - break; - - // - case ERR_CHART_NOT_FOUND: - result = "Chart not found"; - break; - - // - case ERR_CHART_NO_EXPERT: - result = "No Expert Advisor in the chart that could handle the event"; - break; - - // - case ERR_CHART_CANNOT_OPEN: - result = "Chart opening error"; - break; - - // - case ERR_CHART_CANNOT_CHANGE: - result = "Failed to change chart symbol and period"; - break; - - // - case ERR_CHART_CANNOT_CREATE_TIMER: - result = "Failed to create timer"; - break; - - // - case ERR_CHART_WRONG_PROPERTY: - result = "Wrong chart property ID"; - break; - - // - case ERR_CHART_SCREENSHOT_FAILED: - result = "Error creating screenshots"; - break; - - // - case ERR_CHART_NAVIGATE_FAILED: - result = "Error navigating through chart"; - break; - - // - case ERR_CHART_TEMPLATE_FAILED: - result = "Error applying template"; - break; - - // - case ERR_CHART_WINDOW_NOT_FOUND: - result = "Subwindow containing the indicator was not found"; - break; - - // - case ERR_CHART_INDICATOR_CANNOT_ADD: - result = "Error adding an indicator to chart"; - break; - - // - case ERR_CHART_INDICATOR_CANNOT_DEL: - result = "Error deleting an indicator from the chart"; - break; - - // - case ERR_CHART_INDICATOR_NOT_FOUND: - result = "Indicator not found on the specified chart"; - break; - - // - //--- Graphical Objects - case ERR_OBJECT_ERROR: - result = "Error working with a graphical object"; - break; - - // - case ERR_OBJECT_NOT_FOUND: - result = "Graphical object was not found"; - break; - - // - case ERR_OBJECT_WRONG_PROPERTY: - result = "Wrong ID of a graphical object property"; - break; - - // - case ERR_OBJECT_GETDATE_FAILED: - result = "Unable to get date corresponding to the value"; - break; - - // - case ERR_OBJECT_GETVALUE_FAILED: - result = "Unable to get value corresponding to the date"; - break; - - // - //--- MarketInfo - - // - case ERR_MARKET_UNKNOWN_SYMBOL: - result = "Unknown symbol"; - break; - - // - case ERR_MARKET_NOT_SELECTED: - result = "Symbol is not selected in MarketWatch"; - break; - - // - case ERR_MARKET_WRONG_PROPERTY: - result = "Wrong identifier of a symbol property"; - break; - - // - case ERR_MARKET_LASTTIME_UNKNOWN: - result = "Time of the last tick is not known (no ticks)"; - break; - - // - case ERR_MARKET_SELECT_ERROR: - result = "Error adding or deleting a symbol in MarketWatch"; - break; - - // - //--- History Access - - // - case ERR_HISTORY_NOT_FOUND: - result = "Requested history not found"; - break; - - // - case ERR_HISTORY_WRONG_PROPERTY: - result = "Wrong ID of the history property"; - break; - - // - //--- Global_Variables - - // - case ERR_GLOBALVARIABLE_NOT_FOUND: - result = "Global variable of the client terminal is not found"; - break; - - // - case ERR_GLOBALVARIABLE_EXISTS: - result = "Global variable of the client terminal with the same name already exists"; - break; - - // - case ERR_MAIL_SEND_FAILED: - result = "Email sending failed"; - break; - - // - case ERR_PLAY_SOUND_FAILED: - result = "Sound playing failed"; - break; - - // - case ERR_MQL5_WRONG_PROPERTY: - result = "Wrong identifier of the program property"; - break; - - // - case ERR_TERMINAL_WRONG_PROPERTY: - result = "Wrong identifier of the terminal property"; - break; - - // - case ERR_FTP_SEND_FAILED: - result = "File sending via ftp failed"; - break; - - // - case ERR_NOTIFICATION_SEND_FAILED: - result = "Error in sending notification"; - break; - - // - //--- Custom Indicator Buffers - - // - case ERR_BUFFERS_NO_MEMORY: - result = "Not enough memory for the distribution of indicator buffers"; - break; - - // - case ERR_BUFFERS_WRONG_INDEX: - result = "Wrong indicator buffer index"; - break; - - // - //--- Custom Indicator Properties - - // - case ERR_CUSTOM_WRONG_PROPERTY: - result = "Wrong ID of the custom indicator property"; - break; - - // - //--- Account - - // - case ERR_ACCOUNT_WRONG_PROPERTY: - result = "Wrong account property ID"; - break; - - // - case ERR_TRADE_WRONG_PROPERTY: - result = "Wrong trade property ID"; - break; - - // - case ERR_TRADE_DISABLED: - result = "Trading by Expert Advisors prohibited"; - break; - - // - case ERR_TRADE_POSITION_NOT_FOUND: - result = "Position not found"; - break; - - // - case ERR_TRADE_ORDER_NOT_FOUND: - result = "Order not found"; - break; - - // - case ERR_TRADE_DEAL_NOT_FOUND: - result = "Deal not found"; - break; - - // - case ERR_TRADE_SEND_FAILED: - result = "Trade request sending failed"; - break; - - // - //--- Indicators - - // - case ERR_INDICATOR_UNKNOWN_SYMBOL: - result = "Unknown symbol"; - break; - - // - case ERR_INDICATOR_CANNOT_CREATE: - result = "Indicator cannot be created"; - break; - - // - case ERR_INDICATOR_NO_MEMORY: - result = "Not enough memory to add the indicator"; - break; - - // - case ERR_INDICATOR_CANNOT_APPLY: - result = "The indicator cannot be applied to another indicator"; - break; - - // - case ERR_INDICATOR_CANNOT_ADD: - result = "Error applying an indicator to chart"; - break; - - // - case ERR_INDICATOR_DATA_NOT_FOUND: - result = "Requested data not found"; - break; - - // - case ERR_INDICATOR_WRONG_HANDLE: - result = "Wrong indicator handle"; - break; - - // - case ERR_INDICATOR_WRONG_PARAMETERS: - result = "Wrong number of parameters when creating an indicator"; - break; - - // - case ERR_INDICATOR_PARAMETERS_MISSING: - result = "No parameters when creating an indicator"; - break; - - // - case ERR_INDICATOR_CUSTOM_NAME: - result = "The first parameter in the array must be the name of the custom indicator"; - break; - - // - case ERR_INDICATOR_PARAMETER_TYPE: - result = "Invalid parameter type in the array when creating an indicator"; - break; - - // - case ERR_INDICATOR_WRONG_INDEX: - result = "Wrong index of the requested indicator buffer"; - break; - - // - //--- Depth of Market - - // - case ERR_BOOKS_CANNOT_ADD: - result = "Depth Of Market can not be added"; - break; - - // - case ERR_BOOKS_CANNOT_DELETE: - result = "Depth Of Market can not be removed"; - break; - - // - case ERR_BOOKS_CANNOT_GET: - result = "The data from Depth Of Market can not be obtained"; - break; - - // - case ERR_BOOKS_CANNOT_SUBSCRIBE: - result = "Error in subscribing to receive new data from Depth Of Market"; - break; - - // - //--- File Operations - - // - case ERR_TOO_MANY_FILES: - result = "More than 64 files cannot be opened at the same time"; - break; - - // - case ERR_WRONG_FILENAME: - result = "Invalid file name"; - break; - - // - case ERR_TOO_LONG_FILENAME: - result = "Too long file name"; - break; - - // - case ERR_CANNOT_OPEN_FILE: - result = "File opening error"; - break; - - // - case ERR_FILE_CACHEBUFFER_ERROR: - result = "Not enough memory for cache to read"; - break; - - // - case ERR_CANNOT_DELETE_FILE: - result = "File deleting error"; - break; - - // - case ERR_INVALID_FILEHANDLE: - result = "A file with this handle was closed, or was not opening at all"; - break; - - // - case ERR_WRONG_FILEHANDLE: - result = "Wrong file handle"; - break; - - // - case ERR_FILE_NOTTOWRITE: - result = "The file must be opened for writing"; - break; - - // - case ERR_FILE_NOTTOREAD: - result = "The file must be opened for reading"; - break; - - // - case ERR_FILE_NOTBIN: - result = "The file must be opened as a binary one"; - break; - - // - case ERR_FILE_NOTTXT: - result = "The file must be opened as a text"; - break; - - // - case ERR_FILE_NOTTXTORCSV: - result = "The file must be opened as a text or CSV"; - break; - - // - case ERR_FILE_NOTCSV: - result = "The file must be opened as CSV"; - break; - - // - case ERR_FILE_READERROR: - result = "File reading error"; - break; - - // - case ERR_FILE_BINSTRINGSIZE: - result = "String size must be specified, because the file is opened as binary"; - break; - - // - case ERR_INCOMPATIBLE_FILE: - result = "A text file must be for string arrays, for other arrays - binary"; - break; - - // - case ERR_FILE_IS_DIRECTORY: - result = "This is not a file, this is a directory"; - break; - - // - case ERR_FILE_NOT_EXIST: - result = "File does not exist"; - break; - - // - case ERR_FILE_CANNOT_REWRITE: - result = "File can not be rewritten"; - break; - - // - case ERR_WRONG_DIRECTORYNAME: - result = "Wrong directory name"; - break; - - // - case ERR_DIRECTORY_NOT_EXIST: - result = "Directory does not exist"; - break; - - // - case ERR_FILE_ISNOT_DIRECTORY: - result = "This is a file, not a directory"; - break; - - // - case ERR_CANNOT_DELETE_DIRECTORY: - result = "The directory cannot be removed"; - break; - - // - case ERR_CANNOT_CLEAN_DIRECTORY: - result = "Failed to clear the directory (probably one or more files are blocked and removal operation failed)"; - break; - - // - case ERR_FILE_WRITEERROR: - result = "Failed to write a resource to a file"; - break; - - // - //--- String Casting - - // - case ERR_NO_STRING_DATE: - result = "No date in the string"; - break; - - // - case ERR_WRONG_STRING_DATE: - result = "Wrong date in the string"; - break; - - // - case ERR_WRONG_STRING_TIME: - result = "Wrong time in the string"; - break; - - // - case ERR_STRING_TIME_ERROR: - result = "Error converting string to date"; - break; - - // - case ERR_STRING_OUT_OF_MEMORY: - result = "Not enough memory for the string"; - break; - - // - case ERR_STRING_SMALL_LEN: - result = "The string length is less than expected"; - break; - - // - case ERR_STRING_TOO_BIGNUMBER: - result = "Too large number, more than ULONG_MAX"; - break; - - // - case ERR_WRONG_FORMATSTRING: - result = "Invalid format string"; - break; - - // - case ERR_TOO_MANY_FORMATTERS: - result = "Amount of format specifiers more than the parameters"; - break; - - // - case ERR_TOO_MANY_PARAMETERS: - result = "Amount of parameters more than the format specifiers"; - break; - - // - case ERR_WRONG_STRING_PARAMETER: - result = "Damaged parameter of string type"; - break; - - // - case ERR_STRINGPOS_OUTOFRANGE: - result = "Position outside the string"; - break; - - // - case ERR_STRING_ZEROADDED: - result = "0 added to the string end, a useless operation"; - break; - - // - case ERR_STRING_UNKNOWNTYPE: - result = "Unknown data type when converting to a string"; - break; - - // - case ERR_WRONG_STRING_OBJECT: - result = "Damaged string object"; - break; - - // - //--- Operations with Arrays - - // - case ERR_INCOMPATIBLE_ARRAYS: - result = "Copying incompatible arrays. String array can be copied only to a string array, and a numeric array - in numeric array only"; - break; - - // - case ERR_SMALL_ASSERIES_ARRAY: - result = "The receiving array is declared as AS_SERIES, and it is of insufficient size"; - break; - - // - case ERR_SMALL_ARRAY: - result = "Too small array, the starting position is outside the array"; - break; - - // - case ERR_ZEROSIZE_ARRAY: - result = "An array of zero length"; - break; - - // - case ERR_NUMBER_ARRAYS_ONLY: - result = "Must be a numeric array"; - break; - - // - case ERR_ONEDIM_ARRAYS_ONLY: - result = "Must be a one-dimensional array"; - break; - - // - case ERR_SERIES_ARRAY: - result = "Timeseries cannot be used"; - break; - - // - case ERR_DOUBLE_ARRAY_ONLY: - result = "Must be an array of type double"; - break; - - // - case ERR_FLOAT_ARRAY_ONLY: - result = "Must be an array of type float"; - break; - - // - case ERR_LONG_ARRAY_ONLY: - result = "Must be an array of type long"; - break; - - // - case ERR_INT_ARRAY_ONLY: - result = "Must be an array of type int"; - break; - - // - case ERR_SHORT_ARRAY_ONLY: - result = "Must be an array of type short"; - break; - - // - case ERR_CHAR_ARRAY_ONLY: - result = "Must be an array of type char"; - break; - - // - //--- Operations with OpenCL - - // - case ERR_OPENCL_NOT_SUPPORTED: - result = "OpenCL functions are not supported on this computer"; - break; - - // - case ERR_OPENCL_INTERNAL: - result = "Internal error occurred when running OpenCL"; - break; - - // - case ERR_OPENCL_INVALID_HANDLE: - result = "Invalid OpenCL handle"; - break; - - // - case ERR_OPENCL_CONTEXT_CREATE: - result = "Error creating the OpenCL context"; - break; - - // - case ERR_OPENCL_QUEUE_CREATE: - result = "Failed to create a run queue in OpenCL"; - break; - - // - case ERR_OPENCL_PROGRAM_CREATE: - result = "Error occurred when compiling an OpenCL program"; - break; - - // - case ERR_OPENCL_TOO_LONG_KERNEL_NAME: - result = "Too long kernel name (OpenCL kernel)"; - break; - - // - case ERR_OPENCL_KERNEL_CREATE: - result = "Error creating an OpenCL kernel"; - break; - - // - case ERR_OPENCL_SET_KERNEL_PARAMETER: - result = "Error occurred when setting parameters for the OpenCL kernel"; - break; - - // - case ERR_OPENCL_EXECUTE: - result = "OpenCL program runtime error"; - break; - - // - case ERR_OPENCL_WRONG_BUFFER_SIZE: - result = "Invalid size of the OpenCL buffer"; - break; - - // - case ERR_OPENCL_WRONG_BUFFER_OFFSET: - result = "Invalid offset in the OpenCL buffer"; - break; - - // - case ERR_OPENCL_BUFFER_CREATE: - result = "Failed to create and OpenCL buffer"; - break; - - // - //--- User-Defined Errors - default: - result = "UNKNOWN Erro ..."; - break; - } - - // - return result; -} - -// -// Retrieve Specified Error Code Description ... -string GetTradeServerReturnCodeDescription(int return_code) -{ - // - string result = ""; - - // - switch (return_code) - { - // - case TRADE_RETCODE_REQUOTE: - result = "Requote"; - break; - - // - case TRADE_RETCODE_REJECT: - result = "Request rejected"; - break; - - // - case TRADE_RETCODE_CANCEL: - result = "Request canceled by trader"; - break; - - // - case TRADE_RETCODE_PLACED: - result = "Order placed"; - break; - - // - case TRADE_RETCODE_DONE: - result = "Request completed"; - break; - - // - case TRADE_RETCODE_DONE_PARTIAL: - result = "Only part of the request was completed"; - break; - - // - case TRADE_RETCODE_ERROR: - result = "Request processing error"; - break; - - // - case TRADE_RETCODE_TIMEOUT: - result = "Request canceled by timeout"; - break; - - // - case TRADE_RETCODE_INVALID: - result = "Invalid request"; - break; - - // - case TRADE_RETCODE_INVALID_VOLUME: - result = "Invalid volume in the request"; - break; - - // - case TRADE_RETCODE_INVALID_PRICE: - result = "Invalid price in the request"; - break; - - // - case TRADE_RETCODE_INVALID_STOPS: - result = "Invalid stops in the request"; - break; - - // - case TRADE_RETCODE_TRADE_DISABLED: - result = "Trade is disabled"; - break; - - // - case TRADE_RETCODE_MARKET_CLOSED: - result = "Market is closed"; - break; - - // - case TRADE_RETCODE_NO_MONEY: - result = "There is not enough money to complete the request"; - break; - - // - case TRADE_RETCODE_PRICE_CHANGED: - result = "Prices changed"; - break; - - // - case TRADE_RETCODE_PRICE_OFF: - result = "There are no quotes to process the request"; - break; - - // - case TRADE_RETCODE_INVALID_EXPIRATION: - result = "Invalid order expiration date in the request"; - break; - - // - case TRADE_RETCODE_ORDER_CHANGED: - result = "Order state changed"; - break; - - // - case TRADE_RETCODE_TOO_MANY_REQUESTS: - result = "Too frequent requests"; - break; - - // - case TRADE_RETCODE_NO_CHANGES: - result = "No changes in request"; - break; - - // - case TRADE_RETCODE_SERVER_DISABLES_AT: - result = "Autotrading disabled by server"; - break; - - // - case TRADE_RETCODE_CLIENT_DISABLES_AT: - result = "Autotrading disabled by client terminal"; - break; - - // - case TRADE_RETCODE_LOCKED: - result = "Request locked for processing"; - break; - - // - case TRADE_RETCODE_FROZEN: - result = "Order or position frozen"; - break; - - // - case TRADE_RETCODE_INVALID_FILL: - result = "Invalid order filling type"; - break; - - // - case TRADE_RETCODE_CONNECTION: - result = "No connection with the trade server"; - break; - - // - case TRADE_RETCODE_ONLY_REAL: - result = "Operation is allowed only for live accounts"; - break; - - // - case TRADE_RETCODE_LIMIT_ORDERS: - result = "The number of pending orders has reached the limit"; - break; - - // - case TRADE_RETCODE_LIMIT_VOLUME: - result = "The volume of orders and positions for the symbol has reached the limit"; - break; - - // - default: - result = "Invalid return code of the trade server"; - break; - } - - // - return result; -} - -// -// Check Expert Running in Testing Mode or not ... -bool IsRunningOnTestMode() -{ - // - bool result = false; - - // - // check programm mode ... - result = MQL5InfoInteger(MQL5_TESTING); - - // - return result; -} - -// -// Date Time Manipulation Functions ... -// - -// -// Representation of Time Struct ... -// struct MqlDateTime -// { -// int year; // Year -// int mon; // Month -// int day; // Day -// int hour; // Hour -// int min; // Minutes -// int sec; // Seconds -// int day_of_week; // Day of week (0-Sunday, 1-Monday, ... ,6-Saturday) -// int day_of_year; // Day number of the year (January 1st is assigned the number value of zero) -// }; - -// -// Converts Time to Seconds ... -ulong TimeToSeconds( - datetime time // Specify time to Convert ... -) -{ - // - ulong result = (ulong)time; - - // - return result; -} -ulong TimeToSeconds( - MqlDateTime &time // Specify time to Convert ... -) -{ - // - datetime dTime = StructToTime(time); - - // - ulong result = TimeToSeconds(dTime); - - // - return result; -} - -// -// Converts Seconds To Time ... -datetime SecondsToTime( - ulong seconds // Specify Seconds to Convert ... -) -{ - // - datetime result = (datetime)seconds; - - // - return result; -} -MqlDateTime SecondsToStruct( - ulong seconds // Specify Seconds to Convert ... -) -{ - // - datetime dTime = SecondsToTime(seconds); - - // - MqlDateTime result = {}; - TimeToStruct( - dTime, - result); - - // - return result; -} - -// -// Converts Time to MilliSeconds ... -ulong TimeToMilliSeconds( - datetime time // Specify time to Convert ... -) -{ - // - ulong result = TimeToSeconds(time) * 1000; - - // - return result; -} -ulong TimeToMilliSeconds( - MqlDateTime &time // Specify time to Convert ... -) -{ - // - datetime dTime = StructToTime(time); - - // - ulong result = TimeToMilliSeconds(dTime); - - // - return result; -} - -// -// Converts MillisSeconds to Time ... -datetime MilliSecondsToTiem( - ulong milliSeconds // Specify MilliSeconds to Convert ... -) -{ - // - ulong seconds = milliSeconds / 1000; - - // - datetime result = SecondsToTime(seconds); - - // - return result; -} -MqlDateTime MilliSecondsToStruct( - ulong milliSeconds // Specify MilliSeconds to Convert ... -) -{ - // - datetime dTime = MilliSecondsToTiem(milliSeconds); - - // - MqlDateTime result = {}; - TimeToStruct( - dTime, - result); - - // - return result; -} - -// -// Retrieve DateTime Structure ... -MqlDateTime GetCurrentTime() -{ - // - MqlDateTime result = {}; - - // - TimeCurrent(result); - - // - return result; -} - -// -// Retrieve Current Time as Seconds ... -ulong GetCurrentTimeAsSeconds() -{ - // - datetime time = TimeCurrent(); - - // - ulong result = TimeToSeconds(time); - - // - return result; -} - -// -// Retrieve Current Time as MilliSeconds ... -ulong GetCurrentTimeAsMilliSeconds() -{ - // - datetime time = TimeCurrent(); - - // - ulong result = TimeToMilliSeconds(time); - - // - return result; -} - -// -// Retrieve Specified Candle Time ... -datetime GetCandleTime( - string symbol = "", // Specify Symbol - ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame - int bar_index = 0 // Specify Bar Index -) -{ - // - // Validate and Normalize Args ... - - // - // Normalize Symbol ... - symbol = StringLen(symbol) == 0 - ? _Symbol - : symbol; - - // - // Normalize Period ... - period = period == NULL - ? _Period - : period; - - // - // Retrieve Bar Time ... - datetime result = iTime( - symbol, - period, - bar_index); - - // - return result; -} - -// -// Retrieve Specified Candle Time ... -ulong GetCandleTimeAsSeconds( - string symbol = "", // Specify Symbol - ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame - int bar_index = 0 // Specify Bar Index -) -{ - // - // Retrieve Bar Time ... - datetime time = GetCandleTime( - symbol, - period, - bar_index); - - // - ulong result = TimeToSeconds(time); - - // - return result; -} - -// -// Retrieve Specified Candle Time ... -ulong GetCandleTimeAsMilliSeconds( - string symbol = "", // Specify Symbol - ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame - int bar_index = 0 // Specify Bar Index -) -{ - // - // Retrieve Bar Time ... - datetime time = GetCandleTime( - symbol, - period, - bar_index); - - // - ulong result = TimeToMilliSeconds(time); - - // - return result; -} - -// -// Retrieve a Candle Time Structure ... -MqlDateTime GetCandleTimeStruct( - string symbol = "", // Specify Symbol - ENUM_TIMEFRAMES period = NULL, // Specify TimeFrame - int bar_index = 0 // Specify Bar Index -) -{ - // - MqlDateTime result = {}; - - // - // Retrieve Bar Time ... - datetime barTime = GetCandleTime( - symbol, - period, - bar_index); - - // - // Convert to Structure ... - TimeToStruct(barTime, result); - - // - return result; -} - -// -// -// - -// -// Holds Month ... -static int xMonth = -1; - -// -// Holds Day Of Week ... -static int xDayOfWeek = -1; -static int xForWeekDay = -1; - -// -// Holds Day ... -static int xDay = -1; - -// -// Holds Hour ... -static int xHour = -1; - -// -// Reset Timing Variables ... -void ResetTiming() -{ - // - xHour = -1; - xDay = -1; - xDayOfWeek = -1; - xMonth = -1; -} - -// -// Detecting New Houre ... -bool IsNewHour() -{ - // - bool result = false; - - // - // Retrieve Current Time as Struct ... - MqlDateTime timeStruct = GetCurrentTime(); - - // - // Check Houre ... - result = timeStruct.hour != xHour; - if (result) - { - xHour = timeStruct.hour; - } - - // - return result; -} - -// -// Detecting New Day ... -bool IsNewDay() -{ - // - bool result = false; - - // - // Retrieve Current Time as Struct ... - MqlDateTime timeStruct = GetCurrentTime(); - - // - // Check Houre ... - result = timeStruct.day_of_year != xDay; - if (result) - { - xDay = timeStruct.day_of_year; - } - - // - return result; -} - -// -// Detecting New Week ... -bool IsNewWeek() -{ - // - bool result = false; - - // - // Retrieve Current Time as Struct ... - MqlDateTime timeStruct = GetCurrentTime(); - - // - // Check Week ... - // Since Week Starts From Monday in Forex World ... - // we Calculate Start of Week by 1-Monday ... - result = - xDayOfWeek == -1 && - xForWeekDay == -1 - ? true - : timeStruct.day_of_week == 1 && - timeStruct.day_of_year > xForWeekDay; - - // - xForWeekDay = timeStruct.day_of_year; - xDayOfWeek = timeStruct.day_of_week; - - // - return result; -} - -// -// Detecting End Of Week ... -bool IsWeekEnd() -{ - // - bool result = false; - - // - // Retrieve Current Time as Struct ... - MqlDateTime timeStruct = GetCurrentTime(); - - // - // Check WeekEnd ... - // Since Week Starts From Monday in Forex World ... - // we Calculate End of Week by 5-Friday ... - result = - xDayOfWeek != -1 && - timeStruct.day_of_week == 5 && - timeStruct.hour == 23 && - timeStruct.min == 59 && - timeStruct.sec == 59; - - // - return result; -} - -// -// Detecting New Month ... -bool IsNewMonth() -{ - // - bool result = false; - - // - // Retrieve Current Time as Struct ... - MqlDateTime timeStruct = GetCurrentTime(); - - // - // Check Houre ... - result = timeStruct.mon != xMonth; - if (result) - { - xMonth = timeStruct.mon; - } - - // - return result; -} - -// -// Find Farest Time Frame ... -ENUM_TIMEFRAMES GetFarestTimeFrame( - ENUM_TIMEFRAMES mPeriod // Specified Period -) -{ - // - ENUM_TIMEFRAMES result = NULL; - - // - // Normalize Period ... - if ( - mPeriod < 0 || - mPeriod == NULL) - { - mPeriod = _Period; - } - - // - switch (mPeriod) - { - // - case PERIOD_M1: - case PERIOD_M2: - case PERIOD_M3: - case PERIOD_M4: - case PERIOD_M5: - case PERIOD_M6: - case PERIOD_M10: - case PERIOD_M12: - case PERIOD_M15: - case PERIOD_M20: - case PERIOD_M30: - result = PERIOD_H4; - break; - - // - case PERIOD_H1: - case PERIOD_H2: - case PERIOD_H3: - case PERIOD_H4: - result = PERIOD_H12; - break; - - // - case PERIOD_H6: - case PERIOD_H8: - case PERIOD_H12: - case PERIOD_D1: - result = PERIOD_W1; - break; - - // - default: - result = PERIOD_MN1; - break; - } - - // - return result; -} - -// -// Find Medium Time Frame ... -ENUM_TIMEFRAMES GetMediestTimeFrame( - ENUM_TIMEFRAMES mPeriod // Specified Period -) -{ - // - ENUM_TIMEFRAMES result = NULL; - - // - // Normalize Period ... - if ( - mPeriod < 0 || - mPeriod == NULL) - { - mPeriod = _Period; - } - - // - switch (mPeriod) - { - // - case PERIOD_M1: - case PERIOD_M2: - case PERIOD_M3: - case PERIOD_M4: - case PERIOD_M5: - case PERIOD_M6: - case PERIOD_M10: - case PERIOD_M12: - case PERIOD_M15: - case PERIOD_M20: - result = PERIOD_H1; - break; - - // - case PERIOD_M30: - result = PERIOD_H2; - break; - - // - case PERIOD_H1: - case PERIOD_H2: - case PERIOD_H3: - result = PERIOD_H4; - break; - - // - case PERIOD_H4: - case PERIOD_H6: - case PERIOD_H8: - result = PERIOD_H12; - break; - - // - case PERIOD_H12: - result = PERIOD_D1; - break; - - // - case PERIOD_D1: - result = PERIOD_W1; - break; - - // - case PERIOD_W1: - result = PERIOD_MN1; - break; - - // - default: - result = PERIOD_MN1; - break; - } - - // - return result; -} - -// -// Find Nearest Time Frame ... -ENUM_TIMEFRAMES GetNearestTimeFrame( - ENUM_TIMEFRAMES mPeriod // Specified Period -) -{ - // - ENUM_TIMEFRAMES result = NULL; - - // - // Normalize Period ... - if ( - mPeriod < 0 || - mPeriod == NULL) - { - mPeriod = _Period; - } - - // - switch (mPeriod) - { - // - case PERIOD_M1: - case PERIOD_M2: - case PERIOD_M3: - case PERIOD_M4: - result = PERIOD_M5; - break; - - // - case PERIOD_M5: - case PERIOD_M6: - case PERIOD_M10: - case PERIOD_M12: - result = PERIOD_M15; - break; - - // - case PERIOD_M15: - case PERIOD_M20: - result = PERIOD_M30; - break; - - // - case PERIOD_M30: - result = PERIOD_H1; - break; - - // - case PERIOD_H1: - case PERIOD_H2: - case PERIOD_H3: - result = PERIOD_H4; - break; - - // - case PERIOD_H4: - case PERIOD_H6: - case PERIOD_H8: - result = PERIOD_H12; - break; - - // - case PERIOD_H12: - result = PERIOD_D1; - break; - - // - case PERIOD_D1: - result = PERIOD_W1; - break; - - // - case PERIOD_W1: - result = PERIOD_MN1; - break; - - // - default: - result = PERIOD_MN1; - break; - } - - // - return result; -} - -// -// Get Specific Time Frame Start Candle Time ... -datetime GetPeriodStartTime( - string mSymbol = NULL, // Specified Symbol ... - ENUM_TIMEFRAMES mPeriod = NULL, // Specified Period ... - datetime mTime = NULL // Specified Bar Time ... -) -{ - // - // Normalize Arg ... - - // - if ( - mSymbol == NULL || - StringLen(mSymbol) == 0) - { - mSymbol = _Symbol; - } - - // - if ( - mPeriod < 0 || - mPeriod == NULL) - { - mPeriod = _Period; - } - - // - if ( - mTime < 0 || - mTime == NULL) - { - mTime = TimeCurrent(); - } - - // - int barIndex = iBarShift( - mSymbol, - mPeriod, - mTime, - false); - - // - datetime result = iTime( - mSymbol, - mPeriod, - barIndex); - - // - return result; -} - -// -// END Provided Functions ... -// diff --git a/Libraries/x-saherelm.draw.lib.mq5 b/Libraries/x-saherelm.draw.lib.mq5 deleted file mode 100644 index ece98c83..00000000 --- a/Libraries/x-saherelm.draw.lib.mq5 +++ /dev/null @@ -1,2345 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Draw Library -// -------------------------------------- -// Name: XDraw -// Description: provides Draw abilities ... -// -// -// Maintainer: -// ------------ -// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) -// -////////////////////////////////////////////////////// -// -// Global Properties ... -#property library -#property copyright "Copyright 2023, SaherElm IT Center" -#property link "https://www.saherelm.ir" -#property version "1.00" -#property strict - -// -// START Inputs ... -// -// -// END Inputs ... -// - -// -// Include Logger Library ... -#include "x-saherelm.log.lib.mq5" -#include "x-saherelm.common.lib.mq5" - -// -// START Global Definitions: Variables, Properties and etc ... -// -string drawPrefix = "X-OBJ"; -// -// END Global Definitions: Variables, Properties and etc ... -// - -// -// START Provided Functions ... -// -// -// DeInitial Library if required ... -void OnDeinitDrawLibrary() -{ - RemoveDraws(); -} - -// -void DrawSignalShape( - XSignal &signal, // Specify Signal to Draw - color longColor = clrAqua, // Long Signals Color - color shortColor = clrFuchsia, // Short Signal Color - color entryColor = clrGold // Signal Entry Price Color -) -{ - // - // Draw Signal Info : - // - Draw Entry Price Line; - // - Draw SL; - // - Draw TP; - // - Risk Free; - - // - bool isLong = signal.type == X_SIGNAL_LONG; - - // - color tpColor = longColor; - color slColor = shortColor; - - // - string name = "T(" + (string)signal.ticket + ")" + "_" + "TY(" + EnumToString(signal.type) + ")"; - - // - string tpName = "TP_" + name; - if (IsDrawExists(tpName)) - { - RemoveDraw(tpName); - } - - // - string slName = "SL_" + name; - if (IsDrawExists(slName)) - { - RemoveDraw(slName); - } - - // - string riskFreeName = "RF_" + name; - if (IsDrawExists(riskFreeName)) - { - RemoveDraw(riskFreeName); - } - - // - string entryName = "Entry_" + name; - if (IsDrawExists(entryName)) - { - RemoveDraw(entryName); - } - - // - string vlName = "Time_" + name; - if (IsDrawExists(vlName)) - { - RemoveDraw(vlName); - } - - // - int signalBarIndex = iBarShift( - signal.symbol, - _Period, - signal.time); - - // - datetime time1 = iTime( - signal.symbol, - _Period, - signalBarIndex + 1); - datetime time2 = iTime( - signal.symbol, - _Period, - signalBarIndex - 1); - - // - // Entry ... - bool isTrendLineDrawn = DrawTrendLine( - 0, - entryName, - 0, - time1, - signal.entry, - time2, - signal.entry, - entryColor); - - // - // TP ... - bool isTPDrawn = false; - if (signal.tp > 0) - { - // - isTPDrawn = DrawTrendLine( - 0, - tpName, - 0, - time1, - signal.tp, - time2, - signal.tp, - tpColor, - STYLE_SOLID, - 1, - false, - true); - } - - // - // RISKFREE ... - bool isRFDrawn = false; - if (signal.riskFreeStep > 0) - { - // - double firstStepPrice = isLong ? signal.entry + PipsToPrice(signal.riskFreeStep) - : signal.entry - PipsToPrice(signal.riskFreeStep); - - // - isRFDrawn = DrawTrendLine( - 0, - riskFreeName, - 0, - time1, - firstStepPrice, - time2, - firstStepPrice, - tpColor, - STYLE_DOT, - 1, - false, - true); - } - - // - // SL ... - bool isSLDrawn = false; - if (signal.sl > 0) - { - // - isSLDrawn = DrawTrendLine( - 0, - slName, - 0, - time1, - signal.sl, - time2, - signal.sl, - slColor, - STYLE_SOLID, - 1, - false, - true); - } - - // - // Draw a Vertical Line ... - bool isVerticalLineDrawn = DrawVerticalLine( - 0, - vlName, - 0, - signal.time, - slColor); -} - -// -// remove drawn objects ... -void RemoveDraws( - string tag = NULL, - int chartId = -1, - int subWindow = -1) -{ - // - // Normalize Args ... - // - if (tag == NULL) - { - tag = drawPrefix; - } - - // - if (chartId == -1) - { - chartId = 0; - } - - // - if (subWindow == -1) - { - subWindow = 0; - } - - // - for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) - { - // - string on = ObjectName(chartId, iObj, subWindow); - if (StringFind(on, tag) >= 0) - { - ObjectDelete(chartId, on); - } - } - - // - // Redraw Chart ... - ChartRedraw(); -} - -// -bool RemoveDraw( - string name, - int chartId = -1, - int subWindow = -1) -{ - // - bool result = false; - - // - if (chartId == -1) - { - chartId = 0; - } - - // - if (subWindow == -1) - { - subWindow = 0; - } - - // - string objName = ""; - for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) - { - // - string on = ObjectName(chartId, iObj, subWindow); - if (StringFind(on, name) >= 0) - { - // - objName = on; - break; - } - } - - // - if (StringLen(objName) > 0) - { - result = ObjectDelete(chartId, objName); - } - - // - return result; -} - -// -// Check Object Exists ... -bool IsDrawExists( - string name, - int chartId = -1, - int subWindow = -1) -{ - // - bool result = false; - - // - if (chartId == -1) - { - chartId = 0; - } - - // - if (subWindow == -1) - { - subWindow = 0; - } - - // - for (int iObj = ObjectsTotal(chartId, subWindow) - 1; iObj >= 0; iObj--) - { - // - string on = ObjectName(chartId, iObj, subWindow); - result = StringFind(on, name) >= 0; - if (result) - { - break; - } - } - - // - return result; -} -// -// END Provided Functions ... -// - -// -// START Regular Draws ... -// - -// -// START Arrow Functions ... -// -// -// Draw an Arrow Object on Chart ... -bool DrawArrow( - const long chartID = 0, // chart's ID - const string name = "Arrow", // arrow name - const int subWindow = 0, // subwindow index - datetime time = 0, // anchor point time - double price = 0, // anchor point price - const uchar arrowCode = 252, // arrow code - const ENUM_ARROW_ANCHOR anchor = ANCHOR_BOTTOM, // anchor point position - const color clr = clrAqua, // arrow color - const ENUM_LINE_STYLE style = STYLE_SOLID, // border line style - const int width = 3, // arrow size - const bool back = false, // in the background - const bool selection = false, // highlight to move - const bool hidden = false, // hidden in the object list - const long zOrder = 0 // Order Object ... -) -{ - // - // set anchor point coordinates if they are not set ... - ChangeArrowEmptyPoint(time, price); - - // - // reset the error value ... - ResetLastError(); - - // - // Normalize Name ... - string objName = drawPrefix + "_" + name; - - // - // create an arrow ... - if (!ObjectCreate(chartID, objName, OBJ_ARROW, subWindow, time, price)) - { - // - string message = - __FUNCTION__ + - ": failed to create an arrow! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // set the arrow code ... - ObjectSetInteger(chartID, objName, OBJPROP_ARROWCODE, arrowCode); - - // - // set anchor type ... - ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); - - // - // set the arrow color ... - ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); - - // - // set the border line style ... - ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); - - // - // set the arrow's size ... - ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); - - // - // display in the foreground (false) or background (true) ... - ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); - - // - // enable (true) or disable (false) the mode of moving the arrow by mouse - // when creating a graphical object using ObjectCreate function, the object cannot be - // highlighted and moved by default. Inside this method, selection parameter - // is false by default, if you want making it possible to highlight and move the object - // change it to true ... - ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); - ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); - - // - // hide (true) or display (false) graphical object name in the object list ... - ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); - - // - // set the priority for receiving the event of a mouse click in the chart ... - ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); - - // - // successful execution ... - return (true); -} - -// -// Move the anchor point of Arrow ... -bool MoveArrow( - const long chartID = 0, // chart's ID - const string name = "Arrow", // object name - datetime time = 0, // anchor point time coordinate - double price = 0 // anchor point price coordinate -) -{ - // - // if point position is not set, move it to the current bar having Bid price ... - if (!time) - { - time = TimeCurrent(); - } - - // - if (!price) - { - price = SymbolInfoDouble(_Symbol, SYMBOL_BID); - } - - // - // reset the error value - ResetLastError(); - - // - // move the anchor point ... - if (!ObjectMove(chartID, name, 0, time, price)) - { - // - string message = - __FUNCTION__ + - ": failed to move the anchor point! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Delete an arrow ... -bool DeleteArrow( - const long chartID = 0, // chart's ID - const string name = "Arrow" // arrow name -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // delete an arrow ... - if (!ObjectDelete(chartID, name)) - { - // - string message = - __FUNCTION__ + - ": failed to delete an arrow! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Change the arrow code ... -bool ArrowCodeChange( - const long chartID = 0, // chart's ID - const string name = "Arrow", // object name - const uchar code = 252 // arrow code -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // change the arrow code ... - if (!ObjectSetInteger(chartID, name, OBJPROP_ARROWCODE, code)) - { - // - string message = - __FUNCTION__ + - ": failed to change the arrow code! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Change anchor type ... -bool ArrowAnchorChange( - const long chartID = 0, // chart's ID - const string name = "Arrow", // object name - const ENUM_ARROW_ANCHOR anchor = ANCHOR_TOP // anchor type -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // change anchor type ... - if (!ObjectSetInteger(chartID, name, OBJPROP_ANCHOR, anchor)) - { - // - string message = - __FUNCTION__ + - ": failed to change anchor type! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Check anchor point values and set default values -// for empty ones ... -void ChangeArrowEmptyPoint( - datetime &time, - double &price) -{ - // - // if the point's time is not set, it will be on the current bar ... - if (!time) - { - time = TimeCurrent(); - } - - // - // if the point's price is not set, it will have Bid value ... - if (!price) - { - price = SymbolInfoDouble(_Symbol, SYMBOL_BID); - } -} -// -// END Arrow Functions ... -// - -// -// START Horizontal Line Functions ... -// -// -// Create, Draw the horizontal line ... -bool DrawHorizontalLine( - const long chartID = 0, // chart's ID - const string name = "HLine", // line name - const int subWindow = 0, // subwindow index - double price = 0, // line price - const color clr = clrRed, // line color - const ENUM_LINE_STYLE style = STYLE_SOLID, // line style - const int width = 1, // line width - const bool back = false, // in the background - const bool selection = false, // highlight to move - const bool hidden = false, // hidden in the object list - const long zOrder = 0 // priority for mouse click -) -{ - // - // if the price is not set, set it at the current Bid price level ... - if (!price) - { - price = SymbolInfoDouble(Symbol(), SYMBOL_BID); - } - - // - // reset the error value ... - ResetLastError(); - - // - // Normalize Name ... - string objName = drawPrefix + "_" + name; - - // - // create a horizontal line ... - if (!ObjectCreate(chartID, objName, OBJ_HLINE, subWindow, 0, price)) - { - // - string message = - __FUNCTION__ + - ": failed to create a horizontal line! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // set line color ... - ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); - - // - // set line display style ... - ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); - - // - // set line width ... - ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); - - // - // display in the foreground (false) or background (true) ... - ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); - - // - // enable (true) or disable (false) the mode of moving the line by mouse - // when creating a graphical object using ObjectCreate function, the object cannot be - // highlighted and moved by default. Inside this method, selection parameter - // is true by default making it possible to highlight and move the object - ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); - ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); - - // - // hide (true) or display (false) graphical object name in the object list ... - ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); - - // - // set the priority for receiving the event of a mouse click in the chart ... - ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); - - // - // successful execution ... - return (true); -} - -// -// Move horizontal line ... -bool MoveHorizontalLine( - const long chartID = 0, // chart's ID - const string name = "HLine", // line name - double price = 0 // line price -) -{ - // - // if the line price is not set, move it to the current Bid price level ... - if (!price) - { - price = SymbolInfoDouble(Symbol(), SYMBOL_BID); - } - - // - // reset the error value ... - ResetLastError(); - - // - // move a horizontal line ... - if (!ObjectMove(chartID, name, 0, 0, price)) - { - // - string message = - __FUNCTION__ + - ": failed to move the horizontal line! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Delete a horizontal line ... -bool DeleteHorizontalLine( - const long chartID = 0, // chart's ID - const string name = "HLine" // line name -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // delete a horizontal line ... - if (!ObjectDelete(chartID, name)) - { - // - string message = - __FUNCTION__ + - ": failed to delete a horizontal line! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} -// -// END Horizontal Line Functions ... -// - -// -// START Vertical Line Functions ... -// -// -// Create the vertical line ... -bool DrawVerticalLine( - const long chartID = 0, // chart's ID - const string name = "VLine", // line name - const int sub_window = 0, // subwindow index - datetime time = 0, // line time - const color clr = clrRed, // line color - const ENUM_LINE_STYLE style = STYLE_SOLID, // line style - const int width = 1, // line width - const bool back = false, // in the background - const bool selection = false, // highlight to move - const bool hidden = false, // hidden in the object list - const long zOrder = 0 // priority for mouse click -) -{ - // - // if the line time is not set, draw it via the last bar ... - if (!time) - { - time = TimeCurrent(); - } - - // - // reset the error value - ResetLastError(); - - // - // Normalize Name ... - string objName = drawPrefix + "_" + name; - - // - // create a vertical line ... - if (!ObjectCreate(chartID, objName, OBJ_VLINE, sub_window, time, 0)) - { - // - string message = - __FUNCTION__ + - ": failed to create a vertical line! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return false; - } - - // - // set line color ... - ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); - - // - // set line display style ... - ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); - - // - // set line width ... - ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); - - // - // display in the foreground (false) or background (true) ... - ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); - - // - // enable (true) or disable (false) the mode of moving the line by mouse - // when creating a graphical object using ObjectCreate function, the object cannot be - // highlighted and moved by default. Inside this method, selection parameter - // is true by default making it possible to highlight and move the object ... - ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); - ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); - - // - // hide (true) or display (false) graphical object name in the object list ... - ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); - - // - // set the priority for receiving the event of a mouse click in the chart - ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); - - // - // successful execution ... - return true; -} - -// -// Move the vertical line ... -bool MoveVerticalLine( - const long chartID = 0, // chart's ID - const string name = "VLine", // line name - datetime time = 0 // line time -) -{ - // - // if line time is not set, move the line to the last bar ... - if (!time) - { - time = TimeCurrent(); - } - - // - // reset the error value ... - ResetLastError(); - - // - // move the vertical line ... - if (!ObjectMove(chartID, name, 0, time, 0)) - { - // - string message = - __FUNCTION__ + - ": failed to move the vertical line! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Delete the vertical line ... -bool DeleteVerticalLine( - const long chartID = 0, // chart's ID - const string name = "VLine" // line name -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // delete the vertical line ... - if (!ObjectDelete(chartID, name)) - { - // - string message = - __FUNCTION__ + - ": failed to delete the vertical line! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return false; - } - - // - // successful execution ... - return true; -} -// -// END Vertical Line Functions ... -// - -// -// START RectangleLabel Functions ... -// -// -// Create Rectangle Label Object ... -bool DrawRectangleLabel( - const long chartID = 0, // chart's ID - const string name = "RectLabel", // label name - const int subWindow = 0, // subwindow index - const int x = 0, // X coordinate - const int y = 0, // Y coordinate - const int width = 50, // width - const int height = 18, // height - const color back_clr = clrWhiteSmoke, // background color - const ENUM_BORDER_TYPE border = BORDER_SUNKEN, // border type - const ENUM_BASE_CORNER corner = CORNER_LEFT_UPPER, // chart corner for anchoring - const color clr = clrRed, // flat border color (Flat) - const ENUM_LINE_STYLE style = STYLE_SOLID, // flat border style - const int lineWidth = 1, // flat border width - const bool back = false, // in the background - const bool selection = false, // highlight to move - const bool hidden = false, // hidden in the object list - const long zOrder = 0 // priority for mouse click -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // Normalize Name ... - string objName = drawPrefix + "_" + name; - - // - //--- create a rectangle label - if (!ObjectCreate(chartID, objName, OBJ_RECTANGLE_LABEL, subWindow, 0, 0)) - { - // - string message = - __FUNCTION__ + - ": failed to create a rectangle label! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // set label coordinates ... - ObjectSetInteger(chartID, objName, OBJPROP_XDISTANCE, x); - ObjectSetInteger(chartID, objName, OBJPROP_YDISTANCE, y); - - // - // set label size ... - ObjectSetInteger(chartID, objName, OBJPROP_XSIZE, width); - ObjectSetInteger(chartID, objName, OBJPROP_YSIZE, height); - - // - // set background color ... - ObjectSetInteger(chartID, objName, OBJPROP_BGCOLOR, back_clr); - - // - // set border type ... - ObjectSetInteger(chartID, objName, OBJPROP_BORDER_TYPE, border); - - // - // set the chart's corner, relative to which point coordinates are defined ... - ObjectSetInteger(chartID, objName, OBJPROP_CORNER, corner); - - // - // set flat border color (in Flat mode) ... - ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); - - // - // set flat border line style ... - ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); - - // - // set flat border width ... - ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, lineWidth); - - // - // display in the foreground (false) or background (true) ... - ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); - - // - // enable (true) or disable (false) the mode of moving the label by mouse ... - ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, selection); - ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); - - // - // hide (true) or display (false) graphical object name in the object list ... - ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); - - // - // set the priority for receiving the event of a mouse click in the chart ... - ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); - - // - // successful execution ... - return (true); -} - -// -// Move Rectangle Label .. -bool MoveRectangleLabel( - const long chartID = 0, // chart's ID - const string name = "RectLabel", // label name - const int x = 0, // X coordinate - const int y = 0 // Y coordinate -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // move the rectangle label ... - if (!ObjectSetInteger(chartID, name, OBJPROP_XDISTANCE, x)) - { - // - string message = - __FUNCTION__ + - ": failed to move X coordinate of the label! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - if (!ObjectSetInteger(chartID, name, OBJPROP_YDISTANCE, y)) - { - // - string message = - __FUNCTION__ + - ": failed to move Y coordinate of the label! Error code = " + - (string)GetLastError(); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Delete the rectangle label ... -bool DeleteRectangleLabel( - const long chartID = 0, // chart's ID - const string name = "RectLabel" // label name -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // delete the label ... - if (!ObjectDelete(chartID, name)) - { - // - string message = - __FUNCTION__ + - ": failed to delete a rectangle label! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Change Rectangle Label Size ... -bool ChangeSizeRectangleLabel( - const long chartID = 0, // chart's ID - const string name = "RectLabel", // label name - const int width = 50, // label width - const int height = 18 // label height -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // change label size ... - if (!ObjectSetInteger(chartID, name, OBJPROP_XSIZE, width)) - { - // - string message = - __FUNCTION__ + - ": failed to change the label's width! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - if (!ObjectSetInteger(chartID, name, OBJPROP_YSIZE, height)) - { - // - string message = - __FUNCTION__ + - ": failed to change the label's height! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Change rectangle label border type ... -bool RectLabelChangeBorderType( - const long chartID = 0, // chart's ID - const string name = "RectLabel", // label name - const ENUM_BORDER_TYPE border = BORDER_SUNKEN // border type -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // change border type ... - if (!ObjectSetInteger(chartID, name, OBJPROP_BORDER_TYPE, border)) - { - // - string message = - __FUNCTION__ + - ": failed to change the border type! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} -// -// END RectangleLabel Functions ... -// - -// -// START TrendLine Funcions ... -// -// Create a trend line by the given coordinates ... -bool DrawTrendLine( - const long chartID = 0, // chart's ID - const string name = "TrendLine", // line name - const int subWindow = 0, // subwindow index - datetime time1 = 0, // first point time - double price1 = 0, // first point price - datetime time2 = 0, // second point time - double price2 = 0, // second point price - const color clr = clrYellow, // line color - const ENUM_LINE_STYLE style = STYLE_SOLID, // line style - const int width = 1, // line width - const bool back = false, // in the background - const bool selection = false, // highlight to move - const bool rayRight = false, // line's continuation to the right - const bool hidden = false, // hidden in the object list - const long zOrder = 0 // priority for mouse click -) -{ - // - // set anchor points' coordinates if they are not set ... - ChangeTrendLineEmptyPoints( - time1, - price1, - time2, - price2); - - // - // reset the error value ... - ResetLastError(); - - // - // Normalize Name ... - string objName = drawPrefix + "_" + name; - - // - // create a trend line by the given coordinates ... - if (!ObjectCreate(chartID, objName, OBJ_TREND, subWindow, time1, price1, time2, price2)) - { - // - string message = - __FUNCTION__ + - ": failed to create a trend line! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // set line color ... - ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); - - // - // set line display style ... - ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); - - // - // set line width ... - ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); - - // - // display in the foreground (false) or background (true) ... - ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); - - // - // enable (true) or disable (false) the mode of moving the line by mouse - // when creating a graphical object using ObjectCreate function, the object cannot be - // highlighted and moved by default. Inside this method, selection parameter - // is true by default making it possible to highlight and move the object ... - ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); - ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); - - // - // enable (true) or disable (false) the mode of continuation of the line's display to the right ... - ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); - - // - // hide (true) or display (false) graphical object name in the object list ... - ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); - - // - // set the priority for receiving the event of a mouse click in the chart ... - ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); - - // - // successful execution ... - return (true); -} - -// -// Move trend line anchor point ... | -bool ChangeTrendLinePoint( - const long chartID = 0, // chart's ID - const string name = "TrendLine", // line name - const int pointindex = 0, // anchor point index - datetime time = 0, // anchor point time coordinate - double price = 0 // anchor point price coordinate -) -{ - // - // if point position is not set, move it to the current bar having Bid price ... - if (!time) - { - time = TimeCurrent(); - } - - // - if (!price) - { - price = SymbolInfoDouble(Symbol(), SYMBOL_BID); - } - - // - // reset the error value ... - ResetLastError(); - - // - // move trend line's anchor point ... - if (!ObjectMove(chartID, name, pointindex, time, price)) - { - // - string message = - __FUNCTION__ + - ": failed to move the anchor point! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// The function deletes the trend line from the chart ... -bool DeleteTrendLine( - const long chartID = 0, // chart's ID - const string name = "TrendLine" // line name -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // delete a trend line ... - if (!ObjectDelete(chartID, name)) - { - // - string message = - __FUNCTION__ + - ": failed to delete a trend line! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Check the values of trend line's anchor points and set default ... -// values for empty ones ... -void ChangeTrendLineEmptyPoints( - datetime &time1, - double &price1, - datetime &time2, - double &price2) -{ - // - // if the first point's time is not set, it will be on the current bar ... - if (!time1) - { - time1 = TimeCurrent(); - } - - // - // if the first point's price is not set, it will have Bid value ... - if (!price1) - { - price1 = SymbolInfoDouble(Symbol(), SYMBOL_BID); - } - - // - // if the second point's time is not set, it is located 9 bars left from the second one ... - if (!time2) - { - // - // array for receiving the open time of the last 10 bars ... - datetime temp[10]; - CopyTime(Symbol(), Period(), time1, 10, temp); - - // - // set the second point 9 bars left from the first one ... - time2 = temp[0]; - } - - // - // if the second point's price is not set, it is equal to the first point's one ... - if (!price2) - { - price2 = price1; - } -} -// -// END TrendLine Functions ... -// - -// -// START Text Functions ... -// -// Create and Draw a Text Object ... -bool DrawText( - const long chartID = 0, // chart's ID - const string name = "Text", // object name - const int subWindow = 0, // subwindow index - datetime time = 0, // anchor point time - double price = 0, // anchor point price - const string text = "Text", // the text itself - const string font = "Arial", // font - const int fontSize = 10, // font size - const color clr = clrRed, // color - const double angle = 0.0, // text slope - const ENUM_ANCHOR_POINT anchor = ANCHOR_CENTER, // anchor type - const bool back = false, // in the background - const bool selection = false, // highlight to move - const bool hidden = true, // hidden in the object list - const long zOrder = 0 // priority for mouse click -) -{ - // - // set anchor point coordinates if they are not set ... - ChangeTextEmptyPoint(time, price); - - // - // reset the error value ... - ResetLastError(); - - // - // Normalize Name ... - string objName = drawPrefix + "_" + name; - - // - //--- create Text object - if (!ObjectCreate(chartID, objName, OBJ_TEXT, subWindow, time, price)) - { - // - string message = - __FUNCTION__ + - ": failed to create \"Text\" object! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // set the text ... - ObjectSetString(chartID, objName, OBJPROP_TEXT, text); - - // - // set text font ... - ObjectSetString(chartID, objName, OBJPROP_FONT, font); - - // - // set font size ... - ObjectSetInteger(chartID, objName, OBJPROP_FONTSIZE, fontSize); - - // - // set the slope angle of the text ... - ObjectSetDouble(chartID, objName, OBJPROP_ANGLE, angle); - - // - // set anchor type ... - ObjectSetInteger(chartID, objName, OBJPROP_ANCHOR, anchor); - - // - // set color ... - ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); - - // - // display in the foreground (false) or background (true) ... - ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); - - // - // enable (true) or disable (false) the mode of moving the object by mouse ... - ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); - ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); - - // - // hide (true) or display (false) graphical object name in the object list ... - ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); - - // - // set the priority for receiving the event of a mouse click in the chart ... - ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); - - // - // successful execution ... - return (true); -} - -// -// Move the anchor point ... -bool MoveText( - const long chartID = 0, // chart's ID - const string name = "Text", // object name - datetime time = 0, // anchor point time coordinate - double price = 0 // anchor point price coordinate -) -{ - // - //--- if point position is not set, move it to the current bar having Bid price - if (!time) - { - time = TimeCurrent(); - } - - // - if (!price) - { - price = SymbolInfoDouble(_Symbol, SYMBOL_BID); - } - - // - // reset the error value ... - ResetLastError(); - - // - // move the anchor point .. - if (!ObjectMove(chartID, name, 0, time, price)) - { - // - string message = - __FUNCTION__ + - ": failed to move the anchor point! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Change the object text ... -bool ChangeText( - const long chartID = 0, // chart's ID - const string name = "Text", // object name - const string text = "Text" // text -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // change object text ... - if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) - { - // - string message = - __FUNCTION__ + - ": failed to change the text! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Delete Text object ... -bool DeleteText( - const long chartID = 0, // chart's ID - const string name = "Text" // object name -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // delete the object ... - if (!ObjectDelete(chartID, name)) - { - // - string message = - __FUNCTION__ + - ": failed to delete \"Text\" object! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution - return (true); -} - -// -// Check anchor point values and set default values -// for empty ones ... -void ChangeTextEmptyPoint( - datetime &time, - double &price) -{ - // - // if the point's time is not set, it will be on the current bar ... - if (!time) - { - time = TimeCurrent(); - } - - // - // if the point's price is not set, it will have Bid value ... - if (!price) - { - price = SymbolInfoDouble(_Symbol, SYMBOL_BID); - } -} -// -// END Text Functions ... -// - -// -// START Fibonacchi Functions ... -// -// -// Create Fibonacci Retracement by the given coordinates ... -bool DrawFibonacci( - const long chartID = 0, // chart's ID - const string name = "Fibonacci", // object name - const int subWindow = 0, // subwindow index - datetime time1 = 0, // first point time - double price1 = 0, // first point price - datetime time2 = 0, // second point time - double price2 = 0, // second point price - const color clr = clrRed, // object color - const ENUM_LINE_STYLE style = STYLE_SOLID, // object line style - const int width = 1, // object line width - const bool back = false, // in the background - const bool selection = true, // highlight to move - const bool rayRight = false, // object's continuation to the right - const bool hidden = true, // hidden in the object list - const long zOrder = 0 // priority for mouse click -) -{ - // - // set anchor points' coordinates if they are not set ... - ChangeFibonacciEmptyPoints(time1, price1, time2, price2); - - // - // reset the error value ... - ResetLastError(); - - // - // Normalize Name ... - string objName = drawPrefix + "_" + name; - - // - // Create Fibonacci Retracement by the given coordinates ... - if (!ObjectCreate(chartID, objName, OBJ_FIBO, subWindow, time1, price1, time2, price2)) - { - // - string message = - __FUNCTION__ + - ": failed to create \"Fibonacci Retracement\"! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // set color ... - ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); - - // - // set line style ... - ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); - - // - // set line width ... - ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); - - // - // display in the foreground (false) or background (true) ... - ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); - - // - // enable (true) or disable (false) the mode of highlighting the channel for moving - // when creating a graphical object using ObjectCreate function, the object cannot be - // highlighted and moved by default. Inside this method, selection parameter - // is true by default making it possible to highlight and move the object ... - ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); - ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); - - // - // enable (true) or disable (false) the mode of continuation of the object's display to the right ... - ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); - - // - // hide (true) or display (false) graphical object name in the object list ... - ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); - - // - // set the priority for receiving the event of a mouse click in the chart ... - ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); - - // - // successful execution ... - return (true); -} - -// -// Create Fibonacci Retracement by the given coordinates ... -bool DrawCustomFibonacci( - // - int levels, // number of level lines - double &values[], // values of level lines - color &colors[], // color of level lines - ENUM_LINE_STYLE &styles[], // style of level lines - int &widths[], // width of level lines - string &descriptions[], // level Descriptions - // - const long chartID = 0, // chart's ID - const string name = "Fibonacci", // object name - const int subWindow = 0, // subwindow index - datetime time1 = 0, // first point time - double price1 = 0, // first point price - datetime time2 = 0, // second point time - double price2 = 0, // second point price - const color clr = clrAqua, // object color - const ENUM_LINE_STYLE style = STYLE_DOT, // object line style - const int width = 1, // object line width - const bool back = false, // in the background - const bool selection = true, // highlight to move - const bool rayRight = false, // object's continuation to the right - const bool hidden = true, // hidden in the object list - const long zOrder = 0 // priority for mouse click -) -{ - // - // set anchor points' coordinates if they are not set ... - ChangeFibonacciEmptyPoints(time1, price1, time2, price2); - - // - // reset the error value ... - ResetLastError(); - - // - // Normalize Name ... - string objName = drawPrefix + "_" + name; - - // - // Create Fibonacci Retracement by the given coordinates ... - if (!ObjectCreate(chartID, name, OBJ_FIBO, subWindow, time1, price1, time2, price2)) - { - // - string message = - __FUNCTION__ + - ": failed to create \"Fibonacci Retracement\"! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // set color ... - ObjectSetInteger(chartID, objName, OBJPROP_COLOR, clr); - - // - // set line style ... - ObjectSetInteger(chartID, objName, OBJPROP_STYLE, style); - - // - // set line width ... - ObjectSetInteger(chartID, objName, OBJPROP_WIDTH, width); - - // - // display in the foreground (false) or background (true) ... - ObjectSetInteger(chartID, objName, OBJPROP_BACK, back); - - // - // enable (true) or disable (false) the mode of highlighting the channel for moving - // when creating a graphical object using ObjectCreate function, the object cannot be - // highlighted and moved by default. Inside this method, selection parameter - // is true by default making it possible to highlight and move the object ... - ObjectSetInteger(chartID, objName, OBJPROP_SELECTABLE, true); - ObjectSetInteger(chartID, objName, OBJPROP_SELECTED, selection); - - // - // enable (true) or disable (false) the mode of continuation of the object's display to the right ... - ObjectSetInteger(chartID, objName, OBJPROP_RAY_RIGHT, rayRight); - - // - // hide (true) or display (false) graphical object name in the object list ... - ObjectSetInteger(chartID, objName, OBJPROP_HIDDEN, hidden); - - // - // set the priority for receiving the event of a mouse click in the chart ... - ObjectSetInteger(chartID, objName, OBJPROP_ZORDER, zOrder); - - // - // Change Levels Of Fibonacci ... - bool result = FibonacciLevelsSet( - levels, - values, - colors, - styles, - widths, - descriptions, - chartID, - objName); - - // - // successful execution ... - return result; -} - -// -// Set number of levels and their parameters ... -bool FibonacciLevelsSet( - int levels, // number of level lines - double &values[], // values of level lines - color &colors[], // color of level lines - ENUM_LINE_STYLE &styles[], // style of level lines - int &widths[], // width of level lines - string &descriptions[], // level Descriptions - const long chartID = 0, // chart's ID - const string name = "Fibonacci" // object name -) -{ - // - // check array sizes ... - if ( - levels != ArraySize(colors) || - levels != ArraySize(styles) || - levels != ArraySize(widths) || - levels != ArraySize(widths)) - { - // - string message = - __FUNCTION__ + - ": array length does not correspond to the number of levels, error!"; - - // - LogMessage(message); - - // - return (false); - } - - // - // set the number of levels ... - ObjectSetInteger(chartID, name, OBJPROP_LEVELS, levels); - - // - // set the properties of levels in the loop ... - for (int i = 0; i < levels; i++) - { - // - // level value ... - ObjectSetDouble(chartID, name, OBJPROP_LEVELVALUE, i, values[i]); - - // - // level color ... - ObjectSetInteger(chartID, name, OBJPROP_LEVELCOLOR, i, colors[i]); - - // - // level style ... - ObjectSetInteger(chartID, name, OBJPROP_LEVELSTYLE, i, styles[i]); - - // - // level width ... - ObjectSetInteger(chartID, name, OBJPROP_LEVELWIDTH, i, widths[i]); - - // - // level description ... - // ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, DoubleToString(100 * values[i], 1)); - ObjectSetString(chartID, name, OBJPROP_LEVELTEXT, i, descriptions[i]); - } - - // - // successful execution ... - return (true); -} - -// -// Move Fibonacci Retracement anchor point ... -bool FibonacciPointChange( - const long chartID = 0, // chart's ID - const string name = "Fibonacci", // object name - const int pointIndex = 0, // anchor point index - datetime time = 0, // anchor point time coordinate - double price = 0 // anchor point price coordinate -) -{ - // - // if point position is not set, move it to the current bar having Bid price ... - if (!time) - { - time = TimeCurrent(); - } - - // - if (!price) - { - price = SymbolInfoDouble(_Symbol, SYMBOL_BID); - } - - // - // reset the error value ... - ResetLastError(); - - // - // move the anchor point ... - if (!ObjectMove(chartID, name, pointIndex, time, price)) - { - // - string message = - __FUNCTION__ + - ": failed to move the anchor point! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Delete Fibonacci Retracement ... -bool DeleteFibonachi( - const long chartID = 0, // chart's ID - const string name = "Fibonacci" // object name -) -{ - // - // reset the error value ... - ResetLastError(); - - // - // delete the object ... - if (!ObjectDelete(chartID, name)) - { - // - string message = - __FUNCTION__ + - ": failed to delete \"Fibonacci Retracement\"! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution ... - return (true); -} - -// -// Check the values of Fibonacci Retracement anchor points and set -// default values for empty ones ... -void ChangeFibonacciEmptyPoints( - datetime &time1, - double &price1, - datetime &time2, - double &price2) -{ - // - // if the second point's time is not set, it will be on the current bar ... - if (!time2) - { - time2 = TimeCurrent(); - } - - // - // if the second point's price is not set, it will have Bid value ... - if (!price2) - { - price2 = SymbolInfoDouble(_Symbol, SYMBOL_BID); - } - - // - // if the first point's time is not set, it is located 9 bars left from the second one ... - if (!time1) - { - // - // array for receiving the open time of the last 10 bars ... - datetime temp[10]; - CopyTime(Symbol(), Period(), time2, 10, temp); - - // - // set the first point 9 bars left from the second one ... - time1 = temp[0]; - } - - // - // if the first point's price is not set, move it 200 points below the second one ... - if (!price1) - { - price1 = price2 - 200 * SymbolInfoDouble(_Symbol, SYMBOL_POINT); - } -} -// -// END Fibonacci Functions ... -// - -// -// START Event Functions ... -// - -// -// Create an Event ... -bool EventCreate( - const long chartID = 0, // chart's ID - const string name = "Event", // object name - const int subWindow = 0, // subwindow index - const string text = "Content", // event text - datetime time = 0, // anchor point time - const color clr = clrRed, // color - const int width = 1, // point width when highlighted - const bool back = false, // in the background - const bool selection = false, // highlight to move - const bool hidden = true, // hidden in the object list - const long zOrder = 0 // priority for mouse click -) -{ - // - if (!time) - { - time = TimeCurrent(); - } - - // - ResetLastError(); - - // - if (!ObjectCreate(chartID, name, OBJ_EVENT, subWindow, time, 0)) - { - // - string message = - __FUNCTION__ + - ": failed to create \"Event\" object! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // set event text - ObjectSetString(chartID, name, OBJPROP_TEXT, text); - - // - // set color - ObjectSetInteger(chartID, name, OBJPROP_COLOR, clr); - - // - // set anchor point width if the object is highlighted - ObjectSetInteger(chartID, name, OBJPROP_WIDTH, width); - - // - // display in the foreground (false) or background (true) - ObjectSetInteger(chartID, name, OBJPROP_BACK, back); - - // - // enable (true) or disable (false) the mode of moving event by mouse - ObjectSetInteger(chartID, name, OBJPROP_SELECTABLE, selection); - ObjectSetInteger(chartID, name, OBJPROP_SELECTED, selection); - - // - // hide (true) or display (false) graphical object name in the object list - ObjectSetInteger(chartID, name, OBJPROP_HIDDEN, hidden); - - // - // set the priority for receiving the event of a mouse click in the chart - ObjectSetInteger(chartID, name, OBJPROP_ZORDER, zOrder); - - // - // successful execution - return (true); -} - -// -// Change Event object text -bool EventTextChange( - const long chartID = 0, // chart's ID - const string name = "Event", // event name - const string text = "Content" // text -) -{ - // - // reset the error value - ResetLastError(); - - // - // change object text - if (!ObjectSetString(chartID, name, OBJPROP_TEXT, text)) - { - // - string message = - __FUNCTION__ + - ": failed to change the text! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution - return (true); -} - -// -// Move Event object -bool EventMove( - const long chartID = 0, // chart's ID - const string name = "Event", // event name - datetime time = 0 // time -) -{ - // - // if time is not set, move event to the last bar - if (!time) - { - time = TimeCurrent(); - } - - // - // reset the error value - ResetLastError(); - - // - // move the object - if (!ObjectMove(chartID, name, 0, time, 0)) - { - // - string message = - __FUNCTION__ + - ": failed to move \"Event\" object! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution - return (true); -} - -// -// Delete Event object -bool EventDelete( - const long chartID = 0, // chart's ID - const string name = "Event" // event name -) -{ - // - // reset the error value - ResetLastError(); - - // - // delete the object - if (!ObjectDelete(chartID, name)) - { - // - string message = - __FUNCTION__ + - ": failed to delete \"Event\" object! Error code = " + - (string)GetLastError(); - - // - LogMessage(message); - - // - return (false); - } - - // - // successful execution - return (true); -} - -// -// END Event Functions ... -// - -// -// END Regular Draws ... -// - -// -// START Chart Style Drawers ... -// -// -// Apply Styles On Chart ... -void ApplyChartStyle( - int chartId = -1, // chart's ID - ENUM_CHART_MODE mode = CHART_CANDLES, // chart's mode - bool showBidLine = true, // show bid line - bool showAskLine = true, // show ask line - bool showGrid = false, // show grids on chart - bool showVolumes = false, // show volumes - bool showTradeLevels = true, // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders) - bool autoScroll = true, // chart autoscroll - bool quickNavigation = true, // chart quick navigation state - color foreGroundColor = clrWhite, // chart's foreground color - color backGroundColor = clrBlack, // chart's background color - color upColor = clrGreen, // Up Color - color downColor = clrRed, // Down Color - color bullishColor = clrGreen, // Bullish color - color bearishColor = clrRed, // Bearish color - color gridColor = clrGray, // grid color - color bidLineColor = clrGray, // bid line color - color askLineColor = clrRed, // ask line color - color lineColor = clrLime, // line mode and doji candlestick color - color stopColor = clrGold, // Color of stop order levels (Stop Loss and Take Profit) - color volumesColor = clrGreen // volumes color -) -{ - // - // Validate Args ... - if (chartId == -1) - { - chartId = 0; - } - - // - ChartSetInteger(chartId, CHART_MODE, mode); - ChartSetInteger(chartId, CHART_SHOW_BID_LINE, showBidLine); - ChartSetInteger(chartId, CHART_SHOW_ASK_LINE, showAskLine); - ChartSetInteger(chartId, CHART_SHOW_GRID, showGrid); - ChartSetInteger(chartId, CHART_SHOW_VOLUMES, showVolumes); - ChartSetInteger(chartId, CHART_SHOW_TRADE_LEVELS, showTradeLevels); - ChartSetInteger(chartId, CHART_AUTOSCROLL, autoScroll); - ChartSetInteger(chartId, CHART_QUICK_NAVIGATION, quickNavigation); - ChartSetInteger(chartId, CHART_COLOR_FOREGROUND, foreGroundColor); - ChartSetInteger(chartId, CHART_COLOR_BACKGROUND, backGroundColor); - ChartSetInteger(chartId, CHART_COLOR_CHART_UP, upColor); - ChartSetInteger(chartId, CHART_COLOR_CHART_DOWN, downColor); - ChartSetInteger(chartId, CHART_COLOR_CANDLE_BULL, bullishColor); - ChartSetInteger(chartId, CHART_COLOR_CANDLE_BEAR, bearishColor); - ChartSetInteger(chartId, CHART_COLOR_GRID, gridColor); - ChartSetInteger(chartId, CHART_COLOR_BID, bidLineColor); - ChartSetInteger(chartId, CHART_COLOR_ASK, askLineColor); - ChartSetInteger(chartId, CHART_COLOR_STOP_LEVEL, stopColor); - ChartSetInteger(chartId, CHART_COLOR_CHART_LINE, lineColor); - ChartSetInteger(chartId, CHART_COLOR_VOLUME, volumesColor); -} -// -// END Chart Style Drawers ... -// \ No newline at end of file diff --git a/Libraries/x-saherelm.http.lib.mq5 b/Libraries/x-saherelm.http.lib.mq5 deleted file mode 100644 index 97f7ac0a..00000000 --- a/Libraries/x-saherelm.http.lib.mq5 +++ /dev/null @@ -1,177 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Http Library -// ------------------------------------------ -// Name: XHttp -// Description: provide http communication -// abilities ... -// -// -// Maintainer: -// ------------ -// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) -// -////////////////////////////////////////////////////// -// -// Global Properties ... -#property library -#property copyright "Copyright 2023, SaherElm IT Center" -#property link "https://www.saherelm.ir" -#property version "1.00" -#property strict - -// -// START Model Definition ... -// -enum X_HTTP_METHOD -{ - X_HTTP_GET, - X_HTTP_POST -}; -// -// END Model Definition ... -// - -// -// START Inputs ... -// -// -// END Inputs ... -// - -// -// START Global Definitions: Variables, Properties and etc ... -// -// -// END Global Definitions: Variables, Properties and etc ... -// - -// -// START Provided Functions ... -// -// -// Initial Library if required ... -bool OnInInitHttpLibrary() -{ - return false; -} - -// -// DeInitial Library if required ... -void OnDeinitHttpLibrary() -{ -} - -// -// Convert enum to String ... -string ToString(X_HTTP_METHOD method) -{ - // - string result = ""; - - // - switch (method) - { - // - case X_HTTP_GET: - result = "GET"; - break; - - // - case X_HTTP_POST: - result = "POST"; - break; - } - - // - return result; -} - -// -// Send Global Request ... -int SendRequest( - X_HTTP_METHOD method, // Httm Request Method - const string url, // Server Address - const string headers, // Headers providing - const char &payload[], // the Data which needs to Send - char &response[], // Response of request - string responseHeaders, // Response Headers - int timeout = 500 // Timeout for response default is 500 -) -{ - // - int result = -1; - - // - string strMethod = ToString(method); - if (StringLen(strMethod) == 0) { - return result; - } - - // - result = WebRequest( - strMethod, - url, - headers, - timeout, - payload, - response, - responseHeaders - ); - - // - return result; -} - -// -// Get Request ... -int GetRequest( - const string url, // Server Address - const string headers, // Headers providing - const char &payload[], // the Data which needs to Send - char &response[], // Response of request - string responseHeaders, // Response Headers - int timeout = 500 // Timeout for response default is 500 -) { - // - int result = SendRequest( - X_HTTP_GET, - url, - headers, - payload, - response, - responseHeaders, - timeout - ); - - // - return result; -} - -// -// Post Request ... -int PostRequest( - const string url, // Server Address - const string headers, // Headers providing - const char &payload[], // the Data which needs to Send - char &response[], // Response of request - string responseHeaders, // Response Headers - int timeout = 500 // Timeout for response default is 500 -) { - // - int result = SendRequest( - X_HTTP_POST, - url, - headers, - payload, - response, - responseHeaders, - timeout - ); - - // - return result; -} -// -// END Provided Functions ... -// diff --git a/Libraries/x-saherelm.log.lib.mq5 b/Libraries/x-saherelm.log.lib.mq5 deleted file mode 100644 index 70f1bda4..00000000 --- a/Libraries/x-saherelm.log.lib.mq5 +++ /dev/null @@ -1,261 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Logger Library -// --------------------------------------- -// Name: XLogger -// Description: provides Logging abilities ... -// -// -// Maintainer: -// ------------ -// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) -// -////////////////////////////////////////////////////// -// -// Global Properties ... -#property library -#property copyright "Copyright 2023, SaherElm IT Center" -#property link "https://www.saherelm.ir" -#property version "1.00" -#property strict - -// -// START Inputs ... -// -input group "Logging"; -input bool enableLogging = true; // Enable Logging -// -// END Inputs ... -// - -// -// Including Models ... -#include "x-saherelm.models.lib.mq5" - -// -// START Global Definitions: Variables, Properties and etc ... -// -string logTag = "X-Logger"; // LogTag -// -// END Global Definitions: Variables, Properties and etc ... -// - -// -// START Provided Functions ... -// -// -// Logging a Message ... -void LogMessage(string message) -{ - // - if (!enableLogging) - { - return; - } - - // - Print(logTag, " > ", message); -} -void LogMessage(string tag, string message) -{ - // - if (!enableLogging) - { - return; - } - - // - Print(tag, " > ", message); -} - -// -// Logging an Array ... -void LogArray(int &array[]) -{ - // - if (!enableLogging) - { - return; - } - - // - Print(logTag, ">"); - ArrayPrint(array); -} -void LogArray(double &array[]) -{ - // - if (!enableLogging) - { - return; - } - - // - Print(logTag, ">"); - ArrayPrint(array); -} -void LogArray(string &array[]) -{ - // - if (!enableLogging) - { - return; - } - - // - Print(logTag, ">"); - ArrayPrint(array); -} - -// -// Convert a Signal to String Message ... -string SignalToString(const XSignal &signal) -{ - // - string result = "\n"; - - // - result += "Signal: " + "\n"; - result += "id: " + (string)signal.id + "\n"; - result += "symbol: " + signal.symbol + "\n"; - result += "type: " + EnumToString(signal.type) + "\n"; - result += "magicNumber: " + (string)signal.magicNumber + "\n"; - result += "ticket: " + (string)signal.ticket + "\n"; - result += "entry: " + (string)signal.entry + "\n"; - result += "tp: " + (string)signal.tp + "\n"; - result += "sl: " + (string)signal.sl + "\n"; - result += "riskFreeStep: " + (string)signal.riskFreeStep + "\n"; - result += "riskFreeRate: " + (string)signal.riskFreeRate + "\n"; - result += "profit: " + (string)signal.profit + "\n"; - result += "time: " + (string)signal.time + "\n"; - result += "volume: " + (string)signal.volume + "\n"; - result += "comment: " + signal.comment + "\n"; - - // - return result; -} - -// -// Convert an Executed Signal to String Message ... -string ExecutedSignalToString(const XSignal &signal) -{ - // - string result = ""; - - // - result += (signal.type == X_SIGNAL_LONG ? "Buy" : "Sell") + " Signal Executed provided on (" + signal.symbol + " _ " + EnumToString(_Period) + ") by this comment: " + signal.comment; - - // - return result; -} - -// -// Logging Signal ... -void LogSignal(const XSignal &signal) -{ - // - string message = SignalToString(signal); - - // - LogMessage(message); -} - -// -// Log Signal Execution ... -void LogExecutedSignal(const XSignal &signal) -{ - // - string message = ExecutedSignalToString(signal); - - // - LogMessage(message); -} - -// -// Convert a Deal to String ... -string DealToString(const XDeal &deal) -{ - // - string result = "\n"; - - // - result += "Deal:" + "\n"; - result += " " + "\n"; - result += "time: " + (string)deal.time + "\n"; - result += "ticket: " + (string)deal.ticket + "\n"; - result += "order: " + (string)deal.order + "\n"; - result += "positionId: " + (string)deal.positionId + "\n"; - result += "type: " + EnumToString(deal.type) + "\n"; - result += "entry: " + EnumToString(deal.entry) + "\n"; - result += "reason: " + EnumToString(deal.reason) + "\n"; - result += "symbol: " + deal.symbol + "\n"; - result += "price: " + (string)deal.price + "\n"; - result += "profit: " + (string)deal.profit + "\n"; - result += "swap: " + (string)deal.swap + "\n"; - result += "commission: " + (string)deal.commission + "\n"; - result += "volume: " + (string)deal.volume + "\n"; - result += "comment: " + deal.comment + "\n"; - - // - return result; -} - -// -// Log Specific Deal ... -void LogDeal(const XDeal &deal) -{ - // - string message = DealToString(deal); - - // - LogMessage(message); -} - -// -// Convert an Order to String ... -string OrderToString(const XOrder &order) -{ - // - string result = "\n"; - - // - result += "Order: " + "\n"; - result += "magic: " + (string)order.magic + "\n"; - result += "positionId: " + (string)order.positionId + "\n"; - result += "symbol: " + (string)order.symbol + "\n"; - result += "ticket: " + (string)order.ticket + "\n"; - result += "timeSetup: " + (string)order.timeSetup + "\n"; - result += "timeDone: " + (string)order.timeDone + "\n"; - result += "timeExpiration: " + (string)order.timeExpiration + "\n"; - result += "priceOpen: " + (string)order.priceOpen + "\n"; - result += "priceCurrent: " + (string)order.priceCurrent + "\n"; - result += "priceStopLimit: " + (string)order.priceStopLimit + "\n"; - result += "stopLoss: " + (string)order.stopLoss + "\n"; - result += "takeProfit: " + (string)order.takeProfit + "\n"; - result += "volumeInitial: " + (string)order.volumeInitial + "\n"; - result += "volumeCurrent: " + (string)order.volumeCurrent + "\n"; - result += "comment: " + order.comment + "\n"; - result += "type: " + EnumToString(order.type) + "\n"; - result += "state: " + EnumToString(order.state) + "\n"; - result += "typeFilling: " + EnumToString(order.typeFilling) + "\n"; - result += "typeTime: " + EnumToString(order.typeTime) + "\n"; - result += "reason: " + EnumToString(order.reason) + "\n"; - - // - return result; -} - -// -// Log Specific Order ... -void LogOrder(const XOrder &order) -{ - // - string message = OrderToString(order); - - // - LogMessage(message); -} - -// -// END Provided Functions ... -// diff --git a/Libraries/x-saherelm.models.lib.mq5 b/Libraries/x-saherelm.models.lib.mq5 deleted file mode 100644 index b98ae3e8..00000000 --- a/Libraries/x-saherelm.models.lib.mq5 +++ /dev/null @@ -1,438 +0,0 @@ -/////////////////////////////////////////////////////// -// -// SaherElm IT Center MQL5 Models Library -// --------------------------------------- -// Name: XModels -// Description: provides all required models ... -// -// -// Maintainer: -// ------------ -// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) -// -////////////////////////////////////////////////////// -// -// Global Properties ... -#property library -#property copyright "Copyright 2023, SaherElm IT Center" -#property link "https://www.saherelm.ir" -#property version "1.00" -#property strict - -// -// START Inputs ... -// -// -// END Inputs ... -// - -// -// START Global Definitions: Variables, Properties and etc ... -// -// -// END Global Definitions: Variables, Properties and etc ... -// - -// -// START Provided Functions ... -// - -// -// How To Calculate Static Volume ... -enum ENUM_STATIC_VOLUME_METHODS -{ - // - // Based On Deposit ... - X_STATIC_VOLUME_BASED_ON_DEPOSIT, - // - // Based On Balance ... - X_STATIC_VOLUME_BASED_ON_BALANCE, -}; - -// -// START Model Definitions ... -// -// -// OHCL Candel Model ... -enum ENUM_X_PRICE -{ - X_PRICE_HIGH, - X_PRICE_OPEN, - X_PRICE_CLOSE, - X_PRICE_LOW -}; - -// -// Describe an Specific Candle ... -struct XOHCL -{ - double high; - double open; - double close; - double low; -}; - -// -// Swing Types Enum ... -enum ENUM_X_SWING_TYPE -{ - X_NO_SWING = 0, - X_SWING_HIGH = 1, - X_SWING_LOW = -1, -}; - -// -// XTrader Execution Signal Result ... -enum ENUM_EXECUTION_SIGNAL_RESULT -{ - // - X_TRADER_UNKNOWN_ERROR, - X_TRADER_SUCCEED_EXECUTION, - X_TRADER_INVALID_SIGNAL_ERROR, - X_TRADER_NOT_ENOUGH_EQUITY_ERROR, - X_TRADER_MAX_TRADES_REACHED_ERROR, - X_TRADER_NOT_ENOUGH_BALANCE_ERROR, - X_TRADER_NOT_ENOUGH_MARIGIN_ERROR - // -}; - -// -// Signal Types ... -enum ENUM_X_SIGNAL_TYPE -{ - X_SIGNAL_LONG, - X_SIGNAL_SHORT, - X_SIGNAL_UNKNOWN, -}; - -// -// Signal Structure ... -struct XSignal -{ - // - // Identifier ... - ulong id; - - // - // Which Symbol used for Signal ... - string symbol; - - // - // Which Type of operations ... - ENUM_X_SIGNAL_TYPE type; - - // - // Magic Number ... - ulong magicNumber; - - // - // Ticket ... - ulong ticket; - - // - // Entry/Open Price ... - double entry; - - // - // TP ... - double tp; - - // - // SL ... - double sl; - - // - // Make Risk Free Trade on this Value if provided ... - double riskFreeStep; - - // - // a Multiplier for determines how much trade volume exit on risk free time ... - double riskFreeRate; - - // - // Trade Profit ... - double profit; - - // - // Time of Operation ... - datetime time; - - // - // Volume ... - double volume; - - // - // Comment ... - string comment; -}; - -// -// Signal Additional Info ... -struct XProvidedSignal -{ - // - // Suggested TP ... - double tp; - - // - // Suggested SL ... - double sl; - - // - // Signallers ... - string signallers[]; -}; - -// -// Model Specific Deal ... -struct XDeal -{ - // - // the ID of the Expert Advisor, that executed the deal ... - ulong magic; - - // - // the ID of position, in which the deal was involved ... - ulong positionId; - - // - // Ticket ... - ulong ticket; - - // - // the name of the deal symbol ... - string symbol; - - // - // order by which the deal is executed ... - ulong order; - - // - // the time of deal execution ... - datetime time; - - // - // Deal price ... - double price; - - // - // the financial result of the deal (in deposit currency) ... - double profit; - - // - // the amount of swap when position is closed ... - double swap; - - // - // the amount of commission of the deal ... - double commission; - - // - // the volume of deal ... - double volume; - - // - // the deal comment ... - string comment; - - // - // the deal type ... - // ------------------------------------------------------------------ - // DEAL_TYPE_BUY => Buy ... - // DEAL_TYPE_SELL => Sell ... - // DEAL_TYPE_BUY_CANCELED => Canceled buy deal ... - // There can be a situation when a previously executed buy deal is canceled. In this case, - // the type of the previously executed deal (DEAL_TYPE_BUY) is changed to DEAL_TYPE_BUY_CANCELED, - // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation ... - // - // DEAL_TYPE_SELL_CANCELED => Canceled sell deal ... - // There can be a situation when a previously executed sell deal is canceled. In this case, - // the type of the previously executed deal (DEAL_TYPE_SELL) is changed to DEAL_TYPE_SELL_CANCELED, - // and its profit/loss is zeroized. Previously obtained profit/loss is charged/withdrawn using a separated balance operation - // - // DEAL_TYPE_BALANCE => Balance ... - // DEAL_TYPE_CREDIT => Credit ... - // DEAL_TYPE_CHARGE => Additional charge ... - // DEAL_TYPE_CORRECTION => Correction ... - // DEAL_TAX => Tax charges ... - // DEAL_TYPE_BONUS => Bonus ... - // DEAL_TYPE_INTEREST => Interest rate ... - // DEAL_DIVIDEND => Dividend operations... - // DEAL_DIVIDEND_FRANKED => Franked (non-taxable) dividend operations ... - // DEAL_TYPE_COMMISSION => Additional commission ... - // DEAL_TYPE_COMMISSION_DAILY => Daily commission ... - // DEAL_TYPE_COMMISSION_MONTHLY => Monthly commission ... - // DEAL_TYPE_COMMISSION_AGENT_DAILY => Daily agent commission ... - // DEAL_TYPE_COMMISSION_AGENT_MONTHLY => Monthly agent commission - ENUM_DEAL_TYPE type; - - // - // the deal direction ... - // ---------------------------------- - // DEAL_ENTRY_IN => Entry in ... - // DEAL_ENTRY_OUT => Entry out ... - // DEAL_ENTRY_INOUT => Reverse ... - // DEAL_ENTRY_OUT_BY => Close a position by an opposite one ... - ENUM_DEAL_ENTRY entry; - - // - // deal reson ... - // --------------------- - // DEAL_REASON_SL => The deal was executed as a result of Stop Loss activation ... - // DEAL_REASON_TP => The deal was executed as a result of Take Profit activation ... - // DEAL_REASON_SO => The deal was executed as a result of the Stop Out event ... - // DEAL_REASON_WEB => The deal was executed as a result of activation of an order placed from the web platform ... - // DEAL_REASON_SPLIT => The deal was executed after the split (price reduction) of an instrument, which had an open position during split announcement ... - // DEAL_REASON_CLIENT => The deal was executed as a result of activation of an order placed from a desktop terminal ... - // DEAL_REASON_MOBILE => The deal was executed as a result of activation of an order placed from a mobile application ... - // DEAL_REASON_EXPERT => The deal was executed as a result of activation of an order placed from an MQL5 program, i.e. an Expert Advisor or a script ... - // DEAL_REASON_VMARGIN => The deal was executed after charging the variation margin ... - // DEAL_REASON_ROLLOVER => The deal was executed due to a rollover ... - ENUM_DEAL_REASON reason; -}; - -// -// Model Specific Order ... -struct XOrder -{ - // - // the ID of expert that placed the order ... - ulong magic; - - // - // the ID of position ... - ulong positionId; - - // - // the name of order symbol ... - string symbol; - - // - // the ticket of an order, previously selected for access ... - ulong ticket; - - // - // the time of order placement ... - datetime timeSetup; - - // - // the time of order execution or cancellation ... - datetime timeDone; - - // - // the order expiration time ... - datetime timeExpiration; - - // - // the order price ... - double priceOpen; - - // - // the current price by order symbol ... - double priceCurrent; - - // - // the price of a pending order ... - double priceStopLimit; - - // - // the order's Stop Loss ... - double stopLoss; - - // - // the order's Take Profit ... - double takeProfit; - - // - // the initial volume of order ... - double volumeInitial; - - // - // the unfilled volume of order ... - double volumeCurrent; - - // - // the order comment ... - string comment; - - // - // the order type ... - // -------------------- - // ORDER_TYPE_BUY => Market Buy order ... - // ORDER_TYPE_SELL => Market Sell order ... - // ORDER_TYPE_BUY_LIMIT => Buy Limit pending order ... - // ORDER_TYPE_SELL_LIMIT => Sell Limit pending order ... - // ORDER_TYPE_BUY_STOP => Buy Stop pending order ... - // ORDER_TYPE_SELL_STOP => Sell Stop pending order ... - // ORDER_TYPE_BUY_STOP_LIMIT => Upon reaching the order price, a pending Buy Limit order is placed at the StopLimit price ... - // ORDER_TYPE_SELL_STOP_LIMIT => Upon reaching the order price, a pending Sell Limit order is placed at the StopLimit price ... - // ORDER_TYPE_CLOSE_BY => Order to close a position by an opposite one ... - ENUM_ORDER_TYPE type; - - // - // the order state ... - // -------------------------- - // ORDER_STATE_STARTED => Order checked, but not yet accepted by broker ... - // ORDER_STATE_PLACED => Order accepted ... - // ORDER_STATE_CANCELED => Order canceled by client ... - // ORDER_STATE_PARTIAL => Order partially executed ... - // ORDER_STATE_FILLED => Order fully executed ... - // ORDER_STATE_REJECTED => Order rejected ... - // ORDER_STATE_EXPIRED => Order expired ... - // ORDER_STATE_REQUEST_ADD => Order is being registered (placing to the trading system) - // ORDER_STATE_REQUEST_MODIFY => Order is being modified (changing its parameters) ... - // ORDER_STATE_REQUEST_CANCEL => Order is being deleted (deleting from the trading system) ... - ENUM_ORDER_STATE state; - - // - // the order filling type ... - // ---------------------------- - // ORDER_FILLING_FOK => Fill or Kill - // An order can be executed in the specified volume only. - // If the necessary amount of a financial instrument is currently unavailable in the market, - // the order will not be executed. - // The desired volume can be made up of several available offers. - // The possibility of using FOK orders is determined at the trade server. - // ORDER_FILLING_IOC => Immediate or Cancel - // A trader agrees to execute a deal with the volume maximally available in the market within that indicated in the order. - // If the request cannot be filled completely, an order with the available volume will be executed, - // and the remaining volume will be canceled. - // The possibility of using IOC orders is determined at the trade server. - // ORDER_FILLING_BOC => Passive (Book or Cancel) - // The BoC order assumes that the order can only be placed in the Depth of Market and cannot be immediately executed. - // If the order can be executed immediately when placed, then it is canceled. - // In fact, the BOC policy guarantees that the price of the placed order will be worse than - // the current market. BoC orders are used to implement passive trading, - // so that the order is not executed immediately when placed and does not affect current liquidity. - // Only limit and stop limit orders are supported (ORDER_TYPE_BUY_LIMIT, ORDER_TYPE_SELL_LIMIT, ORDER_TYPE_BUY_STOP_LIMIT, ORDER_TYPE_SELL_STOP_LIMIT). - // ORDER_FILLING_RETURN => Return - // In case of partial filling, an order with remaining volume is not canceled but processed further. - // Return orders are not allowed in the Market Execution - // mode (market execution — SYMBOL_TRADE_EXECUTION_MARKET). - ENUM_ORDER_TYPE_FILLING typeFilling; - - // - // the type of order at the time of the expiration ... - // -------------------------------------------------------- - // ORDER_TIME_GTC => Good till cancel order ... - // ORDER_TIME_DAY => Good till current trade day order ... - // ORDER_TIME_SPECIFIED => Good till expired order ... - // ORDER_TIME_SPECIFIED_DAY => The order will be effective till 23:59:59 of the specified day. - // If this time is outside a trading session, the order expires in the nearest trading time ... - ENUM_ORDER_TYPE_TIME typeTime; - - // - // The reason for order placing ... - // -------------------------------------- - // ORDER_REASON_SL => The order was placed as a result of Stop Loss activation ... - // ORDER_REASON_TP => The order was placed as a result of Take Profit activation ... - // ORDER_REASON_SO => The order was placed as a result of the Stop Out event ... - // ORDER_REASON_WEB => The order was placed from a web platform ... - // ORDER_REASON_CLIENT => The order was placed from a desktop terminal ... - // ORDER_REASON_MOBILE => The order was placed from a mobile application ... - // ORDER_REASON_EXPERT => The order was placed from an MQL5-program, i.e. by an Expert Advisor or a script ... - ENUM_ORDER_REASON reason; -}; -// -// END Provided Functions ... -//