
初めてのGrail
"... アートはプログラムされることはありません。詩の二つ意味は
混ぜられることはありません。才能は、
正条植えによっては成長されません。
.. 彼らは生まれるのです。それらは、国家の富である
ラジウム預金のようなもので、
スィグルダやべテスダの9月のようです。"
(Andrey Voznesenskiy)
Holy Grail はChristが一般的に最後の夕食で酔っ払った際に使用したカップで、十字架から血をとる際にJosephによって使用されたものであると考えられています。その聖餐杯を栄養を提供する石で、1週間以内に死ぬことを防ぐものとして表現します。こちらでさらに詳しく知ることができます。また、インターネット検索エンジンを使用してください。
その単語 "grail"は今では現代のプログラムに皮肉的に使用されています。すべての場合に当てはまる「普遍的な」プログラムを作成することは不可能であるという意味で使用されています。MQL4はにおけるプログラミングに関して、この単語は実際のトレーディングにおいて効果的なエキスパートを作成することは不可能という意味を指します。
実際、Forexは、経済・産業の関係、人格、政治などの複雑な現象の集合体の繁栄です。さらに、簡単に公式化することはできません。熟練したトレーダーは、もしトレンドを示す3から5以上のサインがあれば、マーケットに入ることを勧めます。
同時にその規則はかなり高い成功確立のマーケット予測における基礎を完全に提供することはできません。著名な銀行や金融機関の一流のアナリストによってなされる矛盾のある予測は、これを保証しています。全てのアナリストは例外なくすでに起こっている出来事に対しては上手に解釈しますが、ほとんどは自信のある予測を行うことはできません。
それらに焦点を当ててみましょう;彼らはできることをやっているだけで、多くは長いトレーディング経験や知識を持っています。しかし、それを適切に述べるとすれば、彼らのほとんどが失敗しています。彼らはビッグに見え、多かれ少なかれ人気を博し、時折かなりの遺産を残します(Trading for a Living: Psychology, Trading Tactics, Money ManagementというタイトルのAlexander Elderの本にてよく記載されています。)、しかし、事実は依然、 熟練したアナリストがしばしば間違えるということです。
したがって、これらの状況を考慮し、Forexでのトレーディングに最初のステップを踏もうとする初心者プログラマをどうすれば良いのでしょうか?初心者が歩む「聖杯」探求への道を辿ってみましょう。
1. "聖杯"は何で構成されるのか
形式的なロジックにおいて、権威を主張することは証拠とはみなされません。これを知ると、初心者は大方このように推測します:「聖杯の作成は不可能であると証明できるのか?証明できない?もしできないのであれば、それは可能だ!". 初心者は、そのようなものを作成することができるかは未だ証明されていないということを考慮に入れません。そして、その他の「金鉱探し」の経験を学んだり、検討しようとせず、熱意に基づく「できる!」という自分の考えに突き動かされ、プログラミングを始めます。
1.1. 公式の戦略
多くの場合、初心者プログラマは、短期間でかなり利益を生むトレーディング戦略を作成するという作業を自己に課しません。Forexでの大きい利益を生むという夢に奮起され、トレーディング基準が利益を生むエキスパートにおいて必要であると気付きません。
良い基準を見つけるために初心者はMetaTrader 4クライアントターミナルを開き、M!のタイムフレームのEURUSDチャートを見てください。通過レートが波のように変化していることに気づくでしょう。プログラマはこれらの波にて利益を生むことにします。しかし、その波をつかむには、例えば波は上昇をやめ、下降することを知る必要があります。
- もしレートが特定のポイント、例えば、10から15に上昇し、上昇をやめ、およそ3ポイントほど下降(図1 移動 B-C)した場合、(図1移動 A-B)マーケットが下降の動きの時に参加される必要があると想定する。この時、マーケットの降下移動は予測されます(図1のC-D)Buyのクロージングに使用される同様の基準
-
もしレートが特定のポイント、例えば、10から15に下降し、下降をやめ、およそ3ポイントほど上昇(図1 移動 C-D)した場合、(図1移動 D-E)マーケットがその上方の動き(Buy) の時に参加される必要があると想定する。この時、そのマーケットの上昇の動きは予測されます(図1 E-F)Sellのクロージングにおいて使用される同様の基準

