基礎から学ぶシステムトレード
シストレブログ人気ランキング  

シストレ徹底攻略シストレマスターへの道ワールド・トレーディング・エッジ基礎から学ぶシステムトレードシストレニュースシストレツールシストレナビTOPへ

 

著書のご紹介

2010年11月29日(月)

MQL5:スプレッドを表示するインジケータ [MetaTrader5]

MQL5の標準ライブラリを使ったEAの記事が続いたので、今回はちょっと休憩して、インジケータの話です。

MT4とMT5では、ヒストリカルデータの構造が色々と変わっていますが、その一つに、売買スプレッドのデータがあります。

MT4では、売買スプレッドはリアルタイムでBid、Askから算出できますが、過去のデータとしては記録されません。なので、バックテストを行う場合は、それを行った時点でのスプレッドに固定されます。

以前は、FX業者の多くが固定スプレッドを採用していたので問題なかったのですが、最近では、可変スプレッドを採用する業者も増えてきました。また原則固定スプレッドなのですが、時間帯によってスプレッドを変える業者もあります。

そういう状況に対応させるためか、MT5では、スプレッドを過去のデータとして記録できるような構造に変わりました。

そのスプレッドデータの扱いですが、これは簡単で、始値や終値などと同じように扱うことができます。

以前の記事で簡単なカスタム指標を作成したと思いますが、そこで実行される関数は

int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime& Time[],
const double& Open[],
const double& High[],
const double& Low[],
const double& Close[],
const long& Tick_volume[],
const long& Volume[],
const int& Spread[])

のように宣言されていました。これを見ると、Open, High, Low, Close などに並んで最後に Spread というパラメータがあります。これが売買スプレッドのことです。

なので、これを指標バッファに代入すればスプレッドをインジケータとして表示させることができるのです。
for(int i=limit; i<rates_total; i++) Buf[i] = Spread[i];

プログラムはこんな感じになります。

#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots 1

#property indicator_label1 "Spread"
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 Red
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1

// 指標バッファ
double Buf[];

// 初期化関数
int OnInit()
{
// 指標バッファの割り当て
SetIndexBuffer(0, Buf, INDICATOR_DATA);
return(0);
}

// 開始関数
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime& Time[],
const double& Open[],
const double& High[],
const double& Low[],
const double& Close[],
const long& Tick_volume[],
const long& Volume[],
const int& Spread[])
{
int limit = prev_calculated;
if(prev_calculated > 0) limit--;

for(int i=limit; i<rates_total; i++) Buf[i] = Spread[i];

return(rates_total);
}

その他の変更点は、サブウィンドウに表示させるために

#property indicator_separate_window

と指定したところと、スプレッドを棒グラフのような形状で表示するために
#property indicator_type1 DRAW_HISTOGRAM

と指定したところです。

チャートに挿入すると下図のようにスプレッドの変化がサブウィンドウに表示されます。

画像(450x230)・拡大画像(800x409)

Posted at 11時17分 パーマリンク


2010年11月22日(月)

MQL5:時系列クラスを使ったEA [MetaTrader5]

これまで何回かにわたって標準ライブラリのクラスを使ったEAのプログラムを紹介してきました。

クラスを使うメリットの一つは、複雑な手続きをブラックボックス化して、プログラムをシンプルに書けるということです。

実は、EA中でよく出てくる終値についても、「CiClose」というクラスがあることがわかっていました。ただ、MQL5のドキュメントだけ見ると、クラスを使っても使わなくても同じような手間がかかると思い、クラスの導入を見送っていました。ところが、色々とサンプルプログラムを見ていると、簡単な使い方がわかったので、今回はそれをご紹介します。

終値を始め、始値、高値、安値の4本値も、クラスとして扱うことができます。それぞれ、CiClose、CiOpen、CiHigh、CiLow というクラスですが、これらが宣言されているヘッダファイルは、「Indicators¥TimeSeries.mqh」です。

