关于OOP(面向对象的编程)的问题

 

大家好!

我认为是时候创建这个主题了,因为任何地方都没有好的OOP培训,但我们需要也想学习。

在 "新手提出的问题 "分支中加入更多复杂的、不为新手所理解的代码例子,可能不值得。

阅读了两篇文章"面向对象编程的基础知识 MQL5中的OOP:错误和警告代码处理 "的例子

我已经写了一个示例代码,我想详细研究一下。 我也建议你发表你自己的代码,一起讨论。

我对以下内容感兴趣。

  • 这个代码正确吗?
  • 如何改进代码?
  • 如何加快代码的速度?
我的开单密码。

#property strict
input int Slip=30;
input int Magic=0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
class vr_trade
  {
private:
   int               openorders(string sy,int typ,double lot,double price);
   string            tip(int typ);
public:
   int               Buy(string sy,double lot);
   int               Sel(string sy,double lot);
   int               BuyLimit(string sy,double lot, double price);
   int               SelLimit(string sy,double lot, double price);
   int               BuyStop(string sy,double lot, double price);
   int               SelStop(string sy,double lot, double price);
                     vr_trade(){}
                    ~vr_trade(){}
  };
MqlTick st;
vr_trade trade;
//+------------------------------------------------------------------+
void OnTick()
  {
trade.Buy("EURUSD",0.01); // Пример открытия позиции возвращающей тиккет ордера.
  }
//+------------------------------------------------------------------+  
int vr_trade :: Buy(string sy,double lot)
{
return openorders(sy,0,lot);
}
//+------------------------------------------------------------------+  
int vr_trade :: Sel(string sy,double lot)
{
return openorders(sy,1,lot);
}
//+------------------------------------------------------------------+  
int vr_trade :: BuyLimit(string sy,double lot, double price)
{
return openorders(sy,2,lot,price);
}
//+------------------------------------------------------------------+  
int vr_trade :: SelLimit(string sy,double lot, double price)
{
return openorders(sy,3,lot,price);
}
//+------------------------------------------------------------------+  
int vr_trade :: BuyStop(string sy,double lot, double price)
{
return openorders(sy,4,lot,price);
}
//+------------------------------------------------------------------+  
int vr_trade :: SelStop(string sy,double lot, double price)
{
return openorders(sy,5,lot,price);
}
//+------------------------------------------------------------------+
int vr_trade :: openorders(string sy="",int typ=0,double lot=0,double price=0)
  {
   int tik=-2;
   double di=NormalizeDouble(500*_Point,_Digits);
   if(sy==""){sy=_Symbol;Print("Установлен символ текущего графика ",sy);}
   if(lot<MarketInfo(sy,MODE_MINLOT)){lot=MarketInfo(sy,MODE_MINLOT); Print("Советник скорректировал лот ",lot);}
   if(!SymbolInfoTick(sy,st))Print("Не удалось прогрузить цены для символа ",sy);
   if(price==0)
     {
      if(typ==0)price=st.ask;
      if(typ==1)price=st.bid;
      if(typ==2)price=st.ask-di;
      if(typ==3)price=st.bid+di;
      if(typ==4)price=st.ask+di;
      if(typ==5)price=st.bid-di;
     }
   if(IsTradeAllowed()==true)
     {
      RefreshRates();
      tik=OrderSend(sy,typ,lot,price,Slip,0,0,"",Magic,0,clrRed);
      if(tik>0)Print("Успешно открыт ордер Ticket ",tik," Typ ",tip(typ)," Symbol ",sy," Lot ",lot," Price ",price);
      else Print("Ошибка открытия ордера N",GetLastError());
     }
   else
      Print("Торговый поток занят");
   return tik;
  }
//+------------------------------------------------------------------+
string vr_trade :: tip(int typ)
  {
   string txt="";
   switch(typ)
     {
      case 0: txt="BUY";        break;
      case 1: txt="SELL";       break;
      case 2: txt="BUY LIMIT";  break;
      case 3: txt="SELL LIMIT"; break;
      case 4: txt="BUY STOP";   break;
      case 5: txt="SELL STOP";  break;
      default : txt="Ошибка типа ордера";
     }
   return txt;
  }