図1. エキスパートGraal_1 (Grail 1).におけるトレーディング基準
時折予想もしない驚きの経験を与えることがあります:3ほどだけで初心者プログラマが「聖杯」を作成することができました。
extern int TP=100; extern int SL=100; extern int lim=1; extern int prodvig=3; extern double Prots= 10; int total, bb=0,ss=0; double max,min,lmax,lmin,Lot; int start(){ total=OrdersTotal(); if (total==0){bb=0;ss=0;} if (max<Bid) max=Bid;if (min>Ask) min=Ask; if (((max-Bid)>=lim*Point)&&(Bid>lmax )) { for (int i=total;i>=0;i--) { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderType()==OP_BUY) {OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE); bb=0;}} Strateg(1); } if (((Ask-min)>=lim*Point)&&(lmin>Ask )) { for (i=total;i>=0;i--) { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderType()==OP_SELL) {OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE);ss=0;}} Strateg(2);}return;} void Strateg (int vv) {if (vv==1 && ss==0) {OrderSend(Symbol(),OP_SELL,Lots(),Bid,3,Bid+SL*Point,Bid-TP*Point,"",0,0,Red); ss=1;} if (vv==2 && bb==0) {OrderSend(Symbol(),OP_BUY, Lots(),Ask,3,Ask-SL*Point,Ask+TP*Point,"",0,0,Blue);bb=1;} lmax=Ask+prodvig*Point; lmin=Bid-prodvig*Point; return; } double Lots(){ Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1); double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); if (Lot==0 ) Lot=Min_Lot; return(Lot); }
作成することができました。寛大になりましょうーこれはスタイルがまだ形成されていない初心者プログラマの最初の経験です。そして、本当に素晴らしい結果を残したので、このエキスパートを褒め称えましょう。
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // Graal_1.mq4 (Grail 1). // Used as an example in the article My First "Grail". // Sergey Kovalyov, Dnepropetrovsk (Ukraine),sk@mail.dnepr.net,ICQ 64015987, http://autograf.dp.ua/ //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж extern int TP = 100; // TakeProfit orders extern int SL = 100; // StopLoss orders extern int lim= 1; // Distance of the rate return extern int prodvig=3; // Distance of the rate progress extern double Prots= 10; // Percentage of the liquid assets //-------------------------------------------------------------------------------------------- int total, // Count of lots bb=0, // 1 = the Buy order is available ss=0; // 1 = the Sell order is available //-------------------------------------------------------------------------------------------- double max, // Maximum price at the peak (abs.) min, // Minimum price in the trough(abs.) lmax, // Limiting price after the exceeding // of which we consider selling(abs.) lmin, // The same for buying Lot; // Count of lots //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int start() { //============================================================================================ total=OrdersTotal(); // Count of lots if (total==0) // If there are no orders, .. { bb=0; // .. no Buys ss=0; // .. no Sells } if (max<Bid) max=Bid; // Calculate the max. price at the peak if (min>Ask) min=Ask; // Calculate the min. price in the trough //------------------------------------------------------------- The price turns down ---- if (((max-Bid)>=lim*Point)&&(Bid>lmax )) // Turn at a high level { for (int i=total;i>=0;i--) // On all orders { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderType()==OP_BUY) { OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE);// Close Buy bb=0; // No Buys anymore } } Strateg(1); // Opening function } //------------------------------------------------------------ The price turns up ---- if (((Ask-min)>=lim*Point)&&(lmin>Ask )) // Turn at the deep bottom { for (i=total;i>=0;i--) // On all orders { if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true && OrderType()==OP_SELL) { OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE);// Close Sell ss=0; // No Sells anymore } } Strateg(2); // Opening function } //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж void Strateg (int vv) // Opening function { //============================================================================================ if (vv==1 && ss==0) // Sell situation and no Sells { OrderSend(Symbol(),OP_SELL,Lots(),Bid,3,Bid+SL*Point,Bid-TP*Point,"",0,0,Red);// Откр ss=1; // Now, there is a Sell } //-------------------------------------------------------------------------------------------- if (vv==2 && bb==0) // Buy situation and no Buys { OrderSend(Symbol(),OP_BUY, Lots(),Ask,3,Ask-SL*Point,Ask+TP*Point,"",0,0,Blue);// Откр bb=1; // Now, there is a Buy } //-------------------------------------------------------------------------------------------- lmax=Ask+prodvig*Point; // Redefine the new limiting .. lmin=Bid-prodvig*Point; // .. levels for open and close //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж double Lots() // Calculation of lots { //============================================================================================ Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1);// Calculate the amoung of lots double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); // Minimum permissible cost of lots if (Lot == 0 ) Lot = Min_Lot; // For testing on const.min.lots //============================================================================================ return(Lot); } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж /*
一般的にそのエキスパートの内容はかなり理解しやすいです。
その上部では、start()関数前に変数が収集されています。start()関数にて、スロープの頂点にて現在のレートの位置がまず計算され、その状況がトレーディング基準を満たすか分析されます。もしその基準が満たされれば、すでに処理されている注文がクローズされます。二つの以上の関数がエキスパートが使用されています - 新規注文をオープンするためのStarteg()とロットの量を決定するLots()です。変数 ssとbbがオープンされた注文を予約するために使用されます。
ストラテジーテスターは、MetaTrader 4クライアントターミナルにておいてかなり重要なツールです。プログラマは、インプットを最適化するために注意深くエキスパートをテストしました。最良の結果の一つが以下になります:
プログラマが喜んでいる姿を容易に想像できます:彼自身で作品を完成させることができました!こちらが彼らの初めての「聖杯」です!くそのプログラマはシンプルな結論を下しました: "自分だけが作成した!"
1.2. 上級の投資

図3. 攻撃的な投資は、不当な損失につながりうる
我々のヒーローは、そのような結果に驚きました。そしてこのように考えました:「そのエキスパートが利益を生むなら、より多くを投資すれば、より多くを得ることができる!」しかし、テスターの結果は必ずしもそうではないと示しました。
1.2.1. 幾何学的進歩
Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1);// Calculate the amount of lots double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); // Minimum allowed lot value if (Lot == 0 ) Lot = Min_Lot; // For testing on const.min.lots
このアルゴリズムは、幾何学的進歩を示しています。Prots (パーセント)変数は、現在の流動資産の額に応じて注文の額を規定させます。注文の額を計算するこの方法は特定のディーラーの際の証拠金請求を考慮していないので、あまり正しくはありません。同時に、上記のコードは主な問題である比例した投資という問題を解決します。したがって、後続する注文の額は取得された結果に比例して依存します:その額は個々の利益のあるトレードの後に大きくなり、損失を生んだトレードの後に減少します。上記のGraal_1.mq4 (Grail 1)の注文の値は、流動資産の10%です。
以下のコードに応じてProts変数の値を0に設定します。
if (Lot == 0 ) Lot = Min_Lot; // For testing on const.min. lots
定数値の注文値にてエキスパートをテストします。
この場合、テスト結果は以下のようになります。

図4. 定数 ロット値でのExpert Graal_1.mq4 (Grail 1) のテスト結果
累進的な注文の値の除外は、バランスカーブの変化の本当の本質を視覚化します-大波、深い欠点などです。
1.2.2. 攻撃的な再投資
利益を生むエキスパートは、利益と損失の間の利点を探しています。利益を生むトレードのみ を実行する技術は現在ありません。トレードで損失を上げることは、茶道するトレーディングストラテジー全てにおいて普通です。問題は利益を生む処理とそうでないものの比率が何かという点です。
В.以下は実際のトレーディングで起こりうるの利益と損失の非均一の 配分状況の例です。
5つの連続した損失が上記で示され、そのような損失を出すトレードはより長くなる可能性もあります。この場合、その比率は3:1で維持されるということに注意してください。
したがって、この 規則的なランダム性はどういう結果になるのでしょうか?この質問に対する答えは、トレーダーが選択した戦略の質に依存します。攻撃的な再投資: i利益を得るたびに大半のデポジットを一度に投資します。
-
1. 注文のあ愛は、 流動資産の10%(Prots=10)です。そのような状況下で、テストはよい仕事をし、バランスを少しずつ長期的に増加させました。図2.で結果をご覧ください。You can also notice in the Fig.2 that the expert has been working for a very long time (about 10 000 orders)
-
2. 注文の額は 流動資産の70% です (Prots=70;)テスト結果は図3に示されています。連続して損失を出した2、3の注文は、エキスパートが400トレードを実行する前にデポジットが空になる結果となりました。
テスト結果についてレポートに注意を払ってみてください:Graal_1.mq4 (Grail 1) エキスパートにおける連続した損失の最大の数は10のみです。その他の損失は、テスト期間全体で発生しますが、それぞれの損失の数は10を超えません。これらの損失は、(1)のトレーディングの全体の結果を大きく影響しませんが、(2)では壊滅的です
したがって、そのまちがった投資での損失は、完全な失敗につながります。適切な資産管理のために開発された効果的なシステムがあります - Money Management. このシステムによれば、一つの注文の値は、バランス全体の15%を超えず、投資の額は、その50%を超えないようにします。このシステムは、プログラマが読んだことのあるいくつかの便利なルールを提供しています。
したがって、「聖杯」をいじり、すべてがうまく動作することを確認し、プログラマは実際のアカウントを開き、「金を稼ぎ」始めます。複数の注文がオープン・クローズされた後、バランスが成長せず、安定して降下していることがわかりました。さらに、取引所のスタッフがそのプログラマのエキスパートをその日の終わりに停止させます。
そして、プログラマはかなりイライラしだします。ディラーからのそのような不当に対する理由を聞こうとしますが、いかなる説明にも同意しません。困惑します:どのような"技術制限”があるのか?”遅延”と関係があるのか?!実際のトレーディングの最初の経験の結果として、プログラマはこれは「悪い取引所」だという結論に至り、ただいたずらされたのだと考えます。そして、その業者との契約を破棄します。
しかし、諦めず、そのプロセスの詳細を見てみることにし、MQL4にてより熟練したトレーダーにコンタクトを取り、そのコードを見せました。コードをみせますが、いかなる場合においてもそのエキスパートは利益を出さないということに同意します。プログラマは、フォーラムにて議論がなされた後、以下について理解しました。
1.3. エラー
Meta Editorは、継続的にエラーが起こらないことを確認します。

