//+------------------------------------------------------------------+ //| TradeTransaction function | //+------------------------------------------------------------------+ voidOnTradeTransaction(constMqlTradeTransaction &trans, constMqlTradeRequest &request, constMqlTradeResult &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) { // здесь ваши действия } } }
//--- получим тип транзакции в виде значения перечисления ENUM_TRADE_TRANSACTION_TYPE type=trans.type; if(type!=TRADE_TRANSACTION_DEAL_ADD) return; long deal_type =0;
你能告诉我如何知道最后一个或多个交易的结果吗?
有两种方法。
在专家顾问中直接使用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());
}
}
该事件处理程序记录了所有与EA的神奇交易。
但由于某些原因,第一笔交易总是得到一个错误的魔术师(零),而后面的交易却很好。
我怎样才能纠正它?或者,也许我应该用另一种方式来做?
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());
}
}
事件处理程序监控所有的交易与EA的magiks。
但由于某些原因,第一笔交易总是得到一个错误的魔术师(零),而后面的交易却很好。
我怎样才能纠正它?或者,也许我应该用另一种方式来做?
该事件处理程序记录了所有与EA的神奇交易。
但由于某些原因,对于第一笔交易,魔术师(通过chistoriorder收到)总是错误的(零),对于接下来的交易 - 一切正常。
所以打印这个交易的参数。
知道它的门票/类型/符号/利润有什么问题?
所以要打印这个交易的参数。
找出它的票据/类型/符号/利润的问题是什么?
输出。
交易2,魔法0,成交量0.000000
一般来说,在所有的交易中,它显示了一个正确的数字,但弹夹和容量为零。
printf("Сделка %f, Magic %u, Volume %f", trans.deal,deal.Magic(),deal.Volume());
输出。
交易2,魔法0,成交量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_AD "下,魔法和数量都是可见的。
添加这个代码。
//| 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_AD "下,magik和volume都是可见的。
输出。
交易2,魔法0,成交量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_AD"--则退出。
如果我们需要跟踪一个挂单的下达(不是触发,只是下达),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的使用,优化的时间发生了奇怪的变化。15M上的一个系统,非常简单,每年的历史,一次运行发生在0.3-0.4秒。
优化开始后,前200-300次的运行速度不到一秒,接下来的运行速度减慢到15-20秒(50次!)。
没有出现处理器过热或跑偏的情况,一半以上的内存是免费的(从16GB开始)。
在使用OnTradeTransaction处理程序之前,没有这样的情况--即使是小时间段上更复杂的EA,每次运行的速度也大致相同。
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;
}