//+------------------------------------------------------------------+ //| CODE GENERATED with Mission Automate v.2.4.9 | //| -------------------------------------------------------------- | //| Code generation date: 2019.08.10 06:56:16 | //| -------------------------------------------------------------- | //| https://www.mql5.com/en/users/wahoo | //| -------------------------------------------------------------- | #property strict #property version "1.0" #property link "https://www.mql5.com/en/users/wahoo" #property copyright "Generated with Mission Automate: 2019.08.10 06:56:16" //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //#define DEBUG_TRACEERRORS //#define DEBUG_ASSERTIONS //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum eTradeType { TRADETYPE_BUY, // Buy TRADETYPE_SELL // Sell }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum eError { ERROR_NOERROR, // No error ERROR_UNKNOWN, // Unknown error ERROR_NUMBER, // Error number ERROR_TERMINALDISCONNECTED, // Terminal disconnected! ERROR_AUTOTRADINGNOTALLOWED, // AutoTrading disabled! ERROR_OPERATIONISNOTALLOWED, // Operation is not allowed ERROR_POINTERINVALID, // Pointer invalid ERROR_MISSINGSWITCHCASE, // Missing case ERROR_EMPTYBODYMETHODCALL, // Empty body method call ERROR_FAILEDTOSETTIMER, // Failed to set timer ERROR_INVALIDVALUE, // Invalid value! ERROR_INVALIDCHARACTER, // Invalid character! ERROR_NOINPUTSTOARRANGE, // There is no inputs to arrange! ERROR_NOENDSTOARRANGE, // There is no ends to arrange! ERROR_NOLEVELSINGRID, // There is no levels in grid! ERROR_MASTERIDALREADYEXIST, // Master ID already exist! ERROR_INVALIDMASTERID, // Invalid master ID! ERROR_FAILEDTOWRITEEXCHANGEFILE, // Failed to write exchange file! ERROR_FAILEDTOREADEXCHANGEFILE, // Failed to read exchange file! ERROR_EXCHANGEFILEDOESNOTEXIST, // Exchange file does not exist! RETCODE_ORDERCHECKFAILED, // OrderCheck() failed RETCODE_NOFREEMARGIN, // No free margin RETCODE_OPENINGNOTALLOWED, // Opening not allowed RETCODE_CLOSINGNOTALLOWED, // Closing not allowed RETCODE_TRADETYPENOTALLOWED, // Trade type not allowed RETCODE_MAXORDERS, // Max orders RETCODE_WRONGVOLUME, // Invalid volume RETCODE_MAXVOLUME, // Max volume RETCODE_WRONGSTOPS, // Invalid stops RETCODE_TRADENOTFOUND, // Trade not found RETCODE_WRONGORDERPRICE, // Invalid order price RETCODE_ALREADYPLACED, // Already placed RETCODE_NOTICKDATA // No tick data }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum eAllowedTrades { ALLOWEDTRADES_ALL, // ALL ALLOWEDTRADES_BUYONLY, // BUY Only ALLOWEDTRADES_SELLONLY, // SELL Only ALLOWEDTRADES_NONE // NONE }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ePendingOrderType { PENDINGORDERTYPE_BUYSTOP, // Buy Stop PENDINGORDERTYPE_SELLSTOP, // Sell Stop PENDINGORDERTYPE_BUYLIMIT, // Buy Limit PENDINGORDERTYPE_SELLLIMIT // Sell Limit }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum eRelationType { RELATIONTYPE_GTEATER, // Greater RELATIONTYPE_GTEATEROREQUAL, // Greater or Equal RELATIONTYPE_EQUAL, // Equal RELATIONTYPE_LESS, // Less RELATIONTYPE_LESSOREQUAL // Less or Equal }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum eTradeStatus { TRADESTATUS_ALL, // All TRADESTATUS_CURRENT, // Current TRADESTATUS_HISTORY // History }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ePendingOrderStatus { ORDERSTATUS_ALL, // All ORDERSTATUS_PENDING, // Pending ORDERSTATUS_HISTORY // History }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum eTradeInfo { TRADEINFO_TYPE, // Type TRADEINFO_STATUS, // Status TRADEINFO_TICKET, // Ticket TRADEINFO_IDENTIFIER, // Identifier TRADEINFO_SYMBOL, // Symbol TRADEINFO_MAGIC, // Magic TRADEINFO_COMMENT, // Comment TRADEINFO_PROFITMONEY, // Profit in Money TRADEINFO_COMMISSION, // Commission TRADEINFO_SWAP, // Swap TRADEINFO_PROFITPOINTS, // Profit in Points TRADEINFO_LOTS, // Lots TRADEINFO_OPENPRICE, // Open Price TRADEINFO_CLOSEPRICE, // Close Price TRADEINFO_STOPLOSS, // Stop Loss TRADEINFO_TAKEPROFIT, // Take Profit TRADEINFO_OPENTIME, // Open Time TRADEINFO_CLOSETIME // Close Time }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ePendingOrderInfo { PENDINGORDERINFO_TYPE, // Type PENDINGORDERINFO_STATUS, // Status PENDINGORDERINFO_TICKET, // Ticket PENDINGORDERINFO_SYMBOL, // Symbol PENDINGORDERINFO_MAGIC, // Magic PENDINGORDERINFO_COMMENT, // Comment PENDINGORDERINFO_LOTS, // Lots PENDINGORDERINFO_OPENPRICE, // Open Price PENDINGORDERINFO_STOPLOSS, // Stop Loss PENDINGORDERINFO_TAKEPROFIT, // Take Profit PENDINGORDERINFO_EXPIRATION, // Expiration Time PENDINGORDERINFO_OPENTIME, // Open Time PENDINGORDERINFO_CLOSETIME // Close Time }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum eTradesGroupInfo { TRADESGROUPINFO_TRADESNUMBER, // Trades Number TRADESGROUPINFO_PROFITMONEY, // Profit in Money TRADESGROUPINFO_PROFITPOINTS, // Profit in Points TRADESGROUPINFO_TOTALLOTS, // Total Lots TRADESGROUPINFO_AVERAGEPRICE, // Average Price TRADESGROUPINFO_LOWESTOPENPRICETRADETICKET, // Lowest Open Price Trade Ticket TRADESGROUPINFO_HIGHESTOPENPRICETRADETICKET, // Highest Open Price Trade Ticket TRADESGROUPINFO_LOWESTCLOSEPRICETRADETICKET, // Lowest Close Price Trade Ticket TRADESGROUPINFO_HIGHESTCLOSEPRICETRADETICKET, // Highest Close Price Trade Ticket TRADESGROUPINFO_EARLIESTOPENTIMETRADETICKET, // Earliest Open Time Trade Ticket TRADESGROUPINFO_LATESTOPENTIMETRADETICKET, // Latest Open Time Trade Ticket TRADESGROUPINFO_EARLIESTCLOSETIMETRADETICKET, // Earliest Close Time Trade Ticket TRADESGROUPINFO_LATESTCLOSETIMETRADETICKET, // Latest Close Time Trade Ticket TRADESGROUPINFO_SYMBOLSNUMBER // Symbols Number }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum ePendingOrdersGroupInfo { PENDINGSGROUPINFO_ORDERSNUMBER, // Orders Number PENDINGSGROUPINFO_TOTALLOTS, // Total Lots PENDINGSGROUPINFO_AVERAGEPRICE, // Average Price PENDINGSGROUPINFO_LOWESTOPENPRICEORDERTICKET, // Lowest Open Price Order Ticket PENDINGSGROUPINFO_HIGHESTOPENPRICEORDERTICKET, // Highest Open Price Order Ticket PENDINGSGROUPINFO_EARLIESTOPENTIMEORDERTICKET, // Earliest Open Time Order Ticket PENDINGSGROUPINFO_LATESTOPENTIMEORDERTICKET, // Latest Open Time Order Ticket PENDINGSGROUPINFO_EARLIESTCLOSETIMEORDERTICKET, // Earliest Close Time Order Ticket PENDINGSGROUPINFO_LATESTCLOSETIMEORDERTICKET, // Latest Close Time Order Ticket PENDINGSGROUPINFO_SYMBOLSNUMBER // Symbols Number }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum eAccountInfo { ACCOUNTINFO_BALANCE, // Balance ACCOUNTINFO_EQUITY, // Equity ACCOUNTINFO_MARGINUSED, // Used Margin ACCOUNTINFO_FREEMARGIN, // Free Margin ACCOUNTINFO_FLOATINGPROFIT, // Floating Profit ACCOUNTINFO_CREDIT, // Credit ACCOUNTINFO_LEVERAGE, // Leverage ACCOUNTINFO_LOGIN // Account Number }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum eMathOperation { MATHOPERATION_SUM, // Sum MATHOPERATION_ADD, // Add MATHOPERATION_PROPORTIONALTOBALANCE, // Proportional (Balance) MATHOPERATION_PROPORTIONALTOEQUITY, // Proportional (Equity) MATHOPERATION_SUBTRACT, // Subtract MATHOPERATION_DIVIDE, // Divide MATHOPERATION_REMAINDER, // Remainder MATHOPERATION_MULTIPLY, // Multiply MATHOPERATION_POWER, // Power MATHOPERATION_MAXIMUM, // Maximum MATHOPERATION_MINIMUM, // Minimum MATHOPERATION_ROUND, // Round MATHOPERATION_ABSOLUTE, // Absolute MATHOPERATION_SQUAREROOT, // Square Root MATHOPERATION_LOGARITHM, // Logarithm MATHOPERATION_EXPONENT, // Exponent MATHOPERATION_FLOOR, // Floor MATHOPERATION_CEIL, // Ceil MATHOPERATION_PRICETOPOINTS, // Price to Points MATHOPERATION_POINTSTOPRICE, // Points to Price MATHOPERATION_DONTSYNC, // Don't sync MATHOPERATION_SYNCLEVELS, // Sync Levels MATHOPERATION_SYNCPOINTS, // Sync Points MATHOPERATION_OVERWRITEWITH, // Overwrite MATHOPERATION_OVERWRITEPOINTS, // Overwrite Points MATHOPERATION_KEEPORIGINAL // Keep original }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ sinput string Inp_element_6525013 = "=== RSI ==="; // === RSI === input #ifdef __MQL4__ int #else long #endif Inp_element_7637623 = 14; // RSI Period input #ifdef __MQL4__ int #else long #endif Inp_element_7763821 = 70; // Over Bought Level input #ifdef __MQL4__ int #else long #endif Inp_element_7757993 = 30; // Over Sold Level sinput string Inp_element_6544879 = "=== TRADE ==="; // === TRADE === input double Inp_element_3632865 = 2.0; // Risk % per Trade input #ifdef __MQL4__ int #else long #endif Inp_element_3649488 = 500; // Stop Loss, points input #ifdef __MQL4__ int #else long #endif Inp_element_3632359 = 1000; // Take Profit, points input #ifdef __MQL4__ int #else long #endif Inp_element_3634918 = 7575; // Magic sinput string Inp_element_3640359 = "RSI Levels EA"; // Comment //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //=============== // Forward Declaration //=============== /* */class cInfo; // /* = final = public cInfo = */class cTradeInfo; /* = final = public cInfo = */class cPendingOrderInfo; // /* */class cGroupInfo; // /* = final = public cGroupInfo = */class cTradesGroupInfo; /* = final = public cGroupInfo = */class cPendingOrdersGroupInfo; // /* */class cFilter; // /* = final = public cFilter = */class cTradesFilter; /* = final = public cFilter = */class cPendingOrdersFilter; // /* = final = */class cTrade; /* = final = */class cPointer; /* = final = */class cArray; /* = final = */class cRunner; /* = final = */class cExecutableParameter; // /* */class cObject; // /* = final = public cObject */templateclass cVariable; // /* */class cExecutable; /* = final = public cExecutable = */class cExecutableInputLongValue; /* = final = public cExecutable = */class cExecutableInputDoubleValue; /* = final = public cExecutable = */class cExecutableInputStringValue; /* = public cExecutable = */class cExecutableOpen; /* = final = public cExecutableOpen = */class cExecutableOpenTrade; /* = public cExecutable = */class cExecutableModify; /* = public cExecutableModify = */class cExecutableModifyCurrent; /* = public cExecutableModify = */class cExecutableModifyPending; /* = final = public cExecutableModifyCurrent = */class cExecutableModifyTradesGroup; /* = final = public cExecutable = */class cExecutableCloseTradesGroup; /* = final = public cExecutable = */class cExecutableLotCalculator; /* = public cExecutable = */class cExecutableTrades; /* = final = public cExecutableTrades = */class cExecutableTradesGroup; /* = final = public cExecutableTrades = */class cExecutableCombineTradesGroups; /* = public cExecutable = */class cExecutableTradesGroupInfo; /* = final = public cExecutableTradesGroupInfo = */class cExecutableTradesGroupInfoInteger; /* = public cExecutable = */class cExecutableAccountInfo; /* = final = public cExecutableAccountInfo = */class cExecutableAccountInfoDouble; /* = final = public cExecutable = */class cExecutableArithmetic; /* = final = public cExecutable = */class cExecutableAnd; /* = final = public cExecutable = */class cExecutableOr; /* = final = public cExecutable = */class cExecutableCompare; /* = final = public cExecutable = */class cExecutableIndicatorValue; /* = public cExecutable = */class cExecutableIndicator; /* = final = public cExecutableIndicator = */class cExecutableIndicatorRSI; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ enum eElementParameter { ELEMENTPARAMETER_TRIGGER, // Trigger ELEMENTPARAMETER_LONGVALUE, // Value (Integer) ELEMENTPARAMETER_DOUBLEVALUE, // Value (Decimal) ELEMENTPARAMETER_BOOLVALUE, // Logical True/False ELEMENTPARAMETER_STRINGVALUE, // Value (String) ELEMENTPARAMETER_TIMEVALUE, // Value (Time) ELEMENTPARAMETER_CONDITION, // Condition ELEMENTPARAMETER_ORDERPRICE, // Order Price ELEMENTPARAMETER_EXPIRATION, // Expiration ELEMENTPARAMETER_CLOSEBY, // Close By ELEMENTPARAMETER_TIGHTENSTOPSONLY, // Tighten Stops Only ELEMENTPARAMETER_INDICATOR, // Indicator ELEMENTPARAMETER_TRADESGROUP, // Trades ELEMENTPARAMETER_INDICATORPERIOD, // Indicator Period ELEMENTPARAMETER_BARNUMBER, // Bar Number ELEMENTPARAMETER_MAGIC, // Magic ELEMENTPARAMETER_STOPLOSSPOINTS, // Stop Loss (Points) ELEMENTPARAMETER_TAKEPROFITPOINTS, // Take Profit (Points) ELEMENTPARAMETER_TICKETGREATEROREQUALTHAN, // Ticket Greater or Equal than ELEMENTPARAMETER_TICKETLESSOREQUALTHAN, // Ticket Less or Equal than ELEMENTPARAMETER_SLIPPAGE, // Slippage ELEMENTPARAMETER_SYMBOLNAME, // Symbol Name ELEMENTPARAMETER_COMMENT, // Comment ELEMENTPARAMETER_EXACTCOMMENT, // Exact Comment ELEMENTPARAMETER_COMMENTPARTIAL, // Partial Comment ELEMENTPARAMETER_OPENTIMEGREATEROREQUALTHAN, // Open Time Greater or Equal than ELEMENTPARAMETER_OPENTIMELESSOREQUALTHAN, // Open Time Less or Equal than ELEMENTPARAMETER_CLOSETIMEGREATEROREQUALTHAN, // Close Time Greater or Equal than ELEMENTPARAMETER_CLOSETIMELESSOREQUALTHAN, // Close Time Less or Equal than ELEMENTPARAMETER_STOPLOSSPRICE, // Stop Loss (Price) ELEMENTPARAMETER_STOPLOSSMONEY, // Stop Loss (Money) ELEMENTPARAMETER_MONEYRISKPERTRADE, // Money Risk per Trade ELEMENTPARAMETER_TAKEPROFITPRICE, // Take Profit (Price) ELEMENTPARAMETER_TAKEPROFITMONEY, // Take Profit (Money) ELEMENTPARAMETER_DOUBLEVALUE1, // Value #1 ELEMENTPARAMETER_DOUBLEVALUE2, // Value #2 ELEMENTPARAMETER_PROFITGREATEROREQUALTHAN, // Profit Greater or Equal than ELEMENTPARAMETER_PROFITLESSOREQUALTHAN, // Profit Less or Equal than ELEMENTPARAMETER_OPENPRICEGREATEROREQUALTHAN, // Open Price Greater or Equal than ELEMENTPARAMETER_OPENPRICELESSOREQUALTHAN, // Open Price Less or Equal than ELEMENTPARAMETER_CLOSEPRICEGREATEROREQUALTHAN, // Close Price Greater or Equal than ELEMENTPARAMETER_CLOSEPRICELESSOREQUALTHAN, // Close Price Less or Equal than ELEMENTPARAMETER_LOTSGREATEROREQUALTHAN, // Lots Greater or Equal than ELEMENTPARAMETER_LOTSLESSOREQUALTHAN, // Lots Less or Equal than ELEMENTPARAMETER_LOTS, // Lots ELEMENTPARAMETER_TIMEFRAME, // Time Frame ELEMENTPARAMETER_APPLIEDPRICE, // Applied Price ELEMENTPARAMETER_TRADETYPE, // Trade Type ELEMENTPARAMETER_ACCOUNTINFO, // Account Information ELEMENTPARAMETER_TRADESGROUPINFO, // Trades Information ELEMENTPARAMETER_RELATIONTYPE, // Relation Type ELEMENTPARAMETER_TRADESTATUS, // Trade Status ELEMENTPARAMETER_MATHOPERATION // Math Operation }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #define OUTPUTNONE //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #define OUTPUTLONG \ long OutputValue;\ virtual bool OutPutValueGet(long &to)override final const{to=this.OutputValue;return(true);}\ virtual bool OutPutValueGet(double &to)override final const{to=(double)this.OutputValue;return(true);}\ virtual bool OutPutValueGet(string &to)override final const{to=(string)this.OutputValue;return(true);}\ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #define OUTPUTBOOL \ bool OutputValue;\ virtual bool OutPutValueGet(long &to)override final const{to=(long)this.OutputValue;return(true);}\ virtual bool OutPutValueGet(double &to)override final const{to=(double)this.OutputValue;return(true);}\ virtual bool OutPutValueGet(string &to)override final const{to=(string)this.OutputValue;return(true);}\ virtual bool OutPutValueGet(bool &to)override final const{to=this.OutputValue;return(true);}\ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #define OUTPUTDOUBLE \ double OutputValue;\ virtual bool OutPutValueGet(double &to)override final const{to=this.OutputValue;return(true);}\ virtual bool OutPutValueGet(string &to)override final const{to=(string)this.OutputValue;return(true);}\ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #define OUTPUTSTRING \ string OutputValue;\ virtual bool OutPutValueGet(string &to)override final const{to=this.OutputValue;return(true);}\ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #define OUTPUTDATETIME \ datetime OutputValue;\ virtual bool OutPutValueGet(datetime &to)override final const{to=this.OutputValue;return(true);}\ virtual bool OutPutValueGet(string &to)override final const{to=::TimeToString(this.OutputValue,TIME_DATE|TIME_MINUTES|TIME_SECONDS);return(true);}\ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #define OUTPUTENUM(enumname) \ enumname OutputValue;\ virtual bool OutPutValueGet(enumname &to)override final const{to=this.OutputValue;return(true);}\ virtual bool OutPutValueGet(string &to)override final const{to=::EnumToString(this.OutputValue);return(true);}\ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #define OUTPUTPOINTER \ virtual bool OutPutValueGet(const cExecutable *&to)const{to=::GetPointer(this);return(true);}\ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ #define VERTICALBAR " | " #define TOSTRING(expression) (#expression +" = " + (string)(expression)) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //=============== //=============== #ifdef DEBUG_TRACEERRORS //=============== //=============== #define TRACEERRORS_START \ int lasterror=::GetLastError();\ if(lasterror>0)\ {\ ::Alert("!!! TRACE ERRORS !!! (START): ",lasterror,VERTICALBAR,__FUNCSIG__,VERTICALBAR,__FILE__,VERTICALBAR,__LINE__);\ ::DebugBreak();\ ::ResetLastError();\ } //=============== //=============== #define TRACEERRORS_END \ lasterror=::GetLastError();\ if(lasterror>0)\ {\ string errordescription=(string)lasterror;\ if(lasterror>=ERR_USER_ERROR_FIRST)errordescription="CUSTOM: "+(string)(lasterror-ERR_USER_ERROR_FIRST);\ ::Alert("!!! TRACE ERRORS !!! (END): ",errordescription,VERTICALBAR,__FUNCSIG__,VERTICALBAR,__FILE__,VERTICALBAR,__LINE__);\ ::DebugBreak();\ ::ResetLastError();\ } //=============== //=============== #else //=============== //=============== #define TRACEERRORS_START #define TRACEERRORS_END //=============== //=============== #endif //=============== //=============== //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ //=============== //=============== #ifdef DEBUG_ASSERTIONS //=============== //=============== #define ASSERT(executebefore,condition,skipped,executeiffailed) \ {executebefore}\ if(!(condition))\ {\ ::Alert("!!! ASSERT <<",#condition,">> FAILED !!! Function ",((skipped)?"Execution Skipped!!!":"Executed => "),VERTICALBAR,\ __FUNCSIG__,VERTICALBAR,__FILE__,VERTICALBAR,__LINE__);\ ::DebugBreak();\ {executeiffailed}\ } //=============== //=============== #else //=============== //=============== #define ASSERT(executebefore,condition,skipped,executeiffailed) //=============== //=============== #endif //=============== //=============== //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ cRunner *Runner; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit(void) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== Runner=new cRunner; //=============== //=============== /* DEBUG ASSERTION */ASSERT({},cPointer::Valid(Runner),true,{}) //=============== //=============== if(!cPointer::Valid(Runner))return(INIT_FAILED); //=============== //=============== // Element: === RSI === //=============== cExecutableInputStringValue *const element_6525013 = new cExecutableInputStringValue; //=============== Runner.Add(element_6525013,true); //=============== element_6525013.ParameterAdd((string)Inp_element_6525013,ELEMENTPARAMETER_STRINGVALUE,0,true); //=============== //=============== // Element: RSI Period //=============== cExecutableInputLongValue *const element_7637623 = new cExecutableInputLongValue; //=============== Runner.Add(element_7637623,false); //=============== element_7637623.ParameterAdd((long)Inp_element_7637623,ELEMENTPARAMETER_LONGVALUE,0,true); //=============== //=============== // Element: Over Bought Level //=============== cExecutableInputLongValue *const element_7763821 = new cExecutableInputLongValue; //=============== Runner.Add(element_7763821,false); //=============== element_7763821.ParameterAdd((long)Inp_element_7763821,ELEMENTPARAMETER_LONGVALUE,0,true); //=============== //=============== // Element: Over Sold Level //=============== cExecutableInputLongValue *const element_7757993 = new cExecutableInputLongValue; //=============== Runner.Add(element_7757993,false); //=============== element_7757993.ParameterAdd((long)Inp_element_7757993,ELEMENTPARAMETER_LONGVALUE,0,true); //=============== //=============== // Element: === TRADE === //=============== cExecutableInputStringValue *const element_6544879 = new cExecutableInputStringValue; //=============== Runner.Add(element_6544879,true); //=============== element_6544879.ParameterAdd((string)Inp_element_6544879,ELEMENTPARAMETER_STRINGVALUE,0,true); //=============== //=============== // Element: Risk % per Trade //=============== cExecutableInputDoubleValue *const element_3632865 = new cExecutableInputDoubleValue; //=============== Runner.Add(element_3632865,false); //=============== element_3632865.ParameterAdd((double)Inp_element_3632865,ELEMENTPARAMETER_DOUBLEVALUE,0,true); //=============== //=============== // Element: Stop Loss, points //=============== cExecutableInputLongValue *const element_3649488 = new cExecutableInputLongValue; //=============== Runner.Add(element_3649488,false); //=============== element_3649488.ParameterAdd((long)Inp_element_3649488,ELEMENTPARAMETER_LONGVALUE,0,true); //=============== //=============== // Element: Take Profit, points //=============== cExecutableInputLongValue *const element_3632359 = new cExecutableInputLongValue; //=============== Runner.Add(element_3632359,false); //=============== element_3632359.ParameterAdd((long)Inp_element_3632359,ELEMENTPARAMETER_LONGVALUE,0,true); //=============== //=============== // Element: Magic //=============== cExecutableInputLongValue *const element_3634918 = new cExecutableInputLongValue; //=============== Runner.Add(element_3634918,false); //=============== element_3634918.ParameterAdd((long)Inp_element_3634918,ELEMENTPARAMETER_LONGVALUE,0,true); //=============== //=============== // Element: Comment //=============== cExecutableInputStringValue *const element_3640359 = new cExecutableInputStringValue; //=============== Runner.Add(element_3640359,false); //=============== element_3640359.ParameterAdd((string)Inp_element_3640359,ELEMENTPARAMETER_STRINGVALUE,0,true); //=============== //=============== // Element: Close Buys //=============== cExecutableCloseTradesGroup *const element_3626309 = new cExecutableCloseTradesGroup; //=============== Runner.Add(element_3626309,true); //=============== element_3626309.ParameterAdd((bool)false,ELEMENTPARAMETER_CLOSEBY,2,true); //=============== element_3626309.ParameterAdd((long)30,ELEMENTPARAMETER_SLIPPAGE,3,true); //=============== //=============== // Element: Close Sells //=============== cExecutableCloseTradesGroup *const element_3640683 = new cExecutableCloseTradesGroup; //=============== Runner.Add(element_3640683,true); //=============== element_3640683.ParameterAdd((bool)false,ELEMENTPARAMETER_CLOSEBY,2,true); //=============== element_3640683.ParameterAdd((long)30,ELEMENTPARAMETER_SLIPPAGE,3,true); //=============== //=============== // Element: Open Buy //=============== cExecutableOpenTrade *const element_3641151 = new cExecutableOpenTrade; //=============== Runner.Add(element_3641151,true); //=============== element_3641151.ParameterAdd((string)::Symbol(),ELEMENTPARAMETER_SYMBOLNAME,1,true); //=============== element_3641151.ParameterAdd((eTradeType)TRADETYPE_BUY,ELEMENTPARAMETER_TRADETYPE,2,true); //=============== element_3641151.ParameterAdd((long)0,ELEMENTPARAMETER_STOPLOSSPOINTS,6,false); //=============== element_3641151.ParameterAdd((long)0,ELEMENTPARAMETER_TAKEPROFITPOINTS,7,false); //=============== element_3641151.ParameterAdd((double)0.0,ELEMENTPARAMETER_STOPLOSSMONEY,8,false); //=============== element_3641151.ParameterAdd((double)0.0,ELEMENTPARAMETER_TAKEPROFITMONEY,9,false); //=============== element_3641151.ParameterAdd((double)0.0,ELEMENTPARAMETER_STOPLOSSPRICE,10,false); //=============== element_3641151.ParameterAdd((double)0.0,ELEMENTPARAMETER_TAKEPROFITPRICE,11,false); //=============== element_3641151.ParameterAdd((long)30,ELEMENTPARAMETER_SLIPPAGE,12,true); //=============== //=============== // Element: Open Sell //=============== cExecutableOpenTrade *const element_3636083 = new cExecutableOpenTrade; //=============== Runner.Add(element_3636083,true); //=============== element_3636083.ParameterAdd((string)::Symbol(),ELEMENTPARAMETER_SYMBOLNAME,1,true); //=============== element_3636083.ParameterAdd((eTradeType)TRADETYPE_SELL,ELEMENTPARAMETER_TRADETYPE,2,true); //=============== element_3636083.ParameterAdd((long)0,ELEMENTPARAMETER_STOPLOSSPOINTS,6,false); //=============== element_3636083.ParameterAdd((long)0,ELEMENTPARAMETER_TAKEPROFITPOINTS,7,false); //=============== element_3636083.ParameterAdd((double)0.0,ELEMENTPARAMETER_STOPLOSSMONEY,8,false); //=============== element_3636083.ParameterAdd((double)0.0,ELEMENTPARAMETER_TAKEPROFITMONEY,9,false); //=============== element_3636083.ParameterAdd((double)0.0,ELEMENTPARAMETER_STOPLOSSPRICE,10,false); //=============== element_3636083.ParameterAdd((double)0.0,ELEMENTPARAMETER_TAKEPROFITPRICE,11,false); //=============== element_3636083.ParameterAdd((long)30,ELEMENTPARAMETER_SLIPPAGE,12,true); //=============== //=============== // Element: Set SL and TP //=============== cExecutableModifyTradesGroup *const element_3646343 = new cExecutableModifyTradesGroup; //=============== Runner.Add(element_3646343,true); //=============== element_3646343.ParameterAdd((bool)true,ELEMENTPARAMETER_TIGHTENSTOPSONLY,2,true); //=============== element_3646343.ParameterAdd((double)30.0,ELEMENTPARAMETER_STOPLOSSMONEY,5,false); //=============== element_3646343.ParameterAdd((double)30.0,ELEMENTPARAMETER_TAKEPROFITMONEY,6,false); //=============== element_3646343.ParameterAdd((double)0.0,ELEMENTPARAMETER_STOPLOSSPRICE,7,false); //=============== element_3646343.ParameterAdd((double)0.0,ELEMENTPARAMETER_TAKEPROFITPRICE,8,false); //=============== //=============== // Element: Lots //=============== cExecutableLotCalculator *const element_4816263 = new cExecutableLotCalculator; //=============== Runner.Add(element_4816263,false); //=============== element_4816263.ParameterAdd((string)::Symbol(),ELEMENTPARAMETER_SYMBOLNAME,0,true); //=============== //=============== // Element: Buys //=============== cExecutableTradesGroup *const element_3643317 = new cExecutableTradesGroup; //=============== Runner.Add(element_3643317,false); //=============== element_3643317.ParameterAdd((eTradeStatus)TRADESTATUS_CURRENT,ELEMENTPARAMETER_TRADESTATUS,0,true); //=============== element_3643317.ParameterAdd((string)::Symbol(),ELEMENTPARAMETER_SYMBOLNAME,1,true); //=============== element_3643317.ParameterAdd((eTradeType)TRADETYPE_BUY,ELEMENTPARAMETER_TRADETYPE,3,true); //=============== element_3643317.ParameterAdd((string)"Comment",ELEMENTPARAMETER_EXACTCOMMENT,4,false); //=============== element_3643317.ParameterAdd((string)"Comment",ELEMENTPARAMETER_COMMENTPARTIAL,5,false); //=============== element_3643317.ParameterAdd((double)0.0,ELEMENTPARAMETER_PROFITGREATEROREQUALTHAN,6,false); //=============== element_3643317.ParameterAdd((double)0.0,ELEMENTPARAMETER_PROFITLESSOREQUALTHAN,7,false); //=============== element_3643317.ParameterAdd((datetime)D'1970.01.01 00:00:00',ELEMENTPARAMETER_OPENTIMEGREATEROREQUALTHAN,8,false); //=============== element_3643317.ParameterAdd((datetime)D'1970.01.01 00:00:00',ELEMENTPARAMETER_OPENTIMELESSOREQUALTHAN,9,false); //=============== element_3643317.ParameterAdd((datetime)D'1970.01.01 00:00:00',ELEMENTPARAMETER_CLOSETIMEGREATEROREQUALTHAN,10,false); //=============== element_3643317.ParameterAdd((datetime)D'1970.01.01 00:00:00',ELEMENTPARAMETER_CLOSETIMELESSOREQUALTHAN,11,false); //=============== element_3643317.ParameterAdd((double)0.0,ELEMENTPARAMETER_OPENPRICEGREATEROREQUALTHAN,12,false); //=============== element_3643317.ParameterAdd((double)0.0,ELEMENTPARAMETER_OPENPRICELESSOREQUALTHAN,13,false); //=============== element_3643317.ParameterAdd((double)0.0,ELEMENTPARAMETER_CLOSEPRICEGREATEROREQUALTHAN,14,false); //=============== element_3643317.ParameterAdd((double)0.0,ELEMENTPARAMETER_CLOSEPRICELESSOREQUALTHAN,15,false); //=============== element_3643317.ParameterAdd((double)0.0,ELEMENTPARAMETER_LOTSGREATEROREQUALTHAN,16,false); //=============== element_3643317.ParameterAdd((double)0.0,ELEMENTPARAMETER_LOTSLESSOREQUALTHAN,17,false); //=============== element_3643317.ParameterAdd((long)0,ELEMENTPARAMETER_TICKETGREATEROREQUALTHAN,18,false); //=============== element_3643317.ParameterAdd((long)0,ELEMENTPARAMETER_TICKETLESSOREQUALTHAN,19,false); //=============== //=============== // Element: Sells //=============== cExecutableTradesGroup *const element_3651482 = new cExecutableTradesGroup; //=============== Runner.Add(element_3651482,false); //=============== element_3651482.ParameterAdd((eTradeStatus)TRADESTATUS_CURRENT,ELEMENTPARAMETER_TRADESTATUS,0,true); //=============== element_3651482.ParameterAdd((string)::Symbol(),ELEMENTPARAMETER_SYMBOLNAME,1,true); //=============== element_3651482.ParameterAdd((eTradeType)TRADETYPE_SELL,ELEMENTPARAMETER_TRADETYPE,3,true); //=============== element_3651482.ParameterAdd((string)"Comment",ELEMENTPARAMETER_EXACTCOMMENT,4,false); //=============== element_3651482.ParameterAdd((string)"Comment",ELEMENTPARAMETER_COMMENTPARTIAL,5,false); //=============== element_3651482.ParameterAdd((double)0.0,ELEMENTPARAMETER_PROFITGREATEROREQUALTHAN,6,false); //=============== element_3651482.ParameterAdd((double)0.0,ELEMENTPARAMETER_PROFITLESSOREQUALTHAN,7,false); //=============== element_3651482.ParameterAdd((datetime)D'1970.01.01 00:00:00',ELEMENTPARAMETER_OPENTIMEGREATEROREQUALTHAN,8,false); //=============== element_3651482.ParameterAdd((datetime)D'1970.01.01 00:00:00',ELEMENTPARAMETER_OPENTIMELESSOREQUALTHAN,9,false); //=============== element_3651482.ParameterAdd((datetime)D'1970.01.01 00:00:00',ELEMENTPARAMETER_CLOSETIMEGREATEROREQUALTHAN,10,false); //=============== element_3651482.ParameterAdd((datetime)D'1970.01.01 00:00:00',ELEMENTPARAMETER_CLOSETIMELESSOREQUALTHAN,11,false); //=============== element_3651482.ParameterAdd((double)0.0,ELEMENTPARAMETER_OPENPRICEGREATEROREQUALTHAN,12,false); //=============== element_3651482.ParameterAdd((double)0.0,ELEMENTPARAMETER_OPENPRICELESSOREQUALTHAN,13,false); //=============== element_3651482.ParameterAdd((double)0.0,ELEMENTPARAMETER_CLOSEPRICEGREATEROREQUALTHAN,14,false); //=============== element_3651482.ParameterAdd((double)0.0,ELEMENTPARAMETER_CLOSEPRICELESSOREQUALTHAN,15,false); //=============== element_3651482.ParameterAdd((double)0.0,ELEMENTPARAMETER_LOTSGREATEROREQUALTHAN,16,false); //=============== element_3651482.ParameterAdd((double)0.0,ELEMENTPARAMETER_LOTSLESSOREQUALTHAN,17,false); //=============== element_3651482.ParameterAdd((long)0,ELEMENTPARAMETER_TICKETGREATEROREQUALTHAN,18,false); //=============== element_3651482.ParameterAdd((long)0,ELEMENTPARAMETER_TICKETLESSOREQUALTHAN,19,false); //=============== //=============== // Element: All Trades //=============== cExecutableCombineTradesGroups *const element_3634787 = new cExecutableCombineTradesGroups; //=============== Runner.Add(element_3634787,false); //=============== //=============== // Element: Buys Number //=============== cExecutableTradesGroupInfoInteger *const element_3630945 = new cExecutableTradesGroupInfoInteger; //=============== Runner.Add(element_3630945,false); //=============== element_3630945.ParameterAdd((eTradesGroupInfo)TRADESGROUPINFO_TRADESNUMBER,ELEMENTPARAMETER_TRADESGROUPINFO,1,true); //=============== //=============== // Element: Sells Number //=============== cExecutableTradesGroupInfoInteger *const element_3628984 = new cExecutableTradesGroupInfoInteger; //=============== Runner.Add(element_3628984,false); //=============== element_3628984.ParameterAdd((eTradesGroupInfo)TRADESGROUPINFO_TRADESNUMBER,ELEMENTPARAMETER_TRADESGROUPINFO,1,true); //=============== //=============== // Element: Balance //=============== cExecutableAccountInfoDouble *const element_4956492 = new cExecutableAccountInfoDouble; //=============== Runner.Add(element_4956492,false); //=============== element_4956492.ParameterAdd((eAccountInfo)ACCOUNTINFO_BALANCE,ELEMENTPARAMETER_ACCOUNTINFO,0,true); //=============== //=============== // Element: Risk Money //=============== cExecutableArithmetic *const element_4986476 = new cExecutableArithmetic; //=============== Runner.Add(element_4986476,false); //=============== element_4986476.ParameterAdd((bool)true,ELEMENTPARAMETER_TRIGGER,0,true); //=============== element_4986476.ParameterAdd((eMathOperation)MATHOPERATION_MULTIPLY,ELEMENTPARAMETER_MATHOPERATION,2,true); //=============== //=============== // Element: Risk //=============== cExecutableArithmetic *const element_5048973 = new cExecutableArithmetic; //=============== Runner.Add(element_5048973,false); //=============== element_5048973.ParameterAdd((bool)true,ELEMENTPARAMETER_TRIGGER,0,true); //=============== element_5048973.ParameterAdd((eMathOperation)MATHOPERATION_DIVIDE,ELEMENTPARAMETER_MATHOPERATION,2,true); //=============== element_5048973.ParameterAdd((double)100.0,ELEMENTPARAMETER_DOUBLEVALUE2,3,true); //=============== //=============== // Element: Close Sell Trigger //=============== cExecutableAnd *const element_3624028 = new cExecutableAnd; //=============== Runner.Add(element_3624028,false); //=============== //=============== // Element: Close Buy Trigger //=============== cExecutableAnd *const element_3630411 = new cExecutableAnd; //=============== Runner.Add(element_3630411,false); //=============== //=============== // Element: Buy Signal //=============== cExecutableAnd *const element_3636154 = new cExecutableAnd; //=============== Runner.Add(element_3636154,false); //=============== //=============== // Element: Buy Trigger //=============== cExecutableAnd *const element_3639134 = new cExecutableAnd; //=============== Runner.Add(element_3639134,false); //=============== //=============== // Element: Sell Signal //=============== cExecutableAnd *const element_3636410 = new cExecutableAnd; //=============== Runner.Add(element_3636410,false); //=============== //=============== // Element: Sell Trigger //=============== cExecutableAnd *const element_3630655 = new cExecutableAnd; //=============== Runner.Add(element_3630655,false); //=============== //=============== // Element: Trade Exist? //=============== cExecutableOr *const element_3621617 = new cExecutableOr; //=============== Runner.Add(element_3621617,false); //=============== //=============== // Element: OverBought Previous //=============== cExecutableCompare *const element_7950952 = new cExecutableCompare; //=============== Runner.Add(element_7950952,false); //=============== element_7950952.ParameterAdd((eRelationType)RELATIONTYPE_GTEATER,ELEMENTPARAMETER_RELATIONTYPE,1,true); //=============== //=============== // Element: OverSold Previous //=============== cExecutableCompare *const element_7882752 = new cExecutableCompare; //=============== Runner.Add(element_7882752,false); //=============== element_7882752.ParameterAdd((eRelationType)RELATIONTYPE_LESS,ELEMENTPARAMETER_RELATIONTYPE,1,true); //=============== //=============== // Element: OverSold Now //=============== cExecutableCompare *const element_3630672 = new cExecutableCompare; //=============== Runner.Add(element_3630672,false); //=============== element_3630672.ParameterAdd((eRelationType)RELATIONTYPE_LESS,ELEMENTPARAMETER_RELATIONTYPE,1,true); //=============== //=============== // Element: OverBought Now //=============== cExecutableCompare *const element_7936012 = new cExecutableCompare; //=============== Runner.Add(element_7936012,false); //=============== element_7936012.ParameterAdd((eRelationType)RELATIONTYPE_GTEATER,ELEMENTPARAMETER_RELATIONTYPE,1,true); //=============== //=============== // Element: No Buys? //=============== cExecutableCompare *const element_3621495 = new cExecutableCompare; //=============== Runner.Add(element_3621495,false); //=============== element_3621495.ParameterAdd((eRelationType)RELATIONTYPE_EQUAL,ELEMENTPARAMETER_RELATIONTYPE,1,true); //=============== element_3621495.ParameterAdd((double)0.0,ELEMENTPARAMETER_DOUBLEVALUE2,2,true); //=============== //=============== // Element: No Sells? //=============== cExecutableCompare *const element_3645690 = new cExecutableCompare; //=============== Runner.Add(element_3645690,false); //=============== element_3645690.ParameterAdd((eRelationType)RELATIONTYPE_EQUAL,ELEMENTPARAMETER_RELATIONTYPE,1,true); //=============== element_3645690.ParameterAdd((double)0.0,ELEMENTPARAMETER_DOUBLEVALUE2,2,true); //=============== //=============== // Element: RSI Previous //=============== cExecutableIndicatorValue *const element_7674697 = new cExecutableIndicatorValue; //=============== Runner.Add(element_7674697,false); //=============== element_7674697.ParameterAdd((long)2,ELEMENTPARAMETER_BARNUMBER,1,true); //=============== //=============== // Element: RSI Current //=============== cExecutableIndicatorValue *const element_7678300 = new cExecutableIndicatorValue; //=============== Runner.Add(element_7678300,false); //=============== element_7678300.ParameterAdd((long)1,ELEMENTPARAMETER_BARNUMBER,1,true); //=============== //=============== // Element: RSI //=============== cExecutableIndicatorRSI *const element_7640618 = new cExecutableIndicatorRSI; //=============== Runner.Add(element_7640618,false); //=============== element_7640618.ParameterAdd((string)::Symbol(),ELEMENTPARAMETER_SYMBOLNAME,0,true); //=============== element_7640618.ParameterAdd((ENUM_TIMEFRAMES)::Period(),ELEMENTPARAMETER_TIMEFRAME,1,true); //=============== element_7640618.ParameterAdd((ENUM_APPLIED_PRICE)PRICE_CLOSE,ELEMENTPARAMETER_APPLIEDPRICE,3,true); //=============== //=============== // Link: Magic => Buys //=============== element_3643317.LinkAdd(element_3634918,ELEMENTPARAMETER_MAGIC,false,2,true); //=============== //=============== // Link: Magic => Sells //=============== element_3651482.LinkAdd(element_3634918,ELEMENTPARAMETER_MAGIC,false,2,true); //=============== //=============== // Link: Buys => Buys Number //=============== element_3630945.LinkAdd(element_3643317,ELEMENTPARAMETER_TRADESGROUP,false,0,true); //=============== //=============== // Link: Sells => Sells Number //=============== element_3628984.LinkAdd(element_3651482,ELEMENTPARAMETER_TRADESGROUP,false,0,true); //=============== //=============== // Link: Buys Number => No Buys? //=============== element_3621495.LinkAdd(element_3630945,ELEMENTPARAMETER_DOUBLEVALUE1,false,0,true); //=============== //=============== // Link: Sells Number => No Sells? //=============== element_3645690.LinkAdd(element_3628984,ELEMENTPARAMETER_DOUBLEVALUE1,false,0,true); //=============== //=============== // Link: Buy Signal => Buy Trigger //=============== element_3639134.LinkAdd(element_3636154,ELEMENTPARAMETER_BOOLVALUE,false,0,true); //=============== //=============== // Link: No Buys? => Buy Trigger //=============== element_3639134.LinkAdd(element_3621495,ELEMENTPARAMETER_BOOLVALUE,false,1,true); //=============== //=============== // Link: Buy Trigger => Open Buy //=============== element_3641151.LinkAdd(element_3639134,ELEMENTPARAMETER_TRIGGER,false,0,true); //=============== //=============== // Link: Magic => Open Buy //=============== element_3641151.LinkAdd(element_3634918,ELEMENTPARAMETER_MAGIC,false,4,true); //=============== //=============== // Link: Sell Signal => Sell Trigger //=============== element_3630655.LinkAdd(element_3636410,ELEMENTPARAMETER_BOOLVALUE,false,0,true); //=============== //=============== // Link: No Sells? => Sell Trigger //=============== element_3630655.LinkAdd(element_3645690,ELEMENTPARAMETER_BOOLVALUE,false,1,true); //=============== //=============== // Link: Sell Trigger => Open Sell //=============== element_3636083.LinkAdd(element_3630655,ELEMENTPARAMETER_TRIGGER,false,0,true); //=============== //=============== // Link: Magic => Open Sell //=============== element_3636083.LinkAdd(element_3634918,ELEMENTPARAMETER_MAGIC,false,4,true); //=============== //=============== // Link: Sells => Close Sells //=============== element_3640683.LinkAdd(element_3651482,ELEMENTPARAMETER_TRADESGROUP,false,1,true); //=============== //=============== // Link: Close Sell Trigger => Close Sells //=============== element_3640683.LinkAdd(element_3624028,ELEMENTPARAMETER_TRIGGER,false,0,true); //=============== //=============== // Link: Buy Signal => Close Sell Trigger //=============== element_3624028.LinkAdd(element_3636154,ELEMENTPARAMETER_BOOLVALUE,false,0,true); //=============== //=============== // Link: No Sells? => Close Sell Trigger //=============== element_3624028.LinkAdd(element_3645690,ELEMENTPARAMETER_BOOLVALUE,true,1,true); //=============== //=============== // Link: Close Buy Trigger => Close Buys //=============== element_3626309.LinkAdd(element_3630411,ELEMENTPARAMETER_TRIGGER,false,0,true); //=============== //=============== // Link: Buys => Close Buys //=============== element_3626309.LinkAdd(element_3643317,ELEMENTPARAMETER_TRADESGROUP,false,1,true); //=============== //=============== // Link: Sell Signal => Close Buy Trigger //=============== element_3630411.LinkAdd(element_3636410,ELEMENTPARAMETER_BOOLVALUE,false,0,true); //=============== //=============== // Link: No Buys? => Close Buy Trigger //=============== element_3630411.LinkAdd(element_3621495,ELEMENTPARAMETER_BOOLVALUE,true,1,true); //=============== //=============== // Link: No Sells? => Buy Trigger //=============== element_3639134.LinkAdd(element_3645690,ELEMENTPARAMETER_BOOLVALUE,false,2,true); //=============== //=============== // Link: No Buys? => Sell Trigger //=============== element_3630655.LinkAdd(element_3621495,ELEMENTPARAMETER_BOOLVALUE,false,2,true); //=============== //=============== // Link: Comment => Open Buy //=============== element_3641151.LinkAdd(element_3640359,ELEMENTPARAMETER_COMMENT,false,5,true); //=============== //=============== // Link: Comment => Open Sell //=============== element_3636083.LinkAdd(element_3640359,ELEMENTPARAMETER_COMMENT,false,5,true); //=============== //=============== // Link: Buys => All Trades //=============== element_3634787.LinkAdd(element_3643317,ELEMENTPARAMETER_TRADESGROUP,false,0,true); //=============== //=============== // Link: Sells => All Trades //=============== element_3634787.LinkAdd(element_3651482,ELEMENTPARAMETER_TRADESGROUP,false,1,true); //=============== //=============== // Link: All Trades => Set SL and TP //=============== element_3646343.LinkAdd(element_3634787,ELEMENTPARAMETER_TRADESGROUP,false,1,true); //=============== //=============== // Link: No Buys? => Trade Exist? //=============== element_3621617.LinkAdd(element_3621495,ELEMENTPARAMETER_BOOLVALUE,true,0,true); //=============== //=============== // Link: No Sells? => Trade Exist? //=============== element_3621617.LinkAdd(element_3645690,ELEMENTPARAMETER_BOOLVALUE,true,1,true); //=============== //=============== // Link: Trade Exist? => Set SL and TP //=============== element_3646343.LinkAdd(element_3621617,ELEMENTPARAMETER_TRIGGER,false,0,true); //=============== //=============== // Link: Stop Loss, points => Set SL and TP //=============== element_3646343.LinkAdd(element_3649488,ELEMENTPARAMETER_STOPLOSSPOINTS,false,3,true); //=============== //=============== // Link: Take Profit, points => Set SL and TP //=============== element_3646343.LinkAdd(element_3632359,ELEMENTPARAMETER_TAKEPROFITPOINTS,false,4,true); //=============== //=============== // Link: RSI Period => RSI //=============== element_7640618.LinkAdd(element_7637623,ELEMENTPARAMETER_INDICATORPERIOD,false,2,true); //=============== //=============== // Link: RSI => RSI Current //=============== element_7678300.LinkAdd(element_7640618,ELEMENTPARAMETER_INDICATOR,false,0,true); //=============== //=============== // Link: RSI => RSI Previous //=============== element_7674697.LinkAdd(element_7640618,ELEMENTPARAMETER_INDICATOR,false,0,true); //=============== //=============== // Link: RSI Current => OverSold Now //=============== element_3630672.LinkAdd(element_7678300,ELEMENTPARAMETER_DOUBLEVALUE1,false,0,true); //=============== //=============== // Link: Over Sold Level => OverSold Now //=============== element_3630672.LinkAdd(element_7757993,ELEMENTPARAMETER_DOUBLEVALUE2,false,2,true); //=============== //=============== // Link: RSI Previous => OverSold Previous //=============== element_7882752.LinkAdd(element_7674697,ELEMENTPARAMETER_DOUBLEVALUE1,false,0,true); //=============== //=============== // Link: Over Sold Level => OverSold Previous //=============== element_7882752.LinkAdd(element_7757993,ELEMENTPARAMETER_DOUBLEVALUE2,false,2,true); //=============== //=============== // Link: OverSold Now => Buy Signal //=============== element_3636154.LinkAdd(element_3630672,ELEMENTPARAMETER_BOOLVALUE,false,0,true); //=============== //=============== // Link: OverSold Previous => Buy Signal //=============== element_3636154.LinkAdd(element_7882752,ELEMENTPARAMETER_BOOLVALUE,true,1,true); //=============== //=============== // Link: RSI Current => OverBought Now //=============== element_7936012.LinkAdd(element_7678300,ELEMENTPARAMETER_DOUBLEVALUE1,false,0,true); //=============== //=============== // Link: Over Bought Level => OverBought Now //=============== element_7936012.LinkAdd(element_7763821,ELEMENTPARAMETER_DOUBLEVALUE2,false,2,true); //=============== //=============== // Link: RSI Previous => OverBought Previous //=============== element_7950952.LinkAdd(element_7674697,ELEMENTPARAMETER_DOUBLEVALUE1,false,0,true); //=============== //=============== // Link: Over Bought Level => OverBought Previous //=============== element_7950952.LinkAdd(element_7763821,ELEMENTPARAMETER_DOUBLEVALUE2,false,2,true); //=============== //=============== // Link: OverBought Now => Sell Signal //=============== element_3636410.LinkAdd(element_7936012,ELEMENTPARAMETER_BOOLVALUE,false,0,true); //=============== //=============== // Link: OverBought Previous => Sell Signal //=============== element_3636410.LinkAdd(element_7950952,ELEMENTPARAMETER_BOOLVALUE,true,1,true); //=============== //=============== // Link: Lots => Open Buy //=============== element_3641151.LinkAdd(element_4816263,ELEMENTPARAMETER_LOTS,false,3,true); //=============== //=============== // Link: Lots => Open Sell //=============== element_3636083.LinkAdd(element_4816263,ELEMENTPARAMETER_LOTS,false,3,true); //=============== //=============== // Link: Stop Loss, points => Lots //=============== element_4816263.LinkAdd(element_3649488,ELEMENTPARAMETER_STOPLOSSPOINTS,false,1,true); //=============== //=============== // Link: Risk Money => Lots //=============== element_4816263.LinkAdd(element_4986476,ELEMENTPARAMETER_MONEYRISKPERTRADE,false,2,true); //=============== //=============== // Link: Risk % per Trade => Risk //=============== element_5048973.LinkAdd(element_3632865,ELEMENTPARAMETER_DOUBLEVALUE1,false,1,true); //=============== //=============== // Link: Risk => Risk Money //=============== element_4986476.LinkAdd(element_5048973,ELEMENTPARAMETER_DOUBLEVALUE1,false,1,true); //=============== //=============== // Link: Balance => Risk Money //=============== element_4986476.LinkAdd(element_4956492,ELEMENTPARAMETER_DOUBLEVALUE2,false,3,true); //=============== //=============== Runner.OnInit(); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(INIT_SUCCEEDED); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnTick(void) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== /* DEBUG ASSERTION */ASSERT({},cPointer::Valid(Runner),true,{}) //=============== //=============== if(!cPointer::Valid(Runner))::ExpertRemove(); //=============== //=============== Runner.OnTick(); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== /* DEBUG ASSERTION */ASSERT({},cPointer::Valid(Runner),true,{}) //=============== //=============== if(!cPointer::Valid(Runner))return; //=============== //=============== Runner.OnDeinit(); //=============== //=============== cPointer::Delete(Runner); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cPointer final { //==================== private: //==================== //=============== //=============== void cPointer(void){} virtual void ~cPointer(void){} //=============== //=============== //==================== public: //==================== //=============== //=============== static bool Valid(const void *const pointer){return(::CheckPointer(pointer)!=POINTER_INVALID);} //=============== //=============== static void Delete(void *pointer); //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cPointer::Delete(void *pointer) { //=============== /* DEBUG ASSERTION */ASSERT({},::CheckPointer(pointer)==POINTER_DYNAMIC,true,{}) //=============== //=============== if(::CheckPointer(pointer)!=POINTER_DYNAMIC)return; //=============== //=============== delete pointer; //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cArray final { //==================== private: //==================== //=============== //=============== void cArray(void){} virtual void ~cArray(void){} //=============== //=============== static void Sort(int &indexes[],int &sortingvalues[],int &beg,int &end); //=============== //=============== //==================== public: //==================== //=============== //=============== template static void AddLast(T &to[],T item,const int reservesize); //=============== //=============== template static bool ValueExist(const T &array[],const T value); //=============== //=============== template static void Free(T &array[]){::ArrayFree(array);} template static void Initialize(T &array[],const T value){::ArrayInitialize(array,value);} template static int Size(const T &array[]){return(::ArraySize(array));} template static bool Resize(T &array[],const int size,const int reserve); //=============== //=============== static void SortAscend(int &indexes[],const int &sortingvalues[]); //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template static void cArray::AddLast(T &to[],T item,const int reservesize) { //=============== const int size=cArray::Size(to); //=============== //=============== if(!cArray::Resize(to,size+1,reservesize))return; //=============== //=============== to[size]=item; //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template static bool cArray::ValueExist(const T &array[],const T value) { //=============== bool result=false; //=============== //=============== const int size=cArray::Size(array); //=============== for(int i=0;i static bool cArray::Resize(T &array[],const int size,const int reserve) { //=============== const int arrayresizeresult=::ArrayResize(array,size,reserve); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},arrayresizeresult==size,false,::Print(TOSTRING(arrayresizeresult));) //=============== //=============== return(arrayresizeresult==size); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void cArray::SortAscend(int &indexes[],const int &sortingvalues[]) { //=============== const int size=cArray::Size(sortingvalues); //=============== //=============== cArray::Free(indexes); //=============== cArray::Resize(indexes,size,0); //=============== //=============== for(int cnt=0;cnt>1]; //=============== while(irefvalue) { //=============== if(j==0)break; //=============== j--; //=============== } //=============== //=============== if(i<=j) { //=============== if(sortingvalues[i]!=sortingvalues[j]) { //=============== tempdatavalue=sortingvalues[i]; tempindex=indexes[i]; sortingvalues[i]=sortingvalues[j]; indexes[i]=indexes[j]; sortingvalues[j]=tempdatavalue; indexes[j]=tempindex; //=============== } //=============== //=============== if(j==0) { //=============== i++; //=============== break; //=============== } //=============== //=============== i++; j--; //=============== } //=============== } //=============== //=============== if(beg class cVariable final : public cObject { //==================== private: //==================== //=============== //=============== T Value; //=============== //=============== //==================== public: //==================== //=============== //=============== void cVariable(void){} virtual void ~cVariable(void){} //=============== //=============== T Get(void)const{return(this.Value);} void Set(const T value){this.Value=value;} //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cRunner final { //==================== private: //==================== //=============== //=============== cExecutable *Elements[]; cExecutable *EndElements[]; //=============== //=============== void Clear(void); //=============== //=============== void Run(void)const; void SortParameters(void)const; //=============== //=============== //==================== public: //==================== //=============== //=============== void cRunner(void){cArray::Free(this.Elements);cArray::Free(this.EndElements);} virtual void ~cRunner(void){this.Clear();} //=============== //=============== void Add(cExecutable *const element,const bool isend); //=============== //=============== void OnDeinit(void); void OnTick(void)const{this.Run();} void OnInit(void)const{this.SortParameters();} //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cRunner::Run(void)const { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const int elements=cArray::Size(this.Elements); //=============== for(int i=0;i0) { //=============== if(!includehistory)return; //=============== //=============== this.Status=TRADESTATUS_HISTORY; //=============== } //=============== //=============== if(::OrderType()==OP_BUY) { //=============== this.Type=TRADETYPE_BUY; //=============== } else if(::OrderType()==OP_SELL) { //=============== this.Type=TRADETYPE_SELL; //=============== } //=============== //=============== this.Ticket = (long)::OrderTicket(); this.Symbol = ::OrderSymbol(); this.Magic = (long)::OrderMagicNumber(); this.Comment = ::OrderComment(); this.Lots = ::OrderLots(); this.OpenPrice = ::OrderOpenPrice(); this.ClosePrice = ::OrderClosePrice(); this.StopLoss = ::OrderStopLoss(); this.TakeProfit = ::OrderTakeProfit(); this.ProfitMoney = ::OrderProfit(); this.Swap = ::OrderSwap(); this.OpenTime = ::OrderOpenTime(); this.CloseTime = ::OrderCloseTime(); this.Commission = ::OrderCommission(); //=============== //=============== this.ProfitPoints=cTrade::ProfitPointsGet(this.Type,this.OpenPrice,this.ClosePrice,this.Symbol); //=============== //=============== if(searchoriginalticket)cTrade::GetOriginalTicket(this.Ticket,this.Comment); //=============== //=============== this.Identifier=this.Ticket; //=============== } //=============== //=============== #endif //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cTradeInfo::Update(const long ticket,const long identifier,const eTradeType type,const eTradeStatus status,const string symbol, const long magic,const string comment,const double lots,const double openprice,const double stoploss, const double takeprofit,const datetime opentime) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== this.ReSet(); //=============== //=============== this.Ticket = ticket; this.Identifier = identifier; this.Type = type; this.Status = status; this.Symbol = symbol; this.Magic = magic; this.Comment = comment; this.Lots = lots; this.OpenPrice = openprice; this.StopLoss = stoploss; this.TakeProfit = takeprofit; this.OpenTime = opentime; //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cTradeInfo::ReSet(void)override final { //=============== cInfo::ReSet(); //=============== //=============== this.ProfitMoney = 0.0; this.Commission = 0.0; this.Swap = 0.0; this.ClosePrice = 0.0; this.ProfitPoints = 0; this.Identifier = -1; this.Type = WRONG_VALUE; this.Status = WRONG_VALUE; //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cPendingOrderInfo final : public cInfo { //==================== private: //==================== //=============== //=============== datetime Expiration; ePendingOrderType Type; ePendingOrderStatus Status; //=============== //=============== //==================== public: //==================== //=============== //=============== void cPendingOrderInfo(void){this.ReSet();} virtual void ~cPendingOrderInfo(void){} //=============== //=============== datetime ExpirationGet(void)const{return(this.Expiration);} ePendingOrderType TypeGet(void)const{return(this.Type);} ePendingOrderStatus StatusGet(void)const{return(this.Status);} //=============== //=============== void Update(const long ticket); void Update(const long ticket,const ePendingOrderType type,const ePendingOrderStatus status,const string symbol,const long magic, const string comment,const double lots,const double openprice,const double stoploss,const double takeprofit, const datetime expiration,const datetime opentime); //=============== //=============== virtual void ReSet(void)override final; //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cPendingOrderInfo::Update(const long ticket) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== this.ReSet(); //=============== //=============== if(ticket<=0)return; //=============== //=============== #ifdef __MQL5__ //=============== //=============== ENUM_ORDER_TYPE ordertype=WRONG_VALUE; //=============== //=============== // Check Current //=============== if(::OrderSelect((ulong)ticket)) { //=============== ordertype=(ENUM_ORDER_TYPE)::OrderGetInteger(ORDER_TYPE); //=============== if(ordertype==ORDER_TYPE_BUY_STOP || ordertype==ORDER_TYPE_BUY_LIMIT || ordertype==ORDER_TYPE_SELL_STOP || ordertype==ORDER_TYPE_SELL_LIMIT) { //=============== this.Ticket = ::OrderGetInteger(ORDER_TICKET); this.Status = ORDERSTATUS_PENDING; this.Symbol = ::OrderGetString(ORDER_SYMBOL); this.Magic = ::OrderGetInteger(ORDER_MAGIC); this.Comment = ::OrderGetString(ORDER_COMMENT); this.Lots = ::OrderGetDouble(ORDER_VOLUME_CURRENT); this.OpenPrice = ::OrderGetDouble(ORDER_PRICE_OPEN); this.StopLoss = ::OrderGetDouble(ORDER_SL); this.TakeProfit = ::OrderGetDouble(ORDER_TP); this.OpenTime = (datetime)::OrderGetInteger(ORDER_TIME_SETUP); this.Expiration = (datetime)::OrderGetInteger(ORDER_TIME_EXPIRATION); this.CloseTime = 0; //=============== } else { //=============== ordertype=WRONG_VALUE; //=============== } //=============== } //=============== // Check History //=============== else if(::HistoryOrderSelect((ulong)ticket)) { //=============== ::ResetLastError(); //=============== //=============== ordertype=(ENUM_ORDER_TYPE)::HistoryOrderGetInteger((ulong)ticket,ORDER_TYPE); //=============== if(ordertype==ORDER_TYPE_BUY_STOP || ordertype==ORDER_TYPE_BUY_LIMIT || ordertype==ORDER_TYPE_SELL_STOP || ordertype==ORDER_TYPE_SELL_LIMIT) { //=============== this.Ticket = ::HistoryOrderGetInteger((ulong)ticket,ORDER_TICKET); this.Status = ORDERSTATUS_HISTORY; this.Symbol = ::HistoryOrderGetString((ulong)ticket,ORDER_SYMBOL); this.Magic = ::HistoryOrderGetInteger((ulong)ticket,ORDER_MAGIC); this.Comment = ::HistoryOrderGetString((ulong)ticket,ORDER_COMMENT); this.Lots = ::HistoryOrderGetDouble((ulong)ticket,ORDER_VOLUME_CURRENT); this.OpenPrice = ::HistoryOrderGetDouble((ulong)ticket,ORDER_PRICE_OPEN); this.StopLoss = ::HistoryOrderGetDouble((ulong)ticket,ORDER_SL); this.TakeProfit = ::HistoryOrderGetDouble((ulong)ticket,ORDER_TP); this.OpenTime = (datetime)::HistoryOrderGetInteger((ulong)ticket,ORDER_TIME_SETUP); this.Expiration = (datetime)::HistoryOrderGetInteger((ulong)ticket,ORDER_TIME_EXPIRATION); this.CloseTime = (datetime)::HistoryOrderGetInteger((ulong)ticket,ORDER_TIME_DONE); //=============== } else { //=============== ordertype=WRONG_VALUE; //=============== } //=============== } //=============== //=============== if(ordertype==ORDER_TYPE_BUY_STOP) { //=============== this.Type=PENDINGORDERTYPE_BUYSTOP; //=============== } else if(ordertype==ORDER_TYPE_BUY_LIMIT) { //=============== this.Type=PENDINGORDERTYPE_BUYLIMIT; //=============== } else if(ordertype==ORDER_TYPE_SELL_LIMIT) { //=============== this.Type=PENDINGORDERTYPE_SELLLIMIT; //=============== } else if(ordertype==ORDER_TYPE_SELL_STOP) { //=============== this.Type=PENDINGORDERTYPE_SELLSTOP; //=============== } //=============== //=============== //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== //=============== if(::OrderSelect((int)ticket,SELECT_BY_TICKET) && (::OrderType()==OP_BUYSTOP || ::OrderType()==OP_SELLSTOP || ::OrderType()==OP_BUYLIMIT || ::OrderType()==OP_SELLLIMIT)) { //=============== if(::OrderCloseTime()==0) { //=============== this.Status=ORDERSTATUS_PENDING; //=============== } //=============== else if(::OrderCloseTime()>0) { //=============== this.Status=ORDERSTATUS_HISTORY; //=============== } //=============== //=============== const int ordertype=::OrderType(); //=============== if(ordertype==OP_BUYSTOP) { //=============== this.Type=PENDINGORDERTYPE_BUYSTOP; //=============== } else if(ordertype==OP_BUYLIMIT) { //=============== this.Type=PENDINGORDERTYPE_BUYLIMIT; //=============== } else if(ordertype==OP_SELLLIMIT) { //=============== this.Type=PENDINGORDERTYPE_SELLLIMIT; //=============== } else if(ordertype==OP_SELLSTOP) { //=============== this.Type=PENDINGORDERTYPE_SELLSTOP; //=============== } //=============== this.Ticket = (long)::OrderTicket(); this.Symbol = ::OrderSymbol(); this.Magic = (long)::OrderMagicNumber(); this.Comment = ::OrderComment(); this.Lots = ::OrderLots(); this.OpenPrice = ::OrderOpenPrice(); this.StopLoss = ::OrderStopLoss(); this.TakeProfit = ::OrderTakeProfit(); this.OpenTime = ::OrderOpenTime(); this.CloseTime = ::OrderCloseTime(); this.Expiration = ::OrderExpiration(); //=============== } //=============== //=============== #endif //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cPendingOrderInfo::Update(const long ticket,const ePendingOrderType type,const ePendingOrderStatus status,const string symbol,const long magic, const string comment,const double lots,const double openprice,const double stoploss,const double takeprofit, const datetime expiration,const datetime opentime) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== this.ReSet(); //=============== //=============== this.Ticket = ticket; this.Type = type; this.Status = status; this.Symbol = symbol; this.Magic = magic; this.Comment = comment; this.Lots = lots; this.OpenPrice = openprice; this.StopLoss = stoploss; this.TakeProfit = takeprofit; this.Expiration = expiration; this.OpenTime = opentime; //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cPendingOrderInfo::ReSet(void)override final { //=============== cInfo::ReSet(); //=============== //=============== this.Expiration = 0; this.Type = WRONG_VALUE; this.Status = WRONG_VALUE; //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cGroupInfo { //==================== protected: //==================== //=============== //=============== double TotalLots; double AveragePrice; long ItemsNumber; long SymbolsNumber; long LowestOpenPriceTicket; long HighestOpenPriceTicket; long EarliestOpenTimeTicket; long LatestOpenTimeTicket; long EarliestCloseTimeTicket; long LatestCloseTimeTicket; //=============== //=============== virtual void ReSet(void); //=============== //=============== void cGroupInfo(void){this.ReSet();} //=============== //=============== //==================== public: //==================== //=============== //=============== virtual void ~cGroupInfo(void){} //=============== //=============== double TotalLotsGet(void)const{return(this.TotalLots);} double AveragePriceGet(void)const{return(this.AveragePrice);} long ItemsNumberGet(void)const{return(this.ItemsNumber);} long SymbolsNumberGet(void)const{return(this.SymbolsNumber);} long LowestOpenPriceTicketGet(void)const{return(this.LowestOpenPriceTicket);} long HighestOpenPriceTicketGet(void)const{return(this.HighestOpenPriceTicket);} long EarliestOpenTimeTicketGet(void)const{return(this.EarliestOpenTimeTicket);} long LatestOpenTimeTicketGet(void)const{return(this.LatestOpenTimeTicket);} long EarliestCloseTimeTicketGet(void)const{return(this.EarliestCloseTimeTicket);} long LatestCloseTimeTicketGet(void)const{return(this.LatestCloseTimeTicket);} //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cGroupInfo::ReSet(void) { //=============== this.TotalLots = 0.0; this.AveragePrice = 0.0; this.ItemsNumber = 0; this.SymbolsNumber = 0; this.LowestOpenPriceTicket = -1; this.HighestOpenPriceTicket = -1; this.EarliestOpenTimeTicket = -1; this.LatestOpenTimeTicket = -1; this.EarliestCloseTimeTicket = -1; this.LatestCloseTimeTicket = -1; //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cTradesGroupInfo final : public cGroupInfo { //==================== private: //==================== //=============== //=============== double ProfitMoney; long ProfitPoints; long LowestClosePriceTicket; long HighestClosePriceTicket; //=============== //=============== virtual void ReSet(void)override final; //=============== //=============== //==================== public: //==================== //=============== //=============== void cTradesGroupInfo(void){this.ReSet();} virtual void ~cTradesGroupInfo(void){} //=============== //=============== double ProfitMoneyGet(void)const{return(this.ProfitMoney);} long ProfitPointsGet(void)const{return(this.ProfitPoints);} long LowestClosePriceTicketGet(void)const{return(this.LowestClosePriceTicket);} long HighestClosePriceTicketGet(void)const{return(this.HighestClosePriceTicket);} //=============== //=============== void Update(const long &tickets[]); //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cTradesGroupInfo::Update(const long &tickets[]) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== this.ReSet(); //=============== //=============== cTradeInfo trades[]; //=============== //=============== cArray::Free(trades); //=============== //=============== const int size=cArray::Size(tickets); //=============== cArray::Resize(trades,size,0); //=============== //=============== for(int i=0;ihighestopenprice) { //=============== this.HighestOpenPriceTicket=ticket; //=============== highestopenprice=openprice; //=============== } //=============== //=============== if(closepricehighestcloseprice) { //=============== this.HighestClosePriceTicket=ticket; //=============== highestcloseprice=closeprice; //=============== } //=============== //=============== if(opentimelatestopentime) { //=============== this.LatestOpenTimeTicket=ticket; //=============== latestopentime=opentime; //=============== } //=============== //=============== if(closetimelatestclosetime) { //=============== this.LatestCloseTimeTicket=ticket; //=============== latestclosetime=closetime; //=============== } //=============== } //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cTradesGroupInfo::ReSet(void)override final { //=============== cGroupInfo::ReSet(); //=============== //=============== this.ProfitMoney = 0.0; this.ProfitPoints = 0; this.LowestClosePriceTicket = -1; this.HighestClosePriceTicket = -1; //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cPendingOrdersGroupInfo final : public cGroupInfo { //==================== private: //==================== //=============== //=============== virtual void ReSet(void)override final{cGroupInfo::ReSet();} //=============== //=============== //==================== public: //==================== //=============== //=============== void cPendingOrdersGroupInfo(void){this.ReSet();} virtual void ~cPendingOrdersGroupInfo(void){} //=============== //=============== void Update(const long &tickets[]); //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cPendingOrdersGroupInfo::Update(const long &tickets[]) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== this.ReSet(); //=============== //=============== cPendingOrderInfo orders[]; //=============== //=============== cArray::Free(orders); //=============== //=============== const int size=cArray::Size(tickets); //=============== cArray::Resize(orders,size,0); //=============== //=============== for(int i=0;ihighestopenprice) { //=============== this.HighestOpenPriceTicket=ticket; //=============== highestopenprice=openprice; //=============== } //=============== //=============== if(opentimelatestopentime) { //=============== this.LatestOpenTimeTicket=ticket; //=============== latestopentime=opentime; //=============== } //=============== //=============== if(closetimelatestclosetime) { //=============== this.LatestCloseTimeTicket=ticket; //=============== latestclosetime=closetime; //=============== } //=============== } //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cFilter { //==================== protected: //==================== //=============== //=============== bool FilterByMagic; long Magic; bool FilterBySymbol; string Symbol; bool FilterByType; bool FilterByTicketGreaterOrEqualThan; long TicketGreaterOrEqualThan; bool FilterByTicketLessOrEqualThan; long TicketLessOrEqualThan; bool FilterByExactComment; string ExactComment; bool FilterByCommentPartial; string CommentPartial; bool FilterByOpenPriceGreaterOrEqualThan; double OpenPriceGreaterOrEqualThan; bool FilterByOpenPriceLessOrEqualThan; double OpenPriceLessOrEqualThan; bool FilterByOpenTimeGreaterOrEqualThan; datetime OpenTimeGreaterOrEqualThan; bool FilterByOpenTimeLessOrEqualThan; datetime OpenTimeLessOrEqualThan; bool FilterByCloseTimeGreaterOrEqualThan; datetime CloseTimeGreaterOrEqualThan; bool FilterByCloseTimeLessOrEqualThan; datetime CloseTimeLessOrEqualThan; bool FilterByLotsGreaterOrEqualThan; double LotsGreaterOrEqualThan; bool FilterByLotsLessOrEqualThan; double LotsLessOrEqualThan; //=============== //=============== virtual void ReSet(void); //=============== //=============== void cFilter(void){this.ReSet();} //=============== //=============== //==================== public: //==================== //=============== //=============== virtual void ~cFilter(void){} //=============== //=============== void FilterByMagicSet(const bool filterbymagic){this.FilterByMagic=filterbymagic;} void MagicSet(const long magic){this.Magic=magic;} void FilterBySymbolSet(const bool filterbysymbol){this.FilterBySymbol=filterbysymbol;} void SymbolSet(const string symbol){this.Symbol=symbol;} void FilterByTypeSet(const bool filterbytype){this.FilterByType=filterbytype;} void FilterByTicketGreaterSet(const bool filterbyticketgreater){this.FilterByTicketGreaterOrEqualThan=filterbyticketgreater;} void TicketGreaterSet(const long ticketgreater){this.TicketGreaterOrEqualThan=ticketgreater;} void FilterByTicketLessSet(const bool filterbyticketless){this.FilterByTicketLessOrEqualThan=filterbyticketless;} void TicketLessSet(const long ticketless){this.TicketLessOrEqualThan=ticketless;} void FilterByExactCommentSet(const bool filterbyexactcomment){this.FilterByExactComment=filterbyexactcomment;} void ExactCommentSet(const string exactcomment){this.ExactComment=exactcomment;} void FilterByCommentPartialSet(const bool filterbycommentpartial){this.FilterByCommentPartial=filterbycommentpartial;} void CommentPartialSet(const string commentpartial){this.CommentPartial=commentpartial;} void FilterByOpenPriceGreaterSet(const bool filterbyopenpricegreater){this.FilterByOpenPriceGreaterOrEqualThan=filterbyopenpricegreater;} void OpenPriceGreaterSet(const double openpricegreater){this.OpenPriceGreaterOrEqualThan=openpricegreater;} void FilterByOpenPriceLessSet(const bool filterbyopenpriceless){this.FilterByOpenPriceLessOrEqualThan=filterbyopenpriceless;} void OpenPriceLessSet(const double openpriceless){this.OpenPriceLessOrEqualThan=openpriceless;} void FilterByOpenTimeGreaterSet(const bool filterbyopentimegreater){this.FilterByOpenTimeGreaterOrEqualThan=filterbyopentimegreater;} void OpenTimeGreaterSet(const datetime opentimegreater){this.OpenTimeGreaterOrEqualThan=opentimegreater;} void FilterByOpenTimeLessSet(const bool filterbyopentimeless){this.FilterByOpenTimeLessOrEqualThan=filterbyopentimeless;} void OpenTimeLessSet(const datetime opentimeless){this.OpenTimeLessOrEqualThan=opentimeless;} void FilterByCloseTimeGreaterSet(const bool filterbyclosetimegreater){this.FilterByCloseTimeGreaterOrEqualThan=filterbyclosetimegreater;} void CloseTimeGreaterSet(const datetime closetimegreater){this.CloseTimeGreaterOrEqualThan=closetimegreater;} void FilterByCloseTimeLessSet(const bool filterbyclosetimeless){this.FilterByCloseTimeLessOrEqualThan=filterbyclosetimeless;} void CloseTimeLessSet(const datetime closetimeless){this.CloseTimeLessOrEqualThan=closetimeless;} void FilterByLotsGreaterSet(const bool filterbylotsgreater){this.FilterByLotsGreaterOrEqualThan=filterbylotsgreater;} void LotsGreaterSet(const double lotsgreater){this.LotsGreaterOrEqualThan=lotsgreater;} void FilterByLotsLessSet(const bool filterbylotsless){this.FilterByLotsLessOrEqualThan=filterbylotsless;} void LotsLessSet(const double lotsless){this.LotsLessOrEqualThan=lotsless;} //=============== //=============== bool SelectHistory(void)const; //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cFilter::SelectHistory(void)const { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== bool result=false; //=============== //=============== #ifdef __MQL5__ //=============== //=============== const datetime fromtime=0; //=============== const datetime tilltime=::TimeCurrent()+60; //=============== //=============== result=::HistorySelect(fromtime,tilltime); //=============== //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== /* DEBUG ASSERTION */ASSERT({},false,true,{}) //=============== #endif //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(result); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cFilter::ReSet(void) { //=============== this.FilterByMagic = false; this.Magic = -1; this.FilterBySymbol = false; this.Symbol = NULL; this.FilterByType = false; this.FilterByTicketGreaterOrEqualThan = false; this.TicketGreaterOrEqualThan = -1; this.FilterByTicketLessOrEqualThan = false; this.TicketLessOrEqualThan = -1; this.FilterByExactComment = false; this.ExactComment = NULL; this.FilterByCommentPartial = false; this.CommentPartial = NULL; this.FilterByOpenPriceGreaterOrEqualThan = false; this.OpenPriceGreaterOrEqualThan = 0.0; this.FilterByOpenPriceLessOrEqualThan = false; this.OpenPriceLessOrEqualThan = 0.0; this.FilterByOpenTimeGreaterOrEqualThan = false; this.OpenTimeGreaterOrEqualThan = 0; this.FilterByOpenTimeLessOrEqualThan = false; this.OpenTimeLessOrEqualThan = 0; this.FilterByCloseTimeGreaterOrEqualThan = false; this.CloseTimeGreaterOrEqualThan = 0; this.FilterByCloseTimeLessOrEqualThan = false; this.CloseTimeLessOrEqualThan = 0; this.FilterByLotsGreaterOrEqualThan = false; this.LotsGreaterOrEqualThan = 0.0; this.FilterByLotsLessOrEqualThan = false; this.LotsLessOrEqualThan = 0.0; //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cTradesFilter final : public cFilter { //==================== private: //==================== //=============== //=============== eTradeStatus Status; eTradeType Type; bool FilterByProfitGreaterOrEqualThan; double ProfitGreaterOrEqualThan; bool FilterByProfitLessOrEqualThan; double ProfitLessOrEqualThan; bool FilterByClosePriceGreaterOrEqualThan; double ClosePriceGreaterOrEqualThan; bool FilterByClosePriceLessOrEqualThan; double ClosePriceLessOrEqualThan; //=============== //=============== virtual void ReSet(void)override final; //=============== //=============== //==================== public: //==================== //=============== //=============== void cTradesFilter(void){this.ReSet();} virtual void ~cTradesFilter(void){} //=============== //=============== void StatusSet(const eTradeStatus status){this.Status=status;} void TypeSet(const eTradeType type){this.Type=type;} void FilterByProfitGreaterSet(const bool filterbyprofitgreater){this.FilterByProfitGreaterOrEqualThan=filterbyprofitgreater;} void ProfitGreaterSet(const double profitgreater){this.ProfitGreaterOrEqualThan=profitgreater;} void FilterByProfitLessSet(const bool filterbyprofitless){this.FilterByProfitLessOrEqualThan=filterbyprofitless;} void ProfitLessSet(const double profitless){this.ProfitLessOrEqualThan=profitless;} void FilterByClosePriceGreaterSet(const bool filterbyclosepricegreater){this.FilterByClosePriceGreaterOrEqualThan=filterbyclosepricegreater;} void ClosePriceGreaterSet(const double closepricegreater){this.ClosePriceGreaterOrEqualThan=closepricegreater;} void FilterByClosePriceLessSet(const bool filterbyclosepriceless){this.FilterByClosePriceLessOrEqualThan=filterbyclosepriceless;} void ClosePriceLessSet(const double closepriceless){this.ClosePriceLessOrEqualThan=closepriceless;} //=============== //=============== eTradeStatus StatusGet(void)const{return(this.Status);} //=============== //=============== bool Passed(const cTradeInfo &trade)const; //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cTradesFilter::Passed(const cTradeInfo &trade)const { //=============== if(trade.TicketGet()<=0)return(false); //=============== //=============== if(this.FilterByMagic && trade.MagicGet()!=this.Magic)return(false); //=============== //=============== if(this.FilterBySymbol && trade.SymbolGet()!=this.Symbol)return(false); //=============== //=============== if(this.Status!=TRADESTATUS_ALL && trade.StatusGet()!=this.Status)return(false); //=============== //=============== if(this.FilterByType && trade.TypeGet()!=this.Type)return(false); //=============== //=============== if(this.FilterByTicketGreaterOrEqualThan && trade.TicketGet()this.TicketLessOrEqualThan)return(false); //=============== //=============== if(this.FilterByExactComment && trade.CommentGet()!=this.ExactComment)return(false); //=============== //=============== if(this.FilterByCommentPartial && ::StringFind(trade.CommentGet(),this.CommentPartial,0)<0)return(false); //=============== //=============== if(this.FilterByOpenPriceGreaterOrEqualThan && trade.OpenPriceGet()this.OpenPriceLessOrEqualThan)return(false); //=============== //=============== if(this.FilterByClosePriceGreaterOrEqualThan && trade.ClosePriceGet()this.ClosePriceLessOrEqualThan)return(false); //=============== //=============== if(this.FilterByLotsGreaterOrEqualThan && trade.LotsGet()this.LotsLessOrEqualThan)return(false); //=============== //=============== if(this.FilterByOpenTimeGreaterOrEqualThan && trade.OpenTimeGet()this.OpenTimeLessOrEqualThan)return(false); //=============== //=============== if(this.FilterByCloseTimeGreaterOrEqualThan && trade.CloseTimeGet()this.CloseTimeLessOrEqualThan)return(false); //=============== //=============== if(this.FilterByProfitGreaterOrEqualThan && trade.ProfitMoneyGet()this.ProfitLessOrEqualThan)return(false); //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cTradesFilter::ReSet(void)override final { //=============== cFilter::ReSet(); //=============== //=============== this.Status = WRONG_VALUE; this.Type = WRONG_VALUE; this.FilterByProfitGreaterOrEqualThan = false; this.ProfitGreaterOrEqualThan = 0.0; this.FilterByProfitLessOrEqualThan = false; this.ProfitLessOrEqualThan = 0.0; this.FilterByClosePriceGreaterOrEqualThan = false; this.ClosePriceGreaterOrEqualThan = 0.0; this.FilterByClosePriceLessOrEqualThan = false; this.ClosePriceLessOrEqualThan = 0.0; //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cPendingOrdersFilter final : public cFilter { //==================== private: //==================== //=============== //=============== ePendingOrderStatus Status; ePendingOrderType Type; //=============== //=============== virtual void ReSet(void)override final; //=============== //=============== //==================== public: //==================== //=============== //=============== void cPendingOrdersFilter(void){this.ReSet();} virtual void ~cPendingOrdersFilter(void){} //=============== //=============== void StatusSet(const ePendingOrderStatus status){this.Status=status;} void TypeSet(const ePendingOrderType type){this.Type=type;} //=============== //=============== ePendingOrderStatus StatusGet(void)const{return(this.Status);} //=============== //=============== bool Passed(const cPendingOrderInfo &order)const; //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cPendingOrdersFilter::Passed(const cPendingOrderInfo &order)const { //=============== if(order.TicketGet()<=0)return(false); //=============== //=============== if(this.FilterByMagic && order.MagicGet()!=this.Magic)return(false); //=============== //=============== if(this.FilterBySymbol && order.SymbolGet()!=this.Symbol)return(false); //=============== //=============== if(this.Status!=ORDERSTATUS_ALL && order.StatusGet()!=this.Status)return(false); //=============== //=============== if(this.FilterByType && order.TypeGet()!=this.Type)return(false); //=============== //=============== if(this.FilterByTicketGreaterOrEqualThan && order.TicketGet()this.TicketLessOrEqualThan)return(false); //=============== //=============== if(this.FilterByExactComment && order.CommentGet()!=this.ExactComment)return(false); //=============== //=============== if(this.FilterByCommentPartial && ::StringFind(order.CommentGet(),this.CommentPartial,0)<0)return(false); //=============== //=============== if(this.FilterByOpenPriceGreaterOrEqualThan && order.OpenPriceGet()this.OpenPriceLessOrEqualThan)return(false); //=============== //=============== if(this.FilterByOpenTimeGreaterOrEqualThan && order.OpenTimeGet()this.OpenTimeLessOrEqualThan)return(false); //=============== //=============== if(this.FilterByCloseTimeGreaterOrEqualThan && (order.CloseTimeGet()==0 || order.CloseTimeGet()this.CloseTimeLessOrEqualThan))return(false); //=============== //=============== if(this.FilterByLotsGreaterOrEqualThan && order.LotsGet()this.LotsLessOrEqualThan)return(false); //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cPendingOrdersFilter::ReSet(void)override final { //=============== cFilter::ReSet(); //=============== //=============== this.Status = WRONG_VALUE; this.Type = WRONG_VALUE; //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cTrade final { //==================== private: //==================== //=============== //=============== void cTrade(void){} virtual void ~cTrade(void){} //=============== //=============== static void AddCurrentTrades(const cTradesFilter &filter,long &tickets[]); static void AddCurrentOrders(const cPendingOrdersFilter &filter,long &tickets[]); static void AddHistoryTrades(const cTradesFilter &filter,long &tickets[]); static void AddHistoryOrders(const cPendingOrdersFilter &filter,long &tickets[]); //=============== //=============== static double ExistingVolume(const string symbol,const eTradeType type); //=============== //=============== static bool CheckMaxOrders(void); static bool CheckMaxVolume(const string symbol,const eTradeType type,const double volume); static bool CheckPlaced(const string symbol,const eTradeType type,const long magic); static bool CheckMargin(const string symbol,const double volume,const eTradeType type,const double price); static bool CheckOrderPrice(const string symbol,const ePendingOrderType type,const double price); static bool CheckStops(const string symbol,const eTradeType type,const bool istrade,const double entrylevel, const double stoploss,const double takeprofit); //=============== //=============== static int GetMatch(const cTradeInfo &trades[],const int forindex,const long &matched[]); static void TradesCloseBy(const long &tickets[],const bool slippageenabled,const long slippage); //=============== //=============== static void CloseBy(const long ticket1,const long ticket2); //=============== //=============== static void BreakEven(const long ticket,const long belevel,const long beprofit); static void TrailingStop(const long ticket,const long tslstart,const long tsldistance,const bool tsllevelenabled,const double tsllevel); //=============== //=============== static void CalculateSLandTP(const string symbol,const eTradeType type,const double entrylevel,const double lots, const bool slpointsenabled,const long slpoints,const bool tppointsenabled,const long tppoints, const bool slmoneyenabled,const double slmoney,const bool tpmoneyenabled,const double tpmoney, const bool slpriceenabled,const double slprice,const bool tppriceenabled,const double tpprice, double &sllevel,double &tplevel); //=============== //=============== static bool OpeningAllowed(const string symbol,const eTradeType type); static bool ClosingAllowed(const string symbol); //=============== //=============== static void NettPosition(const cTradeInfo &trades[],cTradeInfo &tradesnetted[]); static void GetSymbols(const cTradeInfo &trades[],string &symbols[]); static void GetSymbolTrades(const cTradeInfo &trades[],const string symbol,cTradeInfo &symboltrades[]); static bool GetDealAsTradeFromSelectedHistory(const long ticket,cTradeInfo &trade); //=============== //=============== static bool CanTrade(void); //=============== //=============== #ifdef __MQL5__ static ENUM_ORDER_TYPE_FILLING GetFilling(const string symbol); #endif //=============== //=============== //==================== public: //==================== //=============== //=============== static bool IsNettingAccount(void); //=============== //=============== static void GetPositionAsDeals(const long ticket,cTradeInfo &trades[],const bool searchoriginalticket); static void GetDealAsTrade(const long ticket,cTradeInfo &trade); //=============== //=============== static void GetOriginalTicket(long &originalticket,const string currentcomment); //=============== //=============== static void NettTrades(const cTradeInfo &trades[],cTradeInfo &tradesnetted[]); //=============== //=============== static long ProfitPointsGet(const eTradeType type,const double openprice,const double closeprice,const string symbol); static double CommissionGet(const long positionID); //=============== //=============== static double PointPrice(const string symbol); //=============== //=============== static void GetFilteredTradesTickets(const cTradesFilter &filter,long &tickets[]); static void GetFilteredPendingOrdersTickets(const cPendingOrdersFilter &filter,long &tickets[]); //=============== //=============== static bool TradeTypeAllowed(const eAllowedTrades allowed,const eTradeType type); //=============== //=============== static double CheckLot(const string symbol,const double lots); static double GetLot(const string symbol,const long slpoints,const double moneyrisk); static double CalculateLot(const string symbol,const eTradeType type,const double requiredbelevel,const double dealprice, const double lotsnow,const double belevelnow); //=============== //=============== static long OpenTrade(const string symbol,const eTradeType type,const double lots,const long magic,const string comment, const long slippage,const bool checkplaced,uint &retcode,eError &myretcode); static long OpenTrade(const string symbol,const eTradeType type,const double lots,const long magic,const string comment, const bool slpointsenabled,const long slpoints,const bool tppointsenabled,const long tppoints, const bool slmoneyenabled,const double slmoney,const bool tpmoneyenabled,const double tpmoney, const bool slpriceenabled,const double slprice,const bool tppriceenabled,const double tpprice, const bool slippageenabled,const long slippage,const bool checkplaced,uint &retcode,eError &myretcode); //=============== //=============== static long PlacePendingOrder(const string symbol,const double price,const ePendingOrderType type,const double lots, const long magic,const string comment,const datetime expiration,uint &retcode,eError &myretcode); static long PlacePendingOrder(const string symbol,const double price,const ePendingOrderType type,const double lots, const long magic,const string comment, const bool slpointsenabled,const long slpoints,const bool tppointsenabled,const long tppoints, const bool slmoneyenabled,const double slmoney,const bool tpmoneyenabled,const double tpmoney, const bool slpriceenabled,const double slprice,const bool tppriceenabled,const double tpprice, const bool expirationenabled,const datetime expiration,uint &retcode,eError &myretcode); //=============== //=============== static bool ModifyTrade(const long ticket,const double newsl,const double newtp,uint &retcode,eError &myretcode); static void ModifyTrade(const long ticket,const bool tightenstopsonly, const bool slpointsenabled,const long slpoints,const bool tppointsenabled,const long tppoints, const bool slmoneyenabled,const double slmoney,const bool tpmoneyenabled,const double tpmoney, const bool slpriceenabled,const double slprice,const bool tppriceenabled,const double tpprice); static void ModifyTrades(const long &tickets[],const bool tightenstopsonly, const bool slpointsenabled,const long slpoints,const bool tppointsenabled,const long tppoints, const bool slmoneyenabled,const double slmoney,const bool tpmoneyenabled,const double tpmoney, const bool slpriceenabled,const double slprice,const bool tppriceenabled,const double tpprice); //=============== //=============== static bool ModifyPendingOrder(const long ticket,const double newprice,const double newsl,const double newtp, const datetime newexpiration,uint &retcode,eError &myretcode); static void ModifyPendingOrder(const long ticket,const bool priceenabled,const double price,const bool tightenstopsonly, const bool slpointsenabled,const long slpoints,const bool tppointsenabled,const long tppoints, const bool slmoneyenabled,const double slmoney,const bool tpmoneyenabled,const double tpmoney, const bool slpriceenabled,const double slprice,const bool tppriceenabled,const double tpprice, const bool expirationenabled,const datetime expiration); static void ModifyPendingOrders(const long &tickets[],const bool priceenabled,const double price,const bool tightenstopsonly, const bool slpointsenabled,const long slpoints,const bool tppointsenabled,const long tppoints, const bool slmoneyenabled,const double slmoney,const bool tpmoneyenabled,const double tpmoney, const bool slpriceenabled,const double slprice,const bool tppriceenabled,const double tpprice, const bool expirationenabled,const datetime expiration); //=============== //=============== static bool CloseTrade(const long ticket,const bool slippageenabled,const long slippage,const double lots,uint &retcode,eError &myretcode); static void CloseTrades(const long &tickets[],const bool closeby,const bool slippageenabled,const long slippage); //=============== //=============== static bool DeletePendingOrder(const long ticket,uint &retcode,eError &myretcode); static void DeletePendingOrders(const long &tickets[]); //=============== //=============== static void BreakEven(const long &tickets[],const long belevel,const long beprofit); static void TrailingStop(const long &tickets[],const long tslstart,const long tsldistance,const bool tsllevelenabled,const double tsllevel); //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::CheckMaxOrders(void) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== static const int maxallowed = (int)::AccountInfoInteger(ACCOUNT_LIMIT_ORDERS); const int existing = #ifdef __MQL5__ ::PositionsTotal() + ::OrdersTotal() #endif #ifdef __MQL4__ ::OrdersTotal() #endif; //=============== //=============== if(existing>=maxallowed && maxallowed!=0)return(false); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static double cTrade::ExistingVolume(const string symbol,const eTradeType type) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== double result=0; //=============== //=============== #ifdef __MQL5__ //=============== const int tradesnumber=::PositionsTotal(); //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== const int tradesnumber=::OrdersTotal(); //=============== #endif //=============== //=============== for(int i=0;imaxallowedvolume)return(false); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::CheckPlaced(const string symbol,const eTradeType type,const long magic) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== #ifdef __MQL5__ //=============== //=============== static const bool istesting=(bool)::MQLInfoInteger(MQL_TESTER); //=============== //=============== if(istesting)return(true); //=============== //=============== const int ordersnumber=::OrdersTotal(); //=============== //=============== for(int i=0;i0)continue; //=============== //=============== if(type==TRADETYPE_BUY && ordertype==ORDER_TYPE_BUY)return(false); //=============== //=============== if(type==TRADETYPE_SELL && ordertype==ORDER_TYPE_SELL)return(false); //=============== } //=============== //=============== #endif //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::CheckMargin(const string symbol,const double volume,const eTradeType type,const double price) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== #ifdef __MQL5__ //=============== //=============== const ENUM_ORDER_TYPE ordertype=(type==TRADETYPE_BUY?ORDER_TYPE_BUY:ORDER_TYPE_SELL); //=============== //=============== double init = 0.0; double main = 0.0; double order = 0.0; //=============== //=============== const double tickvalue = ::SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_VALUE); const double ticksize = ::SymbolInfoDouble(symbol, SYMBOL_TRADE_TICK_SIZE); const int leverage = (int)::AccountInfoInteger(ACCOUNT_LEVERAGE); //=============== //=============== const bool getrate=::SymbolInfoMarginRate(symbol,ordertype,init,main); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},getrate,false,{}) //=============== //=============== if(!getrate || ticksize*leverage==0) { //=============== const bool calculate=::OrderCalcMargin(ordertype,symbol,volume,price,order); //=============== /* DEBUG ASSERTION */ASSERT({},calculate,false,{}) //=============== } //=============== //=============== const double marginrequired=(getrate && ticksize*leverage!=0)?(init*price*volume*tickvalue/(ticksize*leverage)):order; //=============== //=============== const bool result=(marginrequired<=0 || marginrequired<::AccountInfoDouble(ACCOUNT_MARGIN_FREE)); //=============== //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== //=============== const double marginrequired=::MarketInfo(symbol,MODE_MARGINREQUIRED)*volume; //=============== //=============== const bool result=(marginrequired<=0 || marginrequired<::AccountInfoDouble(ACCOUNT_MARGIN_FREE)); //=============== //=============== #endif //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(result); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::CheckOrderPrice(const string symbol,const ePendingOrderType type,const double price) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== if(price<=0)return(false); //=============== //=============== MqlTick lasttick; //=============== ::ZeroMemory(lasttick); //=============== const bool gettick=::SymbolInfoTick(symbol,lasttick); //=============== /* DEBUG ASSERTION */ASSERT({},gettick,true,{}) //=============== if(!gettick)return(false); //=============== //=============== const int stopslevel = (int)::SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL); const double point = ::SymbolInfoDouble(symbol,SYMBOL_POINT); const double mindistance = (stopslevel>0?(stopslevel*point):(2.0*(lasttick.ask-lasttick.bid))); //=============== //=============== switch(type) { //=============== case PENDINGORDERTYPE_BUYSTOP : if((price-lasttick.ask)<=mindistance)return(false); break; case PENDINGORDERTYPE_BUYLIMIT : if((lasttick.ask-price)<=mindistance)return(false); break; case PENDINGORDERTYPE_SELLSTOP : if((lasttick.bid-price)<=mindistance)return(false); break; case PENDINGORDERTYPE_SELLLIMIT : if((price-lasttick.bid)<=mindistance)return(false); break; //=============== default :/* DEBUG ASSERTION */ASSERT({},false,false,{}) break; //=============== } //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::CheckStops(const string symbol,const eTradeType type,const bool istrade,const double entrylevel, const double stoploss,const double takeprofit) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== if(stoploss==0 && takeprofit==0)return(true); //=============== //=============== if(stoploss<0 || takeprofit<0)return(false); //=============== //=============== MqlTick lasttick; //=============== ::ZeroMemory(lasttick); //=============== const bool gettick=::SymbolInfoTick(symbol,lasttick); //=============== /* DEBUG ASSERTION */ASSERT({},gettick,true,{}) //=============== if(!gettick)return(false); //=============== //=============== const int stopslevel = (int)::SymbolInfoInteger(symbol,SYMBOL_TRADE_STOPS_LEVEL); const double point = ::SymbolInfoDouble(symbol,SYMBOL_POINT); const double mindistance = (stopslevel>0?(stopslevel*point):(2.0*(lasttick.ask-lasttick.bid))); //=============== //=============== if(type==TRADETYPE_BUY) { //=============== if(!istrade && stoploss>0 && (entrylevel-stoploss)<=mindistance)return(false); if(istrade && stoploss>0 && (lasttick.bid-stoploss)<=mindistance)return(false); //=============== //=============== if(!istrade && takeprofit>0 && (takeprofit-entrylevel)<=mindistance)return(false); if(istrade && takeprofit>0 && (takeprofit-lasttick.bid)<=mindistance)return(false); //=============== } //=============== //=============== if(type==TRADETYPE_SELL) { //=============== if(!istrade && stoploss>0 && (stoploss-entrylevel)<=mindistance)return(false); if(istrade && stoploss>0 && (stoploss-lasttick.ask)<=mindistance)return(false); //=============== //=============== if(!istrade && takeprofit>0 && (entrylevel-takeprofit)<=mindistance)return(false); if(istrade && takeprofit>0 && (lasttick.ask-takeprofit)<=mindistance)return(false); //=============== } //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static int cTrade::GetMatch(const cTradeInfo &trades[],const int forindex,const long &matched[]) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== if(trades[forindex].TicketGet()<=0 || trades[forindex].StatusGet()!=TRADESTATUS_CURRENT)return(-1); //=============== //=============== #ifdef __MQL5__ //=============== const int ordermode=(int)::SymbolInfoInteger(trades[forindex].SymbolGet(),SYMBOL_ORDER_MODE); //=============== const bool orderallowed=((SYMBOL_ORDER_CLOSEBY&ordermode)==SYMBOL_ORDER_CLOSEBY); //=============== /* DEBUG ASSERTION */ASSERT({},orderallowed,true,{}) //=============== if(!orderallowed)return(-1); //=============== #endif //=============== //=============== int result=-1; //=============== //=============== const int size=cArray::Size(trades); //=============== //=============== for(int i=forindex+1;i0) { //=============== cArray::AddLast(tickets1,tickets[i],size); //=============== //=============== cArray::AddLast(tickets2,tickets[matchedindex],size); //=============== } else { //=============== cArray::AddLast(nomatch,tickets[i],size); //=============== } //=============== } //=============== //=============== const int size1 = cArray::Size(tickets1); const int size2 = cArray::Size(tickets2); const int nomatchsize = cArray::Size(nomatch); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},size1==size2,false,{}) //=============== /* DEBUG ASSERTION */ASSERT({},size1+size2+nomatchsize==size,false,{}) //=============== //=============== for(int i=0;i=0) { //=============== const int ticket=(int)::StringToInteger(::StringSubstr(currentcomment,searchfromresult+::StringLen(SEARCHFROM))); //=============== //=============== const int tradesnumber=::OrdersHistoryTotal(); //=============== //=============== // Check for closeby scenario //=============== for(int i=0;i=0) { //=============== originalticket=::OrderTicket(); //=============== //=============== return; //=============== } //=============== } //=============== //=============== if(!::OrderSelect(ticket,SELECT_BY_TICKET,MODE_HISTORY))return; //=============== //=============== originalticket=ticket; //=============== //=============== cTrade::GetOriginalTicket(originalticket,::OrderComment()); //=============== //=============== return; //=============== } //=============== //=============== if(searchtoresult>=0) { //=============== const int tradesnumber=::OrdersHistoryTotal(); //=============== //=============== for(int i=0;i=0) { //=============== originalticket=::OrderTicket(); //=============== //=============== cTrade::GetOriginalTicket(originalticket,comment); //=============== //=============== return; //=============== } //=============== } //=============== } //=============== //=============== #endif //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::GetDealAsTradeFromSelectedHistory(const long ticket,cTradeInfo &trade) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== #ifdef __MQL5__ //=============== //=============== const int dealstotal=::HistoryDealsTotal(); //=============== //=============== for(int i=dealstotal-1;i>=0 && !::IsStopped();i--) { //=============== const ulong dealticket = ::HistoryDealGetTicket(i); const long dealorder = ::HistoryDealGetInteger(dealticket,DEAL_ORDER); //=============== //=============== if(dealorder!=ticket)continue; //=============== //=============== const long identifier =::HistoryDealGetInteger(dealticket,DEAL_POSITION_ID); const datetime opentime = (datetime)::HistoryDealGetInteger(dealticket,DEAL_TIME); const long magic = ::HistoryDealGetInteger(dealticket,DEAL_MAGIC); const string comment = ::HistoryDealGetString(dealticket,DEAL_COMMENT); const string symbol = ::HistoryDealGetString(dealticket,DEAL_SYMBOL); const double lots = ::HistoryDealGetDouble(dealticket,DEAL_VOLUME); const double openprice = ::HistoryDealGetDouble(dealticket,DEAL_PRICE); const ENUM_DEAL_TYPE type = (ENUM_DEAL_TYPE)::HistoryDealGetInteger(dealticket,DEAL_TYPE); //=============== //=============== trade.Update(dealorder,identifier,type==DEAL_TYPE_BUY?TRADETYPE_BUY:TRADETYPE_SELL,TRADESTATUS_CURRENT,symbol, magic,comment,lots,openprice,0,0,opentime); //=============== //=============== return(true); //=============== } //=============== //=============== #endif //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(false); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void cTrade::GetPositionAsDeals(const long ticket,cTradeInfo &trades[],const bool searchoriginalticket) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== cArray::Free(trades); //=============== //=============== // Hedging Accounts //=============== if(!cTrade::IsNettingAccount()) { //=============== cArray::Resize(trades,1,0); //=============== //=============== trades[0].Update(ticket,false,false,searchoriginalticket); //=============== } //=============== // Netting Accounts //=============== else { //=============== #ifdef __MQL5__ //=============== //=============== const bool select=::PositionSelectByTicket(ticket); //=============== //=============== if(!select)return; //=============== //=============== const long identifier = ::PositionGetInteger(POSITION_IDENTIFIER); const double takeprofit = ::PositionGetDouble(POSITION_TP); const double stoploss = ::PositionGetDouble(POSITION_SL); const string symbol = ::PositionGetString(POSITION_SYMBOL); //=============== //=============== if(::HistorySelectByPosition(identifier)) { //=============== const int deals=::HistoryDealsTotal(); //=============== //=============== cArray::Resize(trades,deals,0); //=============== //=============== for(int i=0;i No netting required, just copy as is //=============== bool neednetting = false; eTradeType prevtype = WRONG_VALUE; string symbol = NULL; //=============== for(int i=0;i0 && type==TRADETYPE_SELL) || (netlots<0 && type==TRADETYPE_BUY)) { //=============== // OUT SCENARIO //=============== if(lot<::MathAbs(netlots)) { //=============== double closedlots=0; //=============== //=============== // Check what should be closed before //=============== for(int j=0;j=lot)break; //=============== } //=============== //=============== // Closing a trade //=============== closed[i]=true; //=============== } //=============== // INOUT SCENARIO //=============== else { //=============== // Close everything before //=============== for(int j=0;j0) || (slpriceenabled && slprice>0) || (slmoneyenabled && slmoney>0)); const bool changetp=((tppointsenabled && tppoints>0) || (tppriceenabled && tpprice>0) || (tpmoneyenabled && tpmoney>0)); //=============== //=============== if(!changesl && !changetp)return; //=============== //=============== const double point = ::SymbolInfoDouble(symbol,SYMBOL_POINT); const int digits = (int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS); const double ticksize = ::SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE); //=============== //=============== const double pointprice=lots*cTrade::PointPrice(symbol); //=============== //=============== if(slpointsenabled && slpoints>0)sllevel=(type==TRADETYPE_BUY?(entrylevel-slpoints*point):(entrylevel+slpoints*point)); if(tppointsenabled && tppoints>0)tplevel=(type==TRADETYPE_BUY?(entrylevel+tppoints*point):(entrylevel-tppoints*point)); //=============== //=============== if(slpriceenabled && slprice>0)sllevel=(type==TRADETYPE_BUY?(::MathMax(sllevel,slprice)):(sllevel>0?(::MathMin(sllevel,slprice)):slprice)); if(tppriceenabled && tpprice>0)tplevel=(type==TRADETYPE_BUY?(tplevel>0?(::MathMin(tplevel,tpprice)):tpprice):(::MathMax(tplevel,tpprice))); //=============== //=============== if(pointprice!=0) { //=============== const double slmoneyprice = point*slmoney/pointprice; const double tpmoneyprice = point*tpmoney/pointprice; //=============== //=============== if(slmoneyenabled && slmoney>0)sllevel=(type==TRADETYPE_BUY?(::MathMax(sllevel,entrylevel-slmoneyprice)): (sllevel>0?(::MathMin(sllevel,entrylevel+slmoneyprice)):entrylevel+slmoneyprice)); if(tpmoneyenabled && tpmoney>0)tplevel=(type==TRADETYPE_BUY?(tplevel>0?(::MathMin(tplevel,entrylevel+tpmoneyprice)):entrylevel+tpmoneyprice): (::MathMax(tplevel,entrylevel-tpmoneyprice))); //=============== } //=============== //=============== sllevel = ::NormalizeDouble(sllevel,digits); tplevel = ::NormalizeDouble(tplevel,digits); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void cTrade::TrailingStop(const long ticket,const long tslstart,const long tsldistance,const bool tsllevelenabled,const double tsllevel) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const bool cantrade=cTrade::CanTrade(); //=============== /* DEBUG ASSERTION */ASSERT({},cantrade,true,{}) //=============== if(!cantrade)return; //=============== //=============== cTradeInfo trade; //=============== trade.Update(ticket,false,false,false); //=============== //=============== if(trade.TicketGet()<=0 || trade.StatusGet()!=TRADESTATUS_CURRENT)return; //=============== //=============== if(trade.ProfitPointsGet()trade.StopLossGet()+TSLSTEPPOINTS*point) { //=============== cTrade::ModifyTrade(ticket,sllevel,trade.TakeProfitGet(),retcode,myretcode); //=============== } //=============== } //=============== //=============== if(trade.TypeGet()==TRADETYPE_SELL) { //=============== reference=tsllevelenabled?tsllevel:lasttick.ask; //=============== //=============== sllevel=reference+tsldistance*point; //=============== sllevel=::NormalizeDouble(sllevel,digits); //=============== //=============== if(slleveltrade.StopLossGet()) { //=============== cTrade::ModifyTrade(ticket,sllevel,trade.TakeProfitGet(),retcode,myretcode); //=============== } //=============== } //=============== //=============== if(trade.TypeGet()==TRADETYPE_SELL) { //=============== sllevel=trade.OpenPriceGet()-beprofit*point; //=============== sllevel=::NormalizeDouble(sllevel,digits); //=============== //=============== if(sllevel=ORDER_FILLING_RETURN) || ((fillingmode &(defaultfilling+1))!=defaultfilling+1)) ? (((executionmode==SYMBOL_TRADE_EXECUTION_EXCHANGE) || (executionmode==SYMBOL_TRADE_EXECUTION_INSTANT)) ? ORDER_FILLING_RETURN :((fillingmode==SYMBOL_FILLING_IOC) ? ORDER_FILLING_IOC : ORDER_FILLING_FOK)) : (ENUM_ORDER_TYPE_FILLING)defaultfilling; //=============== } //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(result); //=============== } #endif //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::CanTrade(void) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== static const bool istesting=(bool)::MQLInfoInteger(MQL_TESTER); //=============== //=============== if(istesting)return(true); //=============== //=============== const bool result=(::TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && ::MQLInfoInteger(MQL_TRADE_ALLOWED) && ::AccountInfoInteger(ACCOUNT_TRADE_EXPERT) && ::AccountInfoInteger(ACCOUNT_TRADE_ALLOWED) && ::TerminalInfoInteger(TERMINAL_CONNECTED)); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(result); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::ClosingAllowed(const string symbol) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const ENUM_SYMBOL_TRADE_MODE trademode=(ENUM_SYMBOL_TRADE_MODE)::SymbolInfoInteger(symbol,SYMBOL_TRADE_MODE); //=============== //=============== if(trademode==SYMBOL_TRADE_MODE_DISABLED)return(false); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::OpeningAllowed(const string symbol,const eTradeType type) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const ENUM_SYMBOL_TRADE_MODE trademode=(ENUM_SYMBOL_TRADE_MODE)::SymbolInfoInteger(symbol,SYMBOL_TRADE_MODE); //=============== //=============== switch(trademode) { case SYMBOL_TRADE_MODE_DISABLED : return(false); case SYMBOL_TRADE_MODE_LONGONLY : return(type==TRADETYPE_BUY); case SYMBOL_TRADE_MODE_SHORTONLY : return(type==TRADETYPE_SELL); case SYMBOL_TRADE_MODE_CLOSEONLY : return(false); case SYMBOL_TRADE_MODE_FULL : return(true); //=============== default :/* DEBUG ASSERTION */ASSERT({},false,false,{}) break; //=============== } //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::TradeTypeAllowed(const eAllowedTrades allowed,const eTradeType type) { //=============== switch(allowed) { case ALLOWEDTRADES_ALL : return(true); case ALLOWEDTRADES_NONE : return(false); case ALLOWEDTRADES_BUYONLY : return(type==TRADETYPE_BUY); case ALLOWEDTRADES_SELLONLY : return(type==TRADETYPE_SELL); //=============== default :/* DEBUG ASSERTION */ASSERT({},false,false,{}) break; //=============== } //=============== //=============== return(false); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static double cTrade::CalculateLot(const string symbol,const eTradeType type,const double requiredbelevel,const double dealprice, const double lotsnow,const double belevelnow) { //=============== const double difference=::MathAbs(dealprice-requiredbelevel); //=============== //=============== double requiredlot=(difference!=0?(lotsnow*::MathAbs(requiredbelevel-belevelnow)/difference):0); //=============== //=============== if(type==TRADETYPE_BUY && requiredbelevel>belevelnow)requiredlot=0; //=============== //=============== if(type==TRADETYPE_SELL && requiredbelevelmax)result=max; //=============== //=============== result=::NormalizeDouble(result,2); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(min==0?::MathMax(result,0.01):result); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static long cTrade::OpenTrade(const string symbol,const eTradeType type,const double lots,const long magic,const string comment, const long slippage,const bool checkplaced,uint &retcode,eError &myretcode) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const long ticket=cTrade::OpenTrade(symbol,type,lots,magic,comment, false,0,false,0,false,0,false,0,false,0,false,0, (slippage>0),slippage,checkplaced,retcode,myretcode); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(ticket); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static long cTrade::OpenTrade(const string symbol,const eTradeType type,const double lots,const long magic,const string comment, const bool slpointsenabled,const long slpoints,const bool tppointsenabled,const long tppoints, const bool slmoneyenabled,const double slmoney,const bool tpmoneyenabled,const double tpmoney, const bool slpriceenabled,const double slprice,const bool tppriceenabled,const double tpprice, const bool slippageenabled,const long slippage,const bool checkplaced,uint &retcode,eError &myretcode) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const bool cantrade=cTrade::CanTrade(); //=============== /* DEBUG ASSERTION */ASSERT({},cantrade,true,{}) //=============== if(!cantrade){myretcode=ERROR_AUTOTRADINGNOTALLOWED;return(-1);} //=============== //=============== const bool openingallowed=cTrade::OpeningAllowed(symbol,type); //=============== /* DEBUG ASSERTION */ASSERT({},openingallowed,true,{}) //=============== if(!openingallowed){myretcode=RETCODE_OPENINGNOTALLOWED;return(-1);} //=============== //=============== if(checkplaced) { //=============== const bool noplaced=cTrade::CheckPlaced(symbol,type,magic); //=============== /* DEBUG ASSERTION */ASSERT({},noplaced,true,{}) //=============== if(!noplaced){myretcode=RETCODE_ALREADYPLACED;return(-1);} //=============== } //=============== //=============== const bool maxorders=cTrade::CheckMaxOrders(); //=============== /* DEBUG ASSERTION */ASSERT({},maxorders,true,{}) //=============== if(!maxorders){myretcode=RETCODE_MAXORDERS;return(-1);} //=============== //=============== const double volume=cTrade::CheckLot(symbol,lots); //=============== const bool volumeok=(volume>0); //=============== /* DEBUG ASSERTION */ASSERT({},volumeok,true,{}) //=============== if(!volumeok){myretcode=RETCODE_WRONGVOLUME;return(-1);} //=============== //=============== const bool maxvolume=cTrade::CheckMaxVolume(symbol,type,volume); //=============== /* DEBUG ASSERTION */ASSERT({},maxvolume,true,{}) //=============== if(!maxvolume){myretcode=RETCODE_MAXVOLUME;return(-1);} //=============== //=============== MqlTick lasttick; //=============== const bool gettick=::SymbolInfoTick(symbol,lasttick); //=============== /* DEBUG ASSERTION */ASSERT({},gettick,true,{}) //=============== if(!gettick){myretcode=RETCODE_NOTICKDATA;return(-1);} //=============== //=============== double sllevel=0; //=============== double tplevel=0; //=============== //=============== const double price=(type==TRADETYPE_BUY?lasttick.ask:lasttick.bid); //=============== //=============== cTrade::CalculateSLandTP(symbol,type,price,volume, slpointsenabled,slpoints,tppointsenabled,tppoints, slmoneyenabled,slmoney,tpmoneyenabled,tpmoney, slpriceenabled,slprice,tppriceenabled,tpprice,sllevel,tplevel); //=============== //=============== const bool stopsok=cTrade::CheckStops(symbol,type,true,price,sllevel,tplevel); //=============== /* DEBUG ASSERTION */ASSERT({},stopsok,true,{}) //=============== if(!stopsok){myretcode=RETCODE_WRONGSTOPS;return(-1);} //=============== //=============== long ticket=-1; //=============== //=============== #ifdef __MQL5__ //=============== //=============== const int ordermode=(int)::SymbolInfoInteger(symbol,SYMBOL_ORDER_MODE); //=============== const bool orderallowed=((SYMBOL_ORDER_MARKET&ordermode)==SYMBOL_ORDER_MARKET); //=============== /* DEBUG ASSERTION */ASSERT({},orderallowed,true,{}) //=============== if(!orderallowed){myretcode=RETCODE_TRADETYPENOTALLOWED;return(-1);} //=============== //=============== MqlTradeRequest openrequest; MqlTradeCheckResult opencheckresult; MqlTradeResult openresult; //=============== ::ZeroMemory(openrequest); ::ZeroMemory(opencheckresult); ::ZeroMemory(openresult); //=============== //=============== const ENUM_ORDER_TYPE_FILLING filling=cTrade::GetFilling(symbol); //=============== //=============== openrequest.action = TRADE_ACTION_DEAL; openrequest.magic = magic; openrequest.symbol = symbol; openrequest.volume = volume; openrequest.type = (type==TRADETYPE_BUY?ORDER_TYPE_BUY:ORDER_TYPE_SELL); openrequest.deviation = (slippageenabled?(int)slippage:0); openrequest.comment = comment; openrequest.type_filling = filling; openrequest.price = ::NormalizeDouble(price,(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS)); openrequest.sl = sllevel; openrequest.tp = tplevel; //=============== //=============== const bool marginok=cTrade::CheckMargin(symbol,volume,type,openrequest.price); //=============== /* DEBUG ASSERTION */ASSERT({},marginok,true,{}) //=============== if(!marginok){myretcode=RETCODE_NOFREEMARGIN;return(-1);} //=============== //=============== const bool check=::OrderCheck(openrequest,opencheckresult); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},check && opencheckresult.retcode==0,false,::Print(TOSTRING(opencheckresult.retcode));) //=============== //=============== retcode=opencheckresult.retcode; //=============== //=============== if(check && opencheckresult.retcode==0) { //=============== const bool send=::OrderSend(openrequest,openresult); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},send && (openresult.deal>0 || openresult.order>0),false,::Print(TOSTRING(openresult.retcode));) //=============== //=============== /* DEBUG ASSERTION */ASSERT({},openresult.deal<=0 || openresult.order>0,false,::Print(TOSTRING(openresult.deal),VERTICALBAR,TOSTRING(openresult.order));) //=============== //=============== ticket=(long)openresult.order; //=============== //=============== retcode=openresult.retcode; //=============== } else { //=============== retcode=RETCODE_ORDERCHECKFAILED; //=============== } //=============== //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== //=============== const bool marginok=cTrade::CheckMargin(symbol,volume,type,price); //=============== /* DEBUG ASSERTION */ASSERT({},marginok,true,{}) //=============== if(!marginok){myretcode=RETCODE_NOFREEMARGIN;return(-1);} //=============== //=============== const int cmd=(type==TRADETYPE_BUY?OP_BUY:OP_SELL); //=============== //=============== ::ResetLastError(); //=============== //=============== const int send=::OrderSend(symbol,cmd,volume,::NormalizeDouble(price,(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS)), (slippageenabled?(int)slippage:0),sllevel,tplevel,comment,(int)magic,0,clrNONE); //=============== //=============== retcode=::GetLastError(); //=============== //=============== ticket=send; //=============== //=============== /* DEBUG ASSERTION */ASSERT({},send>0,false,::Print(TOSTRING(retcode));) //=============== //=============== #endif //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(ticket); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static long cTrade::PlacePendingOrder(const string symbol,const double price,const ePendingOrderType type,const double lots, const long magic,const string comment,const datetime expiration,uint &retcode,eError &myretcode) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const long ticket=cTrade::PlacePendingOrder(symbol,price,type,lots,magic,comment, false,0,false,0, false,0,false,0, false,0,false,0, (expiration>0),expiration,retcode,myretcode); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(ticket); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static long cTrade::PlacePendingOrder(const string symbol,const double price,const ePendingOrderType type,const double lots, const long magic,const string comment, const bool slpointsenabled,const long slpoints,const bool tppointsenabled,const long tppoints, const bool slmoneyenabled,const double slmoney,const bool tpmoneyenabled,const double tpmoney, const bool slpriceenabled,const double slprice,const bool tppriceenabled,const double tpprice, const bool expirationenabled,const datetime expiration,uint &retcode,eError &myretcode) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const bool cantrade=cTrade::CanTrade(); //=============== /* DEBUG ASSERTION */ASSERT({},cantrade,true,{}) //=============== if(!cantrade){myretcode=ERROR_AUTOTRADINGNOTALLOWED;return(-1);} //=============== //=============== const eTradeType side=(type==PENDINGORDERTYPE_BUYLIMIT || type==PENDINGORDERTYPE_BUYSTOP)?TRADETYPE_BUY:TRADETYPE_SELL; //=============== //=============== const bool openingallowed=cTrade::OpeningAllowed(symbol,side); //=============== /* DEBUG ASSERTION */ASSERT({},openingallowed,true,{}) //=============== if(!openingallowed){myretcode=RETCODE_OPENINGNOTALLOWED;return(-1);} //=============== //=============== const bool maxorders=cTrade::CheckMaxOrders(); //=============== /* DEBUG ASSERTION */ASSERT({},maxorders,true,{}) //=============== if(!maxorders){myretcode=RETCODE_MAXORDERS;return(-1);} //=============== //=============== const double volume=cTrade::CheckLot(symbol,lots); //=============== const bool volumeok=(volume>0); //=============== /* DEBUG ASSERTION */ASSERT({},volumeok,true,{}) //=============== if(!volumeok){myretcode=RETCODE_WRONGVOLUME;return(-1);} //=============== //=============== const bool maxvolume=cTrade::CheckMaxVolume(symbol,side,volume); //=============== /* DEBUG ASSERTION */ASSERT({},maxvolume,true,{}) //=============== if(!maxvolume){myretcode=RETCODE_MAXVOLUME;return(-1);} //=============== //=============== double sllevel=0; //=============== double tplevel=0; //=============== //=============== cTrade::CalculateSLandTP(symbol,side,price,volume, slpointsenabled,slpoints,tppointsenabled,tppoints, slmoneyenabled,slmoney,tpmoneyenabled,tpmoney, slpriceenabled,slprice,tppriceenabled,tpprice,sllevel,tplevel); //=============== //=============== const bool stopsok=cTrade::CheckStops(symbol,side,false,price,sllevel,tplevel); //=============== /* DEBUG ASSERTION */ASSERT({},stopsok,true,{}) //=============== if(!stopsok){myretcode=RETCODE_WRONGSTOPS;return(-1);} //=============== //=============== const bool orderpriceok=cTrade::CheckOrderPrice(symbol,type,price); //=============== /* DEBUG ASSERTION */ASSERT({},orderpriceok,true,{}) //=============== if(!orderpriceok){myretcode=RETCODE_WRONGORDERPRICE;return(-1);} //=============== //=============== #ifdef __MQL5__ //=============== //=============== const int ordermode=(int)::SymbolInfoInteger(symbol,SYMBOL_ORDER_MODE); //=============== bool orderallowed=((SYMBOL_ORDER_LIMIT&ordermode)==SYMBOL_ORDER_LIMIT); //=============== /* DEBUG ASSERTION */ASSERT({},orderallowed,true,{}) //=============== if(!orderallowed){myretcode=RETCODE_TRADETYPENOTALLOWED;return(-1);} //=============== orderallowed=((SYMBOL_ORDER_STOP&ordermode)==SYMBOL_ORDER_STOP); //=============== /* DEBUG ASSERTION */ASSERT({},orderallowed,true,{}) //=============== if(!orderallowed){myretcode=RETCODE_TRADETYPENOTALLOWED;return(-1);} //=============== //=============== MqlTradeRequest openrequest; MqlTradeCheckResult opencheckresult; MqlTradeResult openresult; //=============== ::ZeroMemory(openrequest); ::ZeroMemory(opencheckresult); ::ZeroMemory(openresult); //=============== //=============== const ENUM_ORDER_TYPE_FILLING filling=cTrade::GetFilling(symbol); //=============== //=============== openrequest.action = TRADE_ACTION_PENDING; openrequest.magic = magic; openrequest.symbol = symbol; openrequest.volume = volume; openrequest.comment = comment; openrequest.type_filling = filling; openrequest.price = ::NormalizeDouble(price,(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS)); openrequest.sl = sllevel; openrequest.tp = tplevel; openrequest.expiration = (expirationenabled?expiration:0); //=============== //=============== switch(type) { //=============== case PENDINGORDERTYPE_BUYLIMIT : openrequest.type=ORDER_TYPE_BUY_LIMIT; break; case PENDINGORDERTYPE_BUYSTOP : openrequest.type=ORDER_TYPE_BUY_STOP; break; case PENDINGORDERTYPE_SELLLIMIT : openrequest.type=ORDER_TYPE_SELL_LIMIT; break; case PENDINGORDERTYPE_SELLSTOP : openrequest.type=ORDER_TYPE_SELL_STOP; break; //=============== default :/* DEBUG ASSERTION */ASSERT({},false,false,{}) break; //=============== } //=============== //=============== const bool marginok=cTrade::CheckMargin(symbol,volume,side,openrequest.price); //=============== /* DEBUG ASSERTION */ASSERT({},marginok,true,{}) //=============== if(!marginok){myretcode=RETCODE_NOFREEMARGIN;return(-1);} //=============== //=============== const bool check=::OrderCheck(openrequest,opencheckresult); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},check && opencheckresult.retcode==0,false,::Print(TOSTRING(opencheckresult.retcode));) //=============== //=============== retcode=opencheckresult.retcode; //=============== //=============== if(check && opencheckresult.retcode==0) { //=============== const bool send=::OrderSend(openrequest,openresult); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},send && openresult.order>0,false,::Print(TOSTRING(openresult.retcode));) //=============== //=============== retcode=openresult.retcode; //=============== //=============== return((long)openresult.order); //=============== } else { //=============== myretcode=RETCODE_ORDERCHECKFAILED; //=============== } //=============== //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== //=============== const bool marginok=cTrade::CheckMargin(symbol,volume,side,price); //=============== /* DEBUG ASSERTION */ASSERT({},marginok,true,{}) //=============== if(!marginok){myretcode=RETCODE_NOFREEMARGIN;return(-1);} //=============== //=============== int cmd=-1; //=============== //=============== switch(type) { //=============== case PENDINGORDERTYPE_BUYLIMIT : cmd=OP_BUYLIMIT; break; case PENDINGORDERTYPE_BUYSTOP : cmd=OP_BUYSTOP; break; case PENDINGORDERTYPE_SELLLIMIT : cmd=OP_SELLLIMIT; break; case PENDINGORDERTYPE_SELLSTOP : cmd=OP_SELLSTOP; break; //=============== default :/* DEBUG ASSERTION */ASSERT({},false,false,{}) break; //=============== } //=============== //=============== ::ResetLastError(); //=============== //=============== const int send=::OrderSend(symbol,cmd,volume,::NormalizeDouble(price,(int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS)),0, sllevel,tplevel,comment,(int)magic,(expirationenabled?expiration:0),clrNONE); //=============== //=============== retcode=::GetLastError();; //=============== //=============== /* DEBUG ASSERTION */ASSERT({},send>0,false,::Print(TOSTRING(retcode));) //=============== //=============== return(send); //=============== //=============== #endif //=============== //=============== return(-1); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::ModifyTrade(const long ticket,const double newsl,const double newtp,uint &retcode,eError &myretcode) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const bool cantrade=cTrade::CanTrade(); //=============== /* DEBUG ASSERTION */ASSERT({},cantrade,true,{}) //=============== if(!cantrade){myretcode=ERROR_AUTOTRADINGNOTALLOWED;return(false);} //=============== //=============== cTradeInfo trade; //=============== trade.Update(ticket,false,false,false); //=============== //=============== const string symbol = trade.SymbolGet(); const int digits = (int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS); //=============== const double SL=::NormalizeDouble(newsl,digits); const double TP=::NormalizeDouble(newtp,digits); //=============== //=============== const bool sameSL = (SL==trade.StopLossGet()); const bool sameTP = (TP==trade.TakeProfitGet()); //=============== //=============== if(sameSL && sameTP)return(false); //=============== //=============== const bool stopsok=cTrade::CheckStops(symbol,trade.TypeGet(),true,trade.OpenPriceGet(),sameSL?0:SL,sameTP?0:TP); //=============== /* DEBUG ASSERTION */ASSERT({},stopsok,true,{}) //=============== if(!stopsok){myretcode=RETCODE_WRONGSTOPS;return(false);} //=============== //=============== bool result=false; //=============== //=============== #ifdef __MQL5__ //=============== //=============== if(!::PositionSelectByTicket(ticket)) { //=============== ::ResetLastError(); //=============== //=============== myretcode=RETCODE_TRADENOTFOUND; //=============== //=============== return(false); //=============== } //=============== //=============== const int ordermode=(int)::SymbolInfoInteger(symbol,SYMBOL_ORDER_MODE); //=============== bool orderallowed=((SYMBOL_ORDER_SL&ordermode)==SYMBOL_ORDER_SL); //=============== /* DEBUG ASSERTION */ASSERT({},orderallowed,true,{}) //=============== if(!orderallowed){myretcode=RETCODE_TRADETYPENOTALLOWED;return(false);} //=============== orderallowed=((SYMBOL_ORDER_TP&ordermode)==SYMBOL_ORDER_TP); //=============== /* DEBUG ASSERTION */ASSERT({},orderallowed,true,{}) //=============== if(!orderallowed){myretcode=RETCODE_TRADETYPENOTALLOWED;return(false);} //=============== //=============== MqlTradeRequest modifyrequest; MqlTradeResult modifyresult; MqlTradeCheckResult modifycheckresult; //=============== ::ZeroMemory(modifyrequest); ::ZeroMemory(modifyresult); ::ZeroMemory(modifycheckresult); //=============== //=============== modifyrequest.action = TRADE_ACTION_SLTP; modifyrequest.position = ticket; modifyrequest.symbol = symbol; modifyrequest.sl = SL; modifyrequest.tp = TP; //=============== //=============== const bool check=::OrderCheck(modifyrequest,modifycheckresult); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},check && modifycheckresult.retcode==0,false,::Print(TOSTRING(modifycheckresult.retcode));) //=============== //=============== retcode=modifycheckresult.retcode; //=============== //=============== if(check && modifycheckresult.retcode==0) { //=============== const bool send=::OrderSend(modifyrequest,modifyresult); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},send && modifyresult.retcode==TRADE_RETCODE_DONE,false,::Print(TOSTRING(modifyresult.retcode));) //=============== //=============== retcode=modifyresult.retcode; //=============== //=============== if(send && modifyresult.retcode==TRADE_RETCODE_DONE) { //=============== result=true; //=============== //=============== retcode=0; //=============== } //=============== } else { //=============== myretcode=RETCODE_ORDERCHECKFAILED; //=============== } //=============== //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== //=============== if(!::OrderSelect((int)ticket,SELECT_BY_TICKET,MODE_TRADES) || ::OrderCloseTime()>0){myretcode=RETCODE_TRADENOTFOUND;return(false);} //=============== //=============== if(::OrderType()!=OP_BUY && ::OrderType()!=OP_SELL){myretcode=RETCODE_TRADENOTFOUND;return(false);} //=============== //=============== ::ResetLastError(); //=============== //=============== result=::OrderModify((int)ticket,::OrderOpenPrice(),SL,TP,0,clrNONE); //=============== //=============== retcode=::GetLastError(); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},result,false,::Print(TOSTRING(retcode));) //=============== //=============== #endif //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(result); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::ModifyPendingOrder(const long ticket,const double newprice,const double newsl,const double newtp, const datetime newexpiration,uint &retcode,eError &myretcode) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const bool cantrade=cTrade::CanTrade(); //=============== /* DEBUG ASSERTION */ASSERT({},cantrade,true,{}) //=============== if(!cantrade){myretcode=ERROR_AUTOTRADINGNOTALLOWED;return(false);} //=============== //=============== cPendingOrderInfo order; //=============== order.Update(ticket); //=============== //=============== if(order.TicketGet()<=0 || order.StatusGet()!=ORDERSTATUS_PENDING){myretcode=RETCODE_TRADENOTFOUND;return(false);} //=============== //=============== const string symbol = order.SymbolGet(); const int digits = (int)::SymbolInfoInteger(symbol,SYMBOL_DIGITS); //=============== const double PRICE = ::NormalizeDouble(newprice,digits); const double SL = ::NormalizeDouble(newsl,digits); const double TP = ::NormalizeDouble(newtp,digits); //=============== //=============== const bool sameSL = (SL==order.StopLossGet()); const bool sameTP = (TP==order.TakeProfitGet()); //=============== //=============== if(sameSL && sameTP && PRICE==order.OpenPriceGet() && newexpiration==order.ExpirationGet())return(false); //=============== //=============== const eTradeType side=(order.TypeGet()==PENDINGORDERTYPE_BUYLIMIT || order.TypeGet()==PENDINGORDERTYPE_BUYSTOP)?TRADETYPE_BUY:TRADETYPE_SELL; //=============== //=============== const bool stopsok=cTrade::CheckStops(symbol,side,false,PRICE,sameSL?0:SL,sameTP?0:TP); //=============== /* DEBUG ASSERTION */ASSERT({},stopsok,true,{}) //=============== if(!stopsok){myretcode=RETCODE_WRONGSTOPS;return(false);} //=============== //=============== const bool orderpriceok=cTrade::CheckOrderPrice(symbol,order.TypeGet(),PRICE); //=============== /* DEBUG ASSERTION */ASSERT({},orderpriceok,true,{}) //=============== if(!orderpriceok){myretcode=RETCODE_WRONGORDERPRICE;return(false);} //=============== //=============== #ifdef __MQL5__ //=============== //=============== if(!::OrderSelect(ticket)) { //=============== ::ResetLastError(); //=============== //=============== myretcode=RETCODE_TRADENOTFOUND; //=============== //=============== return(false); //=============== } //=============== //=============== MqlTradeRequest modifyrequest; MqlTradeResult modifyresult; MqlTradeCheckResult modifycheckresult; //=============== ::ZeroMemory(modifyrequest); ::ZeroMemory(modifyresult); ::ZeroMemory(modifycheckresult); //=============== //=============== modifyrequest.action = TRADE_ACTION_MODIFY; modifyrequest.order = ticket; modifyrequest.price = PRICE; modifyrequest.sl = SL; modifyrequest.tp = TP; modifyrequest.type_time = (ENUM_ORDER_TYPE_TIME)::OrderGetInteger(ORDER_TYPE_TIME); modifyrequest.expiration = newexpiration; //=============== //=============== const bool check=::OrderCheck(modifyrequest,modifycheckresult); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},check && modifycheckresult.retcode==0,false,::Print(TOSTRING(modifycheckresult.retcode));) //=============== //=============== retcode=modifycheckresult.retcode; //=============== //=============== if(check && modifycheckresult.retcode==0) { //=============== const bool send=::OrderSend(modifyrequest,modifyresult); //=============== //=============== retcode=(modifyresult.retcode==TRADE_RETCODE_DONE?0:modifyresult.retcode); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},send && modifyresult.retcode==TRADE_RETCODE_DONE,false,::Print(TOSTRING(modifyresult.retcode));) //=============== //=============== if(send && modifyresult.retcode==TRADE_RETCODE_DONE)return(true); //=============== } else { //=============== myretcode=RETCODE_ORDERCHECKFAILED; //=============== } //=============== //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== //=============== if(!::OrderSelect((int)ticket,SELECT_BY_TICKET,MODE_TRADES) || ::OrderCloseTime()>0){myretcode=RETCODE_TRADENOTFOUND;return(false);} //=============== //=============== if(::OrderType()!=OP_BUYSTOP && ::OrderType()!=OP_SELLSTOP && ::OrderType()!=OP_BUYLIMIT && ::OrderType()!=OP_SELLLIMIT) { //=============== myretcode=RETCODE_TRADENOTFOUND; //=============== //=============== return(false); //=============== } //=============== //=============== ::ResetLastError(); //=============== //=============== const bool modify=::OrderModify((int)ticket,PRICE,SL,TP,newexpiration,clrNONE); //=============== //=============== retcode=::GetLastError(); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},modify,false,::Print(TOSTRING(retcode));) //=============== //=============== return(modify); //=============== //=============== #endif //=============== //=============== return(false); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void cTrade::ModifyTrade(const long ticket,const bool tightenstopsonly, const bool slpointsenabled,const long slpoints,const bool tppointsenabled,const long tppoints, const bool slmoneyenabled,const double slmoney,const bool tpmoneyenabled,const double tpmoney, const bool slpriceenabled,const double slprice,const bool tppriceenabled,const double tpprice) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const bool changesl=(slpointsenabled || slpriceenabled || slmoneyenabled); const bool changetp=(tppointsenabled || tppriceenabled || tpmoneyenabled); //=============== //=============== if(!changesl && !changetp)return; //=============== //=============== const bool cantrade=cTrade::CanTrade(); //=============== /* DEBUG ASSERTION */ASSERT({},cantrade,true,{}) //=============== if(!cantrade)return; //=============== //=============== double sllevel=0; //=============== double tplevel=0; //=============== //=============== cTradeInfo trade; //=============== trade.Update(ticket,false,false,false); //=============== //=============== if(trade.TicketGet()<=0 || trade.StatusGet()!=TRADESTATUS_CURRENT)return; //=============== //=============== cTrade::CalculateSLandTP(trade.SymbolGet(),trade.TypeGet(),trade.OpenPriceGet(),trade.LotsGet(), slpointsenabled,slpoints,tppointsenabled,tppoints, slmoneyenabled,slmoney,tpmoneyenabled,tpmoney, slpriceenabled,slprice,tppriceenabled,tpprice,sllevel,tplevel); //=============== //=============== if(tightenstopsonly) { //=============== if(trade.TypeGet()==TRADETYPE_BUY) { //=============== if(trade.StopLossGet()>0)sllevel=::MathMax(sllevel,trade.StopLossGet()); //=============== //=============== if(trade.TakeProfitGet()>0)tplevel=::MathMin(tplevel,trade.TakeProfitGet()); //=============== } //=============== //=============== if(trade.TypeGet()==TRADETYPE_SELL) { //=============== if(trade.StopLossGet()>0)sllevel=::MathMin(sllevel,trade.StopLossGet()); //=============== //=============== if(trade.TakeProfitGet()>0)tplevel=::MathMax(tplevel,trade.TakeProfitGet()); //=============== } //=============== } //=============== //=============== uint retcode = 0; eError myretcode = WRONG_VALUE; //=============== //=============== cTrade::ModifyTrade(ticket, changesl?sllevel:trade.StopLossGet(),changetp?tplevel:trade.TakeProfitGet(), retcode,myretcode); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void cTrade::ModifyPendingOrder(const long ticket,const bool priceenabled,const double price,const bool tightenstopsonly, const bool slpointsenabled,const long slpoints,const bool tppointsenabled,const long tppoints, const bool slmoneyenabled,const double slmoney,const bool tpmoneyenabled,const double tpmoney, const bool slpriceenabled,const double slprice,const bool tppriceenabled,const double tpprice, const bool expirationenabled,const datetime expiration) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const bool changesl=(slpointsenabled || slpriceenabled || slmoneyenabled); const bool changetp=(tppointsenabled || tppriceenabled || tpmoneyenabled); //=============== //=============== if(!changesl && !changetp && !priceenabled && !expirationenabled)return; //=============== //=============== const bool cantrade=cTrade::CanTrade(); //=============== /* DEBUG ASSERTION */ASSERT({},cantrade,true,{}) //=============== if(!cantrade)return; //=============== //=============== double sllevel=0; //=============== double tplevel=0; //=============== //=============== cPendingOrderInfo order; //=============== order.Update(ticket); //=============== //=============== if(order.TicketGet()<=0 || order.StatusGet()!=ORDERSTATUS_PENDING)return; //=============== //=============== const eTradeType side=(order.TypeGet()==PENDINGORDERTYPE_BUYLIMIT || order.TypeGet()==PENDINGORDERTYPE_BUYSTOP)?TRADETYPE_BUY:TRADETYPE_SELL; //=============== //=============== cTrade::CalculateSLandTP(order.SymbolGet(),side,priceenabled?price:order.OpenPriceGet(),order.LotsGet(), slpointsenabled,slpoints,tppointsenabled,tppoints, slmoneyenabled,slmoney,tpmoneyenabled,tpmoney, slpriceenabled,slprice,tppriceenabled,tpprice,sllevel,tplevel); //=============== //=============== if(tightenstopsonly) { //=============== if(side==TRADETYPE_BUY) { //=============== if(order.StopLossGet()>0)sllevel=::MathMax(sllevel,order.StopLossGet()); //=============== //=============== if(order.TakeProfitGet()>0)tplevel=::MathMin(tplevel,order.TakeProfitGet()); //=============== } //=============== //=============== if(side==TRADETYPE_SELL) { //=============== if(order.StopLossGet()>0)sllevel=::MathMin(sllevel,order.StopLossGet()); //=============== //=============== if(order.TakeProfitGet()>0)tplevel=::MathMax(tplevel,order.TakeProfitGet()); //=============== } //=============== } //=============== //=============== uint retcode = 0; eError myretcode = WRONG_VALUE; //=============== //=============== cTrade::ModifyPendingOrder(ticket,priceenabled?price:order.OpenPriceGet(), changesl?sllevel:order.StopLossGet(), changetp?tplevel:order.TakeProfitGet(), expirationenabled?expiration:order.ExpirationGet(),retcode,myretcode); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::CloseTrade(const long ticket,const bool slippageenabled,const long slippage,const double lots,uint &retcode,eError &myretcode) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const bool cantrade=cTrade::CanTrade(); //=============== /* DEBUG ASSERTION */ASSERT({},cantrade,true,{}) //=============== if(!cantrade){myretcode=ERROR_AUTOTRADINGNOTALLOWED;return(false);} //=============== //=============== #ifdef __MQL5__ //=============== //=============== if(!::PositionSelectByTicket(ticket)) { //=============== ::ResetLastError(); //=============== //=============== myretcode=RETCODE_TRADENOTFOUND; //=============== //=============== return(false); //=============== } //=============== //=============== MqlTradeRequest closerequest; MqlTradeResult closeresult; MqlTradeCheckResult closecheckresult; //=============== ::ZeroMemory(closerequest); ::ZeroMemory(closeresult); ::ZeroMemory(closecheckresult); //=============== //=============== const ENUM_ORDER_TYPE_FILLING filling=cTrade::GetFilling(::PositionGetString(POSITION_SYMBOL)); //=============== //=============== closerequest.action = TRADE_ACTION_DEAL; closerequest.position = ticket; closerequest.magic = ::PositionGetInteger(POSITION_MAGIC); closerequest.symbol = ::PositionGetString(POSITION_SYMBOL); closerequest.price = ::PositionGetDouble(POSITION_PRICE_CURRENT); closerequest.sl = 0; closerequest.tp = 0; closerequest.volume = ((lots<=0)?(::PositionGetDouble(POSITION_VOLUME)):(cTrade::CheckLot(closerequest.symbol,lots))); closerequest.type = ((ENUM_POSITION_TYPE)::PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY?ORDER_TYPE_SELL:ORDER_TYPE_BUY); closerequest.deviation = (slippageenabled?slippage:0); closerequest.comment = ::PositionGetString(POSITION_COMMENT); closerequest.type_filling = filling; //=============== //=============== const bool closingallowed=cTrade::ClosingAllowed(closerequest.symbol); //=============== /* DEBUG ASSERTION */ASSERT({},closingallowed,true,{}) //=============== if(!closingallowed){myretcode=RETCODE_CLOSINGNOTALLOWED;return(false);} //=============== //=============== const bool check=::OrderCheck(closerequest,closecheckresult); //=============== //=============== retcode=closecheckresult.retcode; //=============== //=============== /* DEBUG ASSERTION */ASSERT({},check && closecheckresult.retcode==0,false,::Print(TOSTRING(closecheckresult.retcode));) //=============== //=============== if(check && closecheckresult.retcode==0) { //=============== const bool send=::OrderSend(closerequest,closeresult); //=============== //=============== retcode=closeresult.retcode; //=============== //=============== /* DEBUG ASSERTION */ASSERT({},send && (closeresult.deal>0 || closeresult.order>0),false,::Print(TOSTRING(closeresult.retcode));) //=============== //=============== if(send && (closeresult.deal>0 || closeresult.order>0))return(true); //=============== } else { //=============== myretcode=RETCODE_ORDERCHECKFAILED; //=============== } //=============== //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== //=============== if(!::OrderSelect((int)ticket,SELECT_BY_TICKET,MODE_TRADES) || ::OrderCloseTime()>0){myretcode=RETCODE_TRADENOTFOUND;return(false);} //=============== //=============== const bool closingallowed=cTrade::ClosingAllowed(::OrderSymbol()); //=============== /* DEBUG ASSERTION */ASSERT({},closingallowed,true,{}) //=============== if(!closingallowed){myretcode=RETCODE_CLOSINGNOTALLOWED;return(false);} //=============== //=============== if(::OrderType()!=OP_BUY && ::OrderType()!=OP_SELL){myretcode=RETCODE_TRADENOTFOUND;return(false);} //=============== //=============== ::ResetLastError(); //=============== //=============== const double closelots=((lots<=0)?(::OrderLots()):(cTrade::CheckLot(::OrderSymbol(),lots))); //=============== //=============== const bool close=::OrderClose(::OrderTicket(),closelots,::OrderClosePrice(),(slippageenabled?(int)slippage:0),clrNONE); //=============== //=============== retcode=::GetLastError(); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},close,false,::Print(TOSTRING(retcode));) //=============== //=============== return(close); //=============== //=============== #endif //=============== //=============== return(false); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void cTrade::CloseBy(const long ticket1,const long ticket2) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const bool cantrade=cTrade::CanTrade(); //=============== /* DEBUG ASSERTION */ASSERT({},cantrade,true,{}) //=============== if(!cantrade)return; //=============== //=============== cTradeInfo trade1; cTradeInfo trade2; //=============== trade1.Update(ticket1,false,false,false); trade2.Update(ticket2,false,false,false); //=============== //=============== const bool closingallowed=cTrade::ClosingAllowed(trade1.SymbolGet()); //=============== /* DEBUG ASSERTION */ASSERT({},closingallowed,true,{}) //=============== if(!closingallowed)return; //=============== //=============== if(trade1.TicketGet()<=0 || trade1.StatusGet()!=TRADESTATUS_CURRENT || trade2.TicketGet()<=0 || trade2.StatusGet()!=TRADESTATUS_CURRENT || trade1.TypeGet()==trade2.TypeGet() || trade1.SymbolGet()!=trade2.SymbolGet() || trade1.LotsGet()!=trade2.LotsGet()) { //=============== return; //=============== } //=============== //=============== #ifdef __MQL5__ //=============== //=============== const int ordermode=(int)::SymbolInfoInteger(trade1.SymbolGet(),SYMBOL_ORDER_MODE); //=============== const bool orderallowed=((SYMBOL_ORDER_CLOSEBY&ordermode)==SYMBOL_ORDER_CLOSEBY); //=============== /* DEBUG ASSERTION */ASSERT({},orderallowed,true,{}) //=============== if(!orderallowed)return; //=============== //=============== if(!::PositionSelectByTicket(ticket1) || !::PositionSelectByTicket(ticket2)) { //=============== ::ResetLastError(); //=============== //=============== return; //=============== } //=============== //=============== MqlTradeRequest closerequest; MqlTradeResult closeresult; MqlTradeCheckResult closecheckresult; //=============== ::ZeroMemory(closerequest); ::ZeroMemory(closeresult); ::ZeroMemory(closecheckresult); //=============== //=============== const ENUM_ORDER_TYPE_FILLING filling=cTrade::GetFilling(trade1.SymbolGet()); //=============== //=============== closerequest.action = TRADE_ACTION_CLOSE_BY; closerequest.position = ticket1; closerequest.position_by = ticket2; closerequest.magic = trade1.MagicGet(); closerequest.symbol = trade1.SymbolGet(); closerequest.comment = trade1.CommentGet(); closerequest.type_filling = filling; //=============== //=============== const bool check=::OrderCheck(closerequest,closecheckresult); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},check && closecheckresult.retcode==0,false,::Print(TOSTRING(closecheckresult.retcode));) //=============== //=============== if(check && closecheckresult.retcode==0) { //=============== const bool send=::OrderSend(closerequest,closeresult); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},send && (closeresult.deal>0 || closeresult.order>0),false,::Print(TOSTRING(closeresult.retcode));) //=============== } //=============== //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== //=============== if(!::OrderSelect((int)ticket1,SELECT_BY_TICKET,MODE_TRADES) || ::OrderCloseTime()>0)return; //=============== //=============== if(::OrderType()!=OP_BUY && ::OrderType()!=OP_SELL)return; //=============== //=============== if(!::OrderSelect((int)ticket2,SELECT_BY_TICKET,MODE_TRADES) || ::OrderCloseTime()>0)return; //=============== //=============== if(::OrderType()!=OP_BUY && ::OrderType()!=OP_SELL)return; //=============== //=============== const bool close=::OrderCloseBy((int)ticket1,(int)ticket2,clrNONE); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},close,false,::Print(TOSTRING(::GetLastError()));) //=============== //=============== #endif //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static bool cTrade::DeletePendingOrder(const long ticket,uint &retcode,eError &myretcode) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== const bool cantrade=cTrade::CanTrade(); //=============== /* DEBUG ASSERTION */ASSERT({},cantrade,true,{}) //=============== if(!cantrade){myretcode=ERROR_AUTOTRADINGNOTALLOWED;return(false);} //=============== //=============== #ifdef __MQL5__ //=============== //=============== if(!::OrderSelect(ticket)) { //=============== ::ResetLastError(); //=============== //=============== myretcode=RETCODE_TRADENOTFOUND; //=============== //=============== return(false); //=============== } //=============== //=============== MqlTradeRequest deleterequest; MqlTradeResult deleteresult; MqlTradeCheckResult deletecheckresult; //=============== ::ZeroMemory(deleterequest); ::ZeroMemory(deleteresult); ::ZeroMemory(deletecheckresult); //=============== //=============== deleterequest.action = TRADE_ACTION_REMOVE; deleterequest.order = ticket; //=============== //=============== const bool check=::OrderCheck(deleterequest,deletecheckresult); //=============== //=============== retcode=deletecheckresult.retcode; //=============== //=============== if(check && deletecheckresult.retcode==0) { //=============== const bool send=::OrderSend(deleterequest,deleteresult); //=============== //=============== retcode=(deleteresult.retcode==TRADE_RETCODE_DONE?0:deleteresult.retcode); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},send && deleteresult.retcode==TRADE_RETCODE_DONE,false,::Print(TOSTRING(deleteresult.retcode));) //=============== //=============== if(send && deleteresult.retcode==TRADE_RETCODE_DONE)return(true); //=============== } else { //=============== myretcode=RETCODE_ORDERCHECKFAILED; //=============== } //=============== //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== //=============== if(!::OrderSelect((int)ticket,SELECT_BY_TICKET,MODE_TRADES) || ::OrderCloseTime()>0){myretcode=RETCODE_TRADENOTFOUND;return(false);} //=============== //=============== if(::OrderType()!=OP_BUYSTOP && ::OrderType()!=OP_SELLSTOP && ::OrderType()!=OP_BUYLIMIT && ::OrderType()!=OP_SELLLIMIT) { //=============== myretcode=RETCODE_TRADENOTFOUND; //=============== //=============== return(false); //=============== } //=============== //=============== ::ResetLastError(); //=============== //=============== const bool deleteorder=::OrderDelete(OrderTicket(),clrNONE); //=============== //=============== retcode=::GetLastError(); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},deleteorder,false,::Print(TOSTRING(retcode));) //=============== //=============== return(deleteorder); //=============== //=============== #endif //=============== //=============== return(false); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ static void cTrade::AddCurrentTrades(const cTradesFilter &filter,long &tickets[]) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== #ifdef __MQL5__ //=============== const int tradesnumber=::PositionsTotal(); //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== const int tradesnumber=::OrdersTotal(); //=============== #endif //=============== //=============== for(int i=0;i void Reverse(T &to)const{} void Reverse(bool &to)const{if(this.Reversed)to=!to;} //=============== //=============== //==================== public: //==================== //=============== //=============== template void cExecutableParameter(const eElementParameter type,const T value,const int order,const bool enabled); void cExecutableParameter(const eElementParameter type,cExecutable *const in,const bool reversed,const int order,const bool enabled); virtual void ~cExecutableParameter(void){if(cPointer::Valid(this.OutputValue))cPointer::Delete(this.OutputValue);} //=============== //=============== void StartExecutionThread(void)const; //=============== //=============== eElementParameter TypeGet(void)const{return(this.Type);} //=============== //=============== bool EnabledGet(void)const{return(this.Enabled);} //=============== //=============== int OrderGet(void)const{return(this.Order);} //=============== //=============== template bool ValueGet(T &to)const; bool ValueGet(const cExecutable *&to)const; //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutableParameter::cExecutableParameter(const eElementParameter type,cExecutable *const in, const bool reversed,const int order,const bool enabled): //=============== Reversed(reversed), In(in), OutputValue(NULL), Type(type), Order(order), Enabled(enabled), Connected(true) { } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template void cExecutableParameter::cExecutableParameter(const eElementParameter type, const T value,const int order,const bool enabled): //=============== Reversed(false), In(NULL), Type(type), Order(order), Enabled(enabled), Connected(false) { //=============== cVariable*const variable=new cVariable; //=============== variable.Set(value); //=============== //=============== this.OutputValue=variable; //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutableParameter::StartExecutionThread(void)const { //=============== if(!this.Connected)return; //=============== //=============== /* DEBUG ASSERTION */ASSERT({},cPointer::Valid(this.In),true, return;) //=============== //=============== this.In.StartExecutionThread(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutableParameter::ValueGet(const cExecutable *&to)const { //=============== /* DEBUG ASSERTION */ASSERT({},cPointer::Valid(this.In),true,{}) //=============== //=============== if(!cPointer::Valid(this.In))return(false); //=============== //=============== const bool result=this.In.GetOutPutValue(to); //=============== //=============== return(result); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template bool cExecutableParameter::ValueGet(T &to)const { //=============== if(!this.Connected) { //=============== bool valid=false; //=============== //=============== /* DEBUG ASSERTION */ASSERT(valid=cPointer::Valid(this.OutputValue);, valid,true, return(false);) //=============== //=============== cVariable*const variable=dynamic_cast*>(this.OutputValue); //=============== //=============== /* DEBUG ASSERTION */ASSERT(valid=cPointer::Valid(variable);, valid,true, return(false);) //=============== //=============== to=variable.Get(); //=============== //=============== return(true); //=============== } //=============== //=============== if(this.Connected) { //=============== bool valid=false; //=============== //=============== /* DEBUG ASSERTION */ASSERT(valid=cPointer::Valid(this.In);, valid,true, return(false);) //=============== //=============== const bool result=this.In.GetOutPutValue(to); //=============== //=============== this.Reverse(to); //=============== //=============== return(result); //=============== } //=============== //=============== /* DEBUG ASSERTION */ASSERT({},false,false,::Print(TOSTRING(cPointer::Valid(this.OutputValue)),VERTICALBAR,TOSTRING(cPointer::Valid(this.In)));) //=============== //=============== return(false); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cExecutable { //==================== private: //==================== //=============== //=============== cExecutableParameter *Parameters[]; //=============== //=============== int ParametersIndexes[]; bool ParametersEnabled[]; //=============== //=============== bool Triggered; bool Refreshed; bool Executed; bool ExecutionStarted; //=============== //=============== bool HasTrigger; //=============== //=============== int ParameterIndexSlow(const eElementParameter parametertype)const; int ParameterIndex(const eElementParameter parametertype)const; int ParametersNumber(const eElementParameter parametertype)const; //=============== //=============== bool ParameterEnabledSlow(const eElementParameter parametertype)const; //=============== //=============== void CheckTrigger(void); //=============== //=============== virtual bool OutPutValueGet(long &to)const{return(false);} virtual bool OutPutValueGet(double &to)const{return(false);} virtual bool OutPutValueGet(string &to)const{return(false);} virtual bool OutPutValueGet(bool &to)const{return(false);} virtual bool OutPutValueGet(datetime &to)const{return(false);} virtual bool OutPutValueGet(ENUM_TIMEFRAMES &to)const{return(false);} virtual bool OutPutValueGet(ENUM_MA_METHOD &to)const{return(false);} virtual bool OutPutValueGet(ENUM_APPLIED_PRICE &to)const{return(false);} virtual bool OutPutValueGet(eRelationType &to)const{return(false);} virtual bool OutPutValueGet(eTradeType &to)const{return(false);} virtual bool OutPutValueGet(ePendingOrderType &to)const{return(false);} virtual bool OutPutValueGet(const cExecutable *&to)const{return(false);} template bool OutPutValueGet(T &to)const{return(false);} //=============== //=============== //==================== protected: //==================== //=============== //=============== void cExecutable(void); //=============== //=============== bool ParameterEnabled(const eElementParameter parametertype)const; //=============== //=============== template bool ParameterValueGet(const eElementParameter parametertype,T &to)const; template bool ParameterValuesGet(const eElementParameter parametertype,T &to[])const; //=============== //=============== void TriggeredSet(void){this.Triggered=true;} bool TriggeredGet(void)const{return(this.Triggered);} //=============== //=============== virtual void OnTrigger(void){this.TriggeredSet();} //=============== //=============== virtual bool ReFreshState(void){if(this.Refreshed)return(false);this.Refreshed=true;return(true);} //=============== //=============== //==================== public: //==================== //=============== //=============== virtual void ~cExecutable(void); //=============== //=============== template bool GetOutPutValue(T &to)const; //=============== //=============== void SortParameters(void); //=============== //=============== template void ParameterAdd(const T value,const eElementParameter type,const int parameterorder,const bool enabled); void LinkAdd(cExecutable *const from,const eElementParameter type,const bool reversed,const int parameterorder,const bool enabled); //=============== //=============== void StartExecutionThread(const bool fullcheck); void ReFreshEnable(void){this.Refreshed=false;this.Triggered=false;this.Executed=false;this.ExecutionStarted=false;} //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutable::cExecutable(void):Triggered(false),Refreshed(false),Executed(false),HasTrigger(false) { //=============== cArray::Free(this.Parameters); //=============== //=============== cArray::Free(this.ParametersIndexes); //=============== //=============== cArray::Free(this.ParametersEnabled); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutable::SortParameters(void) { //=============== const int size=cArray::Size(this.Parameters); //=============== //=============== cExecutableParameter *temp[]; //=============== cArray::Free(temp); //=============== cArray::Resize(temp,size,0); //=============== //=============== int indexes[]; //=============== int orders[]; //=============== cArray::Free(orders); //=============== cArray::Resize(orders,size,0); //=============== //=============== for(int i=0;imaxparametertype)maxparametertype=(int)type; //=============== } //=============== //=============== cArray::Resize(this.ParametersIndexes,maxparametertype+1,0); //=============== //=============== cArray::Resize(this.ParametersEnabled,maxparametertype+1,0); //=============== //=============== cArray::Initialize(this.ParametersIndexes,-1); //=============== //=============== cArray::Initialize(this.ParametersEnabled,false); //=============== //=============== for(int i=0;i<=maxparametertype;i++) { //=============== if(this.ParametersNumber((eElementParameter)i)!=1)continue; //=============== //=============== const eElementParameter type=(eElementParameter)i; //=============== //=============== this.ParametersIndexes[i]=this.ParameterIndexSlow(type); //=============== //=============== this.ParametersEnabled[i]=this.ParameterEnabledSlow(type); //=============== } //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutable::~cExecutable(void) { //=============== const int size=cArray::Size(this.Parameters); //=============== //=============== for(int i=0;i=0 && position=0,true,::Print(TOSTRING(index),VERTICALBAR,::EnumToString(parametertype));); //=============== //=============== return(index); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int cExecutable::ParameterIndexSlow(const eElementParameter parametertype)const { //=============== int index=-1; //=============== //=============== bool valid=false; //=============== //=============== const int size=cArray::Size(this.Parameters); //=============== for(int i=0;i=0 && index=cArray::Size(this.Parameters))return(-1); //=============== //=============== /* DEBUG ASSERTION */ASSERT(valid=cPointer::Valid(this.Parameters[index]);, valid,true, return(-1);) //=============== //=============== return(index); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutable::ParameterEnabledSlow(const eElementParameter parametertype)const { //=============== int parametersnumber=0; //=============== //=============== /* DEBUG ASSERTION */ASSERT(parametersnumber=this.ParametersNumber(parametertype);, parametersnumber==1,true, ::Print(TOSTRING(parametersnumber),VERTICALBAR,::EnumToString(parametertype)); return(false); ); //=============== //=============== const int index=this.ParameterIndex(parametertype); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},index>=0,true,::Print(TOSTRING(index),VERTICALBAR,::EnumToString(parametertype));); //=============== //=============== if(index<0)return(false); //=============== //=============== return(this.Parameters[index].EnabledGet()); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutable::ParameterEnabled(const eElementParameter parametertype)const { //=============== const int position=(int)parametertype; //=============== //=============== /* DEBUG ASSERTION */ASSERT({},position>=0 && position bool cExecutable::ParameterValueGet(const eElementParameter parametertype,T &to)const { //=============== int parametersnumber=0; //=============== //=============== /* DEBUG ASSERTION */ASSERT(parametersnumber=this.ParametersNumber(parametertype);, parametersnumber==1,true, ::Print(TOSTRING(parametersnumber),VERTICALBAR,::EnumToString(parametertype)); return(false); ); //=============== //=============== const int index=this.ParameterIndex(parametertype); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},index>=0,true,::Print(TOSTRING(index),VERTICALBAR,::EnumToString(parametertype));); //=============== //=============== if(index<0)return(false); //=============== //=============== return(this.Parameters[index].ValueGet(to)); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template bool cExecutable::ParameterValuesGet(const eElementParameter parametertype,T &to[])const { //=============== cArray::Free(to); //=============== //=============== bool result=true; //=============== //=============== const int size=cArray::Size(this.Parameters); //=============== for(int i=0;i bool cExecutable::GetOutPutValue(T &to)const { //=============== const bool result=this.OutPutValueGet(to); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},result,false,{}) //=============== //=============== return(result); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ template void cExecutable::ParameterAdd(const T value,const eElementParameter type,const int parameterorder,const bool enabled) { //=============== if(type==ELEMENTPARAMETER_TRIGGER)this.HasTrigger=true; //=============== //=============== cExecutableParameter *parameter=new cExecutableParameter(type,value,parameterorder,enabled); //=============== //=============== cArray::AddLast(this.Parameters,parameter,0); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutable::LinkAdd(cExecutable *const from,const eElementParameter type,const bool reversed,const int parameterorder,const bool enabled) { //=============== /* DEBUG ASSERTION */ASSERT({},cPointer::Valid(from),true,::Print(::EnumToString(type));) //=============== //=============== if(!cPointer::Valid(from))return; //=============== //=============== if(type==ELEMENTPARAMETER_TRIGGER)this.HasTrigger=true; //=============== //=============== cExecutableParameter *parameter=new cExecutableParameter(type,from,reversed,parameterorder,enabled); //=============== //=============== cArray::AddLast(this.Parameters,parameter,0); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutable::StartExecutionThread(const bool fullcheck) { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== if(this.Executed)return; //=============== //=============== if(this.ExecutionStarted)return; //=============== //=============== this.ExecutionStarted=true; //=============== //=============== const int size=cArray::Size(this.Parameters); //=============== //=============== bool runfullthread=true; //=============== //=============== if(this.HasTrigger && !fullcheck) { //=============== const int index=this.ParameterIndex(ELEMENTPARAMETER_TRIGGER); //=============== //=============== this.Parameters[index].StartExecutionThread(); //=============== //=============== this.ParameterValueGet(ELEMENTPARAMETER_TRIGGER,runfullthread); //=============== } //=============== //=============== if(runfullthread) { for(int i=0;i(executable); //=============== /* DEBUG ASSERTION */ASSERT({},cPointer::Valid(trades),true,{}) //=============== if(!cPointer::Valid(trades))return(true); //=============== //=============== cArray::Free(this.Tickets); //=============== trades.AddTicketsToArray(this.Tickets); //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cExecutableCloseTradesGroup final : public cExecutable { //==================== private: //==================== //=============== //=============== OUTPUTNONE //=============== //=============== long Tickets[]; bool CloseBy; long Slippage; bool SlippageEnabled; //=============== //=============== virtual bool ReFreshState(void)override final; //=============== //=============== //==================== public: //==================== //=============== //=============== void cExecutableCloseTradesGroup(void):CloseBy(false){cArray::Free(this.Tickets);} virtual void ~cExecutableCloseTradesGroup(void){} //=============== //=============== virtual void OnTrigger(void)override final; //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutableCloseTradesGroup::OnTrigger(void)override final { //=============== cTrade::CloseTrades(this.Tickets,this.CloseBy,this.SlippageEnabled,this.Slippage); //=============== //=============== cExecutable::OnTrigger(); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutableCloseTradesGroup::ReFreshState(void)override final { //=============== if(!cExecutable::ReFreshState())return(false); //=============== //=============== this.Slippage = 0; this.SlippageEnabled = false; this.CloseBy = false; //=============== //=============== const cExecutable *executable=NULL; //=============== const bool executableget=this.ParameterValueGet(ELEMENTPARAMETER_TRADESGROUP,executable); //=============== /* DEBUG ASSERTION */ASSERT({},executableget,false,{}) //=============== //=============== const cExecutableTrades *const trades=dynamic_cast(executable); //=============== /* DEBUG ASSERTION */ASSERT({},cPointer::Valid(trades),true,{}) //=============== if(!cPointer::Valid(trades))return(true); //=============== //=============== cArray::Free(this.Tickets); //=============== trades.AddTicketsToArray(this.Tickets); //=============== //=============== const bool closebyget=this.ParameterValueGet(ELEMENTPARAMETER_CLOSEBY,this.CloseBy); //=============== /* DEBUG ASSERTION */ASSERT({},closebyget,false,{}) //=============== //=============== const bool slippageget=this.ParameterValueGet(ELEMENTPARAMETER_SLIPPAGE,this.Slippage); //=============== /* DEBUG ASSERTION */ASSERT({},slippageget,false,{}) //=============== this.SlippageEnabled=this.ParameterEnabled(ELEMENTPARAMETER_SLIPPAGE); //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cExecutableLotCalculator final : public cExecutable { //==================== private: //==================== //=============== //=============== OUTPUTDOUBLE //=============== //=============== virtual bool ReFreshState(void)override final; //=============== //=============== //==================== public: //==================== //=============== //=============== void cExecutableLotCalculator(void):OutputValue(0.0){} virtual void ~cExecutableLotCalculator(void){} //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutableLotCalculator::ReFreshState(void)override final { //=============== if(!cExecutable::ReFreshState())return(false); //=============== //=============== this.OutputValue=0.0; //=============== //=============== string symbol=NULL; //=============== const bool symbolget=this.ParameterValueGet(ELEMENTPARAMETER_SYMBOLNAME,symbol); //=============== /* DEBUG ASSERTION */ASSERT({},symbolget,false,{}) //=============== //=============== long slpoints=0; //=============== const bool slpointsget=this.ParameterValueGet(ELEMENTPARAMETER_STOPLOSSPOINTS,slpoints); //=============== /* DEBUG ASSERTION */ASSERT({},slpointsget,false,{}) //=============== //=============== double moneyrisk=0.0; //=============== const bool moneyriskget=this.ParameterValueGet(ELEMENTPARAMETER_MONEYRISKPERTRADE,moneyrisk); //=============== /* DEBUG ASSERTION */ASSERT({},moneyriskget,false,{}) //=============== //=============== this.OutputValue=cTrade::GetLot(symbol,slpoints,moneyrisk); //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cExecutableTrades : public cExecutable { //==================== private: //==================== //=============== //=============== OUTPUTPOINTER //=============== //=============== cTradesGroupInfo TradesInfo; //=============== //=============== virtual bool ReFreshState(void)override final; //=============== //=============== virtual void UpdateTicketsArray(void)=NULL; //=============== //=============== //==================== protected: //==================== //=============== //=============== long Tickets[]; //=============== //=============== //==================== public: //==================== //=============== //=============== void cExecutableTrades(void){} virtual void ~cExecutableTrades(void){} //=============== //=============== void ValueGet(double &value,const eTradesGroupInfo infotype)const; void ValueGet(long &value,const eTradesGroupInfo infotype)const; //=============== //=============== void AddTicketsToArray(long &array[])const; //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutableTrades::AddTicketsToArray(long &array[])const { //=============== const int size=cArray::Size(this.Tickets); //=============== const int reserve=cArray::Size(array)+size; //=============== for(int i=0;i(executables[i]); //=============== /* DEBUG ASSERTION */ASSERT({},cPointer::Valid(tradesgroup),true,{}) //=============== if(!cPointer::Valid(tradesgroup))continue; //=============== //=============== tradesgroup.AddTicketsToArray(this.Tickets); //=============== } //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cExecutableTradesGroupInfo : public cExecutable { //==================== protected: //==================== //=============== //=============== void cExecutableTradesGroupInfo(void):InfoType(WRONG_VALUE),TradesGroup(NULL){} //=============== //=============== eTradesGroupInfo InfoType; const cExecutableTrades *TradesGroup; //=============== //=============== virtual bool ReFreshState(void)override; //=============== //=============== //==================== public: //==================== //=============== //=============== virtual void ~cExecutableTradesGroupInfo(void){} //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutableTradesGroupInfo::ReFreshState(void)override { //=============== if(!cExecutable::ReFreshState())return(false); //=============== //=============== const cExecutable *executable=NULL; //=============== const bool executableget=this.ParameterValueGet(ELEMENTPARAMETER_TRADESGROUP,executable); //=============== /* DEBUG ASSERTION */ASSERT({},executableget,false,{}) //=============== //=============== this.TradesGroup=dynamic_cast(executable); //=============== /* DEBUG ASSERTION */ASSERT({},cPointer::Valid(this.TradesGroup),false,{}) //=============== //=============== const bool infotypeget=this.ParameterValueGet(ELEMENTPARAMETER_TRADESGROUPINFO,this.InfoType); //=============== /* DEBUG ASSERTION */ASSERT({},infotypeget,false,{}) //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cExecutableTradesGroupInfoInteger final : public cExecutableTradesGroupInfo { //==================== private: //==================== //=============== //=============== OUTPUTLONG //=============== //=============== virtual bool ReFreshState(void)override final; //=============== //=============== //==================== public: //==================== //=============== //=============== void cExecutableTradesGroupInfoInteger(void):OutputValue(0){} virtual void ~cExecutableTradesGroupInfoInteger(void){} //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutableTradesGroupInfoInteger::ReFreshState(void)override final { //=============== if(!cExecutableTradesGroupInfo::ReFreshState())return(false); //=============== //=============== this.OutputValue=0; //=============== //=============== /* DEBUG ASSERTION */ASSERT({},cPointer::Valid(this.TradesGroup),true,{}) //=============== //=============== if(!cPointer::Valid(this.TradesGroup))return(true); //=============== //=============== this.TradesGroup.ValueGet(this.OutputValue,this.InfoType); //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cExecutableAccountInfo : public cExecutable { //==================== protected: //==================== //=============== //=============== eAccountInfo InfoType; //=============== //=============== void cExecutableAccountInfo(void):InfoType(WRONG_VALUE){} //=============== //=============== virtual bool ReFreshState(void)override; //=============== //=============== void ValueGet(double &value,const eAccountInfo infotype)const; void ValueGet(long &value,const eAccountInfo infotype)const; //=============== //=============== //==================== public: //==================== //=============== //=============== virtual void ~cExecutableAccountInfo(void){} //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutableAccountInfo::ValueGet(double &value,const eAccountInfo infotype)const { //=============== switch(infotype) { //=============== case ACCOUNTINFO_BALANCE : value=::AccountInfoDouble(ACCOUNT_BALANCE); break; case ACCOUNTINFO_EQUITY : value=::AccountInfoDouble(ACCOUNT_EQUITY); break; case ACCOUNTINFO_MARGINUSED : value=::AccountInfoDouble(ACCOUNT_MARGIN); break; case ACCOUNTINFO_FREEMARGIN : value=::AccountInfoDouble(ACCOUNT_MARGIN_FREE); break; case ACCOUNTINFO_FLOATINGPROFIT : value=::AccountInfoDouble(ACCOUNT_PROFIT); break; case ACCOUNTINFO_CREDIT : value=::AccountInfoDouble(ACCOUNT_CREDIT); break; //=============== default :/* DEBUG ASSERTION */ASSERT({},false,false,{}) break; //=============== } //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutableAccountInfo::ValueGet(long &value,const eAccountInfo infotype)const { //=============== switch(infotype) { //=============== case ACCOUNTINFO_LOGIN : value=::AccountInfoInteger(ACCOUNT_LOGIN); break; case ACCOUNTINFO_LEVERAGE : value=::AccountInfoInteger(ACCOUNT_LEVERAGE); break; //=============== default :/* DEBUG ASSERTION */ASSERT({},false,false,{}) break; //=============== } //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutableAccountInfo::ReFreshState(void)override { //=============== if(!cExecutable::ReFreshState())return(false); //=============== //=============== const bool typeget=this.ParameterValueGet(ELEMENTPARAMETER_ACCOUNTINFO,this.InfoType); //=============== /* DEBUG ASSERTION */ASSERT({},typeget,false,{}) //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cExecutableAccountInfoDouble final : public cExecutableAccountInfo { //==================== private: //==================== //=============== //=============== OUTPUTDOUBLE //=============== //=============== virtual bool ReFreshState(void)override final; //=============== //=============== //==================== public: //==================== //=============== //=============== void cExecutableAccountInfoDouble(void):OutputValue(0.0){} virtual void ~cExecutableAccountInfoDouble(void){} //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutableAccountInfoDouble::ReFreshState(void)override final { //=============== if(!cExecutableAccountInfo::ReFreshState())return(false); //=============== //=============== this.OutputValue=0; //=============== //=============== this.ValueGet(this.OutputValue,this.InfoType); //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cExecutableArithmetic final : public cExecutable { //==================== private: //==================== //=============== //=============== double Value1; double Value2; eMathOperation Operation; //=============== //=============== OUTPUTDOUBLE //=============== //=============== virtual bool ReFreshState(void)override final; //=============== //=============== //==================== public: //==================== //=============== //=============== void cExecutableArithmetic(void):OutputValue(0.0),Value1(0.0),Value2(0.0),Operation(WRONG_VALUE){} virtual void ~cExecutableArithmetic(void){} //=============== //=============== virtual void OnTrigger(void)override final; //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutableArithmetic::ReFreshState(void)override final { //=============== if(!cExecutable::ReFreshState())return(false); //=============== //=============== const bool value1get=this.ParameterValueGet(ELEMENTPARAMETER_DOUBLEVALUE1,this.Value1); //=============== /* DEBUG ASSERTION */ASSERT({},value1get,false,{}) //=============== //=============== const bool value2get=this.ParameterValueGet(ELEMENTPARAMETER_DOUBLEVALUE2,this.Value2); //=============== /* DEBUG ASSERTION */ASSERT({},value2get,false,{}) //=============== //=============== const bool operationget=this.ParameterValueGet(ELEMENTPARAMETER_MATHOPERATION,this.Operation); //=============== /* DEBUG ASSERTION */ASSERT({},operationget,false,{}) //=============== //=============== this.OutputValue=this.Value1; //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutableArithmetic::OnTrigger(void)override final { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== this.OutputValue=0.0; //=============== //=============== switch(this.Operation) { //=============== case MATHOPERATION_SUM : this.OutputValue=this.Value1+this.Value2; break; case MATHOPERATION_SUBTRACT : this.OutputValue=this.Value1-this.Value2; break; case MATHOPERATION_DIVIDE : if(this.Value2==0)break;this.OutputValue=this.Value1/this.Value2; break; case MATHOPERATION_REMAINDER : if(this.Value2==0)break;this.OutputValue=(double)((long)this.Value1%(long)this.Value2); break; case MATHOPERATION_MULTIPLY : this.OutputValue=this.Value1*this.Value2; break; case MATHOPERATION_POWER : this.OutputValue=::MathPow(this.Value1,this.Value2); break; case MATHOPERATION_MAXIMUM : this.OutputValue=::MathMax(this.Value1,this.Value2); break; case MATHOPERATION_MINIMUM : this.OutputValue=::MathMin(this.Value1,this.Value2); break; //=============== default :/* DEBUG ASSERTION */ASSERT({},false,false,{}) break; //=============== } //=============== //=============== cExecutable::OnTrigger(); //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cExecutableAnd final : public cExecutable { //==================== private: //==================== //=============== //=============== OUTPUTBOOL //=============== //=============== virtual bool ReFreshState(void)override final; //=============== //=============== //==================== public: //==================== //=============== //=============== void cExecutableAnd(void):OutputValue(false){} virtual void ~cExecutableAnd(void){} //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutableAnd::ReFreshState(void)override final { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== if(!cExecutable::ReFreshState())return(false); //=============== //=============== this.OutputValue=false; //=============== //=============== bool values[]; //=============== cArray::Free(values); //=============== const bool parametersget=this.ParameterValuesGet(ELEMENTPARAMETER_BOOLVALUE,values); //=============== /* DEBUG ASSERTION */ASSERT({},parametersget,false,{}) //=============== //=============== const int parametersnumber=cArray::Size(values); //=============== //=============== if(parametersnumber==0)return(true); //=============== //=============== bool result=true; //=============== //=============== for(int i=0;i=DBL_EPSILON); break; case RELATIONTYPE_GTEATEROREQUAL : this.OutputValue=(difference>-DBL_EPSILON); break; case RELATIONTYPE_EQUAL : this.OutputValue=(::fabs(difference)<=DBL_EPSILON); break; case RELATIONTYPE_LESS : this.OutputValue=(difference<-DBL_EPSILON); break; case RELATIONTYPE_LESSOREQUAL : this.OutputValue=(difference<=DBL_EPSILON); break; //=============== default :/* DEBUG ASSERTION */ASSERT({},false,false,{}) break; //=============== } //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cExecutableIndicatorValue final : public cExecutable { //==================== private: //==================== //=============== //=============== OUTPUTDOUBLE //=============== //=============== virtual bool ReFreshState(void)override final; //=============== //=============== //==================== public: //==================== //=============== //=============== void cExecutableIndicatorValue(void):OutputValue(0.0){} virtual void ~cExecutableIndicatorValue(void){} //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutableIndicatorValue::ReFreshState(void)override final { //=============== if(!cExecutable::ReFreshState())return(false); //=============== //=============== this.OutputValue=0.0; //=============== //=============== const cExecutable *executable=NULL; //=============== const bool getexecutable=this.ParameterValueGet(ELEMENTPARAMETER_INDICATOR,executable); //=============== /* DEBUG ASSERTION */ASSERT({},executable,false,{}) //=============== //=============== const cExecutableIndicator *const indicator=dynamic_cast(executable); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},cPointer::Valid(indicator),true,{}) //=============== //=============== if(!cPointer::Valid(indicator))return(true); //=============== //=============== long barnumber=-1; //=============== const bool getbarnumber=this.ParameterValueGet(ELEMENTPARAMETER_BARNUMBER,barnumber); //=============== /* DEBUG ASSERTION */ASSERT({},getbarnumber,false,{}) //=============== //=============== /* DEBUG ASSERTION */ASSERT({},barnumber>=0,true,{}) //=============== //=============== if(barnumber<0)return(true); //=============== //=============== this.OutputValue=indicator.ValueGet(barnumber); //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cExecutableIndicator : public cExecutable { //==================== private: //==================== //=============== //=============== OUTPUTPOINTER //=============== //=============== //==================== protected: //==================== //=============== //=============== void cExecutableIndicator(void):Symbol(NULL),TimeFrame(WRONG_VALUE),Handle(INVALID_HANDLE),Line(0){} //=============== //=============== int Handle; long Line; //=============== //=============== string Symbol; ENUM_TIMEFRAMES TimeFrame; //=============== //=============== double GetBufferValue(const int barnumber)const; //=============== //=============== virtual bool ReFreshState(void)override; //=============== //=============== //==================== public: //==================== //=============== //=============== void ValuesGet(const int barfromnumber,const int bartillnumber,double &values[])const; //=============== //=============== virtual void ~cExecutableIndicator(void){} //=============== //=============== virtual void HandleCreate(void)=NULL; //=============== //=============== virtual double ValueGet(const long barnumber)const=NULL; //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutableIndicator::ReFreshState(void)override { //=============== if(!cExecutable::ReFreshState())return(false); //=============== //=============== const bool getsymbol=this.ParameterValueGet(ELEMENTPARAMETER_SYMBOLNAME,this.Symbol); //=============== /* DEBUG ASSERTION */ASSERT({},getsymbol,false,{}) //=============== //=============== const bool gettimeframe=this.ParameterValueGet(ELEMENTPARAMETER_TIMEFRAME,this.TimeFrame); //=============== /* DEBUG ASSERTION */ASSERT({},gettimeframe,false,{}) //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutableIndicator::ValuesGet(const int barfromnumber,const int bartillnumber,double &values[])const { //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== cArray::Free(values); //=============== //=============== const int size=barfromnumber-bartillnumber+1; //=============== //=============== /* DEBUG ASSERTION */ASSERT({},size>0,true,{}) //=============== //=============== if(size<=0)return; //=============== //=============== #ifdef __MQL5__ //=============== /* DEBUG ASSERTION */ASSERT({},this.Handle!=INVALID_HANDLE,true,{}) //=============== //=============== if(this.Handle==INVALID_HANDLE)return; //=============== //=============== const int result=::CopyBuffer(this.Handle,(int)this.Line,bartillnumber,size,values); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},result==size,false,{}) //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== if(result!=size) { //=============== cArray::Free(values); //=============== } //=============== //=============== return; //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== for(long i=barfromnumber;i>=bartillnumber;i--) { //=============== cArray::AddLast(values,this.ValueGet(i),size); //=============== } //=============== #endif //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double cExecutableIndicator::GetBufferValue(const int barnumber)const { //=============== #ifdef __MQL5__ //=============== /* DEBUG MACROS' START */TRACEERRORS_START //=============== //=============== /* DEBUG ASSERTION */ASSERT({},this.Handle!=INVALID_HANDLE,true,{}) //=============== //=============== if(this.Handle==INVALID_HANDLE)return(0.0); //=============== //=============== double buffer[]; //=============== cArray::Free(buffer); //=============== //=============== const int result=::CopyBuffer(this.Handle,(int)this.Line,barnumber,1,buffer); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},result==1,false,{}) //=============== //=============== /* DEBUG MACROS' END */TRACEERRORS_END //=============== //=============== if(result!=1)return(0.0); //=============== //=============== return(buffer[0]); //=============== #endif //=============== //=============== return(0.0); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class cExecutableIndicatorRSI final : public cExecutableIndicator { //==================== private: //==================== //=============== //=============== long RSIPeriod; ENUM_APPLIED_PRICE AppliedPrice; //=============== //=============== virtual bool ReFreshState(void)override final; //=============== //=============== //==================== public: //==================== //=============== //=============== void cExecutableIndicatorRSI(void):RSIPeriod(-1),AppliedPrice(WRONG_VALUE){} virtual void ~cExecutableIndicatorRSI(void){} //=============== //=============== virtual void HandleCreate(void)override final; //=============== //=============== virtual double ValueGet(const long barnumber)override final const; //=============== //=============== }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool cExecutableIndicatorRSI::ReFreshState(void)override final { //=============== if(!cExecutableIndicator::ReFreshState())return(false); //=============== //=============== const bool getperiod=this.ParameterValueGet(ELEMENTPARAMETER_INDICATORPERIOD,this.RSIPeriod); //=============== /* DEBUG ASSERTION */ASSERT({},getperiod,false,{}) //=============== //=============== const bool getappliedprice=this.ParameterValueGet(ELEMENTPARAMETER_APPLIEDPRICE,this.AppliedPrice); //=============== /* DEBUG ASSERTION */ASSERT({},getappliedprice,false,{}) //=============== //=============== this.HandleCreate(); //=============== //=============== return(true); //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void cExecutableIndicatorRSI::HandleCreate(void)override final { //=============== #ifdef __MQL5__ //=============== this.Handle=iRSI(this.Symbol,this.TimeFrame,(int)this.RSIPeriod,this.AppliedPrice); //=============== //=============== /* DEBUG ASSERTION */ASSERT({},this.Handle!=INVALID_HANDLE,false,{}) //=============== #endif //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double cExecutableIndicatorRSI::ValueGet(const long barnumber)override final const { //=============== #ifdef __MQL5__ //=============== return(this.GetBufferValue((int)barnumber)); //=============== #endif //=============== //=============== #ifdef __MQL4__ //=============== return(iRSI(this.Symbol,this.TimeFrame,(int)this.RSIPeriod,this.AppliedPrice,(int)barnumber)); //=============== #endif //=============== } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+