にもかかわらずエラーがありました。
1.3.1. 公式戦略からの脱線
かなり知識豊富な戦略がエキスパート作成の根底にあるにもかかわらず、凡用変数の最適化やコーディング中に変更されました。したがって、初期の考えは、縮小された「聖杯」に示されています。実際、その考えは、14-20ポイントの波にて稼ぐことでしたが、このパラメーターは現在の「聖杯」版にて3という悲惨な値を取得します。山と谷を誰がここでわかるでしょうか...
注文が変数ssとbbにてどのように考察されるのか注意しましょう。これは注文を考察する間違った方法です。その注文はすでに形成された時にオープンされていると考えられます。しかし、前もってその注文がオープンされるかはわかりません。サーバーが返答するまで待ち、ターミナルにてその注文の可能性を分析します。実際のトレーディングにおいて、ストラテジテスター内も含めて特定の修正は多くの場合動作しますが(Considering Orders in a Large Programという記事をご覧ください )、このコードは再度書き直される必要があります。
1.4. ハードウェアの制限
エキスパートは、タイムフレームにてテストされ、M1にてそれが意図されています。M1タイムフレームにてエキスパートのトレーディングのモデル化を行う際、とくに価格に敏感なエキスパートにおいてとても注意深くなります。
テストモデルと実際のトレーディング戦略の大きな違いは、テストモードは遅延や再価格設定をしない(ディーラーが別の価格を渡した時)という店です。
異なる取引所は、異なるデータフィードで作動します。より高頻度でレートを変えると、ディーラーがトレーダーに別の価格で注文を実行することを提案するようになります。一方で、よりトラッフィクが滑らかに見えると、再価格設定は起こりにくくなりますが、頻繁にトレードするエキスパートにとってスペースが少なくなります。
プログラマは、別の取引所で1分間の履歴のGraal_1 (Grail 1)をテストし、自身の目で結果がトラッフィクの種類によって大きく変わることを確認しました。
深い欠点の存在や不安定な利益開発は、エキスパートが損失の瀬戸際でバランスをとることを示します。
結果として、その再価格設定額は、1か2ポイントで異なります (早いマーケットではもっと大きく異なります). もしその超過した支払いが10-15などで、より大きければ、この状況は、本質的にエキスパートの成功に影響を与えません。しかし、エキスパートは小さい支払いを持ち、もしそれが2以下であれば、その価格の本質や確定され再価格設定に依存するので、一般的な成功を当てにしません。
特定のディーラーが現在のティックにて再価格設定をするか否かは、ディーラーのみが答えられる質問です。実際のマーケットに取り組み始めると、再価格設定は標準であり、自然な現象であると想定する必要があり、実際のアカウントで動作するトレーディング技術はこれを考慮する必要があります。
1.5. 経済的な要素
- 少額の注文
トレーダーの注目が、トレーディングアカウントや戦略、エキスパートに向けられているという状況は最も直面する状況です。しかし、トレーダーの関心に加えて、ディラーの経済的関心ごとがあります。
「普通の」トレーディングでは双方が勝ちます:よく考えられた戦略を使用するトレーダーや、トレーダーにより実行されるトレード処理の利益を得るディーラーの二人です。この場合、双方はお互いに関連し、助け合おうとします。
しかし、一方の行動が他方の利益に反対するという状況も起こります。例えば、もしディーラーがそのスプレッドをあげ、自動トレーディングを停止させたり、注文をオープンしなければ、これはトレーダーの利益に対します。
同時に、トレーダーの行動がディーラーの経済的な利益に反することがあります。そのような行動の一つは、少額での高頻度なトレード処理です。
ディーラーの技術は、かなり単純です。ディーラーは、買い注文や売り注文を収集し、それらの価格差を処理するため銀行や金融機関と連携します。簡単な例を調査してみましょう。ディーラーが100人のトレーダーに対してサービスをし、その内60人がEURUSDを1ロットで購入し、40人が同じ通貨ペアを1ロットで売りに出します。この場合、そのディーラーは銀行から20ロット購入しなければなりません。その際、その価格の方向がいかなる場合でも同じです。どのような場合でも、そのディーラーは80ロットにおいて全スプレッドと20ロットの部分的なスプレッドを取得します(いくつかはサービスのために銀行に提供されます。)
この場合、40人のトレーダーにおける利益/損失のソースは、その他の40人のトレーダーの損失/利益です。残りの20人のトレーダーの利益/損失のソースは、銀行で、より正確に言うと、銀行により提供されている法的個人や輸出入処理のための売買通貨です。これは、いかに金融市場が相互関連しているかということを示しています。
しかし、どのようにディーラーが銀行や金融機関と連携しているかより詳細に示すものがあります。問題は、ディーラーは、もしトレーダーが少額の金額で購買する場合、銀行と各購買処理時に連携はしないということです。ディーラと銀行でのトレード処理は、MT4ターミナルでのトレーダーのクリックよりも少ない頻度で実行されます。通常、ディーラと銀行感での関係における最小の額は、US$ 50000を超えず、レバレッジ1:100の注文価格は0.5ロットになります。そのため、もしトレーダーが常に少額で行う際、ディーラーと取引を行うということになります。この場合、トレーダーの利益のソースは、ディーラーのお金です。
ディーラーは、金融マーケットの参加者と同様です。ディーラーは、トレーダーの動きを監視し分析しなければなりません。もちろん、ディーラーは不規則に繰り返される投資にはもしトレーダーの損失や特定の機関での結果につながる場合、目を背けることができます。しかし、どのディーラーももしディーラーの損失につながるのであれば、それが続くことを取り止めます。この場合、そのディーラーはどうに反応する必要があります。さもなければ、金融マーケットの経済領域にてディーラーは何も獲得できません。
金融マーケットの現代のルーティンは、ディーラーの気まぐれや、悪意ではありません。ディーラーと銀行の関係は契約されているのです。そして、ディーラーは公平な手段によって利益を得ようとしています(ディーラ側の不正はこの記事は議論されません。)ディーラーは、銀行と毎秒トレードすることを嬉しく思いますが、そのような可能性はありません。
あるトレーダーに実行された少額トレードの条件下で、ディーラはなんらかの手段を講じる必要があります。通知が送られるか、トレーダ0にあまりそれは良くないと告げられます。ディーラーはこのトレーダーの自動トレーディングを停止させるか、再価格設定の額を上げることもできます。
- 多額の注文
実際のトレーディんとテストやデモアカウントでのトレーディングを区別するもう一つの制限があります。ロット価格の最大値です。銀行やブックマーカーのオフィル、金融機関であろうとも、どの取引所も多額の資金でトレードすることはできません。
もし注文が、US$10 000から20 000ほどであれば、取引所はUS$1 000 000.を購買します(100ほどのレバッレッジがありることに注意してください。)これは、本当に多額ですが、ディーラーはそのような多額の量をどう処理するかを学び、成功しています。
いくつかの困難は、もし注文価格がUS$50 000や、US$100 000に達した場合、中小金融機関において発生します。この場合、1000万、500万USドルの額は、銀行間マーケットで目立ちます。この額は、一回での動作において購買する上でそこまで簡単ではありません。
もしその注文がUS$ 300 000から500 000を超えると問題が発生します。この場合、取引所は、トレーダーを個別に対応します。5000万ドルは、どの金融機関にとっても多額のお金です。
この場合、取引所の手数料は問題外で、トレーダーがこの手数料を理解し受け入れていることをベースにトレーディングが実行されます。(マーケットの強い動きの中で、実際、ディーラーがかなりの費用で注文をオープンする上でどのような自由があるでしょうか?)
このため、何百万単位でのエキスパートのトレーディングのスカルピングは実際の生活とは全く関係ありません。
この推論は、プログラマが初期の10000ドルを稼げ、苦手な金融機関を見つけることを推奨します。プログラマは、「すべてが管理下にある」と考えます。
ディーラーは、教育水準を満たした普通の人々で、彼らなりにビジネスを進めていることを忘れてはいけません。ディーラにとって利益のない同じ技術は、アナリストが効果的になり、熟練しておらず必要なソフトウェアを持たないディーラーによって発見されない場所で発見されます。しかし、多くの場合、ディーラーは以前の「聖杯者」であり、トレーディングに熟練し、金融市場でトレーディングの旨味を味わっていますので、幾何学的累進が何か知り、攻撃的再投資や少額多額の注文も知っています。一般的にすべてのトレーダーは、ディーラーの資格はトレーダーのものよりも高く、ディーラーのポジションはよく推察されているという肯定から始める必要があります。
ご自身で判断してください:20000以上の注文を行うエキスパートはどのような結果になるでしょうか?

