admin 发表于 2024-3-19 13:12:29

mql5项目

原代码#property copyright "QQ:2913811"
#property link      "gzpu.com"

extern int BuyOrSell = 0;//0=多 1=空 第一单多空
extern int MaxTrades = 7;//单向最大持仓单数
extern int sliptime = 30;//等待时间秒
extern int slippage = 3;//滑点
extern int MagicN = 10533;//定单识别码
extern string Commentt = "QQ:2913811";//定单注释
extern string Temp0 = "======每单下单量======";
extern double Lots1 = 0.01;
extern double Lots2 = 0.02;
extern double Lots3 = 0.04;
extern double Lots4 = 0.07;
extern double Lots5 = 0.09;
extern double Lots6 = 0.12;
extern double Lots7 = 0.15;
extern string Temp1 = "======每单间隔======";
extern double Pips1 = 15;
extern double Pips2 = 15;
extern double Pips3 = 15;
extern double Pips4 = 15;
extern double Pips5 = 15;
extern double Pips6 = 15;
extern double Pips7 = 15;
extern string Temp2 = "======每单止盈======";
extern double TP1 = 15;
extern double TP2 = 15;
extern double TP3 = 15;
extern double TP4 = 15;
extern double TP5 = 15;
extern double TP6 = 15;
extern double TP7 = 15;

double Gda_292;
double Gda_296;
double Gda_300;
double Gd_304;
double Gd_312;
double Gd_320;
double Gd_328;
double Gd_336;
double Gd_344;
double G_order_open_price_352;
double G_order_open_price_360;
double Gd_368;
double Gd_376;
bool G_bool_384;
int G_pos_388;
int G_index_392;
int G_index_396;
int G_ticket_400;
int Gi_404 = 1;
double G_price_408;
bool TarckInt0;
bool TarckInt1;
bool Open0 = false;
bool Open1 = false;
bool TarckKaiGuan0 = false;
bool TarckKaiGuan1 = false;
int Time0 = 0;
int Time1 = 0;

int init() {
   Gda_292 = Lots1;
   Gda_292 = Lots2;
   Gda_292 = Lots3;
   Gda_292 = Lots4;
   Gda_292 = Lots5;
   Gda_292 = Lots6;
   Gda_292 = Lots7;
   Gda_296 = Pips1;
   Gda_296 = Pips2;
   Gda_296 = Pips3;
   Gda_296 = Pips4;
   Gda_296 = Pips5;
   Gda_296 = Pips6;
   Gda_296 = Pips7;
   Gda_300 = TP1;
   Gda_300 = TP2;
   Gda_300 = TP3;
   Gda_300 = TP4;
   Gda_300 = TP5;
   Gda_300 = TP6;
   Gda_300 = TP7;
   if (Digits == 5 || Digits == 3) Gi_404 = 10;
   if (StringFind(Symbol(), "XAU", 0) >= 0 || StringFind(Symbol(), "GOLD", 0) >= 0) {
      if (Digits == 2) Gi_404 = 10;
      if (Digits == 3) Gi_404 = 100;
   }
   return (0);
}

int start() {
   CountOrders();
   TarckInt0 = false;
   TarckInt1 = false;
   if ((G_index_392 + G_index_396 == 0 && BuyOrSell == 0) || (G_index_392 > 0 && G_index_392 < MaxTrades && G_order_open_price_352 - Ask >= (Gda_296) * Gi_404 * Point)) {
      TarckInt0 = true;
      if (G_index_392 == 0) Open0 = true;
      if (TarckKaiGuan0 && TimeCurrent() - Time0 >= sliptime) Open0 = true;
      if (G_index_392 > 0 && !TarckKaiGuan0) {
         Open0 = false;
         TarckKaiGuan0 = true;
         Time0 = TimeCurrent();
         }
      if(Open0) {
         G_ticket_400 = OrderSend(Symbol(), OP_BUY, Gda_292, Ask, slippage * Gi_404, 0, 0, Commentt, MagicN, 0, Blue);
         if (G_ticket_400 > 0) {
            Open0 = false;
            BuyOrSell = TRUE;
            O_Modify(OP_BUY);
          }
      }
   }
   if ((G_index_392 + G_index_396 == 0 && BuyOrSell == 1) || (G_index_396 > 0 && G_index_396 < MaxTrades && Bid - G_order_open_price_360 >= (Gda_296) * Gi_404 * Point)) {
      TarckInt1 = true;
      if (G_index_396 == 0) Open1 = true;
      if (TarckKaiGuan1 && TimeCurrent() - Time1 >= sliptime) Open1 = true;
      if (G_index_396 > 0 && !TarckKaiGuan1) {
         Open1 = false;
         TarckKaiGuan1 = true;
         Time1 = TimeCurrent();
         }
      if(Open1) {
      G_ticket_400 = OrderSend(Symbol(), OP_SELL, Gda_292, Bid, slippage * Gi_404, 0, 0, Commentt, MagicN, 0, Red);
      if (G_ticket_400 > 0) {
         BuyOrSell = FALSE;
         O_Modify(OP_SELL);
         }
      }
   }
   if(!TarckInt0) TarckKaiGuan0 = false;
   if(!TarckInt1) TarckKaiGuan1 = false;
   return (0);
}

