Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 122
Vous manquez des opportunités de trading :
- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Inscription
Se connecter
Vous acceptez la politique du site Web et les conditions d'utilisation
Si vous n'avez pas de compte, veuillez vous inscrire
J'ai décidé d'ajouter à la question précédente.
1)
Supposons que j'ai un signal - lorsque le spread s'élargit fortement (aux nouvelles).
Fermer toutes les transactions en cours
Mais les ordres ne se contenteront pas de se fermer ou de s'ouvrir pendant les nouvelles.
Par conséquent, si nous prenons une commande, disons, OrderClose, la mettons dans une boucle + Sleep (3000) et l'exécutons jusqu'à ce qu'elle se ferme
2)
Si nous lions une variable interne dans le bouton et assignons la valeur appuyé/fermé à la possibilité d'ouverture de l'ordre, cela fonctionnera-t-il en temps réel ?
J'ai décidé d'ajouter à la question précédente.
1)
Supposons que j'ai un signal - lorsque le spread s'élargit fortement (aux nouvelles).
Fermer toutes les transactions en cours
Mais les ordres ne se contenteront pas de se fermer ou de s'ouvrir pendant les actualités.
Par conséquent, si nous prenons une commande, disons, OrderClose, la mettons dans une boucle + Sleep (3000) et l'exécutons jusqu'à ce qu'elle se ferme
2)
Si nous lions une variable interne dans le bouton et assignons la valeur appuyé/fermé à la possibilité d'ouverture de l'ordre, cela fonctionnera-t-il en temps réel ?
Salutations, j'écris un indicateur qui dessine l'historique des commandes sur un graphique, code:
//| history.mq4 |
//| Copyright 2017, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#property indicator_chart_window
extern int MagicNumber = 1110;
extern datetime HistoryOrdersFromDateTime = 0;
extern color SellColor = clrRed;
extern color BuyColor = clrBlue;
extern color ProfitColor = clrWhite;
extern bool DeleteHistoryOrders = false;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
void start()
{
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
{
if(HistoryOrdersFromDateTime<OrderCloseTime())
{
if((TimeCurrent()-OrderCloseTime())>60)
HistoryOrders();
}
}
}
}
void HistoryOrders()
{
double b=OrderOpenPrice(), d=OrderClosePrice(), lots=OrderLots(), Profit=0;
datetime a=OrderOpenTime(), c=OrderCloseTime(), close_time;
string Ticket=(string)OrderTicket(), type="Sell", symbol=OrderSymbol(), comment=OrderComment(), Background;
color col=SellColor;
if(OrderType()==0) {col=BuyColor; type="Buy";}
if(DeleteHistoryOrders==false)
{
//Начальная точка
ObjectCreate("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJ_ARROW,0,a,b);
ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJPROP_COLOR,col);
ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+"\n"+comment,OBJPROP_ARROWCODE,1);
//Линия
ObjectCreate("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJ_TREND,0,a,b,c,d);
ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_COLOR,col);
ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_WIDTH,1);
ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_STYLE,STYLE_DOT);
ObjectSet("#"+Ticket+" "+DoubleToString(b,Digits)+" -> "+DoubleToString(d,Digits),OBJPROP_RAY,0);
//Конечная точка
ObjectCreate("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJ_ARROW,0,c,d);
ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJPROP_COLOR,col);
ObjectSet("#"+Ticket+" "+type+" "+DoubleToString(lots,2)+" "+symbol+" at "+DoubleToString(b,Digits)+" close at "+DoubleToString(d,Digits),OBJPROP_ARROWCODE,3);
//Расчет профита
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
{
close_time=OrderCloseTime();
//60 секунд разницы между закрытием первого и последнего ордера в сетке
if(c<=close_time+60 && c>=close_time-60)
{
Profit+=OrderProfit()+OrderCommission()+OrderSwap();
Ticket=(string)OrderTicket();
}
}
}
//Размер фона
for(int i=2; i<StringLen(DoubleToString(Profit,2)); i++)
StringAdd(Background,"g");
//Фон профита
ObjectCreate("#"+Ticket+" Background",OBJ_TEXT,0,c,d);
ObjectSet("#"+Ticket+" Background",OBJPROP_ANCHOR,ANCHOR_LOWER);
ObjectSetText("#"+Ticket+" Background",Background,10,"Webdings",col);
ObjectSet("#"+Ticket+" Background",OBJPROP_PRICE1,d);
ObjectSet("#"+Ticket+" Background",OBJPROP_TIME1,c+Period());
//Профит
ObjectCreate("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJ_TEXT,0,c,d);
ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_ANCHOR,ANCHOR_LOWER);
ObjectSetText("#"+Ticket+" Profit: "+DoubleToString(Profit,2),DoubleToString(Profit,2),10,"Arial",ProfitColor);
ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_PRICE1,d);
ObjectSet("#"+Ticket+" Profit: "+DoubleToString(Profit,2),OBJPROP_TIME1,c+Period());
} else ObjectsDeleteAll(0, "#"+Ticket+" ");
}
void OnDeinit(const int reason)
{
//Удалаение истории ордеров
for(int i=0; i<OrdersHistoryTotal(); i++)
{
DeleteHistoryOrders=true;
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol())
HistoryOrders();
}
}
L'indicateur dessine correctement les transactions individuelles (ligne>arrière-plan>profit), mais il y a un petit "bug" dans l'affichage des ensembles d'ordres fermés (capture d'écran jointe), les lignes sont superposées sur l'arrière-plan et le profit (ligne(1)>arrière-plan>profit>ligne(2)>ligne(3)>ligne(4) .. . .).
Il devrait se présenter comme suit : (ligne(1)>ligne(2)>ligne(3)>ligne(4) . . . . >fon>profit). Les diverses manipulations n'ont pas abouti, merci d'aider à les affiner.
Bonjour, j'écris un indicateur qui affiche l'historique des commandes sur un graphique,
L'indicateur rend correctement une transaction unique (ligne>arrière-plan>profit), mais dans l'affichage d'un ensemble d'ordres fermés il y a un petit "shoosh" (je joins une capture d'écran), les lignes (ligne(1)>arrière-plan>profit>ligne(2)>ligne(3)>ligne(4) ... . ).
Il devrait être le suivant : (ligne(1)>ligne(2)>ligne(3)>ligne(4) . . . . >fon>profit). Les diverses manipulations n'ont pas abouti, merci d'aider à les affiner.
Essayez d'attribuer la propriété OBJPROP_BACK aux lignes et aux icônes en arrière-plan.
Ce n'est pas une option, donc les lignes sont en arrière-plan (derrière les chandeliers), et le dessin devrait être au-dessus des chandeliers : chandeliers>lignes>profit>profit arrière-plan
Au passage, cela permet de se débarrasser d'un cycle supplémentaire pour le calcul des bénéfices.
Vous pouvez le faire
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
{
close_time=OrderCloseTime();
//60 секунд разницы между закрытием первого и последнего ордера в сетке
if(c<=close_time+60 && c>=close_time-60)
{
Profit+=OrderProfit()+OrderCommission()+OrderSwap();
Ticket=(string)OrderTicket();
}
}
}
ps S'il vous plaît. Placez une photo avec ce bouton
Ensuite, seulement la séquence de dessin sur le tableau. Ou bien, lorsque l'on dessine l'arrière-plan et le profit, il faut vérifier la disponibilité de ces objets par temps, lire la valeur du profit dans l'objet OBJ_TEXT et l'ajouter au profit de l'ordre en cours. Ensuite, nous devrions supprimer l'arrière-plan et le profit et les dessiner à nouveau.
À propos, cela élimine la nécessité d'un cycle supplémentaire pour le calcul du bénéfice.
Vous définissez le bénéfice au départ, en même temps que tous les autres paramètres de la commande.
Comment puis-je définir cette séquence de dessin, disons, dessiner d'abord tous les points et les lignes qui les relient, puis procéder au dessin du fond et du profit ?
Comment puis-je définir cette séquence de dessin, disons, dessiner d'abord tous les points et les lignes qui les relient, puis procéder au dessin du fond et du profit ?
Vous feriez mieux d'envisager cette variante.
ObjectFind() puis si l'objet est trouvé ObjectGetString() le convertit de texte en nombre, ajoute le bénéfice de la dernière commande à la valeur obtenue, supprime le OBJ_TEXT obsolète et en dessine un nouveau.
Si c'est le premier ou le seul ordre clôturé sur cette barre, nous dessinons simplement OBJ_TEXT et c'est tout.
Pour faciliter les choses, nous devrions spécifier l'heure d'ouverture du bar au lieu du ticket. Ou le ticket est nécessaire pour la suite des opérations ?
Eh bien, si je me fie à ma première supposition, c'est le cas. Et puis j'ai immédiatement eu une pensée impromptue et je n'ai pas supprimé la première phrase, mais je préfère la seconde.
Vous feriez mieux d'envisager cette variante.
ObjectFind() puis si l'objet est trouvé ObjectGetString() le convertit de texte en nombre, ajoute le bénéfice de la dernière commande à la valeur obtenue, supprime le OBJ_TEXT obsolète et en dessine un nouveau.
Si c'est le premier ou le seul ordre clôturé sur cette barre, nous dessinons simplement OBJ_TEXT et c'est tout.
Pour faciliter les choses, nous devrions spécifier l'heure d'ouverture du bar au lieu du ticket. Ou le ticket est nécessaire pour la suite des opérations ?
Oui, le billet est nécessaire pour l'analyse ultérieure de l'histoire. Merci pour le conseil sur le redécoupage. J'ai résolu le problème un peu plus facilement en ajoutant cette vérification et en redessinant le code :
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
{
close_time=OrderCloseTime();
//60 секунд разницы между закрытием первого и последнего ордера в сетке
if(c<=close_time+60 && c>=close_time-60)
{
Profit+=OrderProfit()+OrderCommission()+OrderSwap();
ProfitTicket=(string)OrderTicket();
CountOrders++;
}
}
}
//Перерисовка фона и профита
if(CountOrders>1)
{
ObjectDelete("#"+Ticket+" Background");
ObjectDelete("#"+Ticket+" Profit: "+DoubleToString(Profit,2));
Ticket=ProfitTicket;
}
Je ne sais pas si c'est correct, mais en principe cela dessine comme cela devrait être (lignes>fon>profit) :
Oui, le ticket est nécessaire pour analyser l'histoire par la suite. J'ai résolu le problème un peu plus facilement en ajoutant une telle vérification et un redessin au code :
for(int i=OrdersHistoryTotal()-1; i>=0; i--)
{
if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY) && OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol() && OrderType()<=1)
{
close_time=OrderCloseTime();
//60 секунд разницы между закрытием первого и последнего ордера в сетке
if(c<=close_time+60 && c>=close_time-60)
{
Profit+=OrderProfit()+OrderCommission()+OrderSwap();
ProfitTicket=(string)OrderTicket();
CountOrders++;
}
}
}
//Перерисовка фона и профита
if(CountOrders>1)
{
ObjectDelete("#"+Ticket+" Background");
ObjectDelete("#"+Ticket+" Profit: "+DoubleToString(Profit,2));
Ticket=ProfitTicket;
}
En gros, il dessine correctement (lignes>arrière-plan>bénéfice) :