プログラム入門その5

ここでは、「プログラム入門その5」 に関する記事を紹介しています。
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
プログラム入門その5

前回、売買シグナルを表示するインディケーターを作成しました。

期間の異なる移動平均線ので売買シグナルを表示するプログラム

#property indicator_chart_window
#property indicator_buffers 4

//---- バッファー
double Fa_Buf[];
double Sl_Buf[];
double Buy_Buf[];
double Sell_Buf[];

//---- 期間の変数
extern int Fa_Period=10;
extern int Sl_Period=20;

//初期化
int init()
{
//---- バッファのインディケーターへの割り当て
SetIndexBuffer(0,Fa_Buf);
SetIndexBuffer(1,Sl_Buf);
SetIndexBuffer(2,Buy_Buf);
SetIndexBuffer(3,Sell_Buf);

//---- インディケーターの種類の設定
SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 1, Red);
SetIndexStyle(1, DRAW_LINE, STYLE_SOLID, 1, Blue);
SetIndexStyle(2, DRAW_ARROW, STYLE_SOLID, 1, Blue);
SetIndexArrow(2,233);
SetIndexEmptyValue(2,0);
SetIndexStyle(3, DRAW_ARROW, STYLE_SOLID, 1, Red);
SetIndexArrow(3,234);
SetIndexEmptyValue(3,0);
return(0);
}

//処理
int start()
{
int i, limit = Bars-IndicatorCounted();

for(i=limit-1; i>=0; i--)
{
Fa_Buf[i] = iMA(NULL,0,Fa_Period,0,MODE_SMA,PRICE_CLOSE,i);
Sl_Buf[i] = iMA(NULL,0,Sl_Period,0,MODE_SMA,PRICE_CLOSE,i);

if(Fa_Buf[i+1] <= Sl_Buf[i+1] && Fa_Buf[i] > Sl_Buf[i]) Buy_Buf[i] = Low[i];
if(Fa_Buf[i+1] >= Sl_Buf[i+1] && Fa_Buf[i] < Sl_Buf[i]) Buy_Buf[i] = High[i];
}

return(0);
}

今回、このプログラムのシグナルを使って、自動売買を行うプログラムを作成します。
ルールは
・保有ポジションは1つ
・移動平均線のクロスによるドテン売買を行う
・ストップ、リミットの設定は行はない

ドテン売買とは、
ドル円を例に説明します。
ポジションを持っていない状態で、1$=100円だった時に、買いシグナルが出たとします。
ポジションを持っていないので、1$=100円で買いポジションを持ちます。
1$=101円になった時に、売りシグナルが出たとします。
この時、1$=100円の買いポジションを1$=101円で決済
1$=101円の売りポジションを持ちます。
次に、1$=99円で買いシグナルが出たとすると、1$=101円の売りポジション
1$=99円で決済し新たに1$=99円の買いポジションを持ちます。
このように、シグナルに合わせて、決済と注文を交互に行うことを言います。

さっそく、プログラムに取り掛かりたいのですが、その前に
売買シグナルを出すインディケーターを任意の名前で保存しておいてください。
名前はなんでもいいのですが、漢字やひらがな避けた方がよさそうです。
試しに「MA_cross.mq4」とでもしておきます。

ではプログラムに取り掛かります。
今回はiCustom( string symbol, int timeframe, ..., int mode, int shift)を使います。
これは、すでに作成済みのインディケーターの指定したバッファーの値を取得します。
前回までに作成した「MA_cross.mq4」の売買シグナルを持つバッファーは
Buy_BufSell_Bufです。
バッファーに割り当てた番号(SetIndexBufferで指定した番号)はそれぞれ23です。
使い方はiCustom()を参考にしてください。

double Buy_Buf = iCustom(NULL,0,"MA_Cross",2,0);
double Sell_Buf = iCustom(NULL,0,"MA_Cross",3,0);

これで、Buy_BufSell_Bufにシグナルが代入されました。
今回のルールはポジションが1つですので、シグナルが買い(LONG)なのか売り(SHORT)なのかでドテンしていくため
BuySellという変数にLONG・SHORTを代入して判断したいと思います。
そこで

string BuySell;
if(Buy_Buf>0)BuySell="LONG";
if(Sell_Buf>0)BuySell="SHORT";

という条件分岐を行います。
あとはLONGとSHORTに基づいて売買を行います。

