Diskussion zum Artikel "Die Erstellung eines Helfers im manuellen Handeln"

 

Neuer Artikel Die Erstellung eines Helfers im manuellen Handeln :

Die Anzahl der Handelsroboter für die Arbeit an Devisenmärkten nimmt in den letzten Jahren lawinenartig zu. In den Robotern werden verschiedene Konzepte und Strategien umgesetzt, keinem ist aber bis jetzt gelungen, eine gewinnsichere künstliche Intelligenz zu entwilckeln. Aus diesem Grund bleiben viele Trader manuellem Handel treu. Aber auch für sie werden Assistenten, die sogenannten Trading Panels erstellt. Dieser Artikel stellt ein Beispiel für die Erstellung eines solchen Panels von Grund auf dar.

Nehmen wir ein leeres Blatt und zeichnen unser künftiges Handelspanel sowie platzieren alle notwendigen Elemente.

Beim Entwurf des künftigen Designs des Handelspanels denken Sie auch an die Zweckmäßigkeit seiner Anwendung. Zunächst einmal sollte es recht informativ sein, aber dennoch einfach zu lesen, und nicht mit unnötigen Elementen überlastet sein. Wir müssen immer daran denken, dass es ein Werkzeug für die eigentliche Arbeit des Händlers ist, und nicht nur ein schönes Bild auf dem Bildschirm.

Hier ist meine Variante.

Design

Autor: Dmitriy Gizlyk

 

Ähnliche Tafeln werden auf dieser Website schon seit langem angeboten. Es gibt keinen Nutzen im Vergleich zur Standardtafel.

Was die Ideen betrifft.

1) Schaltfläche für die Umkehrung ausstehender Aufträge hinter dem Stop-Loss.

2) Ein-Knopf-Positionsumkehr-Button.

3) Schaltfläche für die Umkehrung der Position

4) Schaltfläche für die Umkehrung der Martingale-Order

5) Schaltfläche Take Profit 3 bis 1 oder anpassbar.

Mindeststandard eingestellt.

 
Ilya Vasenin:

Ähnliche Tafeln werden auf dieser Website schon seit langem angeboten. Es gibt keinen Nutzen im Vergleich zur Standardtafel.

Was die Ideen betrifft.

1) Schaltfläche für die Umkehrung ausstehender Aufträge hinter dem Stop-Loss.

2) Ein-Knopf-Positionsumkehr-Button.

3) Schaltfläche für die Umkehrung der Position

4) Schaltfläche für die Umkehrung der Martingale-Order

5) Schaltfläche Take Profit 3 bis 1 oder anpassbar.

Mindeststandard festgelegt.

Ja, es gibt eine Menge von Trading-Panels im Marketplace. Viele verschiedene Jobs in Freelance, um Handelspanels zu erstellen. Sie, wie auch jeder andere, können dieses vorgefertigte Panel kostenlos verwenden. Aber dies ist ein Artikel, kein Marktplatzprodukt. Und der Zweck dieses Artikels ist es nicht, ein fertiges Produkt zur Verfügung zu stellen, sondern jedem zu zeigen und denen, die es lernen wollen, beizubringen, wie jeder sein eigenes individuelles Handelspanel nach seinen eigenen Anforderungen erstellen kann.
 
Der Saldo und das Eigenkapital des Kontos werden im unteren Teil des Fensters angezeigt, das die Registerkarte "Tools" des Terminals dupliziert. Ich schlage stattdessen vor, dass an dieser Stelle angezeigt wird, wie viele Geschäfte für den aktuellen Tag getätigt wurden und wie ihr Ergebnis aussieht, und dass sich das Terminal in Zukunft ausschaltet, wenn die festgelegte Anzahl von Geschäften oder der festgelegte Verlust für den Tag erreicht ist.
 
Dmitriy Gizlyk:
Und der Zweck dieses Artikels ist nicht, ein fertiges Produkt zur Verwendung zu geben, sondern zu zeigen und zu lehren, wie jeder sein eigenes individuelles Handelspanel nach seinen eigenen Anforderungen erstellen kann.

Dmitry, heute habe ich begonnen, ein Panel auf µl 4 nach Ihrem Tutorial zu erstellen. Fast alles funktioniert, aber wenn ich auf das Panel oder eine beliebige Schaltfläche klicke, öffnet sich nur buy. Was könnte der Grund dafür sein?

