![異なる国での異なるタイムゾーンに基づくトレーディング戦略例](https://c.mql5.com/i/articles/overlay.png)
異なる国での異なるタイムゾーンに基づくトレーディング戦略例
はじめに
私はいくらか空時間があったので、当然そこでマーケットについて学習したり、経済循環の多様性やテクニカルインディケータの調査をしました。研究結果は『グラフィックコントロールオプションを使用したインディケータ作成』稿でご覧いただけます。でもそれだけではないんです!もっと大きなスケールでの現象も見つけました。しかしそれを理解するには、まずタイムゾーンについて世界を見ていきたいと思います。(図1)
図1 タイムゾーン
国ごとに日の始まりは異なり、様々な時間帯で続いていきます。見てのとおり、われわれの広大な国は約10ものタイムゾーンにかけて広がっています。それに比べ大西洋はたった6のタイムゾーンにしか及びません。
ではここでのパターンはどうなっているのでしょうか?次の国々でのマーケットの開始順序について見てみます。:日本、オーストラリア、中国、ロシア。ロシアの銀行員が最初にオフィスにやってきてトレーディングを始めるまでに、アジアはすでに夕方で、ヨーロッパで取引が始まるころ、アジアマーケットはすでに終了しています。
ここからがお楽しみです。ひとたびマーケットが始まると、ヨーロッパのブローカーやヘッジファンドの幹事会社は資産をマーケットに投資し、投機的または投資家の関心や行動に合った対応をします。6時間しか隔たっていない大西洋を越え、シカゴの夜明けと伴に始まるもっとも面白い部分にはまだ早すぎます。シカゴ株式市場の幹事会社それぞれトレーティング端末を開き、資本を操作し始める時間の到来です。
ここでちょっと一息入れます。小さい大西洋を隔てて。ヨーロッパの取引はまだ終わっていません。(図1) ロンドンとシカゴの時差は8時間です。就業時間が8時間+タバコ休憩45分だとすると、それはあと1時間半~2時間は伸びます(オフィスで働いたことのある人はこれが何かお分かりでしょう)。
これがヨーロッパやアメリカの幹事会社が市場資産を得る時間です。ここで資本の金額は挙げません。ヨーロッパとアメリカの幹事会社は証券取引で利益を得ようと必死に努力し始めています。そしてこれが図2に示されるようなひとつの現象です。
図2 マーケットの 鼓動
金融戦闘がマーケットを席巻し、資本が毎秒持ち主を変えますが、これでマーケットが終わるわけではありません。この時期が終わると、静かな動きが始まり、最新トレンドへと方向を移していくのです。この時点で、レンジはその境界を拡げ、それから再び狭め、主流のトレンドへ向けて動き続けます。
マーケット価格は上下どちらにもなりますが、常に右に向かって動くのはご存じのことと思います。
2. アルゴリズム作成の初期手法のフローチャート
図3に『スタート・ストップ』 プログラムの最初のプロックを示しています。
図3 『スタート・ストップ』プロック
このブロックはプログラムの開始を表示するのに使用されます。関数その他プロシージャの初期化と再初期化のような最初と終わりを示すのです。次に見るブロックは『データ』とつけられており、図4に描かれています。
図4 『データ』プロック
『データ』プロックはプログラムの起動時、またはMQL5の場合はアウトプット変数に指定されたパラメータを決定するのに使用されます。このユニットもグローバル変数の行き先の関数を提供します。
次に共通して使われるブロックMQL(プログラムの99%はこのメソッドを使います。)について考察します。 - それはサイクルの境界を示す2つの部分として描かれます。図5の考察
図5 サイクルブロック
属性や会計などのプロセスは通常こういったサイクルで起こります。その例が図6として示されています。
図6 処理
そして忘れてはならないのは論理ブロックです。図7には『ソリューション』ブロックが示されています。
図7 『ソリューション』ブロック
『ソリューション』ブロックもまた『配置数依存のスイッチ』タイプのオペレータ内に配置されると、3つ以上のアウトプットを持ちます。このユニットはアウトプットの数に対応します。
次のブロックは、 iMACD や iRSAなど定義済み関数を誘導します。プログラムやライブラリの別の場所で定義されるカスタム関数も同様です。(図8)
図8 関数
そして、最後の2つのブロックはサービス関数のみ実装します。 - コメントや違反などです。(図9)
図9 サービスブロック
これらはマシンのために書かれるあらゆるプログラムを記述するのに使うことができる全ブロックタイプです。;それらは開発の初期段階で使うには明確、シンプル、簡単で、システムの弱点を明らかにし、それを除去するデバイスメソッドが明示されます。
これでこのメソッドに関する知識を得ました。ただし、これらスキームについて細かく対応するようにとは言いません。ただフローチャートの初期値を知ると、計算手法のあるタイプを理解するのが簡単になります。このメソッドにより考えを速くまとめることができます。考えがすばやく脳の左半球に撃ち込まれ、右半球から出ていくのです。
3. アルゴリズムの構築
では、フローチャート戦略にのっとりExpert Advisorの準備に進んでいきます。
最初のブロックは入力パラメータを要求します。すでに決めているように、主要な戦いの間は待つのが不可欠で重要です。すなわち、米国で取引が始まった2時間後、ヨーロッパでの取引終了時間です。これを世界時計で見ます。どういうことかと言うと、終了時刻からわれわれ自身の開始時刻を計算するのです。
そして、ポジションサイズ、収益と損失のレベルを判断します。それは将来最適化する可能性のあるものです。マジックナンバーパラメータには特に注意が必要です。なぜなら、われわれのExpert Advisor によって注文とトレード開始を判断するのに使用されるからです。それ以上に、観測のため、ポジションのリスクに限度を設けるためにトレーリングストップを作成します。
その他にも必要となるおもしろいパラメータがあります。 - 安全レベルで、それによりそのときの重大な経済ニュースがあるか見、この2時間の間にマーケットに大きなパニックが起こるか配慮しながらそういったニュースが脅威となるか注意します。
図10 入力パラメータ
//--- input parameters input int America=16; input double Lots=0.1; input int TakeProfit=500; input long MagicNumber=665; input int Limited=600; input int TrailingStop=100;
戦略作成の次の部分に進みます。
セッションがクロスか、そしてで注文が出されているか、または出されようとしているか判断する必要があります。(図11)
Figure 11. トレード時刻
ご覧のようおに、与えられたアルゴリズムは入力パラメータを伴う閉じられたプログラムで、計算と出力結果で完成されます。そのようなミニプログラムは関数と呼ばれ、カプセル化によってメインのプログラムから保護されています。
カプセル化は、メソッドで分けられたプログラムまたはプログラムの一部の間のバリアです。ゲットとセット(get と set)のようなもので、他のゲットとセットの領域を通過することを防ぐのが目的です。このプロセスの基本は変数名が関数内またメインプログラム内で同じであるという事実にありますが、Getメソッドが変数名でセルから引き出そうとするとき、それはカプセル化に直面します。それによりメソッドはこの関数またはプログラムに割り当てられたメモリーセルの特定セクタにしかアクセスできません。
同じことがSetメソッドにも起こりますが、Getメソッドと同じではありません。それは値を変数名としてセルメモリに設定します。プログラムと関数内の変数名が一致すると、カプセル化はSetメソッドが変数値を別のプログラムや関数に割り当てることを許可しません。
bool time2trade(int TradeHour,int Number) { MqlDateTime time2trade; TimeTradeServer(time2trade); if(time2trade.hour!=TradeHour) return(false); time2trade.hour= 0; time2trade.min = 0; time2trade.sec = 1; for(int ii=OrdersTotal()-1;ii>=0;ii--) { OrderGetTicket(ii); long ordmagic=OrderGetInteger(ORDER_MAGIC); if(Number==ordmagic) return(false); } HistorySelect(StructToTime(time2trade),TimeTradeServer()); for(int ii=HistoryOrdersTotal()-1;ii>=0;ii--) { long HistMagic=HistoryOrderGetInteger(HistoryOrderGetTicket(ii),ORDER_MAGIC); if(Number==HistMagic) return(false); } return(true); }
要求されるセッションを特定し、注文を出すかどうか判断しました。では次にすべきことを考えます。
以前、主要な変動は米国のセッション開始2時間後に起こる、と知りました。米国セッションの開始後9本の15分バーを取得します。この期間の最大範囲を見つけ、それについて注意深く考察します。 - もしこの変化が十分大きければ、マーケットには広範なパニックが起こりえ、将来のトレンドは予測の困難なものとなります。そのためここで制約を設ける必要があります。
マーケットが沈静化していると、セッションは予想変動率を上げます。これによりメインのトレンドから最大偏差を決め、安全な距離でオーダートラップをセットする機会を得ます。それはメイントレンドが継続するのでうまくいきます。前にわかったように、価格は上下しますが、常に右方向に移動します。(図12)
図12 発注のアルゴリズム
プログラムコードを作るとき、トレーディング端末であるMetaTrader 5は前回のトランザクション価格に近い注文の設定を許さないことに注意が必要です。このときに価格が新規最小または最大を引き寄せたら、注文について信頼性の高い判断をするために、前回トランザクション価格から最小距離まで下がりポジションを守ります。また、その日の終了前に注文の継続期間を設定します。のちにそれらは有効でなくなるためです。
void OnTick() { //--- if(time2trade(America+2,MagicNumber)) { int i; double Highest = 0; double Lowest = 0; MqlRates Range[]; CopyRates(Symbol(),15,0,9,Range); Lowest=Range[1].low; for(i=0; i<9;i++) { if(Highest<Range[i].high) Highest=Range[i].high;//MathMax(,Highest); if(Lowest>Range[i].low) Lowest=Range[i].low; } long StopLevel=SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL); Highest=Highest+StopLevel*Point(); // add to the current prices parameters of the minimum distance possible for the setting of orders Lowest=Lowest-StopLevel*Point(); // to ensure the maximum probability of the acceptance of our order 30> if((Higest-Lowest)/Point()<Limited) { MqlTradeRequest BigDogBuy; MqlTradeRequest BigDogSell; BigDogBuy.action=TRADE_ACTION_PENDING; // Set the pending order BigDogBuy.magic = MagicNumber; BigDogBuy.symbol=Symbol(); BigDogBuy.price=Highest; //Price by which the order will be set BigDogBuy.volume=Lots; BigDogBuy.sl=Lowest; //if the stop loss is not set, then set by the strategy /s39> BigDogBuy.tp=Highest+TakeProfit*Point(); //set the take profit/s41> BigDogBuy.deviation=dev; //minimum deviation from the requested price, //in other words, by how much the executed price can differ from the specified price BigDogBuy.type=ORDER_TYPE_BUY_STOP; //order type, which is executed based on the specified price or by a higher than specified price //in this case the order is set to a higher or equal amount to the specified price //if the order type was buy_limit, then it would be executed //by the specified price, or prices lower than the specified price BigDogBuy.type_filling=ORDER_FILLING_AON; //the given parameter demonstrates how the order acts //with partial execution of the scope BigDogBuy.expiration=TimeTradeServer()+6*60*60; //by the strategy text the order life span only for the current work day //since it has been 2 hours since the opening of the American market, and the work day is 8 hours, we have 8-2 = 6 BigDogSell.action=TRADE_ACTION_PENDING; // Set the pending order BigDogSell.magic = MagicNumber; BigDogSell.symbol=Symbol(); BigDogSell.price=Lowest; //Price, by which the order will be set BigDogSell.volume=Lots; BigDogSell.sl=Highest; //Stop loss set by the strategy BigDogSell.tp=Lowest-TakeProfit*Point(); //set the take profit BigDogSell.deviation=dev; //Minimum deviation from the requested price, //in other words, by how much the executed price can differ from the specified price BigDogSell.type=ORDER_TYPE_SELL_STOP; //order type, which is executed based on the specified price or by a higher than specified price //in this case the order is set to a higher or equal amount to the specified price //if the order type was buy_limit, then it would be executed //by the specified price, or prices lower than the specified price BigDogSell.type_filling=ORDER_FILLING_AON; //the given parameter demonstrates how the order acts ///with partial execution of the scope BigDogSell.expiration=TimeTradeServer()+6*60*60; //by the strategy text the order life span only for the current work day //since it has been 2 hours since the opening of the American market, and the work day is 8 hours, we have 8-2 = 6 MqlTradeResult ResultBuy,ResultSell; OrderSend(BigDogBuy,ResultBuy); OrderSend(BigDogSell,ResultSell); } }
発注し、トラップも設定しました。ここからポジションのリスクを減らしていきます。トレーリングストップ(trailing stop)の技術を採用します。
ポジションを特定するために、マジックナンバー(MagicNumber)を使い、安値の変動に応じて収益の特定レベルに達したとき、ストップロスのレベルを移動します。(図13)
図13 トレーリングストップの実装
別戦略として、もっともシンプルなメソッドを使ってトレーリングストップを実装します。しかし戦略の中には、価格が目標に達するのを邪魔しないように、またはその原理をノーロス ポジションの変換にのみ使うよう、トレーリングストップを使わないことを推奨するものもあります。ですが、この戦略では、保護的ストップを変動する一般的なメカニズムを採用します。価格変動がある場合は、安値変更の特定数へ向かう方向に動くものです。
//--- trailing implementation int PosTotal=PositionsTotal(); for(int i=PosTotal-1; i>=0; i--) { //--- go through open positions and see if there are positions created by this Expert Advisor. if(PositionGetSymbol(i)==Symbol()) { if(MagicNumber==PositionGetInteger(POSITION_MAGIC)) { MqlTick lasttick; SymbolInfoTick(Symbol(),lasttick); if(PositionGetInteger(POSITION_TYPE)==0) { //--- buy if(TrailingStop>0 &&(((lasttick.bid-PositionGetDouble(POSITION_PRICE_OPEN))/Point())>TrailingStop) && ((lasttick.bid-PositionGetDouble(POSITION_SL))/Point())>TrailingStop) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.bid - TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } if(PositionGetInteger(POSITION_TYPE)==1) {//--- sell if(TrailingStop>0 && ((PositionGetDouble(POSITION_PRICE_OPEN)-lasttick.ask)/Point()>TrailingStop) && (PositionGetDouble(POSITION_SL)==0 || (PositionGetDouble(POSITION_SL)-lasttick.ask)/Point()>TrailingStop)) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.ask + TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } } } } }
次にアルゴリズムをまとめます。 (図14)
図14 アルゴリズムを組み合わせます。
//+------------------------------------------------------------------+ //| BigDog_By_CoreWinTT.mq5 | //| Copyright 2010, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2010, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" //--- input parameters input int America=16; input double Lots=0.1; input int TakeProfit=500; input long MagicNumber=665; input int Limited=600; input int TrailingStop=100; int dev=30; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- return(0); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ bool time2trade(int TradeHour,int Number) { MqlDateTime time2trade; TimeTradeServer(time2trade); if(time2trade.hour!=TradeHour) return(false); time2trade.hour= 0; time2trade.min = 0; time2trade.sec = 1; for(int ii=OrdersTotal()-1;ii>=0;ii--) { OrderGetTicket(ii); long ordmagic=OrderGetInteger(ORDER_MAGIC); if(Number==ordmagic) return(false); } HistorySelect(StructToTime(time2trade),TimeTradeServer()); for(int ii=HistoryOrdersTotal()-1;ii>=0;ii--) { long HistMagic=HistoryOrderGetInteger(HistoryOrderGetTicket(ii),ORDER_MAGIC); if(Number==HistMagic) return(false); } return(true); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- if(time2trade(America+2,int(MagicNumber))) { int i; double Highest= 0; double Lowest = 0; MqlRates Range[]; CopyRates(Symbol(),15,0,9,Range); Lowest=Range[1].low; for(i=0; i<9;i++) { if(Highest<Range[i].high) Highest=Range[i].high; if(Lowest>Range[i].low) Lowest=Range[i].low; } long StopLevel=SymbolInfoInteger(Symbol(),SYMBOL_TRADE_STOPS_LEVEL); Highest=Highest+StopLevel*Point(); //--- add to the current prices the parameters of a minimum possible distance for the order set. Lowest=Lowest-StopLevel*Point(); //--- to ensure the maximum probability of the acceptance of our order. if((Highest-Lowest)/Point()<Limited) { MqlTradeRequest BigDogBuy; MqlTradeRequest BigDogSell; ZeroMemory(BigDogBuy); ZeroMemory(BigDogSell); BigDogBuy.action=TRADE_ACTION_PENDING; //--- set the pending order BigDogBuy.magic = MagicNumber; BigDogBuy.symbol=Symbol(); BigDogBuy.price=Highest; //--- Price by which the order will be set BigDogBuy.volume=Lots; BigDogBuy.sl=Lowest; //--- if the stop loss is not established, then we set by the strategy BigDogBuy.tp=Highest+TakeProfit*Point(); //--- set the take profit BigDogBuy.deviation=dev; //--- Minimum deviation from the requested price, //--- in other words, by how much the executed price can differ from the specified price BigDogBuy.type=ORDER_TYPE_BUY_STOP; //--- order type, which is executed based on the specified price or by a higher than specified price //--- in this case the order is set to a higher or equal amount to the specified price //--- if the order type was buy_limit, then it would be executed //--- by the specified price, or prices lower than the specified price BigDogBuy.type_filling=ORDER_FILLING_FOK; //--- the given parameter demonstrates how the order acts //--- with partial execution of the scope BigDogBuy.expiration=TimeTradeServer()+6*60*60; //--- by the strategy text the order life span only for the current work day //--- since it has been 2 hours since the opening of the American market, //--- and the work day is 8 hours, we have 8-2 = 6 BigDogSell.action=TRADE_ACTION_PENDING; //-- Set the pending order BigDogSell.magic = MagicNumber; BigDogSell.symbol=Symbol(); BigDogSell.price=Lowest; //--- Price by which the order will be set BigDogSell.volume=Lots; BigDogSell.sl=Highest; //-- Stop loss set by the strategy BigDogSell.tp=Lowest-TakeProfit*Point(); //--- Set take profit BigDogSell.deviation=dev; //--- Minimum deviation from the requested price, //--- in other words, by how much the executed price can differ from the specified price BigDogSell.type=ORDER_TYPE_SELL_STOP; //--- order type, which is executed based on the specified price or by a higher than specified price //--- in this case the order is set to a higher or equal amount to the specified price //--- if the order type was buy_limit, then it would be executed //--- by the specified price, or prices lower than the specified price BigDogSell.type_filling=ORDER_FILLING_FOK; //--- the given parameter demonstrates how the order acts //--- with partial execution of the scope BigDogSell.expiration=TimeTradeServer()+6*60*60; //-- by the strategy text the order life span only for the current work day //--- since it has been 2 hours since the opening of the American market, //--- and the work day is 8 hours, we have 8-2 = 6 MqlTradeResult ResultBuy,ResultSell; ZeroMemory(ResultBuy); ZeroMemory(ResultSell); OrderSend(BigDogBuy,ResultBuy); OrderSend(BigDogSell,ResultSell); } } //--- trailing implementation int PosTotal=PositionsTotal(); for(int i=PosTotal-1; i>=0; i--) { //--- go through open positions and see if there are positions created by this Expert Advisor. if(PositionGetSymbol(i)==Symbol()) { if(MagicNumber==PositionGetInteger(POSITION_MAGIC)) { MqlTick lasttick; SymbolInfoTick(Symbol(),lasttick); if(PositionGetInteger(POSITION_TYPE)==0) { //--- buy if(TrailingStop>0 &&(((lasttick.bid-PositionGetDouble(POSITION_PRICE_OPEN))/Point())>TrailingStop) && ((lasttick.bid-PositionGetDouble(POSITION_SL))/Point())>TrailingStop) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.bid - TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } if(PositionGetInteger(POSITION_TYPE)==1) {//--- sell if(TrailingStop>0 && ((PositionGetDouble(POSITION_PRICE_OPEN)-lasttick.ask)/Point()>TrailingStop) && (PositionGetDouble(POSITION_SL)==0 || (PositionGetDouble(POSITION_SL)-lasttick.ask)/Point()>TrailingStop)) { MqlTradeRequest BigDogModif; ZeroMemory(BigDogModif); BigDogModif.action= TRADE_ACTION_SLTP; BigDogModif.symbol= Symbol(); BigDogModif.sl = lasttick.ask + TrailingStop*Point(); BigDogModif.tp = PositionGetDouble(POSITION_TP); BigDogModif.deviation=3; MqlTradeResult BigDogModifResult; ZeroMemory(BigDogModifResult); OrderSend(BigDogModif,BigDogModifResult); } } } } } } //+------------------------------------------------------------------+
おわりに
ときどき、そして定期的に起こるマーケット現象があり、調査によっていくらかの利点を与えてくれます。また、おそらく経験豊かなトレーダーは『ビッグドッグ』としてよく知られている戦略と重なる点があるのをおわかりでしょう。『ビッグドッグ』については本稿では意図的に述べていませんが、それで読者のみなさんは戦略がどのように準備されているかお考えになることと思います。
みなさんはインターネットでこの戦略のバリエーションを目にする機会があると思います。本稿では、この戦略の基となる現象のみを扱ったにすぎません。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/59
![トレードレポートとSMS通知の作成と発行](https://c.mql5.com/2/0/trade_reports_SMS_MQL5.png)
![遺伝的アルゴリズム - とても簡単です!](https://c.mql5.com/2/0/genetic_algorithms_MQL5.png)
![MQL5におけるトレーディング用コントロールパネルの作成](https://c.mql5.com/2/0/panel__2.png)
![「サル」でもわかるMQL:オブジェクトクラスの設計 構築方法](https://c.mql5.com/2/0/cube__1.png)
![MQL5 - MetaTrader 5クライアントターミナルにビルトインされたトレードストラテジーの言語](https://c.mql5.com/i/registerlandings/logo-2.png)
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索