次からいよいよ、自動売買のメインの部分です。
ます、ポジションを持っているかどうかの判断を行います。


ポジションの判断

int cnt, CurrentPosition;
int Ticket;

CurrentPosition=-1;
for(cnt=0;cnt < OrdersTotal();cnt++){
OrderSelect(cnt,SELECT_BY_POS);
if(OrderSymbol() == Symbol()) CurrentPosition=cnt;
}


あとは、売買サインにしたがってポジションを持っているときと持っていないときの条件を書いて終わりです。


ポジションを持っていないとき

if(CurrentPosition == -1)
{
if(BuySell=="LONG")
{
Ticket = OrderSend(Symbol(), OP_BUY, 1, Ask, 3, 0, 0, "Buy", 0, 0, Blue);
}
if(BuySell=="SHORT")
{
Ticket = OrderSend(Symbol(), OP_SELL, 1, Bid, 3, 0, 0, "Sell", 0, 0, Red);
}
}



ポジションを持っているとき

else
{
OrderSelect(Ticket,SELECT_BY_POS);

if(OrderType()==OP_SELL && BuySell=="LONG")
{
OrderClose(OrderTicket(),1,Ask,3,Green);
Ticket = OrderSend(Symbol(), OP_BUY, 1, Ask, 3, 0, 0, "Buy", 0, 0, Blue);
}
if(OrderType()==OP_BUY && BuySell=="SHORT")
{
OrderClose(OrderTicket(),1,Bid,3,Green);
Ticket = OrderSend(Symbol(), OP_SELL, 1, Bid, 3, 0, 0, "Sell", 0, 0, Red);
}
}


注文を行う場合、OrderSend()を使用します。
ポジションがない場合は、売買シグナルによって注文を出すだけです。
ポジションを持っている場合、そのポジションのタイプ(売り or 買い)を判断します。
使用する関数は
OrderType()
です。

シグナルにあわせて、決済を行い(OrderClose)、新たに注文を入れます。(OrderSend)

最後に、全てのプログラムを表示します。

期間の異なる移動平均線ので自動売買を行うプログラム

int start()
{
double Buy_Buf = iCustom(NULL,0,"MA_Cross",2,0);
double Sell_Buf = iCustom(NULL,0,"MA_Cross",3,0);

string BuySell;
if(Buy_Buf>0)BuySell="LONG";
if(Sell_Buf>0)BuySell="SHORT";

//----注文
int cnt, CurrentPosition;
int Ticket;

CurrentPosition=-1;
for(cnt=0;cnt < OrdersTotal();cnt++){
OrderSelect(cnt,SELECT_BY_POS);
if(OrderSymbol() == Symbol()) CurrentPosition=cnt;
}

if(CurrentPosition == -1)
{
if(BuySell=="LONG")
{
Ticket = OrderSend(Symbol(), OP_BUY, 1, Ask, 3, 0, 0, "Buy", 0, 0, Blue);
}
if(BuySell=="SHORT")
{
Ticket = OrderSend(Symbol(), OP_SELL, 1, Bid, 3, 0, 0, "Sell", 0, 0, Red);
}
}
else
{
OrderSelect(Ticket,SELECT_BY_POS);

if(OrderType()==OP_SELL && BuySell=="LONG")
{
OrderClose(OrderTicket(),1,Ask,3,Green);
Ticket = OrderSend(Symbol(), OP_BUY, 1, Ask, 3, 0, 0, "Buy", 0, 0, Blue);
}
if(OrderType()==OP_BUY && BuySell=="SHORT")
{
OrderClose(OrderTicket(),1,Bid,3,Green);
Ticket = OrderSend(Symbol(), OP_SELL, 1, Bid, 3, 0, 0, "Sell", 0, 0, Red);
}
}

return(0);
}


次回は、このプログラムを使ってバックテストを行いたいと思いますので、
任意の名前で保存してください。
試しに「【EA】MA_cross.mq4」とでもしておきます。
コメント
この記事へのコメント
コメントを投稿する
URL:
Comment:
Pass:
秘密: 管理者にだけ表示を許可する
 
トラックバック
この記事のトラックバックURL
http://fxsk.blog105.fc2.com/tb.php/84-9055707f
この記事にトラックバックする(FC2ブログユーザー)
この記事へのトラックバック
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。