//+------------------------------------------------------------------+
//|TradePanel.mq4 |
//| Copyright 2015, MetaQuotes Software Corp. | |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

#include <Controls\Dialog.mqh>
#include <Controls\Label.mqh>
#include <Controls\Button.mqh>

//--- Eingaben
extern double Lot        = 0.1;      // lot
extern int StopLoss      = 500;      // Elch
extern int TakeProfit    = 500;      // yazi
extern int Slip          = 30;       // requotes
extern int Magic         = 0;        // Magie
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
enum label_align
  {
   left=-1,
   right=1,
   center=0
  };
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
class CTradePanel : public CAppDialog
  {
private:

   CLabel            Lots_label;                      // Beschriftung " Lose" anzeigen
   CEdit             Lots;                            // Volumen der nächsten Bestellung anzeigen
   CButton           SELL,BUY;                        // Schaltflächen "Verkaufen und Kaufen
   CButton           CloseAll;                        // Schaltflächen schließen

   //--- Etikettenobjekt erstellen
   bool              CreateLabel(const long chart,const int subwindow,CLabel &object,const string text,const uint x,const uint y,label_align align);
   //--- Schaltfläche erstellen
   bool              CreateButton(const long chart,const int subwindow,CButton &object,const string text,const uint x,const uint y,const uint x_size,const uint y_size);
   //--- Objekt bearbeiten erstellen
   bool              CreateEdit(const long chart,const int subwindow,CEdit &object,const string text,const uint x,const uint y,const uint x_size,const uint y_size);

   //--- Bei Ereignisfunktionen
   void              LotsEndEdit(void);               // Losgröße bearbeiten

   //--- Variablen mit aktuellen Werten
   double            cur_lot;                         // Los der nächsten Bestellung

   void              BuyClick();                      // Klicken Sie auf die Schaltfläche KAUFEN
   void              SellClick();                     // Klicken Sie auf die Schaltfläche SELL
   void              CloseClick();                    // Klicken Sie auf die Schaltfläche CLOSE 

public:
                     CTradePanel(void){};
                    ~CTradePanel(void){};
   virtual bool      Create(const long chart,const string name,const int subwin=0,const int x1=20,const int y1=20,const int x2=320,const int y2=420);
   virtual bool      OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
   virtual void      Destroy(const int reason);
  };

