Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools

Metatrader Forum | Forex Expert-Advisor | Broker & Forex Tools (http://www.expert-advisor.com/forum/index.php)
-   Programmierung MQL4 (http://www.expert-advisor.com/forum/forumdisplay.php?f=220)
-   -   Lotsize aus festgelegter Reihe - Array? (http://www.expert-advisor.com/forum/showthread.php?t=6025)

next user 05.03.18 20:13

Zitat:

Zitat von dundale (Beitrag 40462)
Einzig habe ich jetzt ein "Array out of range"-Problem. Wie erreiche ich, dass der 5. Trade und alle folgenden die Lotsize Nr. 4 also 0.24 haben. Also den letzten Wert der Reihe?

Du vergist aber nicht, den index im Array -1 zu nehmen (also count_lotSize = 1 -->> lotArray[count_lotSize-1]).
Habe ich im Beispielcode vergessen.

Bezüglich den zweiten Teil, einfach eine Beschränkung z.B. so:
Code:

if(count_lotSize > 4)
    ...lotArray[3]...
else
    ...lotArray[count_lotSize-1]...


dundale 05.03.18 21:27

Also irgendwie bekomme ich es nicht hin. Ich habe bestimmt irgendwo ein Denkfehler und stehe dazu noch auf dem Schlauch.

Ich habe mal den Code eingefügt. Es geht ja nur um die Lotsize. Im Test macht er 4 Trades auf und schließt sie wieder. Aber er soll eigentlich 8 Trades eröffnen.

Kannst du bitte noch mal drüber schauen?
Sorry.

Code:

//+------------------------------------------------------------------+
//|                                                    Beispiel.mq4 |
//+------------------------------------------------------------------+
#property strict
#property icon "icon.ico"
#include <stderror.mqh>
#include <stdlib.mqh>

extern double TP                      = 100;
extern double SL                      = 100;
extern double LS                      = 0.02;
extern string MyComment              = "Beispiel";
extern bool  AutoTrade              = true;
double  lotArray[4]  = {0.03, 0.12, 0.18, 0.24};
double  lotSize      = lotArray[0];
int      count_lotSize = 0;
double pips;
//+------------------------------------------------------------------+
//| Expert initialization function                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
// Determine what a pip is.
  pips=Point; //.00001 or .0001. .001 .01.
  if(Digits==3 || Digits==5 || Digits==1) pips*=10;
  else if(Digits==2) pips*=100;
//---
  return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+
//| Expert tick function                                            |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
  if(AutoTrade == true)
      CheckForSignal();
     
    if(TotalOpenOrders() > 4)
      {
      lotSize = lotArray[3];
      } 
      else
      {
      lotSize = lotArray[0];
      }
     
  //if(TotalOpenOrders() >= count_lotSize)
  //  {
  //  lotSize = lotArray[0];
  //  }
  }
//+------------------------------------------------------------------+
//| Check for Signal - Signal für automatischen Handel              |
//+------------------------------------------------------------------+
void CheckForSignal()
{
  if(TotalOpenOrders() < 9)
      PlaceOrder(OP_SELL);
}
//+------------------------------------------------------------------+
//| PlaceOrder-Function                                              |
//+------------------------------------------------------------------+
void PlaceOrder(int dir)
  {
      if(dir==OP_BUY)
        {
        int ticket=OrderSend(Symbol(),dir,lotArray[count_lotSize],Ask,30,Ask-(SL*pips),Ask+(TP*pips),MyComment,0,0,clrGreen);
        count_lotSize++;
        }
      if(dir==OP_SELL)
        {
        int ticket=OrderSend(Symbol(),dir,lotArray[count_lotSize],Bid,30,Bid+(SL*pips),Bid-(TP*pips),MyComment,0,0,clrRed);
        count_lotSize++;
        }
}
//+------------------------------------------------------------------+
//| Total of ALL orders place by this expert.                        |
//+------------------------------------------------------------------+
int TotalOpenOrders()
  {
  int total=0;
  if(OrdersTotal()>0)for(int i=OrdersTotal()-1; i>=0; i--)
    {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
        if(OrderSymbol() == Symbol())
            total++;
        } 
      else Print(__FUNCTION__," Failed to select order ",i," ",GetLastError());
    }
  return (total);
  }
//+------------------------------------------------------------------+


next user 05.03.18 22:13

Ich schreib dir morgen früh was dazu.

Würde gern etwas genauer auf deinen Code eingehen und jetzt fehlt aber die Zeit.
Also bis morgen, sofern niemand anderes antwortet ;)

next user 06.03.18 11:21

Zitat:

Zitat von dundale (Beitrag 40465)
Im Test macht er 4 Trades auf und schließt sie wieder. Aber er soll eigentlich 8 Trades eröffnen.

Sehe jetzt auf den ersten Blick nicht, warum er bei dir nur 4 eröffnet. Da wären Ausgaben an entsprechenden Stellen hilfreich.
Habs mal getestet und bei mir eröffnet er 8.

Noch zum Code:
Code:

if(Digits==3 || Digits==5 || Digits==1)
  pips*=10;
else if(Digits==2)
  pips*=100;

vereinfachen wir das mal...
Code:

if(Digits == 2)
  pips *= 100;
else
  pips *= 10;

=================================================

Code:

if(AutoTrade == true)
  CheckForSignal();

if(TotalOpenOrders() > 4)
  lotSize = lotArray[3];
