classって何?
詳しく書くと難しくなるので、適当に。自由に定義できるデータのひな形です。作りたいプログラムをオブジェクト(物)単位で分割して、オブジェクト間のメッセージのやり取りで処理を設計します。そのオブジェクトの型がclassです。こんな抽象的な説明では理解できなくて当然です。ここはそんなもんかと流してください。
今回は取引の状態クラスを定義します。
基底クラス
各状態のひな形を基底クラスといいます。主にオブジェクトのインターフェース(使い方)を定義します。
設計段階では約定イベントを定義していましたが、今回はMQL4の実装の都合上、tick発生時に毎回呼び出されるcheck関数に判定を含めることとし、イベントにはしていません。設計通りに実装するなら、チケット番号を管理するクラスを作って、変化したらイベント通知するようにするべきですね。異常系の処理も必要なので今回は各状態で注文状態をチェックすることとしました。各状態で共通の変数としてg_ticketを定義しています。
// 状態基底クラス
class CStatus {
private:
// 現在の状態番号
int m_status;
protected:
// チケット番号(クラス共通の変数)
static int g_ticket;
public:
// コンストラクタ(初期化)
CStatus(int st) { m_status = st; }
// 売りシグナル
virtual int sell_signal() { return status(); }
// 買いシグナル
virtual int buy_signal() { return status(); }
// 状態確認(注文の状態が想定外かどうかをチェックする)
virtual int check() { return status(); }
// 現在の状態を返す
int status() { return m_status; }
};
// 静的変数の宣言
int CStatus::g_ticket = -1;
CStatusは基底クラスといって状態のひな形です。主に外部からのインターフェースを定義しています。各状態では状態チェック(check関数)と売り買いのシグナル(sell_signal関数, buy_signal関数)がOnTickで呼び出されます。状態に応じた処理を行い、次の状態番号を返します。このCStatusを継承して複数のオブジェクトを作ります。
状態毎に処理を分けることで、二重注文を防ぐことができプログラムが読みやすく、メンテナンスしやすくなります。特に、発注してから約定するまでの間や動作中にユーザーが手動でポジションを決済してしまった場合などの処理をシンプルに書くことができます。状態の設計については後述します。ここではなんとなくの理解で構いません。