プログラマの脳は、これらすべてのティックやバー、ポイント、金融機関の間で考察を重ねます。詳細に進むべきか、「唯一の質問」に進むべきかを決定します。そして、「テスト結果は実際のトレーディングとは合致しない」という理解に満足します。また、適した技術は、未決注文に基づいて構築されるのだと判断します。さらに、「うまくいかなかったのでしょう!」と結論付けます。
2. 二つ目の"聖杯"
2.1 ストラテジー
エキスパートを未決注文に基づいて構築するという考えは、EURGBPとEURCHFのクロス率を学び思いつきました。

図8. 価格の逸脱を持つクロス率の歴史
ヨーロッパセッションがすでに終わり、アジアセッションが始まらないほどに、いくつかのシンボルチャートは標準の価格から全く異なる予想されない価格にてバーを含んでいます。制限型の未決注文を配置することで十分で、かなりの確率でそれらはオープンされます。未決注文がメインの価格帯の変化に適して反応するため、正中線にドラッグされ、MA(移動平均)戦から特定の距離で維持される必要があります。プログラマは、エキスパートをアイディアを実現するために記述します。
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // Graal_2.mq4 (Grail 2). // Used as an example in the article My First "Grail". // Sergey Kovalyov, Dnepropetrovsk (Ukraine),sk@mail.dnepr.net,ICQ 64015987, http://autograf.dp.ua/ //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж extern int TakeProfit=5; // TakeProfit orders extern int StopLoss= 29; // StopLoss orders extern int Distan = 2; // Distance from the МА line extern int Cls = 2; // Close at ** points of profit extern int period_MA=16; // MA period //extern int Time_1 = 0; // Starting time //extern int Time_2 = 0; // Finishing time extern int Prots = 0; // Percentage of free assets //-------------------------------------------------------------------------------------------- int Nom_bl, // BuyLimit order number Nom_sl, // SellLimit total, // Count of lots bl = 0, // 1 = BuyLimit order availability sl = 0, // 1 = SellLimit order availability b = 0, // 1 = Buy order availability s = 0; // 1 = Sell order availability //-------------------------------------------------------------------------------------------- double OP, // OpenPrice (absolute points) SL, // StopLoss orders (relative points) TP, // TakeProfit orders (relative points) dist, // Distance from МА (relative points) Level, // Min.allowed distance of a pending order OP_bl, // OpenPrice BuyLimit (absolute points) OP_sl, // OpenPrice SellLimit(absolute points) cls, // Close at ** profit (absolute points) MA, // MA value (rate) spred, // Spread (absolute points) Lot; // Count of lots //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int init() { Level=MarketInfo(Symbol(),MODE_STOPLEVEL); // Check what the server shows us Level=(Level+1)*Point; // ?:) SL=StopLoss*Point; // StopLoss orders (relative points) TP=TakeProfit*Point; // TakeProfit orders (relative points) dist=Distan*Point; // Distance from the MA line(relative points) cls=Cls*Point; // Close at ** profit (absolute points) spred=Ask-Bid; // Spread (absolute points) return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int start() { //============================================================================================ total=OrdersTotal(); // Count of lots bl=0; // Zeroize at the start of the pass sl=0; // Zeroize at the start of the pass b=0; // Zeroize at the start of the pass s=0; // Zeroize at the start of the pass //-------------------------------------------------------------------------------------------- for (int i=total; i>=0; i--) // For all orders { if (OrderSelect(i,SELECT_BY_POS)==true && // Select an order OrderSymbol()==Symbol()) { //-------------------------------------------------------------------------------------------- if (OrderType()==OP_BUY) // Buy order { b =1; // The order found Close_B(OrderTicket(),OrderLots()); // Close the order (the function decides // whether it is necessary) } //-------------------------------------------------------------------------------------------- if (OrderType()==OP_SELL) // Sell order { s =1; // The order found Close_S(OrderTicket(),OrderLots()); // Close the order (if necessary) } //-------------------------------------------------------------------------------------------- if (OrderType()==OP_BUYLIMIT) // BuyLimit order { OP_bl=NormalizeDouble(OrderOpenPrice(),Digits);//OpenPrice BuyLimit(absolute points) Nom_bl=OrderTicket(); bl=1; // The order found } //-------------------------------------------------------------------------------------------- if (OrderType()==OP_SELLLIMIT) // SellLimit order { OP_sl=NormalizeDouble(OrderOpenPrice(),Digits);//OpenPrice SellLimit(absolute points) Nom_sl=OrderTicket(); sl=1; // The order found } //-------------------------------------------------------------------------------------------- } } //-------------------------------------------------------------------------------------------- MA = iMA(NULL,0, period_MA, 0,MODE_LWMA, PRICE_TYPICAL, 0);// The MA current value Modify_order(); // Activate modification Open_order() ; // Activate opening //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж void Close_B(int Nomber, double lots) // Close Buy orders { //============================================================================================ if (NormalizeDouble(Bid-OrderOpenPrice(),Digits)>=cls)// If the preset profit is reached { OrderClose( Nomber, lots, Bid, 1, Yellow); // Close b = 0; // No Buy order anymore } //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж void Close_S(int Nomber, double lots) // Close Sell orders { //============================================================================================ if (NormalizeDouble(OrderOpenPrice()-Ask,Digits)>=cls)// If the preset order is reached { OrderClose( Nomber, lots, Ask, 1, Yellow); // Close s = 0; // No Sell order anymore } //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж void Modify_order() // Modification of orders { //============================================================================================ if (bl==1) // If there is BuyLimit { OP=MA-dist; // it must be located here if (MathAbs(OP_bl-OP)>0.5*Point) // if it is not located here { OrderModify(Nom_bl,OP,OP-SL,OP+TP,0,DeepSkyBlue);// The order modification } } //-------------------------------------------------------------------------------------------- if (sl==1) // If there is SeelLimit { OP=MA+spred+dist; // It must be located here if (MathAbs(OP_sl-OP)>0.5*Point) // If it is not located here { OrderModify( Nom_sl, OP, OP+SL, OP-TP, 0, Pink);// The order modification } } //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж void Open_order() // An opening function { // int Tek_Time=TimeHour(CurTime()); // To test by the time // if (Tek_Time>Time_2 && Tek_Time> //============================================================================================ if (b==0 && bl==0) // No Buy orders, open bl { OP=MA-dist; // bl order open rate if(OP>Ask-Level) OP=Ask-Level; // OP precision according to the tolerance OP=NormalizeDouble(OP,Digits); // Normalizing (MA gives the 5th digit) OrderSend(Symbol(),OP_BUYLIMIT, Lots(),OP,3,OP-SL,OP+TP,"",0,0,Blue);// Open bl=1; // Now there is a Buy order b1 } //-------------------------------------------------------------------------------------------- if (s==0 && sl==0) // No Sell orders, open sl { OP=MA+spred+dist; // sl order open rate if(OP<Bid+Level) OP=Bid+Level; // OP precision according to the tolerance OP=NormalizeDouble(OP,Digits); // Normalizing (MA gives the 5th digit) OrderSend(Symbol(),OP_SELLLIMIT,Lots(),OP,3,OP+SL,OP-TP,"",0,0,Red);// Open sl=1; // Now there is a Sell order sl } ///============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж double Lots() // Calculation of lots { //============================================================================================ Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1);// Calculate the amount of lots double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); // Minimum lot values if (Lot == 0 ) Lot = Min_Lot; // For testing on const.min.lots //============================================================================================ return(Lot); } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж /*
StopLoss, TakeProfit, Distan (その注文がメインストリームに沿って維持する距離), Cls (注文にて取得されるポイントの最小値、その注文はポイントの値がこの値に達すればクローズされる必要がある), period_MA (MA期間; MAは、最近の履歴のレートの中間線)、Prots (自由資産のパーセント、注文価格)が調整可能な変数として選択されました。これらは、かなりその考えを実現する上で十分です。
-
特別なstart()関数にて、その注文は分析され(その注文の分析メソッドはこちらで記載されています)、それらの扱い方に関する判断は同時になされます。もしそのターミナルにてオープンの注文があれば、一致する関数Close_*()はクローズの必要性が分析された地点で呼ばれ、その注文はクローズされます。
-
start()関数の終了時に、Modify_order()とOpen_order()関数はそれぞれの修正と、制限型の未決注文のためオープンされました。その他の注文はオープンされていません。
-
Modify_order()関数にて、その注文の位置は計算され、もし適切な位置になければ、そこに移動されます。
-
Open_order()関数にて、未決注文の位置する適切な場所も判断されます。この際に、サーバ制限が考慮され、もし注文がなければ、それが配置されます。

