English Русский 中文 Español Deutsch Português
MetaTrader用の高度なEAコンストラクター - BotBrains.app

MetaTrader用の高度なEAコンストラクター - BotBrains.app

MetaTrader 5トレーディング | 28 1月 2022, 15:55
703 0
Evgenii Shcherbakov
Evgenii Shcherbakov

はじめに

通常、取引ストラテジーは、自動化できる特定のアルゴリズムに縮小できます。自動売買ロボットは人間よりも何千倍も速く取引できますが、すべてのトレーダーがプログラミングに精通しているわけではありません。

BotBrains.appは、自動売買ロボットのためのノーコード開発プラットフォームです。BotBrainsエディターで自動売買ロボットを作成するためには、何もプログラムする必要はありません。必要なブロックをスキームにドラッグし、パラメータを設定して、それらの間の接続を確立するだけです。

BotBrains.appには、エディターのすべての概念を詳細に説明するドキュメント(docs.BotBrains.app)があります。この記事では、エディターのインターフェイスと主要な機能、および「移動平均交差」取引ストラテジーの実装について説明します。


エディター機能

BotBrainsでは、基本的な取引ロボット(たとえば、移動平均の交差に基づく取引ロボット)を開発できるだけでなく、複雑な取引アルゴリズム(たとえば、銘柄間のスプレッド取引に基づく取引ロボット)を実装することもできます。BotBrainsを使用すると、取引ロボットを電報ボットにリンクできます。特別なブロックを使用して、取引結果に関するメッセージを送信したり、カスタムサイズのチャートのスクリーンショットを送信したりすることもできます。アクションを簡単に作成してボタンに割り当てたり、ロボットの実行中に変数値を制御するための入力フィールドを追加したり、その他のさまざまなブロックを追加してロボットインターフェイスを構築したりできます。 

次の表に、BotBrainsエディターで使用できるブロックのカテゴリを示します。利用可能なブロックの完全なリストは、記事の最後に示されています。
カテゴリー
説明
イベント
これらのブロックは、何かが発生したときに有効になります。たとえば、[Start of robot work]イベントブロックは、ロボットが起動されると有効になります。
条件
[if]ブロックを使用してさまざまなチェックを実行できます。
ループ
ループには多くの用途があります。たとえば、ループを使用して、使用可能なすべての銘柄を調べ、最後の取引セッション中で変動が最大であった銘柄を特定できます。
指標
指標はテクニカル分析の重要な手段の1つです。BotBrainsは、単純なボリュームから一目均衡表まで、幅広い指標を備えています。
チャート分析
特定のチャートバーに関する情報を取得し、特定の期間の最大/最小価格を取得します。チャートに水平線と垂直線を描画します。
DOM分析
市場の深さのスプレッドとその相場に関する情報を入手します。
トランザクション
(逆)指値注文を出し、削除します。成行注文を出し、ポジションを決済します。
変数
変数値を変更します。たとえば、変数には、ロボットが取引するロット数を格納できます。
サウンド
サウンドブロックを使用すると、何かが起こったときに特定のサウンドを再生できます。たとえば、ロングポジションを開くためのすべての条件が満たされたときに「買いシグナル」サウンドを再生できます。
情報取得
取引口座、取引セッション、アクティブな(逆)指値注文、履歴内の(逆)指値注文、銘柄、時間および履歴取引に関する情報を取得します。
列挙型
銘柄、アクティブな(逆)指値注文、履歴内の(逆)指値注文、取引履歴を列挙します。
Telegram
メッセージとチャートのスクリーンショットをTelegramに送信します。
インターフェイス
自動売買ロボットの本格的なインターフェイスを構築します。個々のインターフェイス要素は、変更ブロックを使用して変更できます。アクションをインターフェイスボタンにバインドできます。[input field]インターフェイスブロックは、ロボットの実行中に変数値を変更するために使用できます。これらのブロックはすべて、動的なユーザーインターフェイスの作成を可能にします。
事前定義された定数
基本的に、事前定義された定数が比較に使用されます。たとえば、ポジションの方向には[buy], [sell]、[no direction]の3つの定義済み定数があります。現在のポジションの方向を取得し、事前定義された定数の1つと比較できます。
デバッグ
[debug]ブロックを使用すると、デバッグ情報をターミナル操作ログに出力できます。たとえば、このブロックを使用して、変数または定数に正しい値が含まれていることを確認できます。
その他のブロック
ターミナルを閉じ、ロボット作業を停止し、ロボット作業を一時停止します。ファイルにログインし、ターミナルで通知し、チャートにコメントします。
数学演算子
加算、減算、乗算、除算、徐算余剰、平方根、べき乗。比較: <、>、<=、>=
論理演算子
構築条件には論理演算子があります(AND、OR、NOT)。
Teleport
Teleportに出入りするためのブロックがあります。スキームの別のセクションの実行にすばやく便利に切り替える必要がある場合があります。Teleportを使用すると、これを数秒で実行できます。
型変換ブロック
デフォルトでは、すべてのユーザーデータは数値として保存されます。型変換ブロックを使用すると、データを表現する形式を明示的に指定できます。整数、10進数、文字列、日付と時刻の4つの型があります。
可変または定数の選択
可変または定数の選択
値の入力
値の入力

BotBrainsエディターのインターフェイス

BotBrainsエディターには、ロジックインターフェイスコードの3つのモードがあります。

「ロジック」モード:

「ロジック」モードでは、ロボットのロジックスキームを構築できます。このモードでは、[if]ブロックやトランザクションブロックから、メッセージをTelegramに送信するためのブロックやロボットのログを作成するためのブロックまで、大部分のブロックを使用できます。このモードは、自動売買ロボットのロジックを開発するのに使用します。単純なブロックを使用して、ロボットが何をすべきか(いつ売買するか、いつTelegramにメッセージを送信するか、いつ取引を停止するかなど)を指定します。エディターには合計140以上のブロックがあり、ほぼすべての取引ストラテジーはこれを使用して実装できます。

ロジックモード

「インターフェイス」モード:

「インターフェイス」モードでは、その名前が示すように、自動売買ロボットのインターフェイスを構築できます。自動売買ロボット用の本格的なインターフェイスをほんの数分で構築できます。各インターフェイス要素には、設定の完全なセットがあります。[Modify interface element]ブロックを使用すると、インターフェイス要素のプロパティをその場で変更できます。

