diff --git a/EA.mqh b/EA.mqh index 97f0f6471..a7997a5e9 100644 --- a/EA.mqh +++ b/EA.mqh @@ -70,7 +70,7 @@ class EA : public Taskable { BufferStruct data_symbol; Dict ddata; // Custom user data. Dict idata; // Custom user data. - DictObject trade; + DictStruct> trade; DictObject> data_indi; DictObject> data_stg; EAParams eparams; @@ -114,11 +114,11 @@ class EA : public Taskable { // Add and process tasks. Init(); // Initialize a trade instance for the current chart and symbol. - Ref _source = Platform::FetchDefaultCandleIndicator(_Symbol, PERIOD_CURRENT); + Ref _source = Platform::FetchDefaultCandleIndicator(Platform::GetSymbol(), Platform::GetPeriod()); TradeParams _tparams(0, 1.0f, 0, (ENUM_LOG_LEVEL)eparams.Get(STRUCT_ENUM(EAParams, EA_PARAM_PROP_LOG_LEVEL))); - Trade _trade(_tparams, _source.Ptr()); + Ref _trade = new Trade(_tparams, _source.Ptr()); trade.Set(_Symbol, _trade); - logger.Link(_trade.GetLogger()); + logger.Link(_trade REF_DEREF GetLogger()); logger.SetLevel((ENUM_LOG_LEVEL)eparams.Get(STRUCT_ENUM(EAParams, EA_PARAM_PROP_LOG_LEVEL))); //_trade.GetLogger().SetLevel((ENUM_LOG_LEVEL)eparams.Get(STRUCT_ENUM(EAParams, EA_PARAM_PROP_LOG_LEVEL))); } @@ -253,7 +253,7 @@ class EA : public Taskable { */ template void Set(ENUM_TRADE_PARAM _param, T _value) { - for (DictObjectIterator iter = trade.Begin(); iter.IsValid(); ++iter) { + for (DictObjectIterator> iter = trade.Begin(); iter.IsValid(); ++iter) { Trade *_trade = iter.Value(); _trade PTR_DEREF Set(_param, _value); } @@ -279,7 +279,7 @@ class EA : public Taskable { // Ignores already processed signals. continue; } - Trade *_trade = trade.GetByKey(_Symbol); + Trade *_trade = trade.GetByKey(_Symbol).Ptr(); Strategy *_strat = strats.GetByKey(_signal PTR_DEREF Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_MAGIC_ID))).Ptr(); _trade_allowed &= _trade.IsTradeAllowed(); @@ -384,7 +384,7 @@ class EA : public Taskable { */ virtual bool TradeRequest(ENUM_ORDER_TYPE _cmd, string _symbol = NULL, Strategy *_strat = NULL) { bool _result = false; - Trade *_trade = trade.GetByKey(_symbol); + Trade *_trade = trade.GetByKey(_symbol).Ptr(); // Prepare a request. MqlTradeRequest _request = _trade PTR_DEREF GetTradeOpenRequest(_cmd); _request.comment = _strat PTR_DEREF GetOrderOpenComment(); @@ -450,7 +450,7 @@ class EA : public Taskable { for (DictStructIterator> iter = strats.Begin(); iter.IsValid(); ++iter) { bool _can_trade = true; Strategy *_strat = iter.Value().Ptr(); - Trade *_trade = trade.GetByKey(_Symbol); + Trade *_trade = trade.GetByKey(_Symbol).Ptr(); if (_strat PTR_DEREF IsEnabled()) { if (estate.Get(STRUCT_ENUM(EAState, EA_STATE_PROP_NEW_PERIODS)) >= DATETIME_MINUTE) { // Process when new periods started. @@ -595,9 +595,10 @@ class EA : public Taskable { SerializerConverter _stub = SerializerConverter::MakeStubObject>(_serializer_flags); - /* - for (DictStructIterator> iter = strats.Begin(); iter.IsValid(); ++iter) { - ENUM_TIMEFRAMES _itf = iter_tf.Key(); // @fixme + /* @todo + for (DictStructIterator> _iter = GetStrategies() PTR_DEREF Begin(); _iter.IsValid(); ++_iter) + { int _sid = (int)_iter.Key(); Strategy *_strat = _iter.Value().Ptr(); + // ENUM_TIMEFRAMES _itf = iter_tf.Key(); // @fixme if (data_indi.KeyExists(_itf)) { BufferStruct _indi_buff = data_indi.GetByKey(_itf); @@ -630,15 +631,16 @@ class EA : public Taskable { if (eparams.CheckFlagDataStore(EA_DATA_STORE_STRATEGY)) { SerializerConverter _stub = SerializerConverter::MakeStubObject>(_serializer_flags); - /* @fixme - for (DictStructIterator> iter = strats.Begin(); iter.IsValid(); ++iter) { - ENUM_TIMEFRAMES _stf = iter_tf.Key(); // @fixme - if (data_stg.KeyExists(_stf)) { - string _key_stg = StringFormat("Strategy-%d", _stf); - BufferStruct _stg_buff = data_stg.GetByKey(_stf); + for (DictStructIterator> _iter = GetStrategies() PTR_DEREF Begin(); _iter.IsValid(); + ++_iter) { + int _sid = (int)_iter.Key(); + Strategy *_strat = _iter.Value().Ptr(); + if (data_stg.KeyExists(_sid)) { + string _key_stg = StringFormat("Strategy-%d", _sid); + BufferStruct _stg_buff = data_stg.GetByKey(_sid); SerializerConverter _obj = SerializerConverter::FromObject(_stg_buff, _serializer_flags); - _key_stg += StringFormat("-%d-%d-%d", _stf, _stg_buff.GetMin(), _stg_buff.GetMax()); + _key_stg += StringFormat("-%d-%d-%d", _sid, _stg_buff.GetMin(), _stg_buff.GetMax()); if ((_methods & EA_DATA_EXPORT_CSV) != 0) { _obj.ToFile(_key_stg + ".csv", _serializer_flags, &_stub); } @@ -653,7 +655,6 @@ class EA : public Taskable { _obj.Clean(); } } - */ // Required because of SERIALIZER_FLAG_REUSE_STUB flag. _stub.Clean(); } @@ -818,7 +819,7 @@ class EA : public Taskable { */ bool StrategyLoadTrades(Strategy *_strat) { bool _result = true; - Trade *_trade = trade.GetByKey(_Symbol); + Trade *_trade = trade.GetByKey(_Symbol).Ptr(); // Load active trades. _result &= _trade.OrdersLoadByMagic(_strat PTR_DEREF Get(STRAT_PARAM_ID)); // Load strategy-specific order parameters (e.g. conditions). @@ -845,8 +846,8 @@ class EA : public Taskable { bool ProcessTrades() { bool _result = true; ResetLastError(); - for (DictObjectIterator titer = trade.Begin(); titer.IsValid(); ++titer) { - Trade *_trade = titer.Value(); + for (DictStructIterator> titer = trade.Begin(); titer.IsValid(); ++titer) { + Trade *_trade = titer.Value().Ptr(); if (_trade.Get(TRADE_STATE_ORDERS_ACTIVE) && !_trade.Get(TRADE_STATE_MARKET_CLOSED)) { for (DictStructIterator> oiter = _trade.GetOrdersActive().Begin(); oiter.IsValid(); ++oiter) { bool _sl_valid = false, _tp_valid = false; @@ -941,7 +942,7 @@ class EA : public Taskable { bool _result = false; if (eparams.CheckFlag(EA_PARAM_FLAG_LOTSIZE_AUTO)) { // Auto calculate lot size for all strategies. - Trade *_trade = trade.GetByKey(_Symbol); + Trade *_trade = trade.GetByKey(_Symbol).Ptr(); _result &= _trade PTR_DEREF Run(TRADE_ACTION_CALC_LOT_SIZE); Set(STRAT_PARAM_LS, _trade PTR_DEREF Get(TRADE_PARAM_LOT_SIZE)); } @@ -1033,13 +1034,13 @@ class EA : public Taskable { switch (_entry.GetId()) { case EA_ACTION_DISABLE: estate.Enable(false); - return true; + break; case EA_ACTION_ENABLE: estate.Enable(); - return true; + break; case EA_ACTION_EXPORT_DATA: DataExport(); - return true; + break; case EA_ACTION_STRATS_EXE_ACTION: { // Args: // 1st (i:0) - Strategy's enum action to execute. @@ -1051,7 +1052,7 @@ class EA : public Taskable { _result &= _strat PTR_DEREF Run(_entry_strat); } - return _result; + break; } case EA_ACTION_TASKS_CLEAN: tasks.GetTasks().Clear(); @@ -1059,6 +1060,7 @@ class EA : public Taskable { default: GetLogger() PTR_DEREF Error(StringFormat("Invalid EA action: %d!", _entry.GetId(), __FUNCTION_LINE__)); SetUserError(ERR_INVALID_PARAMETER); + _result = false; } return _result; } diff --git a/Exchange/Account/Account.enum.h b/Exchange/Account/Account.enum.h index 9d6246b8d..d1931e20a 100644 --- a/Exchange/Account/Account.enum.h +++ b/Exchange/Account/Account.enum.h @@ -50,6 +50,20 @@ enum ENUM_ACC_STAT_TYPE { ACC_VALUE_MIN = 0, ACC_VALUE_MAX = 1, ACC_VALUE_AVG = /* Account type of index for statistics. */ enum ENUM_ACC_STAT_INDEX { ACC_VALUE_CURR = 0, ACC_VALUE_PREV = 1, FINAL_ENUM_ACC_STAT_INDEX = 2 }; +#ifndef __MQL5__ +/** + * Enumeration for the margin modes. + * + * @docs + * https://www.mql5.com/en/docs/constants/environment_state/accountinformation + */ +enum ENUM_ACCOUNT_MARGIN_MODE { + ACCOUNT_MARGIN_MODE_RETAIL_NETTING, // Used for the OTC markets to interpret positions in the "netting" mode. + ACCOUNT_MARGIN_MODE_EXCHANGE, // Used for the exchange markets. + ACCOUNT_MARGIN_MODE_RETAIL_HEDGING, // Used for the exchange markets where individual positions are possible. +}; +#endif + #ifndef __MQL__ /** * Enumeration for the current account double values. @@ -147,3 +161,33 @@ enum ENUM_ACCOUNT_STOPOUT_MODE { ACCOUNT_STOPOUT_MODE_MONEY, // Account stop out mode in money. }; #endif + +/** + * Enumeration for the account integer param values. + * + * Used for function AccountInfoInteger(). + * + * @docs + * https://www.mql5.com/en/docs/constants/environment_state/accountinformation + */ +enum ENUM_ACCOUNT_PARAM_INTEGER { + ACCOUNT_PARAM_LOGIN = ACCOUNT_LOGIN, // Account number (long). + ACCOUNT_PARAM_TRADE_MODE = ACCOUNT_TRADE_MODE, // Account trade mode (ENUM_ACCOUNT_TRADE_MODE). + ACCOUNT_PARAM_LEVERAGE = ACCOUNT_LEVERAGE, // Account leverage (long). + ACCOUNT_PARAM_LIMIT_ORDERS = ACCOUNT_LIMIT_ORDERS, // Maximum allowed number of active pending orders (int). + ACCOUNT_PARAM_MARGIN_SO_MODE = + ACCOUNT_MARGIN_SO_MODE, // Mode for setting the minimal allowed margin (ENUM_ACCOUNT_STOPOUT_MODE). + ACCOUNT_PARAM_TRADE_ALLOWED = ACCOUNT_TRADE_ALLOWED, // Allowed trade for the current account (bool). + ACCOUNT_PARAM_TRADE_EXPERT = ACCOUNT_TRADE_EXPERT, // Allowed trade for an Expert Advisor (bool). +#ifdef __MQL5__ + ACCOUNT_PARAM_MARGIN_MODE = ACCOUNT_MARGIN_MODE, // Margin calculation mode (ENUM_ACCOUNT_MARGIN_MODE). + ACCOUNT_PARAM_CURRENCY_DIGITS = + ACCOUNT_CURRENCY_DIGITS, // The number of decimal places in the account currency (int). + ACCOUNT_PARAM_FIFO_CLOSE = + ACCOUNT_FIFO_CLOSE, // An indication showing that positions can only be closed by FIFO rule (bool). +#else + ACCOUNT_PARAM_MARGIN_MODE = 7, // Margin calculation mode (ENUM_ACCOUNT_MARGIN_MODE). + ACCOUNT_PARAM_CURRENCY_DIGITS, // The number of decimal places in the account currency (int). + ACCOUNT_PARAM_FIFO_CLOSE, // An indication showing that positions can only be closed by FIFO rule (bool). +#endif +}; diff --git a/Exchange/Account/Account.h b/Exchange/Account/Account.h index 3179fc274..cedbf79e8 100644 --- a/Exchange/Account/Account.h +++ b/Exchange/Account/Account.h @@ -28,6 +28,7 @@ // Includes. #include "../../Serializer/Serializer.h" #include "../../Storage/Dict/Buffer/BufferStruct.h" +#include "Account.struct.h" #include "AccountBase.h" /** @@ -36,6 +37,7 @@ template class Account : public AccountBase { protected: + AccountParams aparams; AS state; BufferStruct entries; @@ -52,8 +54,31 @@ class Account : public AccountBase { */ Account() { Init(); } + /** + * Class constructor with parameters. + */ + Account(AccountParams &_aparams) : aparams(_aparams) { Init(); } + + /** + * Class copy constructor. + */ + Account(Account &_account) { + state = _account.state; + // @todo: Copy entries. + } + /** * Class deconstructor. */ ~Account() {} + + /* Serializers */ + + /** + * Returns serialized representation of the object instance. + */ + virtual SerializerNodeType Serialize(Serializer &_s) { + _s.PassStruct(THIS_REF, "state", state); + return SerializerNodeObject; + } }; diff --git a/Exchange/Account/Account.struct.h b/Exchange/Account/Account.struct.h index eeb5324ee..bbd949095 100644 --- a/Exchange/Account/Account.struct.h +++ b/Exchange/Account/Account.struct.h @@ -34,10 +34,12 @@ class Serializer; // Includes. -#include "Account.enum.h" -#include "../../Serializer/Serializer.h" -#include "../../Serializer/Serializer.enum.h" #include "../../Platform/Terminal.define.h" +#include "../../Serializer/Serializer.enum.h" +#include "../../Serializer/Serializer.h" +#include "../../Serializer/SerializerConverter.h" +#include "../../Serializer/SerializerJson.h" +#include "Account.enum.h" // Struct for account entries. struct AccountEntry { @@ -108,3 +110,149 @@ struct AccountEntry { return WRONG_VALUE; } }; + +// Struct for account parameters. +struct AccountParams { + ENUM_ACCOUNT_MARGIN_MODE margin_mode; + ENUM_ACCOUNT_STOPOUT_MODE margin_so_mode; + ENUM_ACCOUNT_TRADE_MODE trade_mode; + bool trade_allowed, trade_expert; + int currency_digits, fifo_close, leverage, limit_orders, login; + string company, currency, name, server; + + // Default constructor. + AccountParams(int _login = 0, string _name = "Current", string _currency = "USD", string _company = "Unknown", + string _server = "Unknown") + : company(_company), currency(_currency), login(_login), name(_name), server(_server) {} + // Constructor based on JSON string. + AccountParams(string _entry) { SerializerConverter::FromString(_entry).ToStruct(THIS_REF); } + // Copy constructor. + AccountParams(const AccountParams& _aparams) { THIS_REF = _aparams; } + /* Getters */ + template + T Get(ENUM_ACCOUNT_PARAM_INTEGER _param) { + switch (_param) { + case ACCOUNT_PARAM_CURRENCY_DIGITS: + // The number of decimal places in the account currency (int). + return (T)currency_digits; + case ACCOUNT_PARAM_FIFO_CLOSE: + // An indication showing that positions can only be closed by FIFO rule (bool). + return (T)fifo_close; + case ACCOUNT_PARAM_LEVERAGE: + // Account leverage (long). + return (T)leverage; + case ACCOUNT_PARAM_LIMIT_ORDERS: + // Maximum allowed number of active pending orders (int). + return (T)limit_orders; + case ACCOUNT_PARAM_LOGIN: + // Account number (long). + return (T)login; + case ACCOUNT_PARAM_MARGIN_MODE: + // Margin calculation mode (ENUM_ACCOUNT_MARGIN_MODE). + return (T)margin_mode; + case ACCOUNT_PARAM_MARGIN_SO_MODE: + // Mode for setting the minimal allowed margin (ENUM_ACCOUNT_STOPOUT_MODE). + return (T)margin_so_mode; + case ACCOUNT_PARAM_TRADE_ALLOWED: + // Allowed trade for the current account (bool). + return (T)trade_allowed; + case ACCOUNT_PARAM_TRADE_EXPERT: + // Allowed trade for an Expert Advisor (bool). + return (T)trade_expert; + case ACCOUNT_PARAM_TRADE_MODE: + // Account trade mode (ENUM_ACCOUNT_TRADE_MODE). + return (T)trade_mode; + default: + break; + } + SetUserError(ERR_INVALID_PARAMETER); + return WRONG_VALUE; + } + string Get(ENUM_ACCOUNT_INFO_STRING _param) { + switch (_param) { + case ACCOUNT_NAME: + // Client name (string). + return name; + case ACCOUNT_COMPANY: + // Name of a company that serves the account (string). + return company; + case ACCOUNT_CURRENCY: + // Account currency (string). + return currency; + case ACCOUNT_SERVER: + // Trade server name (string). + return server; + default: + break; + } + SetUserError(ERR_INVALID_PARAMETER); + return ""; + } + template + void Set(ENUM_ACCOUNT_PARAM_INTEGER _param, T _value) { + switch (_param) { + case ACCOUNT_PARAM_CURRENCY_DIGITS: + // The number of decimal places in the account currency (int). + ConvertBasic::Convert(_value, currency_digits); + return; + case ACCOUNT_PARAM_FIFO_CLOSE: + // An indication showing that positions can only be closed by FIFO rule (bool). + ConvertBasic::Convert(_value, fifo_close); + return; + case ACCOUNT_PARAM_LEVERAGE: + // Account leverage (long). + ConvertBasic::Convert(_value, leverage); + return; + case ACCOUNT_PARAM_LIMIT_ORDERS: + // Maximum allowed number of active pending orders (int). + ConvertBasic::Convert(_value, limit_orders); + return; + case ACCOUNT_PARAM_LOGIN: + // Account number (long). + ConvertBasic::Convert(_value, login); + return; + case ACCOUNT_PARAM_MARGIN_MODE: + // Margin calculation mode (ENUM_ACCOUNT_MARGIN_MODE). + ConvertBasic::Convert(_value, margin_mode); + return; + case ACCOUNT_PARAM_MARGIN_SO_MODE: + // Mode for setting the minimal allowed margin (ENUM_ACCOUNT_STOPOUT_MODE). + ConvertBasic::Convert(_value, margin_so_mode); + return; + case ACCOUNT_PARAM_TRADE_ALLOWED: + // Allowed trade for the current account (bool). + ConvertBasic::Convert(_value, trade_allowed); + return; + case ACCOUNT_PARAM_TRADE_EXPERT: + // Allowed trade for an Expert Advisor (bool). + ConvertBasic::Convert(_value, trade_expert); + return; + case ACCOUNT_PARAM_TRADE_MODE: + // Account trade mode (ENUM_ACCOUNT_TRADE_MODE). + ConvertBasic::Convert(_value, trade_mode); + return; + default: + break; + } + SetUserError(ERR_INVALID_PARAMETER); + } + // Serializers. + void SerializeStub(int _n1 = 1, int _n2 = 1, int _n3 = 1, int _n4 = 1, int _n5 = 1) {} + SerializerNodeType Serialize(Serializer& _s) { + _s.Pass(THIS_REF, "company", company); + _s.Pass(THIS_REF, "currency", currency); + _s.Pass(THIS_REF, "currency_digits", currency_digits); + _s.Pass(THIS_REF, "fifo_close", fifo_close); + _s.Pass(THIS_REF, "leverage", leverage); + _s.Pass(THIS_REF, "limit_orders", limit_orders); + _s.Pass(THIS_REF, "login", login); + _s.Pass(THIS_REF, "name", name); + _s.Pass(THIS_REF, "server", server); + _s.Pass(THIS_REF, "trade_allowed", trade_allowed); // Convert to states. + _s.Pass(THIS_REF, "trade_expert", trade_expert); // Convert to states. + _s.PassEnum(THIS_REF, "margin_mode", margin_mode); + _s.PassEnum(THIS_REF, "margin_so_mode", margin_so_mode); + _s.PassEnum(THIS_REF, "trade_mode", trade_mode); + return SerializerNodeObject; + } +}; diff --git a/Exchange/Account/AccountBase.h b/Exchange/Account/AccountBase.h index a2011f01f..457d14a5b 100644 --- a/Exchange/Account/AccountBase.h +++ b/Exchange/Account/AccountBase.h @@ -27,6 +27,8 @@ // Includes. #include "../../Refs.mqh" +#include "../../Serializer/SerializerConverter.h" +#include "../../Serializer/SerializerJson.h" #include "AccountBase.struct.h" /** @@ -57,6 +59,20 @@ class AccountBase : public Dynamic { */ ~AccountBase() {} + /* Printer methods */ + + /** + * Returns textual representation of the object instance. + */ + virtual string ToString() { return SerializerConverter::FromObject(THIS_REF).ToString(); } + + /* Serializers */ + + /** + * Returns serialized representation of the object instance. + */ + virtual SerializerNodeType Serialize(Serializer &_s) = 0; + /* Virtual methods */ /** diff --git a/Exchange/Account/AccountBase.struct.h b/Exchange/Account/AccountBase.struct.h index d94d14f10..423784c2e 100644 --- a/Exchange/Account/AccountBase.struct.h +++ b/Exchange/Account/AccountBase.struct.h @@ -34,23 +34,16 @@ class Serializer; // Includes. -#include "Account.enum.h" -#include "../../Serializer/Serializer.h" +#include "../../Platform/Terminal.define.h" #include "../../Serializer/Serializer.enum.h" +#include "../../Serializer/Serializer.h" #include "../../Std.h" -#include "../../Platform/Terminal.define.h" +#include "Account.enum.h" // Struct for account entries. struct AccountBaseEntry { datetime dtime; double balance; - // Serializers. - void SerializeStub(int _n1 = 1, int _n2 = 1, int _n3 = 1, int _n4 = 1, int _n5 = 1) {} - SerializerNodeType Serialize(Serializer& _s) { - _s.Pass(THIS_REF, "time", dtime, SERIALIZER_FIELD_FLAG_DYNAMIC); - _s.Pass(THIS_REF, "balance", balance, SERIALIZER_FIELD_FLAG_DYNAMIC); - return SerializerNodeObject; - } /* Getters */ double Get(ENUM_ACCOUNT_INFO_DOUBLE _param) { switch (_param) { @@ -63,10 +56,23 @@ struct AccountBaseEntry { SetUserError(ERR_INVALID_PARAMETER); return WRONG_VALUE; } + // Serializers. + SERIALIZER_EMPTY_STUB; + SerializerNodeType Serialize(Serializer& _s) { + _s.Pass(THIS_REF, "time", dtime, SERIALIZER_FIELD_FLAG_DYNAMIC); + _s.Pass(THIS_REF, "balance", balance, SERIALIZER_FIELD_FLAG_DYNAMIC); + return SerializerNodeObject; + } }; // Struct for account base. struct AccountBaseState { datetime last_updated; double balance; + // Serializers. + SERIALIZER_EMPTY_STUB; + SerializerNodeType Serialize(Serializer& _s) { + _s.Pass(THIS_REF, "balance", balance); + return SerializerNodeObject; + } }; diff --git a/Exchange/Account/AccountForex.h b/Exchange/Account/AccountForex.h index ad7a97722..3308c9fb8 100644 --- a/Exchange/Account/AccountForex.h +++ b/Exchange/Account/AccountForex.h @@ -35,7 +35,6 @@ */ class AccountForex : public Account { protected: - // AP AccountParams; /** * Init code (called on constructor). */ @@ -49,6 +48,11 @@ class AccountForex : public Account { */ AccountForex() { Init(); } + /** + * Class constructor with account params. + */ + AccountForex(AccountParams &_aparams) : Account(_aparams) { Init(); } + /** * Class deconstructor. */ diff --git a/Exchange/Account/AccountForex.struct.h b/Exchange/Account/AccountForex.struct.h index 34abc2abc..1c8062c7f 100644 --- a/Exchange/Account/AccountForex.struct.h +++ b/Exchange/Account/AccountForex.struct.h @@ -34,9 +34,9 @@ class Serializer; // Includes. -#include "../../Serializer/Serializer.h" -#include "../../Serializer/Serializer.enum.h" #include "../../Platform/Terminal.define.h" +#include "../../Serializer/Serializer.enum.h" +#include "../../Serializer/Serializer.h" // Struct for account entries. struct AccountForexEntry : public AccountBaseEntry { @@ -99,4 +99,14 @@ struct AccountForexState : public AccountBaseState { double margin_used; double margin_free; double margin_avail; + // Serializers. + SerializerNodeType Serialize(Serializer& s) { + s.Pass(THIS_REF, "credit", credit); + s.Pass(THIS_REF, "equity", equity); + s.Pass(THIS_REF, "profit", profit); + s.Pass(THIS_REF, "margin_used", margin_used); + s.Pass(THIS_REF, "margin_free", margin_free); + s.Pass(THIS_REF, "margin_avail", margin_avail); + return SerializerNodeObject; + } }; diff --git a/Exchange/Exchange.enum.h b/Exchange/Exchange.enum.h new file mode 100644 index 000000000..3159069f6 --- /dev/null +++ b/Exchange/Exchange.enum.h @@ -0,0 +1,44 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * @file + * Includes Exchange's enumerations. + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Exchange actions. +enum ENUM_EXCHANGE_ACTION { + EXCHANGE_ACTION_ADD_ACCOUNT = 1, // Add Account + EXCHANGE_ACTION_ADD_SYMBOL, // Add Symbol + FINAL_ENUM_EXCHANGE_ACTION_ENTRY +}; + +// Exchange conditions. +enum ENUM_EXCHANGE_CONDITION { + EXCHANGE_COND_IS_ACTIVE = 1, // Is active + FINAL_ENUM_EXCHANGE_CONDITION_ENTRY +}; diff --git a/Exchange/Exchange.h b/Exchange/Exchange.h index 54c70277c..f29eca913 100644 --- a/Exchange/Exchange.h +++ b/Exchange/Exchange.h @@ -27,17 +27,23 @@ // Includes. #include "../Exchange/SymbolInfo/SymbolInfo.h" +#include "../Serializer/Serializer.h" #include "../Storage/Dict/DictObject.h" +#include "../Storage/State.struct.h" +#include "../Task/TaskManager.h" +#include "../Task/Taskable.h" #include "../Trade.mqh" -#include "Account/Account.h" +#include "Account/AccountForex.h" +#include "Exchange.enum.h" #include "Exchange.struct.h" -class Exchange : public Dynamic { +class Exchange : public Taskable { protected: - DictStruct> accounts; + DictStruct> accounts; DictStruct> symbols; DictStruct> trades; ExchangeParams eparams; + State estate; public: /** @@ -60,9 +66,17 @@ class Exchange : public Dynamic { /** * Adds account instance to the list. */ - void AccountAdd(AccountBase *_account, string _name) { + void AccountAdd(AccountBase *_account, int _id = 0) { Ref _ref = _account; - accounts.Set(_name, _ref); + accounts.Set(_id, _ref); + } + + /** + * Adds account instance to the list. + */ + void AccountAdd(AccountParams &_aparams) { + AccountBase *_account = new AccountForex(/*_aparams*/); + AccountAdd(_account); } /** @@ -81,12 +95,24 @@ class Exchange : public Dynamic { trades.Set(_name, _ref); } + /* Getters */ + + /** + * Gets DictStruct reference to accounts. + */ + DictStruct> *GetAccounts() { return GetPointer(accounts); } + + /** + * Gets DictStruct reference to symbols. + */ + DictStruct> *GetSymbols() { return GetPointer(symbols); } + /* Removers */ /** * Removes account instance from the list. */ - void AccountRemove(string _name) { accounts.Unset(_name); } + void AccountRemove(int _id) { accounts.Unset(_id); } /** * Removes symbol instance from the list. @@ -97,4 +123,84 @@ class Exchange : public Dynamic { * Removes trade instance from the list. */ void TradeRemove(string _name) { trades.Unset(_name); } + + /* Taskable methods */ + + /** + * Checks a condition. + */ + bool Check(const TaskConditionEntry &_entry) { + bool _result = true; + switch (_entry.GetId()) { + default: + _result = false; + SetUserError(ERR_INVALID_PARAMETER); + } + return _result; + } + + /** + * Gets a data param entry. + */ + DataParamEntry Get(const TaskGetterEntry &_entry) { + DataParamEntry _result; + switch (_entry.GetId()) { + default: + SetUserError(ERR_INVALID_PARAMETER); + } + return _result; + } + + /** + * Runs an action. + */ + bool Run(const TaskActionEntry &_entry) { + bool _result = true; + switch (_entry.GetId()) { + case EXCHANGE_ACTION_ADD_ACCOUNT: + if (!_entry.HasArgs()) { + AccountAdd(new AccountForex()); + } else { + AccountParams _aparams(_entry.GetArg(0).ToString()); + Ref _account1_ref = new AccountForex(_aparams); + accounts.Set(_aparams.Get(ACCOUNT_PARAM_LOGIN), _account1_ref); + } + break; + default: + _result = false; + SetUserError(ERR_INVALID_PARAMETER); + } + return _result; + } + + /** + * Sets an entry value. + */ + bool Set(const TaskSetterEntry &_entry, const DataParamEntry &_entry_value) { + bool _result = true; + switch (_entry.GetId()) { + default: + _result = false; + SetUserError(ERR_INVALID_PARAMETER); + } + return _result; + } + + /* Serializers */ + + /** + * Returns serialized representation of the object instance. + */ + SerializerNodeType Serialize(Serializer &_s) { + _s.PassStruct(THIS_REF, "eparams", eparams); + _s.PassStruct(THIS_REF, "accounts", accounts); + //_s.PassStruct(THIS_REF, "symbols", symbols); + //_s.PassStruct(THIS_REF, "trades", trades); + return SerializerNodeObject; + } + + /** + * Returns textual representation of the object instance. + */ + string ToString() { return SerializerConverter::FromObject(THIS_REF).ToString(); } }; diff --git a/Exchange/Exchange.struct.h b/Exchange/Exchange.struct.h index 13c9c569b..34430b5a9 100644 --- a/Exchange/Exchange.struct.h +++ b/Exchange/Exchange.struct.h @@ -30,13 +30,61 @@ #pragma once #endif -// Forward class declaration. -class Exchange; +// Includes. +#include "../Serializer/SerializerNode.enum.h" /* Defines struct for Exchange parameters. */ struct ExchangeParams { + private: + int id; + string name; + + public: + // Enumeration of exchange parameters. + enum ENUM_EXCHANGE_PARAM { + EXCHANGE_PARAM_ID = 1, // ID + EXCHANGE_PARAM_NAME, // Name + FINAL_ENUM_EXCHANGE_PARAM_ENTRY + }; +#define ENUM_EXCHANGE_PARAM STRUCT_ENUM(ExchangeParams, ENUM_EXCHANGE_PARAM) + public: // Constructors. - ExchangeParams() {} - ExchangeParams(const ExchangeParams &_eparams) {} - int64 id; + ExchangeParams(int _id = 0, string _name = "") : id(_id), name(_name) {} + ExchangeParams(const ExchangeParams &_eparams) { THIS_REF = _eparams; } + ExchangeParams(string _entry) { SerializerConverter::FromString(_entry).ToStruct(THIS_REF); } + // Getters. + template + T Get(ENUM_EXCHANGE_PARAM _param) { + switch (_param) { + case EXCHANGE_PARAM_ID: + return (T)id; + case EXCHANGE_PARAM_NAME: + // return (T)name; // @todo + default: + break; + } + SetUserError(ERR_INVALID_PARAMETER); + return WRONG_VALUE; + } + // Setters. + template + void Set(ENUM_TRADE_PARAM _param, T _value) { + switch (_param) { + case EXCHANGE_PARAM_ID: + ConvertBasic::Convert(_value, id); + return; + case EXCHANGE_PARAM_NAME: + ConvertBasic::Convert(_value, name); + return; + default: + break; + } + SetUserError(ERR_INVALID_PARAMETER); + } + // Serializers. + SerializerNodeType Serialize(Serializer &s) { + s.Pass(THIS_REF, "id", id); + s.Pass(THIS_REF, "name", name); + return SerializerNodeObject; + } }; diff --git a/Exchange/README.md b/Exchange/README.md index 31411ab33..bb2cda512 100644 --- a/Exchange/README.md +++ b/Exchange/README.md @@ -4,7 +4,7 @@ ```mermaid classDiagram - Dynamic <|-- Exchange + Taskable <|-- Exchange Exchange: Account[] Exchange: Symbol[] Exchange: Trade[] diff --git a/Exchange/SymbolInfo/SymbolInfo.extern.h b/Exchange/SymbolInfo/SymbolInfo.extern.h index 98a2f4a7c..ca74989b4 100644 --- a/Exchange/SymbolInfo/SymbolInfo.extern.h +++ b/Exchange/SymbolInfo/SymbolInfo.extern.h @@ -32,10 +32,21 @@ // Define external global functions. #ifndef __MQL__ -extern int64 SymbolInfoInteger(string name, ENUM_SYMBOL_INFO_INTEGER prop_id); -extern bool SymbolInfoMarginRate(string name, ENUM_ORDER_TYPE order_type, double &initial_margin_rate, - double &maintenance_margin_rate); -extern bool SymbolInfoTick(string symbol, MqlTick &tick); +int64 SymbolInfoInteger(string name, ENUM_SYMBOL_INFO_INTEGER prop_id) { + Print("Not yet implemented: ", __FUNCTION__, " returns 0."); + return 0; +} + +bool SymbolInfoMarginRate(string name, ENUM_ORDER_TYPE order_type, double& initial_margin_rate, + double& maintenance_margin_rate) { + Print("Not yet implemented: ", __FUNCTION__, " returns false."); + return false; +} + +bool SymbolInfoTick(string symbol, MqlTick& tick) { + Print("Not yet implemented: ", __FUNCTION__, " returns false."); + return 0; +} // Define external global variables. class SymbolGetter { diff --git a/Exchange/tests/Exchange.test.mq5 b/Exchange/tests/Exchange.test.mq5 index 5d94b2246..d9b5205ee 100644 --- a/Exchange/tests/Exchange.test.mq5 +++ b/Exchange/tests/Exchange.test.mq5 @@ -24,6 +24,9 @@ * Test functionality of Exchange class. */ +// Defines. +#define __debug_serializer__ + // Includes. #include "../../Platform/Platform.h" #include "../../Test.mqh" @@ -104,6 +107,24 @@ bool TestExchange01() { return _result; } +// Test dummy Exchange via tasks. +bool TestExchange02() { + bool _result = true; + // Initialize a dummy Exchange instance. + ExchangeParams _eparams(0, __FUNCTION__); + Ref exchange = new ExchangeDummy(_eparams); + // Add account01 via task. + TaskActionEntry _task_add_acc_01(EXCHANGE_ACTION_ADD_ACCOUNT); + exchange.Ptr().Run(_task_add_acc_01); + // Add account02 via task from JSON. + TaskActionEntry _task_add_acc_02(EXCHANGE_ACTION_ADD_ACCOUNT); + DataParamEntry _acc_02_entry = "{\"id\": 1, \"name\": \"Account02\", \"currency\": \"USD\"}"; + _task_add_acc_02.ArgAdd(_acc_02_entry); + exchange.Ptr().Run(_task_add_acc_02); + Print(exchange.Ptr().ToString()); + return _result; +} + /** * Implements OnInit(). */ @@ -111,5 +132,6 @@ int OnInit() { Platform::Init(); bool _result = true; assertTrueOrFail(TestExchange01(), "Fail!"); + assertTrueOrFail(TestExchange02(), "Fail!"); return _result && GetLastError() == 0 ? INIT_SUCCEEDED : INIT_FAILED; } diff --git a/Indicator/IndicatorData.h b/Indicator/IndicatorData.h index e08ab6799..4e3ff01da 100644 --- a/Indicator/IndicatorData.h +++ b/Indicator/IndicatorData.h @@ -2034,7 +2034,7 @@ IValueStorage* ExternInstantiateIndicatorBufferValueStorageDouble::InstantiateIn } #ifndef __MQL__ -int GetBarsFromStart(IndicatorData* _indi) { return _indi PTR_DEREF GetBars(); } +int GetBarsFromStart(IndicatorBase* _indi) { return _indi PTR_DEREF GetBars(); } #endif #ifdef EMSCRIPTEN diff --git a/Platform/Platform.enum.h b/Platform/Platform.enum.h index 8c8b75309..c195ba137 100644 --- a/Platform/Platform.enum.h +++ b/Platform/Platform.enum.h @@ -25,7 +25,7 @@ #pragma once #endif -#ifndef __MQL4__ +#ifndef __MQL__ // @note Values differ from the documentation at // https://www.mql5.com/en/docs/matrix/matrix_initialization/matrix_copyticks // @see https://www.mql5.com/en/forum/448933 @@ -42,3 +42,15 @@ enum ENUM_COPY_TICKS { COPY_TICKS_FLAGS = 2097152 }; #endif + +// Platform actions. +enum ENUM_PLATFORM_ACTION { + PLATFORM_ACTION_ADD_EXCHANGE = 1, // Add Exchange + FINAL_ENUM_PLATFORM_ACTION_ENTRY +}; + +// Platform conditions. +enum ENUM_PLATFORM_CONDITION { + PLATFORM_COND_IS_ACTIVE = 1, // Is active + FINAL_ENUM_PLATFORM_CONDITION_ENTRY +}; diff --git a/Platform/Platform.h b/Platform/Platform.h index 101208e38..5311bdd6b 100644 --- a/Platform/Platform.h +++ b/Platform/Platform.h @@ -28,6 +28,7 @@ #include "Deal.enum.h" #include "Order.struct.h" #include "Platform.define.h" +#include "Platform.enum.h" /** * Extern declarations for C++. @@ -41,16 +42,17 @@ extern int Bars(CONST_REF_TO_SIMPLE(string) _symbol, ENUM_TIMEFRAMES _tf); #endif // Includes. - -/** - * Current platform's static methods. - */ - +#include "../Exchange/Exchange.h" #include "../Indicator/IndicatorData.h" #include "../Indicator/tests/classes/IndicatorTfDummy.h" #include "../Indicators/DrawIndicator.mqh" +#include "../Serializer/Serializer.h" #include "../Std.h" #include "../Storage/Flags.struct.h" +#include "../Task/TaskManager.h" +#include "../Task/Taskable.h" +#include "Platform.enum.h" +#include "Platform.struct.h" #ifdef __MQLBUILD__ #include "../Indicators/Tf/Indi_TfMt.h" @@ -64,7 +66,11 @@ extern int Bars(CONST_REF_TO_SIMPLE(string) _symbol, ENUM_TIMEFRAMES _tf); #endif #include "../Exchange/SymbolInfo/SymbolInfo.struct.static.h" -class Platform { +class Platform : public Taskable { + protected: + DictStruct> exchanges; + PlatformParams pparams; + // Whether Init() was already called. static bool initialized; @@ -98,7 +104,50 @@ class Platform { // Timeframe of the currently ticking indicator. static ENUM_TIMEFRAMES period; + private: + /** + * Sets symbol of the currently ticking indicator. + **/ + static void SetSymbol(string _symbol) { symbol = _symbol; } + + /** + * Sets timeframe of the currently ticking indicator. + **/ + static void SetPeriod(ENUM_TIMEFRAMES _period) { period = _period; } + public: + /** + * Class constructor without parameters. + */ + Platform(){}; + + /** + * Class constructor with parameters. + */ + Platform(PlatformParams &_pparams) : pparams(_pparams){}; + + /** + * Class deconstructor. + */ + ~Platform() {} + + /* Adders */ + + /** + * Adds Exchange instance to the list. + */ + void ExchangeAdd(Exchange *_Exchange, int _id = 0) { + Ref _ref = _Exchange; + exchanges.Set(_id, _ref); + } + + /** + * Adds Exchange instance to the list. + */ + void ExchangeAdd(ExchangeParams &_eparams) { ExchangeAdd(new Exchange(_eparams)); } + + /* Static methods */ + /** * Initializes platform. */ @@ -111,6 +160,26 @@ class Platform { initialized = true; } + /** + * When testing code inside the OnInit() method symbol and tf may be + * undefined. This is a way to solve that problem. Use only for + * testing! + */ + static void SetSymbolTfForTesting(string _symbol, ENUM_TIMEFRAMES _tf) { + if (_symbol == PLATFORM_WRONG_SYMBOL) { + Print("Error: SetSymbolTfForTesting() requires valid symbol. Passed \"", _symbol, "\"."); + DebugBreak(); + } + + if (_tf == PERIOD_CURRENT || _tf == PLATFORM_WRONG_TIMEFRAME) { + Print("Error: SetSymbolTfForTesting() requires valid time-frame. Passed \"", EnumToString(_tf), "\"."); + DebugBreak(); + } + + symbol = _symbol; + period = _tf; + } + /** * Returns global tick index. */ @@ -485,16 +554,83 @@ class Platform { return 2; } - private: + /* Taskable methods */ + /** - * Sets symbol of the currently ticking indicator. - **/ - static void SetSymbol(string _symbol) { symbol = _symbol; } + * Checks a condition. + */ + bool Check(const TaskConditionEntry &_entry) { + bool _result = true; + switch (_entry.GetId()) { + default: + _result = false; + SetUserError(ERR_INVALID_PARAMETER); + } + return _result; + } /** - * Sets timeframe of the currently ticking indicator. - **/ - static void SetPeriod(ENUM_TIMEFRAMES _period) { period = _period; } + * Gets a data param entry. + */ + DataParamEntry Get(const TaskGetterEntry &_entry) { + DataParamEntry _result; + switch (_entry.GetId()) { + default: + SetUserError(ERR_INVALID_PARAMETER); + } + return _result; + } + + /** + * Runs an action. + */ + bool Run(const TaskActionEntry &_entry) { + bool _result = true; + switch (_entry.GetId()) { + case PLATFORM_ACTION_ADD_EXCHANGE: + if (!_entry.HasArgs()) { + ExchangeAdd(new Exchange()); + } else { + ExchangeParams _eparams(_entry.GetArg(0).ToString()); + Ref _exchange1_ref = new Exchange(_eparams); + exchanges.Set(_eparams.Get(STRUCT_ENUM(ExchangeParams, EXCHANGE_PARAM_ID)), _exchange1_ref); + } + break; + default: + _result = false; + SetUserError(ERR_INVALID_PARAMETER); + } + return _result; + } + + /** + * Sets an entry value. + */ + bool Set(const TaskSetterEntry &_entry, const DataParamEntry &_entry_value) { + bool _result = true; + switch (_entry.GetId()) { + default: + _result = false; + SetUserError(ERR_INVALID_PARAMETER); + } + return _result; + } + + /* Serializers */ + + /** + * Returns serialized representation of the object instance. + */ + SerializerNodeType Serialize(Serializer &_s) { + _s.PassStruct(THIS_REF, "params", pparams); + //_s.PassStruct(THIS_REF, "exchanges", exchanges); + return SerializerNodeObject; + } + + /** + * Returns textual representation of the object instance. + */ + string ToString() { return SerializerConverter::FromObject(THIS_REF).ToString(); } }; bool Platform::initialized = false; diff --git a/Platform/Platform.struct.h b/Platform/Platform.struct.h new file mode 100644 index 000000000..182be7476 --- /dev/null +++ b/Platform/Platform.struct.h @@ -0,0 +1,90 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * @file + * Includes Platform's structs. + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +// Includes. +#include "../Serializer/SerializerNode.enum.h" + +/* Defines struct for Platform parameters. */ +struct PlatformParams { + private: + int id; + string name; + + public: + // Enumeration of platform parameters. + enum ENUM_PLATFORM_PARAM { + PLATFORM_PARAM_ID = 1, // ID + PLATFORM_PARAM_NAME, // Name + FINAL_ENUM_PLATFORM_PARAM_ENTRY + }; +#define ENUM_PLATFORM_PARAM STRUCT_ENUM(PlatformParams, ENUM_PLATFORM_PARAM) + public: + // Constructors. + PlatformParams() {} + PlatformParams(const PlatformParams &_eparams) { THIS_REF = _eparams; } + PlatformParams(string _entry) { SerializerConverter::FromString(_entry).ToStruct(THIS_REF); } + // Getters. + template + T Get(ENUM_PLATFORM_PARAM _param) { + switch (_param) { + case PLATFORM_PARAM_ID: + return (T)id; + case PLATFORM_PARAM_NAME: + return (T)name; + default: + break; + } + SetUserError(ERR_INVALID_PARAMETER); + return WRONG_VALUE; + } + // Setters. + template + void Set(ENUM_TRADE_PARAM _param, T _value) { + switch (_param) { + case PLATFORM_PARAM_ID: + ConvertBasic::Convert(_value, id); + return; + case PLATFORM_PARAM_NAME: + ConvertBasic::Convert(_value, name); + return; + default: + break; + } + SetUserError(ERR_INVALID_PARAMETER); + } + // Serializers. + SerializerNodeType Serialize(Serializer &s) { + s.Pass(THIS_REF, "id", id); + s.Pass(THIS_REF, "name", name); + return SerializerNodeObject; + } +}; diff --git a/Platform/README.md b/Platform/README.md new file mode 100644 index 000000000..610ac2115 --- /dev/null +++ b/Platform/README.md @@ -0,0 +1,9 @@ +# Exchange + +## Classes + +```mermaid +classDiagram + Taskable <|-- Platform + Platform: Exchange[] +``` diff --git a/Platform/Terminal.define.h b/Platform/Terminal.define.h index 61ef792c3..c2ac1a0d5 100644 --- a/Platform/Terminal.define.h +++ b/Platform/Terminal.define.h @@ -352,7 +352,9 @@ #define ERR_INVALID_STOPS 130 #define ERR_INVALID_TRADE_VOLUME 131 #define ERR_MARKET_CLOSED 132 -//#define ERR_TRADE_DISABLED 133 +#ifndef __MQL__ +#define ERR_TRADE_DISABLED 133 // Already defined in MQL4. +#endif #define ERR_NOT_ENOUGH_MONEY 134 #define ERR_PRICE_CHANGED 135 #define ERR_OFF_QUOTES 136 diff --git a/Platform/tests/Platform.test.mq5 b/Platform/tests/Platform.test.mq5 index f7df7c7a6..e74c0fc50 100644 --- a/Platform/tests/Platform.test.mq5 +++ b/Platform/tests/Platform.test.mq5 @@ -28,12 +28,30 @@ #include "../../Test.mqh" #include "../Platform.h" +// Test Platform tasks. +bool TestPlatform01() { + bool _result = true; + // Initialize a dummy Exchange instance. + PlatformParams _pparams("{\"name\": \"Platform\"}"); + Ref platform = new Platform(_pparams); + // Add exchange01 via task. + TaskActionEntry _task_add_ex_01(PLATFORM_ACTION_ADD_EXCHANGE); + platform.Ptr().Run(_task_add_ex_01); + // Add exchange02 from JSON via task. + TaskActionEntry _task_add_ex_02(PLATFORM_ACTION_ADD_EXCHANGE); + DataParamEntry _ex_02_entry = "{\"id\": 1, \"name\": \"exchange02\"}"; + _task_add_ex_02.ArgAdd(_ex_02_entry); + platform.Ptr().Run(_task_add_ex_02); + Print(platform.Ptr().ToString()); + return _result; +} + /** * Implements OnInit(). */ int OnInit() { bool _result = true; - // @todo: Write some tests. + assertTrueOrFail(TestPlatform01(), "Fail!"); return _result && GetLastError() == 0 ? INIT_SUCCEEDED : INIT_FAILED; } diff --git a/Refs.struct.h b/Refs.struct.h index e238323c8..3f421fb03 100644 --- a/Refs.struct.h +++ b/Refs.struct.h @@ -31,6 +31,7 @@ #endif #include "Refs.rc.h" +#include "Serializer/SerializerNode.enum.h" #include "Std.h" #ifdef EMSCRIPTEN @@ -38,7 +39,8 @@ #endif class Dynamic; -// Forward class declaration. +// Forward declarations. +class Serializer; template struct WeakRef; @@ -282,6 +284,11 @@ struct Ref { return ptr_object PTR_DEREF ToString(); } + +#ifdef __MQL__ + template <> +#endif + SerializerNodeType Serialize(Serializer& s); }; #ifdef __cplusplus diff --git a/Serializer/Serializer.ref.h b/Serializer/Serializer.ref.h new file mode 100644 index 000000000..06a04388a --- /dev/null +++ b/Serializer/Serializer.ref.h @@ -0,0 +1,49 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +// Prevents processing this includes file for the second time. +#ifndef __MQL__ +#pragma once +#endif + +#include "../Refs.struct.h" + +template +#ifdef __MQL__ +template <> +SerializerNodeType Ref::Serialize(Serializer& s) { +#else +SerializerNodeType Ref::Serialize(Serializer& s) { +#endif + if (s.IsWriting()) { + if (Ptr() == nullptr) { + // Missing object! + Alert("Error: Ref serialization is supported only for non-null references!"); + DebugBreak(); + return SerializerNodeObject; + } + return Ptr() PTR_DEREF Serialize(s); + } else { + // Reading. + return Ptr() PTR_DEREF Serialize(s); + } +} diff --git a/Serializer/SerializerConverter.h b/Serializer/SerializerConverter.h index 31e013779..52827e456 100644 --- a/Serializer/SerializerConverter.h +++ b/Serializer/SerializerConverter.h @@ -35,7 +35,7 @@ class SerializerNode; #include "SerializerDict.h" #include "SerializerNode.h" -#ifdef __debug_verbose__ +#ifdef __debug_serializer__ #include "SerializerJson.h" #endif @@ -68,7 +68,7 @@ class SerializerConverter { _serializer.FreeRootNodeOwnership(); _serializer.PassObject(_value, "", _value, SERIALIZER_FIELD_FLAG_VISIBLE); SerializerConverter _converter(_serializer.GetRoot(), serializer_flags); -#ifdef __debug_verbose__ +#ifdef __debug_serializer__ Print("FromObject(): serializer flags: ", serializer_flags); Print("FromObject(): result: ", _serializer.GetRoot() != NULL ? _serializer.GetRoot() PTR_DEREF ToString(SERIALIZER_JSON_NO_WHITESPACES) @@ -83,7 +83,7 @@ class SerializerConverter { _serializer.FreeRootNodeOwnership(); _serializer.PassObject(_value, "", _value, SERIALIZER_FIELD_FLAG_VISIBLE); SerializerConverter _converter(_serializer.GetRoot(), serializer_flags); -#ifdef __debug_verbose__ +#ifdef __debug_serializer__ Print("FromObject(): serializer flags: ", serializer_flags); Print("FromObject(): result: ", _serializer.GetRoot() != NULL ? _serializer.GetRoot() PTR_DEREF ToString(SERIALIZER_JSON_NO_WHITESPACES) @@ -115,7 +115,7 @@ class SerializerConverter { template static SerializerConverter FromString(string arg) { SerializerConverter _converter(((C*)NULL)PTR_DEREF Parse(arg), 0); -#ifdef __debug_verbose__ +#ifdef __debug_serializer__ Print("FromString(): result: ", _converter.Node() != NULL ? _converter.Node() PTR_DEREF ToString(SERIALIZER_JSON_NO_WHITESPACES) : "NULL"); #endif diff --git a/Serializer/SerializerCsv.h b/Serializer/SerializerCsv.h index 6db82e328..5c16c2857 100644 --- a/Serializer/SerializerCsv.h +++ b/Serializer/SerializerCsv.h @@ -115,7 +115,7 @@ class SerializerCsv { } } -#ifdef __debug_verbose__ +#ifdef __debug_serializer__ Print("Stub: ", _stub PTR_DEREF Node() PTR_DEREF ToString()); Print("Data: ", _root PTR_DEREF ToString()); Print("Size: ", _num_columns, " x ", _num_rows); diff --git a/Serializer/SerializerJson.h b/Serializer/SerializerJson.h index 6e841fb31..776a6818d 100644 --- a/Serializer/SerializerJson.h +++ b/Serializer/SerializerJson.h @@ -145,7 +145,8 @@ class SerializerJson { else if (StringGetCharacter(data, 0) == '[') ; else { - return GracefulReturn("Failed to parse JSON. It must start with either \"{\" or \"[\".", 0, NULL, NULL); + return GracefulReturn( + string(__FUNCTION__) + "(): Failed to parse JSON. It must start with either \"{\" or \"[\".", 0, NULL, NULL); } SerializerNode* root = NULL; @@ -182,7 +183,7 @@ class SerializerJson { extracted = ExtractString(data, i + 1); if (extracted == "") { - return GracefulReturn("Unexpected end of file when parsing string", i, root, key); + return GracefulReturn(string(__FUNCTION__) + "(): Unexpected end of file when parsing string", i, root, key); } if (expectingKey) { key = SerializerNodeParam::FromString(extracted); @@ -193,31 +194,33 @@ class SerializerJson { ? SerializerNodeObjectProperty : SerializerNodeArrayItem, current, key, SerializerNodeParam::FromString(extracted)))); + // Key is in use so we don't want to delete it. + key = NULL; -#ifdef __debug__ - Print("SerializerJson: Value \"" + extracted + "\" for key " + +#ifdef __debug_serializer__ + Print(string(__FUNCTION__) + "(): Value \"" + extracted + "\" for key " + (key != NULL ? ("\"" + key PTR_DEREF ToString() + "\"") : "")); #endif expectingValue = false; } else { - return GracefulReturn("Unexpected '\"' symbol", i, root, key); + return GracefulReturn(string(__FUNCTION__) + "(): Unexpected '\"' symbol", i, root, key); } // Skipping double quotes. i += StringLen(extracted) + 1; } else if (expectingSemicolon) { if (ch != ':') { - return GracefulReturn("Expected semicolon", i, root, key); + return GracefulReturn(string(__FUNCTION__) + "(): Expected semicolon", i, root, key); } expectingSemicolon = false; expectingValue = true; } else if (ch == '{') { if (expectingKey) { - return GracefulReturn("Cannot use object as a key", i, root, key); + return GracefulReturn(string(__FUNCTION__) + "(): Cannot use object as a key", i, root, key); } -#ifdef __debug__ +#ifdef __debug_serializer__ Print("SerializerJson: Entering object for key " + (key != NULL ? ("\"" + key PTR_DEREF ToString() + "\"") : "")); #endif @@ -232,14 +235,15 @@ class SerializerJson { expectingValue = false; expectingKey = ch2 != '}'; + // Key is in use so we don't want to delete it. key = NULL; } else if (ch == '}') { if (expectingKey || expectingValue || PTR_ATTRIB(current, GetType()) != SerializerNodeObject) { - return GracefulReturn("Unexpected end of object", i, root, key); + return GracefulReturn(string(__FUNCTION__) + "(): Unexpected end of object", i, root, key); } -#ifdef __debug__ - Print("SerializerJson: Leaving object for key " + +#ifdef __debug_serializer__ + Print(string(__FUNCTION__) + "(): Leaving object for key " + (current != NULL && current PTR_DEREF GetKeyParam() != NULL ? ("\"" + current PTR_DEREF GetKeyParam() PTR_DEREF ToString() + "\"") : "")); @@ -248,13 +252,13 @@ class SerializerJson { current = PTR_ATTRIB(current, GetParent()); expectingValue = false; } else if (ch == '[') { -#ifdef __debug__ - Print("SerializerJson: Entering list for key " + +#ifdef __debug_serializer__ + Print(string(__FUNCTION__) + "(): Entering list for key " + (key != NULL ? ("\"" + key PTR_DEREF ToString() + "\"") : "")); #endif if (expectingKey) { - return GracefulReturn("Cannot use array as a key", i, root, key); + return GracefulReturn(string(__FUNCTION__) + "(): Cannot use array as a key", i, root, key); } node = new SerializerNode(SerializerNodeArray, current, key); @@ -265,32 +269,33 @@ class SerializerJson { current = node; expectingValue = ch2 != ']'; + // Key is in use so we don't want to delete it. key = NULL; } else if (ch == ']') { -#ifdef __debug__ - Print("SerializerJson: Leaving list for key " + +#ifdef __debug_serializer__ + Print(string(__FUNCTION__) + "(): Leaving list for key " + (key != NULL ? ("\"" + key PTR_DEREF ToString() + "\"") : "")); #endif if (expectingKey || expectingValue || PTR_ATTRIB(current, GetType()) != SerializerNodeArray) { - return GracefulReturn("Unexpected end of array", i, root, key); + return GracefulReturn(string(__FUNCTION__) + "(): Unexpected end of array", i, root, key); } current = PTR_ATTRIB(current, GetParent()); expectingValue = false; } else if (ch >= '0' && ch <= '9') { if (!expectingValue) { - return GracefulReturn("Unexpected numeric value", i, root, key); + return GracefulReturn(string(__FUNCTION__) + "(): Unexpected numeric value", i, root, key); } if (!ExtractNumber(data, i, extracted)) { - return GracefulReturn("Cannot parse numeric value", i, root, key); + return GracefulReturn(string(__FUNCTION__) + "(): Cannot parse numeric value", i, root, key); } value = StringFind(extracted, ".") != -1 ? SerializerNodeParam::FromValue(StringToDouble(extracted)) : SerializerNodeParam::FromValue(StringToInteger(extracted)); -#ifdef __debug__ - Print("SerializerJson: Value " + value PTR_DEREF AsString() + " for key " + +#ifdef __debug_serializer__ + Print(string(__FUNCTION__) + "(): Value " + value PTR_DEREF AsString() + " for key " + (key != NULL ? ("\"" + key PTR_DEREF ToString() + "\"") : "")); #endif @@ -303,16 +308,16 @@ class SerializerJson { // Skipping value. i += StringLen(extracted) - 1; - // We don't want to delete it twice. + // Key is in use so we don't want to delete it. key = NULL; } else if (ch == 't' || ch == 'f') { // Assuming true/false. value = SerializerNodeParam::FromValue(ch == 't' ? true : false); -#ifdef __debug__ - Print(string("SerializerJson: Value ") + (value PTR_DEREF ToBool() ? "true" : "false") + " for key " + - (key != NULL ? ("\"" + key PTR_DEREF ToString() + "\"") : "")); +#ifdef __debug_serializer__ + Print(string(string(__FUNCTION__) + "(): Value ") + (value PTR_DEREF ToBool() ? "true" : "false") + + " for key " + (key != NULL ? ("\"" + key PTR_DEREF ToString() + "\"") : "")); #endif // Skipping value. @@ -324,11 +329,11 @@ class SerializerJson { current, key, value))); expectingValue = false; - // We don't want to delete it twice. + // Key is in use so we don't want to delete it. key = NULL; } else if (ch == ',') { if (expectingKey || expectingValue || expectingSemicolon) { - return GracefulReturn("Unexpected comma", i, root, key); + return GracefulReturn(string(__FUNCTION__) + "(): Unexpected comma", i, root, key); } if (PTR_ATTRIB(current, GetType()) == SerializerNodeObject) @@ -338,7 +343,9 @@ class SerializerJson { } } - if (key) delete key; + if (key) { + delete key; + } return root; } diff --git a/Serializer/SerializerNodeParam.h b/Serializer/SerializerNodeParam.h index c4cd01498..1b1cdb100 100644 --- a/Serializer/SerializerNodeParam.h +++ b/Serializer/SerializerNodeParam.h @@ -176,7 +176,7 @@ class SerializerNodeParam { _fp_precision); } -#ifdef __debug__ +#ifdef __debug_serializer__ PrintFormat("%s: Error: SerializerNodeParam.AsString() called for an unknown value type: %d!", __FUNCTION__, _type); #endif return ""; diff --git a/Serializer/SerializerSqlite.h b/Serializer/SerializerSqlite.h index 0204ee589..0748c6e00 100644 --- a/Serializer/SerializerSqlite.h +++ b/Serializer/SerializerSqlite.h @@ -56,7 +56,7 @@ class SerializerSqlite { string _csv = SerializerCsv::Stringify(source.root_node, _stringify_flags | SERIALIZER_CSV_INCLUDE_TITLES, _stub, &_matrix_out, &_column_types); -#ifdef __debug__ +#ifdef __debug_serializer__ Print("SerializerSqlite: Parsing CSV input:\n", _csv); #endif diff --git a/Serializer/tests/Serializable.test.cpp b/Serializer/tests/Serializable.test.cpp index ad60d7be0..220e8048f 100644 --- a/Serializer/tests/Serializable.test.cpp +++ b/Serializer/tests/Serializable.test.cpp @@ -1,36 +1,36 @@ -//+------------------------------------------------------------------+ -//| EA31337 framework | -//| Copyright 2016-2023, EA31337 Ltd | -//| https://ea31337.github.io | -//+------------------------------------------------------------------+ - -/* - * This file is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @file - * Test C++ compilation of Serializable class. - */ - -// Includes. -#include "../Serializable.h" - -#include "../../Platform/Platform.h" - -int main(int argc, char **argv) { - // @todo - - return 0; -} +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Test C++ compilation of Serializable class. + */ + +// Includes. +#include "../Serializable.h" + +#include "../../Platform/Platform.h" + +int main(int argc, char **argv) { + // @todo + + return 0; +} diff --git a/Serializer/tests/Serializer.test.cpp b/Serializer/tests/Serializer.test.cpp index cd6cad5f9..50b09bbf4 100644 --- a/Serializer/tests/Serializer.test.cpp +++ b/Serializer/tests/Serializer.test.cpp @@ -1,36 +1,36 @@ -//+------------------------------------------------------------------+ -//| EA31337 framework | -//| Copyright 2016-2023, EA31337 Ltd | -//| https://ea31337.github.io | -//+------------------------------------------------------------------+ - -/* - * This file is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @file - * Test C++ compilation of Serializer class. - */ - -// Includes. -#include "../Serializer.h" - -#include "../../Platform/Platform.h" - -int main(int argc, char **argv) { - // @todo - - return 0; -} +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Test C++ compilation of Serializer class. + */ + +// Includes. +#include "../Serializer.h" + +#include "../../Platform/Platform.h" + +int main(int argc, char **argv) { + // @todo + + return 0; +} diff --git a/Serializer/tests/Serializer.test.mq5 b/Serializer/tests/Serializer.test.mq5 index d6e5e1cb0..d47f376ef 100644 --- a/Serializer/tests/Serializer.test.mq5 +++ b/Serializer/tests/Serializer.test.mq5 @@ -19,7 +19,7 @@ * along with this program. If not, see . */ -#define __debug__ +#define __debug_serializer__ /** * @file @@ -27,12 +27,12 @@ */ // Includes. -#include "../../Storage/Dict/Buffer/BufferStruct.h" -#include "../../Platform/Chart/Chart.h" #include "../../Config.mqh" +#include "../../Platform/Chart/Chart.h" #include "../../Storage/Data.define.h" #include "../../Storage/Data.struct.h" #include "../../Storage/Data.struct.serialize.h" +#include "../../Storage/Dict/Buffer/BufferStruct.h" #include "../../Storage/Dict/DictStruct.h" #include "../../Test.mqh" #include "../Serializer.h" diff --git a/Serializer/tests/SerializerBinary.test.cpp b/Serializer/tests/SerializerBinary.test.cpp index 1b784bab3..6348f4455 100644 --- a/Serializer/tests/SerializerBinary.test.cpp +++ b/Serializer/tests/SerializerBinary.test.cpp @@ -1,36 +1,36 @@ -//+------------------------------------------------------------------+ -//| EA31337 framework | -//| Copyright 2016-2023, EA31337 Ltd | -//| https://ea31337.github.io | -//+------------------------------------------------------------------+ - -/* - * This file is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @file - * Test C++ compilation of SerializerBinary class. - */ - -// Includes. -#include "../SerializerBinary.h" - -#include "../../Platform/Platform.h" - -int main(int argc, char **argv) { - // @todo - - return 0; -} +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Test C++ compilation of SerializerBinary class. + */ + +// Includes. +#include "../SerializerBinary.h" + +#include "../../Platform/Platform.h" + +int main(int argc, char **argv) { + // @todo + + return 0; +} diff --git a/Serializer/tests/SerializerConversions.test.cpp b/Serializer/tests/SerializerConversions.test.cpp index 0b06b3943..1bc2cfbb0 100644 --- a/Serializer/tests/SerializerConversions.test.cpp +++ b/Serializer/tests/SerializerConversions.test.cpp @@ -1,36 +1,36 @@ -//+------------------------------------------------------------------+ -//| EA31337 framework | -//| Copyright 2016-2023, EA31337 Ltd | -//| https://ea31337.github.io | -//+------------------------------------------------------------------+ - -/* - * This file is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @file - * Test C++ compilation of SerializerConversions class. - */ - -// Includes. -#include "../SerializerConversions.h" - -#include "../../Platform/Platform.h" - -int main(int argc, char **argv) { - // @todo - - return 0; -} +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Test C++ compilation of SerializerConversions class. + */ + +// Includes. +#include "../SerializerConversions.h" + +#include "../../Platform/Platform.h" + +int main(int argc, char **argv) { + // @todo + + return 0; +} diff --git a/Serializer/tests/SerializerConverter.test.cpp b/Serializer/tests/SerializerConverter.test.cpp index b5156758b..85dac8db3 100644 --- a/Serializer/tests/SerializerConverter.test.cpp +++ b/Serializer/tests/SerializerConverter.test.cpp @@ -1,36 +1,36 @@ -//+------------------------------------------------------------------+ -//| EA31337 framework | -//| Copyright 2016-2023, EA31337 Ltd | -//| https://ea31337.github.io | -//+------------------------------------------------------------------+ - -/* - * This file is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @file - * Test C++ compilation of SerializerConverter class. - */ - -// Includes. -#include "../SerializerConverter.h" - -#include "../../Platform/Platform.h" - -int main(int argc, char **argv) { - // @todo - - return 0; -} +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Test C++ compilation of SerializerConverter class. + */ + +// Includes. +#include "../SerializerConverter.h" + +#include "../../Platform/Platform.h" + +int main(int argc, char **argv) { + // @todo + + return 0; +} diff --git a/Serializer/tests/SerializerCsv.test.cpp b/Serializer/tests/SerializerCsv.test.cpp index 73175c8b9..49487c342 100644 --- a/Serializer/tests/SerializerCsv.test.cpp +++ b/Serializer/tests/SerializerCsv.test.cpp @@ -1,36 +1,36 @@ -//+------------------------------------------------------------------+ -//| EA31337 framework | -//| Copyright 2016-2024, EA31337 Ltd | -//| https://ea31337.github.io | -//+------------------------------------------------------------------+ - -/* - * This file is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @file - * Test C++ compilation of SerializerCsv class. - */ - -// Includes. -#include "../SerializerCsv.h" - -#include "../../Platform/Platform.h" - -int main(int argc, char **argv) { - // @todo - - return 0; -} +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2024, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Test C++ compilation of SerializerCsv class. + */ + +// Includes. +#include "../SerializerCsv.h" + +#include "../../Platform/Platform.h" + +int main(int argc, char **argv) { + // @todo + + return 0; +} diff --git a/Serializer/tests/SerializerDict.test.cpp b/Serializer/tests/SerializerDict.test.cpp index 68b01a7d4..a79d237e3 100644 --- a/Serializer/tests/SerializerDict.test.cpp +++ b/Serializer/tests/SerializerDict.test.cpp @@ -1,36 +1,36 @@ -//+------------------------------------------------------------------+ -//| EA31337 framework | -//| Copyright 2016-2023, EA31337 Ltd | -//| https://ea31337.github.io | -//+------------------------------------------------------------------+ - -/* - * This file is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @file - * Test C++ compilation of SerializerDict class. - */ - -// Includes. -#include "../SerializerDict.h" - -#include "../../Platform/Platform.h" - -int main(int argc, char **argv) { - // @todo - - return 0; -} +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Test C++ compilation of SerializerDict class. + */ + +// Includes. +#include "../SerializerDict.h" + +#include "../../Platform/Platform.h" + +int main(int argc, char **argv) { + // @todo + + return 0; +} diff --git a/Serializer/tests/SerializerJson.test.cpp b/Serializer/tests/SerializerJson.test.cpp index bb3975a0e..5a15a5676 100644 --- a/Serializer/tests/SerializerJson.test.cpp +++ b/Serializer/tests/SerializerJson.test.cpp @@ -1,36 +1,36 @@ -//+------------------------------------------------------------------+ -//| EA31337 framework | -//| Copyright 2016-2023, EA31337 Ltd | -//| https://ea31337.github.io | -//+------------------------------------------------------------------+ - -/* - * This file is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @file - * Test C++ compilation of SerializerJson class. - */ - -// Includes. -#include "../SerializerJson.h" - -#include "../../Platform/Platform.h" - -int main(int argc, char **argv) { - // @todo - - return 0; -} +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Test C++ compilation of SerializerJson class. + */ + +// Includes. +#include "../SerializerJson.h" + +#include "../../Platform/Platform.h" + +int main(int argc, char **argv) { + // @todo + + return 0; +} diff --git a/Serializer/tests/SerializerNode.test.cpp b/Serializer/tests/SerializerNode.test.cpp index cc4f28237..f49862163 100644 --- a/Serializer/tests/SerializerNode.test.cpp +++ b/Serializer/tests/SerializerNode.test.cpp @@ -1,36 +1,36 @@ -//+------------------------------------------------------------------+ -//| EA31337 framework | -//| Copyright 2016-2023, EA31337 Ltd | -//| https://ea31337.github.io | -//+------------------------------------------------------------------+ - -/* - * This file is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @file - * Test C++ compilation of SerializerNode class. - */ - -// Includes. -#include "../SerializerNode.h" - -#include "../../Platform/Platform.h" - -int main(int argc, char **argv) { - // @todo - - return 0; -} +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Test C++ compilation of SerializerNode class. + */ + +// Includes. +#include "../SerializerNode.h" + +#include "../../Platform/Platform.h" + +int main(int argc, char **argv) { + // @todo + + return 0; +} diff --git a/Serializer/tests/SerializerNodeIterator.test.cpp b/Serializer/tests/SerializerNodeIterator.test.cpp index f11e9ee51..0df95521c 100644 --- a/Serializer/tests/SerializerNodeIterator.test.cpp +++ b/Serializer/tests/SerializerNodeIterator.test.cpp @@ -1,36 +1,36 @@ -//+------------------------------------------------------------------+ -//| EA31337 framework | -//| Copyright 2016-2023, EA31337 Ltd | -//| https://ea31337.github.io | -//+------------------------------------------------------------------+ - -/* - * This file is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @file - * Test C++ compilation of SerializerNodeIterator class. - */ - -// Includes. -#include "../SerializerNodeIterator.h" - -#include "../../Platform/Platform.h" - -int main(int argc, char **argv) { - // @todo - - return 0; -} +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Test C++ compilation of SerializerNodeIterator class. + */ + +// Includes. +#include "../SerializerNodeIterator.h" + +#include "../../Platform/Platform.h" + +int main(int argc, char **argv) { + // @todo + + return 0; +} diff --git a/Serializer/tests/SerializerNodeParam.test.cpp b/Serializer/tests/SerializerNodeParam.test.cpp index de4601e87..de1b64317 100644 --- a/Serializer/tests/SerializerNodeParam.test.cpp +++ b/Serializer/tests/SerializerNodeParam.test.cpp @@ -1,36 +1,36 @@ -//+------------------------------------------------------------------+ -//| EA31337 framework | -//| Copyright 2016-2023, EA31337 Ltd | -//| https://ea31337.github.io | -//+------------------------------------------------------------------+ - -/* - * This file is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @file - * Test C++ compilation of SerializerNodeParam class. - */ - -// Includes. -#include "../SerializerNodeParam.h" - -#include "../../Platform/Platform.h" - -int main(int argc, char **argv) { - // @todo - - return 0; -} +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Test C++ compilation of SerializerNodeParam class. + */ + +// Includes. +#include "../SerializerNodeParam.h" + +#include "../../Platform/Platform.h" + +int main(int argc, char **argv) { + // @todo + + return 0; +} diff --git a/Serializer/tests/SerializerObject.test.cpp b/Serializer/tests/SerializerObject.test.cpp index 66bef2d08..f8d5b0586 100644 --- a/Serializer/tests/SerializerObject.test.cpp +++ b/Serializer/tests/SerializerObject.test.cpp @@ -1,36 +1,36 @@ -//+------------------------------------------------------------------+ -//| EA31337 framework | -//| Copyright 2016-2023, EA31337 Ltd | -//| https://ea31337.github.io | -//+------------------------------------------------------------------+ - -/* - * This file is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @file - * Test C++ compilation of SerializerObject class. - */ - -// Includes. -#include "../SerializerObject.h" - -#include "../../Platform/Platform.h" - -int main(int argc, char **argv) { - // @todo - - return 0; -} +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Test C++ compilation of SerializerObject class. + */ + +// Includes. +#include "../SerializerObject.h" + +#include "../../Platform/Platform.h" + +int main(int argc, char **argv) { + // @todo + + return 0; +} diff --git a/Serializer/tests/SerializerSqlite.test.cpp b/Serializer/tests/SerializerSqlite.test.cpp index 13f4002e8..982d6fb8a 100644 --- a/Serializer/tests/SerializerSqlite.test.cpp +++ b/Serializer/tests/SerializerSqlite.test.cpp @@ -1,36 +1,36 @@ -//+------------------------------------------------------------------+ -//| EA31337 framework | -//| Copyright 2016-2023, EA31337 Ltd | -//| https://ea31337.github.io | -//+------------------------------------------------------------------+ - -/* - * This file is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * @file - * Test C++ compilation of SerializerSqlite class. - */ - -// Includes. -#include "../SerializerSqlite.h" - -#include "../../Platform/Platform.h" - -int main(int argc, char **argv) { - // @todo - - return 0; -} +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * @file + * Test C++ compilation of SerializerSqlite class. + */ + +// Includes. +#include "../SerializerSqlite.h" + +#include "../../Platform/Platform.h" + +int main(int argc, char **argv) { + // @todo + + return 0; +} diff --git a/Storage/Data.struct.h b/Storage/Data.struct.h index eccdcb798..7a85f266e 100644 --- a/Storage/Data.struct.h +++ b/Storage/Data.struct.h @@ -36,6 +36,7 @@ struct MqlParam; struct MqlRates; // Includes. +#include "../Convert.extern.h" #include "../Serializer/Serializer.enum.h" #include "../Serializer/SerializerNode.enum.h" #include "../Std.h" @@ -217,9 +218,30 @@ struct DataParamEntry : public MqlParam { /* Getters */ + /** + * Gets a string of the given type. + */ + string ToString() { + switch (type) { + case TYPE_CHAR: + case TYPE_STRING: + case TYPE_UCHAR: + return string_value; + case TYPE_DOUBLE: + case TYPE_FLOAT: + return DoubleToString(double_value); + default: + case TYPE_BOOL: + case TYPE_INT: + case TYPE_LONG: + case TYPE_UINT: + case TYPE_ULONG: + return IntegerToString(integer_value); + } + } + /** * Gets a value of the given type. - * */ template T ToValue() { @@ -307,10 +329,14 @@ struct DataParamEntry : public MqlParam { switch (param.type) { case TYPE_BOOL: return param.integer_value ? 1 : 0; + case TYPE_COLOR: + case TYPE_DATETIME: case TYPE_INT: case TYPE_LONG: + case TYPE_SHORT: case TYPE_UINT: case TYPE_ULONG: + case TYPE_USHORT: return (double)param.integer_value; case TYPE_DOUBLE: case TYPE_FLOAT: @@ -319,11 +345,6 @@ struct DataParamEntry : public MqlParam { case TYPE_STRING: case TYPE_UCHAR: return ::StringToDouble(param.string_value); - case TYPE_COLOR: - case TYPE_DATETIME: - case TYPE_SHORT: - case TYPE_USHORT: - return DBL_MIN; } return DBL_MIN; } @@ -342,6 +363,7 @@ struct DataParamEntry : public MqlParam { case TYPE_UINT: case TYPE_ULONG: case TYPE_SHORT: + case TYPE_USHORT: return param.integer_value; case TYPE_DOUBLE: case TYPE_FLOAT: @@ -351,12 +373,38 @@ struct DataParamEntry : public MqlParam { case TYPE_STRING: case TYPE_UCHAR: return ::StringToInteger(param.string_value); - case TYPE_USHORT: - return INT_MIN; } return INT_MIN; } + /** + * Converts MqlParam struct to string. + * + */ + static string ToString(MqlParam ¶m) { + switch (param.type) { + case TYPE_BOOL: + return param.integer_value ? "true" : "false"; + case TYPE_DATETIME: + case TYPE_INT: + case TYPE_LONG: + case TYPE_UINT: + case TYPE_ULONG: + case TYPE_SHORT: + case TYPE_USHORT: + return IntegerToString(param.integer_value); + case TYPE_DOUBLE: + case TYPE_FLOAT: + return DoubleToString(param.double_value); + case TYPE_CHAR: + case TYPE_COLOR: + case TYPE_STRING: + case TYPE_UCHAR: + return param.string_value; + } + return ""; + } + /* Serializers */ /** diff --git a/Storage/DateTime.extern.h b/Storage/DateTime.extern.h index ebd99b875..1c7b14554 100644 --- a/Storage/DateTime.extern.h +++ b/Storage/DateTime.extern.h @@ -55,14 +55,22 @@ class datetime { operator int64() const { return dt; } }; -extern int CopyTime(string symbol_name, ENUM_TIMEFRAMES timeframe, int start_pos, int count, - ARRAY_REF(datetime, time_array)); +int CopyTime(string symbol_name, ENUM_TIMEFRAMES timeframe, int start_pos, int count, ARRAY_REF(datetime, time_array)) { + Print("Not yet implemented: ", __FUNCTION__, " returns 0."); + return 0; +} extern int CopyTime(string symbol_name, ENUM_TIMEFRAMES timeframe, datetime start_time, int count, - ARRAY_REF(datetime, time_array)); + ARRAY_REF(datetime, time_array)) { + Print("Not yet implemented: ", __FUNCTION__, " returns 0."); + return 0; +} extern int CopyTime(string symbol_name, ENUM_TIMEFRAMES timeframe, datetime start_time, datetime stop_time, - ARRAY_REF(datetime, time_array)); + ARRAY_REF(datetime, time_array)) { + Print("Not yet implemented: ", __FUNCTION__, " returns 0."); + return 0; +} extern datetime StructToTime(MqlDateTime& dt_struct); extern bool TimeToStruct(datetime dt, MqlDateTime& dt_struct); diff --git a/Storage/State.struct.h b/Storage/State.struct.h new file mode 100644 index 000000000..a1ea8757e --- /dev/null +++ b/Storage/State.struct.h @@ -0,0 +1,72 @@ +//+------------------------------------------------------------------+ +//| EA31337 framework | +//| Copyright 2016-2023, EA31337 Ltd | +//| https://ea31337.github.io | +//+------------------------------------------------------------------+ + +/* + * This file is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef __MQL__ +// Allows the preprocessor to include a header file when it is needed. +#pragma once +#endif + +/** + * State structure. + */ +struct State { + protected: + unsigned int state; // Bitwise value. + public: + // Struct constructor. + State() : state(0) {} + unsigned int GetState() { return state; } + // Struct methods for bitwise operations. + bool Has(unsigned int _state) { return (state & _state) != 0 || state == _state; } + // Checks whether current states has any given states. + bool HasAny(unsigned int _state) { return (state & _state) != 0; } + // Checks whether current states has all given states. + bool HasMulti(unsigned int _state) { return (state & _state) == _state; } + // Adds a single state to the current states. + void Add(unsigned int _state) { state |= _state; } + // Clear all states. + void ClearAll() { state = 0; } + // Clears given state or multiple states from the current states. + void Clear(unsigned int _state) { state &= ~_state; } + void SetState(unsigned int _state, bool _value = true) { + if (_value) { + Add(_state); + } else { + Clear(_state); + } + } + void SetState(unsigned int _state) { state = _state; } + // Static methods. + static bool Compare(unsigned int _state1, unsigned int _state2) { + return (_state2 & _state1) != 0 || _state2 == _state1; + } + // Serializers. + void SerializeStub(int _n1 = 1, int _n2 = 1, int _n3 = 1, int _n4 = 1, int _n5 = 1) {} + SerializerNodeType Serialize(Serializer &_s) { + int _size = sizeof(int) * 8; + for (int i = 0; i < _size; i++) { + int _value = Has(1 << i) ? 1 : 0; + _s.Pass(THIS_REF, IntegerToString(i + 1), _value, SERIALIZER_FIELD_FLAG_DYNAMIC); + } + return SerializerNodeObject; + } +}; diff --git a/Task/TaskAction.struct.h b/Task/TaskAction.struct.h index 367967349..a40115cde 100644 --- a/Task/TaskAction.struct.h +++ b/Task/TaskAction.struct.h @@ -30,10 +30,10 @@ #endif // Includes. -#include "../Storage/Data.struct.h" +#include "../Platform/Terminal.define.h" #include "../Serializer/Serializer.define.h" #include "../Std.h" -#include "../Platform/Terminal.define.h" +#include "../Storage/Data.struct.h" #include "Task.enum.h" // Forward declarations. @@ -99,6 +99,7 @@ struct TaskActionEntry { } void SetFlags(unsigned char _flags) { flags = _flags; } // State methods. + bool HasArgs() const { return ::ArraySize(args) > 0; } bool HasTriesLeft() const { return tries > 0 || tries == -1; } bool IsActive() const { return HasFlag(STRUCT_ENUM(TaskActionEntry, TASK_ACTION_ENTRY_FLAG_IS_ACTIVE)); } bool IsDone() const { return HasFlag(STRUCT_ENUM(TaskActionEntry, TASK_ACTION_ENTRY_FLAG_IS_DONE)); } @@ -126,7 +127,13 @@ struct TaskActionEntry { SetUserError(ERR_INVALID_PARAMETER); return InvalidEnumValue::value(); } - DataParamEntry GetArg(int _index) const { return args[_index]; } + DataParamEntry GetArg(int _index) const { + if (_index < 0 || _index >= ArraySize(args)) { + Alert(string("Error at ") + __FUNCSIG__ + ": index " + IntegerToString(_index) + " is out of bounds. There are " + + IntegerToString(ArraySize(args)) + " arguments in the task action."); + } + return args[_index]; + } int GetId() const { return id; } // Setters. void TriesDec() { diff --git a/Trade.enum.h b/Trade.enum.h index 560e4831c..89190879e 100644 --- a/Trade.enum.h +++ b/Trade.enum.h @@ -74,7 +74,7 @@ enum ENUM_TRADE_CONDITION { TRADE_COND_ORDERS_PROFIT_LT_ARG, // Equity >= (arg) TRADE_COND_ORDERS_PROFIT_GT_RISK_MARGIN, // Equity >= Risk Margin TRADE_COND_ORDERS_PROFIT_LT_RISK_MARGIN, // Equity <= Risk Margin - FINAL_ENUM_TRADE_CONDITION_ENTRY = 4 + FINAL_ENUM_TRADE_CONDITION_ENTRY }; // Defines enumeration for trade parameters. diff --git a/Trade.mqh b/Trade.mqh index 0446da64b..e25ec3a37 100644 --- a/Trade.mqh +++ b/Trade.mqh @@ -36,6 +36,7 @@ class Trade; #include "Math/Math.h" #include "Platform/Order.h" #include "Platform/OrderQuery.h" +#include "Serializer/Serializer.ref.h" #include "Storage/Dict/DictStruct.h" #include "Storage/Object.h" #include "Task/TaskManager.h" diff --git a/tests/EA.test.cpp b/tests/EA.test.cpp index 5a93ec93c..da21c1384 100644 --- a/tests/EA.test.cpp +++ b/tests/EA.test.cpp @@ -26,10 +26,10 @@ // Includes. #include "../EA.mqh" + #include "../Platform/Platform.h" int main(int argc, char **argv) { // @todo - return 0; } diff --git a/tests/EATest.mq5 b/tests/EATest.mq5 index 23b0b731f..5c4b4adef 100644 --- a/tests/EATest.mq5 +++ b/tests/EATest.mq5 @@ -32,6 +32,8 @@ struct DataParamEntry; #include "../Exchange/Account/Account.struct.h" #include "../Test.mqh" +DictStruct> _trades_test; + // Defines EA classes. class EA1 : public EA { public: @@ -57,6 +59,9 @@ EA3 *ea3; * Implements OnInit(). */ int OnInit() { + Platform::Init(); + Platform::SetSymbolTfForTesting("EURUSD", PERIOD_M1); + // Task to export to all possible formats once per hour. TaskEntry _task_export_per_hour(EA_ACTION_EXPORT_DATA, EA_COND_ON_NEW_HOUR);