急!!谁熟悉MT5策略编写的帮忙看看,一个本来应该是反转的却只平仓而没有反向开新仓?!

Discussion in 'MetaTrader' started by wj2000, Sep 17, 2011.

  1. 急!谁熟悉MT5策略编写的帮忙看看,一个本来应该是反转的却只平仓而没开新仓?!
    过去自己写的一个反转策略的EA,过去一直没发现问题出在哪里,这几天偶尔可视化运行策略了一下,发现问题出在本来应该是一个反转策略的,实际运行时却在出现反转信号后只平掉原有头寸的仓位而没有反向开仓!检查了好几天也没有发现问题出在哪里?MT5的EA编写逻辑挺怪了,谁能帮我看看问题出在哪里,指点一下,谢谢。

    代码里的其他没用的东西不用去管它,只需要指点是什么原因导致只平仓而没有反向开仓的问题所在就可以了,谢谢


    下面是MT5的EA代码:
    ///+------------------------------------------------------------------+
    //| ATC2010-wj-1-b1.mq5 |
    //| Copyright 2010, MetaQuotes Software Corp. |
    //| http://www.mql5.com |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2010, MetaQuotes Software Corp."
    #property link "http://www.mql5.com"
    #property version "1.00"
    //--- input parameters
    input int StopLoss=50; // Stop Loss
    input int TakeProfit=100; // Take Profit

    input int EA_Magic=12345; // EA Magic Number

    input double Lot=0.1; // Lots to Trade

    //input int MA_Period=8; // Moving Average Period


    //--- Other parameters
    double High[],Low[],Open[],Close[];
    double High0,Low0,Open0,Close0;
    double High1,Low1,Open1,Close1;

    MqlTradeRequest MyTrade;

    MqlTradeResult MyResult;


    int maHandle; // handle for our Moving Average indicator
    double maVal[]; // Dynamic array to hold the values of Moving Average for each bars

    double p_close; // Variable to store the close value of a bar
    int STP, TKP; // To be used for Stop Loss & Take Profit values

    int PositionSig = 0;
    int TradeSig = 0; //1 - signal to buy;-1 - signal to sell;0 - no signal

    input double MaxOrderLots = 5;
    input ulong dev = 8;


    extern double MaximumRisk = 0.02;
    extern double MinLots = 0.1;
    extern double MaxLots = 15;

    extern int CurPairsNum = 1;
    extern string CurPairsSym[]; //Currency_Pairs_Symbol[];
    //+------------------------------------------------------------------+
    //| Expert initialization function |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    //---
    for(int x=1;x<=CurPairsNum;x++)
    {

    }
    //--- Do we have enough bars to work with
    if(Bars(_Symbol,_Period)<60) // if total bars is less than 60 bars
    {
    Alert("We have less than 60 bars, EA will now exit!!");
    return(0);
    }

    //--- Get the handle for Moving Average indicator
    // maHandle=iMA(_Symbol,_Period,MA_Period,0,MODE_EMA,PRICE_CLOSE);

    //--- Let us handle currency pairs with 5 or 3 digit prices instead of 4
    STP = StopLoss;
    TKP = TakeProfit;
    if(_Digits==5 || _Digits==3)
    {
    STP = STP*10;
    TKP = TKP*10;
    }

    //---
    return(0);
    }
    //+------------------------------------------------------------------+
    //| Expert deinitialization function |
    //+------------------------------------------------------------------+
    void OnDeinit(const int reason)
    {
    //---
    //--- Release our indicator handles
    IndicatorRelease(maHandle);

    }
    //+------------------------------------------------------------------+
    //| Expert tick function |
    //+------------------------------------------------------------------+
    void OnTick()
    {
    //---
    // We will use the static Old_Time variable to serve the bar time.
    // At each OnTick execution we will check the current bar time with the saved one.
    // If the bar time isn't equal to the saved time, it indicates that we have a new tick.

    static datetime Old_Time;
    datetime New_Time[1];
    bool IsNewBar=false;

    // copying the last bar time to the element New_Time[0]
    int copied=CopyTime(_Symbol,_Period,0,1,New_Time);
    if(copied>0) // ok, the data has been copied successfully
    {
    if(Old_Time!=New_Time[0]) // if old time isn't equal to new bar time
    {
    IsNewBar=true; // if it isn't a first call, the new bar has appeared
    if(MQL5InfoInteger(MQL5_DEBUGGING)) Print("We have new bar here ",New_Time[0]," old time was ",Old_Time);
    Old_Time=New_Time[0]; // saving bar time
    }
    }
    else
    {
    Alert("Error in copying historical times data, error =",GetLastError());
    ResetLastError();
    return;
    }

    //--- EA should only check for new trade if we have a new bar
    if(IsNewBar==false)
    {
    return;
    }

    //--- Do we have enough bars to work with
    int Mybars=Bars(_Symbol,_Period);
    if(Mybars<60) // if total bars is less than 60 bars
    {
    Alert("We have less than 60 bars, EA will now exit!!");
    return;
    }

    double Ask = SymbolInfoDouble(_Symbol,SYMBOL_ASK); // Ask price
    double Bid = SymbolInfoDouble(_Symbol,SYMBOL_BID); // Bid price

    High0 = iHigh(_Symbol,_Period,1);
    Low0 = iLow(_Symbol,_Period,1);
    Open0 = iOpen(_Symbol,_Period,1);
    Close0 = iClose(_Symbol,_Period,1);

    High1 = iHigh(_Symbol,_Period,0);
    Low1 = iLow(_Symbol,_Period,0);
    Open1 = iOpen(_Symbol,_Period,0);
    Close1 = iClose(_Symbol,_Period,0);

    double BW = (High1 - Low1) * 0.3;

    if(Bid > (Open0 + BW)) TradeSig = 1;
    if(Bid < (Open0 - BW)) TradeSig = -1;
    // if(Bid == Open0 ) TradeSig =0;
    // if(Bid == Open0 ) TradeSig =0;

    /*
    if(IsNewBar==true)
    {
    PositionSig = 0;

    PositionCloseMaxOrder(_Symbol,MaxOrderLots, dev);
    PositionSig = 0;
    }
    */
    /*
    if(TradeSig == 0 && PositionSig != 0)
    {
    PositionCloseMaxOrder(_Symbol,MaxOrderLots, dev);
    PositionSig = 0;
    }
    */

    if(TradeSig == 1 && PositionSig == -1)
    {
    PositionCloseMaxOrder(_Symbol,MaxOrderLots, dev);
    PositionSig = 0;
    }

    if(PositionSig == 0 && TradeSig == 1)
    {
    PositionOpenMaxOrder(ORDER_TYPE_BUY,Lot, MaxOrderLots, 0,0,0,0,"test");
    PositionSig = 1;
    }

    if(TradeSig == -1 && PositionSig == 1)
    {
    PositionCloseMaxOrder(_Symbol,MaxOrderLots, dev);
    PositionSig = 0;
    }

    if(PositionSig == 0 && TradeSig == -1)
    {
    PositionOpenMaxOrder(ORDER_TYPE_SELL,Lot, MaxOrderLots, 0,0,0,0,"test");
    PositionSig = -1;
    }
    /*
    if(PositionSig == 0 && TradeSig == 1)
    {
    PositionOpenMaxOrder(ORDER_TYPE_BUY,Lot, MaxOrderLots, 0,0,0,0,"test");
    PositionSig = 1;
    }

    if(PositionSig == 0 && TradeSig == -1)
    {
    PositionOpenMaxOrder(ORDER_TYPE_SELL,Lot, MaxOrderLots, 0,0,0,0,"test");
    PositionSig = -1;
    }
    */

    return;
    }
    //+------------------------------------------------------------------+

    double LotsOptimized(double StopLoss) //确定下单量,开仓调用
    {
    double lots=0.1;
    lots=MathFloor((MaximumRisk * ACCOUNT_EQUITY )/(StopLoss / _Point));
    if(lots < MinLots) lots = MinLots;
    if(lots > MaxLots) lots = MaxLots;
    return(lots);
    }

    //+------------------------------------------------------------------+
    //| Get Low for specified bar index |
    //+------------------------------------------------------------------+
    double iLow(string symbol,ENUM_TIMEFRAMES timeframe,int index)
    {
    double low=0;
    ArraySetAsSeries(Low,true);
    int copied=CopyLow(symbol,timeframe,0,Bars(symbol,timeframe),Low);
    if(copied>0 && index<copied) low=Low[index];
    return(low);
    }
    //+------------------------------------------------------------------+
    //| Get the High for specified bar index |
    //+------------------------------------------------------------------+
    double iHigh(string symbol,ENUM_TIMEFRAMES timeframe,int index)
    {
    double high=0;
    ArraySetAsSeries(High,true);
    int copied=CopyHigh(symbol,timeframe,0,Bars(symbol,timeframe),High);
    if(copied>0 && index<copied) high=High[index];
    return(high);
    }

    //+------------------------------------------------------------------+
    //| Get Open for specified bar index |
    //+------------------------------------------------------------------+
    double iOpen(string symbol,ENUM_TIMEFRAMES timeframe,int index)
    {
    double open=0;
    ArraySetAsSeries(Open,true);
    int copied=CopyOpen(symbol,timeframe,0,Bars(symbol,timeframe),Open);
    if(copied>0 && index<copied) open=Open[index];
    return(open);
    }

    //+------------------------------------------------------------------+
    //| Get Close for specified bar index |
    //+------------------------------------------------------------------+
    double iClose(string symbol,ENUM_TIMEFRAMES timeframe,int index)
    {
    double close=0;
    ArraySetAsSeries(Close,true);
    int copied=CopyClose(symbol,timeframe,0,Bars(symbol,timeframe),Close);
    if(copied>0 && index<copied) close=Close[index];
    return(close);
    }
    //+------------------------------------------------------------------+

    //+------------------------------------------------------------------+
    //| Open Long position |
    //+------------------------------------------------------------------+
    //+------------------------------------------------------------------+
    //|市价单入场函数(有最大单限制)
    //+------------------------------------------------------------------+
    bool PositionOpenMaxOrder(ulong TradeOrder,double positionlot, double MaxOrderLots, double ST,double TP,ulong Slip,int Magic,string Comm)

    {
    while(positionlot > MaxOrderLots)
    {
    int res = PositionOpen(TradeOrder, positionlot, ST, TP, Slip, Magic, Comm);

    if(res) positionlot = positionlot - MaxOrderLots;
    }
    int res = PositionOpen(TradeOrder, positionlot, ST, TP, Slip, Magic, Comm);

    return(res);
    }

    //+------------------------------------------------------------------+
    //|市价单入场函数(无最大交易单限制)
    //+------------------------------------------------------------------+
    bool PositionOpen(ulong TradeOrder,double Vol,double ST,double TP,ulong Slip,int Magic,string Comm)

    {

    MyTrade.action=TRADE_ACTION_DEAL;

    MyTrade.magic=Magic;

    MyTrade.symbol=Symbol();

    MyTrade.volume=Vol;

    //SymbolInfoTick(Symbol(),MyTick);

    switch(TradeOrder)

    {

    case ORDER_TYPE_BUY:

    MyTrade.price=SymbolInfoDouble(Symbol(),SYMBOL_ASK);

    MyTrade.type=ORDER_TYPE_BUY;

    break;

    case ORDER_TYPE_SELL:

    MyTrade.price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

    MyTrade.type=ORDER_TYPE_SELL;

    break;

    }

    MyTrade.deviation=Slip;

    MyTrade.type_filling=ORDER_FILLING_AON;

    MyTrade.comment=Comm;

    MyTrade.sl=ST;

    MyTrade.tp=TP;

    return(OrderSend(MyTrade,MyResult));

    }

    //+-----------------------------------------------------------+

    //+-----------------------------------------------------------+
    //|当前货币市价平仓单(有最大交易量限制)
    //+-------------------------------------------------------+
    bool PositionCloseMaxOrder(const string symbol,double MaxOrderLots,ulong deviation)
    {
    double positionlot = PositionGetDouble(POSITION_VOLUME);

    while(positionlot > MaxOrderLots)
    {
    int res = PositionCloseNum(_Symbol,MaxOrderLots,deviation);
    if(res) positionlot = positionlot - MaxOrderLots;
    }
    int res = PositionCloseNum(_Symbol,positionlot,deviation);

    return(res);
    }

    bool PositionCloseNum(const string symbol,double lots,ulong deviation)

    {

    double price;

    //— checking

    if(PositionSelect(symbol))

    {

    if(PositionGetInteger(POSITION_TYPE)==ORDER_TYPE_BUY)

    {

    //— prepare query for close BUY position

    MyTrade.type =ORDER_TYPE_SELL;

    MyTrade.price=SymbolInfoDouble(symbol,SYMBOL_BID);

    }

    else

    {

    //— prepare query for close SELL position

    MyTrade.type =ORDER_TYPE_BUY;

    MyTrade.price=SymbolInfoDouble(symbol,SYMBOL_ASK);

    }

    }

    //— setting request

    MyTrade.action =TRADE_ACTION_DEAL;

    MyTrade.symbol =symbol;

    //MyTrade.volume =PositionGetDouble(POSITION_VOLUME);
    MyTrade.volume =lots;

    MyTrade.sl =0.0;

    MyTrade.tp =0.0;

    MyTrade.deviation =(deviation==ULONG_MAX) ? deviation : deviation;

    MyTrade.type_filling=ORDER_FILLING_AON;

    //—

    return(OrderSend(MyTrade,MyResult));

    }

    //+-----------------------------------------------------+
     
  2. 查出来什么原因了,主要是在使用PositionGetDouble() 前需要先检查PositionSelect(symbol)