2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| Grid_2.mq5 |
//| AK47 |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
# property copyright " AK47 "
# property link " https://www.mql5.com "
# property version " 1.00 "
///////INCLUDE//////////
# include <Trade\Trade.mqh>
# include <Trade\OrderInfo.mqh>
# include <Trade\SymbolInfo.mqh>
# include <Trade\AccountInfo.mqh>
# include <Trade\DealInfo.mqh>
# include <Trade\PositionInfo.mqh>
# include <Arrays\ArrayDouble.mqh>
//#include <News.mqh>
//#include <Time.mqh>
////////GLOBALS//////////////
2025-12-22 14:58:27 +03:00
enum Side
2025-12-26 17:12:21 +03:00
{
2025-12-22 14:58:27 +03:00
Buy = 0 , // Buy
Sell = 1 , // Sell
2025-12-21 23:44:47 +03:00
Both = 2 , // Both
2025-12-26 17:12:21 +03:00
} ;
2025-12-21 23:44:47 +03:00
input double FixedLot = 0.01 ; // Fixed Lot
input Side EntrySide = 2 ;
2025-12-22 14:58:27 +03:00
input double TakeProfitFactor = 2 ;
2025-12-21 23:44:47 +03:00
double StopLossFactor = 3 ;
2025-12-24 23:50:14 +03:00
input ushort Grid = 250 ; // Grid Distance
2025-12-21 23:44:47 +03:00
//input double CloseTreshold=1.05;
//input double FreeMarginThreshold=0.3;
//input double EquityStopLossPercent=0.9;
2025-12-24 23:50:14 +03:00
input int PositionsThreshold = 2 ;
2025-12-22 14:58:27 +03:00
input double stDev = 1 ; // deviation
int MALength = 12 ;
2025-12-24 23:50:14 +03:00
input int bandsLength = 18 ;
2025-12-22 14:58:27 +03:00
int ATR1Length = 12 ;
int ATR2Length = 12 ;
2025-12-24 23:50:14 +03:00
input double Grid_mul = 1.2 , Vol_Mul = 1.8 ;
input string GMTstartTime = " 11:30 " ;
input string GMTendTime = " 17:30 " ;
input ENUM_TIMEFRAMES TimeFrame = PERIOD_M5 ;
2025-12-21 23:44:47 +03:00
////////////CLASSES////////////////////
CTrade trade ;
CDealInfo deal ;
CPositionInfo PosInfo ;
CArrayDouble List ;
CAccountInfo Account ;
COrderInfo OrdInfo ;
//CNews News;
//CTime Time;
//////////VARIABLES/////////////
double MAHigh [ ] , MAHighData , MAHighHandle ,
MALow [ ] , MALowData , MALowHandle ,
2025-12-24 23:50:14 +03:00
MA [ ] , MAData , MAHandle , Momentum [ ] , MomentumData , MomentumHandle ,
2025-12-21 23:44:47 +03:00
bands [ ] , bandsupper [ ] , bandslower [ ] , bandsHandle , bandsData ,
MFI [ ] , MFIData , MFIHandle ,
ATR1 [ ] , ATR2 [ ] , ATR1Data , ATR2Data , ATR1Handle , ATR2Handle ;
double ask , bid ,
StopLossBuy = 0 , StopLossSell = 0 ,
TakeProfitBuy = 0 , TakeProfitSell = 0 ,
StartingBalance ,
spread ,
buyFactor , sellFactor ,
Grid_step_buy ,
Grid_step_sell ,
currentGrid ,
nextUpBuy , nextDownBuy ,
nextUpSell , nextDownSell ,
currentUpBuy , currentDownBuy ,
currentUpSell , currentDownSell ,
meanEntry ;
int upCount = 0 , downCount = 0 ;
double maxEquity , equityVolume = 1 ;
string newGrid , previousGrid ;
double buyVolumeFactor = 1 , sellVolumeFactor = 1 ,
buyVolume , sellVolume ;
2025-12-31 12:03:46 +03:00
bool activateSL = false , buyStopSwitch = false , sellStopSwitch = false , buyLimitSwitch = false , sellLimitSwitch = false ;
2025-12-21 23:44:47 +03:00
MqlRates Bar1 [ ] , Bar2 [ ] ;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
//---
// News.LoadHistory();
StartingBalance = Account . Balance ( ) ;
ChartSetSymbolPeriod ( 0 , _Symbol , TimeFrame ) ;
MAHighHandle = iMA ( _Symbol , TimeFrame , MALength , 0 , MODE_EMA , PRICE_HIGH ) ;
MAHandle = iMA ( _Symbol , TimeFrame , MALength , 0 , MODE_EMA , PRICE_CLOSE ) ;
MALowHandle = iMA ( _Symbol , TimeFrame , MALength , 0 , MODE_EMA , PRICE_LOW ) ;
2025-12-22 14:58:27 +03:00
bandsHandle = iBands ( _Symbol , TimeFrame , bandsLength , 0 , stDev , PRICE_TYPICAL ) ;
ATR1Handle = iATR ( _Symbol , TimeFrame , ATR1Length ) ;
ATR2Handle = iATR ( _Symbol , PERIOD_H1 , ATR2Length ) ;
2025-12-24 23:50:14 +03:00
MomentumHandle = iMomentum ( _Symbol , TimeFrame , 21 , PRICE_MEDIAN ) ;
2025-12-21 23:44:47 +03:00
ArraySetAsSeries ( MFI , true ) ;
2025-12-24 23:50:14 +03:00
2025-12-21 23:44:47 +03:00
ArraySetAsSeries ( ATR1 , true ) ;
ArraySetAsSeries ( ATR2 , true ) ;
2025-12-24 23:50:14 +03:00
2025-12-21 23:44:47 +03:00
ArraySetAsSeries ( MAHigh , true ) ;
ArraySetAsSeries ( MA , true ) ;
ArraySetAsSeries ( MALow , true ) ;
2025-12-24 23:50:14 +03:00
2025-12-21 23:44:47 +03:00
ArraySetAsSeries ( bands , true ) ;
ArraySetAsSeries ( bandsupper , true ) ;
ArraySetAsSeries ( bandslower , true ) ;
ArraySetAsSeries ( Bar1 , true ) ;
ArraySetAsSeries ( Bar2 , true ) ;
2025-12-24 23:50:14 +03:00
ArraySetAsSeries ( Momentum , true ) ;
2025-12-21 23:44:47 +03:00
bid = NormalizeDouble ( SymbolInfoDouble ( _Symbol , SYMBOL_BID ) , _Digits ) ;
ask = NormalizeDouble ( SymbolInfoDouble ( _Symbol , SYMBOL_ASK ) , _Digits ) ;
// double Prices[];
// double Volumes[];
// double levelstep = 5;
// CalculateVolumeDistribution(3,levelstep,Volumes,Prices);
//
// int peaks[];
// int peak_count = ArrayPeaks(Prices,peaks,100);
//
//
// FindIndices((ask+bid)/2,Prices,nextDown,nextUp);
nextUpBuy = ask + Grid * _Point ;
nextDownBuy = bid - Grid * _Point ;
nextUpSell = ask + Grid * _Point ;
nextDownSell = bid - Grid * _Point ;
Print ( " Buy NextLevelUp: " + nextUpBuy ) ;
Print ( " Buy NextLevelDown: " + nextDownBuy ) ;
Print ( " Sell NextLevelUp: " + nextUpSell ) ;
Print ( " Sell NextLevelDown: " + nextDownSell ) ;
//Print("PeaksCount: " + peak_count);
//---
return ( INIT_SUCCEEDED ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit ( const int reason )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
//---
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
// CloseByWin();
//Trailing();
2026-01-12 09:52:43 +03:00
//breakEven();
2025-12-21 23:44:47 +03:00
//TPmodify();
MqlDateTime dt ;
datetime gmtTime = TimeGMT ( dt ) ;
bid = NormalizeDouble ( SymbolInfoDouble ( _Symbol , SYMBOL_BID ) , _Digits ) ;
ask = NormalizeDouble ( SymbolInfoDouble ( _Symbol , SYMBOL_ASK ) , _Digits ) ;
spread = ask - bid ;
//////////////TP&SL//////////////////////////////////////////
MAHighData = CopyBuffer ( MAHighHandle , 0 , 0 , 4 , MAHigh ) ;
MAData = CopyBuffer ( MAHandle , 0 , 0 , 4 , MA ) ;
MALowData = CopyBuffer ( MALowHandle , 0 , 0 , 4 , MALow ) ;
2025-12-31 12:03:46 +03:00
ATR1Data = CopyBuffer ( ATR1Handle , 0 , 0 , 15 , ATR1 ) ;
ATR2Data = CopyBuffer ( ATR2Handle , 0 , 0 , 15 , ATR2 ) ;
2025-12-21 23:44:47 +03:00
bandsData = CopyBuffer ( bandsHandle , 0 , 0 , 4 , bands ) ;
bandsData = CopyBuffer ( bandsHandle , 1 , 0 , 4 , bandsupper ) ;
bandsData = CopyBuffer ( bandsHandle , 2 , 0 , 4 , bandslower ) ;
2025-12-31 16:18:24 +03:00
2025-12-24 23:50:14 +03:00
MomentumData = CopyBuffer ( MomentumHandle , 2 , 0 , 4 , Momentum ) ;
2025-12-21 23:44:47 +03:00
CopyRates ( _Symbol , TimeFrame , 0 , 10 , Bar1 ) ;
CopyRates ( _Symbol , TimeFrame , 0 , 10 , Bar2 ) ;
// TakeProfitBuy = bid+Grid_step*TakeProfitFactor*_Point;
// TakeProfitSell = ask-Grid_step*TakeProfitFactor*_Point;
2025-12-31 16:18:24 +03:00
StopLossBuy = bandslower [ 1 ] ;
StopLossSell = bandsupper [ 1 ] ;
2025-12-21 23:44:47 +03:00
2025-12-24 23:50:14 +03:00
//////////////////// Factors //////////////////////////////////
2025-12-21 23:44:47 +03:00
if ( BuyPositionsCount ( ) ! = 0 )
buyVolumeFactor = NormalizeDouble ( MathPow ( Vol_Mul , BuyPositionsCount ( ) ) , 0 ) ;
else
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
buyVolumeFactor = 1 ;
// Grid_step = Grid;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( SellPositionsCount ( ) ! = 0 )
sellVolumeFactor = NormalizeDouble ( MathPow ( Vol_Mul , SellPositionsCount ( ) ) , 0 ) ;
else
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
sellVolumeFactor = 1 ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( PositionsTotal ( ) < 1 )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Grid_step_buy = Grid ;
Grid_step_sell = Grid ;
2025-12-26 17:12:21 +03:00
}
2026-01-12 09:52:43 +03:00
int babar = 0 ;
2026-01-12 13:41:09 +03:00
if ( babar < iBars ( _Symbol , PERIOD_H1 ) )
2026-01-12 09:52:43 +03:00
{
2026-01-12 13:41:09 +03:00
IdentifyFractalLevels ( 50 , 2 , PERIOD_H1 ) ;
2026-01-12 09:52:43 +03:00
2026-01-12 13:41:09 +03:00
babar = iBars ( _Symbol , PERIOD_H1 ) ;
2026-01-12 09:52:43 +03:00
}
2025-12-21 23:44:47 +03:00
///////////////////BALANCEGRID//////////////////////////////////
string expire_date = " 2026.01.14 " ; //<-- hard coded datetime
datetime e_d = StringToTime ( expire_date ) ;
2025-12-26 17:12:21 +03:00
bool tradetime = true ; // (dt.hour == 8 || dt.hour == 14 || dt.hour == 0 || dt.hour == 1);
//bool tradetime = ((StringToTime(GMTstartTime) < StringToTime(GMTendTime) && gmtTime >= StringToTime(GMTstartTime) && gmtTime <= StringToTime(GMTendTime)) || (StringToTime(GMTstartTime) > StringToTime(GMTendTime) && gmtTime <= StringToTime(GMTstartTime) && gmtTime >= StringToTime(GMTendTime)));
2025-12-24 23:50:14 +03:00
//bool tradays = !((dt.day >= 1 && dt.day <= 7 && dt.day_of_week == 5) || (dt.day >= 10 && dt.day <=13) || (dt.day == 16 && dt.mon == 10));
2025-12-22 01:13:08 +03:00
2025-12-24 23:50:14 +03:00
if ( TimeCurrent ( ) < = e_d ) //spread<1500*_Point){
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Grid_step_buy = Grid * MathPow ( Grid_mul , BuyPositionsCount ( ) ) ;
Grid_step_sell = Grid * MathPow ( Grid_mul , SellPositionsCount ( ) ) ;
2025-12-24 23:50:14 +03:00
2025-12-21 23:44:47 +03:00
buyVolumeFactor = MathPow ( Vol_Mul , BuyPositionsCount ( ) ) ;
sellVolumeFactor = MathPow ( Vol_Mul , SellPositionsCount ( ) ) ;
2025-12-24 23:50:14 +03:00
buyVolume = NormalizeDouble ( equityVolume * buyVolumeFactor * FixedLot , 2 ) ;
sellVolume = NormalizeDouble ( equityVolume * sellVolumeFactor * FixedLot , 2 ) ;
2025-12-22 14:58:27 +03:00
2025-12-31 16:18:24 +03:00
//double meanATR1 = ArrayCountAverage(ATR1,3);
//double meanATR2 = ArrayCountAverage(ATR2,3);
2025-12-21 23:44:47 +03:00
//Print("bands: " + bands[1]);
2025-12-31 12:03:46 +03:00
//Comment("\MATR~1: " + meanATR1 + "MATR~2 " + meanATR2);
//--- BuyLimit
2025-12-21 23:44:47 +03:00
if ( ask < nextDownBuy )
2025-12-26 17:12:21 +03:00
{
2025-12-31 12:03:46 +03:00
buyLimitSwitch = true ;
currentDownBuy = nextDownBuy ;
2025-12-21 23:44:47 +03:00
nextUpBuy = ask + Grid_step_buy * _Point ;
nextDownBuy = bid - Grid_step_buy * _Point ;
2025-12-26 17:12:21 +03:00
}
2025-12-31 12:03:46 +03:00
2026-01-12 09:52:43 +03:00
//if((CheckFractalTrend(10) != "Bullish" && CheckFractalTrend(1) != "Bearish") && tradetime && (EntrySide == 2 || EntrySide == 0) && buyLimitSwitch && currentDownBuy + 100*_Point && !OtherBuyPosition(NULL) && ask > bands[1] && ask < bandslower[0])
// {
// trade.Buy(buyVolume,_Symbol,0,0,TakeProfitBuy,"BuyLimit");
// buyLimitSwitch = false;
// }
2025-12-31 12:03:46 +03:00
//--- BuyStop
2025-12-24 23:50:14 +03:00
if ( ask > nextUpBuy )
2025-12-26 17:12:21 +03:00
{
2025-12-31 12:03:46 +03:00
buyStopSwitch = true ;
2025-12-21 23:44:47 +03:00
currentUpBuy = nextUpBuy ;
nextUpBuy = ask + Grid_step_buy * _Point ;
2025-12-24 23:50:14 +03:00
nextDownBuy = ask - Grid_step_buy * _Point ;
2025-12-26 17:12:21 +03:00
}
2026-01-12 09:52:43 +03:00
if ( CheckFractalTrend ( 10 ) = = " Bullish " & & tradetime & & ( EntrySide = = 2 | | EntrySide = = 0 ) & & buyStopSwitch & & currentUpBuy - 10 * _Point & & ! OtherBuyPosition ( NULL ) & & ask > bandsupper [ 1 ] & & Bar1 [ 1 ] . high > Bar1 [ 2 ] . high )
//
2025-12-31 16:18:24 +03:00
{
trade . Buy ( buyVolume , _Symbol , 0 , StopLossBuy , TakeProfitBuy , " BuyStop " ) ;
buyStopSwitch = false ;
}
2025-12-31 12:03:46 +03:00
//--- SellLimit
2025-12-21 23:44:47 +03:00
2025-12-24 23:50:14 +03:00
if ( bid > nextUpSell )
2025-12-26 17:12:21 +03:00
{
2025-12-31 12:03:46 +03:00
sellLimitSwitch = true ;
currentUpSell = nextUpSell ;
2025-12-24 23:50:14 +03:00
nextUpSell = bid + Grid_step_sell * _Point ;
2025-12-21 23:44:47 +03:00
nextDownSell = bid - Grid_step_sell * _Point ;
2025-12-26 17:12:21 +03:00
}
2026-01-12 09:52:43 +03:00
//if((CheckFractalTrend(10) != "Bullish" && CheckFractalTrend(1) != "Bearish") && tradetime && (EntrySide == 2 || EntrySide == 1) && sellLimitSwitch && currentUpSell - 100*_Point && !OtherSellPosition(NULL) && bid > bands[1] && bid < bandsupper[0])
2025-12-31 16:18:24 +03:00
//{
2026-01-12 09:52:43 +03:00
// trade.Sell(sellVolume,_Symbol,0,StopLossSell,TakeProfitSell,"SellLimit");
2025-12-31 16:18:24 +03:00
// sellLimitSwitch = false;
//}
2025-12-31 12:03:46 +03:00
//--- SellStop
if ( bid < nextDownSell ) // && bid > currentDownSell + 10*_Point && ask < currentUpBuyStop - 10*_Point
{
sellStopSwitch = true ;
2025-12-21 23:44:47 +03:00
currentDownSell = nextDownSell ;
2025-12-24 23:50:14 +03:00
nextUpSell = bid + Grid_step_sell * _Point ;
2025-12-21 23:44:47 +03:00
nextDownSell = bid - Grid_step_sell * _Point ;
2025-12-26 17:12:21 +03:00
}
2026-01-12 09:52:43 +03:00
if ( CheckFractalTrend ( 10 ) = = " Bearish " & & tradetime & & ( EntrySide = = 2 | | EntrySide = = 1 ) & & sellStopSwitch & & currentDownSell + 10 * _Point & & ! OtherSellPosition ( NULL ) & & bid < bandslower [ 1 ] & & Bar1 [ 1 ] . low < Bar1 [ 2 ] . low )
//
2025-12-26 17:12:21 +03:00
{
2025-12-31 16:18:24 +03:00
trade . Sell ( sellVolume , _Symbol , 0 , StopLossSell , TakeProfitSell , " SellStop " ) ;
sellStopSwitch = false ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
else
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Comment ( " Your license is expired! " ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//////////////////////CLOSERS//////////////////////////////////////////////
2025-12-31 16:18:24 +03:00
StoplossUpdate ( " buy " ) ;
StoplossUpdate ( " sell " ) ;
2025-12-21 23:44:47 +03:00
2025-12-22 14:58:27 +03:00
if ( Account . Equity ( ) > maxEquity & & PositionsTotal ( ) < 2 )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
maxEquity = Account . Equity ( ) ;
//equityVolume = MathCeil(maxEquity/10000);
2025-12-31 12:03:46 +03:00
//if(VolumeTotal("Total") > StartingBalance/1000)
//{
// CloseAllPositions();
//}
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
2025-12-22 14:58:27 +03:00
if ( Account . Equity ( ) > = 1.01 * maxEquity )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
activateSL = true ;
maxEquity = Account . Equity ( ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
2025-12-22 14:58:27 +03:00
if ( activateSL & & Account . Equity ( ) < = 1 / ( 1.01 ) * maxEquity )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
activateSL = false ;
2025-12-31 12:03:46 +03:00
//CloseAllPositions();
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| Trade function |
//+------------------------------------------------------------------+
void OnTrade ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
//---
2025-12-26 17:12:21 +03:00
}
2025-12-31 12:03:46 +03:00
2026-01-12 09:52:43 +03:00
/// Global arrays to store fractal highs and lows
double fractalHighs [ ] ;
double fractalLows [ ] ;
//double fractalHighsTime[];
//double fractalLowsTime[];
//int fractalHighsIndex[];
//int fractalLowsIndex[];
MqlRates Bar3 [ ] ;
//Function to identify fractal bars and store their levels
void IdentifyFractalLevels ( int period , int n , ENUM_TIMEFRAMES TF )
{
// Ensure the period is valid
if ( period < n )
{
Print ( " Period must be at least " , n ) ;
return ;
}
// Resize arrays to the specified period
double highs [ ] ;
double lows [ ] ;
ArrayResize ( highs , period ) ;
ArrayResize ( lows , period ) ;
// Copy high and low prices for the given period
if ( CopyHigh ( _Symbol , TF , 0 , period , highs ) < = 0 | | CopyLow ( _Symbol , TF , 0 , period , lows ) < = 0 ) // || CopyTime(_Symbol, TF, 0, period, time) <= 0)
{
Print ( " Failed to copy price data. " ) ;
return ;
}
if ( CopyRates ( _Symbol , TF , 0 , period , Bar3 ) < = 0 )
{
Print ( " Failed to copy rates " ) ;
return ;
}
// Clear previous fractal data
ArrayResize ( fractalHighs , 0 ) ;
ArrayResize ( fractalLows , 0 ) ;
// ArrayResize(fractalHighsTime, 0);
// ArrayResize(fractalLowsTime, 0);
// ArrayResize(fractalHighsIndex,0);
// ArrayResize(fractalLowsIndex,0);
//
// Adjust the loop to find local maxima and minima for n bars around the highest/lowest bar
for ( int i = n ; i < period - n ; i + + )
{
bool isLocalMax = true ;
bool isLocalMin = true ;
// Check for local maximum
for ( int j = 1 ; j < = n ; j + + )
{
if ( highs [ i ] < = highs [ i + j ] | | highs [ i ] < = highs [ i - j ] )
{
isLocalMax = false ;
break ;
}
}
if ( isLocalMax )
{
ArrayResize ( fractalHighs , ArraySize ( fractalHighs ) + 1 ) ;
fractalHighs [ ArraySize ( fractalHighs ) - 1 ] = highs [ i ] ;
// ArrayResize(fractalHighsTime, ArraySize(fractalHighsTime) + 1);
// fractalHighsTime[ArraySize(fractalHighsTime) - 1] = (double) Bar3[i].time;
// ArrayResize(fractalHighsIndex, ArraySize(fractalHighsIndex) + 1);
// fractalHighsIndex[ArraySize(fractalHighsIndex) - 1] = i;
//
// DrawArrow(highs[i],i,"top", clrRed);
}
// Check for local minimum
for ( int j = 1 ; j < = n ; j + + )
{
if ( lows [ i ] > = lows [ i + j ] | | lows [ i ] > = lows [ i - j ] )
{
isLocalMin = false ;
break ;
}
}
if ( isLocalMin )
{
ArrayResize ( fractalLows , ArraySize ( fractalLows ) + 1 ) ;
fractalLows [ ArraySize ( fractalLows ) - 1 ] = lows [ i ] ;
// ArrayResize(fractalLowsTime, ArraySize(fractalLowsTime) + 1);
// fractalLowsTime[ArraySize(fractalLowsTime) - 1] = (double) Bar3[i].time;
// ArrayResize(fractalLowsIndex, ArraySize(fractalLowsIndex) + 1);
// fractalLowsIndex[ArraySize(fractalLowsIndex) - 1] = i;
//
// DrawArrow(lows[i],i,"bottom", clrRed);
}
}
//Print the fractal highs and lows for debugging
for ( int i = 0 ; i < ArraySize ( fractalHighs ) ; i + + )
{
//Print("Fractal High at index ", i, ": ", fractalHighs[i]);
}
for ( int i = 0 ; i < ArraySize ( fractalLows ) ; i + + )
{
//Print("Fractal Low at index ", i, ": ", fractalLows[i]);
}
}
// Function to draw an arrow on the chart
void DrawArrow ( double priceLevel , int index , string arrowPosition , color arrowColor )
{
// Create a unique name for the arrow object
string arrowName = " Arrow_ " + IntegerToString ( index ) + " _ " + arrowPosition ;
int arrowCode = 0 ;
// Determine the y-coordinate for the arrow based on the position (top or bottom)
double yCoordinate = priceLevel ;
if ( arrowPosition = = " top " )
{
// Place the arrow above the bar
yCoordinate + = 10 * Point ( ) ; // Adjust the multiplier as needed
arrowCode = 233 ;
}
else if ( arrowPosition = = " bottom " )
{
// Place the arrow below the bar
yCoordinate - = 10 * Point ( ) ; // Adjust the multiplier as needed
arrowCode = 234 ;
}
// Create the arrow object
if ( ! ObjectCreate ( 0 , arrowName , OBJ_ARROW , 0 , index , yCoordinate ) )
{
//Print("Failed to create arrow object: ", arrowName);
return ;
}
// Set the properties of the arrow
ObjectSetInteger ( 0 , arrowName , OBJPROP_ARROWCODE , arrowCode ) ;
ObjectSetInteger ( 0 , arrowName , OBJPROP_COLOR , arrowColor ) ;
ObjectSetInteger ( 0 , arrowName , OBJPROP_WIDTH , 1 ) ; // Set the width of the arrow
ObjectSetInteger ( 0 , arrowName , OBJPROP_SELECTABLE , false ) ;
ObjectSetInteger ( 0 , arrowName , OBJPROP_HIDDEN , true ) ;
ObjectSetInteger ( 0 , arrowName , OBJPROP_ZORDER , 0 ) ;
}
//-----------------------------------------------------------------------+
// Function to determine the trend based on fractal highs and lows |
//-----------------------------------------------------------------------+
string CheckFractalTrend ( int n )
{
// Ensure there are enough data points to analyze
if ( ArraySize ( fractalHighs ) < 2 | | ArraySize ( fractalLows ) < 2 )
{
//Print("Not enough fractal data to determine trend.");
return " Not enough fractal data to determine trend. " ;
}
// Initialize flags for trend detection
bool higherHighs = false ;
bool lowerLows = false ;
bool higherLows = false ;
bool lowerHighs = false ;
// modify to Check only the last n values from fractal highs and lows
// To modify the code to check only the last `n` values from fractal highs and lows, you need to iterate over the last `n` elements of the `fractalHighs` and `fractalLows` arrays. You can achieve this by using a loop that starts from the end of the array and goes back `n` elements. Here's how you can modify your code:
//
// Define the number of last values to check
// Check the last n values for fractal higherhighs
//for(int i = ArraySize(fractalHighs) - 1; i >= ArraySize(fractalHighs) - n; i--)
//{
// if(i <= 0)
// break; // Ensure we don't go out of bounds
if ( fractalHighs [ ArraySize ( fractalHighs ) -1 ] > fractalHighs [ ArraySize ( fractalHighs ) - 2 ] )
{
higherHighs = true ;
//break;
}
//}
//// Check the last n values for fractal lowerlows
// for(int i = ArraySize(fractalLows) - 1; i >= ArraySize(fractalLows) - n; i--)
// {
// if(i <= 0)
// break; // Ensure we don't go out of bounds
if ( fractalLows [ ArraySize ( fractalLows ) -1 ] < fractalLows [ ArraySize ( fractalLows ) - 2 ] )
{
lowerLows = true ;
//break;
}
//}
//// Check the last n values for fractal higherlows
// for(int i = ArraySize(fractalLows) - 1; i >= ArraySize(fractalLows) - n; i--)
// {
// if(i <= 0)
// break; // Ensure we don't go out of bounds
//
if ( fractalLows [ ArraySize ( fractalLows ) -1 ] > fractalLows [ ArraySize ( fractalLows ) - 2 ] )
{
higherLows = true ;
//break;
}
//}
2025-12-31 12:03:46 +03:00
2026-01-12 09:52:43 +03:00
//// Check the last n values for fractal lows
// for(int i = ArraySize(fractalHighs) - 1; i >= ArraySize(fractalHighs) - n; i--)
// {
// if(i <= 0)
// break; // Ensure we don't go out of bounds
//
if ( fractalHighs [ ArraySize ( fractalHighs ) -1 ] < fractalHighs [ ArraySize ( fractalHighs ) - 2 ] )
{
lowerHighs = true ;
//break;
}
//}
// Now higherHighs and lowerLows will reflect the result of checking the last n values
2025-12-31 12:03:46 +03:00
2026-01-12 09:52:43 +03:00
//
// ### Explanation:
// - **Loop Setup**: The loops iterate from the last element of the array to the element `n` positions back. This ensures that only the last `n` elements are checked.
// - **Boundary Check**: The `if(i <= 0) break;` statement ensures that the loop does not attempt to access an element before the start of the array, which would cause an out-of-bounds error.
// - **Condition Check**: The conditions inside the loops check if the current element is less than or greater than the previous one, updating the `higherHighs` and `lowerLows` flags accordingly.
// - **Flags**: The `higherHighs` and `lowerLows` flags are set to `true` initially and are only set to `false` if a condition is not met during the iteration. This means that if all conditions are met, the flags remain `true`.
//
// Determine and print the trend
if ( higherHighs & & lowerLows )
{
//Print("The fractals are making undefined moves (notrend).");
return " undefined " ;
}
else if ( higherHighs & & higherLows )
{
//Print("The fractals are making higher highs (uptrend).");
//Comment("BULL");
return " Bullish " ;
}
else if ( lowerLows & & lowerHighs )
{
//Print("The fractals are making lower lows (downtrend).");
//Comment("BEAR");
return " Bearish " ;
}
else
{
//Print("The fractals do not show a clear trend.");
//Comment("???");
return " unclear. " ;
}
}
2025-12-31 12:03:46 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double ArrayCountAverage ( double & array [ ] , int count )
{
double sum ;
double mean ;
//if (ArraySize(array) < count - 1);
//{
// Print("Array has less elements than required for mean" + ArraySize(array) + " count: " + (count-1));
//}
for ( int i = 0 ; i < count -1 ; i + + )
{
sum + = array [ i ] - array [ i + 1 ] ;
}
mean = sum / ( count -1 ) ;
Print ( " Derivative is: " + mean ) ;
return mean ;
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double meanEntryPrice ( string type )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double quantity = 0 ;
double volume = 0 ;
double entry = 0 ;
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
PositionGetTicket ( i ) ;
//////////////////////////////////
if ( type = = " Buy " & & PositionGetInteger ( POSITION_TYPE ) = = POSITION_TYPE_BUY & & PositionGetString ( POSITION_SYMBOL ) = = _Symbol )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
quantity = quantity + PosInfo . Volume ( ) * PosInfo . PriceOpen ( ) ;
volume = volume + PosInfo . Volume ( ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( type = = " Sell " & & PositionGetInteger ( POSITION_TYPE ) = = POSITION_TYPE_SELL & & PositionGetString ( POSITION_SYMBOL ) = = _Symbol )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
quantity = quantity + PosInfo . Volume ( ) * PosInfo . PriceOpen ( ) ;
volume = volume + PosInfo . Volume ( ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( type = = " Total " & & PositionGetString ( POSITION_SYMBOL ) = = _Symbol )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
quantity = quantity + PosInfo . Volume ( ) * PosInfo . PriceOpen ( ) ;
volume = volume + PosInfo . Volume ( ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( type = = " BuysAbove " & & PositionGetInteger ( POSITION_TYPE ) = = POSITION_TYPE_BUY & & PosInfo . PriceOpen ( ) > PosInfo . PriceCurrent ( ) & & PositionGetString ( POSITION_SYMBOL ) = = _Symbol )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
quantity = quantity + PosInfo . Volume ( ) * PosInfo . PriceOpen ( ) ;
volume = volume + PosInfo . Volume ( ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( type = = " BuysBelow " & & PositionGetInteger ( POSITION_TYPE ) = = POSITION_TYPE_BUY & & PosInfo . PriceOpen ( ) < PosInfo . PriceCurrent ( ) & & PositionGetString ( POSITION_SYMBOL ) = = _Symbol )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
quantity = quantity + PosInfo . Volume ( ) * PosInfo . PriceOpen ( ) ;
volume = volume + PosInfo . Volume ( ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
/////////////////////////////
if ( type = = " SellsAbove " & & PosInfo . PositionType ( ) = = POSITION_TYPE_SELL & & PosInfo . PriceOpen ( ) > PosInfo . PriceCurrent ( ) & & PositionGetString ( POSITION_SYMBOL ) = = _Symbol )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
quantity = quantity + PosInfo . Volume ( ) * PosInfo . PriceOpen ( ) ;
volume = volume + PosInfo . Volume ( ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( type = = " SellsBelow " & & PosInfo . PositionType ( ) = = POSITION_TYPE_SELL & & PosInfo . PriceOpen ( ) < PosInfo . PriceCurrent ( ) & & PositionGetString ( POSITION_SYMBOL ) = = _Symbol )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
quantity = quantity + PosInfo . Volume ( ) * PosInfo . PriceOpen ( ) ;
volume = volume + PosInfo . Volume ( ) ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
entry = quantity / volume ;
return entry ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double VolumeTotal ( string positionType )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double totalVolume = 0 ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) & & positionType = = " Buy " & & PosInfo . PositionType ( ) = = POSITION_TYPE_BUY )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
totalVolume + = PosInfo . Volume ( ) ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
//Print("BV: " + positionType + ": "+ totalVolume);
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) & & positionType = = " Sell " & & PosInfo . PositionType ( ) = = POSITION_TYPE_SELL )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
totalVolume + = PosInfo . Volume ( ) ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
//Print("SV: " + positionType + ": " + totalVolume);
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) & & positionType = = " Total " )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
totalVolume + = PosInfo . Volume ( ) ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
//Print("TV: " + positionType + ": " + totalVolume);
return totalVolume ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int FindIndices ( double value , double & arr [ ] , int & indexlow , int & indexhigh )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
int size = ArraySize ( arr ) ;
// Check if the array has at least two elements
if ( size < 2 )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Print ( " Array must have at least two elements. " ) ;
// return -1; // Return -1 to indicate an error
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
// Iterate through the array to find the indices
for ( int i = 0 ; i < size - 1 ; i + + )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( ( value > arr [ i ] & & value < arr [ i + 1 ] ) | | ( value < arr [ i ] & & value > arr [ i + 1 ] ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
indexlow = i ;
indexhigh = i + 1 ;
return 0 ; // Return 0 to indicate success
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
// If no such indices are found
Print ( " No indices found where the value is between two consecutive elements. " ) ;
return -1 ; // Return -1 to indicate failure
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
void CalculateVolumeDistribution ( int Days , double levelStep , double & volumeArray [ ] , double & priceLevelArray [ ] )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
// Determine the number of bars in two full days
int barsInFullDay = 1440 ; // 1440 minutes in a day
int barsInDays = Days * barsInFullDay ;
// Calculate the number of bars that have elapsed today
datetime currentTime = TimeCurrent ( ) ;
datetime startOfDay = currentTime - ( currentTime % 86400 ) ; // Start of the current day
int barsElapsedToday = ( int ) ( ( currentTime - startOfDay ) / 60 ) ; // Convert seconds to minutes
// Total lookback bars
int lookbackBars = barsInDays + barsElapsedToday ;
// Initialize variables to store the lowest low and highest high
double lowestLow = 0 ;
double highestHigh = 0 ;
// Arrays to store the data
double lowArray [ ] ;
double highArray [ ] ;
long volumeArrayRaw [ ] ;
// Copy the data for the specified number of bars
if ( CopyLow ( _Symbol , PERIOD_M1 , 0 , lookbackBars , lowArray ) < = 0 | |
2025-12-26 17:12:21 +03:00
CopyHigh ( _Symbol , PERIOD_M1 , 0 , lookbackBars , highArray ) < = 0 | |
CopyTickVolume ( _Symbol , PERIOD_M1 , 0 , lookbackBars , volumeArrayRaw ) < = 0 )
{
2025-12-21 23:44:47 +03:00
Print ( " Error copying data " ) ;
return ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
// Loop through the lookback period to find the lowest low and highest high
for ( int i = 0 ; i < lookbackBars ; i + + )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double low = lowArray [ i ] ;
double high = highArray [ i ] ;
if ( ( low ! = 0 & & low < lowestLow ) | | lowestLow = = 0 )
lowestLow = low ;
if ( high > highestHigh )
highestHigh = high ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
Print ( " Lowest Level: " , lowestLow ) ;
Print ( " Highest Level: " , highestHigh ) ;
// Calculate the number of levels
int numberOfLevels = int ( ( highestHigh - lowestLow ) / levelStep ) + 1 ;
// Resize the arrays to hold the data
ArrayResize ( volumeArray , numberOfLevels ) ;
ArrayResize ( priceLevelArray , numberOfLevels ) ;
// Initialize arrays
for ( int i = 0 ; i < numberOfLevels ; i + + )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
volumeArray [ i ] = 0 ;
priceLevelArray [ i ] = lowestLow + i * levelStep ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
// Aggregate volume for each level
for ( int i = 0 ; i < lookbackBars ; i + + )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double low = lowArray [ i ] ;
double high = highArray [ i ] ;
double volume = ( double ) volumeArrayRaw [ i ] ;
// Determine which levels the current bar's range covers
int startLevel = int ( ( low - lowestLow ) / levelStep ) ;
int endLevel = int ( ( high - lowestLow ) / levelStep ) ;
// Distribute volume across the levels covered by the bar
for ( int level = startLevel ; level < = endLevel ; level + + )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( level > = 0 & & level < numberOfLevels )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
volumeArray [ level ] + = volume ;
//Print("Level: ", level, " Volume: ", volumeArray[level]);
2025-12-26 17:12:21 +03:00
}
}
}
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int ArrayPeaks ( const double & array [ ] , int & peaks [ ] , double min_distance )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
int LevelsToCheck = Grid ;
int array_size = ArraySize ( array ) ;
if ( array_size < LevelsToCheck )
return 0 ; // Return 0 if the array is too small to have peaks
int peak_count = 0 ;
ArrayResize ( peaks , array_size ) ; // Resize peaks array to the maximum possible size initially
// Iterate through the array to find peaks
for ( int i = ( int ) ( LevelsToCheck / 2 ) ; i < array_size - ( int ) ( LevelsToCheck / 2 ) ; i + + ) // Start from level index and end at array_size - level index
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
bool is_peak = true ;
// Check if the current element is greater than the elements in the range of indices around it
for ( int j = i - ( int ) ( LevelsToCheck / 2 ) ; j < = i + ( int ) ( LevelsToCheck / 2 ) ; j + + )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( j ! = i & & array [ i ] < = array [ j ] )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
is_peak = false ;
break ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( is_peak )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
bool is_far_enough = true ;
for ( int j = 0 ; j < peak_count ; j + + )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( MathAbs ( i - peaks [ j ] ) < min_distance )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
is_far_enough = false ;
break ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
if ( is_far_enough )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
peaks [ peak_count ] = i ;
peak_count + + ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
ArrayResize ( peaks , peak_count ) ; // Resize peaks array to the actual number of peaks found
return peak_count ; // Return the number of peaks found
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CalculateValueArea ( const double & priceLevels [ ] , const double & volumes [ ] , double & valAreaHigh , double & valAreaLow , double percentage = 70.0 )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
int size = ArraySize ( volumes ) ;
if ( size < = 0 | | size ! = ArraySize ( priceLevels ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
//Print("Array Issue: Price Levels and Volumes don't match or are empty.");
return ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
// Calculate total volume
double totalVolume = 0.0 ;
for ( int i = 0 ; i < size ; i + + )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
totalVolume + = volumes [ i ] ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
// Target volume for the value area
double targetVolume = totalVolume * ( percentage / 100.0 ) ;
// Find the POC
int pocIndex = 0 ;
double maxVolume = volumes [ 0 ] ;
for ( int i = 1 ; i < size ; i + + )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( volumes [ i ] > maxVolume )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
maxVolume = volumes [ i ] ;
pocIndex = i ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
// Initialize the value area with the POC
valAreaLow = priceLevels [ pocIndex ] ;
valAreaHigh = priceLevels [ pocIndex ] ;
double cumulativeVolume = maxVolume ;
// Expand the value area around the POC
int leftIndex = pocIndex - 1 ;
int rightIndex = pocIndex + 1 ;
while ( cumulativeVolume < targetVolume )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
// Consider both directions and choose the one with larger volume
if ( leftIndex > = 0 & & ( rightIndex > = size | | volumes [ leftIndex ] > = volumes [ rightIndex ] ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
cumulativeVolume + = volumes [ leftIndex ] ;
valAreaLow = priceLevels [ leftIndex ] ;
leftIndex - - ;
2025-12-26 17:12:21 +03:00
}
else if ( rightIndex < size )
{
cumulativeVolume + = volumes [ rightIndex ] ;
valAreaHigh = priceLevels [ rightIndex ] ;
rightIndex + + ;
}
2025-12-21 23:44:47 +03:00
else
2025-12-26 17:12:21 +03:00
{
// No more price levels to consider
break ;
}
}
}
2025-12-21 23:44:47 +03:00
////////////////CLOSING FUNCTIONS////////////////////////////////////
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseAllPositions ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
if ( PosInfo . SelectByIndex ( i ) ) // select a position
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
trade . PositionClose ( PosInfo . Ticket ( ) ) ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CancelLimits ( string comment )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
for ( int i = OrdersTotal ( ) -1 ; i > = 0 ; i - - )
if ( OrdInfo . SelectByIndex ( i ) & & PosInfo . Comment ( ) = = comment )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
trade . OrderDelete ( OrdInfo . Ticket ( ) ) ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseByWinning ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_BUY )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double thebuy = PosInfo . PriceOpen ( ) ;
int theBuyTicket = PosInfo . Ticket ( ) ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - )
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_SELL )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double thesell = PosInfo . PriceOpen ( ) ;
int theSellTicket = PosInfo . Ticket ( ) ;
if ( thesell - thebuy > 0 )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
trade . PositionCloseBy ( theBuyTicket , theSellTicket ) ;
2025-12-26 17:12:21 +03:00
}
}
}
}
}
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseByLosing ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
if ( PosInfo . SelectByIndex ( i ) & & PosInfo . PositionType ( ) = = POSITION_TYPE_BUY )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double thebuy = PosInfo . PriceOpen ( ) ;
int theBuyTicket = PosInfo . Ticket ( ) ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - )
if ( PosInfo . SelectByIndex ( i ) & & PosInfo . PositionType ( ) = = POSITION_TYPE_SELL )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double thesell = PosInfo . PriceOpen ( ) ;
int theSellTicket = PosInfo . Ticket ( ) ;
if ( thesell - thebuy < - Grid * _Point )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
trade . PositionCloseBy ( theBuyTicket , theSellTicket ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseByWin ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
int profitTicket ;
double profit ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_BUY )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . Profit ( ) > profit )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
profit = PosInfo . Profit ( ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
double thebuy = PosInfo . PriceOpen ( ) ;
int theBuyTicket = PosInfo . Ticket ( ) ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - )
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_SELL )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double thesell = PosInfo . PriceOpen ( ) ;
int theSellTicket = PosInfo . Ticket ( ) ;
if ( thesell - thebuy > 0 )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
trade . PositionCloseBy ( theBuyTicket , theSellTicket ) ;
2025-12-26 17:12:21 +03:00
}
}
}
}
}
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseByLoss ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
if ( PosInfo . SelectByIndex ( i ) & & PosInfo . PositionType ( ) = = POSITION_TYPE_BUY )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double thebuy = PosInfo . PriceOpen ( ) ;
int theBuyTicket = PosInfo . Ticket ( ) ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - )
if ( PosInfo . SelectByIndex ( i ) & & PosInfo . PositionType ( ) = = POSITION_TYPE_SELL )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double thesell = PosInfo . PriceOpen ( ) ;
int theSellTicket = PosInfo . Ticket ( ) ;
if ( thesell - thebuy < - Grid * _Point )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
trade . PositionCloseBy ( theBuyTicket , theSellTicket ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseWinners ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . Profit ( ) > 0 )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
int Ticket = PosInfo . Ticket ( ) ;
trade . PositionClose ( Ticket ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseLosers ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . Profit ( ) < 0 )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
int Ticket = PosInfo . Ticket ( ) ;
trade . PositionClose ( Ticket ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseBuyWin ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double Profit ;
int ProfitTicket ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_BUY & & PosInfo . Profit ( ) > Profit & & PosInfo . Profit ( ) > 0 )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Profit = PosInfo . Profit ( ) ;
ProfitTicket = PosInfo . Ticket ( ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
trade . PositionClose ( ProfitTicket ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseSellWin ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double Profit ;
int ProfitTicket ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_SELL & & PosInfo . Profit ( ) > Profit & & PosInfo . Profit ( ) > 0 )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Profit = PosInfo . Profit ( ) ;
ProfitTicket = PosInfo . Ticket ( ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
trade . PositionClose ( ProfitTicket ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseBuyLoss ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double Profit ;
int ProfitTicket ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_BUY & & PosInfo . Profit ( ) < Profit & & PosInfo . Profit ( ) < 0 )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Profit = PosInfo . Profit ( ) ;
ProfitTicket = PosInfo . Ticket ( ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
trade . PositionClose ( ProfitTicket ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double HighestBuy ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double Price = 0 ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_BUY & & PosInfo . PriceOpen ( ) > Price )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Price = PosInfo . PriceOpen ( ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
return Price ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double HighestSell ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double Price = 0 ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_SELL & & PosInfo . PriceOpen ( ) > Price )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Price = PosInfo . PriceOpen ( ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
return Price ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double LowestBuy ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double Price = 2 ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_BUY & & PosInfo . PriceOpen ( ) < Price )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Price = PosInfo . PriceOpen ( ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
return Price ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double LowestSell ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double Price = 2 ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_SELL & & PosInfo . PriceOpen ( ) < Price )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Price = PosInfo . PriceOpen ( ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
return Price ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseSellLoss ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double Profit ;
int ProfitTicket ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_SELL & & PosInfo . Profit ( ) < Profit & & PosInfo . Profit ( ) < 0 )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Profit = PosInfo . Profit ( ) ;
ProfitTicket = PosInfo . Ticket ( ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
trade . PositionClose ( ProfitTicket ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void MAStopLoss ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
int ProfitTicket ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_BUY & & PosInfo . PriceOpen ( ) > MAHigh [ 0 ] & & PosInfo . PriceCurrent ( ) < MALow [ 0 ] )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
ProfitTicket = PosInfo . Ticket ( ) ;
trade . PositionClose ( ProfitTicket ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( PosInfo . PositionType ( ) = = POSITION_TYPE_SELL & & PosInfo . PriceOpen ( ) < MALow [ 0 ] & & PosInfo . PriceCurrent ( ) > MAHigh [ 0 ] )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
ProfitTicket = PosInfo . Ticket ( ) ;
trade . PositionClose ( ProfitTicket ) ;
2025-12-26 17:12:21 +03:00
}
}
}
}
2025-12-21 23:44:47 +03:00
///////////////////POSITIONS CHECK/////////////////////////
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool OtherBuyPosition ( string comment )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
bool other = false ;
for ( int i = PositionsTotal ( ) ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
ulong ticket = PositionGetTicket ( i ) ;
if ( PosInfo . SelectByTicket ( ticket ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double currentPrice = PosInfo . PriceCurrent ( ) ;
double openPrice = PosInfo . PriceOpen ( ) ;
if ( MathAbs ( currentPrice - openPrice ) < Grid_step_buy * _Point & & PosInfo . PositionType ( ) = = POSITION_TYPE_BUY & & ( comment = = PosInfo . Comment ( ) | | comment = = NULL ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
other = true ;
break ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
else
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
other = false ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
return other ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool OtherSellPosition ( string comment )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
bool other = false ;
for ( int i = PositionsTotal ( ) ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
ulong ticket = PositionGetTicket ( i ) ;
if ( PosInfo . SelectByTicket ( ticket ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double currentPrice = PosInfo . PriceCurrent ( ) ;
double openPrice = PosInfo . PriceOpen ( ) ;
if ( MathAbs ( currentPrice - openPrice ) < Grid_step_sell * _Point & & PosInfo . PositionType ( ) = = POSITION_TYPE_SELL & & ( comment = = PosInfo . Comment ( ) | | comment = = NULL ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
other = true ;
break ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
else
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
other = false ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
return other ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseBuys ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
if ( PosInfo . SelectByIndex ( i ) & & PosInfo . PositionType ( ) = = POSITION_TYPE_BUY )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double thebuy = PosInfo . PriceOpen ( ) ;
int theBuyTicket = PosInfo . Ticket ( ) ;
trade . PositionClose ( theBuyTicket ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseSells ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
if ( PosInfo . SelectByIndex ( i ) & & PosInfo . PositionType ( ) = = POSITION_TYPE_SELL )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double thesell = PosInfo . PriceOpen ( ) ;
int theSellTicket = PosInfo . Ticket ( ) ;
trade . PositionClose ( theSellTicket ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseBuy ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double Profit ;
int theBuyTicket = PosInfo . Ticket ( ) ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) & & PosInfo . PositionType ( ) = = POSITION_TYPE_BUY )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( Profit > PosInfo . Profit ( ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Profit = PosInfo . Profit ( ) ;
theBuyTicket = PosInfo . Ticket ( ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
trade . PositionClose ( theBuyTicket ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseSell ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double Profit ;
int theSellTicket = PosInfo . Ticket ( ) ;
for ( int i = PositionsTotal ( ) - 1 ; i > = 0 ; i - - ) // loop all Open Positions
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( PosInfo . SelectByIndex ( i ) & & PosInfo . PositionType ( ) = = POSITION_TYPE_SELL )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( Profit > PosInfo . Profit ( ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Profit = PosInfo . Profit ( ) ;
theSellTicket = PosInfo . Ticket ( ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
trade . PositionClose ( theSellTicket ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Trailing ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
// if(PositionGetInteger(POSITION_MAGIC) == 444444)//adding magic number, if you want you can delete this if you don't want to use magic number
// {
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
// string symbol = PositionGetSymbol(i);
ulong PositionTicket = PositionGetTicket ( i ) ;
long trade_type = PositionGetInteger ( POSITION_TYPE ) ;
if ( trade_type = = 0 ) // && (PositionGetString(POSITION_COMMENT) == "BuyLimit" || PositionGetString(POSITION_COMMENT) == "BuyGrid"))
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( bid > PositionGetDouble ( POSITION_PRICE_OPEN ) + NormalizeDouble ( _Point * Grid , _Digits ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
trade . PositionModify ( PositionTicket , NormalizeDouble ( PositionGetDouble ( POSITION_PRICE_OPEN ) + Grid * _Point , _Digits ) , PositionGetDouble ( POSITION_TP ) ) ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
if ( trade_type = = 1 ) // && (PositionGetString(POSITION_COMMENT) == "SellLimit"|| PositionGetString(POSITION_COMMENT) == "SellGrid"))
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
if ( ask < PositionGetDouble ( POSITION_PRICE_OPEN ) - NormalizeDouble ( _Point * Grid , _Digits ) )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
trade . PositionModify ( PositionTicket , NormalizeDouble ( PositionGetDouble ( POSITION_PRICE_OPEN ) - Grid * _Point , _Digits ) , PositionGetDouble ( POSITION_TP ) ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void TPmodify ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
// if(PositionGetInteger(POSITION_MAGIC) == 444444)//adding magic number, if you want you can delete this if you don't want to use magic number
// {
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
ulong PositionTicket = PositionGetTicket ( i ) ;
long trade_type = PositionGetInteger ( POSITION_TYPE ) ;
if ( trade_type = = 0 & & PosInfo . TakeProfit ( ) ! = meanEntryPriceBuy ( ) + TakeProfitFactor * Grid * _Point & & BuyPositionsCount ( ) > PositionsThreshold )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
trade . PositionModify ( PositionTicket , PositionGetDouble ( POSITION_SL ) , PositionGetDouble ( POSITION_PRICE_OPEN ) + TakeProfitFactor * Grid * _Point ) ;
if ( PosInfo . PriceCurrent ( ) > meanEntryPriceBuy ( ) + Grid * _Point )
CloseBuys ( ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( trade_type = = 1 & & PosInfo . TakeProfit ( ) ! = meanEntryPriceSell ( ) - TakeProfitFactor * Grid * _Point & & SellPositionsCount ( ) > PositionsThreshold )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
trade . PositionModify ( PositionTicket , PositionGetDouble ( POSITION_SL ) , PositionGetDouble ( POSITION_PRICE_OPEN ) - TakeProfitFactor * Grid * _Point ) ;
if ( PosInfo . PriceCurrent ( ) < meanEntryPriceSell ( ) - Grid * _Point )
CloseSells ( ) ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void breakEven ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2026-01-12 09:52:43 +03:00
double meanEntryBuy = meanEntryPriceBuy ( ) ;
double meanEntrySell = meanEntryPriceSell ( ) ;
2025-12-21 23:44:47 +03:00
ulong PositionTicket = PositionGetTicket ( i ) ;
long trade_type = PositionGetInteger ( POSITION_TYPE ) ;
2026-01-12 09:52:43 +03:00
2025-12-21 23:44:47 +03:00
if ( trade_type = = 0 )
2026-01-12 09:52:43 +03:00
if ( meanEntryBuy < ask - Grid * _Point & & ( PosInfo . StopLoss ( ) < meanEntryBuy | | PosInfo . StopLoss ( ) = = 0 ) )
2025-12-26 17:12:21 +03:00
{
2026-01-12 09:52:43 +03:00
trade . PositionModify ( PositionTicket , meanEntryBuy + 150 * _Point , PositionGetDouble ( POSITION_TP ) ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( trade_type = = 1 )
2026-01-12 09:52:43 +03:00
if ( meanEntrySell > bid + Grid * _Point & & ( PosInfo . StopLoss ( ) > meanEntrySell | | PosInfo . StopLoss ( ) = = 0 ) )
2025-12-26 17:12:21 +03:00
{
2026-01-12 09:52:43 +03:00
trade . PositionModify ( PositionTicket , meanEntrySell - 150 * _Point , PositionGetDouble ( POSITION_TP ) ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void slStepUp ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
ulong PositionTicket = PositionGetTicket ( i ) ;
long trade_type = PositionGetInteger ( POSITION_TYPE ) ;
if ( trade_type = = 0 & & PosInfo . StopLoss ( ) > PosInfo . PriceOpen ( ) ) // && (PositionGetString(POSITION_COMMENT) == "BuyLimit" || PositionGetString(POSITION_COMMENT) == "BuyGrid"))
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
trade . PositionModify ( PositionTicket , NormalizeDouble ( PositionGetDouble ( POSITION_SL ) + Grid * _Point , _Digits ) , PositionGetDouble ( POSITION_TP ) ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void slStepDown ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
ulong PositionTicket = PositionGetTicket ( i ) ;
long trade_type = PositionGetInteger ( POSITION_TYPE ) ;
if ( trade_type = = 1 & & PosInfo . StopLoss ( ) < PosInfo . PriceOpen ( ) ) // && (PositionGetString(POSITION_COMMENT) == "BuyLimit" || PositionGetString(POSITION_COMMENT) == "BuyGrid"))
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
trade . PositionModify ( PositionTicket , NormalizeDouble ( PositionGetDouble ( POSITION_SL ) - Grid * _Point , _Digits ) , PositionGetDouble ( POSITION_TP ) ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void StoplossUpdate ( string comment )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
2025-12-31 12:03:46 +03:00
int buyCount = BuyPositionsCount ( ) ;
int sellCount = SellPositionsCount ( ) ;
2025-12-21 23:44:47 +03:00
double meanEntryBuy = meanEntryPriceBuy ( ) ;
double meanEntrySell = meanEntryPriceSell ( ) ;
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
ulong PositionTicket = PositionGetTicket ( i ) ;
long trade_type = PositionGetInteger ( POSITION_TYPE ) ;
double newStopLoss ;
if ( trade_type = = 0 & & comment = = " buy " )
2025-12-26 17:12:21 +03:00
{
2025-12-31 16:18:24 +03:00
if ( ask < meanEntryBuy + TakeProfitFactor * Grid * _Point )
newStopLoss = StopLossBuy ;
2025-12-26 17:12:21 +03:00
if ( ask > meanEntryBuy + TakeProfitFactor * Grid * _Point )
2025-12-31 16:18:24 +03:00
newStopLoss = NormalizeDouble ( ( ( ( ask + meanEntryBuy ) / 2 ) + ask ) / 2 , _Digits ) ;
if ( PositionGetDouble ( POSITION_SL ) < newStopLoss )
trade . PositionModify ( PositionTicket , newStopLoss , PositionGetDouble ( POSITION_TP ) ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( trade_type = = 1 & & comment = = " sell " )
2025-12-26 17:12:21 +03:00
{
2025-12-31 16:18:24 +03:00
if ( bid > meanEntrySell - TakeProfitFactor * Grid * _Point )
newStopLoss = StopLossSell ;
2025-12-26 17:12:21 +03:00
if ( bid < meanEntrySell - TakeProfitFactor * Grid * _Point )
2025-12-31 16:18:24 +03:00
newStopLoss = NormalizeDouble ( ( ( ( bid + meanEntrySell ) / 2 ) + bid ) / 2 , _Digits ) ;
if ( PositionGetDouble ( POSITION_SL ) > newStopLoss | | PositionGetDouble ( POSITION_SL ) = = 0 )
trade . PositionModify ( PositionTicket , newStopLoss , PositionGetDouble ( POSITION_TP ) ) ;
2025-12-26 17:12:21 +03:00
}
}
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string crossOver ( double & Array1 [ ] , double & Array2 [ ] )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
string crossOver ;
if ( Array1 [ 1 ] > Array2 [ 1 ] & & Array1 [ 2 ] < Array2 [ 2 ] )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
crossOver = " up " ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( Array1 [ 1 ] < Array2 [ 1 ] & & Array1 [ 2 ] > Array2 [ 2 ] )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
crossOver = " down " ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
else
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
crossOver = NULL ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
return ( crossOver ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int BuyPositionsCount ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
int Buys = 0 ;
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
PositionGetTicket ( i ) ;
if ( PositionGetInteger ( POSITION_TYPE ) = = POSITION_TYPE_BUY & & PositionGetString ( POSITION_SYMBOL ) = = _Symbol )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Buys = Buys + 1 ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
return Buys ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int SellPositionsCount ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
int Sells = 0 ;
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
PositionGetTicket ( i ) ;
if ( PositionGetInteger ( POSITION_TYPE ) = = POSITION_TYPE_SELL & & PositionGetString ( POSITION_SYMBOL ) = = _Symbol )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
Sells = Sells + 1 ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
return Sells ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void SLmodify ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
// if(PositionGetInteger(POSITION_MAGIC) == 444444)//adding magic number, if you want you can delete this if you don't want to use magic number
// {
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
ulong PositionTicket = PositionGetTicket ( i ) ;
long trade_type = PositionGetInteger ( POSITION_TYPE ) ;
if ( trade_type = = 0
2025-12-26 17:12:21 +03:00
& & PosInfo . PriceCurrent ( ) > meanEntryPriceBuy ( ) + ( 0.5 * Grid * _Point )
& & ( PositionGetDouble ( POSITION_SL ) < PosInfo . PriceCurrent ( ) - ( ( LowestBuy ( ) + 0.5 * Grid * _Point ) - meanEntryPriceBuy ( ) ) | | PositionGetDouble ( POSITION_SL ) = = 0 ) )
{
2025-12-21 23:44:47 +03:00
trade . PositionModify ( PositionTicket , PosInfo . PriceCurrent ( ) - ( ( LowestBuy ( ) + 0.5 * Grid * _Point ) - meanEntryPriceBuy ( ) ) , PositionGetDouble ( POSITION_TP ) ) ;
Print ( " Lowest buy: " + LowestBuy ( ) ) ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
if ( trade_type = = 1
2025-12-26 17:12:21 +03:00
& & PosInfo . PriceCurrent ( ) < meanEntryPriceSell ( ) - ( 0.5 * Grid * _Point )
& & ( PositionGetDouble ( POSITION_SL ) > PosInfo . PriceCurrent ( ) - ( ( HighestSell ( ) - 0.5 * Grid * _Point ) - meanEntryPriceSell ( ) ) | | PositionGetDouble ( POSITION_SL ) = = 0 ) )
{
2025-12-21 23:44:47 +03:00
trade . PositionModify ( PositionTicket , PosInfo . PriceCurrent ( ) - ( ( HighestSell ( ) - 0.5 * Grid * _Point ) - meanEntryPriceSell ( ) ) , PositionGetDouble ( POSITION_TP ) ) ;
Print ( " highest sell: " + HighestSell ( ) ) ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double meanEntryPriceBuy ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double price = 0 ;
double volume = 0 ;
double entry ;
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
PositionGetTicket ( i ) ;
if ( PositionGetInteger ( POSITION_TYPE ) = = POSITION_TYPE_BUY & & PositionGetString ( POSITION_SYMBOL ) = = _Symbol )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
price = price + PosInfo . Volume ( ) * PosInfo . PriceOpen ( ) ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
PositionGetTicket ( i ) ;
if ( PositionGetInteger ( POSITION_TYPE ) = = POSITION_TYPE_BUY & & PositionGetString ( POSITION_SYMBOL ) = = _Symbol )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
volume = volume + PosInfo . Volume ( ) ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
entry = price / volume ;
return entry ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double meanEntryPriceSell ( )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
double price = 0 ;
double volume = 0 ;
double entry ;
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
PositionGetTicket ( i ) ;
if ( PositionGetInteger ( POSITION_TYPE ) = = POSITION_TYPE_SELL & & PositionGetString ( POSITION_SYMBOL ) = = _Symbol )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
price = price + PosInfo . Volume ( ) * PosInfo . PriceOpen ( ) ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
for ( int i = PositionsTotal ( ) -1 ; i > = 0 ; i - - )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
PositionGetTicket ( i ) ;
if ( PositionGetInteger ( POSITION_TYPE ) = = POSITION_TYPE_SELL & & PositionGetString ( POSITION_SYMBOL ) = = _Symbol )
2025-12-26 17:12:21 +03:00
{
2025-12-21 23:44:47 +03:00
volume = volume + PosInfo . Volume ( ) ;
2025-12-26 17:12:21 +03:00
}
}
2025-12-21 23:44:47 +03:00
entry = price / volume ;
return entry ;
2025-12-26 17:12:21 +03:00
}
2025-12-21 23:44:47 +03:00
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+