void O_Modify(int A_cmd_0) {
   CountOrders();
   if (A_cmd_0 == OP_BUY) G_price_408 = G_order_open_price_352 + (Gda_300) * Gi_404 * Point;
   if (A_cmd_0 == OP_SELL) G_price_408 = G_order_open_price_360 - (Gda_300) * Gi_404 * Point;
   for (int pos_4 = OrdersTotal() - 1; pos_4 >= 0; pos_4--) {
      if (OrderSelect(pos_4, SELECT_BY_POS, MODE_TRADES)) {
         if (OrderSymbol() == Symbol() && OrderType() == A_cmd_0)
            if (OrderTakeProfit() != G_price_408) G_bool_384 = OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), G_price_408, 0, Yellow);
      }
   }
}

void CountOrders() {
   G_index_392 = 0;
   G_index_396 = 0;
   Gd_320 = 0;
   Gd_328 = 0;
   Gd_304 = 0;
   Gd_312 = 0;
   Gd_336 = 0;
   Gd_344 = 0;
   G_order_open_price_352 = 0;
   G_order_open_price_360 = 0;
   Gd_368 = 0;
   Gd_376 = 0;
   for (G_pos_388 = 0; G_pos_388 < OrdersTotal(); G_pos_388++) {
      if (OrderSelect(G_pos_388, SELECT_BY_POS, MODE_TRADES)) {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicN) {
            if (OrderType() == OP_BUY) {
               G_index_392++;
               Gd_304 += OrderLots();
               Gd_320 += OrderProfit();
               Gd_336 += OrderLots() * OrderOpenPrice();
               G_order_open_price_352 = OrderOpenPrice();
            }
            if (OrderType() == OP_SELL) {
               G_index_396++;
               Gd_312 += OrderLots();
               Gd_328 += OrderProfit();
               Gd_344 += OrderLots() * OrderOpenPrice();
               G_order_open_price_360 = OrderOpenPrice();
            }
         }
      }
   }
   if (Gd_304 != 0.0) Gd_368 = NormalizeDouble(Gd_336 / Gd_304, Digits);
   if (Gd_312 != 0.0) Gd_376 = NormalizeDouble(Gd_344 / Gd_312, Digits);
}


admin 发表于 2024-3-19 13:14:00

这段 MQL5 代码是一个基于 MetaTrader 5 (MT5) 的 EA(智能交易系统)脚本,主要功能如下:

参数设置:

定义了多个外部变量用于控制交易方向(BuyOrSell)、最大持仓单数(MaxTrades)、等待时间(sliptime)、滑点(slippage)、订单识别码(MagicN)以及与每笔交易相关的下单量(Lots1-Lots7)、间隔(Pips1-Pips7)和止盈目标(TP1-TP7)。
全局变量:

定义了一系列的数组和双精度浮点数变量,用于存储每笔交易的相关数据,如下单量、价格间隔和止盈值等。
还定义了一些布尔型变量和整型变量,用于跟踪订单状态、开平仓标志、时间和订单索引等信息。
初始化函数init():

初始化了各个交易单位的数量、价格间隔和止盈目标,并根据交易品种的报价小数位数调整了一些计算参数。
启动函数start():

主要处理下单逻辑,当满足一定的条件时(如当前无持仓或某个方向上还有剩余交易次数且满足价格条件),尝试进行买卖操作。
使用 OrderSend 函数发送订单,并在成功下单后调用 O_Modify 函数来修改订单的止损和止盈。
O_Modify 函数:

根据交易方向计算并设定相应的止盈价格,然后遍历所有交易订单,对符合条件的订单执行 OrderModify 操作以更新其止损和止盈。
CountOrders 函数:

计算当前交易品种下,EA 所管理的所有订单的统计信息,包括多空持仓数量、总盈利、平均入场价格等。
整体来看,这个 EA 脚本采用的是分批加仓的方式进行交易,每次加仓的数量和间隔是预先设置好的,并根据市场行情动态地开启新的加仓批次。同时,它还具有实时监控订单并调整止损和止盈的能力。

admin 发表于 2024-3-19 13:14:26

优化建议:
虽然这段代码实现了基本的批量加仓交易策略,但为了提升代码可读性和维护性,以及潜在的性能优化,以下是一些建议:

变量命名规范:

变量名应当清晰明了,反映其用途,例如G_order_open_price_352这样的变量名不易理解,可以改为last_buy_order_open_price或类似更具描述性的名称。
结构化数据:

可以考虑使用结构体或类来封装一组相关联的数据(如下单量、价格间隔、止盈距离),避免使用多个数组分别存储这些属性。
减少重复代码:

开仓逻辑分为两个几乎完全相同的分支(买和卖),可以通过抽象出一个通用函数来处理这两种情况,减少重复代码。
代码组织:

将一些逻辑独立为单独的函数,如“判断是否满足开仓条件”、“更新订单统计信息”等,提高代码的模块化程度。
错误处理:

