/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XSCBaseEA // Description: provides all Base EA requirements ... // // // 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 // // Imports ... #include "../Classes/x-saherelm.xalert.class.mq5" #include "../Classes/x-saherelm.xtrade.class.mq5" // // Define On Signal Event Handler Type ... typedef void (*TOnSignal)(XSignal &signal); // // Class Definition ... class XSCBaseEA : public XSCBaseAlert { // // Public ... public: // // Props ... // // Constructor ... XSCBaseEA( // // XTrade Class Requirements ... int slippage, // Specify Slippage ulong magicNumber, // Specify Magic Number // // Event Handlers ... TOnSignal onSignal = NULL, // On Signal Recieved Event Handler TOnModify onModifyPosition = NULL, // On Modify Position Event Handler TOnStopLoss onStopLossTriggered = NULL, // On StopLoass Triggered Event Handler TOnTakeProfit onTakeProfitTriggered = NULL, // On TakeProfit Triggered Event Handler TOnForceClose onForceClosePosition = NULL, // On Force Close Position Event Handler TOnPartialClose onPartialClosePosition = NULL, // On Partial Close Position Event Handler TOnDealsChanged onDealsChangedHandler = NULL, // On Deals Changed Event Handler TOnOrdersChanged onOrdersChangedHandler = NULL, // On Orders Changed Event Handler TOnPositionsChanged onPositionsChangedHandler = NULL, // On Positions Changed Event Handler TOnTradeStateChanged onTradeStateChangedHandler = NULL // On Trade State Changed Event Handler ) { // // Instance XSCTrade Class ... mTrader = new XSCTrade( slippage, magicNumber // ); // mIsInTestMode = IsRunningOnTestMode(); mStaticBalanceForCalculateDrawdown = 0; // Ignore ... // // Set Event Handlers ... mOnSignal = onSignal; mOnModifyPosition = onModifyPosition; mOnStopLossTriggered = onStopLossTriggered; mOnForceClosePosition = onForceClosePosition; mOnTakeProfitTriggered = onTakeProfitTriggered; mOnDealsChangedHandler = onDealsChangedHandler; mOnPartialClosePosition = onPartialClosePosition; mOnOrdersChangedHandler = onOrdersChangedHandler; mOnPositionsChangedHandler = onPositionsChangedHandler; mOnTradeStateChangedHandler = onTradeStateChangedHandler; // if (mOnSignal != NULL) { AddOnSignalEventHandler(mOnSignal); } // if (mOnModifyPosition != NULL) { mTrader.AddOnModifyPositionEventHandler(mOnModifyPosition); } // if (mOnForceClosePosition != NULL) { mTrader.AddOnForceClosePositionEventHandler(mOnForceClosePosition); } // if (mOnPartialClosePosition != NULL) { mTrader.AddOnPartialClosePositionEventHandler(mOnPartialClosePosition); } // if (mOnStopLossTriggered != NULL) { mTrader.AddOnStopLossEventHandler(mOnStopLossTriggered); } // if (mOnTakeProfitTriggered != NULL) { mTrader.AddOnTakeProfitEventHandler(mOnTakeProfitTriggered); } // if (mOnDealsChangedHandler != NULL) { mTrader.AddOnDealsChangedEventHandler(mOnDealsChangedHandler); } // if (mOnOrdersChangedHandler != NULL) { mTrader.AddOnOrdersChangedEventHandler(mOnOrdersChangedHandler); } // if (mOnPositionsChangedHandler != NULL) { mTrader.AddOnPositionsChangedEventHandler(mOnPositionsChangedHandler); } // if (mOnTradeStateChangedHandler != NULL) { mTrader.AddOnTradeStateChangedEventHandler(mOnTradeStateChangedHandler); } } // // Deconstractor ... ~XSCBaseEA() { // delete mTrader; } // // Properties Getter(s) / Setter(s) ... // // Retrieve Slippage ... int GetSlippage() { return mTrader.GetSlippage(); } // // Retrieve Magic Number ... ulong GetMagicNumber() { return mTrader.GetMagicNumber(); } // double GetDrawdownPercent() { return mDrawdownPercent; } // void AddOnSignalEventHandler(TOnSignal handler) { // Add( handler, mOnSignalEventHandlers // ); } // double MinRequiredProfitPerTrade() { return mMinRequiredProfitPerTrade; } // void MinRequiredProfitPerTrade(double value) { // if (value < 0) { value = 0; } // mMinRequiredProfitPerTrade = value; } // double MinRequiredProfitPerVolumeFactor() { return mMinRequiredProfitPerVolumeFactor; } // void MinRequiredProfitPerVolumeFactor(double value) { // if (value < 0) { value = 0; } // if (value > 0 && value < 0.01) { value = 0.01; } // mMinRequiredProfitPerVolumeFactor = value; } // int RestingAfterHedge() { return mRestingAfterHedge; } // void RestingAfterHedge(int value) { // if (value < 0) { value = 0; } // mRestingAfterHedge = value; } // // Overrides ... // // Customize Token ... virtual string GetToken() { return GetSpecificToken(this); } // virtual string GetTag() { return this.GetToken(); } // // Virtual Functions ... // // Handle Chart Events ... virtual void OnChartEvent( const int id, // event ID const long &lparam, // long type event parameter const double &dparam, // double type event parameter const string &sparam // string type event parameter ) { } // // OnTick Handler ... virtual void OnTick() { // CalculateMaxDrawdown(); // // Draw ... Draw(); // // Check Trade Events ... OnTrade(); // SyncSupports(); // // First Check For Any Guard Actions ... // then Handle Guards if Provided ... XGuard guards[]; bool hasGuard = CheckForGuard(guards); if (hasGuard) { DoGuards(guards); } // XSignal signals[]; // // Second Check for Position Management or Equity Management // Actions like Supports or etc ... bool isIgnored = HandleStateManagement(signals); if (isIgnored) { return; } // // Second Check For Signals ... // then Execute Signals if Provided ... int signalsCount = RequestForSignal(signals); if (signalsCount <= 0) { return; } // // Execute Signals ... HandleSignalsExecution(signals); } // // These are Some Event Handler ... // // Calls whenever a signal Executed ... virtual void OnSignalExecuted(const XSignal &signal) {} // // Cals whenever a Signal Execution Failed ... virtual void OnSignalExecutionFailed( const XSignal &signal, const ENUM_X_SIGNAL_EXECUTION_RESULT reason // ) { } // // Calls when a Position Modified ... virtual void OnPositionModified( const XPosition &position, const string comment // ) { } // // Calls when a Position Closed ... virtual void OnPositionClosed( const XPosition &position, const string comment // ) { } // // Calls when a Position Partially Closed ... virtual void OnPositionPartialyClosed( const XPosition &position, const string comment // ) { } // // Handle StopLoss Event ... virtual void OnStopLossTriggered(const XDeal &deal) {} // // Handle TakeProfit Event ... virtual void OnTakeProfitTriggered(const XDeal &deal) {} // // Handle Deals Changed Event ... virtual void OnDealsChangedHandler(int count) {} // // Handle Order Changed Event ... virtual void OnOrdersChangedHandler(int count) {} // // Handle Position Changed Event ... virtual void OnPositionsChangedHandler(int count) {} // // Handle Trade State Changed ... virtual void OnTradeStateChangedHandler(const XOnTradeHandlerState &state) {} // // Handle On Trade ... virtual void OnTrade() { // XOnTradeHandlerState state = mTrader.HandleOnTrade(); // if ( !state.hasNewDeal && !state.hasNewOrder && !state.hasNewPosition && !state.hasNewHistoryOrder) { return; } // // STATE ... // // Notfy Trade State Changed Event ... OnTradeStateChangedHandler(state); // // DEALS ... if (state.hasNewDeal) { // // Notfy Deals Changed Event ... OnDealsChangedHandler(state.newDeals); // // Retrieve Last Deal ... XDeal deals[]; mTrader.GetDeals(deals); int dealsCount = ArraySize(deals); if (dealsCount > 0) { // XDeal lastDeal = deals[0]; // if (lastDeal.reason == DEAL_REASON_TP) { OnTakeProfitTriggered(lastDeal); } else if (lastDeal.reason == DEAL_REASON_SL) { OnStopLossTriggered(lastDeal); } } } // // ORDERS ... if (state.hasNewOrder || state.hasNewHistoryOrder) { // // Notfy Orders Changed Event ... OnOrdersChangedHandler(state.newOrders + state.newHistoryOrders); } // // POSITIONS ... if (state.hasNewPosition) { // // Notfy Positions Changed Event ... OnPositionsChangedHandler(state.newPositions); } } // // Retrieve Dept Of Market ... virtual void OnBookEvent(const string &symbol) { // // TODO: Implement this ... } // // Draw On Chart if anything is required ... virtual void Draw() {} // // Check For any Guard Actions ... virtual bool CheckForGuard(XGuard &guards[]) { return false; } // // When a Guard Notified to Do Support Signal ... // this Method Calls For Retrieve Support Signal ... // if it's Provided, Execute it ... virtual bool RequestForSupport( XSignal &support, // Holds Support Signal, if Provided string provider, // Positions Provided by Specific Provider string symbol, // Trading Symbol ENUM_X_POSITION_TYPES type, // Trading Type ENUM_TIMEFRAMES period // Specified Time Frame ) { return false; } // // Handle Position(s)/ Order(s) or EQM Supporting Action ... // if returns true, prevent for process Tick ... virtual bool HandleStateManagement(XSignal &signals[]) { return false; } // // Regulary Filtered Signals passed to this // and here we can do Additional Signal Filtering // for Signal Management such as (Providers and etc) ... virtual int HandleSignalManagement(XSignal &signals[]) { // int result = ArraySize(signals); // return result; } // // Here we Have to Check Market based // on our Strategy for Trading ... // and if a Good Entry founded ... // model it as an XSignal struct and passed it to result ... virtual int RequestForSignal( XSignal &signals[] // Holds Signals ... ) { return 0; } // // Execute Provided Signals ... virtual void HandleSignalsExecution(XSignal &signals[]) { // int signalsCount = ArraySize(signals); if (signalsCount <= 0) { return; } // int managedSignalsCount = HandleSignalManagement(signals); if (managedSignalsCount <= 0) { return; } // // Notify Signal Event Handlers for Reciving New Signal ... for (int i = 0; i < managedSignalsCount; i++) { NotifyOnSignalEventHandlers(signals[i]); } // // Try to Execute Signals ... ENUM_X_SIGNAL_EXECUTION_RESULT reasons[]; int executedSignalsCount = ExecuteSignals( signals, reasons // ); } // // Protected ... protected: // // Props ... // // Trade Class Instance ... XSCTrade *mTrader; // // Check in Test Mode or not ... bool mIsInTestMode; // // Save Max Drawdown ... double mMaxDrawdown; double mDrawdownPercent; double mStaticBalanceForCalculateDrawdown; // // Calculate Max Drawdown and it's Percent ... void CalculateMaxDrawdown() { // int positionsCount = PositionsTotal(); if (IsValidSize(positionsCount)) { double mEquity = mTrader.mAccount.GetEquity(); if (mEquity > mMaxDrawdown) { mMaxDrawdown = mEquity; } // mDrawdownPercent = (mMaxDrawdown - mEquity) / (mStaticBalanceForCalculateDrawdown > 0 ? mStaticBalanceForCalculateDrawdown : mMaxDrawdown) * 100; mDrawdownPercent = NormalizeDouble(mDrawdownPercent, 3); } else { // mMaxDrawdown = 0.0; mDrawdownPercent = 0.0; } } // // // Tools ... // // Since we need to Calls Some Event Handlers on // - Signal Execution; // - Modified; // - Closed; // - Partial Closed; // events ... // we have to implement thouse Methods here and use them ... // // Execute Stand alone Signal ... bool ExecuteSignal( XSignal &signal, // Signal ENUM_X_SIGNAL_EXECUTION_RESULT &state, // Result bool checkPolicies = true, // Check Account Policies ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime datetime expiration = NULL // order expiration time ) { // bool result = false; // result = mTrader.ExecuteSignal( signal, state, lifetime, expiration, checkPolicies // ); if (result) { // OnSignalExecuted(signal); // string message = "Signal Executed (" + ToString(signal.positionId) + ") Successfully ..."; // Alert(message); } else { // OnSignalExecutionFailed(signal, state); // // // string message = "Signal Execution Failed: " + ToString(state) + " ..."; // // // Alert(message); } // return result; } // // Execute a Collection of Signals ... int ExecuteSignals( XSignal &signals[], // Collection of Signal for Execution ENUM_X_SIGNAL_EXECUTION_RESULT &states[], // Signal Execution Result bool checkPolicies = true, // Check Account Policies ENUM_ORDER_TYPE_TIME lifetime = ORDER_TIME_GTC, // Order LifeTime datetime expiration = NULL // order expiration time ) { // int result = 0; // int signalsCount = ArraySize(signals); if (!IsValidSize(signalsCount)) { return result; } // Clean(states); ArrayResize(states, signalsCount, X_SIGNAL_EXECUTION_UNKNOWN); // for (int i = 0; i < signalsCount; i++) { // bool isExecuted = ExecuteSignal( signals[i], states[i], checkPolicies, lifetime, expiration // ); if (isExecuted) { result++; } } // return result; } // // Modify ... bool Modify( ulong ticket, // position ticket double sl = 0, // stop loss price double tp = 0, // take profit string comment = NULL // comment ) { // bool result = false; // result = mTrader.Modify( ticket, sl, tp, comment // ); // if (result) { // XPosition position; result = mTrader.GetPosition( ticket, position // ); if (result) { // OnPositionModified( position, comment // ); // string message = "Position " + ToString(ticket) + " Modified Successfully ..."; // Alert(message); } } // return result; } // // Close ... bool Close( ulong ticket, string comment // ) { // bool result = false; // XPosition position; result = mTrader.GetPosition( ticket, position // ); // result = mTrader.Close( ticket, comment // ); // if (result) { // OnPositionClosed( position, comment // ); // string message = "Position " + ToString(ticket) + " Closed Successfully ..."; // Alert(message); } // return result; } // // Close ... int Close( XPosition &positions[], string comment // ) { // int result = 0; // int count = ArraySize(positions); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // bool isClosed = Close( positions[i].ticket, comment // ); // if (isClosed) { result++; } } // return result; } // // Partial Close ... bool PartialClose( ulong ticket, double volume, string comment // ) { // bool result = false; // XPosition position; result = mTrader.GetPosition( ticket, position // ); if (!result) { return result; } // result = mTrader.ClosePartial( ticket, volume, comment // ); // if (result) { // OnPositionPartialyClosed( position, comment // ); // string message = "Position " + ToString(ticket) + " Successfully Closed Parital ..."; // Alert(message); } // return result; } // // Partial Close ... int PartialClose( XPosition &positions[], double volume, string comment // ) { // int result = 0; // int count = ArraySize(positions); if (!IsValidSize(count)) { return result; } // for (int i = 0; i < count; i++) { // bool isClosed = PartialClose( positions[i].ticket, volume, comment // ); // if (isClosed) { result++; } } // return result; } // int CancelOrders() { // int result = 0; // XOrder supports[]; int supportsCount = mTrader.GetOrders( supports, NULL, // All Symbols ... XEQMSupportToken, // Only EQM Supports ... NULL, // All Periods ... X_POSITION_TYPE_ALL, // All Order Types ... ORDER_STATE_PLACED, // Untriggered Orders ... true // Filter by Magic ... ); if (!IsValidSize(supportsCount)) { return result; } // result = mTrader.CancelOrders( supports // ); // return result; } // // Search Positions and Remove // non Exists Positions Support Orders ... void SyncSupports() { // XOrder orders[]; int ordersCount = mTrader.GetOrders( orders, NULL, // All Symbols ... NULL, // All Providers ... NULL, // All Periods ... X_POSITION_TYPE_ALL, // All Types ... ORDER_STATE_PLACED, // Placed Untriggered Orders ... true // Filter by Magic ... ); if (!IsValidSize(ordersCount)) { return; } // XPosition positions[]; int positionsCount = mTrader.GetPositions( positions // ); if (!IsValidSize(positions)) { // mTrader.CancelOrders(orders); return; } // XOrder mustCancel[]; for (int i = 0; i < ordersCount; i++) { // XOrder iOrder = orders[i]; // // Check Order is Support or not ... ulong iParentTicket = ExtractSupportedTicket(iOrder.comment); if (iParentTicket <= 0) { continue; } // // We Sure it is support Order ... XPosition parent; bool isParentExists = mTrader.GetPosition( iParentTicket, parent // ); if (!isParentExists) { // AddRef( iOrder, mustCancel // ); } } // int mustCancelCount = ArraySize(mustCancel); if (!IsValidSize(mustCancelCount)) { return; } // mTrader.CancelOrders(mustCancel); } // // Hedging ... // // Check Required Properties Setted for Hedge or not ... bool AllowHedge() { // bool result = false; // result = // mMinRequiredProfitPerTrade > 0 && mMinRequiredProfitPerVolumeFactor > 0 // ; // return result; } // // Check Hedge Conditions is Happens or not ... // if true doing Hedge ... bool DoHedge() { // bool result = false; // result = AllowHedge(); if (!result) { return result; } // XPosition positions[]; int positionsCount = mTrader.GetPositions(positions); result = IsValidSize(positions); if (!result) { return result; } // // Check At Least One Support Positions Open For Hedging ... // XPosition supports[]; // int supportsCount = ExtractSupports( // positions, // supports // // ); // result = IsValidSize(supportsCount); // if (!result) // { // return result; // } // double profits = SpecifiedCalculatePositionsProfit(positions); double requiredProfit = SpecifiedCalculateRequiredProfitForHedge( positions, mMinRequiredProfitPerTrade, mMinRequiredProfitPerVolumeFactor // ); // result = profits >= requiredProfit; if (!result) { return result; } // string comment = XEQMSupportToken + " Hedge ..."; // int closed = Close( positions, comment // ); result = IsValidSize(closed); if (!result) { return result; } // SyncSupports(); // string message = XEQMSupportToken + " Hedge: " + ToString(profits) + " ..."; // Alert(message); // if (mRestingAfterHedge > 0) { Sleep(mRestingAfterHedge * 1000); } // return result; } // // Signal Event Listeners ... // void NotifyOnSignalEventHandlers(XSignal &signal) { // int listenersCount = ArraySize(mOnSignalEventHandlers); if (listenersCount <= 0) { return; } // for (int i = 0; i < listenersCount; i++) { // TOnSignal iListener = mOnSignalEventHandlers[i]; // iListener(signal); } } // // Guards ... // // Do All Provided Guards ... void DoGuards(XGuard &guards[]) { // int guardsCount = ArraySize(guards); if (guardsCount <= 0) { return; } // for (int i = 0; i < guardsCount; i++) { // XGuard iGuard = guards[i]; // switch (iGuard.action) { // // Hedge In Profit Specified Positions ... case X_GUARD_ACTION_HEDGE: HandleGuardHedgeAction( iGuard.provider, iGuard.symbol, iGuard.type, iGuard.period); break; // // Trail Stop Loss in Specified Positions ... case X_GUARD_ACTION_TRAIL_STOP: HandleGuardTrailingStopAction( iGuard.provider, iGuard.symbol, iGuard.type, iGuard.period, iGuard.dblPayLoad); break; // // Force Close Specified Positions ... case X_GUARD_ACTION_FORCE_CLOSE: HandleGuardForceCloseAction( iGuard.provider, iGuard.symbol, iGuard.type, iGuard.period); break; // // Generate and Place Support Signals ... case X_GUARD_ACTION_ADD_SUPPORT_SIGNAL: HandleGuardAddSupportPositionAction( iGuard.provider, iGuard.symbol, iGuard.type, iGuard.period); break; // // Delete All Placed Pending Orders ... case X_GUARD_ACTION_CANCEL_PENDING_ORDERS: HandleGuardCancelPendingOrdersAction( iGuard.provider, iGuard.symbol, iGuard.type, iGuard.period); break; } } } // // Close All Specified Provider's Positions in Profit Summary ... void HandleGuardHedgeAction( string provider, // Positions Provided by Specific Provider string symbol, // Trading Symbol ENUM_X_POSITION_TYPES type, // Trading Type ENUM_TIMEFRAMES period, // Specified Time Frame double minProfitForHedging = 1, // Specified Profit for Hedge double minProfitForHedgingVolumeFactor = 0.01 // Specified Volume Factor for Hedge ) { // XPosition positions[]; int positionsCount = mTrader .GetPositions( positions, symbol, provider, period, type // ); if (positionsCount <= 1) { return; } // double profit = SpecifiedCalculatePositionsProfit(positions); double requiredProfit = SpecifiedCalculateRequiredProfitForHedge( positions, minProfitForHedging, minProfitForHedgingVolumeFactor // ); // bool isReadyForHedge = profit >= requiredProfit; if (!isReadyForHedge) { return; } // string comment = "Guard Hedge " + provider; int closed = mTrader.Close( positions, comment // ); if (closed > 0) { // string message = "Guard Hedge " + provider + "'s Positions on Profit: " + ToString(profit); // Alert(message); } } // // Close Max In Profit Trade Guard Action ... void HandleGuardCloseInProfitAction( string provider, // Positions Provided by Specific Provider string symbol, // Trading Symbol ENUM_X_POSITION_TYPES type, // Trading Type ENUM_TIMEFRAMES period, // Specified Time Frame ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method ) { // XPosition positions[]; int positionsCount = mTrader .GetInProfitPositions( positions, symbol, provider, period, type, method // ); if (positionsCount <= 0) { return; } // string comment = "Close InProfit ..."; mTrader.Close( positions, comment // ); // string message = "Guard Close (" + ToString(positionsCount) + ") Postion(s) In Profit ..."; // Alert(message); } // // Close Max In Drawdown Trade Guard Action ... void HandleGuardCloseInDrawdownAction( string provider, // Positions Provided by Specific Provider string symbol, // Trading Symbol ENUM_X_POSITION_TYPES type, // Trading Type ENUM_TIMEFRAMES period, // Specified Time Frame ENUM_X_POSITION_SELECT_METHODS method = NULL // Select Method ) { // XPosition positions[]; int positionsCount = mTrader .GetInDrawdownPositions( positions, symbol, provider, period, type, method // ); if (positionsCount <= 0) { return; } // string comment = "Close InDrawdown ..."; mTrader.Close( positions, comment // ); // string message = "Guard Close (" + ToString(positionsCount) + ") Position(s) In Drawdown ..."; // Alert(message); } // // Force Close Specified Set Of Position ... void HandleGuardForceCloseAction( string provider, // Positions Provided by Specific Provider string symbol, // Trading Symbol ENUM_X_POSITION_TYPES type, // Trading Type ENUM_TIMEFRAMES period, // Specified Time Frame ulong ticket = 0 // Specific Ticket ) { // string comment = ""; // // Close All Positions ... if (ticket == 0) { // XPosition positions[]; int positionsCount = mTrader.GetPositions( positions, symbol, provider, period, type // ); if (positionsCount <= 0) { return; } // comment = provider + " Force Close Guard ..."; // mTrader.Close( positions, comment // ); } // // Close Specific Position ... else { // XPosition position; bool hasPosition = mTrader .GetPosition( ticket, position // ); // if (hasPosition) { // comment = provider + "(" + ToString(ticket) + ")" + " Force Close Guard ..."; // mTrader.Close( ticket, comment // ); } } // if (IsValid(comment)) { Alert(comment); } } // // Trailing Specified Set Of Positions Stop Losses ... void HandleGuardTrailingStopAction( string provider, // Positions Provided by Specific Provider string symbol, // Trading Symbol ENUM_X_POSITION_TYPES type, // Trading Type ENUM_TIMEFRAMES period, // Specified Time Frame double sl // Desired SL Value ... ) { // if (sl <= 0) { return; } // NormalizePrice( sl, symbol // ); // XPosition positions[]; int positionsCount = mTrader .GetPositions( positions, symbol, provider, period, type // ); if (positionsCount <= 0) { return; } // int modified = 0; for (int i = 0; i < positionsCount; i++) { // XPosition iPosition = positions[i]; // string comment = PrepareSLTrailTag(iPosition.comment); // if (iPosition.sl == sl) { continue; } // bool isModified = mTrader.Modify( iPosition.ticket, sl, iPosition.tp, comment); if (isModified) { modified++; } } // if (modified > 0) { // string message = "(" + ToString(modified) + ") Position's Stop Trailed Successfully ..."; // Alert(message); } } // // Add Support Signal for Specified Positions ... void HandleGuardAddSupportPositionAction( string provider, // Positions Provided by Specific Provider string symbol, // Trading Symbol ENUM_X_POSITION_TYPES type, // Trading Type ENUM_TIMEFRAMES period // Specified Time Frame ) { // XSignal support; bool hasSupport = RequestForSupport( support, provider, symbol, type, period // ); // if (!hasSupport || !support.IsValid()) { return; } // // TODO: May be need to add Support Tag to comments ... // ENUM_X_SIGNAL_EXECUTION_RESULT reason = NULL; bool isExecuted = ExecuteSignal( support, reason // ); // string comment = NULL; if (!isExecuted) { comment = "Support Execution Failed doue " + ToString(reason); } else { comment = "Guard Support Signal Executed Successfully ..."; } // if (IsValid(comment)) { Alert(comment); } } // // Cancel all Placed Orders ... void HandleGuardCancelPendingOrdersAction( string provider, // Positions Provided by Specific Provider string symbol, // Trading Symbol ENUM_X_POSITION_TYPES type, // Trading Type ENUM_TIMEFRAMES period // Specified Time Frame ) { // XOrder orders[]; int ordersCount = mTrader.GetOrders( orders, symbol, provider, period, type, ORDER_STATE_PLACED, true // Filter by Magic ... // ); if (ordersCount <= 0) { return; } // int canceledOrdersCount = mTrader.CancelOrders(orders); // if (canceledOrdersCount > 0) { // string message = "Guard Cancel (" + ToString(canceledOrdersCount) + ") Pending Orders ..."; // Alert(message); } } // // Private ... private: // // Props ... // int mRestingAfterHedge; // Resting Bars After Hedge double mMinRequiredProfitPerTrade; // Minimum Required Profit for Hedging double mMinRequiredProfitPerVolumeFactor; // Minimum Required Profit for Hedging Per Velume // // Signal Event Listeners ... TOnSignal mOnSignalEventHandlers[]; // // Event Handlers ... TOnSignal mOnSignal; TOnModify mOnModifyPosition; TOnStopLoss mOnStopLossTriggered; TOnTakeProfit mOnTakeProfitTriggered; TOnForceClose mOnForceClosePosition; TOnDealsChanged mOnDealsChangedHandler; TOnPartialClose mOnPartialClosePosition; TOnOrdersChanged mOnOrdersChangedHandler; TOnPositionsChanged mOnPositionsChangedHandler; TOnTradeStateChanged mOnTradeStateChangedHandler; }; //