Untitled
unknown
plain_text
10 months ago
6.9 kB
5
Indexable
#include <Trade/Trade.mqh>
#include <Arrays/ArrayLong.mqh>
// Lot sizes for up to 20 orders in one cycle
static double lotSizes[20] = {0.01, 0.02, 0.02, 0.03, 0.05, 0.08, 0.11, 0.17, 0.26, 0.38,
0.58, 0.86, 1.30, 1.95, 2.92, 4.38, 6.75, 9.85, 10, 10};
// Adjustable parameters
input double StepPercent = 0.2; // Percentage change relative to the open price to trigger step-in
input double ProfitLotStep = 10; // Profit threshold (scaled by lot) to close the cycle
input double StopLoss = 300; // Stop-loss threshold (in account currency) to cut losses
// Separate arrays to store tickets for BUY and SELL orders
CArrayLong buyTickets;
CArrayLong sellTickets;
int barsTotal = 0;
int OnInit()
{
barsTotal = iBars(_Symbol, PERIOD_M15); // Initialize barsTotal
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
// Function to close all BUY positions
void CloseBuyPositions(CTrade &trade)
{
for (int i = buyTickets.Total() - 1; i >= 0; i--)
{
CPositionInfo pos;
if (pos.SelectByTicket(buyTickets.At(i)))
{
if (trade.PositionClose(pos.Ticket()))
{
buyTickets.Delete(i);
}
}
}
}
// Function to close all SELL positions
void CloseSellPositions(CTrade &trade)
{
for (int i = sellTickets.Total() - 1; i >= 0; i--)
{
CPositionInfo pos;
if (pos.SelectByTicket(sellTickets.At(i)))
{
if (trade.PositionClose(pos.Ticket()))
{
sellTickets.Delete(i);
}
}
}
}
void OnTick()
{
// Update barsTotal if a new M15 bar is formed
int currentBars = iBars(_Symbol, PERIOD_M15);
if(currentBars != barsTotal)
{
barsTotal = currentBars;
}
CTrade trade;
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
// Calculate profit and total lot separately for BUY orders
double buyProfit = 0, buyLots = 0;
for (int i = 0; i < buyTickets.Total(); i++)
{
CPositionInfo pos;
if (pos.SelectByTicket(buyTickets.At(i)))
{
buyProfit += pos.Profit() + pos.Swap();
buyLots += pos.Volume();
}
}
// Calculate profit and total lot separately for SELL orders
double sellProfit = 0, sellLots = 0;
for (int i = 0; i < sellTickets.Total(); i++)
{
CPositionInfo pos;
if (pos.SelectByTicket(sellTickets.At(i)))
{
sellProfit += pos.Profit() + pos.Swap();
sellLots += pos.Volume();
}
}
double lotstep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
// --- STEP-IN for BUY cycle ---
if (buyTickets.Total() > 0 && buyTickets.Total() < 20)
{
CPositionInfo pos;
if (pos.SelectByTicket(buyTickets.At(buyTickets.Total() - 1)))
{
double newLot = lotSizes[buyTickets.Total()];
// If the current bid is sufficiently lower than the open price of the last BUY order
if (bid < pos.PriceOpen() - pos.PriceOpen() * StepPercent / 100)
{
Print(__FUNCTION__, " > Step buy Signal with lot ", newLot, "...");
if (trade.Buy(newLot) && trade.ResultOrder() > 0 && trade.ResultRetcode() == TRADE_RETCODE_DONE)
buyTickets.Add(trade.ResultOrder());
}
}
}
// --- STEP-IN for SELL cycle ---
if (sellTickets.Total() > 0 && sellTickets.Total() < 20)
{
CPositionInfo pos;
if (pos.SelectByTicket(sellTickets.At(sellTickets.Total() - 1)))
{
double newLot = lotSizes[sellTickets.Total()];
// If the current bid is sufficiently higher than the open price of the last SELL order
if (bid > pos.PriceOpen() + pos.PriceOpen() * StepPercent / 100)
{
Print(__FUNCTION__, " > Step sell Signal with lot ", newLot, "...");
if (trade.Sell(newLot) && trade.ResultOrder() > 0 && trade.ResultRetcode() == TRADE_RETCODE_DONE)
sellTickets.Add(trade.ResultOrder());
}
}
}
// --- Activate initial orders for each independent cycle ---
double openPrevious = iOpen(_Symbol, PERIOD_M15, 1);
double openCurrent = iOpen(_Symbol, PERIOD_M15, 0);
// If there are no BUY orders and the market is falling, then enter a BUY order
if (buyTickets.Total() == 0 && openCurrent < openPrevious)
{
double newLot = lotSizes[0];
Print(__FUNCTION__, " Initial buy Signal with lot ", newLot, "...");
if (trade.Buy(newLot) && trade.ResultOrder() > 0 && trade.ResultRetcode() == TRADE_RETCODE_DONE)
buyTickets.Add(trade.ResultOrder());
}
// If there are no SELL orders and the market is rising, then enter a SELL order
if (sellTickets.Total() == 0 && openCurrent > openPrevious)
{
double newLot = lotSizes[0];
Print(__FUNCTION__, " Initial sell Signal with lot ", newLot, "...");
if (trade.Sell(newLot) && trade.ResultOrder() > 0 && trade.ResultRetcode() == TRADE_RETCODE_DONE)
sellTickets.Add(trade.ResultOrder());
}
// --- Risk management for BUY cycle ---
if (buyTickets.Total() > 0)
{
// If the profit target for the BUY cycle is reached
if (buyProfit > ProfitLotStep * buyLots / lotstep)
{
Print(__FUNCTION__, " > BUY cycle hit profit target, closing BUY positions...");
CloseBuyPositions(trade);
}
// If loss exceeds the StopLoss for the BUY cycle
if (buyProfit <= -StopLoss)
{
Print(__FUNCTION__, " > BUY cycle StopLoss reached (loss ", buyProfit, "), closing BUY positions...");
CloseBuyPositions(trade);
}
// If 20 BUY orders are reached in the cycle
if (buyTickets.Total() >= 20)
{
Print(__FUNCTION__, " > 20 BUY orders reached, closing BUY cycle...");
CloseBuyPositions(trade);
}
}
// --- Risk management for SELL cycle ---
if (sellTickets.Total() > 0)
{
// If the profit target for the SELL cycle is reached
if (sellProfit > ProfitLotStep * sellLots / lotstep)
{
Print(__FUNCTION__, " > SELL cycle hit profit target, closing SELL positions...");
CloseSellPositions(trade);
}
// If loss exceeds the StopLoss for the SELL cycle
if (sellProfit <= -StopLoss)
{
Print(__FUNCTION__, " > SELL cycle StopLoss reached (loss ", sellProfit, "), closing SELL positions...");
CloseSellPositions(trade);
}
// If 20 SELL orders are reached in the cycle
if (sellTickets.Total() >= 20)
{
Print(__FUNCTION__, " > 20 SELL orders reached, closing SELL cycle...");
CloseSellPositions(trade);
}
}
}
Editor is loading...
Leave a Comment