インターフェイスモード

「コード」モード:

このモードでは、自動売買ロボットの生成されたコードを確認できます。自動売買ロボットのコードを生成するには、〜キーを押すか、右側のツールバーの対応するボタンをクリックします。

コードモード

自動売買ロボットの起動

自動売買ロボットのすべてのコードは、キーボードの1つのキーを押してから数秒で生成されます。BotBrainsで作成されたロボットを実行するには、必要なすべての依存ファイルがインストールされていることを確認する必要があります。

  1. ライブラリ - BotBrains_lib.ex5
  2. インクルードファイル - BotBrains_lib.mqh
  3. インクルードファイル - BotBrains_constants.mqh
  4. サウンドファイル
上記の依存ファイルがインストールされていない場合、BotBrainsで作成されたロボットを起動できないか、正しく動作しません。

必要な依存ファイルはすべてのこちらからダウンロードできます。依存ファイルのインストールについては、対応するドキュメントの記事で詳しく説明されています。

移動平均クロスの例

BotBrainsエディターで「移動平均交差」取引ストラテジーの実装を見てみましょう。リンクをクリックすると、エディターでスキーム全体を直接開くことができます。

エディターを開き、5つの定数を作成します。

  1. slow_ma_period - 低速移動平均期間(定数値: 60)
  2. fast_ma_period - 高速移動平均期間(定数値: 30)
  3. symbol - 取引する銘柄のコード(定数値: MGCV21または取引ターミナルで使用可能なその他の銘柄)
  4. admin_id - ロボットによる取引情報とチャートのスクリーンショットを含むメッセージの送信先となる、ユーザーのTelegram ID(定数値: Telegram ID)
  5. lot - 取引されたロット数
定数

2つの移動平均が交差したという事実を検出するには、次の4つの変数を作成する必要があります。

  1. ma_slow - 低速移動平均の現在値
  2. ma_fast - 高速移動平均の現在値
  3. ma_slow_prev - 前のバーの低速移動平均の平均値
  4. ma_fast_prev - 前のバーの高速移動平均の平均値


これらの変数の値を比較するだけで、低速移動平均と高速移動平均の項さを検出できます。変数には初期値を設定しません。これらの変数の値は、取引されている銘柄の新しいティックが受信されるとすぐに更新されます。

ロボットが起動したときに「Robot is launched」というメッセージを出力してみましょう。 これを実装するには、[Robot start]イベントブロックと[Journal message]ブロックの2つのブロックをロボットロジックスキームにドラッグアンドドロップするだけです。次に、これらのブロックのコネクタをリンクします。

ロボット起動メッセージ

[Journal message]ブロックの設定で、表示するメッセージを指定します。

操作ログメッセージブロック設定

取引されている銘柄の新しいティックが受信されると、ロボットは変数値を更新する必要があります。そのために、[New Tick]イベントブロックと4つの[Set variable complex value]ブロックをロボットのロジックスキームにドラッグしましょう。各[Set variable complex value]ブロックの本体に[Moving average]ブロックをドロップし、これらの各ブロックで対応する変数を選択します。次に、これらのブロック間の接続を確立します。

新しいティックでの変数の更新

[Moving average]ブロックを使用すれば「移動平均」指標の値を取得できます。このブロックには6つのパラメータがあります。

  1. Symbo(銘柄)
  2. Timeframe(時間枠)
  3. Period(期間)
  4. Smoothing method(平滑化メソッド)
  5. Applied price(適用価格)
  6. Shift(シフト)

[shift]パラメータを使用すると、特定のバーでの「移動平均」指標値を取得できます。たとえば、シフト値0は、最後に使用可能なバーの値(シフトなし)、値1は、前のバーの値です。このようにして、現在および前のバーの低速移動平均と高速移動平均の値を取得できます。[shfit]パラメータと[period]パラメータの異なる値を設定するだけです。

最初の[MA]ブロックのパラメータを指定しましょう。


対応する定数が[symbol]パラメータと[period]パラメータの値として使用されます。変数をパラメータ値として使用することもできます。

変数と定数の操作の詳細については、関連するドキュメントの記事を参照してください。

[ma_slow]変数の値は、取引されている銘柄の新しいティックが受信されるたびに更新されます。 

[ma_fast]変数についても同じことをしましょう。

この段階で移動平均の現在値を更新しますが、交差の事実を判断するには、前のバーの移動平均の値を知る必要があります。現在のバーのシフトは0、前のバーのシフトは1、というように続きます。したがって、[Set variable complex value]の最後の2ブロックでも同様にすべてを実行しますが、今回は[Moving average]ブロックの[shift]パラメータを1に設定して、[ma_slow_prev]および[ma_fast_prev]変数に前のバーからの移動平均値が含まれるようにします。

[ma_fast_prev]変数についても同じことをします。

変数が正しい値に設定されていることを確認しましょう。[Timer]ブロックをスキームにドロップします。このブロックには、[Interval (sec)]という1つのパラメータしかありません。このパラメータはデフォルトで1に設定されているため、このブロックはデフォルトで1秒ごとに実行されます。次に、4つの[Print debug info]ブロックをスキームにドロップします。このブロックは、指定されたメッセージをターミナル操作ログに出力するだけです。このブロックを使用して、変数に含まれる値を確認できます。[Print debug info]のそれぞれに、次の順序で3つのブロックを配置します。

  1. 値の入力 - このブロックは、任意のテキストを入力できる単純な入力フィールドです。この場合、どの変数がどの値を参照しているかを理解できるように、変数名を入力する必要があります。
  2. +演算子- このブロックを使用して、2つの文字列を結合できます。
  3. 変数選択- このブロックを使用して、指定された変数の値を取得できます。

この段階では、スキームは次のようになります。

BotBrainsでは、すべてのユーザー値が数値として保存されます。この場合、[値の入力]ブロックにテキストが含まれるように明示的に指定する必要があります。これにより、テキスト自体が出力され、数値表現ではなくなります。

これを行うには、[S](通常の文字列)型の変換ブロックを各[値の入力]ブロックに配置するだけです。

この時点で、ロボットのコードをコンパイルし、実行することもできます。指定された変数の値は、毎秒ターミナル操作ログに出力されます。ただし、警告「implicit conversion from 'number' to 'string」がコンパイル中に表示されます。

