MQL4外汇EA: 实现锁仓和加仓逻辑
MQL4外汇EA: 实现锁仓和加仓逻辑
不好意思,之前的代码还是有问题。以下是修订后的代码,包括加入锁仓和加仓的逻辑:cpp//+------------------------------------------------------------------+//| 7777.mq4 |//| Copyright 2023, MetaQuotes Ltd. |//| https://www.mql5.com |//+------------------------------------------------------------------+#property copyright 'Copyright 2023, MetaQuotes Ltd.'#property link 'https://www.mql5.com'#property version '1.00'#property strict
//+------------------------------------------------------------------+//| Global variables |//+------------------------------------------------------------------+int MAGIC_NUMBER = 92133;double INITIAL_LOTS = 0.5;double REPLENISH_MULTIPLIER = 0.6;int REPLENISH_ATTEMPTS = 5;double PROFIT_TARGET = 40;double MIN_FLUCTUATION = MarketInfo(Symbol(), MODE_POINT) * 100;
bool hasLongPosition = false;bool hasShortPosition = false;
//+------------------------------------------------------------------+//| Expert initialization function |//+------------------------------------------------------------------+int OnInit(){ return (INIT_SUCCEEDED);}
//+------------------------------------------------------------------+//| Expert deinitialization function |//+------------------------------------------------------------------+void OnDeinit(const int reason){ // Close all open orders CloseOrders();}
//+------------------------------------------------------------------+//| Expert tick function |//+------------------------------------------------------------------+void OnTick(){ // Check if all positions have been closed if (!hasLongPosition && !hasShortPosition) { // Determine the prices for the pending orders double askPrice = NormalizeDouble(MarketInfo(Symbol(), MODE_ASK), Digits); double bidPrice = NormalizeDouble(MarketInfo(Symbol(), MODE_BID), Digits); double buyPrice = askPrice + MIN_FLUCTUATION; double sellPrice = bidPrice - MIN_FLUCTUATION;
// Place pending orders if there are no open positions if (!hasLongPosition && CountOrders(OP_BUYSTOP) == 0) { if (CountOrders(OP_SELLSTOP) > 0) { DeleteOrders(OP_SELLSTOP); }
if (CountOrders(OP_BUYLIMIT) > 0) { DeleteOrders(OP_BUYLIMIT); }
if (OpenBuyOrder(INITIAL_LOTS, buyPrice)) { Print('Opened buy order'); hasLongPosition = true; } else { Print('Failed to open buy order'); } }
if (!hasShortPosition && CountOrders(OP_SELLSTOP) == 0) { if (CountOrders(OP_BUYSTOP) > 0) { DeleteOrders(OP_BUYSTOP); }
if (CountOrders(OP_SELLLIMIT) > 0) { DeleteOrders(OP_SELLLIMIT); }
if (OpenSellOrder(INITIAL_LOTS, sellPrice)) { Print('Opened sell order'); hasShortPosition = true; } else { Print('Failed to open sell order'); } } } else { // Check if any positions have reached the profit target double totalProfit = 0; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC_NUMBER) { totalProfit += OrderProfit(); } } if (totalProfit >= PROFIT_TARGET) { CloseOrders(); } else { // Check if the market has moved against the positions by 100 points double point = MarketInfo(Symbol(), MODE_POINT); double minPrice = NormalizeDouble(OrderOpenPrice() - (100 * point), Digits); double maxPrice = NormalizeDouble(OrderOpenPrice() + (100 * point), Digits); double currentBid = NormalizeDouble(MarketInfo(Symbol(), MODE_BID), Digits); double currentAsk = NormalizeDouble(MarketInfo(Symbol(), MODE_ASK), Digits);
if (hasLongPosition && currentBid <= minPrice) { // Lock the long position by opening a sell order if (OpenSellOrder(INITIAL_LOTS, currentBid)) { Print('Locked long position by opening sell order'); hasShortPosition = true; } else { Print('Failed to open sell order to lock long position'); } } else if (hasShortPosition && currentAsk >= maxPrice) { // Lock the short position by opening a buy order if (OpenBuyOrder(INITIAL_LOTS, currentAsk)) { Print('Locked short position by opening buy order'); hasLongPosition = true; } else { Print('Failed to open buy order to lock short position'); } }
// Replenish the positions if not already at the maximum attempts if (!hasLongPosition && CountOrders(OP_BUYSTOP) == 1 && CountOrders(OP_BUYLIMIT) == 0) { double lastBuyPrice = GetLastOrderPrice(OP_BUYSTOP); double replenishPrice = lastBuyPrice + MIN_FLUCTUATION; double replenishLots = GetLastOrderLots(OP_BUYSTOP) * REPLENISH_MULTIPLIER;
if (replenishPrice <= currentAsk && ReplenishAttemptsRemaining(OP_BUYSTOP) > 0) { if (OpenBuyOrder(replenishLots, replenishPrice)) { Print('Replenished buy order'); } else { Print('Failed to replenish buy order'); } } }
if (!hasShortPosition && CountOrders(OP_SELLSTOP) == 1 && CountOrders(OP_SELLLIMIT) == 0) { double lastSellPrice = GetLastOrderPrice(OP_SELLSTOP); double replenishPrice = lastSellPrice - MIN_FLUCTUATION; double replenishLots = GetLastOrderLots(OP_SELLSTOP) * REPLENISH_MULTIPLIER;
if (replenishPrice >= currentBid && ReplenishAttemptsRemaining(OP_SELLSTOP) > 0) { if (OpenSellOrder(replenishLots, replenishPrice)) { Print('Replenished sell order'); } else { Print('Failed to replenish sell order'); } } } } }}
//+------------------------------------------------------------------+//| Open buy order function |//+------------------------------------------------------------------+bool OpenBuyOrder(double lots, double price){ int ticket = OrderSend(Symbol(), OP_BUYSTOP, lots, price, 0, 0, 0, 'Buy Order', MAGIC_NUMBER, 0, Green); if (ticket > 0) { if (OrderSelect(ticket, SELECT_BY_TICKET)) { return true; } else { Print('Failed to select order with ticket ', ticket); } } else { Print('Failed to send buy order'); } return false;}
//+------------------------------------------------------------------+//| Open sell order function |//+------------------------------------------------------------------+bool OpenSellOrder(double lots, double price){ int ticket = OrderSend(Symbol(), OP_SELLSTOP, lots, price, 0, 0, 0, 'Sell Order', MAGIC_NUMBER, 0, Red); if (ticket > 0) { if (OrderSelect(ticket, SELECT_BY_TICKET)) { return true; } else { Print('Failed to select order with ticket ', ticket); } } else { Print('Failed to send sell order'); } return false;}
//+------------------------------------------------------------------+//| Close all orders function |//+------------------------------------------------------------------+void CloseOrders(){ for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC_NUMBER) { if (!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0)) { Print('Failed to close order with ticket ', OrderTicket()); } } }
hasLongPosition = false; hasShortPosition = false;}
//+------------------------------------------------------------------+//| Delete orders of a specific type |//+------------------------------------------------------------------+void DeleteOrders(int orderType){ for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC_NUMBER && OrderType() == orderType) { if (!OrderDelete(OrderTicket())) { Print('Failed to delete order with ticket ', OrderTicket()); } } }}
//+------------------------------------------------------------------+//| Count orders of a specific type |//+------------------------------------------------------------------+int CountOrders(int orderType){ int count = 0; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC_NUMBER && OrderType() == orderType) { count++; } } return count;}
//+------------------------------------------------------------------+//| Get the remaining replenish attempts for a specific order type |//+------------------------------------------------------------------+int ReplenishAttemptsRemaining(int orderType){ int attempts = REPLENISH_ATTEMPTS; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (attempts == 0) { break; }
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC_NUMBER && OrderType() == orderType) { attempts--; } } return attempts;}
//+------------------------------------------------------------------+//| Get the price of the last order of a specific type |//+------------------------------------------------------------------+double GetLastOrderPrice(int orderType){ for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC_NUMBER && OrderType() == orderType) { return OrderOpenPrice(); } } return 0;}
//+------------------------------------------------------------------+//| Get the lots of the last order of a specific type |//+------------------------------------------------------------------+double GetLastOrderLots(int orderType){ for (int i = OrdersTotal() - 1; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC_NUMBER && OrderType() == orderType) { return OrderLots(); } } return 0;}
现在,代码会在持有多单并且市场下跌100个点时锁仓做空,并在持有空单并且市场上涨100个点时锁仓做多。非常抱歉之前的代码有误,并感谢您的耐心和理解。请注意,这只是一个简单的示例,并且可能需要根据您的具体需求进行调整和完善。编写自动交易系统需要特定的经验和知识,确保您充分了解和测试代码,以确保其符合您的交易策略和需求。
原文地址: https://www.cveoy.top/t/topic/b3fW 著作权归作者所有。请勿转载和采集!