/*******************************************************************************
 * Name         : システムトレード 
 * System       : 
 * type         : 
 * Function     : 
 * References   : 
 * Remarks      : 
 * Version      : 
 * History      :
 * Ver.-----Date--------Name------------Comment---------------------------------
 * 1.00     2007/xx/xx  xxxxxx          新規作成
 ******************************************************************************/
#property copyright "doubleUp-Sys"
#property link      ""


/*******************************************************************************
 * パラメータ
 ******************************************************************************/
// 売買数量用パラメータ
extern double p_lots              = 1.0;
extern double p_lotsRate          = 1.5;
extern double p_lotsMax           = 8.0;


// 利食い、損きり用パラメータ
extern double p_takeProfit        = 0; // リミット
extern double p_stopLoss          = 0; // ストップ
extern double p_slipPage          = 3;

// 名称
extern string p_nameEA       = "doubleUp-Sys";  


/*******************************************************************************
 * 組み込み関数定義
 ******************************************************************************/
/*******************************************************************************
 * 
 * 初期化
 *
 ******************************************************************************/
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(isClosing){
                    OrderClose(OrderTicket(),
                               OrderLots(),
                               Bid,
                               p_slipPage,
                               Violet);   
                }
            }

            // 売り建玉仕切り判定
            else{

                if(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 ma = iMA(Symbol(), PERIOD_M30, 15, 0, MODE_EMA, PRICE_CLOSE, 0);

    if(Close[0] > ma){
        isBuying = true;
    }
    else if(Close[0] < ma){
        isSelling = true;
    }
}


/*******************************************************************************
 * 
 * 数量の最適化
 *
 ******************************************************************************/
double LotsOptimized()
{
    double lot;
    int    orders = HistoryTotal();
    int    losses = 0;


    // 連敗数をカウント
    for(int i=orders-1;i>=0;i--){
        if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==false) {
            Print("Error in history!");
            break;
        }
        if(OrderSymbol()!=Symbol() || OrderType() > OP_SELL){
            continue;
        }
        
        if(OrderProfit()>0){
            break;
        }
        if(OrderProfit()<0){
            losses++;
        }
    }

    // 数量決定
    if(losses >= 1){
        lot = MathCeil(p_lots * MathPow(p_lotsRate, losses));
    }
    else{
        lot = p_lots;
    }

    // 最大値制限
    if(lot > p_lotsMax){
        lot = p_lotsMax;
    }

    return(lot);
}