図9. MIG Investments会社 のトレーディング条件下のM1 EURUSDチャート 2005年3月から2006年7月までの履歴のGraal_2.mq4 (Grail 2)におけるテスト結果
2.2. 幾何学的累進

Рис. 10. 一定の注文価格での
MIG Investments Companyトレーディング条件下 2005年3月から2006年7月までの履歴におけるМ1 EURUSD チャートのGraal_2.mq4 (Grail 2)
元来、プログラマは夜のみお金を稼ぎたかったのですが、1日中うまくエキスパートが稼働するので驚きました。この美しさを見て、再び判断しました: "自分だけだ" そして、"もう一度お金稼ごうか?"と考え始めますしかし、何も起こらないのです。今回、プログラマは「spikes」を知る必要があります。
2.3. エラー
上記の例には、たくさんの欠陥やまちがったプログラミング手段があります。Modify_order()には、未決注文においての最少の距離は考慮されておらず、そのオープン注文はまちがってまとめられており、TakeProfitはClsの利益に奮闘するため個別に修正されず、エキスパートの分析部分は全体のコードにおいて消されています。
まちがった、さらに不注意なプログラミングはしばしば、識別できないエラーに繋がり、時折、もしそのコードがその他のエキスパートに統合されれば、エラーが複製されます。
2.4. 技術制限 (Spikes)
技術的・組織的にしろ、すべての制限は最終的に経済的な損失に変わります。誰の費用でこれらの損失がカバーされるかという疑問が生まれます。
モニターにてトレーダーによって見られている標準のろうそく足チャートは、特定の領域でのマーケット開発の平均した結果です。異なるディーラーでの短期間の履歴におけるレートの所作が分析されます。この際、すべてのチャートは類似はしていますが、お互いに異なります。いくつかのディーラーのチャートは、長い多方向的なろうそくをたくさん含み、その他のディーラーのチャートは「安穏無事」な様子を示しています。
ティックチャートはまた売り上げのオブジェクトです。超過し、不自然な価格ティックをフィルタリングするプログラムの動作結果です。そして、それらが ("不自然な" ティック) 現れます。これは、いくつかの個人的な理由のため、銀行の人がマーケット価格とはかなり異なる価格でいくらかを購買すると発生します。その処理プログラムは、この情報を取得し、もしそのような取引が一度だけ発生すれば、最終的なチャートには考慮しません。プログラムは、どの価格が「標準」で、何が違うのかを理解しがたいことがあります。この理由のため、(プログラムのアルゴリズムに応じて)異なる長さのろうそくはチャートにて現れます。これらはspikesです。異なる種類として表示されますが、金融市場での本当の状況を示しません。
これらの「pin」や「spikes」を捉え、価格が最も利益を生む際の注文を捉えるエキスパートを作るのはそこまで難しくはありません。しかし、ディーラーと銀行間で結論づけられた契約下で、銀行はディーラーへのそのような取引費用を払わないことをしっかり理解する必要があります。これは、トレーダーの利益のソースは、再びディーラーのポケットになるということです。そして、そのディーラーはこれをもちろん望んでおらず、ディーラは標準のマーケット価格でトレード処理を行うためにトレーダーと戦います。
ディーラーのための機会を提供する手段として、ディーラーとトレーダー間の契約には、普通強い価格の動きの際に注文の保証や再価格設定の可能性や、未決注文やその他の事項を含んだディーラーの権利に関する条項が記載されています。ディーラーは、注文がスパイクにてオープンされれば、すでにオープンされた注文をキャンセルすることができます。
これが実際に起こったことです。その聖杯は再び訂正されました。今回、プログラマは受信者を無視せず、注文が強制的にクローズされた理由を説明するたびに注意深くディーラーに耳を傾けました。しかし、ディーラーはエキスパートを停止させた時、プログラマは耐え切れず、契約を破棄しました。
そして、繰り返される失敗は、1分間のタイムフレームが原因であると考えます。フォーラムの投稿を読み、その他のトレーダーとコミュニケーションをとり、プログラマはそれらの多くは同じシンボルでより大きいタイムフレームに励みます。"これで意味が通るはずだ"と考えます。だんだん、プログラマは、"Mozart and me"の結論に至り、M1チャート上ではなく、3番目のプログラムの会はを始めます。
3. 3番目の"聖杯"
3.1公式の戦略
EURUSD H1チャートを注意深く学び、分析のため異なるインジケーターを使用し、プログラマはとても魅力的な規則性を発見しました:もし短期間のMAがより大きい期間のMAに合致すると、マーケットはより短い期間のMAが動く方向に動きます。
図11. 異なる期間のMAの交差に基づく戦略のグラフィカル表現
プログラマは、この相互関係はすべてのタイムフレームで見られることに気づきますが、大きいもののみを扱い始めました。それは、抽出された知識をMQL4に変換するためにのみ残っており、エキスパートにどの方向、どの条件下で注文をオープンするかを知らせます。そして、エキスパートが準備できれば、そのパラメーターを最適化する必要があり、最も効果的なMAの長さをソートし、StopLossとTakeProfitを適切に配置します。
今回は、以下のエキスパートが生まれました://жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // Graal_3.mq4 (Grail 3). // Used as an example in the article My First "Grail". // Sergey Kovalyov, Dnepropetrovsk (Ukraine),sk@mail.dnepr.net,ICQ 64015987, http://autograf.dp.ua/ //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // // //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж extern int MA1 = 11; // Period of the first MA extern int MA2 = 23; // Period of the second MA extern double TP = 50; // TakeProfit orders extern double SL = 15; // StopLoss orders extern double Prots= 0; // Percentage of free assets //-------------------------------------------------------------------------------------------- int ret, // Direction of intersection total; // Count of open orders //-------------------------------------------------------------------------------------------- double Lot, // Count of lots Pred, // Preceding value of the 1st MA(red) Tek, // Current value of the 1st MA (red) Golub; // Current value of the 2nd MA (blue) //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int init() { //============================================================================================ SL = SL*Point; // StopLoss in points TP = TP*Point; // TakeProfit in points return; //============================================================================================ } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int start() { //============================================================================================ total=OrdersTotal(); // Total amount of orders if (total==2)return; // Both orders are already open //-------------------------------------------------------------------------------------------- Tek =iMA(NULL,0, MA1, 0,MODE_LWMA, PRICE_TYPICAL, 0);// Current value of the 1st MA Pred =iMA(NULL,0, MA1, 0,MODE_LWMA, PRICE_TYPICAL, 1);// Preceding value of the 2nd MA Golub=iMA(NULL,0, MA2, 0,MODE_LWMA, PRICE_TYPICAL, 0);// Current value of the 2nd MA //-------------------------------------------------------------------------------------------- if (Peresechenie()==1) Open_Buy(); // Movement bottom-up = open Buy if (Peresechenie()==2) Open_Sell(); // Movement top-down = open Sell //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Peresechenie() // Function determining intersection { //============================================================================================ if ((Pred<=Golub && Tek> Golub) || (Pred< Golub && Tek>=Golub) ) ret=1; // Intersection bottom-up //-------------------------------------------------------------------------------------------- if ((Pred>=Golub && Tek< Golub) || (Pred> Golub && Tek<=Golub) ) ret=2; // Intersection top-down //============================================================================================ return(ret); // Return the intersection direction } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Open_Buy() // Function opening Buy { //============================================================================================ if (total==1) // If there is only one order... { // ... it means another can be opened OrderSelect(0, SELECT_BY_POS); // Select the order if (OrderType()==0)return; // If it is Buy, do not open } OrderSend(Symbol(),0, Lots(), Ask, 0, Ask-SL, Ask+TP, "", 0, 0, Blue);// open //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Open_Sell() // Function opening Sell { //============================================================================================ if (total==1) // If there is only one order... { // ... it means another can be opened OrderSelect(0, SELECT_BY_POS); // Select the order if (OrderType()==1)return; // If it is Sell, do not open } OrderSend(Symbol(),1, Lots(), Bid, 0, Bid+SL, Bid-TP, "", 0, 0, Red);// Open //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж double Lots() // Calculation of lots { //============================================================================================ Lot=NormalizeDouble(AccountEquity()*Prots/100/1000,1);// Calculate the amount of lots double Min_Lot = MarketInfo(Symbol(), MODE_MINLOT); // Minimum lot values if (Lot == 0 ) Lot = Min_Lot; // For testing on const. min. lots //============================================================================================ return(Lot); } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж /*
このエキスパートは、以前のものと同様、かなりシンプルです。
変数を記述するブロックから始まります。start()関数では、注文の最大量は、より大きい、短い期間におけるMA値と同様、定義されています。MAが合致すると、一致する関数は呼ばれ、注文をオープンします:Open_*()MAが合致すると、Peresechenie()が使用され、ロットの値を計算します - Lots()関数

