インジケーターの開発費用の見えない事情

プログラマーの技術の差
yuki
yuki
本日はインジケーター開発の裏側のお話です
カオチャイ
カオチャイ
サインツールの開発料金は業者によってお値段に差がでますが、こういう部分は一体何が違うのか?というお話でございますよ

プログラムのコードはいかに少なく、いかに美しく

MT4のツールを作成するためのMQL言語は、たとえチャート上で同じ挙動をするソフトウェアだとしてもコードを見れば誰が書いたかがわかるくらいに個性がでます。

これは、1つの結果を出すためにとれる選択肢がたくさんあることが原因なのですが、サインツール開発業者のお値段の違いというものはこのあたりがどうやら関わっているようです。

たとえば下記の2種類のコードはMT4上ではどちらもトレイリングストップを行うコードですが、書き方はここまで差が出ます。

だめな例
for(int i = 0; i < OrdersTotal(); i++) {
      if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
         if(OrderSymbol() == Symbol()) {
            if(OrderMagicNumber() == MagicNumber) {
               if(OrderType() == OP_BUY) {
                  if(NormalizeDouble(OrderStopLoss(), Digits) < NormalizeDouble(Bid - _Point * TrSt, Digits)) {
                     bool result = OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(Bid - _Point * TrSt, Digits), OrderTakeProfit(), 0, clrBlue);
                     if(result == false) {
                        Print("OrderModify error " + GetLastError());
                     }
                  }
               }
               if(OrderType() == OP_SELL) {
                  if(NormalizeDouble(OrderStopLoss(), Digits) > NormalizeDouble(Ask + _Point * TrSt, Digits)) {
                     bool result = OrderModify(OrderTicket(), OrderOpenPrice(), NormalizeDouble(Ask + Point * TrSt, Digits), OrderTakeProfit(), 0, clrRed);
                     if(result == false) {
                        Print("OrderModify error " + GetLastError());
                     }
                  }
               }
            }
         }
      }
   }

 

良い例
for(int i = 0; i < OrdersTotal(); i++) {
      if(!OrderSelect(i, SELECT_BY_POS)) continue;
      if(OrderSymbol() != Symbol()) continue;
      if(OrderMagicNumber() != MagicNumber) continue;

      if(OrderType() == OP_BUY) {
         double trailingStop = NormalizeDouble(Bid - TrailingPips * Point, Digits);
         if(NormalizeDouble(OrderStopLoss(), Digits) < trailingStop) {
            if(!OrderModify(OrderTicket(), OrderOpenPrice(), trailingStop, OrderTakeProfit(), 0, clrRed))
               Print("OrderModify error ", GetLastError());
         }
      } else if(OrderType() == OP_SELL) {
         double trailingStop = NormalizeDouble(Ask + TrailingPips * Point, Digits);
         if(NormalizeDouble(OrderStopLoss(), Digits) > trailingStop) {
            if(!OrderModify(OrderTicket(), OrderOpenPrice(), trailingStop, OrderTakeProfit(), 0, clrRed))
               Print("OrderModify error ", GetLastError());
         }
      }
   }

 

カオチャイ
カオチャイ
同じ挙動なのに随分と内容が違いますねぇ・・
yuki
yuki
悪い例の方はエラーが起きた時に処理を止める記述なども抜けていたのでそこはさすがに修正しておいてあげましたがそれでもだいぶ異なりますね
カオチャイ
カオチャイ
ちなみに動作確認はしておらず、あくまでサンプルですのでご注意くださいね!

 

コードの書き方が変わる理由

yuki
yuki
ここでコードの書き方を毎週のゴミ出しに例えてみましょう
カオチャイ
カオチャイ
例として、「毎週月曜日(祝日の場合は翌火曜日)の朝9時までにゴミを出す」というロジックで考えてみますと・・・
熟練プログラマの場合

もし(if)(月曜日 or 月曜日が祝日で今日は火曜日)
if(現在時刻<朝9時)
ゴミを出す

