普乐智能

查看: 4050|回复: 1

用MQL4 写一个亏损马丁加仓的 EA

[复制链接]

338

主题

424

帖子

1670

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1670
发表于 2023-6-25 17:12:16 | 显示全部楼层 |阅读模式
由于亏损马丁加仓策略存在一定的风险,建议在使用前充分测试并注意风险控制。

以下是一个简单的亏损马丁加仓 EA。


// 输入参数设置
input double Lots=0.01;      // 初始交易手数
input double Multiplier=2;  // 加仓手数倍增率
input double MaxLots=10;    // 最大交易手数
input double StopLoss=50;   // 止损距离点数
input double TakeProfit=150;// 止盈距离点数
input double MaxTrades=10;  // 最大交易次数
input double LossPips=30;   // 亏损距离点数

// 全局变量设置
int TotalTrades=0;          // 当前交易次数
double LastLots=Lots;       // 上一次交易手数
double LastPrice=0;         // 上一次交易价格
double TotalProfit=0;       // 总利润
double TotalLoss=0;         // 总亏损

// EA 初始化
void OnInit()
{
    // 设置止损和止盈
    StopLoss = StopLoss * Point;
    TakeProfit = TakeProfit * Point;
}

// EA 运行
void OnTick()
{
    // 获取当前价格和波动点数
    double current_price = Ask;
    double fluctuation = StopLoss * 2;

    // 计算下一次加仓手数
    double next_lots = LastLots * Multiplier;

    // 当当前交易次数小于最大交易次数时,继续交易
    if(TotalTrades < MaxTrades)
    {
        // 如果当前没有头寸,则开仓
        if (OrdersTotal() == 0)
        {
            // 开多头寸
            LastLots = Lots;
            TotalTrades = 1;
            TotalProfit = 0;
            TotalLoss = 0;

            OrderSend(Symbol(), OP_BUY, Lots, current_price, 3, StopLoss, TakeProfit, "Martingale EA", 0, 0, Green);
            LastPrice = current_price;
        }
        // 如果当前有头寸,则检查是否需要加仓或平仓
        else
        {
            // 检查最后一笔交易是否处于亏损状态,并计算亏损点数
            if(OrderType() == OP_BUY && (current_price - LastPrice) < 0)
            {
                double loss = (current_price - LastPrice) / Point;
                // 如果当前亏损点数超过预设的亏损距离,则加仓
                if(loss < -LossPips)
                {
                    // 开多头寸
                    next_lots = MathMin(next_lots, MaxLots - (Lots + LastLots));
                    TotalTrades++;
                    TotalLoss += loss * LastLots;
                    TotalProfit = OrderProfit() - TotalLoss;

                    OrderSend(Symbol(), OP_BUY, next_lots, current_price, 3, StopLoss, TakeProfit, "Martingale EA", 0, 0, Green);
                    LastLots = next_lots;
                    LastPrice = current_price;
                }
            }
            // 检查最后一笔交易是否处于盈利状态,并计算盈利点数
            else if(OrderType() == OP_BUY && (current_price - OrderOpenPrice()) > 0)
            {
                double profit = (current_price - OrderOpenPrice()) / Point;
                // 如果当前盈利点数超过预设的止盈距离,则平仓
                if(profit > TakeProfit/2)
                {
                    TotalProfit += profit * OrderLots();
                    TotalLoss = 0;

                    OrderClose(OrderTicket(), OrderLots(), current_price, 3, Green);
                    TotalTrades = 0;
                    LastLots = Lots;
                    LastPrice = 0;
                }
            }
            // 如果当前头寸既不处于盈利也不处于亏损状态,则不操作
        }
    }
    // 如果当前交易次数已达到最大次数,则平仓
    else
    {
        OrderClose(OrderTicket(), OrderLots(), current_price, 3, Green);
        TotalTrades = 0;
        LastLots = Lots;
        LastPrice = 0;
    }
}


可以看到,这个 EA 采用了以下几个关键步骤:

设置输入参数,包括初始手数、加仓倍增率、最大交易手数等;
初始化函数 OnInit() 中设置止损和止盈;
在主函数 OnTick() 中检查当前交易次数和头寸情况;
当当前没有头寸时,开仓;
当当前有头寸时,并且头寸处于亏损状态,检查亏损点数是否超过预设的亏损距离,如果超过则加仓;
当当前有头寸时,并且头寸处于盈利状态,检查盈利点数是否超过预设的止盈距离,如果超过则平仓;
当当前交易次数已达到最大次数时,平仓。
需要注意的是,由于亏损马丁加仓策略存在一定的风险,建议在使用前充分测试并注意风险控制。同时,本示例仅为展示亏损马丁加仓 EA 的基本结构和代码实现方式,并不具备实际应用的可行性。真正的交易策略需要根据实际情况进行设计和开发。


回复

使用道具 举报

338

主题

424

帖子

1670

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1670
 楼主| 发表于 2023-6-25 17:16:45 | 显示全部楼层
// 定义全局变量
double initialLotSize = 0.01;  // 初始交易手数
double lotMultiplier = 2;      // 加仓倍数
int maxOrders = 5;             // 最大加仓次数
double stopLoss = 100;         // 止损点数

// 定义交易信号枚举
enum TradeSignal {
    NO_SIGNAL,
    BUY,
    SELL
};

// 初始化函数
int init()
{
    // 设置交易手数
    Lots = initialLotSize;

    // 返回0表示成功初始化
    return (0);
}

// EA主函数
int start()
{
    // 获取当前账户余额
    double accountBalance = AccountBalance();

    // 检查是否有开仓信号
    TradeSignal signal = checkTradeSignal();

    // 如果有开仓信号
    if (signal != NO_SIGNAL)
    {
        // 计算当前持仓数量
        int openOrders = OrdersTotal();

        // 如果持仓数量小于最大加仓次数
        if (openOrders < maxOrders)
        {
            // 获取当前价格
            double currentPrice = MarketInfo(Symbol(), MODE_BID);

            // 设置加仓口数和价格
            double nextLotSize = Lots * MathPow(lotMultiplier, openOrders);
            double nextEntryPrice = signal == BUY ? currentPrice + stopLoss * Point : currentPrice - stopLoss * Point;

            // 执行加仓交易
            bool result = signal == BUY ? OrderSend(Symbol(), OP_BUY, nextLotSize, nextEntryPrice, 0, 0, 0, "Martingale", 0, 0, Green)
                                       : OrderSend(Symbol(), OP_SELL, nextLotSize, nextEntryPrice, 0, 0, 0, "Martingale", 0, 0, Red);
            if (result)
            {
                Print("加仓交易执行成功");
            }
            else
            {
                Print("加仓交易执行失败 - 错误代码:" + GetLastError());
            }

        }
    }

    // 返回0表示成功执行主函数
    return (0);
}

// 检查交易信号函数
TradeSignal checkTradeSignal()
{
    // 在这里实现您的交易信号策略
    // 可以根据自己的策略逻辑返回 NO_SIGNAL,BUY 或者 SELL

    return NO_SIGNAL;  // 返回 NO_SIGNAL 表示没有交易信号
}

// 其他自定义函数和指标
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|11wo.com

Copyright © 2001-2013 Comsenz Inc.Template by Comsenz Inc.All Rights Reserved.

Powered by Discuz!X3.4( 备案号:桂ICP备18000909号-1 )QQ

快速回复 返回顶部 返回列表