。MetaQuotes Software Corp.条件下でH1 EURUSD チャートを使用しています。
5ヶ月で300万でした!すばらしい!しかし、このバランスグラフでは、以前の経験での苦い経験と似ている何かがあります。そして、プログラマは少し遅めることにしました。
3.2. 進歩
同じエキスパートが一定の注文値でテストされ、かなり受け入れられるバランスグラフを示しました。

MetaQuotes Software Corp条件下でH1 EURUSD チャートを使用しています。一定のロット価格のデモサーバーで行っています。
5ヶ月間で6000ポイントでした-ナイフで切ることができます一月で1000ポイントです。しかし、実際のトレーディングでそのエキスパートを設定することを疑いました。結局、二度も失敗しているのですから...

3.3. エラー
"これはおかしい!MetaEditorに何かまちがった部分があるはずだ!”と最初はそう考えました。しかし、コードを学んでいくと、プログラマはエラーを再び見つけました。それらについて学んでいきましょう。
3.3.1初期の戦略からの逸脱 - アルゴリズムのエラー
以下のシンプルな関数をみてください:
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Peresechenie() // Function that detects the intersection { //================================================================================================= if ((Pred<=Golub && Tek> Golub) || (Pred< Golub && Tek>=Golub) ) ret=1; // Bottom-up intersection //------------------------------------------------------------------------------------------------- if ((Pred>=Golub && Tek< Golub) || (Pred> Golub && Tek<=Golub) ) ret=2; // Top-down intersection //================================================================================================= return(ret); // Return the intersection direction } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
かなり明確に見えますが、何が見つけられるでしょうか?しかし、エラーがここでもあります。グローバル変数retが使用された時、その値は最後に計算されたもの、1か2に等しく保存されるのです。このため、現在の状況に関係なく、Peresechenie()関数は、最後に計算された値を返します。そのため、start()関数にて開くため、注文されます:
if (Peresechenie()==1) Open_Buy(); // Bottom-up movement = open Buy if (Peresechenie()==2) Open_Sell(); // Top-down movement = open Sell
Peresechenie() 関数の初期にてret変数を0にする上で十分です。アルゴリズムのエラーにとらわれ、それを訂正し、一つのバーのみでオープンするよう同じ時間のフラグメントを記述しました。エキスパートはこのようになります:
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // Graal_31.mq4 (Grail 31) // Used as an example in the article My First "Grail" // Sergey Kovalyov, Dnepropetrovsk, sk@mail.dnepr.net, ICQ 64015987, http://autograf.dp.ua/. //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж // // //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж extern int MA1 = 11; // Period of the 1st MA extern int MA2 = 23; // Period of the 2nd MA extern double TP = 50; // TakeProfit orders extern double SL = 15; // StopLoss orders extern double Prots= 0; // Percentage of free assets //-------------------------------------------------------------------------------------------- int New_Bar, // 0/1 The fact of new bar forming Time_0, // The new bar beginning time ret, // Intersection direction total; // Count of open orders //-------------------------------------------------------------------------------------------- double Lot, // Count of lots Pred, // Previous value of the 1st MA (red) Tek, // Current value of the 1st MA (red) Golub; // Current value of the 2nd MA (blue) //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int init() { //============================================================================================ SL = SL*Point; // SL in points TP = TP*Point; // ТР in points return; //============================================================================================ } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int start() { //============================================================================================ total=OrdersTotal(); // Total count of orders if (total==2)return; // Both orders already opened //----------------------------------------------------------------------------- New bar ------ New_Bar=0; // First zeroize if (Time_0 != Time[0]) // If the bar beginning time changed { New_Bar= 1; // Here we have a new bar Time_0 = Time[0]; // Remember the new bar beginning time } //-------------------------------------------------------------------------------------------- Tek =iMA(NULL,0, MA1, 0,MODE_LWMA, PRICE_TYPICAL, 0);// Current value of the 1st MA Pred =iMA(NULL,0, MA1, 0,MODE_LWMA, PRICE_TYPICAL, 1);// Previous value of the 2nd MA Golub=iMA(NULL,0, MA2, 0,MODE_LWMA, PRICE_TYPICAL, 0);// Current value of the 2nd MA //-------------------------------------------------------------------------------------------- if (Peresechenie()==1 && New_Bar==1) Open_Buy(); // Bottom-up movement = open Buy if (Peresechenie()==2 && New_Bar==1) Open_Sell(); // Top-down movement = open Sell //============================================================================================ return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Peresechenie() { ret=0; // That's the heart of the matter!:) //============================================================================================ if ((Pred<=Golub && Tek> Golub) || (Pred< Golub && Tek>=Golub) ) ret=1; // Bottom-up intersection //-------------------------------------------------------------------------------------------- if ((Pred>=Golub && Tek< Golub) || (Pred> Golub && Tek<=Golub) ) ret=2; // Top-down intersection //============================================================================================ return(ret); // Return the intersection direction } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Open_Buy() { if (total==1) { OrderSelect(0, SELECT_BY_POS); // Select the order if (OrderType()==0)return; // If it is buy, don't open } OrderSend(Symbol(),0, Lots(), Ask, 0, Ask-SL, Ask+TP, "", 0, 0, Blue);// Open return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж int Open_Sell() { if (total==1) { OrderSelect(0, SELECT_BY_POS); // Select the order if (OrderType()==1)return; // If it is sell, don't open } OrderSend(Symbol(),1, Lots(), Bid, 0, Bid+SL, Bid-TP, "", 0, 0, Red);// Open return; } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж double Lots() { Lot = NormalizeDouble( AccountEquity()*Prots/100/1000, 1);// Calculate the amount of lots if (Lot<0.1)Lot = 0.1; // For testing on const. min. lots return(Lot); } //жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж /*
一定のロット価格でのエキスパートのテストは、制限された成功と一致します:

