そもそもオブジェクト指向ってなんだ?
オブジェクト指向なんて知らなくてもEAは作れる
このページをご覧の方は別にプログラマーではないけどMT4で動作する簡単なEAくらいは作ったことがあるという方でしょうか。そのときはオブジェクト指向なんて言葉は聞かなかったかもしれません。
MT4のEA作成に使用されるMQL4という言語はオブジェクト指向向きの言語ではありません。今ではオブジェクト指向プログラミングもできるようになってますが、おおもとの仕組みは昔ながらの手続き型プログラミング用の言語です。Web上のサンプルコードもオブジェクト指向で作られているものは少なく、オブジェクト指向という言葉に触れる機会もなかったでしょう。
そのせいかMT4とcTraderを比較した記事ではcAlgoはプログラムの勉強が大変とか、オブジェクト指向という概念がわかりにくいとか、まるでC#が難しいかのような意見が散見されます。確かにプログラミングになじみがない方から見るとそう見えるのかもしれません。
じゃあ知らなくてもいいんじゃないの?
いえいえ、それは非常にもったいないです。確かにオブジェクト指向の話となると、いろんな用語が出てきて敷居が高く感じるかもしれません。しかし、少しわかってしまえばオブジェクト指向の方が直感的でわかりやすいと個人的には思います。
また、プログラミングをスキルとして身に着けたいという人にとってはオブジェクト指向の知識は必須です。Webアプリを作るにせよ、スマホアプリを作るにせよ今はオブジェクト指向で作るのが当たり前となってます。
ここではオブジェクト指向とはなんなのか、手続き型とはなにが違うのか、ということを簡単に説明したいと思います。
なお、MT4とかMQLとかcAlgoとかさっぱり知らんけど、このページに迷い込んでしまったという方はMQL→C言語、cAlgo→C#に読み替えてご覧いただけるとなんとなく通じるかもしれません。
手続き型プログラミングとオブジェクト指向プログラミングの違い
手続き型では「手順書」をプログラムする
手続き型プログラミングは用意されてる機能を並べて新しい機能をプログラムします。自動売買システムなら「自動売買を行う機能」を作ります。
例えばMQLには「標準関数」と呼ばれる関数が数多くあります。たとえば「文字列を切り分ける関数」だとか「配列を並び替える関数」だとか、全部どこからでも使える関数として用意されてます。また、自分で新たに関数を作ることもできます。
さらに必要に応じてプログラムの状態を記録しておく変数なども用意でき、この変数にもどこからでもアクセスできます。
プログラマーは変数による計算処理や様々な関数をうまく組み合わせて新しい機能を実現する「手順書」をプログラムします。プログラムの実行時は作成した機能が呼び出され、手順書通りに計算処理と関数が上から並べられた順に実行されます。
オブジェクト指向では「設計書」をプログラムする
オブジェクト指向プログラミングは「オブジェクト=モノ」中心の視点で考えて、さまざまなモノの機能を組み合わせて、新しい機能を持ったモノの「設計書」であるクラスをプログラムします。
もちろんこの「設計書」の中に機能を実現するための「手順」も含みます。自動売買システムなら「自動売買を行う機能を持ったクラス」を作ります。
例えばcAlgoで新しいプログラム(cBot)を作ろうとすると、最初に本体のクラス (仮に名前をMyRobotとしましょう)の雛形が自動的にに作られます。プログラマの仕事はこのMyRobotクラスの中身を作ることです。
どこからでも使える標準関数のようなものはありませんが、便利な道具は最初から用意されてます。様々な機能(≒関数)をもった様々なクラスです。
例えば文字列用のstringクラスは自分自身を切り分ける機能を持っていますし、リストのListクラスは自分自身を並び替える機能を持っています。
また、どこからでも参照できるプログラムの状態変数のようなものもありませんが、それぞれのオブジェクトが自分の状態や必要な情報をプロパティや自分しか見ない自分専用変数(C#ではフィールドと呼ばれる)として保持することは可能です。
これらクラスオブジェクトの機能や情報にはそのクラスのオブジェクトを通じてしかアクセスできません。
クラスはあくまで設計書なので、自分が使いたいクラスがある場合は最初に自分で用意してあげる必要があります。例えばListという名前のオブジェクトを使いたいならvar li = new List();みたいな感じでオブジェクトを作るところから始まります。
(なお、cAlgoの場合はMyRobotのベースとなるRobotクラスが最初からいくつかのオブジェクトをプロパティとして持ってますので、自分で作る必要はありません。)
そして、それら手元にあるオブジェクトの機能を組み合わせて、MyRobotの機能を設計するのです。プログラマーが作ったクラスはあくまでMyRobotオブジェクトの「設計書」ですが、プログラムの実行時はMyRobotが設計書通りに実体化され、必要な機能が呼び出されるという形で実行されます。
結局はどっちも同じことなんじゃないの?と思うもしれません。そうです。最終的には同じことが起きてます。あくまでオブジェクト指向というのはプログラミングのやり方をさすものであり、「オブジェクト指向だから超高性能なプログラムができるぜー!」みたいなことはありません。
ただし、一般的にプログラムが大規模になればなるほど、オブジェクト指向の方が作りやすく、メンテナンスもしやすいといわれています。
で、オブジェクト指向だと何がいいの?
オブジェクト指向のメリット
さて、ここまでみてきてどうでしょう。プログラムのどこからでも関数や変数を自由に使える手続き型と、オブジェクトを通じてしか関数や変数にアクセスできないオブジェクト指向、一見するとオブジェクト指向は不自由でデメリットが大きいように感じるかもしれません。
ところがです、実はここがオブジェクト指向の最大のメリットなのです。
例えば、ここに数千行のソースコードからなるそこそこ大きなプログラムがあるとします。
もし手続き型で作られていたら?
あるとき、この機能の一部、関数Aを別のプログラムで使いたいということになりました。単純に考えれば、関数を丸っとコピペでもすればいいだけのように思えますが、関数Aの中でプログラムの状態を記録しておいた変数aにアクセスしてたらどうでしょう。
もしくは中で別の関数Bを呼び出してたらどうなるでしょう。「えっと、じゃあ変数aと同じの用意して、あとこの関数Bも持ってきて、あ、でもこの関数B内では変数bと関数Cも使ってるからこっちも持ってきて・・・」一つの機能を移植するだけでとんでもない手間と労力がかかります。
おっと、今度はバグ対応でプログラムを改修する必要がでてきました。関数Aのなかで変数bの値も変更しなければいけなかったようです。じゃあ関数Aの処理をさらっと書きかえて無事終了・・・とはいきません。
変数bの値を書き換えたことにより、変数bを使ってる他のすべての関数で挙動が変わってしまっている可能性があります。なので変数bを使ってる関数すべてを確認する必要があるのです。さて、まずは数千行のコードの中で変数bを使ってる部分を探すとこから始めましょうか。・・・気が遠くなりますよね。
もしオブジェクト指向で作られていたら?
ではこのプログラムがオブジェクト指向で作られていた場合はどうでしょう。関数Aの機能が使いたいなら、関数Aを持つクラスをまるごとそのまま再利用するだけです。
各クラスはそれぞれ独立した機能と情報を持っていますので、切り離して再利用がしやすいのです。もちろんクラスのプロパティとして別のクラスを持っていたりとクラス同士の関連性は多少なりともでてきますが、クラスという大きな塊間の関連性を把握しておけばいいだけなのでそこまで大変な話ではありません。
プログラムを改修するときも同様です。クラス内から変更できるのは自分のフィールドだけなので、改修時も機能自体をまるっと変更するような改修でない限りは影響は自分のクラス内だけでおさまります。
つまりクラスが改修されクラス内の挙動が多少変わったとしても、これまで使われてた機能や情報が外から見てなにも変わってないのであれば、クラスを使う側からはなにも気にしなくていいのです。
(「いやいや、俺の知ってるオブジェクト指向で作られたアプリはクラス同士がめちゃくちゃにこんがらがってちょっとした改修も再利用もとんでもなく大変だったぞ!」という場合は、そもそも一番最初のアプリの設計自体がマズイです。)
自動売買システム作成にはどっちがいいのか
ここまでさんざんオブジェクト指向をよいしょしておきながらなんですが、簡単な自動売買システムに限って言えば、ぶっちゃけどっちでもいいと思います。
オブジェクト指向で作っておいた方が、大規模になってもメンテしやすい、部品の再利用がしやすい、という利点は確かにあります。ですが、そもそも一つのEAやcBotでそんな大掛かりになることは稀でしょうし、手続き型でも作り方さえ工夫すれば機能の再利用は可能です。
また同じ機能であればクラスやオブジェクトをごちゃごちゃ使わない手続き型中心で作った方が、(微々たる差ですが)動作は軽くなるというメリットもあります。
MT4のサンプルコードの多くが、オブジェクト指向じゃなく書かれているのも、「オブジェクト作るほどのもんでもないから」という理由も大きいと思います。
じゃあなんでcBot開発はオブジェクト指向なんだ
一言でいうならcBot開発で使われるC#はオブジェクト指向の言語だからです。そして開発に使われるcAlgoAPIもオブジェクト指向で用意されています。そのため、cTraderで動くcBotやIndicatorを作りたいならオブジェクト指向は必須の考え方なのです。
一応、OnStart()やOnTick()内にだけずらっと処理を並べて手続き型っぽく作ることはできますが、どうしてもその中ではオブジェクトを扱う必要が出てきます。なのでオブジェクトの使い方くらいは知っておく必要があります。
逆に言えば、自分でクラス作ったりすることはできなくても、用意されてるオブジェクトだけ使うことができればcBotは作れます。
まぁ、プログラムやるなら避けては通れない考え方ですし、基本くらいは身に着けおきましょう。大丈夫、繰り返しになりますが、わかってしまえば簡単です。
最初は聞いたことない用語に圧倒されてなんとなく難しそうに見えてるだけです。次の記事では用語を解説していきます。