CTradePanel TradePanel;
//+------------------------------------------------------------------+
//| Experteninitialisierungsfunktion|
//+------------------------------------------------------------------+
int OnInit()
  {
//---
// Handelspanel erstellen
   TradePanel.Create(ChartID(),"Panelka",0,20,20,150,200);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Experten-Deinitialisierungsfunktion|
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   TradePanel.Destroy(reason);
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool CTradePanel::CreateLabel(const long chart,const int subwindow,CLabel &object,const string text,const uint x,const uint y,label_align align)
  {
// Alle Objekte müssen einen eigenen Namen haben
   string name=m_name+"Label"+(string)ObjectsTotal(chart,-1,OBJ_LABEL);
//--- Aufruf der Funktion Erstellen
   if(!object.Create(chart,name,subwindow,x,y,0,0))
     {
      return false;
     }
//--- Text anpassen
   if(!object.Text(text))
     {
      return false;
     }
//--- Text am Gitter des Dialogfelds ausrichten
   ObjectSetInteger(chart,object.Name(),OBJPROP_ANCHOR,(align==left ? ANCHOR_LEFT_UPPER :(align==right ? ANCHOR_RIGHT_UPPER : ANCHOR_UPPER)));
//--- Objekt zu Steuerelementen hinzufügen
   if(!Add(object))
     {
      return false;
     }
   return true;
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool CTradePanel::CreateButton(const long chart,const int subwindow,CButton &object,const string text,const uint x,const uint y,const uint x_size,const uint y_size)
  {
// Alle Objekte müssen einen eigenen Namen haben
   string name=m_name+"Button"+(string)ObjectsTotal(chart,-1,OBJ_BUTTON);
//--- Aufruf der Funktion Erstellen
   if(!object.Create(chart,name,subwindow,x,y,x+x_size,y+y_size))
     {
      return false;
     }
//--- Text anpassen
   if(!object.Text(text))
     {
      return false;
     }
//--- Knopf zum Entsperren setzen
   object.Locking(false);
//--- Schaltfläche auf "nicht gedrückt" setzen
   if(!object.Pressed(false))
     {
      return false;
     }
//--- Objekt zu Steuerelementen hinzufügen
   if(!Add(object))
     {
      return false;
     }
   return true;
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool CTradePanel::CreateEdit(const long chart,const int subwindow,CEdit &object,const string text,const uint x,const uint y,const uint x_size,const uint y_size)
  {
// Alle Objekte müssen einen eigenen Namen haben
   string name=m_name+"Edit"+(string)ObjectsTotal(chart,-1,OBJ_EDIT);
//--- Aufruf der Funktion Erstellen
   if(!object.Create(chart,name,subwindow,x,y,x+x_size,y+y_size))
     {
      return false;
     }
//--- Text anpassen
   if(!object.Text(text))
     {
      return false;
     }
//--- Text im Bearbeitungsfeld ausrichten
   if(!object.TextAlign(ALIGN_CENTER))
     {
      return false;
     }
//--- Nur-Lesen-Flagge auf false setzen
   if(!object.ReadOnly(false))
     {
      return false;
     }
//--- Objekt zu Steuerelementen hinzufügen
   if(!Add(object))
     {
      return false;
     }
   return true;
  }
//+------------------------------------------------------------------+
//||
//+------------------------------------------------------------------+
bool CTradePanel::Create(const long chart,const string name,const int subwin=0,const int x1=20,const int y1=20,const int x2=320,const int y2=420)
  {
// Beim ersten Aufruf der Funktion create der Elternklasse
   CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2);

// Berechnung der Koordinaten und Größe des BID-Objekts

// Objekt erstellen
   CreateLabel(chart,subwin,Lots_label,"LOT",55,5,0);
   CreateEdit(chart,subwin,Lots,"0.1",33,35,60,20);
   CreateButton(chart,subwin,BUY,"BUY",33,65,60,20);
   CreateButton(chart,subwin,SELL,"SELL",33,95,60,20);
   CreateButton(chart,subwin,CloseAll,"CLOSE",33,125,60,20);

   return(true);
  }
//+------------------------------------------------------------------+
//| Ereignisbehandlung|
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CTradePanel)
ON_EVENT(ON_END_EDIT,Lots,LotsEndEdit)
ON_EVENT(ON_CLICK,BUY,BuyClick)
ON_EVENT(ON_CLICK,SELL,SellClick)
ON_EVENT(ON_CLICK,CloseAll,CloseClick)
EVENT_MAP_END(CAppDialog)
//+------------------------------------------------------------------+
//| Klicken Sie auf die Schaltfläche KAUFEN|
//+------------------------------------------------------------------+
void CTradePanel::BuyClick(void)
  {
   PutOrder(0,Ask);
  }
//+------------------------------------------------------------------+
//| Klicken Sie auf die Schaltfläche KAUFEN|
//+------------------------------------------------------------------+
void CTradePanel::SellClick(void)
  {
   PutOrder(1,Bid);
  }
//+------------------------------------------------------------------+
//| Klicken Sie auf die Schaltfläche KAUFEN|
//+------------------------------------------------------------------+
void CTradePanel::CloseClick(void)
  {
   CloseAll();
  }
//+------------------------------------------------------------------+
//| Lose Wert nach Bearbeitung lesen|
//+------------------------------------------------------------------+
void CTradePanel::LotsEndEdit(void)
  {
//--- Lotwert lesen und normalisieren
   cur_lot=NormalizeDouble(StringToDouble(Lots.Text()),2);
  }
//+------------------------------------------------------------------+
//| Deinitialisierungsfunktion der Anwendung |
//+------------------------------------------------------------------+
void CTradePanel::Destroy(const int reason)
  {
   CAppDialog::Destroy(reason);
   return;
  }
//+------------------------------------------------------------------+
//| Einstellung einer Bestellung|
//+------------------------------------------------------------------+
void PutOrder(int type,double price)
  {
   int r=0;
   color clr=Green;
   double sl=0,tp=0;

   if(type==1 || type==3 || type==5)
     {
      clr=Red;
      if(StopLoss>0)   sl=NormalizeDouble(price+StopLoss*Point,Digits);
      if(TakeProfit>0) tp=NormalizeDouble(price-TakeProfit*Point,Digits);
     }

   if(type==0 || type==2 || type==4)
     {
      clr=Blue;
      if(StopLoss>0)   sl=NormalizeDouble(price-StopLoss*Point,Digits);
      if(TakeProfit>0) tp=NormalizeDouble(price+TakeProfit*Point,Digits);
     }

   r=OrderSend(NULL,type,Lot,NormalizeDouble(price,Digits),Slip,sl,tp,"",Magic,0,clr);
   return;
  }
//+------------------------------------------------------------------+
//| Schließen einer Position nach Auftragsart|
//+------------------------------------------------------------------+
void CloseAll(int ot=-1)
  {
   bool cl;
   for(int i=OrdersTotal()-1;i>=0;i--)
     {
      if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
        {
         if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic)
           {
            if(OrderType()==0 && (ot==0 || ot==-1))
              {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slip,White);
              }
            if(OrderType()==1 && (ot==1 || ot==-1))
              {
               RefreshRates();
               cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slip,White);
              }
           }
        }
     }
  }