MetaQuotes Software Corpのトレーディング条件下での一定のロット価格のデモサーバを使用しています。
プログラマはかなりがっかりしました。たくさんの作業が無駄になりました。プログラマは、「聖杯」の探求に時間を費やしました。数ヶ月後、Graal_3.mq4 (Grail 3)エキスパートに戻ることにしました。"エラーがあったが、良い結果だった。おそらく、これは当然のことだ。良い結果のみが維持されるならエキスパートは注文をオープンするだろう。そして、テストを再び開始しました。

MetaQuotes Software Corpのトレーディング条件下での一定のロット値のデモサーバーを使用しています。
3.4. 結果のすり合わせ
自分自身をダチョウのように感じました。履歴セグメントのエキスパートのために最適なパラメーターを調節することに困難はありませんでした。同じエキスパートは常に異なる履歴期間で異なる結果を出します。
質問は、可能であれば、そのような最適な入力を見つける方法の質問となります。価格の小さい市場変動はエキスパートの動作や効果に影響を与えません。一般的に、マーケットにていかなる変化にも耐えうる戦略に焦点を当てる必要があり、パラメータの最適化はベストな結果を取得するためにいくらか助ける必要があります。
エキスパートGraal_3.mq4 (Grail 3)の最適な設定のための検索は、何にも繋がりませんでした。外部変数の異なる値のエキスパートのテストは、損失を示すか、異なる履歴期間のための異なる設定に繋がります。このため、最適な設定を見つけることに失敗しました。なので、この戦略はすべての場合のための普遍的な設定を持つと結論づけました。
プログラマは、Graal_31.mq4 (Grail 31)エキスパートに戻り、望んだ結果の取得に悶えます。しかし、最適な設定は以下のようになります:

