//+------------------------------------------------------------------+
//| Open sell position |
//+------------------------------------------------------------------+
void OpenSellPosition()
{
if(!TradeEnabled) return;
MqlTradeRequest request;
MqlTradeResult result;
double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double sl = (StopLoss > 0) ? price + StopLoss * _Point : 0;
double tp = (TakeProfit > 0) ? price - TakeProfit * _Point : 0;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = LotSize;
request.type = ORDER_TYPE_SELL;
request.price = price;
request.sl = sl;
request.tp = tp;
request.magic = MagicNumber;
request.deviation = 10;
if(OrderSend(request, result))
{
Print("SELL order opened. Ticket: ", result.order);
}
else
{
Print("Error opening SELL order: ", GetLastError());
}
}
//+------------------------------------------------------------------+
//| Close all positions |
//+------------------------------------------------------------------+
void CloseAllPositions()
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong ticket = PositionGetTicket(i);
if(PositionGetString(POSITION_SYMBOL) == _Symbol &&
PositionGetInteger(POSITION_MAGIC) == MagicNumber)
{
ClosePosition(ticket);
}
}
}
//+------------------------------------------------------------------+
//| Close individual position |
//+------------------------------------------------------------------+
void ClosePosition(ulong ticket)
{
MqlTradeRequest request;
MqlTradeResult result;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.position = ticket;
request.symbol = _Symbol;
request.volume = PositionGetDouble(POSITION_VOLUME);
request.deviation = 10;
request.magic = MagicNumber;
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
{
request.type = ORDER_TYPE_SELL;
request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
}
else
{
request.type = ORDER_TYPE_BUY;
request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
}
if(OrderSend(request, result))
{
Print("Position closed. Ticket: ", result.order);
}
else
{
Print("Error closing position: ", GetLastError());
}
}
//+------------------------------------------------------------------+
//| Count positions by type |
//+------------------------------------------------------------------+
int CountPositions(ENUM_POSITION_TYPE type)
{
int count = 0;
for(int i = 0; i < PositionsTotal(); i++)
{
if(PositionGetTicket(i))
{
if(PositionGetString(POSITION_SYMBOL) == _Symbol &&
PositionGetInteger(POSITION_MAGIC) == MagicNumber &&
PositionGetInteger(POSITION_TYPE) == type)
{
count++;
}
}
}
return count;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Analyze signals and execute trades |
//+------------------------------------------------------------------+
void AnalyzeAndTrade()
{
bool buySignal = false;
bool sellSignal = false;
// Get current and previous values
double stoch_curr = stochasticMain[0];
double stoch_prev = stochasticMain[1];
// Initialize second indicator variables with default values
double sdcp_curr = 0;
double sdcp_prev = 0;
bool secondIndicatorAvailable = false;
// Determine which second indicator to use
if(sdcpHandle != INVALID_HANDLE)
{
sdcp_curr = sdcpMain[0];
sdcp_prev = sdcpMain[1];
secondIndicatorAvailable = true;
}
else if(altStochasticHandle != INVALID_HANDLE)
{
sdcp_curr = altStochasticMain[0];
sdcp_prev = altStochasticMain[1];
secondIndicatorAvailable = true;
}
// Check BUY conditions (bounce from oversold)
if(stoch_prev <= OversoldLevel && stoch_curr > OversoldLevel && stoch_curr > stoch_prev)
{
if(!RequireBothIndicators)
{
buySignal = true;
}
else if(secondIndicatorAvailable &&
sdcp_prev <= OversoldLevel && sdcp_curr > OversoldLevel && sdcp_curr > sdcp_prev)
{
buySignal = true;
}
}
// Check SELL conditions (bounce from overbought)
if(stoch_prev >= OverboughtLevel && stoch_curr < OverboughtLevel && stoch_curr < stoch_prev)
{
if(!RequireBothIndicators)
{
sellSignal = true;
}
else if(secondIndicatorAvailable &&
sdcp_prev >= OverboughtLevel && sdcp_curr < OverboughtLevel && sdcp_curr < sdcp_prev)
{
sellSignal = true;
}
}
// Execute trading operations
if(buySignal)
{
if(ReversePosition) CloseAllPositions();
if(CountPositions(POSITION_TYPE_SELL) == 0 || !ReversePosition)
OpenBuyPosition();
}
else if(sellSignal)
{
if(ReversePosition) CloseAllPositions();
if(CountPositions(POSITION_TYPE_BUY) == 0 || !ReversePosition)
OpenSellPosition();
}
}
//+------------------------------------------------------------------+
//| Open buy position |
//+------------------------------------------------------------------+
void OpenBuyPosition()
{
if(!TradeEnabled) return;
MqlTradeRequest request;
MqlTradeResult result;
double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double sl = (StopLoss > 0) ? price - StopLoss * _Point : 0;
double tp = (TakeProfit > 0) ? price + TakeProfit * _Point : 0;
ZeroMemory(request);
ZeroMemory(result);
request.action = TRADE_ACTION_DEAL;
request.symbol = _Symbol;
request.volume = LotSize;
request.type = ORDER_TYPE_BUY;
request.price = price;
request.sl = sl;
request.tp = tp;
request.magic = MagicNumber;
request.deviation = 10;
if(OrderSend(request, result))
{
Print("BUY order opened. Ticket: ", result.order);
}
else
{
Print("Error opening BUY order: ", GetLastError());
}
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
if(stochasticHandle != INVALID_HANDLE) IndicatorRelease(stochasticHandle);
if(sdcpHandle != INVALID_HANDLE) IndicatorRelease(sdcpHandle);
if(altStochasticHandle != INVALID_HANDLE) IndicatorRelease(altStochasticHandle);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Check for new bar
if(!IsNewBar()) return;
// Update indicator data
if(!UpdateIndicatorData()) return;
// Analyze signals and execute trades
AnalyzeAndTrade();
}
//+------------------------------------------------------------------+
//| Check for new bar |
//+------------------------------------------------------------------+
bool IsNewBar()
{
datetime currentBarTime = iTime(_Symbol, _Period, 0);
if(currentBarTime == lastBarTime) return false;
lastBarTime = currentBarTime;
return true;
}
//+------------------------------------------------------------------+
//| Update indicator data |
//+------------------------------------------------------------------+
bool UpdateIndicatorData()
{
// Get Stochastic data
if(CopyBuffer(stochasticHandle, 0, 0, 3, stochasticMain) < 3 ||
CopyBuffer(stochasticHandle, 1, 0, 3, stochasticSignal) < 3)
{
Print("Error copying Stochastic data");
return false;
}
// Get StochDivCandlePro data if available
if(sdcpHandle != INVALID_HANDLE)
{
if(CopyBuffer(sdcpHandle, 0, 0, 3, sdcpMain) < 3 ||
CopyBuffer(sdcpHandle, 1, 0, 3, sdcpSignal) < 3)
{
Print("Error copying StochDivCandlePro data");
}
}
// Get alternative Stochastic data if needed
if(altStochasticHandle != INVALID_HANDLE && sdcpHandle == INVALID_HANDLE)
{
if(CopyBuffer(altStochasticHandle, 0, 0, 3, altStochasticMain) < 3 ||
CopyBuffer(altStochasticHandle, 1, 0, 3, altStochasticSignal) < 3)
{
Print("Error copying alternative Stochastic data");
}
}
return true;
}
//+------------------------------------------------------------------+
//| StochasticBouncePRO.mq5 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "2.00"
//+------------------------------------------------------------------+
//| Input parameters |
//+------------------------------------------------------------------+
//--- Stochastic Settings
input group "=== Stochastic Settings ==="
input int StochasticPeriodK = 5; // Period %K
input int StochasticPeriodD = 3; // Period %D
input int StochasticSlowing = 3; // Slowing
input ENUM_MA_METHOD StochasticMethod = MODE_SMA; // Method
input ENUM_STO_PRICE StochasticPrice = STO_LOWHIGH; // Prices
//--- StochDivCandlePro Settings
input group "=== StochDivCandlePro Settings ==="
input bool UseSDCP = true; // Use StochDivCandlePro
input int SDCP_Period = 14; // SDCP Period
input bool UseAlternative = true; // Use Alternative if SDCP unavailable
//--- Trading Levels
input group "=== Trading Levels ==="
input double OverboughtLevel = 80.0; // Overbought Level
input double OversoldLevel = 20.0; // Oversold Level
input bool RequireBothIndicators = false; // Require both indicators confirmation
//--- Trading Settings
input group "=== Trading Settings ==="
input double LotSize = 0.1; // Lot Size
input int StopLoss = 50; // Stop Loss (points)
input int TakeProfit = 100; // Take Profit (points)
input bool ReversePosition = true; // Reverse Position
input int MagicNumber = 12345; // Magic Number
input bool TradeEnabled = true; // Trading Enabled
//--- Global variables
int stochasticHandle, sdcpHandle, altStochasticHandle;
double stochasticMain[], stochasticSignal[];
double sdcpMain[], sdcpSignal[];
double altStochasticMain[], altStochasticSignal[];
datetime lastBarTime;
string logInfo;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
Print("StochasticBouncePRO v2.00 initializing...");
// Create Stochastic indicator
stochasticHandle = iStochastic(_Symbol, _Period, StochasticPeriodK, StochasticPeriodD,
StochasticSlowing, StochasticMethod, StochasticPrice);
if(stochasticHandle == INVALID_HANDLE)
{
Print("Error creating Stochastic indicator");
return INIT_FAILED;
}
// Try to create StochDivCandlePro indicator
if(UseSDCP)
{
sdcpHandle = iCustom(_Symbol, _Period, "StochDivCandlePro", SDCP_Period);
if(sdcpHandle == INVALID_HANDLE)
{
Print("StochDivCandlePro not found, using alternative if enabled");
if(UseAlternative)
{
altStochasticHandle = iStochastic(_Symbol, _Period, 14, 3, 3, MODE_SMA, STO_CLOSECLOSE);
if(altStochasticHandle == INVALID_HANDLE)
{
Print("Error creating alternative Stochastic");
}
}
}
}
// Set array as series
ArraySetAsSeries(stochasticMain, true);
ArraySetAsSeries(stochasticSignal, true);
ArraySetAsSeries(sdcpMain, true);
ArraySetAsSeries(sdcpSignal, true);
ArraySetAsSeries(altStochasticMain, true);
ArraySetAsSeries(altStochasticSignal, true);
Print("StochasticBouncePRO initialized successfully");
return INIT_SUCCEEDED;
}
← предыдущая следующая →
evgsergej