Questions from Beginners MQL5 MT5 MetaTrader 5 - page 728
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Hello. I used to write an Expert Advisor in MetaTraider 4. Or rather, I was trying to learn how to write it. I don't know a lot of things. I decided to port it to MetaTraider 5, which turned out to be a bit different. In general, I took another Expert Advisor. I disassembled it. I have copied the code for opening bets. I have no errors, but it does not work as it should. Help me move it correctly.
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);
}
And that's how it transferred to 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;
}
Hello. I used to write an Expert Advisor in MetaTraider 4. Or rather, I was trying to learn how to write it. I don't know a lot of things. I decided to transfer it to MetaTraider 5, which turned out to be a bit different. In general, I took another Expert Advisor. I disassembled it. I have copied the code for opening bets. I have no errors, but it does not work as it should. Help me to transfer the right.
The code will be like this (but be careful - there is a check for the total number of positions on the trading account(PositionsTotal):
that is, there is no check of exactly how many positions for a given symbol and a given Magic (by the way, Magic is not set at all))
//| 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;
}
//+------------------------------------------------------------------+
Also the result ofOrderSend operationhas the bool type.
I used a static variable for storing balance
if(Balance==0.0)
Balance=AccountInfoDouble(ACCOUNT_BALANCE);
- It means that the variable "Balance" won't be recreated during subsequent arrivals of OnTick(), but it will remember its value from the previous tick.
Although I would write it this way:
//| 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);
}
//+------------------------------------------------------------------+
Here:
Added:
Got a very interesting result of a single run in the strategy tester:
Although I would write it this way:
The basic functionality is implemented, but I keep getting errors like "Invalid price". I have added some additional checks to eliminate their possible causes and set them to certainly correct values, but the errors have not disappeared. I don't know which way to go myself. Could you please tell me where I made a mistake? I'm attaching the source code.
Hello! I decided to make a multi-currency Expert Advisor based on Green-Red Candle strategy in MQL5 for my self-study.
I have implemented the basic functionality but keep getting errors like "Invalid price". I have added additional checks to eliminate their possible causes and, respectively, set them to known-correct values, but the errors have not disappeared. I don't know which way to go myself. Could you please tell me where I made a mistake? I'm attaching the source code.
You need to update prices in the CSymbolInfo object of the trade class before making a trade operation. In my mono projects (which only have one symbol) I use this function:
//| 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);
}
and usage - if no succeeded to update prices, then just exit, if succeeded to update prices, then there will be a trade operation:
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(
What's a nice and "easy" solution to replace this design?
It's like this now, but it's too "heavy" for my taste:
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);
}
What's a nice and "easy" solution to replace this design?
It's like this now, but it's too "heavy" for my taste:
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);
}
//+------------------------------------------------------------------+
I haven't checked it, to be honest - I don't get it all the time. Check it, write the result please.
What's a nice and "easy" solution to replace this design?
It's like this now, but it's too "heavy" for my taste:
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);
}