この前作ったトラリピの売買プログラムを改良してみました。

改良点は、エントリーシグナルにボリンジャーバンドを利用して、

現在価格と乖離した注文にはキャンセル処理を加えただけですが。

しかし、今だにバックテストでプラスになりません(笑)


// 外部パラメータ
extern double Lots = 0.1; // ロット数
extern int MaxLots = 5;  // 最大ポジション数
extern int StopLoss = 30; // 損切り値(Stop):0=不要
extern int TakeProfit = 50; // 利食い値(Limit):0=不要
extern int Slippage = 3; // スリッページ
extern int TradeMode = 2; // 0=買:1=売:2=売買
extern double PriceRange = 0.20; // 指値の値幅
extern double CancelRange = 100; // これ以上価格が乖離したら注文取消
extern int Magic = 10001; // マジックナンバー
extern int BBPeriod = 20; // ボリンジャーバンドの期間
extern int BBSigma = 1;  // 標準偏差の倍率


//////////////// スタート関数 /////////////////
int start() {
 double OrderPrice,BBUpper,BBLower,MinAskPrice,MaxBidPrice;


 // ボリンジャーバンドの計算
 BBUpper = iBands(NULL, 0, BBPeriod, BBSigma, 0, PRICE_CLOSE, MODE_UPPER, 1);
 BBLower = iBands(NULL, 0, BBPeriod, BBSigma, 0, PRICE_CLOSE, MODE_LOWER, 1);


 // 現在価格から乖離した注文は取消
 DeletePendingOrder();


 for(int i=0; i<MaxLots; i++) {
  // 現在のポジションのチェック
  if(CheckPosition(Magic+i) == 1) { continue; }


  // エントリーシグナルのチェック
  int signal = CheckEntrySignal(BBUpper, BBLower);


  // 買い注文
  if(signal > 0 && (TradeMode == 0 || TradeMode == 2)) {
   OrderPrice = Ask-PriceRange*i;
   OrderSend(Symbol(), OP_BUYLIMIT, Lots, OrderPrice, Slippage,
        OrderPrice-Point*StopLoss, OrderPrice+Point*TakeProfit, "Buy", Magic+i, 0, Red);
  }
  // 売り注文
  if(signal < 0 && (TradeMode == 1 || TradeMode == 2)) {
   OrderPrice = Bid+PriceRange*i;
   OrderSend(Symbol(), OP_SELLLIMIT, Lots, OrderPrice, Slippage,
        OrderPrice+Point*StopLoss, OrderPrice-Point*TakeProfit, "Sell", Magic+i, 0, Blue);
  }
 }
 return(0);
}


//////////////// エントリーシグナルのチェック /////////////////
int CheckEntrySignal(double BBUpper,double BBLower) {
 // 買いシグナル
 if(Close[0] < BBLower) { return(1); }
 // 売りシグナル
 if(Close[0] > BBUpper) { return(-1); }
 return(0);
}


//////////////// ポジションのチェック /////////////////
int CheckPosition(int magic) {
 int OpenPosition = 0;
 for (int i = OrdersTotal() - 1; i >= 0; i--){
  if(OrderSelect(i, SELECT_BY_POS,MODE_TRADES) == false) { break; }
  if(OrderSymbol() != Symbol() || OrderMagicNumber() != magic) { continue; }
   OpenPosition++;
  }
  if(OpenPosition != 0) { return(1); }
  return(0);
}


//////////////// 現在価格から乖離した注文は取消 /////////////////
int DeletePendingOrder() {
 for (int i = OrdersTotal() - 1; i >= 0; i--){
  if(OrderSelect(i, SELECT_BY_POS,MODE_TRADES) == false) { break; }
  if(OrderSymbol() != Symbol()) { break; }


  if(OrderType() == OP_BUYLIMIT && OrderOpenPrice()+Point*CancelRange < Ask) {
    OrderDelete(OrderTicket());
  }
  if(OrderType() == OP_SELLLIMIT && OrderOpenPrice()-Point*CancelRange > Bid) {
    OrderDelete(OrderTicket());
  }
 }
}