Questions des débutants MQL5 MT5 MetaTrader 5 - page 728
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
Bonjour. J'avais l'habitude d'écrire un conseiller expert dans MetaTraider 4. Ou plutôt, j'essayais d'apprendre à l'écrire. Je ne sais pas beaucoup de choses. J'ai décidé de le porter sur MetaTraider 5, qui s'est avéré être un peu différent. En général, j'ai pris un autre conseiller expert. Je l'ai démonté. J'ai copié le code pour l'ouverture des paris. Je n'ai pas d'erreur, mais cela ne fonctionne pas comme il le faudrait. Aidez-moi à le déplacer correctement.
MetaTraider 4 :
int err = 0;
double Lot = 0.01; // Лот
double CoofLot = 0;
double Ballance = AccountBalance();
double loss = 100;
bool nap = true; //true - 1
//false - 0
int start()
{
if(OrdersTotal()==0)
{
if(Ballance != AccountBalance())
{
if(AccountBalance() < Ballance )
{
CoofLot++;
Lot = pow(2, CoofLot) * 0.01;
if(nap == true)
{
nap = false;
}
else
{
nap = true;
}
}
if(AccountBalance() > Ballance)
{
Lot = 0.01;
CoofLot = 0;
}
}
Ballance = AccountBalance();
int order;
if(nap == true)
{
order = OrderSend(Symbol(),OP_BUY,Lot,Ask,1*Point,Ask-loss*Point,Ask+loss*Point); // Вверх
}
else
{
order = OrderSend(Symbol(),OP_SELL,Lot,Bid,1*Point,Bid+loss*Point,Bid-loss*Point); // Вниз
}
if(order<0)
{
if (GetLastError()==134)
{
err=1;
Print("NOT ENOGUGHT MONEY!!");
}
return (-1);
}
}
return(0);
}
Et c'est ainsi qu'il a été transféré à MetaTraider 5 :
double CoofLot = 0;
double Ballance = ACCOUNT_BALANCE;
double loss = 100;
bool nap = true; //true - 1
//false - 0
void OnTick()
{
MqlTick latest_price; // Будет использоваться для текущих котировок
MqlTradeRequest mrequest; // Будет использоваться для отсылки торговых запросов
MqlTradeResult mresult;
if(OrdersTotal()==0)
{
if(!SymbolInfoTick(_Symbol,latest_price))
{
Alert("Ошибка получения последних котировок - ошибка:",GetLastError(),"!!");
return;
}
if(Ballance != ACCOUNT_BALANCE)
{
if(ACCOUNT_BALANCE < Ballance )
{
CoofLot++;
Lot = pow(2, CoofLot) * 0.01;
if(nap == true)
{
nap = false;
}
else
{
nap = true;
}
}
if(ACCOUNT_BALANCE > Ballance)
{
Lot = 0.01;
CoofLot = 0;
}
}
Ballance = ACCOUNT_BALANCE;
int order;
if(nap == true)
{
mrequest.action = TRADE_ACTION_DEAL; // немедленное исполнение
mrequest.price = NormalizeDouble(latest_price.ask,_Digits); // последняя цена ask
mrequest.sl = NormalizeDouble(latest_price.ask - 100*_Point,_Digits); // Stop Loss
mrequest.tp = NormalizeDouble(latest_price.ask + 100*_Point,_Digits); // Take Profit
mrequest.symbol = _Symbol; // символ
mrequest.volume = Lot; // количество лотов для торговли
mrequest.type = ORDER_TYPE_BUY; // ордер на покупку
mrequest.type_filling = ORDER_FILLING_FOK; // тип исполнения ордера - все или ничего
mrequest.deviation=100; // проскальзывание от текущей цены
//--- отсылаем ордер
order = OrderSend(mrequest,mresult);
}
else
{
mrequest.action = TRADE_ACTION_DEAL; // немедленное исполнение
mrequest.price = NormalizeDouble(latest_price.bid,_Digits); // последняя цена Bid
mrequest.sl = NormalizeDouble(latest_price.bid + 100*_Point,_Digits); // Stop Loss
mrequest.tp = NormalizeDouble(latest_price.bid - 100*_Point,_Digits); // Take Profit
mrequest.symbol = _Symbol; // символ
mrequest.volume = Lot; // количество лотов для торговли
mrequest.type= ORDER_TYPE_SELL; // ордер на продажу
mrequest.type_filling = ORDER_FILLING_FOK; // тип исполнения ордера - все или ничего
mrequest.deviation=100; // проскальзывание от текущей цены
//--- отсылаем ордер
order = OrderSend(mrequest,mresult);
}
}
return;
}
Bonjour. J'avais l'habitude d'écrire un conseiller expert dans MetaTraider 4. Ou plutôt, j'essayais d'apprendre à l'écrire. Je ne sais pas beaucoup de choses. J'ai décidé de le transférer sur MetaTraider 5, qui s'est avéré être un peu différent. En général, j'ai pris un autre conseiller expert. Je l'ai démonté. J'ai copié le code pour l'ouverture des paris. Je n'ai pas d'erreur, mais cela ne fonctionne pas comme il le faudrait. Aidez-moi à transférer le droit.
Le code sera comme ceci (mais attention - il y a une vérification pour le nombre total de positions sur le compte de trading(PositionsTotal) :
c'est-à-dire qu'il n'y a pas de contrôle du nombre exact de positions pour un symbole donné et une Magie donnée (d'ailleurs, la Magie n'est pas du tout définie))
//| TestEA.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"
//---
double Lot = 0.01;
double CoofLot = 1.0;
double loss = 100.0;
bool nap = true;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
CoofLot = 1.0;
loss = 100.0;
nap = true;
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
static double Balance=0.0;
if(Balance==0.0)
Balance=AccountInfoDouble(ACCOUNT_BALANCE);
if(PositionsTotal()==0)
{
MqlTick latest_price; // Будет использоваться для текущих котировок
if(!SymbolInfoTick(_Symbol,latest_price))
{
Alert("Ошибка получения последних котировок - ошибка:",GetLastError(),"!!");
return;
}
if(Balance!=AccountInfoDouble(ACCOUNT_BALANCE))
{
if(AccountInfoDouble(ACCOUNT_BALANCE)<Balance)
{
CoofLot++;
Lot=pow(2,CoofLot)*0.01;
if(nap==true)
{
nap=false;
}
else
{
nap=true;
}
}
if(AccountInfoDouble(ACCOUNT_BALANCE)>Balance)
{
Lot=0.01;
CoofLot=1.0;
}
}
Balance=AccountInfoDouble(ACCOUNT_BALANCE);
MqlTradeRequest mrequest; // Будет использоваться для отсылки торговых запросов
MqlTradeResult mresult;
ZeroMemory(mrequest);
ZeroMemory(mresult);
bool order=false;
if(nap==true)
{
mrequest.action = TRADE_ACTION_DEAL; // немедленное исполнение
mrequest.price = NormalizeDouble(latest_price.ask,_Digits); // последняя цена ask
mrequest.sl = NormalizeDouble(latest_price.bid - 100*_Point,_Digits); // Stop Loss
mrequest.tp = NormalizeDouble(latest_price.bid + 100*_Point,_Digits); // Take Profit
mrequest.symbol = _Symbol; // символ
mrequest.volume = Lot; // количество лотов для торговли
mrequest.type = ORDER_TYPE_BUY; // ордер на покупку
mrequest.type_filling = ORDER_FILLING_FOK; // тип исполнения ордера - все или ничего
mrequest.deviation=100; // проскальзывание от текущей цены
//--- отсылаем ордер
order=OrderSend(mrequest,mresult);
}
else
{
mrequest.action = TRADE_ACTION_DEAL; // немедленное исполнение
mrequest.price = NormalizeDouble(latest_price.bid,_Digits); // последняя цена Bid
mrequest.sl = NormalizeDouble(latest_price.ask + 100*_Point,_Digits); // Stop Loss
mrequest.tp = NormalizeDouble(latest_price.ask - 100*_Point,_Digits); // Take Profit
mrequest.symbol = _Symbol; // символ
mrequest.volume = Lot; // количество лотов для торговли
mrequest.type= ORDER_TYPE_SELL; // ордер на продажу
mrequest.type_filling = ORDER_FILLING_FOK; // тип исполнения ордера - все или ничего
mrequest.deviation=100; // проскальзывание от текущей цены
//--- отсылаем ордер
order=OrderSend(mrequest,mresult);
}
}
return;
}
//+------------------------------------------------------------------+
Le résultat de l'opérationOrderSend est également detype bool.
J'ai utilisé une variable statique pour stocker la balance
if(Balance==0.0)
Balance=AccountInfoDouble(ACCOUNT_BALANCE);
- Cela signifie que la variable "Balance" ne sera pas recréée lors des arrivées ultérieures de OnTick(), mais qu'elle se souviendra de sa valeur du tick précédent.
Bien que je l'écrirais de cette façon :
//| TestEA.mq5 |
//| Copyright © 2017, Vladimir Karputov |
//| http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link "http://wmua.ru/slesar/"
#property version "1.001"
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
CPositionInfo m_position; // trade position object
CTrade m_trade; // trading object
CSymbolInfo m_symbol; // symbol info object
CAccountInfo m_account; // account info wrapper
//---
double Lot = 0.01;
double CoofLot = 1.0;
double Loss = 100.0;
bool nap = true;
//---
ulong m_magic = 15489; // magic number
ulong m_slippage = 10; // slippage
double m_adjusted_point; // point value adjusted for 3 or 5 points
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
m_symbol.Name(Symbol()); // sets symbol name
if(!RefreshRates())
{
Print("Error RefreshRates. Bid=",DoubleToString(m_symbol.Bid(),Digits()),
", Ask=",DoubleToString(m_symbol.Ask(),Digits()));
return(INIT_FAILED);
}
m_symbol.Refresh();
//---
m_trade.SetExpertMagicNumber(m_magic);
//---
m_trade.SetDeviationInPoints(m_slippage);
//--- tuning for 3 or 5 digits
int digits_adjust=1;
if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
digits_adjust=10;
m_adjusted_point=m_symbol.Point()*digits_adjust;
//---
CoofLot = 1.0;
Loss = 100.0;
nap = true;
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
static double static_Balance=0.0;
if(static_Balance==0.0)
static_Balance=m_account.Balance();
double balance=m_account.Balance(); // локальная переменная для хранения баланса на время OnTick
//--- считаем позиции по символу и по Magic
int total=0;
for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positions
if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==m_magic)
total++;
if(total==0)
{
//--- попытка обновить цены
if(!RefreshRates())
return; // есил не удалось обновить цены - просто выходим
if(static_Balance!=balance)
{
if(balance<static_Balance)
{
CoofLot++;
double lots=pow(2,CoofLot)*0.01; // локальная переменная для временных расчётов лота
//--- проверка корректности лота
Lot=LotCheck(lots);
if(Lot==0.0)
return;
if(nap)
nap=false;
else
nap=true;
}
if(balance>static_Balance)
{
Lot=0.01;
CoofLot=1.0;
}
}
static_Balance=balance;
if(nap==true)
{
double sl=m_symbol.NormalizePrice(m_symbol.Bid() - Loss*m_adjusted_point); // Stop Loss
double tp=m_symbol.NormalizePrice(m_symbol.Bid() + Loss*m_adjusted_point); // Take Profit
if(m_trade.Buy(Lot,NULL,m_symbol.Ask(),sl,tp))
{
if(m_trade.ResultDeal()==0)
Print("Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),
", description of result: ",m_trade.ResultRetcodeDescription());
else
Print("Buy -> true. Result Retcode: ",m_trade.ResultRetcode(),
", description of result: ",m_trade.ResultRetcodeDescription());
}
else
Print("Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),
", description of result: ",m_trade.ResultRetcodeDescription());
}
else
{
double sl=m_symbol.NormalizePrice(m_symbol.Ask()+Loss*m_adjusted_point); // Stop Loss
double tp=m_symbol.NormalizePrice(m_symbol.Ask()-Loss*m_adjusted_point); // Take Profit
if(m_trade.Sell(Lot,NULL,m_symbol.Ask(),sl,tp))
{
if(m_trade.ResultDeal()==0)
Print("Sell -> false. Result Retcode: ",m_trade.ResultRetcode(),
", description of result: ",m_trade.ResultRetcodeDescription());
else
Print("Sell -> true. Result Retcode: ",m_trade.ResultRetcode(),
", description of result: ",m_trade.ResultRetcodeDescription());
}
else
Print("Sell -> false. Result Retcode: ",m_trade.ResultRetcode(),
", description of result: ",m_trade.ResultRetcodeDescription());
}
}
return;
}
//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data |
//+------------------------------------------------------------------+
bool RefreshRates()
{
//--- refresh rates
if(!m_symbol.RefreshRates())
return(false);
//--- protection against the return value of "zero"
if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+
//| Lot Check |
//+------------------------------------------------------------------+
double LotCheck(double lots)
{
//--- calculate maximum volume
double volume=NormalizeDouble(lots,2);
double stepvol=m_symbol.LotsStep();
if(stepvol>0.0)
volume=stepvol*MathFloor(volume/stepvol);
//---
double minvol=m_symbol.LotsMin();
if(volume<minvol)
volume=0.0;
//---
double maxvol=m_symbol.LotsMax();
if(volume>maxvol)
volume=maxvol;
return(volume);
}
//+------------------------------------------------------------------+
Ici :
Ajouté :
J'ai obtenu un résultat très intéressant lors d'une seule exécution dans le testeur de stratégie :
Bien que je l'écrirais de cette façon :
La fonctionnalité de base est implémentée, mais des erreurs comme "Prix invalide" continuent d'apparaître. J'ai ajouté quelques contrôles supplémentaires pour éliminer leurs causes possibles et les ai réglés sur des valeurs certainement correctes, mais les erreurs n'ont pas disparu. Je ne sais pas moi-même quelle direction prendre. Pouvez-vous me dire où j'ai fait une erreur ? Je joins le code source.
Bonjour, j'ai décidé de faire un Expert Advisor multi-devises basé sur la stratégie de la bougie verte-rouge dans MQL5 pour mon auto-apprentissage.
J'ai mis en œuvre la fonctionnalité de base mais je continue à obtenir des erreurs telles que "Prix non valide". J'ai ajouté des contrôles supplémentaires pour éliminer leurs causes possibles et, respectivement, je les ai réglés sur des valeurs correctes connues, mais les erreurs n'ont pas disparu. Je ne sais pas moi-même quelle direction prendre. Pouvez-vous me dire où j'ai fait une erreur ? Je joins le code source.
Vous devez mettre à jour les prix dans l'objet CSymbolInfo de la classe de négociation avant d'effectuer une opération de négociation. Dans mes projets mono (qui n'ont qu'un seul symbole), j'utilise cette fonction :
//| Refreshes the symbol quotes data |
//+------------------------------------------------------------------+
bool RefreshRates()
{
//--- refresh rates
if(!m_symbol.RefreshRates())
return(false);
//--- protection against the return value of "zero"
if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
return(false);
//---
return(true);
}
et l'utilisation - si la mise à jour des prix ne réussit pas, il suffit de sortir, si la mise à jour des prix réussit, il y aura une opération commerciale :
if(!m_symbol.RefreshRates())
return;
if(m_trade.Buy(lots,NULL,m_symbol.Ask(),sl,tp))
{
if(m_trade.ResultDeal()==0)
Print("Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),
", description of result: ",m_trade.ResultRetcodeDescription());
else
Print("Buy -> true. Result Retcode: ",m_trade.ResultRetcode(),
", description of result: ",m_trade.ResultRetcodeDescription());
}
else
Print("Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),
", description of result: ",m_trade.ResultRetcodeDescription(
Quelle est une solution agréable et "facile" pour remplacer ce modèle ?
C'est comme ça maintenant, mais c'est trop "lourd" à mon goût :
if(time<0) return(-1);
datetime Arr[],time1;
CopyTime(symbol,tf,0,1,Arr);
time1=Arr[0];
if(CopyTime(symbol,tf,time,time1,Arr)>0) {
if(ArraySize(Arr)>2) return(ArraySize(Arr)-1);
if(time<time1) return(1);
else return(0);
}
else return(-1);
}
Quelle est une solution agréable et "facile" pour remplacer ce modèle ?
C'est comme ça maintenant, mais c'est trop "lourd" à mon goût :
if(time<0) return(-1);
datetime Arr[],time1;
CopyTime(symbol,tf,0,1,Arr);
time1=Arr[0];
if(CopyTime(symbol,tf,time,time1,Arr)>0) {
if(ArraySize(Arr)>2) return(ArraySize(Arr)-1);
if(time<time1) return(1);
else return(0);
}
else return(-1);
}
//| Возвращает смещение бара по времени |
//+------------------------------------------------------------------+
int GetBarShift(const string symbol_name, const ENUM_TIMEFRAMES timeframe, const datetime time) {
int res=-1;
datetime last_bar;
if(SeriesInfoInteger(symbol_name,timeframe,SERIES_LASTBAR_DATE,last_bar)) {
if(time>last_bar) res=0;
else {
const int shift=Bars(symbol_name,timeframe,time,last_bar);
if(shift>0) res=shift-1;
}
}
return(res);
}
//+------------------------------------------------------------------+
Je ne l'ai pas vérifié, pour être honnête - je ne le reçois pas tout le temps. Vérifiez-le, écrivez le résultat s'il vous plaît.
Quelle est une solution agréable et "facile" pour remplacer ce modèle ?
C'est comme ça maintenant, mais c'est trop "lourd" à mon goût :
if(time<0) return(-1);
datetime Arr[],time1;
CopyTime(symbol,tf,0,1,Arr);
time1=Arr[0];
if(CopyTime(symbol,tf,time,time1,Arr)>0) {
if(ArraySize(Arr)>2) return(ArraySize(Arr)-1);
if(time<time1) return(1);
else return(0);
}
else return(-1);
}