//+------------------------------------------------------------------+
//| Experten-Tick-Funktion|
//+------------------------------------------------------------------+
void OnTick()
  {
//---

  }
//+------------------------------------------------------------------+
//| ChartEvent-Funktion|
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   TradePanel.OnEvent(id,lparam,dparam,sparam);
  }
//+------------------------------------------------------------------+
 
Andrew Kornishkin:

Dmitry, heute habe ich begonnen, ein Panel auf µl 4 nach Ihrem Tutorial zu machen. Fast alles funktioniert, aber wenn ich auf das Panel oder eine Schaltfläche klicke, öffnet sich nur buy. Was könnte der Grund dafür sein?

Gute Nacht, Andrew.
Sie haben in der Klassenbeschreibung alles richtig gemacht. Ihr einziger Fehler ist, dass Sie in der OnInit-Funktion nach dem Erstellen der Trading-Panel-Klasse deren Ausführung nicht mit der Run-Funktion gestartet haben.

int OnInit()
  {
//---
// Handelspanel erstellen
   TradePanel.Create(ChartID(),"Panelka",0,20,20,150,200);
   TradePanel.Run();
//---
   return(INIT_SUCCEEDED);
  }

Mit freundlichen Grüßen,

Dmitri.

 
Dmitriy Gizlyk:

Gute Nacht, Andrey.
Sie haben in der Klassenbeschreibung alles richtig gemacht. Ihr einziger Fehler ist, dass Sie in der OnInit-Funktion nach dem Erstellen der Trade-Panel-Klasse deren Ausführung nicht mit der Run-Funktion gestartet haben.

Mit freundlichen Grüßen,

Dmitri.

Vielen Dank, Dmitry!
Es hat funktioniert!
 
Ich habe Ihr Trading-Panel auf Metatrader heruntergeladen, aber es funktioniert nicht. Das ist sehr schade.
 
19681:
Ich habe Ihr Trading-Panel auf Metatrader heruntergeladen, aber es funktioniert nicht. Das ist sehr schade.
Wie äußert sich das?
Damit das Panel funktioniert, wie auch jedes andere Handelsprogramm, muss der automatische Handel im Terminal aktiviert werden.
 
Dmitriy Gizlyk:
Worin äußert sich das?
Damit das Panel wie jedes andere Handelsprogramm funktioniert, muss der Autohandel im Terminal aktiviert werden.
Autotrading ist natürlich aktiviert. Und es äußert sich darin, dass die Schaltflächen nicht funktionieren (wenn Sie auf Verkaufen oder Kaufen klicken, erhalten Sie "error of open BUY ORDER").
 
19681:
Autotrading ist natürlich aktiviert. Und es äußert sich darin, dass die Schaltflächen nicht funktionieren (wenn Sie auf Verkaufen oder Kaufen klicken, wird "Fehler bei offenem BUY ORDER" angezeigt).
Prüfen Sie, ob der Handel mit dem Symbol überhaupt erlaubt ist? Aufgrund der jüngsten Ereignisse (Brexit) haben einige Broker den Handel vorübergehend eingeschränkt