カオチャイ
カオチャイ
と、このようにシンプルなコードで仕上げます、しかし経験の浅い開発者はこのようなコードの書き方が思いつかずに・・・

 

新人プログラマの場合

もし(if)(月曜日) 月曜日だとチェック
if(月曜日=祝日)月曜日は祝日だとチェック
if(火曜日) 火曜日のチェック
if(現在時刻<朝9時)ゴミ捨てチェック
if(月曜日のチェックがON or 月曜日は祝日のチェックがON & 火曜日のチェックON & ゴミ捨てチェックON)
ゴミを出す

というような基本的なコードの書き方のみで動かそうとしてしまいます。

熟練プログラマのコードは「月曜日か火曜日以外は一切時間を確認しない(する必要がない)」のに対し、後者はたとえ土曜日であっても「今何時だ?9時前だ。ゴミ捨てしなきゃ」という判定を毎回してその分CPUのパワーが取られてしまいます。

こういう無駄な処理をどれだけ削除するかが軽量化とエラーを防ぐ鍵なんですね。

 

プログラマーの実力の差がでるコード例

yuki
yuki
それではプログラマの実力がでるコードをご紹介です
カオチャイ
カオチャイ
下記は一見同じ処理をしているように見えますが、悪い例はティック毎に4つの指標を全部計算するのに対し、
良い例は指標を1つずつ計算し、条件に合わない指標が出た時点で処理をやめております
yuki
yuki
そのため、インジケーターの重さに差が出てくるんですね
無駄な処理が毎回発生する悪い例
void OnTick() {
   for(int i = limit - 1; i >= 0; i--) {
      double ma5 = iMA(省略);
      double ma5_1 = iMA(省略);
      double ma20 = iMA(省略);
      double ma20_1 = iMA(省略);

      bool isGoldenCross = false;
      if(ma5_1 < ma20_1 && ma5 > ma20) {
         isGoldenCross = true;
      }

      double bb20_sigma2_upper = iBands(省略);
      bool underSigma2 = false;
      if(bb20_sigma2_upper < Close[i]) {
         underSigma2 = true;
      }

      double rsi14 = iRSI(省略);
      bool rsiUnder60 = false;
      if(rsi14 < 60) {
         rsiUnder60 = true;
      }

      double sugoiIndicator = iCustom(Symbol(), PERIOD_CURRENT, "sugoiIndicator", 省略);
      bool sugoiIndicatorFlag = false;
      if(sugoiIndicator > 100) {
         sugoiIndicatorFlag = true;
      }

      if(isGoldenCross && underSigma2 && rsiUnder60 && sugoiIndicatorFlag) {
         OrderSend();
      }
   }
}

 

条件に合わない判断が出たらそこで処理を止める良い例
void OnTick() {
   for(int i = limit - 1; i >= 0; i--) {
      if(IsGoldenCross(i) && UnderSigma2(i) && RsiUnder60(i) && SugoiIndicatorIsTrue(i))
         OrderSend();
   }
}
bool IsGoldenCross(int bar) {
   double ma5 = iMA(省略);
   double ma5_1 = iMA(省略);
   double ma20 = iMA(省略);
   double ma20_1 = iMA(省略);

   return (ma5_1 < ma20_1 && ma5 > ma20);
}
bool UnderSigma2(int bar) {
   double bb20_sigma2_upper = iBands(省略);
   
   return bb20_sigma2_upper < Close[bar];
}
bool RsiUnder60(int bar) {
   double rsi14 = iRSI(省略);
   
   return rsi14 < 60;
}
bool SugoiIndicatorIsTrue(int bar) {
   double sugoiIndicator = iCustom(Symbol(), PERIOD_CURRENT, "sugoiIndicator", 省略);
   
   return sugoiIndicator > 100;
}

 

