Fragen von Anfängern MQL5 MT5 MetaTrader 5 - Seite 728
![MQL5 - Sprache von Handelsstrategien, eingebaut ins Kundenterminal MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
Sie verpassen Handelsmöglichkeiten:
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Registrierung
Einloggen
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Wenn Sie kein Benutzerkonto haben, registrieren Sie sich
Hallo. Ich habe einen Expert Advisor in MetaTraider 4 geschrieben. Oder besser gesagt, ich habe versucht, zu lernen, wie man es schreibt. Ich weiß eine Menge Dinge nicht. Ich beschloss, es auf MetaTraider 5 zu portieren, was sich als etwas anders herausstellte. Im Allgemeinen habe ich einen anderen Expert Advisor genommen. Ich habe es zerlegt. Ich habe den Code für die Eröffnung von Wetten kopiert. Ich habe keine Fehler, aber es funktioniert nicht so, wie es sollte. Helfen Sie mir, es richtig zu bewegen.
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);
}
Und so wurde es auf MetaTraider 5 übertragen:
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;
}
Hallo. Ich habe einen Expert Advisor in MetaTraider 4 geschrieben. Oder besser gesagt, ich habe versucht, zu lernen, wie man es schreibt. Ich weiß eine Menge Dinge nicht. Ich beschloss, sie auf MetaTraider 5 zu übertragen, was sich als etwas anders herausstellte. Im Allgemeinen habe ich einen anderen Expert Advisor genommen. Ich habe es zerlegt. Ich habe den Code für die Eröffnung von Wetten kopiert. Ich habe keine Fehler, aber es funktioniert nicht so, wie es sollte. Helfen Sie mir, das Recht zu übertragen.
Der Code wird wie folgt aussehen (aber Vorsicht - es gibt eine Überprüfung der Gesamtzahl der Positionen auf dem Handelskonto(PositionsTotal):
d. h. es wird nicht überprüft, wie viele Positionen für ein bestimmtes Symbol und eine bestimmte Magie (die Magie ist übrigens nicht festgelegt) genau vorhanden sind.)
//| 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;
}
//+------------------------------------------------------------------+
Auch das Ergebnis der OperationOrderSend hat den Typ bool.
Ich habe eine statische Variable zum Speichern des Gleichgewichts verwendet
if(Balance==0.0)
Balance=AccountInfoDouble(ACCOUNT_BALANCE);
- Das bedeutet, dass die Variable "Balance" bei den folgenden OnTick()-Aufrufen nicht neu erstellt wird, sondern ihren Wert vom vorherigen Tick behält.
Obwohl ich es so schreiben würde:
//| 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);
}
//+------------------------------------------------------------------+
Hier:
Hinzugefügt:
Ich habe ein sehr interessantes Ergebnis eines einzelnen Laufs im Strategietester:
Obwohl ich es so schreiben würde:
Die Grundfunktionalität ist implementiert, aber Fehler wie "Ungültiger Preis" erscheinen immer wieder. Ich habe einige zusätzliche Prüfungen hinzugefügt, um die möglichen Ursachen zu beseitigen, und sie auf die richtigen Werte gesetzt, aber die Fehler sind nicht verschwunden. Ich weiß selbst nicht, welchen Weg ich einschlagen soll. Könnten Sie mir bitte sagen, wo ich einen Fehler gemacht habe? Ich füge den Quellcode bei.
Hallo! Ich habe mich entschlossen, für mein Selbststudium einen Multi-Currency Expert Advisor auf Basis der Green-Red Candle Strategie in MQL5 zu erstellen.
Ich habe die Grundfunktionen implementiert, erhalte aber immer wieder Fehlermeldungen wie "Ungültiger Preis". Ich habe zusätzliche Prüfungen hinzugefügt, um die möglichen Ursachen zu beseitigen, bzw. sie auf bekannte, korrekte Werte gesetzt, aber die Fehler sind nicht verschwunden. Ich weiß selbst nicht, welchen Weg ich einschlagen soll. Könnten Sie mir bitte sagen, wo ich einen Fehler gemacht habe? Ich füge den Quellcode bei.
Sie müssen die Preise im CSymbolInfo-Objekt der Handelsklasse aktualisieren, bevor Sie eine Handelsoperation durchführen. In meinen Mono-Projekten (die nur ein Symbol haben) verwende ich diese Funktion:
//| 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);
}
und Verwendung - wenn es nicht gelingt, die Preise zu aktualisieren, dann einfach beenden, wenn es gelingt, die Preise zu aktualisieren, dann wird ein Handel stattfinden:
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(
Was ist eine schöne und "einfache" Lösung, um dieses Design zu ersetzen?
So ist es jetzt auch, aber für meinen Geschmack ist es zu "schwer":
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);
}
Was ist eine schöne und "einfache" Lösung, um dieses Design zu ersetzen?
So ist es jetzt auch, aber für meinen Geschmack ist es zu "schwer":
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);
}
//+------------------------------------------------------------------+
Ich habe es nicht überprüft, um ehrlich zu sein - ich bekomme es nicht immer. Prüfen Sie es und schreiben Sie bitte das Ergebnis.
Was ist eine schöne und "einfache" Lösung, um dieses Design zu ersetzen?
So ist es jetzt auch, aber für meinen Geschmack ist es zu "schwer":
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);
}