//+------------------------------------------------------------------+ //| TrapRepeatIFD.mq4 | //+------------------------------------------------------------------+ #include #include #define COMMENT "TrapRepeatIFD" #define WAIT_TIME 5 // トラップ設定 extern double lots = 0.01; // ロット数 1000通貨 extern double maxOpenPrice = 90.00; // 新規指値(最高値) 上値90円から extern int trapCount = 30; // トラップ数 extern int profitPips = 100; // 利益幅 1円 extern int trapIntervalPips = 50; // トラップ幅 50銭 extern double stoploss = 0; // ストップロス なし extern bool isBuyTrap = true; // 買 extern int magic = 1000; // MAGIC NUMBER extern bool isTrendFollowOnly = false; extern int stopOrderSpreadPips = 5; extern int doOrderRangePips = 300; int slippage = 3; // 注文時の矢印の色 color ArrowColor[6] = {Green, Red, Green, Red, Green, Red}; double pointPerPips; int slippagePips; int ticketArray[]; int magicArray[]; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { // 5digit業者への対応 int mult = 1; if(Digits == 3 || Digits == 5) { mult = 10; } pointPerPips = Point * mult; slippagePips = slippage * mult; return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start(){ // トレード停止中は何もしない if(IsTradeAllowed() == false) { Print("Trade not Allowed"); return(0); } if(initOrderTicketInfo() == false) return(0); doTrapRepeatIfDone(isBuyTrap, lots, maxOpenPrice , trapCount , profitPips, trapIntervalPips , stoploss, magic); return(0); } //+------------------------------------------------------------------+ // トラリピを実行する int doTrapRepeatIfDone(bool isBuyTrap, double lots, double maxOpenPrice, int trapCount, int profitPips, int trapIntervalPips, double stoploss, int magic) { for(int i=0; i < trapCount; i++){ double openPrice = maxOpenPrice - trapIntervalPips * i * pointPerPips; // 現値より大きく乖離した発注は出さない double currentPrice; if(isBuyTrap){ currentPrice = Ask; } else { currentPrice = Bid; } if( doOrderRangePips != 0 && (openPrice < currentPrice - doOrderRangePips * pointPerPips || openPrice > currentPrice + doOrderRangePips * pointPerPips) ){ continue; } double closePrice; if(isBuyTrap == true){ closePrice = openPrice + profitPips * pointPerPips; } else { closePrice = openPrice - profitPips * pointPerPips; } int magicNumber = magic+i; // 注文状態をチェックし、注文がなければリピートする int ticket = getOrderTicket(magicNumber); if ( ticket <= 0) { ticket = doRepeatIfDone(lots, openPrice, slippagePips, stoploss, closePrice, isBuyTrap, magicNumber); } } } // 指定された条件でリピートIfDone注文を実行する int doRepeatIfDone(double lots, double openPrice, int slippage, double stoploss, double closePrice, bool isBuyTrap, int magic) { // 注文形式を決定する int tradeType = -1; if( isTrendFollowOnly == true ) { // トレンドフォローモードの場合、トレンドフォローを確認するため、 // ASK値が一旦、閾値以上の下値に達した後に建値まで戻ってきた場合にのみ // リピートするようにする if(isBuyTrap && openPrice >= Ask + stopOrderSpreadPips * pointPerPips ) { tradeType = OP_BUYSTOP; } else if(!isBuyTrap && openPrice < Bid - stopOrderSpreadPips * pointPerPips ) { tradeType = OP_SELLSTOP; } } else { if(isBuyTrap && openPrice <= Ask) { // 買い注文で、建値 <= 現在価格(Ask) の場合は買い指値 tradeType = OP_BUYLIMIT; } else if(isBuyTrap && openPrice > Ask) { // 買い注文で、建値 > 現在価格(Ask) の場合は買い逆指値 tradeType = OP_BUYSTOP; } else if(!isBuyTrap && openPrice >= Bid) { // 売り注文で、建値 >= 現在価格(Bid) の場合は売り指値 tradeType = OP_SELLLIMIT; } else if(!isBuyTrap && openPrice < Bid) { // 売り注文で、建値 < 現在価格(Bid) の場合は売り逆指値 tradeType = OP_SELLSTOP; } } // 注文形式が注文不要の場合はそのまま終了する if(tradeType == -1) { return(-1); } int errCode = 0; int ticket = doOrderSend(tradeType,lots,openPrice,slippage,stoploss,closePrice,COMMENT,magic,errCode); return(ticket); } // 発注する int doOrderSend(int type, double lots, double openPrice, int slippage, double stoploss, double closePrice, string comment, int magic, int &errCode) { openPrice = NormalizeDouble(openPrice, Digits); stoploss = NormalizeDouble(stoploss, Digits); closePrice = NormalizeDouble(closePrice, Digits); int starttime = GetTickCount(); while(true) { if(GetTickCount() - starttime > WAIT_TIME * 1000) { Print("OrderSend timeout. Check the experts log."); return(false); } if(IsTradeAllowed() == true) { RefreshRates(); int ticket = OrderSend(Symbol(), type, lots, openPrice, slippage, stoploss, closePrice, comment, magic, 0, ArrowColor[type]); if( ticket > 0) { return(ticket); } errCode = GetLastError(); Print("[OrderSendError] : ", errCode, " ", ErrorDescription(errCode)); Print("price=",openPrice,": stop=",stoploss,": close=",closePrice); if(errCode == ERR_INVALID_PRICE || errCode == ERR_INVALID_STOPS) { break; } } Sleep(100); } return(-1); } bool initOrderTicketInfo(){ // 対象通貨ペアの件数を取得 int orderCount=0; for(int j=0; j < OrdersTotal(); j++) { if(OrderSelect(j,SELECT_BY_POS,MODE_TRADES) == false) return(false); if(OrderSymbol() == Symbol()) { orderCount++; } } // 配列を初期化 ArrayResize(ticketArray,orderCount); ArrayResize(magicArray,orderCount); orderCount=0; // 配列にセット for(j=0; j < OrdersTotal(); j++) { if(OrderSelect(j,SELECT_BY_POS,MODE_TRADES) == false) return(false); if(OrderSymbol() == Symbol()) { ticketArray[orderCount] = OrderTicket(); magicArray[orderCount] = OrderMagicNumber(); orderCount++; } } return(true); } // 指定されたMAGIC注文があるかどうかをチェックする // int getOrderTicket(int magic){ int orderCount = 0; int ticket = -1; for(int i=0; i < ArraySize(magicArray); i++) { if(magic == magicArray[i]) { ticket = ticketArray[i]; orderCount++; } } if(orderCount > 1){ Print("order duplicate:MagicNumber=",magic,", orderCount=",orderCount); } return(ticket); }