519 lines
68 KiB
MQL5
519 lines
68 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| Position.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"
|
|
|
|
#include "Deal.mqh"
|
|
#include <Arrays\ArrayObj.mqh>
|
|
|
|
//--- Перечисление целочисленных свойств позиции
|
|
enum ENUM_POSITION_PROPERTY_INT
|
|
{
|
|
POSITION_PROP_TICKET = 0, // Тикет позиции
|
|
POSITION_PROP_TIME, // Время открытия позиции
|
|
POSITION_PROP_TIME_MSC, // Время открытия позиции в миллисекундах
|
|
POSITION_PROP_TIME_UPDATE, // Время изменения позиции
|
|
POSITION_PROP_TIME_UPDATE_MSC, // Время изменения позиции в миллисекундах
|
|
POSITION_PROP_TYPE, // Тип позиции
|
|
POSITION_PROP_MAGIC, // Magic number позиции
|
|
POSITION_PROP_IDENTIFIER, // Идентификатор позиции
|
|
POSITION_PROP_REASON, // Причина открытия позиции
|
|
POSITION_PROP_ACCOUNT_LOGIN, // Номер счёта
|
|
POSITION_PROP_TIME_CLOSE, // Время закрытия позиции
|
|
POSITION_PROP_TIME_CLOSE_MSC, // Время закрытия позиции в миллисекундах
|
|
};
|
|
|
|
//--- Перечисление вещественных свойств позиции
|
|
enum ENUM_POSITION_PROPERTY_DBL
|
|
{
|
|
POSITION_PROP_VOLUME = POSITION_PROP_TIME_CLOSE_MSC+1,// Объем позиции
|
|
POSITION_PROP_PRICE_OPEN, // Цена позиции
|
|
POSITION_PROP_SL, // Stop Loss для открытой позиции
|
|
POSITION_PROP_TP, // Take Profit для открытой позиции
|
|
POSITION_PROP_PRICE_CURRENT, // Текущая цена по символу
|
|
POSITION_PROP_SWAP, // Накопленный своп
|
|
POSITION_PROP_PROFIT, // Текущая прибыль
|
|
POSITION_PROP_CONTRACT_SIZE, // Размер торгового контракта символа
|
|
POSITION_PROP_PRICE_CLOSE, // Цена закрытия позиции
|
|
POSITION_PROP_COMMISSIONS, // Накопленная комиссия
|
|
POSITION_PROP_FEE, // Накопленная оплата за сделки
|
|
};
|
|
|
|
//--- Перечисление строковых свойств позиции
|
|
enum ENUM_POSITION_PROPERTY_STR
|
|
{
|
|
POSITION_PROP_SYMBOL = POSITION_PROP_FEE+1,// Символ, по которому открыта позиция
|
|
POSITION_PROP_COMMENT, // Комментарий к позиции
|
|
POSITION_PROP_EXTERNAL_ID, // Идентификатор позиции во внешней системе
|
|
POSITION_PROP_CURRENCY_PROFIT, // Валюта прибыли символа позиции
|
|
POSITION_PROP_ACCOUNT_CURRENCY, // Валюта депозита аккаунта
|
|
POSITION_PROP_ACCOUNT_SERVER, // Имя сервера
|
|
};
|
|
|
|
//+------------------------------------------------------------------+
|
|
//| Класс позиции |
|
|
//+------------------------------------------------------------------+
|
|
class CPosition : public CObject
|
|
{
|
|
private:
|
|
long m_lprop[POSITION_PROP_TIME_CLOSE_MSC+1]; // Массив для хранения целочисленных свойств
|
|
double m_dprop[POSITION_PROP_FEE-POSITION_PROP_TIME_CLOSE_MSC]; // Массив для хранения вещественных свойств
|
|
string m_sprop[POSITION_PROP_ACCOUNT_SERVER-POSITION_PROP_FEE]; // Массив для хранения строковых свойств
|
|
|
|
//--- Возвращает индекс массива, по которому фактически расположено (1) double-свойство и (2) string-свойство ордера
|
|
int IndexProp(ENUM_POSITION_PROPERTY_DBL property) const { return(int)property-POSITION_PROP_TIME_CLOSE_MSC-1;}
|
|
int IndexProp(ENUM_POSITION_PROPERTY_STR property) const { return(int)property-POSITION_PROP_FEE-1; }
|
|
|
|
protected:
|
|
CArrayObj m_list_deals; // Список сделок позиции
|
|
CDeal m_temp_deal; // Временный объект-сделка для поиска по свойству в списке
|
|
|
|
//--- Возвращает время с миллисекундами
|
|
string TimeMscToString(const long time_msc,int flags=TIME_DATE|TIME_MINUTES|TIME_SECONDS) const;
|
|
|
|
//--- Дополнительные свойства
|
|
int m_profit_pt; // Прибыль в пунктах
|
|
int m_digits; // Digits символа
|
|
double m_point; // Значение одного пункта символа
|
|
double m_tick_value; // Рассчитанная стоимость тика
|
|
|
|
//--- Возвращает указатель на сделку (1) открытия, (2) закрытия
|
|
CDeal *GetDealIn(void) const;
|
|
CDeal *GetDealOut(void) const;
|
|
|
|
public:
|
|
//--- Возвращает список сделок
|
|
CArrayObj *GetListDeals(void) { return(&this.m_list_deals); }
|
|
|
|
//--- Установка свойств
|
|
//--- Устанавливает (1) целочисленное, (2) вещественное и (3) строковое свойство
|
|
void SetProperty(ENUM_POSITION_PROPERTY_INT property,long value) { this.m_lprop[property]=value; }
|
|
void SetProperty(ENUM_POSITION_PROPERTY_DBL property,double value) { this.m_dprop[this.IndexProp(property)]=value; }
|
|
void SetProperty(ENUM_POSITION_PROPERTY_STR property,string value) { this.m_sprop[this.IndexProp(property)]=value; }
|
|
|
|
//--- Целочисленные свойства
|
|
void SetTicket(const long ticket) { this.SetProperty(POSITION_PROP_TICKET, ticket); } // Тикет позиции
|
|
void SetTime(const datetime time) { this.SetProperty(POSITION_PROP_TIME, time); } // Время открытия позиции
|
|
void SetTimeMsc(const long value) { this.SetProperty(POSITION_PROP_TIME_MSC, value); } // Время открытия позиции в миллисекундах с 01.01.1970
|
|
void SetTimeUpdate(const datetime time) { this.SetProperty(POSITION_PROP_TIME_UPDATE, time); } // Время изменения позиции
|
|
void SetTimeUpdateMsc(const long value) { this.SetProperty(POSITION_PROP_TIME_UPDATE_MSC, value); } // Время изменения позиции в миллисекундах с 01.01.1970
|
|
void SetTypePosition(const ENUM_POSITION_TYPE type) { this.SetProperty(POSITION_PROP_TYPE, type); } // Тип позиции
|
|
void SetMagic(const long magic) { this.SetProperty(POSITION_PROP_MAGIC, magic); } // Magic number для позиции (смотри ORDER_MAGIC)
|
|
void SetID(const long id) { this.SetProperty(POSITION_PROP_IDENTIFIER, id); } // Идентификатор позиции
|
|
void SetReason(const ENUM_POSITION_REASON reason) { this.SetProperty(POSITION_PROP_REASON, reason); } // Причина открытия позиции
|
|
void SetTimeClose(const datetime time) { this.SetProperty(POSITION_PROP_TIME_CLOSE, time); } // Время закрытия
|
|
void SetTimeCloseMsc(const long value) { this.SetProperty(POSITION_PROP_TIME_CLOSE_MSC, value); } // Время закрытия в миллисекундах
|
|
void SetAccountLogin(const long login) { this.SetProperty(POSITION_PROP_ACCOUNT_LOGIN, login); } // Номер счёта
|
|
|
|
//--- Вещественные свойства
|
|
void SetVolume(const double volume) { this.SetProperty(POSITION_PROP_VOLUME, volume); } // Объем позиции
|
|
void SetPriceOpen(const double price) { this.SetProperty(POSITION_PROP_PRICE_OPEN, price); } // Цена позиции
|
|
void SetSL(const double value) { this.SetProperty(POSITION_PROP_SL, value); } // Уровень Stop Loss для открытой позиции
|
|
void SetTP(const double value) { this.SetProperty(POSITION_PROP_TP, value); } // Уровень Take Profit для открытой позиции
|
|
void SetPriceCurrent(const double price) { this.SetProperty(POSITION_PROP_PRICE_CURRENT, price); } // Текущая цена по символу
|
|
void SetSwap(const double value) { this.SetProperty(POSITION_PROP_SWAP, value); } // Накопленный своп
|
|
void SetProfit(const double value) { this.SetProperty(POSITION_PROP_PROFIT, value); } // Текущая прибыль
|
|
void SetPriceClose(const double price) { this.SetProperty(POSITION_PROP_PRICE_CLOSE, price); } // Цена закрытия
|
|
void SetContractSize(const double value) { this.SetProperty(POSITION_PROP_CONTRACT_SIZE, value); } // Размер торгового контракта символа
|
|
void SetCommissions(void); // Совокупная комиссия всех сделок
|
|
void SetFee(void); // Совокупная оплату за проведение сделок
|
|
|
|
//--- Строковые свойства
|
|
void SetSymbol(const string symbol) { this.SetProperty(POSITION_PROP_SYMBOL, symbol); } // Символ, по которому открыта позиция
|
|
void SetComment(const string comment) { this.SetProperty(POSITION_PROP_COMMENT, comment); } // Комментарий к позиции
|
|
void SetExternalID(const string ext_id) { this.SetProperty(POSITION_PROP_EXTERNAL_ID, ext_id); } // Идентификатор позиции во внешней системе (на бирже)
|
|
void SetAccountServer(const string server) { this.SetProperty(POSITION_PROP_ACCOUNT_SERVER, server); } // Имя сервера
|
|
void SetAccountCurrency(const string currency) { this.SetProperty(POSITION_PROP_ACCOUNT_CURRENCY, currency); } // Валюта депозита аккаунта
|
|
void SetCurrencyProfit(const string currency) { this.SetProperty(POSITION_PROP_CURRENCY_PROFIT, currency); } // Валюта прибыли символа позиции
|
|
|
|
//--- Получение свойств
|
|
//--- Возвращает из массива свойств (1) целочисленное, (2) вещественное и (3) строковое свойство
|
|
long GetProperty(ENUM_POSITION_PROPERTY_INT property) const { return this.m_lprop[property]; }
|
|
double GetProperty(ENUM_POSITION_PROPERTY_DBL property) const { return this.m_dprop[this.IndexProp(property)]; }
|
|
string GetProperty(ENUM_POSITION_PROPERTY_STR property) const { return this.m_sprop[this.IndexProp(property)]; }
|
|
|
|
//--- Целочисленные свойства
|
|
long Ticket(void) const { return this.GetProperty(POSITION_PROP_TICKET); } // Тикет позиции
|
|
datetime Time(void) const { return (datetime)this.GetProperty(POSITION_PROP_TIME); } // Время открытия позиции
|
|
long TimeMsc(void) const { return this.GetProperty(POSITION_PROP_TIME_MSC); } // Время открытия позиции в миллисекундах с 01.01.1970
|
|
datetime TimeUpdate(void) const { return (datetime)this.GetProperty(POSITION_PROP_TIME_UPDATE);} // Время изменения позиции
|
|
long TimeUpdateMsc(void) const { return this.GetProperty(POSITION_PROP_TIME_UPDATE_MSC); } // Время изменения позиции в миллисекундах с 01.01.1970
|
|
ENUM_POSITION_TYPE TypePosition(void) const { return (ENUM_POSITION_TYPE)this.GetProperty(POSITION_PROP_TYPE);}// Тип позиции
|
|
long Magic(void) const { return this.GetProperty(POSITION_PROP_MAGIC); } // Magic number для позиции (смотри ORDER_MAGIC)
|
|
long ID(void) const { return this.GetProperty(POSITION_PROP_IDENTIFIER); } // Идентификатор позиции
|
|
ENUM_POSITION_REASON Reason(void) const { return (ENUM_POSITION_REASON)this.GetProperty(POSITION_PROP_REASON);}// Причина открытия позиции
|
|
datetime TimeClose(void) const { return (datetime)this.GetProperty(POSITION_PROP_TIME_CLOSE); } // Время закрытия
|
|
long TimeCloseMsc(void) const { return this.GetProperty(POSITION_PROP_TIME_CLOSE_MSC); } // Время закрытия в миллисекундах
|
|
long AccountLogin(void) const { return this.GetProperty(POSITION_PROP_ACCOUNT_LOGIN); } // Логин
|
|
|
|
//--- Вещественные свойства
|
|
double Volume(void) const { return this.GetProperty(POSITION_PROP_VOLUME); } // Объем позиции
|
|
double PriceOpen(void) const { return this.GetProperty(POSITION_PROP_PRICE_OPEN); } // Цена позиции
|
|
double SL(void) const { return this.GetProperty(POSITION_PROP_SL); } // Уровень Stop Loss для открытой позиции
|
|
double TP(void) const { return this.GetProperty(POSITION_PROP_TP); } // Уровень Take Profit для открытой позиции
|
|
double PriceCurrent(void) const { return this.GetProperty(POSITION_PROP_PRICE_CURRENT); } // Текущая цена по символу
|
|
double Swap(void) const { return this.GetProperty(POSITION_PROP_SWAP); } // Накопленный своп
|
|
double Profit(void) const { return this.GetProperty(POSITION_PROP_PROFIT); } // Текущая прибыль
|
|
double ContractSize(void) const { return this.GetProperty(POSITION_PROP_CONTRACT_SIZE); } // Размер торгового контракта символа
|
|
double PriceClose(void) const { return this.GetProperty(POSITION_PROP_PRICE_CLOSE); } // Цена закрытия
|
|
double Commissions(void) const { return this.GetProperty(POSITION_PROP_COMMISSIONS); } // Совокупная комиссия всех сделок
|
|
double Fee(void) const { return this.GetProperty(POSITION_PROP_FEE); } // Совокупная оплата за проведение сделок
|
|
|
|
//--- Строковые свойства
|
|
string Symbol(void) const { return this.GetProperty(POSITION_PROP_SYMBOL); } // Символ, по которому открыта позиция
|
|
string Comment(void) const { return this.GetProperty(POSITION_PROP_COMMENT); } // Комментарий к позиции
|
|
string ExternalID(void) const { return this.GetProperty(POSITION_PROP_EXTERNAL_ID); } // Идентификатор позиции во внешней системе (на бирже)
|
|
string AccountServer(void) const { return this.GetProperty(POSITION_PROP_ACCOUNT_SERVER); } // Имя сервера
|
|
string AccountCurrency(void) const { return this.GetProperty(POSITION_PROP_ACCOUNT_CURRENCY); } // Валюта депозита аккаунта
|
|
string CurrencyProfit(void) const { return this.GetProperty(POSITION_PROP_CURRENCY_PROFIT); } // Валюта прибыли символа позиции
|
|
|
|
|
|
//--- Дополнительные свойства
|
|
ulong DealIn(void) const; // Тикет сделки открытия
|
|
ulong DealOut(void) const; // Тикет сделки закрытия
|
|
int ProfitInPoints(void) const; // Прибыль в пунктах
|
|
int SpreadIn(void) const; // Спред при открытии
|
|
int SpreadOut(void) const; // Спред при закрытии
|
|
double SpreadOutCost(void) const; // Стоимость спреда при закрытии
|
|
double PriceOutAsk(void) const; // Цена Ask при закрытии
|
|
double PriceOutBid(void) const; // Цена Bid при закрытии
|
|
|
|
//--- Добавляет сделку в список сделок, возвращает указатель
|
|
CDeal *DealAdd(const long ticket);
|
|
|
|
//--- Возвращает описание типа позиции
|
|
string TypeDescription(void) const;
|
|
|
|
//--- Возвращает описание времени и цены открытия позиции
|
|
string TimePriceCloseDescription(void);
|
|
|
|
//--- Возвращает описание времени и цены закрытия позиции
|
|
string TimePriceOpenDescription(void);
|
|
|
|
//--- Возвращает описание позиции
|
|
string Description(void);
|
|
|
|
//--- Распечатывает в журнале свойства позиции и её сделок
|
|
void Print(void);
|
|
|
|
//--- Сравнивает два объекта между собой по указанному в mode свойству
|
|
virtual int Compare(const CObject *node, const int mode=0) const;
|
|
|
|
//--- Конструктор/деструктор
|
|
CPosition(const long position_id, const string symbol);
|
|
CPosition(void){}
|
|
~CPosition();
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Конструктор |
|
|
//+------------------------------------------------------------------+
|
|
CPosition::CPosition(const long position_id, const string symbol)
|
|
{
|
|
this.m_list_deals.Sort(DEAL_PROP_TIME_MSC);
|
|
this.SetID(position_id);
|
|
this.SetSymbol(symbol);
|
|
this.SetAccountLogin(::AccountInfoInteger(ACCOUNT_LOGIN));
|
|
this.SetAccountServer(::AccountInfoString(ACCOUNT_SERVER));
|
|
this.SetAccountCurrency(::AccountInfoString(ACCOUNT_CURRENCY));
|
|
this.SetCurrencyProfit(::SymbolInfoString(this.Symbol(),SYMBOL_CURRENCY_PROFIT));
|
|
this.SetContractSize(::SymbolInfoDouble(this.Symbol(),SYMBOL_TRADE_CONTRACT_SIZE));
|
|
this.m_digits = (int)::SymbolInfoInteger(this.Symbol(),SYMBOL_DIGITS);
|
|
this.m_point = ::SymbolInfoDouble(this.Symbol(),SYMBOL_POINT);
|
|
this.m_tick_value = ::SymbolInfoDouble(this.Symbol(), SYMBOL_TRADE_TICK_VALUE);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Деструктор |
|
|
//+------------------------------------------------------------------+
|
|
CPosition::~CPosition()
|
|
{
|
|
this.m_list_deals.Clear();
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Сравнивает два объекта между собой по указанному свойству |
|
|
//+------------------------------------------------------------------+
|
|
int CPosition::Compare(const CObject *node,const int mode=0) const
|
|
{
|
|
const CPosition *obj=node;
|
|
switch(mode)
|
|
{
|
|
case POSITION_PROP_TICKET : return(this.Ticket() > obj.Ticket() ? 1 : this.Ticket() < obj.Ticket() ? -1 : 0);
|
|
case POSITION_PROP_TIME : return(this.Time() > obj.Time() ? 1 : this.Time() < obj.Time() ? -1 : 0);
|
|
case POSITION_PROP_TIME_MSC : return(this.TimeMsc() > obj.TimeMsc() ? 1 : this.TimeMsc() < obj.TimeMsc() ? -1 : 0);
|
|
case POSITION_PROP_TIME_UPDATE : return(this.TimeUpdate() > obj.TimeUpdate() ? 1 : this.TimeUpdate() < obj.TimeUpdate() ? -1 : 0);
|
|
case POSITION_PROP_TIME_UPDATE_MSC : return(this.TimeUpdateMsc() > obj.TimeUpdateMsc() ? 1 : this.TimeUpdateMsc() < obj.TimeUpdateMsc() ? -1 : 0);
|
|
case POSITION_PROP_TYPE : return(this.TypePosition() > obj.TypePosition() ? 1 : this.TypePosition() < obj.TypePosition() ? -1 : 0);
|
|
case POSITION_PROP_MAGIC : return(this.Magic() > obj.Magic() ? 1 : this.Magic() < obj.Magic() ? -1 : 0);
|
|
case POSITION_PROP_IDENTIFIER : return(this.ID() > obj.ID() ? 1 : this.ID() < obj.ID() ? -1 : 0);
|
|
case POSITION_PROP_REASON : return(this.Reason() > obj.Reason() ? 1 : this.Reason() < obj.Reason() ? -1 : 0);
|
|
case POSITION_PROP_ACCOUNT_LOGIN : return(this.AccountLogin() > obj.AccountLogin() ? 1 : this.AccountLogin() < obj.AccountLogin() ? -1 : 0);
|
|
case POSITION_PROP_TIME_CLOSE : return(this.TimeClose() > obj.TimeClose() ? 1 : this.TimeClose() < obj.TimeClose() ? -1 : 0);
|
|
case POSITION_PROP_TIME_CLOSE_MSC : return(this.TimeCloseMsc() > obj.TimeCloseMsc() ? 1 : this.TimeCloseMsc() < obj.TimeCloseMsc() ? -1 : 0);
|
|
case POSITION_PROP_VOLUME : return(this.Volume() > obj.Volume() ? 1 : this.Volume() < obj.Volume() ? -1 : 0);
|
|
case POSITION_PROP_PRICE_OPEN : return(this.PriceOpen() > obj.PriceOpen() ? 1 : this.PriceOpen() < obj.PriceOpen() ? -1 : 0);
|
|
case POSITION_PROP_SL : return(this.SL() > obj.SL() ? 1 : this.SL() < obj.SL() ? -1 : 0);
|
|
case POSITION_PROP_TP : return(this.TP() > obj.TP() ? 1 : this.TP() < obj.TP() ? -1 : 0);
|
|
case POSITION_PROP_PRICE_CURRENT : return(this.PriceCurrent() > obj.PriceCurrent() ? 1 : this.PriceCurrent() < obj.PriceCurrent() ? -1 : 0);
|
|
case POSITION_PROP_SWAP : return(this.Swap() > obj.Swap() ? 1 : this.Swap() < obj.Swap() ? -1 : 0);
|
|
case POSITION_PROP_PROFIT : return(this.Profit() > obj.Profit() ? 1 : this.Profit() < obj.Profit() ? -1 : 0);
|
|
case POSITION_PROP_CONTRACT_SIZE : return(this.ContractSize() > obj.ContractSize() ? 1 : this.ContractSize() < obj.ContractSize() ? -1 : 0);
|
|
case POSITION_PROP_PRICE_CLOSE : return(this.PriceClose() > obj.PriceClose() ? 1 : this.PriceClose() < obj.PriceClose() ? -1 : 0);
|
|
case POSITION_PROP_COMMISSIONS : return(this.Commissions() > obj.Commissions() ? 1 : this.Commissions() < obj.Commissions() ? -1 : 0);
|
|
case POSITION_PROP_FEE : return(this.Fee() > obj.Fee() ? 1 : this.Fee() < obj.Fee() ? -1 : 0);
|
|
case POSITION_PROP_SYMBOL : return(this.Symbol() > obj.Symbol() ? 1 : this.Symbol() < obj.Symbol() ? -1 : 0);
|
|
case POSITION_PROP_COMMENT : return(this.Comment() > obj.Comment() ? 1 : this.Comment() < obj.Comment() ? -1 : 0);
|
|
case POSITION_PROP_EXTERNAL_ID : return(this.ExternalID() > obj.ExternalID() ? 1 : this.ExternalID() < obj.ExternalID() ? -1 : 0);
|
|
case POSITION_PROP_CURRENCY_PROFIT : return(this.CurrencyProfit() > obj.CurrencyProfit() ? 1 : this.CurrencyProfit() < obj.CurrencyProfit() ? -1 : 0);
|
|
case POSITION_PROP_ACCOUNT_CURRENCY : return(this.AccountCurrency() > obj.AccountCurrency() ? 1 : this.AccountCurrency() < obj.AccountCurrency() ? -1 : 0);
|
|
case POSITION_PROP_ACCOUNT_SERVER : return(this.AccountServer() > obj.AccountServer() ? 1 : this.AccountServer() < obj.AccountServer() ? -1 : 0);
|
|
default : return -1;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает время с миллисекундами |
|
|
//+------------------------------------------------------------------+
|
|
string CPosition::TimeMscToString(const long time_msc, int flags=TIME_DATE|TIME_MINUTES|TIME_SECONDS) const
|
|
{
|
|
return(::TimeToString(time_msc/1000, flags) + "." + ::IntegerToString(time_msc %1000, 3, '0'));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает указатель на сделку открытия |
|
|
//+------------------------------------------------------------------+
|
|
CDeal *CPosition::GetDealIn(void) const
|
|
{
|
|
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)
|
|
continue;
|
|
if(deal.Entry()==DEAL_ENTRY_IN)
|
|
return deal;
|
|
}
|
|
return NULL;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает указатель на сделку закрытия |
|
|
//+------------------------------------------------------------------+
|
|
CDeal *CPosition::GetDealOut(void) const
|
|
{
|
|
for(int i=this.m_list_deals.Total()-1; i>=0; i--)
|
|
{
|
|
CDeal *deal=this.m_list_deals.At(i);
|
|
if(deal==NULL)
|
|
continue;
|
|
if(deal.Entry()==DEAL_ENTRY_OUT || deal.Entry()==DEAL_ENTRY_OUT_BY)
|
|
return deal;
|
|
}
|
|
return NULL;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает тикет сделки открытия |
|
|
//+------------------------------------------------------------------+
|
|
ulong CPosition::DealIn(void) const
|
|
{
|
|
CDeal *deal=this.GetDealIn();
|
|
return(deal!=NULL ? deal.Ticket() : 0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает тикет сделки закрытия |
|
|
//+------------------------------------------------------------------+
|
|
ulong CPosition::DealOut(void) const
|
|
{
|
|
CDeal *deal=this.GetDealOut();
|
|
return(deal!=NULL ? deal.Ticket() : 0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает спред при открытии |
|
|
//+------------------------------------------------------------------+
|
|
int CPosition::SpreadIn(void) const
|
|
{
|
|
CDeal *deal=this.GetDealIn();
|
|
return(deal!=NULL ? deal.Spread() : 0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает спред при закрытии |
|
|
//+------------------------------------------------------------------+
|
|
int CPosition::SpreadOut(void) const
|
|
{
|
|
CDeal *deal=this.GetDealOut();
|
|
return(deal!=NULL ? deal.Spread() : 0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает цену Ask при закрытии |
|
|
//+------------------------------------------------------------------+
|
|
double CPosition::PriceOutAsk(void) const
|
|
{
|
|
CDeal *deal=this.GetDealOut();
|
|
return(deal!=NULL ? deal.Ask() : 0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает цену Bid при закрытии |
|
|
//+------------------------------------------------------------------+
|
|
double CPosition::PriceOutBid(void) const
|
|
{
|
|
CDeal *deal=this.GetDealOut();
|
|
return(deal!=NULL ? deal.Bid() : 0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает прибыль в пунктах |
|
|
//+------------------------------------------------------------------+
|
|
int CPosition::ProfitInPoints(void) const
|
|
{
|
|
//--- Если Point символа не получен ранее, сообщаем об этом и возвращаем 0
|
|
if(this.m_point==0)
|
|
{
|
|
::Print("The Point() value could not be retrieved.");
|
|
return 0;
|
|
}
|
|
//--- Получаем цены открытия и закрытия позиции
|
|
double open =this.PriceOpen();
|
|
double close=this.PriceClose();
|
|
|
|
//--- Если цены получить не удалось - возвращаем 0
|
|
if(open==0 || close==0)
|
|
return 0;
|
|
|
|
//--- В зависимости от типа позиции возвращаем рассчитанное значение прибыли позиции в пунктах
|
|
return (int)::round(this.TypePosition()==POSITION_TYPE_BUY ? (close-open)/this.m_point : (open-close)/this.m_point);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает стоимость спреда при закрытии |
|
|
//+------------------------------------------------------------------+
|
|
double CPosition::SpreadOutCost(void) const
|
|
{
|
|
//--- Получаем сделку закрытия
|
|
CDeal *deal=this.GetDealOut();
|
|
if(deal==NULL)
|
|
return 0;
|
|
|
|
//--- Получаем профит позиции и профит позиции в пунктах
|
|
double profit=this.Profit();
|
|
int profit_pt=this.ProfitInPoints();
|
|
|
|
//--- Если профит нулевой - возвращаем стоимость спреда по формуле TickValue * Spread * Lots
|
|
if(profit==0)
|
|
return(this.m_tick_value * deal.Spread() * deal.Volume());
|
|
|
|
//--- Рассчитываем и возвращаем стоимость спреда (пропорция)
|
|
return(profit_pt>0 ? deal.Spread() * ::fabs(profit / profit_pt) : 0);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Устанавливает совокупную комиссию всех сделок |
|
|
//+------------------------------------------------------------------+
|
|
void CPosition::SetCommissions(void)
|
|
{
|
|
double res=0;
|
|
int total=this.m_list_deals.Total();
|
|
for(int i=0; i<total; i++)
|
|
{
|
|
CDeal *deal=this.m_list_deals.At(i);
|
|
res+=(deal!=NULL ? deal.Commission() : 0);
|
|
}
|
|
this.SetProperty(POSITION_PROP_COMMISSIONS, res);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Устанавливает совокупную оплату за проведение сделок |
|
|
//+------------------------------------------------------------------+
|
|
void CPosition::SetFee(void)
|
|
{
|
|
double res=0;
|
|
int total=this.m_list_deals.Total();
|
|
for(int i=0; i<total; i++)
|
|
{
|
|
CDeal *deal=this.m_list_deals.At(i);
|
|
res+=(deal!=NULL ? deal.Fee() : 0);
|
|
}
|
|
this.SetProperty(POSITION_PROP_FEE, res);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Добавляет сделку в список сделок |
|
|
//+------------------------------------------------------------------+
|
|
CDeal *CPosition::DealAdd(const long ticket)
|
|
{
|
|
//--- Устанавливаем временному объекту тикет искомой сделки и устанавливаем флаг сортировки списка сделок по тикету
|
|
this.m_temp_deal.SetTicket(ticket);
|
|
this.m_list_deals.Sort(DEAL_PROP_TICKET);
|
|
|
|
//--- Записываем результат проверки присутствия в списке сделки с таким тикетом
|
|
bool exist=(this.m_list_deals.Search(&this.m_temp_deal)!=WRONG_VALUE);
|
|
|
|
//--- Возвращаем для списка сортировку по времени в миллисекундах
|
|
this.m_list_deals.Sort(DEAL_PROP_TIME_MSC);
|
|
|
|
//--- Если сделка с таким тикетом уже есть в списке - возвращаем NULL
|
|
if(exist)
|
|
return NULL;
|
|
|
|
//--- Создаём новый объект-сделку
|
|
CDeal *deal=new CDeal(ticket);
|
|
if(deal==NULL)
|
|
return NULL;
|
|
|
|
//--- Добавляем созданный объект в список в порядке сортировки по времени в миллисекундах
|
|
//--- Если сделку добавить в список не удалось - удаляем объект сделки и возвращаем NULL
|
|
if(!this.m_list_deals.InsertSort(deal))
|
|
{
|
|
delete deal;
|
|
return NULL;
|
|
}
|
|
|
|
//--- Если это сделка закрытия позиции - записываем в значение прибыли позиции прибыль и своп из свойств сделки
|
|
if(deal.Entry()==DEAL_ENTRY_OUT || deal.Entry()==DEAL_ENTRY_OUT_BY)
|
|
{
|
|
this.SetProfit(deal.Profit());
|
|
this.SetSwap(deal.Swap());
|
|
}
|
|
|
|
//--- Возвращаем указатель на созданный объект-сделку
|
|
return deal;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает описание типа позиции |
|
|
//+------------------------------------------------------------------+
|
|
string CPosition::TypeDescription(void) const
|
|
{
|
|
return(this.TypePosition()==POSITION_TYPE_BUY ? "Buy" : this.TypePosition()==POSITION_TYPE_SELL ? "Sell" : "Unknown::"+(string)this.TypePosition());
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает описание времени и цены открытия позиции |
|
|
//+------------------------------------------------------------------+
|
|
string CPosition::TimePriceOpenDescription(void)
|
|
{
|
|
return(::StringFormat("Opened %s [%.*f]", this.TimeMscToString(this.TimeMsc()),this.m_digits, this.PriceOpen()));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает описание времени и цены закрытия позиции |
|
|
//+------------------------------------------------------------------+
|
|
string CPosition::TimePriceCloseDescription(void)
|
|
{
|
|
if(this.TimeCloseMsc()==0)
|
|
return "Not closed yet";
|
|
return(::StringFormat("Closed %s [%.*f]", this.TimeMscToString(this.TimeCloseMsc()),this.m_digits, this.PriceClose()));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Возвращает краткое описание позиции |
|
|
//+------------------------------------------------------------------+
|
|
string CPosition::Description(void)
|
|
{
|
|
return(::StringFormat("%I64d (%s): %s %.2f %s #%I64d, Magic %I64d", this.AccountLogin(), this.AccountServer(),
|
|
this.Symbol(), this.Volume(), this.TypeDescription(), this.ID(), this.Magic()));
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Распечатывает в журнале свойства позиции и её сделок |
|
|
//+------------------------------------------------------------------+
|
|
void CPosition::Print(void)
|
|
{
|
|
::PrintFormat("%s\n-%s\n-%s", this.Description(), this.TimePriceOpenDescription(), this.TimePriceCloseDescription());
|
|
for(int i=0; i<this.m_list_deals.Total(); i++)
|
|
{
|
|
CDeal *deal=this.m_list_deals.At(i);
|
|
if(deal==NULL)
|
|
continue;
|
|
deal.Print();
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|