MetaQuotes Software Corpのトレーディング条件下、デモサーバー一定のロット価格
にて実行。
プログラマが見たものは、全く「聖杯」に類似していませんでした。チャートの真ん中で水面低下したため、そのエキスパートを実際のアカウントのために使用することができません。しかし、かなりすごいものではありませんが、以前よい結果を残すエキスパートです。
4. まとめ
幻滅は、その錯覚が陽気で、幸せなものなら、常につらいものです。しかし、人生は遅かれ早かれその場所に導きます。世界の配慮がそのプログラマから元気を奪いました:そのプログラマは、二つの取引所と関係を破棄し、稼いだお金をかなり失いました。プログラミングやForexでのトレーディングなど貴重な経験を得て、"Mozartだけ..."という結論をみちびだそうとしますが、そのような早急な結論を取り止めます。
代わりに、そのプログラマは空白の紙を取り、教訓をもとに結論を公式化しました。
-
実際のトレーディングでの累進的投資は標準である。しかし、注文は高すぎる価格ではない。
-
初期の戦略に固執しなければならない
もし調節可能なパラメーターにおける重要な変化は、結果における変化につながれば、初期の戦略はレベルアップかダウンされます。新しい戦略はより効果的な可能性があります。この場合、しばらく中止される必要があり、そのような予想されない成功の理由がよく学ばれた後、呼び出される必要があります。しかし、最もな制限の中でパラメーターの変化を許容する最大の範囲でユーザビリティを調査するため初期のアイディアに戻る必要があります。 -
アルゴリズムエラーを詳しく監視してください。
アルゴリズムエラーの存在は、かなり不自然な現象です。そのようなエラーを発見するためにはかなりの経験が必要です。同時に、それらはエキスパートの動作の最終結果にて見つけられる必要があります。オープンやマークから外れたオープンの提供は、アルゴリズムエラーの証拠になります。 -
ストラテジーテスターのエキスパートテスト結果を適切に解釈してください
実際のアカウントでのエキスパートの動作やストラテジーのモデリングはお互いに異なります。その違いは、モデリングは実際のトレーディングで発生する再価格設定や、注文の実行の拒否を考慮しないという点です。これは、高い見返りが期待されるエキスパートには問題ではありませんが、低い見返りのものにとって、その結果は、テスト中に大きく異なってきます。多くの場合、エキスパートは低い見返りをもち、テスト時にはかなりの利益を出し、実際のトレーディングでは、損失という結果で終わります。 -
攻撃的投資を控える
いかなるトレーディング戦略は、損失処理を考慮しなければなりません。もしその注文価格が無限に高い場合、少しの損失も修復不可能な損益ミスに繋がり、デポジットすべてを失うことにもなります。監視されていない攻撃的な再投資の許可は、現実逃避であり、保証された破産を意味します。 - 変動にて利益を得ようとしない
スパイクは、標準で自然なマーケットのレートを反映しません。もしトレーダーがそのようなスパイクで稼ぐなら、利益のソースはディーラのお金になります。この事実は、ディーラーにより発見されます:取引処理のキャンセルや、エキスパートの停止、アカウントのブロックに繋がります。 - 異なる履歴期間でのクロスチェックテスト
すべてのエキスパートは、異なるタイムフレームにて異なる結果を示します。それぞれの履歴インターバルにおいて、最適な設定が見つけられ、結果は最も良いものになります。テストに注意深くなり、現実逃避をせず、取得した結果をできるだけたくさんの履歴インターバルにてクロスチェックしてください。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/1413





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索