yuki
yuki
良い例と悪い例では、条件によっては計算量に2倍以上も差がでます
カオチャイ
カオチャイ
しかしツールとして売られていると、こういう差は残念ながらわかりませんね・・
yuki
yuki
たしかに一見わかりません。しかしコードを複雑に書いてしまうとある条件が整った時などに、売りと買いのサインが両方同時にでてしまうというエラーをもったまま売りに出されているツールも存在しますので、注意が必要です
カオチャイ
カオチャイ
自動売買は放置する人が多いのでこういうエラーは気づかないままスルーされることも多いですしね

開発依頼はやっぱり専門業者が安心

このように熟練プログラマと新人プログラマではコードの書き方に大きく差がでます。

一般の人が見ても区別がつかないですが、プログラマの世界ではコードを見れば実力が一発でわかってしまうので、お給料なんかは完全に差が出るんですね。なので熟練プログラマ揃いの業者はやはり開発コストが高くなってしまう傾向があります。

最近はプログラミング学校を出たばかりの開発者さんが、自分のスキルアップのためにSNSなどで格安でサインツールの作成依頼を募集したりしますが、これは勉強のためもあるので利益度外視で引き受けてくれる事があります。

しかしツールの内容によってはもちろん実装できないものも数多くあります。

これが開発ノウハウがある会社でしたら熟練プログラマに聞けば解決ですが、経験の浅い個人プログラマーは気軽に質問ができる熟練プログラマとの繋がりは持っていないのが普通ですので、何時間も費やしてエラーと戦ったものの原因がわからず解決できないことが多々あります。

それを正直に依頼主へ「できない」と正直にお伝えするならまだ良い方で、ここまで費やした開発時間と頓挫した事実を伝えるのはプライドが許さず、かなりの確率で返金せずに「逃亡」があったりします。

ですので、もしサインツールの作成をお願いするのでしたらできれば個人は避け、ある程度受注実績があり、きちんと法人登記されている業者に依頼するのが最善なのです。

yuki
yuki
個人案件では納品されないといったクレームは近年多発しています
カオチャイ
カオチャイ
あと、個人案件は納品日のノルマはあってないようなものなので、引き伸ばして訴えられないように間を取りつつけるというプログラマーも多く存在しますので注意してくださいね!

※開発中で納品できない=納品する気はあるのでお客さんが訴えることはできない。注文のキャンセルもお客さん都合なので全額戻ってこないことが多い。

 

EA・インジケーター制作のご依頼はこちら
インジケーターのバックテスト&リペイントチェック代行サービスMT4やMT5に関するツールを作成する際の流れを説明しています。 シストレファクトリーでは一からEAの制作以外にもツールの修正や、統計的なアプローチができるソフトなどお客様の欲しいツールを形にいたします。...
EA&インジケーター制作代行
【MT4&MT5】EA&インジケーター制作代行承ります EA&インジケーター制作代行とは? EA&インジケーター制作代行では、皆さんが日頃使っている手法をMT4(MT5)でエントリーサイ...

 

インジケーターをより使いやすく
MQLコードでEAをカスタマイズ
【MQLコード解説】EA・インジケーターのカスタマイズ【体験版・LINE通知】EAやインジケーターに口座番号認証を実装する方法を紹介しています。 認証システムにはMQLAuthを利用して解説していきます。...
MQLAuth準備編
MQLAuthシステムを利用するための事前準備 MQLAuthを使うための準備 MQLAuthシステムを使う前提条件として「インジケーターをMT4の口座番号やパスワードで縛って管...
バイナリーオプションツールに認証をつける
バイナリーオプションのインジケーターに口座認証を実装する方法 https://interactivebrokers.work/start_mqlauth/ 口座番号認証はパスワードよりも安...
体験版EA
自動的に期限付き体験版になる機能をEAに追加する方法 https://interactivebrokers.work/start_mqlauth/ 体験版機能を使うとなにができる?...
メッセージ送付機能
配布したEA利用者のMT4にメッセージを一斉配信する方法 https://interactivebrokers.work/start_mqlauth/ 一斉送信機能で確実な宣伝が可能に...