保持敬畏之心
交易是一场持久战

MQL4(56):采用挂单进场的基础版EA程序

本节展示的是一款采用挂单(止损单)方式进行交易的基础版EA。
和第55篇里的基础版源码的区别:使用挂单来开仓。
MQL4(55):基础版EA交易程序源码
#property copyright "tudaojiaoyi"

// ===== 外部输入参数 =====
extern double LotSize      = 0.1;
extern double StopLoss     = 50;
extern double TakeProfit   = 100;
extern int    PendingPips  = 10;   // 挂单距离当前价格的点数
extern int    Slippage     = 5;    // 挂单成交时允许的滑点 (通常对挂单意义不大,但OrderSend需要此参数)
extern int    MagicNumber  = 123;
extern int    FastMAPeriod = 10;
extern int    SlowMAPeriod = 20;

// ===== 全局变量 =====
int    BuyTicket;
int    SellTicket;
double UsePoint;
int    UseSlippage;

// ===== 初始化函数 =====
int OnInit()
{
    UsePoint = PipPoint(Symbol());
    UseSlippage = GetSlippage(Symbol(), Slippage);
    return(INIT_SUCCEEDED);  
}

// ===== 主体逻辑函数 =====
void OnTick()
{
    // --- 计算移动平均线 ---
    double FastMA = iMA(NULL, 0, FastMAPeriod, 0, 0, 0, 0);
    double SlowMA = iMA(NULL, 0, SlowMAPeriod, 0, 0, 0, 0);

    // --- 买入挂单条件与执行 ---
    if(FastMA > SlowMA && BuyTicket == 0) // MA金叉且无现有买单/买挂单
    {
        // 处理反向订单/挂单
        if(SellTicket > 0) // 如果存在卖方订单号
        {
            if(OrderSelect(SellTicket, SELECT_BY_TICKET))
            {
                if(OrderType() == OP_SELL && OrderCloseTime() == 0) // 如果是已成交的卖单
                {
                    bool Closed = OrderClose(SellTicket, OrderLots(), Ask, UseSlippage, Red);
                }
                else if(OrderType() == OP_SELLSTOP) // 如果是未成交的卖出止损挂单
                {
                    bool Deleted = OrderDelete(SellTicket, Red); // 删除该挂单
                }
            }
        }

        // 设置买入止损挂单 (Buy Stop)
        double PendingPrice = High[0] + (PendingPips * UsePoint); // 挂单价格设在当前K线最高点上方N点
        double BuyStopLoss  = 0;
        double BuyTakeProfit= 0;

        if(StopLoss > 0)
        {
            BuyStopLoss = PendingPrice - (StopLoss * UsePoint);
        }
        if(TakeProfit > 0)
        {
            BuyTakeProfit = PendingPrice + (TakeProfit * UsePoint);
        }

        BuyTicket = OrderSend(Symbol(), OP_BUYSTOP, LotSize, PendingPrice, UseSlippage,
                              BuyStopLoss, BuyTakeProfit, "Buy Stop Order", MagicNumber, 0, Green);
        SellTicket = 0;
    }

    // --- 卖出挂单条件与执行 ---
    if(FastMA < SlowMA && SellTicket == 0) // MA死叉且无现有卖单/卖挂单
    {
        // 处理反向订单/挂单
        if(BuyTicket > 0) // 如果存在买方订单号
        {
            if(OrderSelect(BuyTicket, SELECT_BY_TICKET))
            {
                if(OrderType() == OP_BUY && OrderCloseTime() == 0) // 如果是已成交的买单
                {
                    bool BuyClosed = OrderClose(BuyTicket, OrderLots(), Bid, UseSlippage, Red);
                }
                else if(OrderType() == OP_BUYSTOP)
                {
                    bool BuyDeleted = OrderDelete(BuyTicket, Red);
                }
            }
        }

        // 设置卖出止损挂单 (Sell Stop)
        double SellPendingPrice = Low[0] - (PendingPips * UsePoint); // 挂单价格设在当前K线最低点下方N点
        double SellStopLoss = 0;
        double SellTakeProfit= 0;

        if(StopLoss > 0)
        {
            SellStopLoss = SellPendingPrice + (StopLoss * UsePoint);
        }
        if(TakeProfit > 0)
        {
            SellTakeProfit = SellPendingPrice - (TakeProfit * UsePoint);
        }

        SellTicket = OrderSend(Symbol(), OP_SELLSTOP, LotSize, SellPendingPrice, UseSlippage,
                                SellStopLoss, SellTakeProfit, "Sell Stop Order", MagicNumber, 0, Red);
        BuyTicket = 0;
    }
}

// ===== 辅助函数:计算点值 =====
// (与上一个EA中的 PipPoint 函数相同)
double PipPoint(string Currency)
{
    int    CalcDigits = MarketInfo(Currency, MODE_DIGITS);
    double CalcPoint  = 0.0;

    if(CalcDigits == 2 || CalcDigits == 3)
    {
        CalcPoint = 0.01;
    }
    else if(CalcDigits == 4 || CalcDigits == 5)
    {
        CalcPoint = 0.0001;
    }
    return(CalcPoint);
}

// ===== 辅助函数:获取滑点 =====
// (与上一个EA中的 GetSlippage 函数相同)
int GetSlippage(string Currency, int SlippagePips)
{
    int CalcDigits   = MarketInfo(Currency, MODE_DIGITS);
    int CalcSlippage = 0;

    if(CalcDigits == 2 || CalcDigits == 4)
    {
        CalcSlippage = SlippagePips;
    }
    else if(CalcDigits == 3 || CalcDigits == 5)
    {
        CalcSlippage = SlippagePips * 10;
    }
    return(CalcSlippage);
}

赞(0)
未经允许不得转载:图道交易 » MQL4(56):采用挂单进场的基础版EA程序
分享到