MQL5におけるOOPに関する質問 - ページ 28

 
Dmitry Fedoseev:

また、クラスを使わないと、常にSymbolInfoDouble(_Symbol,MODE_BID)のような書き方をしていると、疲れてしまうでしょう。 そんなのが毎回踊っている。カッコもアンダースコアも、capslockを押すか(そして、見ずにどこかで大文字の文字列を全部入力して打ち直す)、シフターを押したままにするか、迷うところである。少なくとも、そこにOOPの有用性がある。少なくとも、これらの機能のためのクラスを作るのであれば、そうです - 巨大なものです。自分のために書くのであれば、問題ありません。オーダーの操作に関しては、頻繁に使う関数はそれほど多くないので、いくつかの関数をライブラリに入れればいいだけです。しかし、一般的には理想的な方法はまだ見つかっていません。

オープン/クローズ/ストップロスを設定し、後で注文状況を 表示できるクラスのイメージは以下の通りです。

class CConstVolume
{
protected:
   static const double  VolumeMAX;
   static const double  VolumeMIN;
   static const double  VolumeSTEP;
   static const double  ZerroPrice;
   static const int     VolumeDIGITS;
   static int           GetDigitsInVolumeStep(); };
//___________________________________________________________________________
static int CConstVolume::GetDigitsInVolumeStep()
{  int result = 0;
   long i = 10000000, k = long(::SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP) / 0.0000001);
   while(result < 7 && k % i > 0)
   {  i /= 10;
      result++; }
   return(result); }
//____________________________________________________________________
static const double CConstVolume::VolumeMAX = ::SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
//____________________________________________________________________
static const double CConstVolume::VolumeMIN = ::SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
//____________________________________________________________________
static const double CConstVolume::VolumeSTEP = ::SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
static const double CConstVolume::ZerroPrice = ::NormalizeDouble(0.0, _Digits);
//____________________________________________________________________
static const int CConstVolume::VolumeDIGITS = CConstVolume::GetDigitsInVolumeStep();
//____________________________________________________________________




//+------------------------------------------------------------------+
//|   class COrder                                                   |
//+------------------------------------------------------------------+
class COrder : private CConstVolume
{
private:
   SOrderInfo        m_info;        //структура для инициализации класса, и хранения информации о ордере, тип, цена отркытия, лот, и состояние ордера
   CError            error;         //класс с описание ошибок на 2-х языках
   int               sl_error_count;//счетчик ошибок установки стоплосса/тейка
   bool              m_needstoploss;//флаг для установки стоплосса, сбросим когда все ОК
   bool              CheckMarginRequirements();
   bool              ServerDisable();
   int               Ordersend();
   int               CheckOrderByMagicnumber(int magic_);   //метод нужен для поиска открытого ордера по магику, использую в конструкторе
   void              SetStoploss();
   void              NULLOrder()             { ZeroMemory(m_info); m_info.cmd = -1; m_info.status = ErrorOrder; m_needstoploss = false;   }
   void              PrintError(string func) { Print(func); error.GetLastError();                                                         }
public:
                     COrder():m_needstoploss(false) { NULLOrder();                                                                        }
                     COrder(SOrderInfo &ordersetting);
   SOrderInfo        GetOrderInfo(); 
   bool              Orderclose();};
//________________________________

を使用し、1つのシンボルで使用することに注意してください。

すべてにおいて、意図したとおりに動作している......。しかし、私はそれが好きではありません、私が上に書いたように、それは面倒で余分なものです。

 
Dmitry Fedoseev:

また、クラスを使わないと、SymbolInfoDouble(_Symbol,SYMBOL_BID)のようなものを常に書いていると、疲れてしまうでしょう。 これは、毎回踊っている ...

特に、最近のビルドでようやくnamespaceが追加されたことを考慮すると、すべてが素晴らしい。 以前はstaticメソッドとして実装しなければならなかったが、今はすべてがはるかに簡単だ。

namespace SymbolInfo
{
  double Bid(string symbol) { return SymbolInfoDouble(symbol, SYMBOL_BID); }
  double Ask(string symbol) { return SymbolInfoDouble(symbol, SYMBOL_ASK); }
};
 
Alexey Navoykov:

