MT4 EA

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
sydney

MT4 EA

#1

投稿記事 by sydney » 10年前

先日質問させて頂き一瞬で解決したのですが違うトラブルが発生しどうにか頑張ってみましたが対処出来なかったのでお恥ずかしながら再度投稿させて頂きます。
結論から申しますと買い注文がだせません。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);
    }

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: MT4 EA

#2

投稿記事 by みけCAT » 10年前

インデントを整えることをおすすめします。
sydney さんが書きました:結論から申しますと買い注文がだせません。isBuytrapG をfalseにすると売り注文は全てうまくいきます。
doTrapRepeatIfDone関数のループ内の処理が「isBuyTrapが真なら、ローカル変数openPriceに計算式を評価した値を代入してすぐにそれを破棄するだけ」となっているからである気がします。
やりたいのはこういうことでしょうか?

コード:

// トラリピを実行する
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){
            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);
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: MT4 EA

#3

投稿記事 by みけCAT » 10年前

オフトピック
前のトピック
超初心者です。エラーが解決出来なく困ってます。 • C言語交流フォーラム ~ mixC++ ~
によく似ており、投稿日時も近い記事が見つかりました。
C++ - エラーが解決できなくこまっています。(超初心者) - Qiita (WebArchive)
この掲示板を投稿先に含むマルチポストをする場合は、相互リンクが必要です。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る