実際、ここでのスキームでは、文字列値(文字列に変換された[値入力]ブロック)と数値(移動平均の数値を含む変数)を合計しようとしています。これを修正するには、すべての変数を文字列にキャストする必要があります。これは2つの方法で実行できます。

  1. [S](通常の文字列)の変換ブロックの使用
  2. [D](小数)型の変換ブロックの使用 - [S](通常の文字列)ブロックとの唯一の違いは小数点以下の桁数を制限できる点

2番目の方法を使用しましょう。これを行うには、[D](小数)型の変換ブロックを各[variable select]ブロックに配置します。

各[D](小数)ブロックの設定で、唯一のパラメータとして[Decimal places]を2に指定します。

型の操作については、関連するドキュメントの記事で詳しく説明されています。

ターミナルを開き、ロボットで使用されているのと同じパラメータを使用して、取引されている銘柄のチャートに2つの「移動平均」指標を追加します。これにより、変数の値をチャートの指標値と比較できます。

次に、「~」キーを使用するか、右側のツールボックスの対応するボタンを使用して、ロボットのコードを生成します。

ターミナルでロボットを実行し、ターミナル操作ログの出力値をチャートの指標の実際の値と比較します。

すべての値が一致するため、作業を続行できます。

残された唯一のことは、移動平均の交差を検出して、すべての条件が満たされている場合に取引を行うために、新しいティックが受信されたときに変数値を比較することです。

まず、取引を行うための条件を決定しましょう。ロングポジションを選択するために満たすべき条件は3つあります。

  1. 高速移動平均の現在値は低速移動平均の現在値よりも大きい。
  2. 前のバーの高速移動平均の値は前のバーの低速移動平均の値よりも小さい。
  3. 現在のポジションの方向は「買」ではない。

1番目と2番目の条件は1秒に複数回満たされる可能性があるため、最後の条件を省略すると、ロボットが短時間で多くの取引を実行することがあります。3番目の条件の結果として、ロボットは既存のロングポジションに加えて新しいロングポジションを開くことはありません。

BotBrainsエディターでは、取引頻度の上限と疑わしい取引の頻度を指定できます。最大取引頻度に達すると、ロボットはすべてのポジションを即座に決済して、すべての注文を削除します。また、ロボットのセキュリティ設定で設定されたパラメータに応じて、Telegramで通知したり、ターミナルで直接通知したりします。 疑わしい取引の頻度に達した場合、ロボットはポジションを決済したり注文を削除したりする代わりに、Telegramで通知したりターミナルで直接通知したりします。

ショートを注文するには、次の条件が満たされている必要があります。

  1. 高速移動平均の現在の値は低速移動平均の現在の値よりも低い。
  2. 前のバーの高速移動平均の値は前のバーの低速移動平均の値よりも大きい。
  3. 現在のポジションの方向は「売」ではない。

ロングポジションを開くための条件を構築しましょう。

[Position info]ブロックには2つのパラメータがあります。

  1. Symbol - 情報を取得するポジションに関する銘柄
  2. Block value - 目標ポジションパラメータ。利用可能なオプションは、ポジションボリューム、ポジションを開く時間、始値、ポジションの現在の利益とポジションの方向です。

[symbol]パラメータの値として[symbol]定数を使用します。2番目のパラメータの値として[Position direction]を選択します。

[Position info]ブロックの値は、指定された銘柄による現在の開いたポジションの方向と等しくなります。

このブロックの後には、[Not]、[Equals]、[Positiondirection]の3つのブロックがあります。[Position direction]ブロックには、[Buy direction]、[sell direction]、[No direction]のすべての可能な方向が含まれています。現在ポジションの方向が「買」ではないことを確認します。

次に、1つの[Market order]ブロックをスキームに追加し、このブロックを[If]ブロックの[Yes]コネクタにリンクします。

[Market order]ブロックには、次の3つのパラメータがあります。

  1. Symbol - 成行注文が出される銘柄
  2. Direction - 注文方向(買/売)
  3. Volume - 注文量


多くのパラメータの値として定数が使用されているため、ロボットを簡単に構成できるようになります。定数値を1つの場所で変更するだけで、その定数が使用されるすべての場所で新しい値が自動的に使用されます。

BotBrainsエディターで作成された自動売買ロボットに定数がある場合、それらは生成されたコードの最上部にリストされます。

/********** <ROBOT CONSTANTS> **********/

const double __slow_ma_period = user_value("60");
const double __fast_ma_period = user_value("30");
const double __symbol         = user_value("MGCG22");
const double __admin_id       = user_value("744875082");
const double __lot            = user_value("1");

/********** </ROBOT CONSTANTS> **********/

定数はロボットの設定と考えることができます。たとえば、別の銘柄を取引する場合は、[symbol]定数の値を変更するだけです。または、コードを直接操作したくない場合は、BotBrainsエディターで定数値を直接変更し、コードを再生成することができます。 

この時点で、高速移動平均が低速移動平均を下から上に横切ると、自動売買ロボットはロングを開きます。ロボットがロングポジションを開いたときに通知するようにしましょう。

  1. ターミナル操作ログに表示する
  2. ターミナルでアラートを作成する
  3. 取引実行に関するレコードをロボットのログファイルに追加する
  4. 「BuySignal」サウンドを再生する
  5. Telegramにメッセージを送信する
  6. Telegramにチャートのスクリーンショットを送信する
取引を行った直後に「BuySignal」サウンドを再生すると、トランザクションが行われるたびにMetaTraderが自動的に独自のサウンドを再生するため、サウンドが再生されない可能性があります。したがって、すぐにではなく、トランザクションが行われた後、一定の遅延を伴ってサウンドを再生する必要があります(1秒)。 

6つのステップすべてを実装するには長い時間がかかるように思われるかもしれません。実際、これらすべてに特別なブロックがあります。6つのステップすべてを実装するには、文字通り20〜30秒かかります。これまでに行ったことはすべて、ほんの数分で実行できます。手作業でコードを書くよりも何倍も高速です。

Telegramブロックが正しく機能するためには、ボットを@BotFatherボットに登録し、ボットのトークンを取得して、BotBrainsエディターのボットの設定で指定する必要があります。また、@getmyid_botから取得できるTelegram IDを知っている必要があります。これはすべて、関連するドキュメントの記事で詳しく説明されています。Telegramを操作するためのブロックは、プロユーザーのみが利用できます。