#include <Indicators¥TimeSeries.mqh>

と書くと、これらのクラスが利用できるようになります。使い方は以前紹介したCiMAとほぼ同じです。

まず、
CiClose Close;

と書いて、Close という名前のCiCloseクラスのオブジェクトを宣言します。

それからOnInit()関数中に
Close.Create(NULL, 0);

と書き、初期化します。ここでの引数は、通貨ペア名、タイムフレームです。NULL、0を代入するとプログラムを挿入した通貨ペアのチャートの終値に対応します。

実際に終値を取得する前に、
Close.Refresh(-1);

と書いてデータを更新します。すると、最新のバーにおける終値がClose.GetData(0)、1本前のバーにおける終値がClose.GetData(1)として取得できます。

プログラムは、これまでの Close[2]、Close[1]をそれぞれ、Close.GetData(2)、Close.GetData(1)と書き換えるだけです。

全体のプログラムを以下に示します。終値を求める部分が簡単に書けるようになったので、RefreshRates()関数はカットして、その部分をOnTick()関数の始めに書くようにしました。これでかなりすっきりしたんじゃないかと思います。

#include <Trade¥Trade.mqh>
#include <Indicators¥trend.mqh>
#include <Indicators¥TimeSeries.mqh>

// パラメータ
input int MAPeriod = 20;
input double Lots = 0.1;
input uint Slippage = 2;

CTrade Trade; //トレードクラス
CiMA MA; //MAクラス
CiClose Close; //Closeクラス

// 初期化関数
int OnInit()
{
// MAの初期化
MA.Create(NULL, 0, MAPeriod, 0, MODE_SMA, PRICE_CLOSE);

// Closeの初期化
Close.Create(NULL, 0);

uint slippage = Slippage;
if(_Digits == 3 || _Digits == 5) slippage *= 10;
Trade.SetDeviationInPoints(slippage);

return(0);
}

// ティック関数
void OnTick()
{
MA.Refresh(-1);
Close.Refresh(-1);

double pos = OpenLots();
double lots = MathAbs(pos) + Lots;

if(pos <= 0 && Close.GetData(2) <= MA.Main(2) && Close.GetData(1) > MA.Main(1))
Trade.Buy(lots);
if(pos >= 0 && Close.GetData(2) >= MA.Main(2) && Close.GetData(1) < MA.Main(1))
Trade.Sell(lots);
}

// オープンポジションのロット数
double OpenLots()
{
double lots = 0.0;
if(PositionSelect(_Symbol))
{
lots = PositionGetDouble(POSITION_VOLUME);
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) lots = -lots;
}
return(lots);
}

Posted at 17時27分 パーマリンク


2010年11月15日(月)

MQL5:トレードクラスを使ったEAその2 [MetaTrader5]

前回、前々回と、標準ライブラリのトレードクラスを使ったEAを紹介しましたが、MQL5のサイトでも、同様の記事が掲載されています。

と言っても、同様なのはタイトルだけで、中身はむこうの方が圧倒的に多いです。その中で、EAをもう少し簡単に書ける方法があったので、今回はその部分だけ紹介します。

今回紹介するのは、CTradeクラスのメンバ関数の中の成行買い、成行売り、指値買い、指値売り、逆指値買い、逆指値売りに対応するメンバ関数です。

成行買い - Buy()
成行売り - Sell()
指値買い - BuyLimit()
指値売り - SellLimit()
逆指値買い - BuyStop()
逆指値売り - SellStop()

ここでは、成行買いのBuy()というメンバ関数の仕様を見てみます。このメンバ関数は次のような引数を取ります。
double volume //売買ロット数
const string symbol=NULL //通貨ペア名
double price=0.0 //売買価格
double sl=0.0 // 損切り価格
double tp=0.0 //利食い価格
const string comment="" //コメント

