Article-16991-MQL5-Post-Fac.../SymbolTrade.mqh

439 lines
55 KiB
MQL5
Raw Permalink Normal View History

2026-03-24 13:45:14 +07:00
<EFBFBD><EFBFBD>//+------------------------------------------------------------------+
//| SymbolTrade.mqh |
//| Copyright 2024, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#define DIRECTORY "TradingByHistoryDeals"
#define FILE_NAME "HistoryDealsData.bin"
#define PATH DIRECTORY+"\\"+FILE_NAME
#include <Arrays\ArrayObj.mqh>
#include <Trade\Trade.mqh>
//+------------------------------------------------------------------+
//| !B@C:BC@0 A45;:8. A?>;L7C5BAO 4;O A>740=8O D09;0 8AB>@88 A45;>:|
//+------------------------------------------------------------------+
struct SDeal
{
ulong ticket; // "8:5B A45;:8
long order; // @45@, =0 >A=>20=88 :>B>@>3> 1K;0 >B:@KB0 A45;:0
long pos_id; // 45=B8D8:0B>@ ?>78F88
long time_msc; // @5<O 2 <8;;8A5:C=40E
datetime time; // @5<O
double volume; // 1JQ<
double price; // &5=0
double profit; // @81K;L
double commission; // ><8AA8O ?> A45;:5
double swap; // 0:>?;5==K9 A2>? ?@8 70:@KB88
double fee; // ?;0B0 70 ?@>2545=85 A45;:8, =0G8A;O5BAO A@07C ?>A;5 A>25@H5=8O A45;:8
double sl; // #@>25=L Stop Loss
double tp; // #@>25=L Take Profit
ENUM_DEAL_TYPE type; // "8?
ENUM_DEAL_ENTRY entry; // !?>A>1 87<5=5=8O ?>78F88
ENUM_DEAL_REASON reason; // @8G8=0 8;8 8AB>G=8: ?@>2545=8O A45;:8
long magic; // 45=B8D8:0B>@ M:A?5@B0
int digits; // Digits A8<2>;0
ushort symbol[16]; // !8<2>;
ushort comment[64]; // ><<5=B0@89 : A45;:5
ushort external_id[256]; // 45=B8D8:0B>@ A45;:8 2> 2=5H=59 B>@3>2>9 A8AB5<5 (=0 18@65)
//--- #AB0=>2:0 AB@>:>2KE A2>9AB2
bool SetSymbol(const string deal_symbol) { return(::StringToShortArray(deal_symbol, symbol)==deal_symbol.Length()); }
bool SetComment(const string deal_comment) { return(::StringToShortArray(deal_comment, comment)==deal_comment.Length()); }
bool SetExternalID(const string deal_external_id) { return(::StringToShortArray(deal_external_id, external_id)==deal_external_id.Length()); }
//--- >72@0B AB@>:>2KE A2>9AB2
string Symbol(void) { return(::ShortArrayToString(symbol)); }
string Comment(void) { return(::ShortArrayToString(comment)); }
string ExternalID(void) { return(::ShortArrayToString(external_id)); }
};
//--- "8?K A>@B8@>2:8 A45;>:
enum ENUM_DEAL_SORT_MODE
{
SORT_MODE_DEAL_TICKET = 0, // 568< A@02=5=8O/A>@B8@>2:8 ?> B8:5BC A45;:8
SORT_MODE_DEAL_ORDER, // 568< A@02=5=8O/A>@B8@>2:8 ?> >@45@C, =0 >A=>20=85 :>B>@>3> 2K?>;=5=0 A45;:0
SORT_MODE_DEAL_TIME, // 568< A@02=5=8O/A>@B8@>2:8 ?> 2@5<5=8 A>25@H5=8O A45;:8
SORT_MODE_DEAL_TIME_MSC, // 568< A@02=5=8O/A>@B8@>2:8 ?> 2@5<5=8 A>25@H5=8O A45;:8 2 <8;;8A5:C=40E
SORT_MODE_DEAL_TYPE, // 568< A@02=5=8O/A>@B8@>2:8 ?> B8?C A45;:8
SORT_MODE_DEAL_ENTRY, // 568< A@02=5=8O/A>@B8@>2:8 ?> =0?@02;5=8N A45;:8
SORT_MODE_DEAL_MAGIC, // 568< A@02=5=8O/A>@B8@>2:8 ?> Magic number A45;:8
SORT_MODE_DEAL_REASON, // 568< A@02=5=8O/A>@B8@>2:8 ?> ?@8G8=5 8;8 8AB>G=8:C ?@>2545=8O A45;:8
SORT_MODE_DEAL_POSITION_ID, // 568< A@02=5=8O/A>@B8@>2:8 ?> 845=B8D8:0B>@C ?>78F88
SORT_MODE_DEAL_VOLUME, // 568< A@02=5=8O/A>@B8@>2:8 ?> >1J5<C A45;:8
SORT_MODE_DEAL_PRICE, // 568< A@02=5=8O/A>@B8@>2:8 ?> F5=5 A45;:8
SORT_MODE_DEAL_COMMISSION, // 568< A@02=5=8O/A>@B8@>2:8 ?> :><8AA88
SORT_MODE_DEAL_SWAP, // 568< A@02=5=8O/A>@B8@>2:8 ?> =0:>?;5==><C A2>?C ?@8 70:@KB88
SORT_MODE_DEAL_PROFIT, // 568< A@02=5=8O/A>@B8@>2:8 ?> D8=0=A>2><C @57C;LB0BC A45;:8
SORT_MODE_DEAL_FEE, // 568< A@02=5=8O/A>@B8@>2:8 ?> >?;0B5 70 ?@>2545=85 A45;:8
SORT_MODE_DEAL_SL, // 568< A@02=5=8O/A>@B8@>2:8 ?> C@>2=N Stop Loss
SORT_MODE_DEAL_TP, // 568< A@02=5=8O/A>@B8@>2:8 ?> C@>2=N Take Profit
SORT_MODE_DEAL_SYMBOL, // 568< A@02=5=8O/A>@B8@>2:8 ?> 8<5=8 A8<2>;0, ?> :>B>@><C ?@>872545=0 A45;:0
SORT_MODE_DEAL_COMMENT, // 568< A@02=5=8O/A>@B8@>2:8 ?> :><<5=B0@8N : A45;:5
SORT_MODE_DEAL_EXTERNAL_ID, // 568< A@02=5=8O/A>@B8@>2:8 ?> 845=B8D8:0B>@C A45;:8 2> 2=5H=59 B>@3>2>9 A8AB5<5
SORT_MODE_DEAL_TICKET_TESTER, // 568< A@02=5=8O/A>@B8@>2:8 ?> B8:5BC A45;:8 2 B5AB5@5
SORT_MODE_DEAL_POS_ID_TESTER, // 568< A@02=5=8O/A>@B8@>2:8 ?> 845=B8D8:0B>@C ?>78F88 2 B5AB5@5
};
//+------------------------------------------------------------------+
//| ;0AA A45;:8. A?>;L7C5BAO 4;O B>@3>2;8 2 B5AB5@5 AB@0B5389 |
//+------------------------------------------------------------------+
class CDeal : public CObject
{
protected:
//--- &5;>G8A;5==K5 A2>9AB20
ulong m_ticket; // "8:5B A45;:8. #=8:0;L=>5 G8A;>, :>B>@>5 ?@8A208205BAO :064>9 A45;:5
long m_order; // @45@, =0 >A=>20=85 :>B>@>3> 2K?>;=5=0 A45;:0
datetime m_time; // @5<O A>25@H5=8O A45;:8
long m_time_msc; // @5<O A>25@H5=8O A45;:8 2 <8;;8A5:C=40E A 01.01.1970
ENUM_DEAL_TYPE m_type; // "8? A45;:8
ENUM_DEAL_ENTRY m_entry; // 0?@02;5=85 A45;:8  2E>4 2 @K=>:, 2KE>4 87 @K=:0 8;8 @072>@>B
long m_magic; // Magic number 4;O A45;:8 (A<>B@8 ORDER_MAGIC)
ENUM_DEAL_REASON m_reason; // @8G8=0 8;8 8AB>G=8: ?@>2545=8O A45;:8
long m_pos_id; // 45=B8D8:0B>@ ?>78F88, 2 >B:@KB88, 87<5=5=88 8;8 70:@KB88 :>B>@>9 CG0AB2>20;0 MB0 A45;:0
//--- 5I5AB25==K5 A2>9AB20
double m_volume; // 1J5< A45;:8
double m_price; // &5=0 A45;:8
double m_commission; // ><8AA8O ?> A45;:5
double m_swap; // 0:>?;5==K9 A2>? ?@8 70:@KB88
double m_profit; // $8=0=A>2K9 @57C;LB0B A45;:8
double m_fee; // ?;0B0 70 ?@>2545=85 A45;:8, =0G8A;O5BAO A@07C ?>A;5 A>25@H5=8O A45;:8
double m_sl; // #@>25=L Stop Loss
double m_tp; // #@>25=L Take Profit
//--- !B@>:>2K5 A2>9AB20
string m_symbol; // <O A8<2>;0, ?> :>B>@><C ?@>872545=0 A45;:0
string m_comment; // ><<5=B0@89 : A45;:5
string m_external_id; // 45=B8D8:0B>@ A45;:8 2> 2=5H=59 B>@3>2>9 A8AB5<5 (=0 18@65)
//--- >?>;=8B5;L=K5 A2>9AB20
int m_digits; // Digits A8<2>;0
double m_point; // Point A8<2>;0
ulong m_ticket_tester; // "8:5B ?>78F88 2 B5AB5@5
long m_pos_id_tester; // 45=B8D8:0B>@ ?>78F88 2 B5AB5@5
public:
//--- #AB0=>2:0 A2>9AB2 A45;:8
void SetTicket(const ulong ticket) { this.m_ticket=ticket; }
void SetOrder(const long order) { this.m_order=order; }
void SetTime(const datetime time) { this.m_time=time; }
void SetTimeMsc(const long value) { this.m_time_msc=value; }
void SetType(const ENUM_DEAL_TYPE type) { this.m_type=type; }
void SetEntry(const ENUM_DEAL_ENTRY entry) { this.m_entry=entry; }
void SetMagic(const long magic) { this.m_magic=magic; }
void SetReason(const ENUM_DEAL_REASON reason) { this.m_reason=reason; }
void SetPositionID(const long id) { this.m_pos_id=id; }
void SetVolume(const double volume) { this.m_volume=volume; }
void SetPrice(const double price) { this.m_price=price; }
void SetCommission(const double commission) { this.m_commission=commission; }
void SetSwap(const double swap) { this.m_swap=swap; }
void SetProfit(const double profit) { this.m_profit=profit; }
void SetFee(const double fee) { this.m_fee=fee; }
void SetSL(const double sl) { this.m_sl=sl; }
void SetTP(const double tp) { this.m_tp=tp; }
void SetSymbol(const string symbol) { this.m_symbol=symbol; }
void SetComment(const string comment) { this.m_comment=comment; }
void SetExternalID(const string ext_id) { this.m_external_id=ext_id; }
void SetTicketTester(const ulong ticket) { this.m_ticket_tester=ticket; }
void SetPosIDTester(const long pos_id) { this.m_pos_id_tester=pos_id; }
//--- >72@0B A2>9AB2 A45;:8
ulong Ticket(void) const { return this.m_ticket; }
long Order(void) const { return this.m_order; }
datetime Time(void) const { return this.m_time; }
long TimeMsc(void) const { return this.m_time_msc; }
ENUM_DEAL_TYPE TypeDeal(void) const { return this.m_type; }
ENUM_DEAL_ENTRY Entry(void) const { return this.m_entry; }
long Magic(void) const { return this.m_magic; }
ENUM_DEAL_REASON Reason(void) const { return this.m_reason; }
long PositionID(void) const { return this.m_pos_id; }
double Volume(void) const { return this.m_volume; }
double Price(void) const { return this.m_price; }
double Commission(void) const { return this.m_commission; }
double Swap(void) const { return this.m_swap; }
double Profit(void) const { return this.m_profit; }
double Fee(void) const { return this.m_fee; }
double SL(void) const { return this.m_sl; }
double TP(void) const { return this.m_tp; }
string Symbol(void) const { return this.m_symbol; }
string Comment(void) const { return this.m_comment; }
string ExternalID(void) const { return this.m_external_id; }
int Digits(void) const { return this.m_digits; }
double Point(void) const { return this.m_point; }
ulong TicketTester(void) const { return this.m_ticket_tester; }
long PosIDTester(void) const { return this.m_pos_id_tester; }
//--- !@02=8205B 420 >1J5:B0 <564C A>1>9 ?> C:070==><C 2 mode A2>9AB2C
virtual int Compare(const CObject *node, const int mode=0) const
{
const CDeal *obj=node;
switch(mode)
{
case SORT_MODE_DEAL_TICKET : return(this.Ticket() > obj.Ticket() ? 1 : this.Ticket() < obj.Ticket() ? -1 : 0);
case SORT_MODE_DEAL_ORDER : return(this.Order() > obj.Order() ? 1 : this.Order() < obj.Order() ? -1 : 0);
case SORT_MODE_DEAL_TIME : return(this.Time() > obj.Time() ? 1 : this.Time() < obj.Time() ? -1 : 0);
case SORT_MODE_DEAL_TIME_MSC : return(this.TimeMsc() > obj.TimeMsc() ? 1 : this.TimeMsc() < obj.TimeMsc() ? -1 : 0);
case SORT_MODE_DEAL_TYPE : return(this.TypeDeal() > obj.TypeDeal() ? 1 : this.TypeDeal() < obj.TypeDeal() ? -1 : 0);
case SORT_MODE_DEAL_ENTRY : return(this.Entry() > obj.Entry() ? 1 : this.Entry() < obj.Entry() ? -1 : 0);
case SORT_MODE_DEAL_MAGIC : return(this.Magic() > obj.Magic() ? 1 : this.Magic() < obj.Magic() ? -1 : 0);
case SORT_MODE_DEAL_REASON : return(this.Reason() > obj.Reason() ? 1 : this.Reason() < obj.Reason() ? -1 : 0);
case SORT_MODE_DEAL_POSITION_ID : return(this.PositionID() > obj.PositionID() ? 1 : this.PositionID() < obj.PositionID() ? -1 : 0);
case SORT_MODE_DEAL_VOLUME : return(this.Volume() > obj.Volume() ? 1 : this.Volume() < obj.Volume() ? -1 : 0);
case SORT_MODE_DEAL_PRICE : return(this.Price() > obj.Price() ? 1 : this.Price() < obj.Price() ? -1 : 0);
case SORT_MODE_DEAL_COMMISSION : return(this.Commission() > obj.Commission() ? 1 : this.Commission() < obj.Commission() ? -1 : 0);
case SORT_MODE_DEAL_SWAP : return(this.Swap() > obj.Swap() ? 1 : this.Swap() < obj.Swap() ? -1 : 0);
case SORT_MODE_DEAL_PROFIT : return(this.Profit() > obj.Profit() ? 1 : this.Profit() < obj.Profit() ? -1 : 0);
case SORT_MODE_DEAL_FEE : return(this.Fee() > obj.Fee() ? 1 : this.Fee() < obj.Fee() ? -1 : 0);
case SORT_MODE_DEAL_SL : return(this.SL() > obj.SL() ? 1 : this.SL() < obj.SL() ? -1 : 0);
case SORT_MODE_DEAL_TP : return(this.TP() > obj.TP() ? 1 : this.TP() < obj.TP() ? -1 : 0);
case SORT_MODE_DEAL_SYMBOL : return(this.Symbol() > obj.Symbol() ? 1 : this.Symbol() < obj.Symbol() ? -1 : 0);
case SORT_MODE_DEAL_COMMENT : return(this.Comment() > obj.Comment() ? 1 : this.Comment() < obj.Comment() ? -1 : 0);
case SORT_MODE_DEAL_EXTERNAL_ID : return(this.ExternalID() >obj.ExternalID() ? 1 : this.ExternalID() <obj.ExternalID() ? -1 : 0);
case SORT_MODE_DEAL_TICKET_TESTER : return(this.TicketTester()>obj.TicketTester()? 1 : this.TicketTester()<obj.TicketTester() ? -1 : 0);
case SORT_MODE_DEAL_POS_ID_TESTER : return(this.PosIDTester() >obj.PosIDTester() ? 1 : this.PosIDTester() <obj.PosIDTester() ? -1 : 0);
default : return(WRONG_VALUE);
}
}
//--- >=AB@C:B>@K/45AB@C:B>@
CDeal(const ulong ticket, const string symbol) : m_ticket(ticket), m_symbol(symbol), m_ticket_tester(0), m_pos_id_tester(0)
{ this.m_digits=(int)::SymbolInfoInteger(symbol, SYMBOL_DIGITS); this.m_point=::SymbolInfoDouble(symbol, SYMBOL_POINT); }
CDeal(void) {}
~CDeal(void) {}
};
//+------------------------------------------------------------------+
//| ;0AA B>@3>2;8 ?> A8<2>;C |
//+------------------------------------------------------------------+
CDeal DealTmp; // @5<5==K9 >1J5:B A45;:8 4;O ?>8A:0 ?> A2>9AB20<
class CSymbolTrade : public CObject
{
private:
int m_index_next_deal; // =45:A >G5@54=>9 5IQ =5 >1@01>B0==>9 A45;:8
int m_deals_processed; // >;8G5AB2> >1@01>B0==KE A45;>:
protected:
MqlTick m_tick; // !B@C:BC@0 B8:0
CArrayObj m_list_deals; // !?8A>: A45;>:, ?@>254Q==KE ?> A8<2>;C
CTrade m_trade; // ">@3>2K9 :;0AA
string m_symbol; // 08<5=>20=85 A8<2>;0
public:
//--- >72@0I05B A?8A>: A45;>:
CArrayObj *GetListDeals(void) { return(&this.m_list_deals); }
//--- #AB0=02;8205B A8<2>;
void SetSymbol(const string symbol) { this.m_symbol=symbol; }
//--- (1) #AB0=02;8205B, (2) 2>72@0I05B :>;8G5AB2> >1@01>B0==KE A45;>:
void SetNumProcessedDeals(const int num) { this.m_deals_processed=num; }
int NumProcessedDeals(void) const { return this.m_deals_processed; }
//--- >102;O5B A45;:C 2 <0AA82 A45;>:
bool AddDeal(CDeal *deal);
//--- >72@0I05B A45;:C (1) ?> 2@5<5=8 2 A5:C=40E, (2) ?> 8=45:AC 2 A?8A:5,
//--- (3) A45;:C >B:@KB8O ?> 845=B8D8:0B>@C ?>78F88, (4) B5:CICN A45;:C 2 A?8A:5
CDeal *GetDealByTime(const datetime time);
CDeal *GetDealByIndex(const int index);
CDeal *GetDealInByPosID(const long pos_id);
CDeal *GetDealCurrent(void);
//--- >72@0I05B (1) :>;8G5AB2> A45;>: 2 A?8A:5, (2) 8=45:A B5:CI59 A45;:8 2 A?8A:5
int DealsTotal(void) const { return this.m_list_deals.Total(); }
int DealCurrentIndex(void) const { return this.m_index_next_deal; }
//--- #AB0=02;8205B 8=45:A A;54CNI59 A45;:8
void SetNextDealIndex(void) { this.m_index_next_deal++; }
//--- >72@0I05B (1) A8<2>;, (2) >?8A0=85 >1J5:B0
string Symbol(void) const { return this.m_symbol; }
string Description(void) const
{
return ::StringFormat("%s trade object. Total deals: %d", this.Symbol(), this.DealsTotal() );
}
//--- >72@0I05B B5:CICN F5=C (1) Bid, (2) Ask, 2@5<O 2 (3) A5:C=40E, (4) <8;;8A5:C=40E
double Bid(void);
double Ask(void);
datetime Time(void);
long TimeMsc(void);
//--- B:@K205B (1) 4;8==CN, (2) :>@>B:CN ?>78F8N, (3) 70:@K205B ?>78F8N ?> B8:5BC
ulong Buy(const double volume, const ulong magic, const double sl, const double tp, const string comment);
ulong Sell(const double volume, const ulong magic, const double sl, const double tp, const string comment);
bool ClosePos(const ulong ticket);
//--- >72@0I05B @57C;LB0B A@02=5=8O B5:CI53> 2@5<5=8 A C:070==K<
bool CheckTime(const datetime time) { return(this.Time()>=time); }
//--- 1@01>BG8: OnTester. >72@0I05B :>;8G5AB2> >1@01>B0==KE B5AB5@>< A45;>:
double OnTester(void)
{
::PrintFormat("Symbol %s: Total deals: %d, number of processed deals: %d", this.Symbol(), this.DealsTotal(), this.NumProcessedDeals());
return this.m_deals_processed;
}
//--- !@02=8205B 420 >1J5:B0 <564C A>1>9 (A@02=5=85 B>;L:> ?> A8<2>;C)
virtual int Compare(const CObject *node, const int mode=0) const
{
const CSymbolTrade *obj=node;
return(this.Symbol()>obj.Symbol() ? 1 : this.Symbol()<obj.Symbol() ? -1 : 0);
}
//--- >=AB@C:B>@K/45AB@C:B>@
CSymbolTrade(void) : m_index_next_deal(0), m_deals_processed(0) {}
CSymbolTrade(const string symbol) : m_symbol(symbol), m_index_next_deal(0), m_deals_processed(0)
{
this.m_trade.SetMarginMode();
this.m_trade.SetTypeFillingBySymbol(this.m_symbol);
}
~CSymbolTrade(void) {}
};
//+------------------------------------------------------------------+
//| CSymbolTrade::>102;O5B A45;:C 2 <0AA82 A45;>: |
//+------------------------------------------------------------------+
bool CSymbolTrade::AddDeal(CDeal *deal)
{
//--- A;8 2 A?8A:5 C65 5ABL A45;:0 A B8:5B>< A45;:8, ?5@540==>9 2 <5B>4 - 2>72@0I05< true
this.m_list_deals.Sort(SORT_MODE_DEAL_TICKET);
if(this.m_list_deals.Search(deal)>WRONG_VALUE)
return true;
//--- >102;O5< C:070B5;L =0 A45;:C 2 A?8A>: 2 ?>@O4:5 A>@B8@>2:8 ?> 2@5<5=8 2 <8;;8A5:C=40E
this.m_list_deals.Sort(SORT_MODE_DEAL_TIME_MSC);
if(!this.m_list_deals.InsertSort(deal))
{
::PrintFormat("%s: Failed to add deal", __FUNCTION__);
return false;
}
//--- AQ CA?5H=>
return true;
}
//+------------------------------------------------------------------+
//| CSymbolTrade::>72@0I05B >1J5:B A45;:8 ?> 2@5<5=8 2 A5:C=40E |
//+------------------------------------------------------------------+
CDeal* CSymbolTrade::GetDealByTime(const datetime time)
{
DealTmp.SetTime(time);
this.m_list_deals.Sort(SORT_MODE_DEAL_TIME_MSC);
int index=this.m_list_deals.Search(&DealTmp);
return this.m_list_deals.At(index);
}
//+------------------------------------------------------------------+
//|CSymbolTrade::>72@0I05B A45;:C >B:@KB8O ?> 845=B8D8:0B>@C ?>78F88|
//+------------------------------------------------------------------+
CDeal *CSymbolTrade::GetDealInByPosID(const long pos_id)
{
int total=this.m_list_deals.Total();
for(int i=0; i<total; i++)
{
CDeal *deal=this.m_list_deals.At(i);
if(deal==NULL || deal.PositionID()!=pos_id)
continue;
if(deal.Entry()==DEAL_ENTRY_IN)
return deal;
}
return NULL;
}
//+------------------------------------------------------------------+
//| CSymbolTrade::>72@0I05B >1J5:B A45;:8 ?> 8=45:AC 2 A?8A:5 |
//+------------------------------------------------------------------+
CDeal *CSymbolTrade::GetDealByIndex(const int index)
{
return this.m_list_deals.At(index);
}
//+------------------------------------------------------------------+
//| >72@0I05B A45;:C, =0 :>B>@CN C:07K205B 8=45:A B5:CI59 A45;:8 |
//+------------------------------------------------------------------+
CDeal *CSymbolTrade::GetDealCurrent(void)
{
this.m_list_deals.Sort(SORT_MODE_DEAL_TIME_MSC);
return this.GetDealByIndex(this.m_index_next_deal);
}
//+------------------------------------------------------------------+
//| CSymbolTrade::>72@0I05B B5:CICN F5=C Bid |
//+------------------------------------------------------------------+
double CSymbolTrade::Bid(void)
{
::ResetLastError();
if(!::SymbolInfoTick(this.m_symbol, this.m_tick))
{
::PrintFormat("%s: SymbolInfoTick() failed. Error %d",__FUNCTION__, ::GetLastError());
return 0;
}
return this.m_tick.bid;
}
//+------------------------------------------------------------------+
//| CSymbolTrade::>72@0I05B B5:CICN F5=C Ask |
//+------------------------------------------------------------------+
double CSymbolTrade::Ask(void)
{
::ResetLastError();
if(!::SymbolInfoTick(this.m_symbol, this.m_tick))
{
::PrintFormat("%s: SymbolInfoTick() failed. Error %d",__FUNCTION__, ::GetLastError());
return 0;
}
return this.m_tick.ask;
}
//+------------------------------------------------------------------+
//| CSymbolTrade::>72@0I05B B5:CI55 2@5<O 2 A5:C=40E |
//+------------------------------------------------------------------+
datetime CSymbolTrade::Time(void)
{
::ResetLastError();
if(!::SymbolInfoTick(this.m_symbol, this.m_tick))
{
::PrintFormat("%s: SymbolInfoTick() failed. Error %d",__FUNCTION__, ::GetLastError());
return 0;
}
return this.m_tick.time;
}
//+------------------------------------------------------------------+
//| CSymbolTrade::>72@0I05B B5:CI55 2@5<O 2 <8;;8A5:C=40E |
//+------------------------------------------------------------------+
long CSymbolTrade::TimeMsc(void)
{
::ResetLastError();
if(!::SymbolInfoTick(this.m_symbol, this.m_tick))
{
::PrintFormat("%s: SymbolInfoTick() failed. Error %d",__FUNCTION__, ::GetLastError());
return 0;
}
return this.m_tick.time_msc;
}
//+------------------------------------------------------------------+
//| CSymbolTrade::B:@K205B 4;8==CN ?>78F8N |
//+------------------------------------------------------------------+
ulong CSymbolTrade::Buy(const double volume, const ulong magic, const double sl, const double tp, const string comment)
{
this.m_trade.SetExpertMagicNumber(magic);
if(!this.m_trade.Buy(volume, this.m_symbol, 0, sl, tp, comment))
{
return 0;
}
return this.m_trade.ResultOrder();
}
//+------------------------------------------------------------------+
//| CSymbolTrade::B:@K205B :>@>B:CN ?>78F8N |
//+------------------------------------------------------------------+
ulong CSymbolTrade::Sell(const double volume, const ulong magic, const double sl, const double tp, const string comment)
{
this.m_trade.SetExpertMagicNumber(magic);
if(!this.m_trade.Sell(volume, this.m_symbol, 0, sl, tp, comment))
{
return 0;
}
return this.m_trade.ResultOrder();
}
//+------------------------------------------------------------------+
//| CSymbolTrade::0:@K205B ?>78F8N ?> B8:5BC |
//+------------------------------------------------------------------+
bool CSymbolTrade::ClosePos(const ulong ticket)
{
return this.m_trade.PositionClose(ticket);
}
//+------------------------------------------------------------------+