else
  lotSize = lotArray[0];

  • True braucht man nicht auszuschreiben, einfach if(AutoTrade)
  • Es wäre sinnvoller, ERST die LotSize bei evtl. manuell erstellten Orders anzupassen, und DANN erst eine neue Order zu eröffnen.
  • Müsste der untere Teil nicht so aussehen:
    Code:

    if(TotalOpenOrders() > 4)
      lotSize = lotArray[3];
    else
      lotSize = lotArray[count_lotSize-1];

    So wie du es jetzt hast, müssten die ersten 4 Orders bei dir die ERSTE LotSize haben.
    Die -1 am Ende für den richtigen Index (ohne: bei Order 4 -> Index 4 -> Array Out of Range...)
  • Ich hoffe, dein Code im OnTick() ist nur zum testen. So ein ungefiltertes, direktes setzen einer Order bei jedem Tick ist nicht so toll.

=================================================

Code:

void CheckForSignal()
{
  if(TotalOpenOrders() < 9)
      PlaceOrder(OP_SELL);
}

Da du es bei jedem einzelnen Tick ausführst, "überlappen" sich die Orders extrem.
Auch das kann eine Fehlerquelle sein. Wenn der Kurs jetzt um einen Pip nach unten geht, platzierst du eine Order.
Der Kurs geht einen Pip nach oben -> du platzierst eine Order. Was passiert, wenn der Kurs jetzt um einen Pip wieder nach unten geht ???
Wenn man dann noch beachtet, das du nur Sell-Orders erstellst...

=================================================

Code:

void PlaceOrder(int dir)
{
  if(dir==OP_BUY)
  {
      int ticket=OrderSend(Symbol(),dir,lotArray[count_lotSize],Ask,30,Ask-(SL*pips),Ask+(TP*pips),MyComment,0,0,clrGreen);
      count_lotSize++;
  }
 
  if(dir==OP_SELL)
  {
      int ticket=OrderSend(Symbol(),dir,lotArray[count_lotSize],Bid,30,Bid+(SL*pips),Bid-(TP*pips),MyComment,0,0,clrRed);
      count_lotSize++;
  }
}

Zum einen erstellst du hier zwei mal die gleiche Variable (beim Kompilieren müsste er dir "'ticket' - variable already defined" sagen).
Zum anderen ist "ticket" hier sinnlos, da du nichts weiter damit anfängst.

=================================================

Code:

int TotalOpenOrders()
{
  int total=0;
 
  if(OrdersTotal()>0)
  {
      for(int i=OrdersTotal()-1; i>=0; i--)
      {
        if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
            if(OrderSymbol() == Symbol())
              total++;
        } 
        else
            Print(__FUNCTION__," Failed to select order ",i," ",GetLastError());
      }
  }
 
  return (total);
}

Die Funktion ist ja doch anders, als ich vermutet hatte. Da hast du mich aber nicht (wirklich) darauf hingeweisen...
Um nicht so viele Funktionsaufrufe zu haben, könnte man es noch etwas verändern, z.B.:
Code:

// Globale Variablen (im Code global!)
int  totalOrders = 0;
int  sameSymbolOrders = 0;

// Bei Ordereröffnung...
void PlaceOrder(int dir)
{
  int ticket = 0;

  if(dir == OP_BUY)
      ticket = OrderSend(Symbol(),dir,lotArray[count_lotSize],Ask,30,Ask-(SL*pips),Ask+(TP*pips),MyComment,0,0,clrGreen);
  else if(dir == OP_SELL)
      ticket = OrderSend(Symbol(),dir,lotArray[count_lotSize],Bid,30,Bid+(SL*pips),Bid-(TP*pips),MyComment,0,0,clrRed);
     
  if(ticket != -1)
  {
      count_lotSize++;
      sameSymbolOrders++;
      totalOrders++;
  }
}

// In OnTick()...
void OnTick()
{
  if(OrdersTotal() != totalOrders)
      CheckAllOrders();

  if(sameSymbolOrders > 4)
      lotSize = lotArray[3];
  else
      lotSize = lotArray[count_lotSize-1];
     
  if(AutoTrade)
      CheckForSignal();
}

// CheckAllOrders()... (TotalOpenOrders())
void CheckAllOrders()
{
  totalOrders = OrdersTotal();
  int count = 0;
 
  for(int i=totalOrders-1; i>=0; i--)
  {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
      {
        if(OrderSymbol() == Symbol())
            count++;
      } 
      else
        Print(__FUNCTION__," Failed to select order ",i," ",GetLastError());
  }
 
  if(sameSymbolOrders != count)
      sameSymbolOrders = count;
     
  // Wenn manuell erstellte Orders auch zu "count_lotSize" zählen sollen
  // count_lotSize++;
}

So wird die Funktion nur aufgerufen, wenn manuell eine Order erstellt wurde (oder eine gelöscht wurde), und nicht bei jedem Tick erneut.
Außerdem habe ich paar Kleinigkeiten im Code angepasst ("ticket" abgefangen, Code verkleinert, ect...).


Alle Zeitangaben in WEZ +2. Es ist jetzt 09:15 Uhr.

Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
SEO by vBSEO 3.6.1
Powered by vBCMS® 2.7.0 ©2002 - 2024 vbdesigns.de
Copyright ©2009 - 2023 by Expert-Advisor.com - Das Metatrader Forum