特に、最新のビルドでようやくnamespaceが追加されたのは素晴らしい。 以前はstaticメソッドとして実装しなければならなかったが、今はすべてがシンプルになった。

限度額内であることが本当に重要なのでしょうか?境界を守ることが重要な場合は、関数も書くことができます。

 
Igor Makanu:

注文を設定するためのアクションはたくさんありますが、ここでは、オープン、クローズ、ストップロスの設定、さらに注文状況を 出力する方法を知っているクラスについて、私のビジョンを説明します。

を使用し、1つのシンボルで使用することに注意してください。

全体として、すべてが意図したとおりに動いている......。しかし、私はそれが好きではありません、私が上に書いたように、それは面倒で余分なものです。

そうそう、ここでも何度も出てくる、明確な答えのない質問です。自分のクラスを継承する必要がある場合 - 継承するのと、新たに拡張版を書くのと、どちらが良いでしょうか。

 
Alexey Navoykov:

特に、最新のビルドでようやくnamespaceが追加されたのは素晴らしいことです。 以前はstaticメソッドとして実装しなければなりませんでしたが、今はずっとシンプルになりました。

簡潔な表記がないんですね、チェックがなければそのまま書いた方が楽です。

#define  Ask SymbolInfoDouble(_Symbol,SYMBOL_ASK)
#define  Bid SymbolInfoDouble(_Symbol,SYMBOL_BID)

void OnStart()
  {
   Print("Ask = ",Ask);
   Print("Bid = ",Bid);
  }
 
Igor Makanu:

を使用し、1文字で使用することに注意してください。

コンストラクタにシンボル名を渡して、クラスを柔軟かつ汎用的にすることを妨げるものは何ですか? ポートフォリオトレードの可能性を原則と考えないのですか?
 
Igor Makanu:

エントリーは、チェックがなければそのまま書きやすいので、簡潔なものではありません。

SymbolInfoDoubleの ような関数がたくさんあります。全部に短い名前をつけるのは面倒ですが、クラス化することで名前の一意性を全く気にすることなく使えます。

 

私は以下の回路で問題なく使用できています。

  1. TCと書くのはテスターのためだけです。ログやエラーハンドラーなど、くだらないものは一切ありません。コードは非常に簡潔で理解しやすく、OOPで行えば編集も可能です(ただし、基本的なものではありません)。すでにKBに例を掲載しています。ボーナスは高速な最適化 です。
  2. 主にテスター用と独立したブロックで利用できるようにすることです。売買シグナルの生成-1ブロック。シグナルトレード - もう一つのブロック
  3. リアルアカウントへの転送は、常に複数の同じ動きで行われます。TSは、コードを変更することなく、仮想環境に置かれる。複数のTSを一つの環境に置いたり、それぞれのTSを独立した環境に置いたりする場合、OOPは特に便利である。そして、コピー機(マーケットにはコピー機がたくさんあるので、人々はコピー機の論理に長けています)を使って、取引や注文を仮想環境から現実の環境に単純にコピーします。
  4. この方式なら、TSの書き込みも素早く簡単にできます。リアルへの移行は(実際には稀ですが)いつも統一された迅速かつ明確な方法で行われます。
 
Igor Makanu:

あなたのエントリーは簡潔ではありません、チェックがない場合、そのまま書くと簡単です。

そういうわけにはいきません。少なくともBid()とAsk()の両方を呼び出す必要があります。 あなたのエントリは単なる変数のように見え、その値が変化していないように見せかけますが、実際にはそうではありません。
 
Alexey Navoykov:
コンストラクタにシンボル名を渡して、クラスを柔軟かつ汎用的にすることを妨げるものは何ですか? 根本的にポートフォリオトレードの可能性を考えていないのでしょうか?

その妨げとなるのは、1文字のEAがほとんどであり、シンボルを渡すことが不要な(疲れる))アクションになる場合がほとんどであることです。もうひとつは、デフォルトでチャートシンボルが自動的に選択されるようにし、必要であればしばらくの間、シンボルを上書きすることができるようにすることです。しかし、1つのクラスのインスタンスを使い、必要に応じてシンボルをオーバーライドするのと、シンボルごとに別のインスタンスを作成するのと、どちらが良いかという疑問が再び湧いてくる。