同様に、ショートポジションを開くためのロジックを実装しましょう。これを行うには、ロングポジションのオープンに関連するすべてのブロックを選択し、コピー(CTRL + C)し、それらを貼り付け(CTRL + V)、必要な変更を加えます。

ロボットのコードを生成し、コンパイルしてターミナルで実行し、自動売買ロボットのパフォーマンスを確認します。

取引ロボットはデモ口座でのみテストしてください。デフォルトでは、BotBrainsエディターで作成されたすべてのロボットのセキュリティ設定により、実際の口座での取引が禁止されています。自動売買ロボットがデモ口座で完全にテストされた後でのみ、リアル口座での取引に切り替えてください。

ランダムな移動平均期間を設定し、1分の時間枠で取引ロボットを実行してみましょう。この時点で、自動売買ロボットのパフォーマンスをテストし、潜在的な間違いを検出して修正することが重要です。80分の取引の後、取引ロボットは4つのポジションを開きました。各ポジションが開かれた後、ロボットはターミナルで正常に通知を行い、適切なサウンドを再生し、ロボットのログファイルとターミナル操作ログに適切な記録を作成しました。ロボットはまた、メッセージとチャートのスクリーンショットを問題なくTelegramに直接送信しました。それにもかかわらず、コードは1行も記述していません。このような単純なロボットは、わずか数分で構築できます。

すべてが順調に見えるかもしれません。しかし、ここでの自動売買ロボットによって行われた取引を詳しく見ると、最初のポジションを除くすべてのポジションで、私たちの自動売買ロボットが2つの取引に参加していることがわかります。最初の取引では現在のポジションをエグジットし、2番目の取引では次のポジションを開きます。これを検出するのは簡単です。チャートを見て、ログファイルを確認し、自動売買ロボットがTelegramに送信するメッセージを見るか、取引が実行された後に自動売買ロボットが音声アラートを生成する回数を聞くだけです。また、ターミナルでの取引履歴を分析することもできます。

BotBrainsエディターでは、ロボットのセキュリティ設定で疑わしい取引と最大取引の頻度を指定できます。デフォルトでは、最大取引頻度は10秒あたり2取引です。取引の最大頻度に達すると、取引ロボットは開いたすべてのポジションを即座に閉じ、すべての注文を削除し、ライブチャットで通知したり、ターミナルで通知を作成したりします。

問題は、ロボットが必要な2倍の取引を行い、より望ましくない価格でほとんどのポジションに入るだけでなく、ある時点で最大取引頻度に達して取引を停止するということです。これはまさにこの場合に起こったことです。ログファイルの最後のレコードに注意してください。


この問題を修正しましょう。full_lot変数を作成します。

ロボットが起動したら、full_lot変数をlot定数の値に設定します。

次に、トランザクションブロックでは、lot定数を使用する代わりに、full_lot変数を使用する必要があります。

次に、ポジションを入力した後、full_lot変数の値をlot定数の値の2倍に設定します。最初の取引の後、ロボットは2倍のボリュームで取引を開始します。したがって、既存のポジションを決済して、1回の取引で新しいポジションを開きます。

自動売買ロボットは、1回の取引ですべてのポジションに入ることができます。ターミナルでロボットを実行して確認します。取引履歴を見ると、最初の取引は1ロットで開始され、次の取引は2ロットで開始されたことがわかります。

自動売買ロボットのインターフェイスを作成しましょう。これを行うには、エディターの「インターフェイス」モードに移動し、特別なブロックを使用してインターフェイスを構築します。

このようなインターフェイスを構築するには、次のインターフェイスブロックを使用するだけで十分です。

  1. 長方形
  2. ボタン
  3. テキスト
ダッシュの代わりに、高速移動平均と低速移動平均の現在の値を使用する必要があります。これを実装するには、[Modify interface element]ブロックを使用します。このブロックを使用して、指定したIDでブロックのプロパティを変更できます。

4つの[Modify interface element]ブロックをロボットのロジックスキームに移動してみましょう。

ブロックIDをコピーするには、次の手順を実行します。

  1. Ctrlキーを押す。
  2. Ctrlキーを離さずに、ターゲットブロックをダブルクリックする。

最初のダッシュのIDをコピーします。

最初の[Modify interface element]ブロックの設定を開き、パラメータ値を設定します。最初に行うことは、変更するプロパティのブロックのIDを指定することです。ここでの場合、それは最初のダッシュのコピーされたIDです。変更の種類として[Text]を選択する必要があります。新しいテキストとして変数ma_fast_prevを指定します。必要に応じて、新しいテキストの小数点以下の桁数を設定することもできます(この設定は、インターフェイステキストのテキストコンテンツとして数値が使用されている場合にのみ使用する必要があります)。


同様に、残りの3つの[Modify interface element]ブロックのパラメータを設定しましょう。このように、取引されている銘柄の新しいティックが受信されると、移動平均の対応する値が変数ma_fastma_slowma_fast_prevma_slow_prevに書き込まれます。 次に、これらの変数の値がインターフェイスの対応するテキスト要素に書き込まれます。

対応するアクションをインターフェイスボタンに割り当てましょう。これを行うには、2つの[Market order]ブロックと1つの[Close position]ブロックの3つのブロックをロボットの論理図に移動します。

次に、これらのブロックの設定を行います。

最初の[Market Order]ブロックのIDをコピーし、コピーしたIDを最初のボタンの[Linked block ID]パラメータの値として指定します。

これで、[Buy]ボタンを押すと、対応するブロックが呼び出されます。同様に、他のボタンにアクションを割り当てます。ロボットコードを生成し、ターミナルで実行してその機能を確認しましょう。

エディターで構築したインターフェイスは、取引ターミナルに完全に転送されていることに注意してください。インターフェイスボタンは機能し、ダッシュの代わりに移動平均の実際の値を確認できます。

その結果、自動売買ロボットの生成されたコードは以下のようになります。

//+------------------------------------------------------------------+
//|                                      moving_average_cross_en.mq5 |
//|                                                    botbrains.app |
//+------------------------------------------------------------------+

#include <botbrains_constants.mqh>
#include <botbrains_lib.mqh>

/********** <ROBOT CONSTANTS> **********/

const double __slow_ma_period = user_value("60");
const double __fast_ma_period = user_value("30");
const double __symbol         = user_value("MGCG22");
const double __admin_id       = user_value("744875082");
const double __lot            = user_value("1");

