Вопросы от начинающих MQL5 MT5 MetaTrader 5 - страница 713
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Подскажите, как узнать результат последней одной или нескольких сделок?
Есть два пути:
прямо в советнике использовать OnTradeTransaction() и отлавливать сделки, которые были записаны в историю.
//| TradeTransaction function |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
//--- get transaction type as enumeration value
ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in history
if(type==TRADE_TRANSACTION_DEAL_ADD)
{
long deal_entry =0;
double deal_profit =0.0;
double deal_volume =0.0;
string deal_symbol ="";
long deal_magic =0;
if(HistoryDealSelect(trans.deal))
{
deal_entry=HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
deal_profit=HistoryDealGetDouble(trans.deal,DEAL_PROFIT);
deal_volume=HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
deal_symbol=HistoryDealGetString(trans.deal,DEAL_SYMBOL);
deal_magic=HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
}
else
return;
if(deal_symbol==Symbol() && deal_magic==m_magic)
if(deal_entry==DEAL_ENTRY_OUT)
{
// здесь ваши действия
}
}
}
или обращаться к торговой истории, например что-то вроде этого:
//| HistorySelect.mq5 |
//| Copyright © 2016, Vladimir Karputov |
//| http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link "http://wmua.ru/slesar/"
#property version "1.00"
#property description "Реверс позиции и исследование \"DEAL_POSITION_ID\" истории сделок"
#property script_show_inputs
//---
input datetime start=D'2016.08.05 09:00:00';
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
if(AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING)
{
Print("This script cannot be run on a hedge; Этот скрипт нельзя запускать на хедж");
return;
}
Print_IDs();
}
//+------------------------------------------------------------------+
//| List all positions and deals |
//+------------------------------------------------------------------+
void Print_IDs(void)
{
//--- запрашиваем историю сделок и ордеров за указанный период серверного времени
HistorySelect(start,TimeCurrent()+86400);
uint total =HistoryDealsTotal(); // количество сделок в истории
ulong ticket =0; // тикет сделки в истории
long type =0; // тип сделки
long deal_id=0; // идентификатор позиции, в открытии, изменении или закрытии которой участвовала эта сделка
double volume =0.0; // объём сделки
double profit =0.0; // финансовый результат сделки
double price =0.0; // цена сделки
string symbol =NULL; // имя символа, по которому произведена сделка
long entry =0; // направление сделки – вход в рынок, выход из рынка или разворот
//--- for all deals
for(uint i=0;i<total;i++)
{
//--- try to get deals ticket
if((ticket=HistoryDealGetTicket(i))>0)
{
//--- get deals properties
type =HistoryDealGetInteger(ticket,DEAL_TYPE);
deal_id =HistoryDealGetInteger(ticket,DEAL_POSITION_ID);
volume =HistoryDealGetDouble(ticket,DEAL_VOLUME);
profit =HistoryDealGetDouble(ticket,DEAL_PROFIT);
price =HistoryDealGetDouble(ticket,DEAL_PRICE);
symbol =HistoryDealGetString(ticket,DEAL_SYMBOL);
entry =HistoryDealGetInteger(ticket,DEAL_ENTRY);
Print(EnumToString((ENUM_DEAL_ENTRY)entry),
", type ",EnumToString((ENUM_DEAL_TYPE)type),
", price ",DoubleToString(price,Digits()),
", Deal ",symbol," volume ",DoubleToString(volume,2),
", DEAL_POSITION_ID #",deal_id,
", profit ",DoubleToString(profit,2));
}
}
Print("");
}
//+------------------------------------------------------------------+
В зависимости от того, какой метод Вы выберите, нужно будет немного редактировать код - для получения информации об последней сделке.
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
if (trans.type == TRADE_TRANSACTION_DEAL_ADD && trans.symbol == _Symbol)
{
if (!HistoryOrderSelect(trans.order)) printf("Ордер не найден");
if (order.Magic() != MagicNumber) printf("Ошибка: магик неправильный %u",order.Magic());
}
}
Обработчик события отслеживает все сделки с магиками советника.
Но почему то для первой сделки всегда магик (получаю через хисториордер) неправильный приходит (нулевой), для следующих сделок - все нормально.
Как исправить? Или может по-другому сделать в принципе?
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
if (trans.type == TRADE_TRANSACTION_DEAL_ADD && trans.symbol == _Symbol)
{
if (!HistoryOrderSelect(trans.order)) printf("Ордер не найден");
if (order.Magic() != MagicNumber) printf("Ошибка: магик неправильный %u",order.Magic());
}
}
Обработчик события отслеживает все сделки с магиками советника.
Но почему то для первой сделки всегда магик (получаю через хисториордер) неправильный приходит (нулевой), для следующих сделок - все нормально.
Как исправить? Или может по-другому сделать в принципе?
Обработчик события отслеживает все сделки с магиками советника.
Но почему то для первой сделки всегда магик (получаю через хисториордер) неправильный приходит (нулевой), для следующих сделок - все нормально.
ну так выведите параметры этой сделки.
в чем проблема узнать её тикет/тип/символ/профит ?
ну так выведите параметры этой сделки.
в чем проблема узнать её тикет/тип/символ/профит ?
Выдает:
Сделка 2, Magic 0, Volume 0.000000
Вообще по всем сделкам выдает правильный номер, но нулевые магики и объемы.
printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());
Выдает:
Сделка 2, Magic 0, Volume 0.000000
Вообще по всем сделкам выдает правильный номер, но нулевые магики и объемы.
printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());
Добавьте вот этот код:
//| TradeTransaction function |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
//--- получим тип транзакции в виде значения перечисления
ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
Print(EnumToString(type));
long deal_type =0;
long deal_positions_id =0;
long deal_ticket =0;
double deal_volume =0;
long deal_entry =0;
long deal_magic =0;
string deal_symbol ="";
string deal_comment ="";
if(HistoryDealSelect(trans.deal))
{
deal_type =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
deal_positions_id =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);
deal_ticket =HistoryDealGetInteger(trans.deal,DEAL_TICKET);
deal_volume =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
deal_entry =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
deal_magic =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
deal_symbol =HistoryDealGetString(trans.deal,DEAL_SYMBOL);
deal_comment =HistoryDealGetString(trans.deal,DEAL_COMMENT);
Print("D_TYPE: ",EnumToString((ENUM_DEAL_TYPE)deal_type),", ",
"D_POSITION_ID: ",deal_positions_id,", ",
"D_TICKET: ",deal_ticket,", ",
"D_VOLUME: ",DoubleToString(deal_volume,2),", ",
"D_ENTRY: ",EnumToString((ENUM_DEAL_ENTRY)deal_entry),", ",
"_MAGIC: ",deal_magic,", ",
"D_SYMBOL: ",deal_symbol,", ",
"D_COMMENT: ",deal_comment);
}
else
return;
}
и Вы увидите какие типы транзакций происходят, а также увидите, что при "TRADE_TRANSACTION_DEAL_ADD" виден и магик и объём.
Добавьте вот этот код:
//| TradeTransaction function |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
//--- получим тип транзакции в виде значения перечисления
ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
Print(EnumToString(type));
long deal_type =0;
long deal_positions_id =0;
long deal_ticket =0;
double deal_volume =0;
long deal_entry =0;
long deal_magic =0;
string deal_symbol ="";
string deal_comment ="";
if(HistoryDealSelect(trans.deal))
{
deal_type =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
deal_positions_id =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);
deal_ticket =HistoryDealGetInteger(trans.deal,DEAL_TICKET);
deal_volume =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
deal_entry =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
deal_magic =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
deal_symbol =HistoryDealGetString(trans.deal,DEAL_SYMBOL);
deal_comment =HistoryDealGetString(trans.deal,DEAL_COMMENT);
Print("D_TYPE: ",EnumToString((ENUM_DEAL_TYPE)deal_type),", ",
"D_POSITION_ID: ",deal_positions_id,", ",
"D_TICKET: ",deal_ticket,", ",
"D_VOLUME: ",DoubleToString(deal_volume,2),", ",
"D_ENTRY: ",EnumToString((ENUM_DEAL_ENTRY)deal_entry),", ",
"_MAGIC: ",deal_magic,", ",
"D_SYMBOL: ",deal_symbol,", ",
"D_COMMENT: ",deal_comment);
}
else
return;
}
и Вы увидите какие типы транзакций происходят, а также увидите, что при "TRADE_TRANSACTION_DEAL_ADD" виден и магик и объём.
Выдает:
Сделка 2, Magic 0, Volume 0.000000
Вообще по всем сделкам выдает правильный номер, но нулевые магики и объемы.
printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());
Д Я уже давно заметил что при использовании класса CDealInfo нужно самостоятельно подгружать историю сделок, тогда все функционитрует нормально
{
HistorySelect(0,TimeCurrent());
deal.Ticket(trans.deal);
printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());
}
Спасибо, так работает.
Чтобы не печатать все типы транзакций сделайте в OnTradeTransaction такое условие:
ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
if(type!=TRADE_TRANSACTION_DEAL_ADD)
return;
long deal_type =0;
то есть, если тип транзакции не "TRADE_TRANSACTION_DEAL_ADD" - значит выходим.
Если нужно отследить размещение (не срабатывание, а именно размещение) отложенного ордера, то OnTradeTransaction примет такой вид:
//| TradeTransaction function |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
//--- get transaction type as enumeration value
ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
Print(EnumToString(type));
//--- if transaction is result of addition of the transaction in history
if(type==TRADE_TRANSACTION_ORDER_ADD)
{
long order_type =0;
double order_price =0.0;
double order_volume =0.0;
string order_symbol ="";
long order_magic =0;
if(OrderSelect(trans.order)) // select pending orders
{
order_type=OrderGetInteger(ORDER_TYPE);
order_price=OrderGetDouble(ORDER_PRICE_OPEN);
order_volume=OrderGetDouble(ORDER_VOLUME_INITIAL);
order_symbol=OrderGetString(ORDER_SYMBOL);
order_magic=OrderGetInteger(ORDER_MAGIC);
}
else
return;
if(order_symbol==m_symbol.Name() && order_magic==m_magic)
{
if(order_type==ORDER_TYPE_BUY_LIMIT)
{
//
}
if(order_type==ORDER_TYPE_SELL_LIMIT)
{
//
}
}
}
}
С использованием OnTradeTransaction странно изменилось время оптимизации. Система на 15М, очень простая, история годовая, один прогон происходит за 0,3 - 0,4 секунды.
После запуска оптимизации первые 200-300 прогонов идут со скоростью меньше секунды, следующие замедляются вплоть до 15-20 секунд (в 50 раз!);
Перегрева процессора и троттлинга нет, памяти свободно больше половины (из 16 ГБ).
До использования обработчика OnTradeTransaction ничего подобного не было - даже более сложные советники на мелких таймфреймах оптимизировались с примерно одинаковой скоростью каждый прогон.
Это HistoryDealSelect так сильно влияет на скорость? Как можно ликвидировать тормоза?
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
if( trans.type != TRADE_TRANSACTION_DEAL_ADD) return;
ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
long deal_type =0;
double deal_volume =0;
long deal_magic =0;
if(HistoryDealSelect(trans.deal))
{
deal_type =HistoryDealGetInteger(trans.deal,DEAL_TYPE);
deal_volume =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
deal_magic =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
}
else
return;
if (deal_type == DEAL_TYPE_BUY && deal_magic == MagicNumber) current_position += deal_volume;
if (deal_type == DEAL_TYPE_SELL && deal_magic == MagicNumber) current_position -= deal_volume;
}