//+------------------------------------------------------------------+
 
所以OOP只是把一个函数塞进一个类里?富有成效,可能很快就会在论坛上找到乐趣了。
 
VOLDEMAR:


  • 代码正确吗?
  • 如何改进代码?
  • 如何加快代码的速度?


你说的对或错是什么意思?如果它工作正常,那就是正确的。如果它不起作用,那就是错的。

改进。当某样东西不能满足需求时,要加以改进。哪些需求它不能满足,那么你就应该在这个方向上改进它。

为什么要加快速度?订单的开仓频率并不高,甚至与测试器中的总点数相比都很少。

但那是哲学。

练习。如果有一个很好的标准班,我们为什么还需要这个班呢?这是真的,它是针对MT5的,我不知道它是否适用于MT4。你没有吗?

你的代码中有一个缺点 - 没有止损和止盈。

 
TheXpert:
所以OOP只是把一个函数塞进一个类里?富有成效,可能很快就会在论坛上找到乐趣了。

如果你这么聪明,那就用正确的方式来写,这个话题不是为讽刺而设立的 ....
 
VOLDEMAR:

如果你这么聪明,那就用正确的方式来写,这个话题不是用来讽刺的....。


这取决于你想要什么,你需要什么,以及你的编程风格是什么。

你可以把一个类作为一组带参数的函数,就像你的例子一样。

你可以让方法设置参数,并通过调用无参数的方法直接打开订单

如果它更简单,那就更好了--在这种情况下,它将更适用于不同的情况。试图做一些超级完美的普遍性的事情是白痴的梦想,是对时间和精神努力的浪费。

更多。在你不得不解决同一个问题20次之前,你最好不要试图创造一个通用的方法。

 
Integer:


这意味着什么是对或错?如果它工作正常,那就是正确的。如果它不起作用,那就是错的。

改进。当一些东西不能满足需要时,你应该改进。哪些需求没有得到满足,在这个方向上要改进。

为什么要加快速度?订单的开仓频率并不高,甚至与测试器中的总点数相比都很少。

但那是哲学。

练习。如果有一个很好的标准班,我们为什么还需要这个班呢?这是真的,它是针对MT5的,我不知道它是否适用于MT4。你没有吗?

你的代码中有一个缺点 - 没有止损和止盈。


订单的止损 和止盈是单独设置的,因为我们可能不知道我们将在什么类型的账户上工作....。
 
Integer:

你可以制作方法来设置参数,通过调用没有参数的方法直接开单。

你能用我的例子证明这一点吗?

 

我不喜欢编码。总之...在私人部分声明止损、止盈和手数的变量。这些变量用于开单方法,当然,地段如是,价格水平是用这些变量计算的。但我们应该为这些变量设定值。这意味着我们需要的方法包括:SetTakeProfit(int Value), SetStopLoss(int Value), SetLots(double Value)。

在大多数EA中,SetTakeProfit(int Value)、SetStopLoss(int Value)、SetLots(double Value)等方法只需要在inite中调用一次。调用没有参数的开单方法,大大加快了执行时间

 
VOLDEMAR:
如果你这么聪明,请正确地写下来,这个话题不是为讽刺而设立的....。
不要在没有必要的地方拖动OOP。仅仅有对象的存在并不能使代码更快、更有效,等等。
 

像往常一样,我想学习,但一定会有一些人除了耍嘴皮子外,没有别的话可说......。

我写了一个简单的例子,把它拆开,我不知道如何用OOP写得更有能力 ...这只是一个例子,如果你知道如何正确地写一个类似的代码和OOP,那么请写出来,以便我和其他人可以学习...

 
VOLDEMAR:

像往常一样,我想学习,但一定会有一些人除了耍嘴皮子外,没有别的话可说......。

我写了一个简单的例子,把它拆开,我不知道如何用OOP写得更有能力 ...这只是一个例子,如果你知道如何正确地写这样的代码和OOP,那么请写出来,这样我和其他人就可以学到...


不要管我。

* * *

你应该努力确保在调用主要和最常用的方法时不传递任何参数。这将提高性能。但它会降低可用性。