/********** </ROBOT CONSTANTS> **********/

/********** <ROBOT VARIABLES> **********/

double __ma_slow      = user_value("");
double __ma_fast      = user_value("");
double __ma_slow_prev = user_value("");
double __ma_fast_prev = user_value("");
double __full_lot     = user_value("");

/********** </ROBOT VARIABLES> **********/

int OnInit(){

  //Is autotrading allowed:
  if(!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)){
    MessageBox("Autotrading is not allowed, expert will be removed");
    ExpertRemove();
    return(-1);
  }

  //Is trading on live account allowed:
  if(AccountInfoInteger(ACCOUNT_TRADE_MODE) == ACCOUNT_TRADE_MODE_REAL){
    MessageBox("Expert is not allowd to trade on live account!");
    ExpertRemove();
    return(-1);
  }

  //Set robot name:
  set_robot_name("moving_average_cross_en");

  //Set license key:
  set_license_key("2L5J7K-K986ND-KMPT94-1Q");

  //Set language:
  set_lang("en");

  //Generate robot magic number:
  generate_magic();

  //Set initial trading account balance:
  set_init_account_balance();

  //Set suspicious deals frequency params:
  set_suspicous_deals_frequency(60, 3, false, true);

  //Set maximal deals frequency params:
  set_max_deals_frequency(10, 2, false, true);

  //Set the timer with an interval of 1 second:
  EventSetTimer(1);

  //Blocks executed when the robot is launched:
  block_bYi6ikfde();
  block_bYUS6GLT0();

  //Create interface elements:
  create_rectangle("b1ELCu5iq", 0, 0, CORNER_LEFT_UPPER, 15, 15, 390, 195, C'20,20,20', BORDER_FLAT, STYLE_SOLID, C'10,191,254', 2, 0, false, false, false);
  create_button("b4rh5uKlb", 0, 0, CORNER_LEFT_UPPER, 195, 165, 150, 30, "Sell", "Ubuntu Mono", 8, C'255,255,255', C'20,20,20', C'255,51,0', false, 0, false, false, false);
  create_text("b5BGSldua", 0, 0, CORNER_LEFT_UPPER, 120, 135, "-", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("b9EjNpibO", 0, 0, CORNER_LEFT_UPPER, 30, 30, "\"MA Cross\" trading robot", "Ubuntu Mono", 14, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_button("bBTrBQlkS", 0, 0, CORNER_LEFT_UPPER, 30, 165, 150, 30, "Buy", "Ubuntu Mono", 8, C'255,255,255', C'20,20,20', C'51,255,0', false, 0, false, false, false);
  create_text("bEncRhDIR", 0, 0, CORNER_LEFT_UPPER, 285, 75, "Current bar:", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bI0vadsS2", 0, 0, CORNER_LEFT_UPPER, -195, 270, "Text", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bK1cW1i6s", 0, 0, CORNER_LEFT_UPPER, 30, 135, "MA slow:", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bLcIIkYqO", 0, 0, CORNER_LEFT_UPPER, 285, 135, "-", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bSDWBsxbk", 0, 0, CORNER_LEFT_UPPER, 285, 105, "-", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bTK8r1zb1", 0, 0, CORNER_LEFT_UPPER, 30, 105, "MA fast:", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bhKcJ2pwx", 0, 0, CORNER_LEFT_UPPER, 120, 75, "Previous bar:", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_text("bj6MtjhZF", 0, 0, CORNER_LEFT_UPPER, 120, 105, "-", "Ubuntu Mono", 9, C'255,255,255', 0, ANCHOR_LEFT_UPPER, 0, false, false, false);
  create_button("bympSPhAp", 0, 0, CORNER_LEFT_UPPER, 360, 165, 30, 30, "X", "Ubuntu Mono", 8, C'255,255,255', C'20,20,20', C'255,51,0', false, 0, false, false, false);

  ChartRedraw();

  //Robot initialization was successful:
  return(INIT_SUCCEEDED);

}

void OnDeinit(const int reason){

  Comment("");
  PlaySound(NULL);

  //Remove all graphical objects from the chart on which the robot was launched:
  remove_all_objects(0);

}

void OnTimer(){

  //Timer with 1 sec. interval (bgP4YbxaQ):
  block_bTonyumSN();
  block_bO7LNEs4m();
  block_bS1JODjZj();
  block_bM4s77Wvc();

  //Every 10 sec. reset the counter of the performed deals number (max deals frequency):
  if(get_timer_tick_index() % 10 == 0){

    deals_max_frequency_counter_reset();

  }

  //Every 60 sec. reset the counter of the performed deals number (suspicious deals frequency):
  if(get_timer_tick_index() % 60 == 0){

    deals_suspicious_frequency_counter_reset();

  }

  timer_tick_index_increment();

}

void OnTick(void){

  //Blocks executed when a new tick is received on the symbol on the chart of which the robot was launched:
  block_bHxbWWtwW();
  block_bvIvs7SMe();
  block_boHVNlqnO();

}

void OnTrade(){

  //Check deals frequency:
  check_deals_frequency();

}

void OnChartEvent(
  const int      id,      // event identificator
  const long&    lparam,  // event parameter of type long
  const double&  dparam,  // event parameter of type double
  const string&  sparam   // event parameter of type string
){

  if(id == CHARTEVENT_OBJECT_CLICK){

    string object_name = sparam;

    if(ObjectGetInteger(0, object_name, OBJPROP_TYPE) == OBJ_BUTTON){

      if(object_name == "b4rh5uKlb"){

        block_bYGEhpZDM();

      }

      if(object_name == "bBTrBQlkS"){

        block_bCa4uSC92();

      }

      if(object_name == "bympSPhAp"){

        block_bXRrICVna();

      }

      Sleep(100);
      ObjectSetInteger(0, object_name, OBJPROP_STATE, false);
      ChartRedraw();

    }

  }

}

//Function of the block b0Wkfq6OD (set_complex_variable_value):
void block_b0Wkfq6OD(){

  vset(__ma_fast, ( moving_average(to_string(__symbol), PERIOD_CURRENT, (int)__fast_ma_period, MODE_SMA, PRICE_CLOSE, 0) ));

  block_b6LYVQGej();

}

//Function of the block b1VYatoxs (interface_element_modify):
void block_b1VYatoxs(){

  modify_text("b5BGSldua", DoubleToString(__ma_slow_prev, 2) );

}

//Function of the block b3UJfY74N (interface_element_modify):
void block_b3UJfY74N(){

  modify_text("bSDWBsxbk", DoubleToString(__ma_fast, 2) );

}

//Function of the block b3crj4ayK (log):
void block_b3crj4ayK(){

  log_to_file("Open short!");

  block_bzVyOb4tW();

}

//Function of the block b6LYVQGej (set_complex_variable_value):
void block_b6LYVQGej(){

  vset(__ma_slow_prev, ( moving_average(to_string(__symbol), PERIOD_CURRENT, (int)__slow_ma_period, MODE_SMA, PRICE_CLOSE, 1) ));

  block_bQMre45Bd();

}

//Function of the block bCa4uSC92 (place_market_order):
void block_bCa4uSC92(){

  place_market_order(to_string(__symbol), "BUY", __lot);

}

//Function of the block bHxbWWtwW (condition):
void block_bHxbWWtwW(){

  if (( __ma_fast > __ma_slow ) && ( __ma_fast_prev < __ma_slow_prev ) && ( get_position_info(to_string(__symbol), "POSITION_DIRECTION") != BUY_DIRECTION )){

    block_bUySCvh6M();

  }

}

//Function of the block bM4s77Wvc (print_debug_info):
void block_bM4s77Wvc(){

  print_debug_info(( to_string(to_double("ma_fast_prev = ")) + DoubleToString(__ma_fast_prev, 2) ));

}

//Function of the block bMgaVnT74 (pause):
void block_bMgaVnT74(){

  pause(1000);

  block_bT8xv0qGj();

}

//Function of the block bO7LNEs4m (print_debug_info):
void block_bO7LNEs4m(){

  print_debug_info(( to_string(to_double("ma_fast = ")) + DoubleToString(__ma_fast, 2) ));

}

//Function of the block bPlXoF1uA (set_complex_variable_value):
void block_bPlXoF1uA(){

  vset(__full_lot, ( __lot * to_double("2") ));

}

//Function of the block bQ4zsFoIh (log):
void block_bQ4zsFoIh(){

  log_to_file("Open long!");

  block_bMgaVnT74();

}

//Function of the block bQMre45Bd (set_complex_variable_value):
void block_bQMre45Bd(){

  vset(__ma_fast_prev, ( moving_average(to_string(__symbol), PERIOD_CURRENT, (int)__fast_ma_period, MODE_SMA, PRICE_CLOSE, 1) ));

  block_bRUr8MnXh();
  block_b1VYatoxs();
  block_b3UJfY74N();
  block_bofgi9HOT();

}

//Function of the block bRUr8MnXh (interface_element_modify):
void block_bRUr8MnXh(){

  modify_text("bj6MtjhZF", DoubleToString(__ma_fast_prev, 2) );

}

//Function of the block bS1JODjZj (print_debug_info):
void block_bS1JODjZj(){

  print_debug_info(( to_string(to_double("ma_slow_prev = ")) + DoubleToString(__ma_slow_prev, 2) ));

}

//Function of the block bT8xv0qGj (buy_signal_sound):
void block_bT8xv0qGj(){

  play_sound("buy_signal");

  block_bPlXoF1uA();

}

//Function of the block bTonyumSN (print_debug_info):
void block_bTonyumSN(){

  print_debug_info(( to_string(to_double("ma_slow = ")) + DoubleToString(__ma_slow, 2) ));

}

//Function of the block bTs8fZtAO (telegram_send_chart_screenshot):
void block_bTs8fZtAO(){

  telegram_send_chart_screenshot(to_string(__symbol), 2160, 720, (int)__admin_id);

}

//Function of the block bUySCvh6M (place_market_order):
void block_bUySCvh6M(){

  place_market_order(to_string(__symbol), "BUY", __full_lot);

  block_bfrp6ajWk();
  block_bjBTLJMym();
  block_boX0sSwri();
  block_bQ4zsFoIh();

}

//Function of the block bWkG0nSQa (telegram_send_message):
void block_bWkG0nSQa(){

  telegram_send_message("Open short!", (int)__admin_id);

}

//Function of the block bX2tY0y68 (terminal_print):
void block_bX2tY0y68(){

  terminal_print("Open short!");

}

//Function of the block bXRrICVna (close_position):
void block_bXRrICVna(){

  close_position(to_string(__symbol));

}

//Function of the block bYGEhpZDM (place_market_order):
void block_bYGEhpZDM(){

  place_market_order(to_string(__symbol), "SELL", __lot);

}

//Function of the block bYUS6GLT0 (set_complex_variable_value):
void block_bYUS6GLT0(){

  vset(__full_lot, ( __lot ));

}

//Function of the block bYi6ikfde (terminal_print):
void block_bYi6ikfde(){

  terminal_print("Робот запущен!");

}

//Function of the block bfrp6ajWk (terminal_print):
void block_bfrp6ajWk(){

  terminal_print("Open long!");

}

//Function of the block biLE3RJAD (sell_signal_sound):
void block_biLE3RJAD(){

  play_sound("sell_signal");

  block_bPlXoF1uA();

}

//Function of the block bjBTLJMym (telegram_send_message):
void block_bjBTLJMym(){

  telegram_send_message("Open long!", (int)__admin_id);

}

//Function of the block boHVNlqnO (set_complex_variable_value):
void block_boHVNlqnO(){

  vset(__ma_slow, ( moving_average(to_string(__symbol), PERIOD_CURRENT, (int)__slow_ma_period, MODE_SMA, PRICE_CLOSE, 0) ));

  block_b0Wkfq6OD();

}

//Function of the block boX0sSwri (telegram_send_chart_screenshot):
void block_boX0sSwri(){

  telegram_send_chart_screenshot(to_string(__symbol), 2160, 720, (int)__admin_id);

}

//Function of the block bofgi9HOT (interface_element_modify):
void block_bofgi9HOT(){

  modify_text("bLcIIkYqO", DoubleToString(__ma_slow, 2) );

}

//Function of the block bugmLdNsU (place_market_order):
void block_bugmLdNsU(){

  place_market_order(to_string(__symbol), "SELL", __full_lot);

  block_bX2tY0y68();
  block_bWkG0nSQa();
  block_bTs8fZtAO();
  block_b3crj4ayK();

}

//Function of the block bvIvs7SMe (condition):
void block_bvIvs7SMe(){

  if (( __ma_fast < __ma_slow ) && ( __ma_fast_prev > __ma_slow_prev ) && ( get_position_info(to_string(__symbol), "POSITION_DIRECTION") != SELL_DIRECTION )){

    block_bugmLdNsU();

  }

}

//Function of the block bzVyOb4tW (pause):
void block_bzVyOb4tW(){

  pause(1000);

  block_biLE3RJAD();

}

BotBrainsエディターでは、このような取引ロボットを数分で構築できて、コード生成にかかるのは数分の1秒です。

利用可能なブロック

BotBrainsエディターには140を超えるブロックがあります。以下は、使用可能なすべてのブロックの完全な表です。エディターの使用方法を完全に理解するために、ドキュメントを読むことを強くお勧めします。

イベントブロック:

ブロック 説明
Start of robot work
ロボットが起動すると有効になります。
End of robot work
ロボットをオフにすると有効になります。
Depth of market change
指定された銘柄の市場の深さが変化するたびに有効になります。
New tick
ロボットが起動されたチャート上の銘柄で新しいティックが受信されるたびに有効になります。
Open volume change
指定された銘柄のオープンボリュームが変更されるたびに有効になります。
Limit order number change
指定された銘柄のアクティブな指値注文の数が変わるたびに有効になります。
Stop orders number change
指定された銘柄のアクティブなストップ注文の数が変わるたびに有効になります。
Timer
指定された秒数ごとに1回有効になります。
Key press
指定したコードのキーを押すと有効になります。

条件:

[if]ブロックは、特定の条件をチェックするために使用されます。
ブロック 説明
[if]ブロック
このブロックは、さまざまなチェックを実行するために使用されます。このブロックには、1つの入力と2つの出力があります。

ループ:

ループブロックは、主に特定の値を列挙するために使用されます。たとえば、ループブロックを使用して、アクティブな指値注文のリストを列挙できます。

ブロック
説明
Whileループ
指定された条件が真である限りアクティブになります。

トレンド指標:

ブロック
Adaptive Moving Average(適応型移動平均)
Average Directional Movement Index(平均方向性指数)
Average Directional Movement Index by Welles Wilder(ウェルズワイルダーの平均方向性指数)
Bollinger Bands(ボリンジャーバンド)
Double Exponential Moving Average(2重指数移動平均)
Envelopes(エンベローブ)
Fractal Adaptive Moving Average(フラクタル適応型移動平均)
一目均衡表
Moving Average(移動平均)
Parabolic SAR(パラボリック SAR)
Standard Deviation(標準偏差)
Triple Exponential Moving Average(3重指数移動平均)
Variable Index Dynamic Average(可変インデックス動的平均)  

オシレータ―

ブロック
Average True Range(ATR)
Bears Power(ベアパワー)
Bulls Power(ブルパワー)
Chaikin Oscillator(チャイキンオシレーター)
Commodity Channel Index(商品チャンネル指数)
DeMarker(デマーカー)
Force Index(勢力指数)
MACD(移動平均収束拡散法)
Momentum(モメンタム)
Moving Average of Oscillator(移動平均オシレーター)
RSI (Relative Strength Index、相対強度指数)
Relative Vigor Index(相対活力指数)
Stochastic Oscillator(ストキャスティックス)
TRIX (Triple Exponential Moving Averages Oscillator、3重指数移動平均)
Larry Williams' Percent Range(ウィリアムパーセントレンジ)
Accumulation / Distribution(累積/分布)
Money Flow Index(マネーフローインデックス)
On Balance Volume(オンバランス数量)
Volume(数量)

Bill Williams(ビルウィリアムズ):

ブロック
Accelerator Oscillator(ACオシレーター)
Alligator(アリゲーター)
Awesome Oscillator(オーサムオシレータ)
Fractals(フラクタル)
Gator(ゲータ―)
Market Facilitation Index(マーケットファシリテーションインデックス)

チャート分析:

チャートと個々のバーに関する情報を取得します。チャートに垂直線と水平線を描画します。

ブロック 説明
Bar information
特定のチャートバーに関する情報を取得します。
Chart information
特定のチャートに関する情報を取得します。たとえば、利用可能なバーの数を取得したり、最初に利用可能なバーの時間を取得したり、最後のバーの時間を取得したりします。
Max price
指定された期間の銘柄の最高価格を取得します。
Min price
指定された期間の銘柄の最低価格を取得します。
Average price
指定された期間の銘柄の平均価格を取得します。
Draw horizontal line
銘柄のチャートに水平線を描画します。
Draw vertical line
銘柄のチャートに垂直線を描画します。
Remove all lines
チャートからすべての水平線と垂直線を削除します。

チャート分析:

市場の深さとその具体的な相場に関する情報を取得します。

ブロック
説明
Quote info
DOM(市場の深さ)の特定の見積もりに関する情報を取得します。
Spread
指定された銘柄のDOMのスプレッド値(ティック単位)を取得します。

トランザクション:

成行注文、(逆)指値注文を出します。(逆)指値注文を削除します。ポジションを決済します。

ブロック 説明
Market order
成行注文を出します。
Limit order
指値注文を出します。
Remove limit order
指値注文を削除します。
Remove all limit orders
指定された銘柄のすべての指値注文を削除します。
Stop order
逆指値注文を出します。
Remove stop order
逆指値注文を削除します。
Remove all stop orders
指定された銘柄のすべての逆指値注文を削除します。
Close position
指定された銘柄のポジションを決済します。
Close all open positions
ロボットが開いたすべてのポジションを決済します。

変数:

ブロック
説明
Set variable simple value
変数の新しい値は、単一の入力フィールドで指定されます。つまり、このブロックを使用すると、変数に固有の何かを書き込むことができます-数字またはテキストだけです。
Set variable complex value
変数の新しい値は、計算された値によって決定されます。たとえば、このブロックを使用して、取引されたシンボルの現在の預金値または現在の価格を変数に書き込むことができます。
Variable select
変数の選択。たとえば、[variable select]ブロックを条件ブロック内で使用して、変数の値を確認できます。

サウンド:

ブロック
説明
Smooth sound
「なめらかな音」を再生します。
Alarm
「アラーム」を再生します。
Buy signal
「Buy Signal」サウンドを再生します。
Sell signal
「Sell Signal」サウンドを再生します。

情報:

口座、ポジション、アクティブおよび過去の(逆)指値注文、過去の取引に関する情報を取得します。取引セッション、銘柄仕様、時間に関する情報を取得します。

ブロック
Account information
Position information
Limit order information
All limit orders information
Stop order information
All stop orders information
History limit order information
History stop order information
History deal information
Trading session information
Symbol information
Time information

列挙:

Enumブロックは何かを列挙するために使用されます。たとえば、列挙型ブロックを使用して、シンボルのリストまたはアクティブな指値/ストップ注文のリストを列挙できます。

ブロック 説明
銘柄名
銘柄名を取得します。
Request active orders list
アクティブ注文のリストをリクエストします。
Active limit order ticket
アクティブな指値注文のリストを取得します。
Active stop order ticket
アクティブな逆指値注文のリストを取得します。
アクティブな注文のリストを列挙する前に、必ず[Request list active orders list]ブロックを使用してください。そうしないと、無関係なデータを処理することになります。

履歴:

ブロック 説明
Request history
指定された期間の履歴をリクエストします。
History deal ticket
取引チケットの履歴を取得します。
History limit order ticket
指値注文の履歴を取得します。
History stop order ticket
逆指値注文の履歴を取得します。
過去の注文と取引のリストを列挙する前に、必ず[Request history]ブロックを呼び出してください。そうしないと、無関係なデータを処理することになります。

Telegram:

特別なブロックを使用すると、ロボットはメッセージやグラフのスクリーンショットをTelegramに直接送信できます。

ブロック
説明
Send message
指定されたIDのユーザーにTelegramメッセージを送信します。
Send chart screenshot
指定されたIDのユーザーにチャートのスクリーンショットを送信します。
New line
このブロックは、Telegramメッセージに改行を作成するために使用されます。

その他のブロック:

ブロック 説明
Journal message
ターミナルの操作ログにメッセージを印刷します。
Terminal alert
ターミナルで通知を行います。
Chart comment
指定された銘柄のチャートにコメントを表示します。
Log to file
ロボットのログファイルにログを作成します。
Pause
指定されたミリ秒数の間、ロボットを一時停止します。
Turn the robot off
ロボットをオフにします。
Close terminal
ターミナルを閉じます。

インターフェイス要素:

ブロック
説明
長方形
「長方形」インターフェイス要素
ボタン
「ボタン」インターフェイス要素
テキスト
「テキスト」インターフェイス要素
値の入力
「値の入力」インターフェイス要素

インターフェイス要素の変更:

ブロック
説明
Modify interface element
インターフェイス要素の特定のプロパティを変更します。

インターフェイス要素情報:

ブロック
説明
Interface element info
このブロックは、指定されたIDを持つインターフェイス要素ブロックの指定されたプロパティの値を返します。

事前定義された定数:

事前定義された定数は、特定のプロパティの可能な値です。たとえば、[direction]ブロックには、可能な方向の事前定義された定数が含まれています(売、買、方向なし)。

ブロック
説明
方向
可能なポジションの方向(売、買、方向なし)
Deal entry
可能な取引エントリ(エントリイン、エントリアウト、リバース、反対のポジションでポジションを決済)
取引タイプ
可能な取引タイプ(購入、販売、残高、クレジット、修正など)

デバッグ:

[print debug info]には多くの用途があります。これは主に、変数の値とブロックが返す値を確認するために使用されます。

ブロック 説明
Print debug info
指定されたメッセージをターミナルの操作ログに出力します。

数学演算子:

ブロック 説明
+
加算
-
減算
/ 徐算
* 乗算

平方根
^ 累乗
%
除算剰余
( 開き括弧
) 閉じ括弧
> 次より大きい
< 次より小さい
>= 以上
<= 以下

論理演算子:

ブロック 説明
AND 論理AND
OR 論理OR
NOT 論理NOT

Teleports:

ブロック
Teleport IN
Teleport OUT
Variable or constant select:
ブロック
Variable select
Constant select

Value input:

ブロック 説明
値の入力
このブロックを使用して、スキーム内で特定の値を正しく設定できます。

Type conversion:

デフォルトでは、すべてのデータは数値として表されます。型変換ブロックを使用すると、特定の値を表す必要がある形式を明示的に指定できます。

ブロック 説明
Regular string
値を通常の文字列に変換します。
Date and time format string
値を日付と時刻の形式に変換します。
Integer
値を整数に変換します。
Fraction
値を小数に変換します。

終わりに

このプロジェクトを完了するには、開発に数か月かかりました。エディターの動作に関するアイデアや提案があれば、support@botbrains.appにメールを送ってください。ご意見を考慮いたします。

MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/9998

取引のための組合せ論と確率論(第IV部): ベルヌーイの定理 取引のための組合せ論と確率論(第IV部): ベルヌーイの定理
本稿では、よく知られているベルヌーイスキームをハイライトし、それを使用して取引関連のデータ配列を記述する方法を示すことにしました。これらはすべて、自己適応型の取引システムを作成するために使用されます。また、より一般的なアルゴリズムを探して、その応用を見つけます。ベルヌーイの定理はその特殊なケースです。
マーケット価格予測に対する汎用回帰モデル(第2部): 自然、技術、社会の過渡関数 マーケット価格予測に対する汎用回帰モデル(第2部): 自然、技術、社会の過渡関数
本稿は前稿からの論理的続編で、最初の記事で出された結論を確認する事実にハイライトを当てています。これらの事実は、その出版後10年以内に明らかになったもので、マーケット価格変化のパターンを説明する3つの検出された動的過渡関数を中心としています。
固定プライスアクションストップロスまたは固定RSI(スマートストップロス) 固定プライスアクションストップロスまたは固定RSI(スマートストップロス)
ストップロスは、取引における資金管理に関する主要なツールです。ストップロス、テイクプロフィット、ロットサイズを効果的に使用することで、トレーダーは取引の一貫性を改善し、全体的に収益性を高めることができます。ストップロスは優れたツールですが、使用時に課題に遭遇することがあります。主要なものはストップロスハントです。この記事では、取引でのストップロスハントを減らす方法と、従来のストップロスの使用法と比較して収益性を判断する方法について説明します。
より優れたプログラマー(第07部): 成功したフリーランス開発者になるためのメモ より優れたプログラマー(第07部): 成功したフリーランス開発者になるためのメモ
MQL5でフリーランス開発者として成功したいならば、この記事はあなたにぴったりです。