この前作ったトラリピの売買プログラムを改良してみました。
改良点は、エントリーシグナルにボリンジャーバンドを利用して、
現在価格と乖離した注文にはキャンセル処理を加えただけですが。
しかし、今だにバックテストでプラスになりません(笑)
// 外部パラメータ
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());
}
}
}