これらの引数のうち、volume 以外はそれぞれ初期値が代入されているので、初期値を変更する必要がなければ指定する必要はありません。

実際、この関数の中身を見ると、price=0の場合、買値のAskが代入され、symbol=NULLの場合、Symbol()が代入されるようになっています。なので、引数を省略しても、挿入したチャート上の通貨ペアをトレードできるようになっています。

ということで、予め、売買ロット数lotsと、CTradeのオブジェクトTradeを

double lots = 0.1;
CTrade Trade;
のように宣言しておけば、
Trade.Buy(lots);
と書くだけで、成行買いオーダーを送信することができるわけです。

成行売りの場合も同様で、
Trade.Sell(lots);
と書くだけでOKです。

このようにトレードクラスのメンバ関数を使うと、BidとAskを求めるコードを書く必要がなくなるので、プログラムがさらに簡単になります。

結局、前回のEAのプログラムは以下のように書くことができます。

#include <Trade¥Trade.mqh>
#include <Indicators¥Trend.mqh>

// パラメータ
input int MAPeriod = 20;
input double Lots = 0.1;
input uint Slippage = 2;

// レート
double Close[];

// トレードクラス
CTrade Trade;

// MAクラス
CiMA MA;

// 初期化関数
int OnInit()
{
// MAの初期化
MA.Create(NULL, 0, MAPeriod, 0, MODE_SMA, PRICE_CLOSE);

ArraySetAsSeries(Close, true);

uint slippage = Slippage;
if(_Digits == 3 || _Digits == 5) slippage *= 10;
Trade.SetDeviationInPoints(slippage);

return(0);
}

// ティック関数
void OnTick()
{
if(!RefreshRates()) return;
double pos = OpenLots();
double lots = MathAbs(pos) + Lots;

if(pos <= 0 && Close[2] <= MA.Main(2) && Close[1] > MA.Main(1))
Trade.Buy(lots);
if(pos >= 0 && Close[2] >= MA.Main(2) && Close[1] < MA.Main(1))
Trade.Sell(lots);
}

// レートの更新
bool RefreshRates()
{
// MAの更新
MA.Refresh(-1);

int count = 3;
if(CopyClose(_Symbol, _Period, 0, count, Close) < count) return(false);
return(true);
}

// オープンポジションのロット数
double OpenLots()
{
double lots = 0.0;
if(PositionSelect(_Symbol))
{
lots = PositionGetDouble(POSITION_VOLUME);
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) lots = -lots;
}
return(lots);
}

Posted at 13時40分 パーマリンク


過去の記事へ

ページのトップへ ページのトップへ

Sponsor AD

シストレナビモバイル

シストレナビモバイル
ケータイでバーコードを読み取りアクセス(詳細はこちら

プロフィール

豊嶋久道

2003年よりFX取引を始め、システムトレードの道へ。最近ではFXオプション取引も含めたトレーディングシステムの研究を行っている。システムトレードを基礎から正しく理解するための情報を発信する予定。

活動状況・Website

ToyolabFX
Toyolab FX-手ぶらで為替取引
FXトレーディング研究所。
FXメタトレーダー入門
FXメタトレーダー入門
最先端システムトレードソフト使いこなし術。
FXメタトレーダー実践プログラミング
FXメタトレーダー実践プログラミング
システム開発過程を段階的に学ぶ。

2010/11

  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        

PHOTO

ランダムウォークとランダムトレード(4)

ランダムウォークとランダムトレード(4)

カテゴリーリスト

最近の記事

スポンサードリンク

検索


当サイトコメントについて

当コメントは情報提供のみを目的として作成されたものであり、投資に関してはご自身でご判断くださいますようお願い致します。また、当資料は著作物であり著作権法により保護されております。無断で全文または一部を転載することはできません。

RSS1.0

[Login]


powered by a-blog
Copyright (C) 2008 PhiConcept,Inc. All rights reserved.