/*******************************************************************************
 * Name         : システムトレード 
 * System       : 
 * type         : 
 * Function     : 
 * References   : 
 * Remarks      : 
 * Version      : 
 * History      :
 * Ver.-----Date--------Name------------Comment---------------------------------
 * 1.00     2007/xx/xx  xxxxxx          新規作成
 ******************************************************************************/
#property copyright "QQE-Sys"
#property link      ""


/*******************************************************************************
 * パラメータ
 ******************************************************************************/
// 売買数量用パラメータ
extern double p_lots              = 1.0;

// 利食い、損きり用パラメータ
extern double p_trailingStop      = 0;
extern double p_takeProfit        = 0;
extern double p_stopLoss          = 0;
extern double p_maStop            = 1.5;
extern double p_slipPage          = 3;

// 名称
extern string p_nameEA       = "QQE-Sys";  

// QQEパラメータ
extern int SF = 5; // original 5
extern int RSI_Period = 14; // original 14
extern double DARFACTOR = 4.236; //original 4.236


/*******************************************************************************
 * 組み込み関数定義
 ******************************************************************************/
/*******************************************************************************
 * 組み込み関数定義
 ******************************************************************************/
/*******************************************************************************
 * 
 * 初期化
 *
 ******************************************************************************/
int init() 
{
    return(0);
}


/*******************************************************************************
 * 
 * 再初期化
 *
 ******************************************************************************/
int deinit() 
{
    return(0);
}


/*******************************************************************************
 * 
 * メイン
 *
 ******************************************************************************/
int start() 
{
    int cnt, ticket;    
    double realTP = 0;
    double realSL = 0;
    bool isBuying;
    bool isSelling;
    bool isClosing;

    // 十分なデータがあるかどうかを確認
    if(Bars < 200) {
        Print("Not enough bars for this strategy - ", p_nameEA);
        return(-1);
    }

    
    // 売買判定
    isBuying = false;
    isSelling = false;
    isClosing = false;
    judgeBuySell(isBuying, isSelling, isClosing);

    
    // 仕切り処理
    int totalOrders = OrdersTotal();
    int numPos = 0;
    for(cnt = 0; cnt < totalOrders; cnt++){        
        OrderSelect(cnt, SELECT_BY_POS); 
        if(OrderSymbol() == Symbol() &&
           OrderType() <= OP_SELL &&
           OrderComment() == p_nameEA){   
            numPos++;
            
            // 買い建玉仕切り判定
            if(OrderType() == OP_BUY){

                // トレイリングストップ
                if(Bid-OrderOpenPrice() > p_trailingStop*Point){
                    if(p_trailingStop > 0){             
                        if(OrderStopLoss() == 0 ||
                           OrderStopLoss() < (Bid - p_trailingStop*Point)){
                            OrderModify(OrderTicket(),
                                        OrderOpenPrice(), 
                                        Bid-p_trailingStop*Point,
                                        OrderTakeProfit(),
                                        0,
                                        Blue);
                        }
                    }
                }
                    
                if(isSelling || isClosing){
                    OrderClose(OrderTicket(),
                               OrderLots(),
                               Bid,
                               p_slipPage,
                               Violet);   
                }
            }

            // 売り建玉仕切り判定
            else{
                // トレイリングストップ
                if(OrderOpenPrice() - Ask > p_trailingStop*Point){
                    if(p_trailingStop > 0){
                        if(OrderStopLoss() == 0 ||
                           OrderStopLoss() > Ask + p_trailingStop*Point){
                            OrderModify(OrderTicket(),
                                        OrderOpenPrice(),
                                        Ask + p_trailingStop*Point,
                                        OrderTakeProfit(),
                                        0,
                                        Red);
                        }
                    }
                }

                if(isBuying || isClosing){
                    OrderClose(OrderTicket(),
                               OrderLots(),
                               Ask,
                               p_slipPage,
                               Violet);
                }
            }
        }
    }

    // 建玉処理
    if(numPos < 1){   
        if(AccountFreeMargin() < 1000*LotsOptimized()){
            return(0);
        }

        // 買い建玉処理
        if(isBuying && !isSelling){  
            if(p_stopLoss > 0){
                realSL = Ask - p_stopLoss * Point;
            }

            if(p_takeProfit > 0){
                realTP = Ask + p_takeProfit * Point;
            }
            ticket = OrderSend(Symbol(),
                               OP_BUY,
                               LotsOptimized(),
                               Ask,
                               p_slipPage,
                               realSL,
                               realTP, 
                               p_nameEA,
                               16384,
                               0,
                               Red);  
            if(ticket < 0){
                Print("OrderSend (",p_nameEA,") failed with error #",
                      GetLastError());
            }
        }
        
        // 売り建玉処理
        if(isSelling && !isBuying){  
            if(p_stopLoss > 0){
                realSL = Bid + p_stopLoss * Point;
            }
            if(p_takeProfit > 0){
                realTP = Bid - p_takeProfit * Point;
            }
            ticket = OrderSend(Symbol(),
                               OP_SELL,
                               LotsOptimized(),
                               Bid,
                               p_slipPage,
                               realSL,
                               realTP, 
                               p_nameEA,
                               16384,
                               0,
                               Red); 
            if(ticket < 0){
                Print("OrderSend (",p_nameEA,") failed with error #",
                      GetLastError());
            }
        }
    }
    return(0);
}


/*******************************************************************************
 * 自作関数定義
 ******************************************************************************/
/*******************************************************************************
 * 
 * 売買判定
 *
 ******************************************************************************/
void judgeBuySell(bool &isBuying, bool &isSelling, bool &isClosing)
{
    double qqe_f;
    double qqe_s;
    double qqe_f_p;
    double qqe_s_p;
    qqe_f = iCustom(Symbol(),0,"QQEA",SF,RSI_Period,DARFACTOR,0,0);
    qqe_s = iCustom(Symbol(),0,"QQEA",SF,RSI_Period,DARFACTOR,1,0);
    qqe_f_p = iCustom(Symbol(),0,"QQEA",SF,RSI_Period,DARFACTOR,0,1);
    qqe_s_p = iCustom(Symbol(),0,"QQEA",SF,RSI_Period,DARFACTOR,1,1);

    if(qqe_f > qqe_s && qqe_f_p <= qqe_s_p){
        isBuying = true;
    }
    else if(qqe_f < qqe_s && qqe_f_p >= qqe_s_p){
        isSelling = true;
    }
}


/*******************************************************************************
 * 
 * 数量の最適化
 *
 ******************************************************************************/
double LotsOptimized()
{
    return(p_lots);
}

