結論から申しますと買い注文がだせません。isBuytrapG をfalseにすると売り注文は全てうまくいきます。
どうぞご指南頂ければ幸いです。
#define COMMENT "TrapRepeatIFD"
#define WAIT_TIME 5
// トラップ群1用
extern double lotsG = 0.01; // ロット数
extern double maxOpenPriceG = 92.00; // 新規指値(最高値)
extern int trapCountG = 30; // トラップ数
extern int profitPipsG = 50; // 利益幅
extern int trapIntervalPipsG = 20; // トラップ幅
extern double stoplossG = 0; // ストップロス
extern bool isBuyTrapG = true; // 買/売
extern int magicG = 1000; // MAGIC NUMBER
extern bool isTrendFollowOnly = false;
extern int stopOrderSpreadPips = 5;
extern int doOrderRangePips = 30000;
int slippageG = 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 = slippageG * 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(isBuyTrapG, lotsG, maxOpenPriceG
, trapCountG , profitPipsG, trapIntervalPipsG
, stoplossG, magicG);
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++)
if(isBuyTrap){
double openPrice = maxOpenPrice - trapIntervalPips * ((trapCount-1)-i )* pointPerPips;
}else{
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);
}
}
return(0);
}
// 指定された条件でリピート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_BUY;
openPrice=Ask;
} 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, 0, 0, comment, magic, 0, ArrowColor[type]);
if( ticket > 0) {
if(OrderSelect(ticket,SELECT_BY_TICKET)==true){
if(isBuyTrapG== true){ //true kai
closePrice = openPrice + profitPipsG * pointPerPips;
}else { //else =false uri
closePrice = openPrice - profitPipsG * pointPerPips;
}
closePrice = NormalizeDouble(closePrice, Digits);
if(OrderModify(OrderTicket(),OrderOpenPrice(),0,closePrice,0,WhiteSmoke)){}
}
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);
}