在OrderSend和OrderModify调用之后,应检查返回值并处理可能出现的错误,如网络连接失败、超出账户风险限制等情况。
注释和文档:

增加必要的注释,解释关键算法思路、重要变量的作用以及函数的主要功能,以便于其他开发者理解和维护代码。
条件判断优化:

对于复杂嵌套的条件判断,可以尝试简化或重构,使得代码更简洁高效。

admin 发表于 2024-3-19 13:14:52

完整优化后的代码
#include <stdio.h>
#include <MetaTrader5/MetaTrader5.h>

// 定义交易批次结构体
struct TradeBatch {
    double lot_size;
    double price_interval;
    double take_profit;
};

extern int BuyOrSell = 0; // 0=多, 1=空
extern int MaxTrades = 7;
extern int sliptime = 30;
extern int slippage = 3;
extern int MagicN = 10533;
extern string Commentt = "QQ:2913811";

// 交易批次列表
TradeBatch trade_batches;

double current_bid_price;
double current_ask_price;
int long_index = 0;
int short_index = 0;

bool OpenLong = false;
bool OpenShort = false;
bool TrackOpenLong = false;
bool TrackOpenShort = false;
datetime TimeLong = 0;
datetime TimeShort = 0;

void OnInit() {
    SetIndexStyle(0, DRAW_LINE, EMPTY);
    SetIndexBuffer(0, Gda_296);
   
    trade_batches = {0.01, 15, 15};
    trade_batches = {0.02, 15, 15};
    trade_batches = {0.04, 15, 15};
    trade_batches = {0.07, 15, 15};
    trade_batches = {0.09, 15, 15};
    trade_batches = {0.12, 15, 15};
    trade_batches = {0.15, 15, 15};

    for (int i = 0; i < 7; ++i) {
      if (Digits == 5 || Digits == 3) {
            trade_batches.price_interval *= 10;
            trade_batches.take_profit *= 10;
      }
      else if (StringFind(Symbol(), "XAU", 0) >= 0 || StringFind(Symbol(), "GOLD", 0) >= 0 && (Digits == 2 || Digits == 3)) {
            trade_batches.price_interval *= (Digits == 2 ? 10 : 100);
            trade_batches.take_profit *= (Digits == 2 ? 10 : 100);
      }
    }
}

void OnTick() {
    CountOrders();
    TrackOpenLong = false;
    TrackOpenShort = false;
    current_bid_price = Bid;
    current_ask_price = Ask;

    if ((long_index + short_index == 0 && BuyOrSell == 0) || (long_index > 0 && long_index < MaxTrades && CheckOpenPosition(OP_BUY))) {
      TrackOpenLong = true;
      TryOpenPosition(OP_BUY, long_index, OpenLong, TimeLong);
    }

    if ((long_index + short_index == 0 && BuyOrSell == 1) || (short_index > 0 && short_index < MaxTrades && CheckOpenPosition(OP_SELL))) {
      TrackOpenShort = true;
      TryOpenPosition(OP_SELL, short_index, OpenShort, TimeShort);
    }

    if (!TrackOpenLong) ResetTrack(OpenLong, TimeLong);
    if (!TrackOpenShort) ResetTrack(OpenShort, TimeShort);

    O_Modify(OP_BUY);
    O_Modify(OP_SELL);
}

bool CheckOpenPosition(int positionSide) {
    double reference_price = positionSide == OP_BUY ? current_ask_price : current_bid_price;
    double last_open_price = positionSide == OP_BUY ? G_order_open_price_352 : G_order_open_price_360;
    return (positionSide == OP_BUY ? last_open_price - reference_price : reference_price - last_open_price) >= trade_batches.price_interval * Point;
}

void TryOpenPosition(int positionSide, int &index, bool &isOpen, datetime &trackTime) {
    if (index == 0 || isOpen && TimeCurrent() - trackTime >= sliptime * TimeSpanSeconds(M1)) {
      isOpen = true;
      double order_price = positionSide == OP_BUY ? Ask : Bid;
      int ticket = OrderSend(Symbol(), positionSide, trade_batches.lot_size, order_price, slippage * Point, 0, 0, Commentt, MagicN, 0, positionSide == OP_BUY ? Blue : Red);
      if (ticket > 0) {
            isOpen = false;
            BuyOrSell = positionSide == OP_BUY ? TRUE : FALSE;
            index++;
      }
    }
}

void ResetTrack(bool &isOpen, datetime &trackTime) {
    isOpen = false;
    trackTime = 0;
}

// ... 保留原有的O_Modify函数和其他辅助函数 ...

admin 发表于 2024-3-19 13:23:58

这段代码已经更加接近完整可运行的状态,但仍然依赖于您原始代码中的某些未在该段代码中展示的变量,如 G_order_open_price_352 和 G_order_open_price_360 等。此外,还需要您在 EA 中实现 CountOrders 和 O_Modify 函数,以及其他必要的辅助函数。在实际使用前,请务必根据您的具体情况进行测试和调整。
页: [1]
查看完整版本: mql5项目