Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Да никак нельзя определить. SL и TP - сущность исключительно MT-сервера.
Вот так работает:
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
if(trans.type==TRADE_TRANSACTION_DEAL_ADD)
{
datetime end=TimeCurrent();
datetime start=end-end%PeriodSeconds(PERIOD_D1);
ResetLastError();
if(!HistorySelect(start,end))
{
Print("Getting deals history failed. Error ",GetLastError());
return;
}
ulong ticket=HistoryDealGetTicket(HistoryDealsTotal()-1);
if(ticket==trans.deal)
{
if(HistoryDealGetInteger(ticket,DEAL_ENTRY)==DEAL_ENTRY_OUT &&
(StringFind(HistoryDealGetString(ticket,DEAL_COMMENT),"tp")!=-1
|| StringFind(HistoryDealGetString(ticket,DEAL_COMMENT),"sl")!=-1))
{
Print(HistoryDealGetString(ticket,DEAL_SYMBOL)," Profit= ",HistoryDealGetDouble(ticket,DEAL_PROFIT)," ticket=",ticket);
}
}
}
}
{
if ((Trans.type == TRADE_TRANSACTION_ORDER_ADD) &&
PositionSelectByTicket(Trans.position) && OrderSelect(Trans.order) &&
(PositionGetInteger(POSITION_TYPE) == 1 - OrderGetInteger(ORDER_TYPE)))
{
const double Price = OrderGetDouble(ORDER_PRICE_OPEN);
if (Price == PositionGetDouble(POSITION_TP))
Print("Position #" + (string)Trans.position + " - triggered TP.");
else if (Price == PositionGetDouble(POSITION_SL))
Print("Position #" + (string)Trans.position + " - triggered SL.");
}
}
Рабочий вариант для реала (не для тестера)
{
if ((Trans.type == TRADE_TRANSACTION_ORDER_ADD) &&
PositionSelectByTicket(Trans.position) && OrderSelect(Trans.order) &&
(PositionGetInteger(POSITION_TYPE) == 1 - OrderGetInteger(ORDER_TYPE)))
{
const double Price = OrderGetDouble(ORDER_PRICE_OPEN);
if (Price == PositionGetDouble(POSITION_TP))
Print("Position #" + (string)Trans.position + " - triggered TP.");
else if (Price == PositionGetDouble(POSITION_SL))
Print("Position #" + (string)Trans.position + " - triggered SL.");
}
}
Проверил в тестере - не работает, думаю и на реале работать не будет, поскольку позиции по которой идет проверка уже не существует.
{
string s = DoubleToString(PosTotalCommissSwap (Symbol (), true, true), 4);
Comment (s);
}
//+------------------------------------------------------------------+
// Подсчет комиссий и свопов указанной позиции по символу
double PosTotalCommissSwap (string symb, bool commiss, bool swap)
{
int posTotal = PositionsTotal (); //всего открытых позиций
Print (posTotal);
//пройдем по всем открытым позициям
for(int i = posTotal - 1; i >=0; i--)
{
string posSymb = PositionGetSymbol (i);
Print (posSymb);
//если найдена позиция по указанному символу
if(symb == posSymb)
{
Print ("Позиция найдена");
long posID = PositionGetInteger (POSITION_IDENTIFIER);
//выберем историю сделок, относящуюся к выбранной позиции
if(HistorySelectByPosition (posID))
{
int dealsTotal = HistoryDealsTotal (); //всего сделок в истории позиции
Print ("Всего сделок в позиции: " + dealsTotal);
double fees = 0.0; //все комиссии и свопы
//пройдем по всем сделкам позиции
for(int k = 0; k < dealsTotal; k++)
{
ulong dealTicket = HistoryDealGetTicket (k); //тикет сделки
if(commiss)
fees += HistoryDealGetDouble (dealTicket, DEAL_COMMISSION);
if(swap)
fees += HistoryDealGetDouble (dealTicket, DEAL_SWAP);
}
return (fees);
}
else
Print ("Историю сделок выбрать не удалось");
}
}
return (0.0);
}
Похоже поломался выбор истории сделок по идентификатору позиции.
Принт иногда (а иногда и нет) пишет
2016.12.05 11:26:11.767 Get current commission of pos (GBPUSD,M5) 1
2016.12.05 11:26:11.767 Get current commission of pos (GBPUSD,M5) GBPUSD
2016.12.05 11:26:11.767 Get current commission of pos (GBPUSD,M5) Позиция найдена
2016.12.05 11:26:11.767 Get current commission of pos (GBPUSD,M5) Всего сделок в позиции: 0
Похоже поломался выбор истории сделок по идентификатору позиции.
Если это происходит после OrderSend, то нормально.
Нет, это никак не нормально. В любом случае позиция есть, а значит и есть сделки которые участвовали в её "жизни". Но более странно то, что сделки код не видит даже если кинуть советник уже при наличии позиции...
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Как правильно работать в MT5 с OrderSend
fxsaber, 2016.11.19 23:59
Выдрал из библиотеки сюда синхронизированный OrderSendSyncconst bool IsTester = (::MQLInfoInteger(MQL_TESTER) || ::MQLInfoInteger(MQL_OPTIMIZATION) ||
::MQLInfoInteger(MQL_VISUAL_MODE) || ::MQLInfoInteger(MQL_FRAME_MODE));
bool Waiting( const bool FlagInit = false )
{
static ulong StartTime = 0;
if (FlagInit)
StartTime = ::GetMicrosecondCount();
const bool Res = (::GetMicrosecondCount() - StartTime < OrderSend_MaxPause);
if (Res)
::Sleep(0);
return(Res);
}
bool EqualPrices( const double Price1, const double Price2, const int digits)
{
return(::NormalizeDouble(Price1 - Price2, digits) == 0);
}
#define WHILE(A) while (!(Res = (A)) && Waiting())
bool OrderSendSync( const MqlTradeRequest &Request, MqlTradeResult &Result )
{
bool Res = ::OrderSend(Request, Result);
if (Res && !IsTester && (Result.retcode < TRADE_RETCODE_ERROR) && (OrderSend_MaxPause > 0))
{
Res = (Result.retcode == TRADE_RETCODE_DONE);
Waiting(true);
if (Request.action == TRADE_ACTION_DEAL)
{
WHILE(::HistoryOrderSelect(Result.order))
;
Res = Res && (((ENUM_ORDER_STATE)::HistoryOrderGetInteger(Result.order, ORDER_STATE) == ORDER_STATE_FILLED) ||
((ENUM_ORDER_STATE)::HistoryOrderGetInteger(Result.order, ORDER_STATE) == ORDER_STATE_PARTIAL));
if (Res)
WHILE(::HistoryDealSelect(Result.deal))
;
}
else if (Request.action == TRADE_ACTION_PENDING)
{
if (Res)
WHILE(::OrderSelect(Result.order))
;
else
{
WHILE(::HistoryOrderSelect(Result.order))
;
Res = false;
}
}
else if (Request.action == TRADE_ACTION_SLTP)
{
if (Res)
{
bool EqualSL = false;
bool EqualTP = false;
const int digits = (int)::SymbolInfoInteger(Request.symbol, SYMBOL_DIGITS);
if ((Request.position == 0) ? ::PositionSelect(Request.symbol) : ::PositionSelectByTicket(Request.position))
{
EqualSL = EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
EqualTP = EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
}
WHILE((EqualSL && EqualTP))
if ((Request.position == 0) ? ::PositionSelect(Request.symbol) : ::PositionSelectByTicket(Request.position))
{
EqualSL = EqualPrices(::PositionGetDouble(POSITION_SL), Request.sl, digits);
EqualTP = EqualPrices(::PositionGetDouble(POSITION_TP), Request.tp, digits);
}
}
}
else if (Request.action == TRADE_ACTION_MODIFY)
{
if (Res)
{
bool EqualSL = false;
bool EqualTP = false;
const int digits = (int)::SymbolInfoInteger(Request.symbol, SYMBOL_DIGITS);
if (::OrderSelect(Result.order))
{
EqualSL = EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
EqualTP = EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
}
WHILE((EqualSL && EqualTP))
if (::OrderSelect(Result.order))
{
EqualSL = EqualPrices(::OrderGetDouble(ORDER_SL), Request.sl, digits);
EqualTP = EqualPrices(::OrderGetDouble(ORDER_TP), Request.tp, digits);
}
}
}
else if (Request.action == TRADE_ACTION_REMOVE)
if (Res)
WHILE(::HistoryOrderSelect(Result.order))
;
}
return(Res);
}
#undef WHILE
Если будете использовать этот OrderSend, то проблем таких не возникнет.
Либо ждите соответствующих сообщений в OnTradeTransaction.
Ренат говорит, что это нормально, не спорьте! Вот решение для OrderSend
Если будете использовать этот OrderSend, то проблем таких не возникнет.
Либо ждите соответствующих сообщений в OnTradeTransaction.
Да нет же, это ненормально.
Позиция есть. Кидаем советник на чарт. Истории сделок по выбранной позиции нет. Что же тут нормального то?)))