找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 35|回复: 4

mql5项目

[复制链接]

295

主题

38

回帖

1265

积分

管理员

积分
1265
发表于 2024-3-19 13:12:29 | 显示全部楼层 |阅读模式
原代码
  1. #property copyright "QQ:2913811"
  2. #property link      "gzpu.com"

  3. extern int BuyOrSell = 0;//0=多 1=空 第一单多空
  4. extern int MaxTrades = 7;//单向最大持仓单数
  5. extern int sliptime = 30;//等待时间秒
  6. extern int slippage = 3;//滑点
  7. extern int MagicN = 10533;//定单识别码
  8. extern string Commentt = "QQ:2913811";//定单注释
  9. extern string Temp0 = "======每单下单量======";
  10. extern double Lots1 = 0.01;
  11. extern double Lots2 = 0.02;
  12. extern double Lots3 = 0.04;
  13. extern double Lots4 = 0.07;
  14. extern double Lots5 = 0.09;
  15. extern double Lots6 = 0.12;
  16. extern double Lots7 = 0.15;
  17. extern string Temp1 = "======每单间隔======";
  18. extern double Pips1 = 15;
  19. extern double Pips2 = 15;
  20. extern double Pips3 = 15;
  21. extern double Pips4 = 15;
  22. extern double Pips5 = 15;
  23. extern double Pips6 = 15;
  24. extern double Pips7 = 15;
  25. extern string Temp2 = "======每单止盈======";
  26. extern double TP1 = 15;
  27. extern double TP2 = 15;
  28. extern double TP3 = 15;
  29. extern double TP4 = 15;
  30. extern double TP5 = 15;
  31. extern double TP6 = 15;
  32. extern double TP7 = 15;

  33. double Gda_292[7];
  34. double Gda_296[7];
  35. double Gda_300[7];
  36. double Gd_304;
  37. double Gd_312;
  38. double Gd_320;
  39. double Gd_328;
  40. double Gd_336;
  41. double Gd_344;
  42. double G_order_open_price_352;
  43. double G_order_open_price_360;
  44. double Gd_368;
  45. double Gd_376;
  46. bool G_bool_384;
  47. int G_pos_388;
  48. int G_index_392;
  49. int G_index_396;
  50. int G_ticket_400;
  51. int Gi_404 = 1;
  52. double G_price_408;
  53. bool TarckInt0;
  54. bool TarckInt1;
  55. bool Open0 = false;
  56. bool Open1 = false;
  57. bool TarckKaiGuan0 = false;
  58. bool TarckKaiGuan1 = false;
  59. int Time0 = 0;
  60. int Time1 = 0;

  61. int init() {
  62.    Gda_292[0] = Lots1;
  63.    Gda_292[1] = Lots2;
  64.    Gda_292[2] = Lots3;
  65.    Gda_292[3] = Lots4;
  66.    Gda_292[4] = Lots5;
  67.    Gda_292[5] = Lots6;
  68.    Gda_292[6] = Lots7;
  69.    Gda_296[0] = Pips1;
  70.    Gda_296[1] = Pips2;
  71.    Gda_296[2] = Pips3;
  72.    Gda_296[3] = Pips4;
  73.    Gda_296[4] = Pips5;
  74.    Gda_296[5] = Pips6;
  75.    Gda_296[6] = Pips7;
  76.    Gda_300[0] = TP1;
  77.    Gda_300[1] = TP2;
  78.    Gda_300[2] = TP3;
  79.    Gda_300[3] = TP4;
  80.    Gda_300[4] = TP5;
  81.    Gda_300[5] = TP6;
  82.    Gda_300[6] = TP7;
  83.    if (Digits == 5 || Digits == 3) Gi_404 = 10;
  84.    if (StringFind(Symbol(), "XAU", 0) >= 0 || StringFind(Symbol(), "GOLD", 0) >= 0) {
  85.       if (Digits == 2) Gi_404 = 10;
  86.       if (Digits == 3) Gi_404 = 100;
  87.    }
  88.    return (0);
  89. }

  90. int start() {
  91.    CountOrders();
  92.    TarckInt0 = false;
  93.    TarckInt1 = false;
  94.    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[G_index_392 - 1]) * Gi_404 * Point)) {
  95.       TarckInt0 = true;
  96.       if (G_index_392 == 0) Open0 = true;
  97.       if (TarckKaiGuan0 && TimeCurrent() - Time0 >= sliptime) Open0 = true;
  98.       if (G_index_392 > 0 && !TarckKaiGuan0) {
  99.          Open0 = false;
  100.          TarckKaiGuan0 = true;
  101.          Time0 = TimeCurrent();
  102.          }
  103.       if(Open0) {
  104.          G_ticket_400 = OrderSend(Symbol(), OP_BUY, Gda_292[G_index_392], Ask, slippage * Gi_404, 0, 0, Commentt, MagicN, 0, Blue);
  105.          if (G_ticket_400 > 0) {
  106.             Open0 = false;
  107.             BuyOrSell = TRUE;
  108.             O_Modify(OP_BUY);
  109.           }
  110.       }
  111.    }
  112.    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[G_index_396 - 1]) * Gi_404 * Point)) {
  113.       TarckInt1 = true;
  114.       if (G_index_396 == 0) Open1 = true;
  115.       if (TarckKaiGuan1 && TimeCurrent() - Time1 >= sliptime) Open1 = true;
  116.       if (G_index_396 > 0 && !TarckKaiGuan1) {
  117.          Open1 = false;
  118.          TarckKaiGuan1 = true;
  119.          Time1 = TimeCurrent();
  120.          }
  121.       if(Open1) {
  122.       G_ticket_400 = OrderSend(Symbol(), OP_SELL, Gda_292[G_index_396], Bid, slippage * Gi_404, 0, 0, Commentt, MagicN, 0, Red);
  123.       if (G_ticket_400 > 0) {
  124.          BuyOrSell = FALSE;
  125.          O_Modify(OP_SELL);
  126.          }
  127.       }
  128.    }
  129.    if(!TarckInt0) TarckKaiGuan0 = false;
  130.    if(!TarckInt1) TarckKaiGuan1 = false;
  131.    return (0);
  132. }

  133. void O_Modify(int A_cmd_0) {
  134.    CountOrders();
  135.    if (A_cmd_0 == OP_BUY) G_price_408 = G_order_open_price_352 + (Gda_300[G_index_392 - 1]) * Gi_404 * Point;
  136.    if (A_cmd_0 == OP_SELL) G_price_408 = G_order_open_price_360 - (Gda_300[G_index_396 - 1]) * Gi_404 * Point;
  137.    for (int pos_4 = OrdersTotal() - 1; pos_4 >= 0; pos_4--) {
  138.       if (OrderSelect(pos_4, SELECT_BY_POS, MODE_TRADES)) {
  139.          if (OrderSymbol() == Symbol() && OrderType() == A_cmd_0)
  140.             if (OrderTakeProfit() != G_price_408) G_bool_384 = OrderModify(OrderTicket(), OrderOpenPrice(), OrderStopLoss(), G_price_408, 0, Yellow);
  141.       }
  142.    }
  143. }

  144. void CountOrders() {
  145.    G_index_392 = 0;
  146.    G_index_396 = 0;
  147.    Gd_320 = 0;
  148.    Gd_328 = 0;
  149.    Gd_304 = 0;
  150.    Gd_312 = 0;
  151.    Gd_336 = 0;
  152.    Gd_344 = 0;
  153.    G_order_open_price_352 = 0;
  154.    G_order_open_price_360 = 0;
  155.    Gd_368 = 0;
  156.    Gd_376 = 0;
  157.    for (G_pos_388 = 0; G_pos_388 < OrdersTotal(); G_pos_388++) {
  158.       if (OrderSelect(G_pos_388, SELECT_BY_POS, MODE_TRADES)) {
  159.          if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicN) {
  160.             if (OrderType() == OP_BUY) {
  161.                G_index_392++;
  162.                Gd_304 += OrderLots();
  163.                Gd_320 += OrderProfit();
  164.                Gd_336 += OrderLots() * OrderOpenPrice();
  165.                G_order_open_price_352 = OrderOpenPrice();
  166.             }
  167.             if (OrderType() == OP_SELL) {
  168.                G_index_396++;
  169.                Gd_312 += OrderLots();
  170.                Gd_328 += OrderProfit();
  171.                Gd_344 += OrderLots() * OrderOpenPrice();
  172.                G_order_open_price_360 = OrderOpenPrice();
  173.             }
  174.          }
  175.       }
  176.    }
  177.    if (Gd_304 != 0.0) Gd_368 = NormalizeDouble(Gd_336 / Gd_304, Digits);
  178.    if (Gd_312 != 0.0) Gd_376 = NormalizeDouble(Gd_344 / Gd_312, Digits);
  179. }
