| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902 |
- //+------------------------------------------------------------------+
- //| MetaTrader 5 API |
- //| Copyright 2000-2019, MetaQuotes Software Corp. |
- //| http://www.metaquotes.net |
- //+------------------------------------------------------------------+
- #pragma once
- #include <time.h>
- #include "MT5APIStr.h"
- #include "MT5APIMath.h"
- #include "MT5APITime.h"
- #include "..\Bases\MT5APITick.h"
- #include "..\Bases\MT5APIOrder.h"
- #include "..\Bases\MT5APIDeal.h"
- #include "..\Bases\MT5APIPosition.h"
- //+------------------------------------------------------------------+
- //| Format strings |
- //+------------------------------------------------------------------+
- class SMTFormat
- {
- private:
- //--- constants
- enum constants
- {
- SIG_DECIMAL =L'.',
- SIG_NEGATIVE =L'-',
- SIG_THOUSAND =L' ',
- VOLUME_K =L'K',
- VOLUME_M =L'M',
- };
- public:
- //--- error
- static LPCWSTR FormatError(const MTAPIRES retcode);
- //--- double to string
- static LPCWSTR FormatDouble(CMTStr &str,double val,UINT digits);
- static LPCWSTR FormatMoney(CMTStr &str,double val,UINT digits);
- //--- price to string
- static LPCWSTR FormatPrice(CMTStr &str,double val,UINT digits,UINT extra_digits=0);
- static LPCWSTR FormatPrices(CMTStr &str,MTTickShort& tick,const UINT digits);
- //--- volume & size
- static LPCWSTR FormatVolumeDouble(CMTStr &str,const double volume,const bool compact);
- static LPCWSTR FormatVolume(CMTStr &str,const UINT64 volume,const bool compact=true);
- static LPCWSTR FormatVolumeExt(CMTStr &str,const UINT64 volume,const bool compact=true);
- static LPCWSTR FormatVolumeOrder(CMTStr &str,const UINT64 volume_initial,const UINT64 volume_current);
- static LPCWSTR FormatVolumeExtOrder(CMTStr &str,const UINT64 volume_initial,const UINT64 volume_current);
- static LPCWSTR FormatSize(CMTStr &str,const double size,const bool compact=true);
- static LPCWSTR FormatSizeOrder(CMTStr &str,const double size_initial,const double size_current);
- //--- date & time
- static LPCWSTR FormatDateTime(CMTStr &str,const SYSTEMTIME &st,bool useTime=true,bool useSec=false);
- static LPCWSTR FormatDateTime(CMTStr &str,INT64 ctm,bool useTime=true,bool useSec=false);
- static LPCWSTR FormatDateTimeMsc(CMTStr &str,const SYSTEMTIME &st,bool useTime=true,bool useSec=false);
- static LPCWSTR FormatDateTimeMsc(CMTStr &str,INT64 ctm,bool useTime=true,bool useSec=false);
- static LPCWSTR FormatTime(CMTStr &str,INT64 ctm,bool useSec=false);
- static LPCWSTR FormatTimeMsc(CMTStr &str,INT64 ctm,bool useSec=false);
- //--- IP & port
- static LPCWSTR FormatIP(CMTStr &str,const UINT ip,const UINT port=0);
- static LPCWSTR FormatIP(CMTStr &str,const USHORT* ip,const UINT port=0);
- //--- positions
- static LPCWSTR FormatPositionType(CMTStr &str,const UINT type);
- //--- orders
- static LPCWSTR FormatOrderType(CMTStr &str,const UINT type);
- static LPCWSTR FormatOrderStatus(CMTStr &str,const UINT status);
- static LPCWSTR FormatOrderTypeFilling(CMTStr &str,const UINT type);
- static LPCWSTR FormatOrderTypeTime(CMTStr &str,const UINT type);
- static LPCWSTR FormatOrderTypeReason(CMTStr &str,UINT reason);
- static LPCWSTR FormatOrderPrice(CMTStr &str,const double price_order,const double price_trigger,const UINT digits);
- //--- deals
- static LPCWSTR FormatDealAction(CMTStr &str,const UINT action);
- static LPCWSTR FormatDealEntry(CMTStr &str,const UINT entry);
- //---
- static LPCWSTR FormatModifyFlags(CMTStr &str,const UINT modify_flags);
- private:
- //--- UINT64 to string
- static LPCWSTR FormatDouble(CMTStr &str,UINT64 val,UINT digits);
- static LPCWSTR FormatDoubleBrief(CMTStr &str,UINT64 val,UINT digits);
- static LPCWSTR FormatMoney(CMTStr &str,UINT64 val,UINT digits);
- //--- trim zero
- static void TrimZeros(CMTStr &str,UINT extra_digits=UINT_MAX);
- };
- //+------------------------------------------------------------------+
- //| Retcode description |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatError(const MTAPIRES retcode)
- {
- //--- error description
- struct ErrorDesc
- {
- MTAPIRES code;
- LPCWSTR desc;
- };
- //--- errors
- static ErrorDesc errors[]=
- {
- { MT_RET_OK, L"Done" },
- { MT_RET_OK_NONE, L"OK/None" },
- { MT_RET_ERROR, L"Common error" },
- { MT_RET_ERR_PARAMS, L"Invalid parameters" },
- { MT_RET_ERR_DATA, L"Invalid data" },
- { MT_RET_ERR_DISK, L"Disk error" },
- { MT_RET_ERR_MEM, L"Memory error" },
- { MT_RET_ERR_NETWORK, L"Network error" },
- { MT_RET_ERR_PERMISSIONS, L"Not enough permissions" },
- { MT_RET_ERR_TIMEOUT, L"Operation timeout" },
- { MT_RET_ERR_CONNECTION, L"No connection" },
- { MT_RET_ERR_NOSERVICE, L"Service is not available" },
- { MT_RET_ERR_FREQUENT, L"Too frequent requests" },
- { MT_RET_ERR_NOTFOUND, L"Not found" },
- { MT_RET_ERR_SHUTDOWN, L"Server shutdown in progress" },
- { MT_RET_ERR_CANCEL, L"Operation was canceled" },
- { MT_RET_ERR_DUPLICATE, L"Duplicate attempt" },
- //--- auth errors
- { MT_RET_AUTH_CLIENT_INVALID, L"Invalid terminal type" },
- { MT_RET_AUTH_ACCOUNT_INVALID, L"Invalid account" },
- { MT_RET_AUTH_ACCOUNT_DISABLED, L"Account disabled" },
- { MT_RET_AUTH_ADVANCED, L"Advanced authorization" },
- { MT_RET_AUTH_CERTIFICATE, L"Certificate required" },
- { MT_RET_AUTH_CERTIFICATE_BAD, L"Invalid certificate" },
- { MT_RET_AUTH_NOTCONFIRMED, L"Certificate is not confirmed" },
- { MT_RET_AUTH_SERVER_INTERNAL, L"Attempt to connect to non-access server" },
- { MT_RET_AUTH_SERVER_BAD, L"Invalid or fake server" },
- { MT_RET_AUTH_UPDATE_ONLY, L"Only updates available" },
- { MT_RET_AUTH_CLIENT_OLD, L"Old version" },
- { MT_RET_AUTH_MANAGER_NOCONFIG, L"Account doesn't have manager config" },
- { MT_RET_AUTH_MANAGER_IPBLOCK, L"IP address unallowed for manager" },
- { MT_RET_AUTH_GROUP_INVALID, L"Group is not initialized, server restart needed" },
- { MT_RET_AUTH_CA_DISABLED, L"Certificate generation disabled" },
- { MT_RET_AUTH_INVALID_ID, L"Invalid or disabled server id [check server id]"},
- { MT_RET_AUTH_INVALID_IP, L"Unallowed address [check server ip address]" },
- { MT_RET_AUTH_INVALID_TYPE, L"Invalid server type [check server id and type]" },
- { MT_RET_AUTH_SERVER_BUSY, L"Server is busy" },
- { MT_RET_AUTH_SERVER_CERT, L"Invalid server certificate or invalid local time" },
- { MT_RET_AUTH_ACCOUNT_UNKNOWN, L"Unknown account" },
- { MT_RET_AUTH_SERVER_OLD, L"Old server version" },
- { MT_RET_AUTH_SERVER_LIMIT, L"Server cannot be connected due to license limitation" },
- { MT_RET_AUTH_MOBILE_DISABLED, L"Mobile terminal isn't allowed in license" },
- { MT_RET_AUTH_MANAGER_TYPE, L"Connection type is not permitted for manager" },
- { MT_RET_AUTH_DEMO_DISABLED, L"Demo allocation disabled" },
- { MT_RET_AUTH_RESET_PASSWORD, L"Master password must be changed" },
- //--- config errors
- { MT_RET_CFG_LAST_ADMIN, L"Last admin config cannot be deleted" },
- { MT_RET_CFG_LAST_ADMIN_GROUP, L"Last admin group cannot be deleted" },
- { MT_RET_CFG_NOT_EMPTY, L"Accounts or trades in group/symbol" },
- { MT_RET_CFG_INVALID_RANGE, L"Invalid account or trade ranges"},
- { MT_RET_CFG_NOT_MANAGER_LOGIN, L"Account doesn't belong to manager group"},
- { MT_RET_CFG_BUILTIN, L"Built-in protected config" },
- { MT_RET_CFG_DUPLICATE, L"Configuration duplicate" },
- { MT_RET_CFG_LIMIT_REACHED, L"Configuration limit reached" },
- { MT_RET_CFG_NO_ACCESS_TO_MAIN, L"Invalid network configuration" },
- { MT_RET_CFG_DEALER_ID_EXIST, L"Dealer with same ID already exists" },
- { MT_RET_CFG_BIND_ADDR_EXIST, L"Binding address already exists" },
- { MT_RET_CFG_WORKING_TRADE, L"Attempt to delete working trade server" },
- { MT_RET_CFG_GATEWAY_NAME_EXIST,L"Gateway with same name already exists" },
- { MT_RET_CFG_SWITCH_TO_BACKUP, L"Server must be switched to backup mode" },
- { MT_RET_CFG_NO_BACKUP_MODULE, L"Backup server module is absent" },
- { MT_RET_CFG_NO_TRADE_MODULE, L"Trade server module is absent" },
- { MT_RET_CFG_NO_HISTORY_MODULE, L"History server module is absent" },
- { MT_RET_CFG_ANOTHER_SWITCH, L"Another switching process in progress" },
- { MT_RET_CFG_NO_LICENSE_FILE, L"License file is absent" },
- { MT_RET_CFG_GATEWAY_LOGIN_EXIST,L"Gateway with same login already exist" },
- //--- client errors
- { MT_RET_USR_LAST_ADMIN, L"Last admin account cannot be deleted" },
- { MT_RET_USR_LOGIN_EXHAUSTED, L"Login range exhausted" },
- { MT_RET_USR_LOGIN_PROHIBITED, L"Login reserved at another server" },
- { MT_RET_USR_LOGIN_EXIST, L"Account already exists" },
- { MT_RET_USR_SUICIDE, L"Attempt of self-deletion" },
- { MT_RET_USR_INVALID_PASSWORD, L"Invalid account password" },
- { MT_RET_USR_LIMIT_REACHED, L"User limit reached" },
- { MT_RET_USR_HAS_TRADES, L"Account has open trades" },
- { MT_RET_USR_DIFFERENT_SERVERS, L"Attempt to move account to different server" },
- { MT_RET_USR_DIFFERENT_CURRENCY,L"Attempt to move account to group with different currency" },
- { MT_RET_USR_IMPORT_BALANCE, L"Account balance import error" },
- { MT_RET_USR_IMPORT_GROUP, L"Imported account has invalid group"},
- { MT_RET_USR_ACCOUNT_EXIST, L"Account already exist" },
- //--- trade errors
- { MT_RET_TRADE_LIMIT_REACHED, L"Order or deal limit reached" },
- { MT_RET_TRADE_ORDER_EXIST, L"Order already exists" },
- { MT_RET_TRADE_ORDER_EXHAUSTED, L"Order range exhausted" },
- { MT_RET_TRADE_DEAL_EXHAUSTED, L"Deal range exhausted" },
- { MT_RET_TRADE_MAX_MONEY, L"Money limit reached" },
- { MT_RET_TRADE_DEAL_EXIST, L"Deal already exists" },
- { MT_RET_TRADE_ORDER_PROHIBITED,L"Order ticket reserved at another server" },
- { MT_RET_TRADE_DEAL_PROHIBITED, L"Deal ticket reserved at another server" },
- //--- report errors
- { MT_RET_REPORT_SNAPSHOT, L"Base snapshot error" },
- { MT_RET_REPORT_NOTSUPPORTED, L"Method is not supported by this report" },
- { MT_RET_REPORT_NODATA, L"No data for report" },
- { MT_RET_REPORT_TEMPLATE_BAD, L"Bad template" },
- { MT_RET_REPORT_TEMPLATE_END, L"End of template" },
- { MT_RET_REPORT_INVALID_ROW, L"Invalid row size" },
- { MT_RET_REPORT_LIMIT_REPEAT, L"Tag repeat limit reached " },
- { MT_RET_REPORT_LIMIT_REPORT, L"Report size limit reached" },
- //--- history errors
- { MT_RET_HST_SYMBOL_NOTFOUND, L"Symbol not found, try to restart history server" },
- //--- request errors
- { MT_RET_REQUEST_INWAY, L"Request on the way" },
- { MT_RET_REQUEST_ACCEPTED, L"Request accepted" },
- { MT_RET_REQUEST_PROCESS, L"Request processed" },
- { MT_RET_REQUEST_REQUOTE, L"Requote" },
- { MT_RET_REQUEST_PRICES, L"Prices" },
- { MT_RET_REQUEST_REJECT, L"Request rejected" },
- { MT_RET_REQUEST_CANCEL, L"Request canceled" },
- { MT_RET_REQUEST_PLACED, L"Order placed" },
- { MT_RET_REQUEST_DONE, L"Request executed" },
- { MT_RET_REQUEST_DONE_PARTIAL, L"Request executed partially" },
- { MT_RET_REQUEST_ERROR, L"Request error" },
- { MT_RET_REQUEST_TIMEOUT, L"Request timeout" },
- { MT_RET_REQUEST_INVALID, L"Invalid request" },
- { MT_RET_REQUEST_INVALID_VOLUME,L"Invalid volume" },
- { MT_RET_REQUEST_INVALID_PRICE, L"Invalid price" },
- { MT_RET_REQUEST_INVALID_STOPS, L"Invalid stops" },
- { MT_RET_REQUEST_TRADE_DISABLED,L"Trade disabled" },
- { MT_RET_REQUEST_MARKET_CLOSED, L"Market closed" },
- { MT_RET_REQUEST_NO_MONEY, L"No money" },
- { MT_RET_REQUEST_PRICE_CHANGED, L"Price changed" },
- { MT_RET_REQUEST_PRICE_OFF, L"No prices" },
- { MT_RET_REQUEST_INVALID_EXP, L"Invalid expiration" },
- { MT_RET_REQUEST_ORDER_CHANGED, L"Order has been changed already" },
- { MT_RET_REQUEST_TOO_MANY, L"Too many trade requests" },
- { MT_RET_REQUEST_AT_DISABLED_SERVER, L"AutoTrading disabled by server" },
- { MT_RET_REQUEST_AT_DISABLED_CLIENT, L"AutoTrading disabled by client" },
- { MT_RET_REQUEST_LOCKED, L"Order locked by dealer" },
- { MT_RET_REQUEST_FROZEN, L"Modification failed due to order or position being close to market" },
- { MT_RET_REQUEST_INVALID_FILL, L"Unsupported filling mode" },
- { MT_RET_REQUEST_RETURN, L"Request returned in queue" },
- { MT_RET_REQUEST_DONE_CANCEL, L"Request executed partially" },
- { MT_RET_REQUEST_ONLY_REAL, L"Allowed for real accounts only" },
- { MT_RET_REQUEST_LIMIT_ORDERS, L"Order limit reached" },
- { MT_RET_REQUEST_LIMIT_VOLUME, L"Volume limit reached" },
- { MT_RET_REQUEST_POSITION_CLOSED, L"Position already closed" },
- { MT_RET_REQUEST_EXECUTION_SKIPPED, L"Execution doesn't belong to this server" },
- { MT_RET_REQUEST_INVALID_CLOSE_VOLUME, L"Volume to be closed exceeds the position volume" },
- { MT_RET_REQUEST_CLOSE_ORDER_EXIST, L"Order to close this position already exists" },
- { MT_RET_REQUEST_REQUOTE_RETURN, L"Requote" },
- { MT_RET_REQUEST_LIMIT_POSITIONS, L"Position limit reached" },
- { MT_RET_REQUEST_REJECT_CANCEL, L"Request rejected, order will be canceled"},
- { MT_RET_REQUEST_LONG_ONLY, L"Only long positions are allowed" },
- { MT_RET_REQUEST_SHORT_ONLY, L"Only short positions are allowed" },
- { MT_RET_REQUEST_CLOSE_ONLY, L"Only position closing is allowed" },
- //--- API retcodes
- { MT_RET_ERR_NOTIMPLEMENT, L"Not implemented" },
- { MT_RET_ERR_NOTMAIN, L"Operation must be performed on main server"},
- { MT_RET_ERR_NOTSUPPORTED, L"Command doesn't supported" },
- { MT_RET_ERR_DEADLOCK, L"Operation canceled due possible deadlock" },
- { MT_RET_ERR_LOCKED, L"Operation on locked entity" },
- //--- default
- { INT_MAX, L"Network problem" },
- };
- //--- search description
- for(UINT i=0;i<_countof(errors);i++)
- if(errors[i].code==retcode) return(errors[i].desc);
- //--- default value
- return(L"Unknown error");
- }
- //+------------------------------------------------------------------+
- //| Format double value |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatDouble(CMTStr &str,double val,UINT digits)
- {
- double valdec;
- UINT digits_int=(digits<10)?digits:10;
- //--- convert to integer
- valdec=val*SMTMath::DecPow((int)digits_int);
- //--- check size
- if(valdec>=double(_I64_MAX/100i64) || valdec<=double(_I64_MIN/100i64))
- {
- CMTStr32 fmt;
- int pos;
- //--- format using CRT
- fmt.Format(L"%%.0%ulf",digits_int);
- str.Format(fmt.Str(),val);
- //--- decimal point
- pos=str.FindRChar(L'.');
- if(pos>=0) str.Buffer()[pos]=SIG_DECIMAL;
- //---
- return(str.Str());
- }
- //--- format fast
- if(val>=0)
- FormatDouble(str,UINT64(valdec+0.5),digits_int);
- else
- {
- FormatDouble(str,UINT64(0.5-valdec),digits_int);
- str.Insert(0,SIG_NEGATIVE);
- }
- //---
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format money |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatMoney(CMTStr &str,double val,UINT digits)
- {
- double valdec;
- //--- convert to integer
- valdec=val*SMTMath::DecPow((int)digits);
- //--- check size
- if(valdec>=double(_I64_MAX/100i64) || valdec<=double(_I64_MIN/100i64))
- {
- CMTStr32 fmt;
- int pos;
- //--- format using CRT
- fmt.Format(L"%%.0%ulf",digits);
- str.Format(fmt.Str(),val);
- //--- decimal point
- pos=str.FindRChar(L'.');
- if(pos>=0) str.Buffer()[pos]=SIG_DECIMAL;
- //--- insert thousands delimeters
- for(pos=str.FindRChar(L'.')-3;pos>=3;pos-=3)
- str.Insert((UINT)pos,SIG_THOUSAND);
- //---
- return(str.Str());
- }
- //--- format fast
- if(val>=0)
- FormatMoney(str,UINT64(valdec+0.5),digits);
- else
- {
- FormatMoney(str,UINT64(0.5-valdec),digits);
- str.Insert(0,SIG_NEGATIVE);
- }
- //---
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format price |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatPrice(CMTStr &str,double val,UINT digits,UINT extra_digits)
- {
- //--- format with extra digits
- FormatDouble(str,val,digits+extra_digits);
- //--- trim zero
- TrimZeros(str,extra_digits);
- //--- return
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Current prices |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatPrices(CMTStr &str,MTTickShort& tick,const UINT digits)
- {
- CMTStr32 sbid,sask,slast;
- //--- check last prices
- if(!tick.last) str.Format(L"%s / %s" ,FormatPrice(sbid,tick.bid,digits),FormatPrice(sask,tick.ask,digits));
- else str.Format(L"%s / %s / %s",FormatPrice(sbid,tick.bid,digits),FormatPrice(sask,tick.ask,digits),FormatPrice(slast,tick.last,digits));
- //--- return
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format trade volume |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatVolumeDouble(CMTStr &str,const double volume,const bool compact/*=true*/)
- {
- //--- check M
- if(compact && volume>1000000.0)
- {
- //---
- str.Format(L"%.8lf",volume/1000000.0);
- TrimZeros(str,8);
- str.Append(VOLUME_M);
- //---
- return(str.Str());
- }
- //--- check K
- if(compact && volume>1000.0)
- {
- //---
- str.Format(L"%.5lf",volume/1000.0);
- TrimZeros(str,5);
- str.Append(VOLUME_K);
- //---
- return(str.Str());
- }
- //--- normal method
- FormatDouble(str,volume,MTAPI_VOLUME_EXT_DIGITS);
- TrimZeros(str,6);
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format trade volume |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatVolume(CMTStr &str,const UINT64 volume,const bool compact/*=true*/)
- {
- return(FormatVolumeDouble(str,SMTMath::VolumeToDouble(volume),compact));
- }
- //+------------------------------------------------------------------+
- //| Format trade volume |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatVolumeExt(CMTStr &str,const UINT64 volume,const bool compact/*=true*/)
- {
- return(FormatVolumeDouble(str,SMTMath::VolumeExtToDouble(volume),compact));
- }
- //+------------------------------------------------------------------+
- //| Format order volume |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatVolumeOrder(CMTStr &str,const UINT64 volume_initial,const UINT64 volume_current)
- {
- CMTStr64 vol_filled,vol_init;
- //---
- str.Format(L"%s / %s",FormatVolume(vol_init,volume_initial),
- FormatVolume(vol_filled,volume_initial-volume_current));
- //--- summary
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format order volume |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatVolumeExtOrder(CMTStr &str,const UINT64 volume_initial,const UINT64 volume_current)
- {
- CMTStr64 vol_filled,vol_init;
- //---
- str.Format(L"%s / %s",FormatVolumeExt(vol_init,volume_initial),
- FormatVolumeExt(vol_filled,volume_initial-volume_current));
- //--- summary
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format trade amount |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatSize(CMTStr &str,const double volume,const bool compact/*=true*/)
- {
- return(FormatVolumeDouble(str,volume,compact));
- }
- //+------------------------------------------------------------------+
- //| Format order amount |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatSizeOrder(CMTStr &str,const double size_initial,const double size_current)
- {
- CMTStr64 sz_filled,sz_current;
- //---
- str.Format(L"%s / %s",FormatSize(sz_filled,size_initial),
- FormatSize(sz_current,size_initial-size_current));
- //---
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format date & time |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatDateTime(CMTStr &str,const SYSTEMTIME &st,bool useTime/*=true*/,bool useSec/*=false*/)
- {
- //---
- if(useTime)
- {
- if(useSec)
- str.Format(L"%04d.%02d.%02d %02d:%02d:%02d",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
- else
- str.Format(L"%04d.%02d.%02d %02d:%02d",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute);
- }
- else str.Format(L"%04d.%02d.%02d",st.wYear,st.wMonth,st.wDay);
- //---
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format date & time |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatDateTime(CMTStr &str,INT64 ctm,bool useTime/*=true*/,bool useSec/*=false*/)
- {
- tm ttm={};
- //---
- if(!SMTTime::ParseTime(ctm,&ttm)) return(str.Str());
- //---
- if(useTime)
- {
- if(useSec)
- str.Format(L"%04d.%02d.%02d %02d:%02d:%02d",ttm.tm_year+1900,ttm.tm_mon+1,ttm.tm_mday,ttm.tm_hour,ttm.tm_min,ttm.tm_sec);
- else
- str.Format(L"%04d.%02d.%02d %02d:%02d",ttm.tm_year+1900,ttm.tm_mon+1,ttm.tm_mday,ttm.tm_hour,ttm.tm_min);
- }
- else str.Format(L"%04d.%02d.%02d",ttm.tm_year+1900,ttm.tm_mon+1,ttm.tm_mday);
- //---
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format date & time |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatDateTimeMsc(CMTStr &str,const SYSTEMTIME &st,bool useTime/*=true*/,bool useSec/*=false*/)
- {
- //---
- if(useTime)
- {
- if(useSec)
- str.Format(L"%04d.%02d.%02d %02d:%02d:%02d.%03u",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond,st.wMilliseconds);
- else
- str.Format(L"%04d.%02d.%02d %02d:%02d",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute);
- }
- else str.Format(L"%04d.%02d.%02d",st.wYear,st.wMonth,st.wDay);
- //---
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format date & time |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatDateTimeMsc(CMTStr &str,INT64 ctm,bool useTime/*=true*/,bool useSec/*=false*/)
- {
- tm ttm={};
- //---
- if(!SMTTime::ParseTime(ctm/1000,&ttm))
- return(str.Str());
- //---
- if(useTime)
- {
- if(useSec)
- str.Format(L"%04d.%02d.%02d %02d:%02d:%02d.%03d",ttm.tm_year+1900,ttm.tm_mon+1,ttm.tm_mday,ttm.tm_hour,ttm.tm_min,ttm.tm_sec,(int)(ctm%1000));
- else
- str.Format(L"%04d.%02d.%02d %02d:%02d",ttm.tm_year+1900,ttm.tm_mon+1,ttm.tm_mday,ttm.tm_hour,ttm.tm_min);
- }
- else str.Format(L"%04d.%02d.%02d",ttm.tm_year+1900,ttm.tm_mon+1,ttm.tm_mday);
- //---
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format time |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatTime(CMTStr &str,INT64 ctm,bool useSec/*=false*/)
- {
- tm ttm={};
- //---
- if(!SMTTime::ParseTime(ctm,&ttm))
- return(str.Str());
- //---
- if(useSec) str.Format(L"%02d:%02d:%02d",ttm.tm_hour,ttm.tm_min,ttm.tm_sec);
- else str.Format(L"%02d:%02d",ttm.tm_hour,ttm.tm_min);
- //---
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format time |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatTimeMsc(CMTStr &str,INT64 ctm,bool useSec/*=false*/)
- {
- tm ttm={};
- //---
- if(!SMTTime::ParseTime(ctm/1000,&ttm))
- return(str.Str());
- //---
- if(useSec) str.Format(L"%02d:%02d:%02d.%03d",ttm.tm_hour,ttm.tm_min,ttm.tm_sec,(int)(ctm%1000));
- else str.Format(L"%02d:%02d",ttm.tm_hour,ttm.tm_min);
- //---
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format IP[:port] |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatIP(CMTStr &str,const UINT ip,const UINT port/*=0*/)
- {
- if(port>0) str.Format(L"%d.%d.%d.%d:%u",ip&255,(ip>>8)&255,(ip>>16)&255,(ip>>24)&255,port);
- else str.Format(L"%d.%d.%d.%d", ip&255,(ip>>8)&255,(ip>>16)&255,(ip>>24)&255);
- //---
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Format IP[:port] |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatIP(CMTStr &str,const USHORT *ip,const UINT port/*=0*/)
- {
- if(ip)
- {
- if(port>0)
- str.Format(L"[%04x:04x:04x:04x:04x:04x:04x:04x]:%u",
- ip[0],ip[1],ip[2],ip[3],ip[4],ip[5],ip[6],ip[7],port);
- else
- str.Format(L"[%04x:04x:04x:04x:04x:04x:04x:04x]",
- ip[0],ip[1],ip[2],ip[3],ip[4],ip[5],ip[6],ip[7]);
- }
- //---
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Position type |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatPositionType(CMTStr &str,const UINT type)
- {
- //--- clear
- str.Clear();
- //--- check type
- switch(type)
- {
- case IMTPosition::POSITION_BUY : str.Assign(L"buy"); break;
- case IMTPosition::POSITION_SELL : str.Assign(L"sell"); break;
- }
- //--- return
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Order type |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatOrderType(CMTStr &str,const UINT type)
- {
- //--- clear
- str.Clear();
- //--- check type
- switch(type)
- {
- case IMTOrder::OP_BUY : str.Assign(L"buy"); break;
- case IMTOrder::OP_SELL : str.Assign(L"sell"); break;
- case IMTOrder::OP_BUY_LIMIT : str.Assign(L"buy limit"); break;
- case IMTOrder::OP_SELL_LIMIT : str.Assign(L"sell limit"); break;
- case IMTOrder::OP_BUY_STOP : str.Assign(L"buy stop"); break;
- case IMTOrder::OP_SELL_STOP : str.Assign(L"sell stop"); break;
- case IMTOrder::OP_BUY_STOP_LIMIT : str.Assign(L"buy stop limit"); break;
- case IMTOrder::OP_SELL_STOP_LIMIT: str.Assign(L"sell stop limit"); break;
- }
- //--- return
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Order status |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatOrderStatus(CMTStr &str,const UINT status)
- {
- //--- clear
- str.Clear();
- //--- check type
- switch(status)
- {
- case IMTOrder::ORDER_STATE_STARTED : str.Assign(L"started"); break;
- case IMTOrder::ORDER_STATE_PLACED : str.Assign(L"placed"); break;
- case IMTOrder::ORDER_STATE_CANCELED: str.Assign(L"canceled"); break;
- case IMTOrder::ORDER_STATE_PARTIAL : str.Assign(L"partial"); break;
- case IMTOrder::ORDER_STATE_FILLED : str.Assign(L"filled"); break;
- case IMTOrder::ORDER_STATE_REJECTED: str.Assign(L"rejected"); break;
- case IMTOrder::ORDER_STATE_EXPIRED : str.Assign(L"expired"); break;
- case IMTOrder::ORDER_STATE_REQUEST_ADD : str.Assign(L"request adding"); break;
- case IMTOrder::ORDER_STATE_REQUEST_MODIFY: str.Assign(L"request modification"); break;
- case IMTOrder::ORDER_STATE_REQUEST_CANCEL: str.Assign(L"request cancelling"); break;
- }
- //--- return
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Order filling type |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatOrderTypeFilling(CMTStr &str,const UINT type)
- {
- //--- clear
- str.Clear();
- //--- check type
- switch(type)
- {
- case IMTOrder::ORDER_FILL_FOK : str.Assign(L"fill or kill"); break;
- case IMTOrder::ORDER_FILL_IOC : str.Assign(L"immediate or cancel"); break;
- case IMTOrder::ORDER_FILL_RETURN: str.Assign(L"return"); break;
- }
- //--- return
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Order expiration type |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatOrderTypeTime(CMTStr &str,const UINT type)
- {
- //--- clear
- str.Clear();
- //--- check type
- switch(type)
- {
- case IMTOrder::ORDER_TIME_GTC : str.Assign(L"gtc"); break;
- case IMTOrder::ORDER_TIME_DAY : str.Assign(L"day"); break;
- case IMTOrder::ORDER_TIME_SPECIFIED: str.Assign(L"specified"); break;
- }
- //--- return
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Order reason |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatOrderTypeReason(CMTStr &str,UINT reason)
- {
- //--- clear
- str.Clear();
- //--- check type
- switch(reason)
- {
- case IMTOrder::ORDER_REASON_CLIENT : str.Assign(L"Client"); break;
- case IMTOrder::ORDER_REASON_EXPERT : str.Assign(L"Expert"); break;
- case IMTOrder::ORDER_REASON_DEALER : str.Assign(L"Dealer"); break;
- case IMTOrder::ORDER_REASON_SL : str.Assign(L"Stop loss"); break;
- case IMTOrder::ORDER_REASON_TP : str.Assign(L"Take profit"); break;
- case IMTOrder::ORDER_REASON_SO : str.Assign(L"Stop out"); break;
- case IMTOrder::ORDER_REASON_ROLLOVER : str.Assign(L"Rollover"); break;
- case IMTOrder::ORDER_REASON_EXTERNAL_CLIENT : str.Assign(L"External Client"); break;
- case IMTOrder::ORDER_REASON_VMARGIN : str.Assign(L"Variation margin"); break;
- case IMTOrder::ORDER_REASON_GATEWAY : str.Assign(L"Gateway"); break;
- case IMTOrder::ORDER_REASON_SIGNAL : str.Assign(L"Signal"); break;
- case IMTOrder::ORDER_REASON_SETTLEMENT : str.Assign(L"Settlement"); break;
- case IMTOrder::ORDER_REASON_TRANSFER : str.Assign(L"Transfer"); break;
- case IMTOrder::ORDER_REASON_SYNC : str.Assign(L"Synchronization"); break;
- case IMTOrder::ORDER_REASON_EXTERNAL_SERVICE : str.Assign(L"External Service"); break;
- case IMTOrder::ORDER_REASON_MIGRATION : str.Assign(L"Migration"); break;
- case IMTOrder::ORDER_REASON_MOBILE : str.Assign(L"Mobile"); break;
- case IMTOrder::ORDER_REASON_WEB : str.Assign(L"Web"); break;
- case IMTOrder::ORDER_REASON_SPLIT : str.Assign(L"Split"); break;
- }
- //--- return
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Order price |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatOrderPrice(CMTStr &str,const double price_order,const double price_trigger,const UINT digits)
- {
- CMTStr64 price,trigger;
- //--- clear
- str.Clear();
- //--- check trigger price
- if(price_trigger)
- {
- FormatPrice(price,price_order,digits);
- FormatPrice(trigger,price_trigger,digits);
- str.Format(L"%s (%s)",price.Str(),trigger.Str());
- }
- else
- {
- if(price_order!=0) FormatPrice(str,price_order,digits);
- else str.Assign(L"market");
- }
- //--- return
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Deal action |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatDealAction(CMTStr &str,const UINT action)
- {
- //--- clear
- str.Clear();
- //--- check type
- switch(action)
- {
- case IMTDeal::DEAL_BUY : str.Assign(L"buy"); break;
- case IMTDeal::DEAL_SELL : str.Assign(L"sell"); break;
- case IMTDeal::DEAL_BALANCE : str.Assign(L"balance"); break;
- case IMTDeal::DEAL_CREDIT : str.Assign(L"credit"); break;
- case IMTDeal::DEAL_CHARGE : str.Assign(L"charge"); break;
- case IMTDeal::DEAL_CORRECTION: str.Assign(L"correction"); break;
- case IMTDeal::DEAL_BONUS : str.Assign(L"bonus"); break;
- case IMTDeal::DEAL_COMMISSION: str.Assign(L"commission"); break;
- case IMTDeal::DEAL_COMMISSION_DAILY : str.Assign(L"daily commission"); break;
- case IMTDeal::DEAL_COMMISSION_MONTHLY: str.Assign(L"monthly commission"); break;
- case IMTDeal::DEAL_AGENT_DAILY : str.Assign(L"daily agent commission"); break;
- case IMTDeal::DEAL_AGENT_MONTHLY : str.Assign(L"monthly agent commission"); break;
- case IMTDeal::DEAL_INTERESTRATE : str.Assign(L"interest rate"); break;
- case IMTDeal::DEAL_BUY_CANCELED : str.Assign(L"canceled buy"); break;
- case IMTDeal::DEAL_SELL_CANCELED : str.Assign(L"canceled sell"); break;
- case IMTDeal::DEAL_DIVIDEND : str.Assign(L"dividend"); break;
- case IMTDeal::DEAL_DIVIDEND_FRANKED : str.Assign(L"franked dividend"); break;
- case IMTDeal::DEAL_TAX : str.Assign(L"tax"); break;
- case IMTDeal::DEAL_AGENT : str.Assign(L"agent commission"); break;
- case IMTDeal::DEAL_SO_COMPENSATION : str.Assign(L"so compensation"); break;
- }
- //--- return
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Deal direction |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatDealEntry(CMTStr &str,const UINT entry)
- {
- //--- clear
- str.Clear();
- //--- check type
- switch(entry)
- {
- case IMTDeal::ENTRY_IN : str.Assign(L"in"); break;
- case IMTDeal::ENTRY_OUT : str.Assign(L"out"); break;
- case IMTDeal::ENTRY_INOUT : str.Assign(L"in/out"); break;
- case IMTDeal::ENTRY_OUT_BY: str.Assign(L"out by"); break;
- }
- //--- return
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| Modify flags |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatModifyFlags(CMTStr &str,const UINT modify_flags)
- {
- //--- description
- static struct
- {
- UINT flag;
- LPCWSTR desc;
- } modify_flags_desc[]=
- {
- { IMTOrder::MODIFY_FLAGS_ADMIN, L"Administrator" },
- { IMTOrder::MODIFY_FLAGS_MANAGER, L"Manager" },
- { IMTOrder::MODIFY_FLAGS_POSITION, L"Position" },
- { IMTOrder::MODIFY_FLAGS_RESTORE, L"Restore" },
- { IMTOrder::MODIFY_FLAGS_API_ADMIN, L"Administrator API"},
- { IMTOrder::MODIFY_FLAGS_API_MANAGER, L"Manager API" },
- { IMTOrder::MODIFY_FLAGS_API_SERVER, L"Server API" },
- { IMTOrder::MODIFY_FLAGS_API_GATEWAY, L"Gateway API" }
- };
- //--- counter
- UINT added=0;
- //--- collect description
- str.Clear();
- for(UINT i=0;i<_countof(modify_flags_desc);i++)
- if(modify_flags_desc[i].flag&modify_flags)
- {
- //--- add comma
- if(added++)
- str.Append(L", ");
- //--- write
- str.Append(modify_flags_desc[i].desc);
- }
- //--- result
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatDouble(CMTStr &str,UINT64 val,UINT digits)
- {
- static const wchar_t cd[]={ L'0',L'1',L'2',L'3',L'4',L'5',L'6',L'7',L'8',L'9',0 };
- wchar_t tmp[256]=L"",*cp,*dst;
- UINT i,len;
- //---
- str.Clear();
- cp=tmp;
- //--- check
- if(digits>8) return(str.Str());
- //---
- if(digits>0)
- {
- for(i=0;i<digits;i++)
- {
- *cp++=cd[val%10];
- val/=10;
- }
- *cp++=SIG_DECIMAL;
- }
- //--- integer part
- *cp++=cd[val%10];
- for(val/=10,i=1;val!=0;val/=10,i++)
- *cp++=cd[val%10];
- *cp=0;
- //--- check size
- len=UINT(cp-tmp);
- if(len>=str.Max()-1) return(str.Str());
- //--- string reverse
- dst=str.Buffer(); cp=tmp+len-1;
- while(cp>=tmp) *dst++=*cp--;
- *dst=0;
- str.Refresh();
- //---
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| |
- //+------------------------------------------------------------------+
- inline LPCWSTR SMTFormat::FormatMoney(CMTStr &str,UINT64 val,UINT digits)
- {
- static const wchar_t cd[]={ L'0',L'1',L'2',L'3',L'4',L'5',L'6',L'7',L'8',L'9',0 };
- wchar_t tmp[256]=L"",*cp,*dst;
- UINT i,len;
- //---
- str.Clear();
- cp=tmp;
- //--- checks
- if(digits>8) return(str.Str());
- //---
- if(digits>0)
- {
- for(i=0;i<digits;i++)
- {
- *cp++=cd[val%10];
- val/=10;
- }
- *cp++=SIG_DECIMAL;
- }
- //--- integer part
- *cp++=cd[val%10];
- for(val/=10,i=1;val!=0;val/=10,i++)
- {
- if(i%3==0) *cp++=SIG_THOUSAND;
- *cp++=cd[val%10];
- }
- *cp=0;
- //--- check size
- len=UINT(cp-tmp);
- if(len>=str.Max()-1) return(str.Str());
- //--- reverse string
- dst=str.Buffer(); cp=tmp+len-1;
- while(cp>=tmp) *dst++=*cp--;
- *dst=0;
- str.Refresh();
- //---
- return(str.Str());
- }
- //+------------------------------------------------------------------+
- //| |
- //+------------------------------------------------------------------+
- inline void SMTFormat::TrimZeros(CMTStr &str,UINT extra_digits)
- {
- UINT len=str.Len(),digits=0;
- //--- remove zero
- while(len>0 && str[len-1]==L'0' && digits<extra_digits) { len--; digits++; }
- str.Trim(len);
- //--- remove points
- if(len>0 && str[len-1]==L'.') str.Trim(len-1);
- }
- //+------------------------------------------------------------------+
|