#property description "Expert Advisor per inviare richieste di trade "
" usando la duznione OrderSendAsync().\r\n"
#property description "Handling degli eventi di trading usando"
" le funzioni handler OnTrade() ed OnTradeTransaction() (viene visualizzato)\r\n"
#property description "I parametri dell' Expert Advisor consentono di impostare il Magic Number"
" (ID univoco) "
#property description "e la modalità di visualizzazione dei messaggi nell' Experts log. Tutti i dettagli vengono visualizzati per default.\r\n"
//--- parametri di input
input int MagicNumber=1234567; // ID Expert Advisor
input bool DescriptionModeFull=true; // Modalità dettagliata di output
//--- variabile per usare nella chiamata HistorySelect()
datetime history_start;
//+--------------------------------------------------------------------------------+
//| Funzione di inizializzazione dell' Expert |
//+--------------------------------------------------------------------------------+
int OnInit()
{
//--- controlla se l'autotrading è consentito
if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
{
Alert("L' Autotrading nel terminale è disabilitato, l' Expert Advisor verrà rimosso");
ExpertRemove();
return(-1);
}
//--- Non in grado di operare su un conto reale
if(AccountInfoInteger(ACCOUNT_TRADE_MODE)==ACCOUNT_TRADE_MODE_REAL)
{
Alert("L' Expert Advisor non può fare trading sun un account reale!");
ExpertRemove();
return(-2);
}
//--- verifica se è possibile fare trading su questo account (per esempio, il trading è impossibile quando si utilizza una password investitore)
if(!AccountInfoInteger(ACCOUNT_TRADE_ALLOWED))
{
Alert("Il trading su questo account è disabilitato");
ExpertRemove();
return(-3);
}
//--- salva l'orario di lancio dell'Expert Advisor per la ricezione della cronistoria di trading
history_start=TimeCurrent();
//---
CreateBuySellButtons();
return(INIT_SUCCEEDED);
}
//+--------------------------------------------------------------------------------+
//| Funzione deinizializzazione Expert |
//+--------------------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- elimina tutti gli oggetti grafici
ObjectDelete(0,"Buy");
ObjectDelete(0,"Sell");
//---
}
//+--------------------------------------------------------------------------------+
//| Funzione TradeTransaction |
//+--------------------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
//--- intestazione nominata dopo l'event handler della funzione di trading
Print("=> ",__FUNCTION__," at ",TimeToString(TimeCurrent(),TIME_SECONDS));
//--- riceve il tipo di transazione come valore dell'enumerazione
ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- se la trascrizione è il risultato di una richiesta di handling
if(type==TRADE_TRANSACTION_REQUEST)
{
//--- mostra il nome della transazione
Print(EnumToString(type));
//--- quindi mostra la descrizione della stringa della richiesta di handling
Print("------------RequestDescription\r\n",
RequestDescription(request,DescriptionModeFull));
//--- e mostra la desceizione del risultato della richiesta
Print("------------ ResultDescription\r\n",
TradeResultDescription(result,DescriptionModeFull));
}
else // mostra la descrizione completa della transazione per la transazione di altro tipo
{
Print("------------ TransactionDescription\r\n",
TransactionDescription(trans,DescriptionModeFull));
}
//---
}
//+--------------------------------------------------------------------------------+
//| Funzione di Trade |
//+--------------------------------------------------------------------------------+
void OnTrade()
{
//--- membro statico per la memorizzazione dello status dell'account di trading
static int prev_positions=0,prev_orders=0,prev_deals=0,prev_history_orders=0;
//--- richiesta cronistoria di trading
bool update=HistorySelect(history_start,TimeCurrent());
PrintFormat("HistorySelect(%s , %s) = %s",
TimeToString(history_start),TimeToString(TimeCurrent()),(string)update);
//--- intestazione nominata dopo l'event handler della funzione di trading
Print("=> ",__FUNCTION__," at ",TimeToString(TimeCurrent(),TIME_SECONDS));
//--- mostra il nome dell handler ed il numero di ordini al momento dell'handling
int curr_positions=PositionsTotal();
int curr_orders=OrdersTotal();
int curr_deals=HistoryOrdersTotal();
int curr_history_orders=HistoryDealsTotal();
//--- mostra il numero di ordini, posizioni, affari, così come cambi nelle parentesi
PrintFormat("PositionsTotal() = %d (%+d)",
curr_positions,(curr_positions-prev_positions));
PrintFormat("OrdersTotal() = %d (%+d)",
curr_orders,curr_orders-prev_orders);
PrintFormat("HistoryOrdersTotal() = %d (%+d)",
curr_deals,curr_deals-prev_deals);
PrintFormat("HistoryDealsTotal() = %d (%+d)",
curr_history_orders,curr_history_orders-prev_history_orders);
//--- inserisce il break di stringa per visualizzare il log più convenientemente
Print("");
//--- salva lo status dell' account
prev_positions=curr_positions;
prev_orders=curr_orders;
prev_deals=curr_deals;
prev_history_orders=curr_history_orders;
//---
}
//+--------------------------------------------------------------------------------+
//| Funzione ChartEvent |
//+--------------------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
//--- handling CHARTEVENT_CLICK event ("Click sul chart")
if(id==CHARTEVENT_OBJECT_CLICK)
{
Print("=> ",__FUNCTION__,": sparam = ",sparam);
//--- minimo volume per un affare
double volume_min=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
//--- se viene premuto il bottone "Buy", allora compra
if(sparam=="Buy")
{
PrintFormat("Buy %s %G lot",_Symbol,volume_min);
BuyAsync(volume_min);
//--- rilascia il bottone
ObjectSetInteger(0,"Buy",OBJPROP_STATE,false);
}
//--- se viene premuto il bottone "Sell", allora vende
if(sparam=="Sell")
{
PrintFormat("Sell %s %G lot",_Symbol,volume_min);
SellAsync(volume_min);
//--- rilascia il bottone
ObjectSetInteger(0,"Sell",OBJPROP_STATE,false);
}
ChartRedraw();
}
//---
}
//+--------------------------------------------------------------------------------+
//| Restituisce la descrizione testuale di una transazione |
//+--------------------------------------------------------------------------------+
string TransactionDescription(const MqlTradeTransaction &trans,
const bool detailed=true)
{
//--- prepara la stringa per la restituzione dalla funzione
string desc=EnumToString(trans.type)+"\r\n";
//--- tutti i possibili dati vengono aggiunti in modalità dettagliata
if(detailed)
{
desc+="Simbolo: "+trans.symbol+"\r\n";
desc+="Ticket dell'affare: "+(string)trans.deal+"\r\n";
desc+="Tipo dell'Affare: "+EnumToString(trans.deal_type)+"\r\n";
desc+="Ticket dell'Ordine: "+(string)trans.order+"\r\n";
desc+="Tipo dell'Ordine: "+EnumToString(trans.order_type)+"\r\n";
desc+="Status dell'Ordine: "+EnumToString(trans.order_state)+"\r\n";
desc+="Tipo di orario dell'Ordine: "+EnumToString(trans.time_type)+"\r\n";
desc+="Espirazione(scadenza) dell'Ordine: "+TimeToString(trans.time_expiration)+"\r\n";
desc+="Prezzo: "+StringFormat("%G",trans.price)+"\r\n";
desc+="Innesco del Prezzo: "+StringFormat("%G",trans.price_trigger)+"\r\n";
desc+="Stop Loss: "+StringFormat("%G",trans.price_sl)+"\r\n";
desc+="Take Profit: "+StringFormat("%G",trans.price_tp)+"\r\n";
desc+="Volume: "+StringFormat("%G",trans.volume)+"\r\n";
}
//--- restituisce una stringa ricevuta
return desc;
}
//+--------------------------------------------------------------------------------+
//| Restituisce la descrizione testuale della richiesta di trade |
//+--------------------------------------------------------------------------------+
string RequestDescription(const MqlTradeRequest &request,
const bool detailed=true)
{
//--- prepara la stringa per la restituzione dalla funzione
string desc=EnumToString(request.action)+"\r\n";
//--- aggiunge tutti i dati disponibili in modalità dettagliata
if(detailed)
{
desc+="Simbolo: "+request.symbol+"\r\n";
desc+="Magic Number: "+StringFormat("%d",request.magic)+"\r\n";
desc+="Ticket dell'Ordine: "+(string)request.order+"\r\n";
desc+="Tipo di Ordine: "+EnumToString(request.type)+"\r\n";
desc+="Riempimento dell'Ordine: "+EnumToString(request.type_filling)+"\r\n";
desc+="Tipo di orario dell'Ordine: "+EnumToString(request.type_time)+"\r\n";
desc+="Espirazione dell'Ordine: "+TimeToString(request.expiration)+"\r\n";
desc+="Prezzo: "+StringFormat("%G",request.price)+"\r\n";
desc+="Punti di Deviazione: "+StringFormat("%G",request.deviation)+"\r\n";
desc+="Stop Loss: "+StringFormat("%G",request.sl)+"\r\n";
desc+="Take Profit: "+StringFormat("%G",request.tp)+"\r\n";
desc+="Stop Limit: "+StringFormat("%G",request.stoplimit)+"\r\n";
desc+="Volume: "+StringFormat("%G",request.volume)+"\r\n";
desc+="Commento: "+request.comment+"\r\n";
}
//--- restituisce la stringa ricevuta
return desc;
}
//+--------------------------------------------------------------------------------+
//| Restituisce la descrizione testuale del risultato della richiesta di handling |
//+--------------------------------------------------------------------------------+
string TradeResultDescription(const MqlTradeResult &result,
const bool detailed=true)
{
//--- prepara la stringa per il ritorno dalla funzione
string desc="Retcode "+(string)result.retcode+"\r\n";
//--- aggiunge tutti i dati disponibili in modalità dettagliata
if(detailed)
{
desc+="ID della Richiesta: "+StringFormat("%d",result.request_id)+"\r\n";
desc+="Ticket dell'Ordine: "+(string)result.order+"\r\n";
desc+="Ticket dell'Affare: "+(string)result.deal+"\r\n";
desc+="Volume: "+StringFormat("%G",result.volume)+"\r\n";
desc+="Prezzo: "+StringFormat("%G",result.price)+"\r\n";
desc+="Ask: "+StringFormat("%G",result.ask)+"\r\n";
desc+="Bid: "+StringFormat("%G",result.bid)+"\r\n";
desc+="Commento: "+result.comment+"\r\n";
}
//--- restituisce la stringa ricevuta
return desc;
}
//+--------------------------------------------------------------------------------+
//| Crea due bottoni per l'acquisto e la vendita |
//+--------------------------------------------------------------------------------+
void CreateBuySellButtons()
{
//--- controlla l'oggetto nominato "Buy"
if(ObjectFind(0,"Buy")>=0)
{
//--- se l'oggetto trovato non è un bottone, lo elimina
if(ObjectGetInteger(0,"Buy",OBJPROP_TYPE)!=OBJ_BUTTON)
ObjectDelete(0,"Buy");
}
else
ObjectCreate(0,"Buy",OBJ_BUTTON,0,0,0); // crea il bottone "Buy"
//--- configura il bottone "Sell"
ObjectSetInteger(0,"Buy",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
ObjectSetInteger(0,"Buy",OBJPROP_XDISTANCE,100);
ObjectSetInteger(0,"Buy",OBJPROP_YDISTANCE,50);
ObjectSetInteger(0,"Buy",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"Buy",OBJPROP_YSIZE,30);
ObjectSetString(0,"Buy",OBJPROP_TEXT,"Buy");
ObjectSetInteger(0,"Buy",OBJPROP_COLOR,clrRed);
//--- controlla la presenza di un oggetto chiamato "Sell"
if(ObjectFind(0,"Sell")>=0)
{
//--- se l'oggetto trovato non è un bottone, lo elimina
if(ObjectGetInteger(0,"Sell",OBJPROP_TYPE)!=OBJ_BUTTON)
ObjectDelete(0,"Sell");
}
else
ObjectCreate(0,"Sell",OBJ_BUTTON,0,0,0); // crea il bottone "Sell"
//--- configura il bottone "Sell"
ObjectSetInteger(0,"Sell",OBJPROP_CORNER,CORNER_RIGHT_UPPER);
ObjectSetInteger(0,"Sell",OBJPROP_XDISTANCE,100);
ObjectSetInteger(0,"Sell",OBJPROP_YDISTANCE,100);
ObjectSetInteger(0,"Sell",OBJPROP_XSIZE,70);
ObjectSetInteger(0,"Sell",OBJPROP_YSIZE,30);
ObjectSetString(0,"Sell",OBJPROP_TEXT,"Sell");
ObjectSetInteger(0,"Sell",OBJPROP_COLOR,clrBlue);
//--- esegue l'aggiornamento forzato del chart per visualizzare i bottoni immediatamente
ChartRedraw();
//---
}
//+--------------------------------------------------------------------------------+
//| Compra usando la funzione asincrona OrderSendAsync() |
//+--------------------------------------------------------------------------------+
void BuyAsync(double volume)
{
//--- prepara la richiesta
MqlTradeRequest req={};
req.action =TRADE_ACTION_DEAL;
req.symbol =_Symbol;
req.magic =MagicNumber;
req.volume =0.1;
req.type =ORDER_TYPE_BUY;
req.price =SymbolInfoDouble(req.symbol,SYMBOL_ASK);
req.deviation =10;
req.comment ="Buy(compra), usando OrderSendAsync()";
MqlTradeResult res={};
if(!OrderSendAsync(req,res))
{
Print(__FUNCTION__,": error ",GetLastError(),", retcode = ",res.retcode);
}
//---
}
//+--------------------------------------------------------------------------------+
//| Vende usando la funzione asincrona OrderSendAsync() |
//+--------------------------------------------------------------------------------+
void SellAsync(double volume)
{
//--- prepara la richiesta
MqlTradeRequest req={};
req.action =TRADE_ACTION_DEAL;
req.symbol =_Symbol;
req.magic =MagicNumber;
req.volume =0.1;
req.type =ORDER_TYPE_SELL;
req.price =SymbolInfoDouble(req.symbol,SYMBOL_BID);
req.deviation =10;
req.comment ="Sell(vende) usando OrderSendAsync()";
MqlTradeResult res={};
if(!OrderSendAsync(req,res))
{
Print(__FUNCTION__,": error ",GetLastError(),", retcode = ",res.retcode);
}
//---
}
//+--------------------------------------------------------------------------------+
|