复制代码


回复

使用道具 举报

295

主题

38

回帖

1265

积分

管理员

积分
1265
 楼主| 发表于 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 脚本采用的是分批加仓的方式进行交易,每次加仓的数量和间隔是预先设置好的,并根据市场行情动态地开启新的加仓批次。同时,它还具有实时监控订单并调整止损和止盈的能力。
回复

使用道具 举报

295

主题

38

回帖

1265

积分

管理员

积分
1265
 楼主| 发表于 2024-3-19 13:14:26 | 显示全部楼层
优化建议:
虽然这段代码实现了基本的批量加仓交易策略,但为了提升代码可读性和维护性,以及潜在的性能优化,以下是一些建议:

变量命名规范:

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

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

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

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

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

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

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

使用道具 举报

295

主题

38

回帖

1265

积分

管理员

积分
1265
 楼主| 发表于 2024-3-19 13:14:52 | 显示全部楼层
完整优化后的代码
  1. #include <stdio.h>
  2. #include <MetaTrader5/MetaTrader5.h>

  3. // 定义交易批次结构体
  4. struct TradeBatch {
  5.     double lot_size;
  6.     double price_interval;
  7.     double take_profit;
  8. };

  9. extern int BuyOrSell = 0; // 0=多, 1=空
  10. extern int MaxTrades = 7;
  11. extern int sliptime = 30;
  12. extern int slippage = 3;
  13. extern int MagicN = 10533;
  14. extern string Commentt = "QQ:2913811";

  15. // 交易批次列表
  16. TradeBatch trade_batches[7];

  17. double current_bid_price;
  18. double current_ask_price;
  19. int long_index = 0;
  20. int short_index = 0;

  21. bool OpenLong = false;
  22. bool OpenShort = false;
  23. bool TrackOpenLong = false;
  24. bool TrackOpenShort = false;
  25. datetime TimeLong = 0;
  26. datetime TimeShort = 0;

  27. void OnInit() {
  28.     SetIndexStyle(0, DRAW_LINE, EMPTY);
  29.     SetIndexBuffer(0, Gda_296);
  30.    
  31.     trade_batches[0] = {0.01, 15, 15};
  32.     trade_batches[1] = {0.02, 15, 15};
  33.     trade_batches[2] = {0.04, 15, 15};
  34.     trade_batches[3] = {0.07, 15, 15};
  35.     trade_batches[4] = {0.09, 15, 15};
  36.     trade_batches[5] = {0.12, 15, 15};
  37.     trade_batches[6] = {0.15, 15, 15};

  38.     for (int i = 0; i < 7; ++i) {
  39.         if (Digits == 5 || Digits == 3) {
  40.             trade_batches[i].price_interval *= 10;
  41.             trade_batches[i].take_profit *= 10;
  42.         }
  43.         else if (StringFind(Symbol(), "XAU", 0) >= 0 || StringFind(Symbol(), "GOLD", 0) >= 0 && (Digits == 2 || Digits == 3)) {
  44.             trade_batches[i].price_interval *= (Digits == 2 ? 10 : 100);
  45.             trade_batches[i].take_profit *= (Digits == 2 ? 10 : 100);
  46.         }
  47.     }
  48. }

  49. void OnTick() {
  50.     CountOrders();
  51.     TrackOpenLong = false;
  52.     TrackOpenShort = false;
  53.     current_bid_price = Bid;
  54.     current_ask_price = Ask;

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

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

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

  65.     O_Modify(OP_BUY);
  66.     O_Modify(OP_SELL);
  67. }

  68. bool CheckOpenPosition(int positionSide) {
  69.     double reference_price = positionSide == OP_BUY ? current_ask_price : current_bid_price;
  70.     double last_open_price = positionSide == OP_BUY ? G_order_open_price_352 : G_order_open_price_360;
  71.     return (positionSide == OP_BUY ? last_open_price - reference_price : reference_price - last_open_price) >= trade_batches[positionSide == OP_BUY ? long_index - 1 : short_index - 1].price_interval * Point;
  72. }

  73. void TryOpenPosition(int positionSide, int &index, bool &isOpen, datetime &trackTime) {
  74.     if (index == 0 || isOpen && TimeCurrent() - trackTime >= sliptime * TimeSpanSeconds(M1)) {
  75.         isOpen = true;
  76.         double order_price = positionSide == OP_BUY ? Ask : Bid;
  77.         int ticket = OrderSend(Symbol(), positionSide, trade_batches[positionSide == OP_BUY ? long_index : short_index].lot_size, order_price, slippage * Point, 0, 0, Commentt, MagicN, 0, positionSide == OP_BUY ? Blue : Red);
  78.         if (ticket > 0) {
  79.             isOpen = false;
  80.             BuyOrSell = positionSide == OP_BUY ? TRUE : FALSE;
  81.             index++;
  82.         }
  83.     }
  84. }

  85. void ResetTrack(bool &isOpen, datetime &trackTime) {
  86.     isOpen = false;
  87.     trackTime = 0;
  88. }

  89. // ... 保留原有的O_Modify函数和其他辅助函数 ...
复制代码


回复

使用道具 举报

295

主题

38

回帖

1265

积分

管理员

积分
1265
 楼主| 发表于 2024-3-19 13:23:58 | 显示全部楼层
这段代码已经更加接近完整可运行的状态,但仍然依赖于您原始代码中的某些未在该段代码中展示的变量,如 G_order_open_price_352 和 G_order_open_price_360 等。此外,还需要您在 EA 中实现 CountOrders 和 O_Modify 函数,以及其他必要的辅助函数。在实际使用前,请务必根据您的具体情况进行测试和调整。
回复

使用道具 举报

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

本版积分规则

QQ|Archiver|手机版|小黑屋|外汇论坛 ( 粤ICP备16021788号 )

GMT+8, 2024-4-28 14:30 , Processed in 0.074300 second(s), 18 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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