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

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

 

2012年04月17日(火)

コピートレードのプログラミング(14) [MQL4]



コピートレードのプログラミングも佳境に入ってきました。今回は、コピー元のポジションを一度に決済するケースだけでなく、段階的に決済するケースにも対応させたEAを作ってみます。

まず、前回と同様に変数を定義しておきます。

remote_lots : コピー元のポジション
local_lots : コピー先のポジション
trade_lots = remote_lots - local_lots

オープンしているポジションの一部を決済する例を見てみましょう。

 remote_lots=0.1, local_lots=0.2, trade_lots=0.1-0.2=-0.1

の場合、コピー先の買いポジションの方が0.1ロット多いので、0.1ロットを決済する必要があります。また

 remote_lots=-0.1, local_lots=-0.2, trade_lots=-0.1-(-0.2)=0.1

の場合も、コピー先の売りポジションのうち、0.1ロットを決済する必要があります。

これを見ると、部分決済させるための条件は以下の二つの条件を同時に満たすときだとわかります。

1.remote_lotsとlocal_lotsの符号が同じ
2.local_lotsとtrade_lotsの符号が逆

二つの値の符号が同じか逆かというのは、前にも出てきたように、二つの値の積がプラスかマイナスかで判別できます。条件式は次のように書けます。

if(remote_lots*local_lots > 0 && local_lots*trade_lots < 0)

次に、部分決済するロット数について見てみます。

例えば、0.2ロットの買いポジションが二つある場合(合計0.4ロット)を考えてみましょう。

ここで、コピー元のポジションが0.3ロットになったとすると、一方のポジションのうち、0.1ロットだけを決済すればよいことになります。

またコピー元のポジションが0.1ロットになった場合は、一方のポジションすべてと、もう一方のポジションの0.1ロット分を部分決済する必要があります。

これらのケースを考慮すると、選択したポジションのロット数がtrade_lots以下であれば、すべて決済し、trade_lotsの方が小さければ、tarde_lotsの分だけ、部分決済すればよいことになります。

このような部分決済のコードは次のように書けます。

double close_lots = MathMin(OrderLots(), MathAbs(trade_lots));
OrderClose(OrderTicket(), close_lots, OrderClosePrice(), slippage);

close_lotsという変数に決済するロット数を算出しますが、条件文の代わりに、MathMin()という二つのパラメータの小さいほうを返す関数を使っています。

以上説明した部分決済のコードを追加した全体のプログラムは次のようになります。

extern int MAGIC = 9999;   // マジックナンバー
extern int Slippage = 2; // スリッページ

int start()
{
int handle = FileOpen("Position¥¥"+Symbol()+".txt", FILE_CSV|FILE_READ);
if(handle == -1) return(0);
double remote_lots = FileReadNumber(handle);
FileClose(handle);

double local_lots = OpenLots();

if(IsTradeAllowed() == false) return(1);
double slippage = Slippage;
if(Digits == 3 || Digits == 5) slippage *= 10;

// 決済オーダー
if(local_lots != 0 && (remote_lots == 0 || remote_lots*local_lots < 0))
{
for(int i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i, SELECT_BY_POS) == false ) break;
if(OrderSymbol() != Symbol() || OrderMagicNumber() != MAGIC) continue;
if(OrderType() == OP_BUY || OrderType() == OP_SELL)
{
OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slippage);
}
}
return(0);
}

// 部分決済オーダー
double trade_lots = remote_lots - local_lots;
if(remote_lots*local_lots > 0 && local_lots*trade_lots < 0)
{
for(i=OrdersTotal()-1; i>=0; i--)
{
if(OrderSelect(i, SELECT_BY_POS) == false ) break;
if(OrderSymbol() != Symbol() || OrderMagicNumber() != MAGIC) continue;
if(OrderType() == OP_BUY || OrderType() == OP_SELL)
{
double close_lots = MathMin(OrderLots(), MathAbs(trade_lots));
OrderClose(OrderTicket(), close_lots, OrderClosePrice(), slippage);
return(0);
}
}
}

//売買オーダー
if(trade_lots > 0)
{
int ticket=OrderSend(Symbol(),OP_BUY,trade_lots,Ask,slippage,0,0,"",MAGIC);
}
if(trade_lots < 0)
{
ticket=OrderSend(Symbol(),OP_SELL,-trade_lots,Bid,slippage,0,0,"",MAGIC);
}
return(0);
}

// オープンロット数
double OpenLots()
{
double lots = 0.0;

for(int i=0; i<OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS) == false) break;
if(OrderSymbol() != Symbol() || OrderMagicNumber() != MAGIC) continue;

if(OrderType() == OP_BUY) lots += OrderLots();
if(OrderType() == OP_SELL) lots -= OrderLots();
}
return(lots);
}

これで、コピー元のポジションの変化にだいたい対応することができるようになりました。

でもまだ続きがあります。


>>“基礎から学ぶシステムトレード”全記事バックナンバーはこちらから




Posted at 12時00分


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

Sponsor AD

2012/4

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          

プロフィール

豊嶋久道

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

PHOTO

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

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

カテゴリーリスト

最近の記事

検索


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

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

RSS1.0

[Login]


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