2014年6月30日月曜日

ポジション数、ロット数、損益などを計算する関数


エントリーやエグジット部分のプログラムは、ストラテジー(EA)の手法次第で、それぞれのストラテジーにより異なりますが、ポジションの数、ロット数、損益等の情報を参照する部分のプログラムは、多くのストラテジーでほぼ同じ形に集約されます。これからご紹介する、複数のストラテジーで共通化して使うことができるポジション関連のプログラム等は、関数として作成しておくと、後日新しいストラテジー作成時にそのまま使ったり、必要に応じて少し変えるだけで使うことができる、便利な関数です。

この関数は以下のポジション情報を計算します。
買い/売りポジション数
買い/売りポジションのロット数
買い/売りポジションの損益
買い/売り指値未約定注文数
買い/売りストップ未約定注文数



コード説明

void OnTick(){
int longPos, shortPos, longPendOrders, shortPendOrders, longLimitPendOrders, longStopPendOrders, shortLimitPendOrders, shortStopPendOrders;
double longLots, shortLots, longProfit, shortProfit;

関数呼び出し前に、関数で使うパラメータを宣言します。ポジション数などは整数なのでintで、ロット数は千通貨の場合0.01ロットで小数になるのでdoubleで宣言します。


positionsInfo(longPos, shortPos, longPendOrders, shortPendOrders, longLots, shortLots, longProfit, shortProfit, longLimitPendOrders, longStopPendOrders, shortLimitPendOrders, shortStopPendOrders);
}

関数に適切な順番にパラメータを入れて関数呼び出します。「適切な順番」は、以下の「void positionsInfo()」以下でパラメータを書いた順序です。
これでOnTick内で好きな時に、関数で計算したポジション情報を参照することができます。


void positionsInfo(
int &longPos,
int &shortPos,
int &longPendOrders,
int &shortPendOrders,
double &longLots,
double &shortLots,
double &longProfit,
double &shortProfit,
int &longLimitPendOrders,
int &longStopPendOrders,
int &shortLimitPendOrders,
int &shortStopPendOrders
 ){

関数のパラメータの前に「&」を付けることで参照渡しになります。これにより一度に複数の値を戻すことができます。


   for( int i=0; i<OrdersTotal(); i++)
   {

全注文の中で、


     if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;

ポジションによる識別の場合、


     if(OrderSymbol() != Symbol() && OrderMagicNumber() != 11111) continue;

また銘柄とマジック番号が同じ場合、


     if (OrderType() == OP_BUY){
         longPos ++;
         longLots += OrderLots();
         longProfit += OrderProfit();    
     }else

買いポジション、買いポジションのロット数、買いポジションの損益を計算。

     if (OrderType() == OP_SELL){
         shortPos ++;
         shortLots += OrderLots();
         shortProfit += OrderProfit();   
     }else

売りポジション、売りポジションのロット数、売りポジションの損益を計算。


     if (OrderType() == OP_BUYLIMIT){
         longLimitPendOrders ++;    
     }else

買い指値未約定注文数を計算。


     if (OrderType() == OP_BUYSTOP){
         longStopPendOrders ++;    
     }else

買いストップ未約定注文数を計算。


     if (OrderType() == OP_SELLLIMIT){
         shortLimitPendOrders ++;    
     }else

売り指値未約定注文を計算。


     if (OrderType() == OP_SELLSTOP){  
         shortStopPendOrders ++;   
 
売りストップ未約定注文を計算。

コード全体

void OnTick()
{
int longPos, shortPos, longPendOrders, shortPendOrders, longLimitPendOrders, longStopPendOrders, shortLimitPendOrders, shortStopPendOrders;
double longLots, shortLots, longProfit, shortProfit;

positionsInfo(longPos, shortPos, longPendOrders, shortPendOrders, longLots, shortLots, longProfit, shortProfit, longLimitPendOrders, longStopPendOrders, shortLimitPendOrders, shortStopPendOrders);
}

void positionsInfo(
int &longPos,
int &shortPos,
int &longPendOrders,
int &shortPendOrders,
double &longLots,
double &shortLots,
double &longProfit,
double &shortProfit,
int &longLimitPendOrders,
int &longStopPendOrders,
int &shortLimitPendOrders,
int &shortStopPendOrders
 ){
   for( int i=0; i<OrdersTotal(); i++)
   {
     if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false) break;
     if(OrderSymbol() != Symbol() && OrderMagicNumber() != 11111) continue;
     if (OrderType() == OP_BUY){
         longPos ++;
         longLots += OrderLots();
         longProfit += OrderProfit();    
     }else
     if (OrderType() == OP_SELL){
         shortPos ++;
         shortLots += OrderLots();
         shortProfit += OrderProfit();   
     }else
     if (OrderType() == OP_BUYLIMIT){
         longLimitPendOrders ++;    
     }else
     if (OrderType() == OP_BUYSTOP){
         longStopPendOrders ++;    
     }else
     if (OrderType() == OP_SELLLIMIT){
         shortLimitPendOrders ++;    
     }else
     if (OrderType() == OP_SELLSTOP){  
         shortStopPendOrders ++;    
     }
  }
}

0 件のコメント:

コメントを投稿