mql5/Experts/Scale Rev with Mkt Struct.mq5
abel324d 0379b1a968
2026-01-29 11:56:59 +03:00

1862 行
61 KiB
MQL5

//+------------------------------------------------------------------+
//| 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//////////////
enum Side
{
Buy=0, // Buy
Sell=1, // Sell
Both=2, // Both
};
input double FixedLot=0.01; // Fixed Lot
input Side EntrySide = 2;
input double TakeProfitFactor=2;
double StopLossFactor=3;
input ushort Grid=250; // Grid Distance
//input double CloseTreshold=1.05;
//input double FreeMarginThreshold=0.3;
//input double EquityStopLossPercent=0.9;
input int PositionsThreshold=2;
input double stDev = 1; // deviation
int MALength = 12;
input int bandsLength = 18;
int ATR1Length = 12;
int ATR2Length = 12;
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;// Entry Time Frame
input ENUM_TIMEFRAMES MktStTimeFrame = PERIOD_M5;// Market Structure Time Frame
////////////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,
MA[], MAData, MAHandle, Momentum[], MomentumData, MomentumHandle,
bands[],bandsupper[],bandslower[], bandsHandle, bandsData,
MFI[], MFIData, MFIHandle,
ATR1[], ATR2[], ATR1Data, ATR2Data, ATR1Handle, ATR2Handle;
double ask, bid, tradeVolume,
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;
bool activateSL = false, buyStopSwitch = false, sellStopSwitch = false, buyLimitSwitch = false, sellLimitSwitch = false;
MqlRates Bar1[], Bar2[];
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
// 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);
bandsHandle = iBands(_Symbol,TimeFrame,bandsLength,0,stDev,PRICE_TYPICAL);
//ATR1Handle = iATR(_Symbol,TimeFrame,ATR1Length);
//ATR2Handle = iATR(_Symbol,PERIOD_H1,ATR2Length);
MomentumHandle = iMomentum(_Symbol,TimeFrame,21,PRICE_MEDIAN);
ArraySetAsSeries(MFI,true);
ArraySetAsSeries(ATR1,true);
ArraySetAsSeries(ATR2,true);
ArraySetAsSeries(MAHigh,true);
ArraySetAsSeries(MA,true);
ArraySetAsSeries(MALow,true);
ArraySetAsSeries(bands,true);
ArraySetAsSeries(bandsupper,true);
ArraySetAsSeries(bandslower,true);
ArraySetAsSeries(Bar1, true);
ArraySetAsSeries(Bar2, true);
ArraySetAsSeries(Momentum, true);
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);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//CloseByWin();
//Trailing();
//breakEven();
//TPmodify();
tradeVolume = iVolume(_Symbol,PERIOD_H1,0);
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);
ATR1Data = CopyBuffer(ATR1Handle,0,0,15,ATR1);
ATR2Data = CopyBuffer(ATR2Handle,0,0,15,ATR2);
bandsData = CopyBuffer(bandsHandle,0,0,4,bands);
bandsData = CopyBuffer(bandsHandle,1,0,4,bandsupper);
bandsData = CopyBuffer(bandsHandle,2,0,4,bandslower);
MomentumData = CopyBuffer(MomentumHandle,0,0,4,Momentum);
CopyRates(_Symbol,TimeFrame,0,10,Bar1);
CopyRates(_Symbol,MktStTimeFrame,0,10,Bar2);
// TakeProfitBuy = bid+Grid_step*TakeProfitFactor*_Point;
// TakeProfitSell = ask-Grid_step*TakeProfitFactor*_Point;
StopLossBuy = bands[1];
StopLossSell = bands[1];
//////////////////// Factors //////////////////////////////////
if(BuyPositionsCount() != 0)
buyVolumeFactor = NormalizeDouble(MathPow(Vol_Mul,BuyPositionsCount()),0);
else
{
buyVolumeFactor = 1;
// Grid_step = Grid;
}
if(SellPositionsCount() != 0)
sellVolumeFactor = NormalizeDouble(MathPow(Vol_Mul,SellPositionsCount()),0);
else
{
sellVolumeFactor = 1;
}
if(PositionsTotal() < 1)
{
Grid_step_buy = Grid;
Grid_step_sell = Grid;
}
//int babar = 0;
//Comment(tradeVolume);
// if(babar < iBars(_Symbol,MktStTimeFrame))
// {
// IdentifyFractalLevels(100,1,MktStTimeFrame);
//
// babar = iBars(_Symbol,MktStTimeFrame);
// }
///////////////////BALANCEGRID//////////////////////////////////
string expire_date = "2026.02.14"; //<-- hard coded datetime
datetime e_d = StringToTime(expire_date);
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)));
//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));
if(TimeCurrent() <= e_d) //spread<1500*_Point){
{
Grid_step_buy = Grid * MathPow(Grid_mul, BuyPositionsCount());
Grid_step_sell = Grid * MathPow(Grid_mul, SellPositionsCount());
buyVolumeFactor = MathPow(Vol_Mul,BuyPositionsCount());
sellVolumeFactor = MathPow(Vol_Mul,SellPositionsCount());
buyVolume = NormalizeDouble(equityVolume*buyVolumeFactor*FixedLot,2);
sellVolume = NormalizeDouble(equityVolume*sellVolumeFactor*FixedLot,2);
//double meanATR1 = ArrayCountAverage(ATR1,3);
//double meanATR2 = ArrayCountAverage(ATR2,3);
//Print("bands: " + bands[1]);
//Comment("\MATR~1: " + meanATR1 + "MATR~2 " + meanATR2);
//--- BuyLimit
if(ask < nextDownBuy)
{
buyLimitSwitch = true;
currentDownBuy = nextDownBuy;
nextUpBuy = ask + Grid_step_buy*_Point;
nextDownBuy = bid - Grid_step_buy*_Point;
}
//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;
// }
//--- BuyStop
if(ask > nextUpBuy)
{
buyStopSwitch = true;
currentUpBuy = nextUpBuy;
nextUpBuy = ask + Grid_step_buy*_Point;
nextDownBuy = ask - Grid_step_buy*_Point;
}
if( tradeVolume > 10000 && tradetime && (EntrySide == 2 || EntrySide == 0) && buyStopSwitch && currentUpBuy - 5*_Point && !OtherBuyPosition(NULL) && ask > bandsupper[1] )
//&& Bar1[1].high > Bar1[2].highCheckFractalTrend(10) == "Bullish" &&
{
trade.Buy(buyVolume,_Symbol,0,StopLossBuy,TakeProfitBuy,"BuyStop");
buyStopSwitch = false;
}
//--- SellLimit
if(bid > nextUpSell)
{
sellLimitSwitch = true;
currentUpSell = nextUpSell;
nextUpSell = bid + Grid_step_sell*_Point;
nextDownSell = bid - Grid_step_sell*_Point;
}
//if((CheckFractalTrend(10) != "Bullish" && CheckFractalTrend(1) != "Bearish") && tradetime && (EntrySide == 2 || EntrySide == 1) && sellLimitSwitch && currentUpSell - 100*_Point && !OtherSellPosition(NULL) && bid > bands[1] && bid < bandsupper[0])
//{
// trade.Sell(sellVolume,_Symbol,0,StopLossSell,TakeProfitSell,"SellLimit");
// sellLimitSwitch = false;
//}
//--- SellStop
if(bid < nextDownSell)// && bid > currentDownSell + 10*_Point && ask < currentUpBuyStop - 10*_Point
{
sellStopSwitch = true;
currentDownSell = nextDownSell;
nextUpSell = bid + Grid_step_sell*_Point;
nextDownSell = bid - Grid_step_sell*_Point;
}
if( tradeVolume > 10000 && tradetime && (EntrySide == 2 || EntrySide == 1) && sellStopSwitch && currentDownSell + 5*_Point && !OtherSellPosition(NULL) && bid < bandslower[1] )
//&& Bar1[1].low < Bar1[2].lowCheckFractalTrend(10) == "Bearish" &&
{
trade.Sell(sellVolume,_Symbol,0,StopLossSell,TakeProfitSell,"SellStop");
sellStopSwitch = false;
}
}
else
{
Comment("Your license is expired!");
}
//////////////////////CLOSERS//////////////////////////////////////////////
//if(tradeVolume < 8000)
// {
StoplossUpdate("buy");
StoplossUpdate("sell");
//}
if(Account.Equity() > maxEquity && PositionsTotal() < 2)
{
maxEquity = Account.Equity();
//equityVolume = MathCeil(maxEquity/10000);
//if(VolumeTotal("Total") > StartingBalance/1000)
//{
// CloseAllPositions();
//}
}
if(Account.Equity() >= 1.01*maxEquity)
{
activateSL = true;
maxEquity = Account.Equity();
}
if(activateSL && Account.Equity() <= 1/(1.01)*maxEquity)
{
activateSL = false;
//CloseAllPositions();
}
}
//+------------------------------------------------------------------+
//| Trade function |
//+------------------------------------------------------------------+
void OnTrade()
{
//---
}
/// 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;
}
//}
//// 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
//
// ### 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).");
//Comment("?????");
return "undefined";
}
if(higherHighs && higherLows)
{
//Print("The fractals are making higher highs (uptrend).");
//Comment("BULL");
return "Bullish";
}
if(lowerLows && lowerHighs)
{
//Print("The fractals are making lower lows (downtrend).");
//Comment("BEAR");
return "Bearish";
}
if(lowerHighs && higherLows)
{
//Print("The fractals do not show a clear trend.");
//Comment("???");
return "unclear.";
}
return 0;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
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;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double meanEntryPrice(string type)
{
double quantity = 0;
double volume = 0;
double entry = 0;
for(int i = PositionsTotal()-1; i>=0; i--)
{
PositionGetTicket(i);
//////////////////////////////////
if(type == "Buy" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
volume = volume + PosInfo.Volume();
}
if(type == "Sell" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
volume = volume + PosInfo.Volume();
}
if(type == "Total" && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
volume = volume + PosInfo.Volume();
}
if(type == "BuysAbove" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PosInfo.PriceOpen() > PosInfo.PriceCurrent() && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
volume = volume + PosInfo.Volume();
}
if(type == "BuysBelow" && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PosInfo.PriceOpen() < PosInfo.PriceCurrent() && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
volume = volume + PosInfo.Volume();
}
/////////////////////////////
if(type == "SellsAbove" && PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.PriceOpen() > PosInfo.PriceCurrent() && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
volume = volume + PosInfo.Volume();
}
if(type == "SellsBelow" && PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.PriceOpen() < PosInfo.PriceCurrent() && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
quantity = quantity + PosInfo.Volume()*PosInfo.PriceOpen();
volume = volume + PosInfo.Volume();
}
}
entry = quantity / volume;
return entry;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double VolumeTotal(string positionType)
{
double totalVolume = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
{
if(PosInfo.SelectByIndex(i) && positionType == "Buy" && PosInfo.PositionType() == POSITION_TYPE_BUY)
{
totalVolume += PosInfo.Volume();
}
}
//Print("BV: " + positionType + ": "+ totalVolume);
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(PosInfo.SelectByIndex(i) && positionType == "Sell" && PosInfo.PositionType() == POSITION_TYPE_SELL)
{
totalVolume += PosInfo.Volume();
}
}
//Print("SV: " + positionType + ": " + totalVolume);
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
if(PosInfo.SelectByIndex(i) && positionType == "Total")
{
totalVolume += PosInfo.Volume();
}
}
//Print("TV: " + positionType + ": " + totalVolume);
return totalVolume;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int FindIndices(double value, double &arr[], int &indexlow, int &indexhigh)
{
int size = ArraySize(arr);
// Check if the array has at least two elements
if(size < 2)
{
Print("Array must have at least two elements.");
// return -1; // Return -1 to indicate an error
}
// Iterate through the array to find the indices
for(int i = 0; i < size - 1; i++)
{
if((value > arr[i] && value < arr[i+1]) || (value < arr[i] && value > arr[i+1]))
{
indexlow = i;
indexhigh = i + 1;
return 0; // Return 0 to indicate success
}
}
// 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
}
//+------------------------------------------------------------------+
void CalculateVolumeDistribution(int Days, double levelStep, double &volumeArray[], double &priceLevelArray[])
{
// 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 ||
CopyHigh(_Symbol, PERIOD_M1, 0, lookbackBars, highArray) <= 0 ||
CopyTickVolume(_Symbol, PERIOD_M1, 0, lookbackBars, volumeArrayRaw) <= 0)
{
Print("Error copying data");
return;
}
// Loop through the lookback period to find the lowest low and highest high
for(int i = 0; i < lookbackBars; i++)
{
double low = lowArray[i];
double high = highArray[i];
if((low != 0 && low < lowestLow) || lowestLow == 0)
lowestLow = low;
if(high > highestHigh)
highestHigh = high;
}
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++)
{
volumeArray[i] = 0;
priceLevelArray[i] = lowestLow + i * levelStep;
}
// Aggregate volume for each level
for(int i = 0; i < lookbackBars; i++)
{
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++)
{
if(level >= 0 && level < numberOfLevels)
{
volumeArray[level] += volume;
//Print("Level: ", level, " Volume: ", volumeArray[level]);
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int ArrayPeaks(const double &array[], int &peaks[], double min_distance)
{
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
{
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++)
{
if(j != i && array[i] <= array[j])
{
is_peak = false;
break;
}
}
if(is_peak)
{
bool is_far_enough = true;
for(int j = 0; j < peak_count; j++)
{
if(MathAbs(i - peaks[j]) < min_distance)
{
is_far_enough = false;
break;
}
}
if(is_far_enough)
{
peaks[peak_count] = i;
peak_count++;
}
}
}
ArrayResize(peaks, peak_count); // Resize peaks array to the actual number of peaks found
return peak_count; // Return the number of peaks found
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CalculateValueArea(const double &priceLevels[], const double &volumes[], double &valAreaHigh, double &valAreaLow, double percentage = 70.0)
{
int size = ArraySize(volumes);
if(size <= 0 || size != ArraySize(priceLevels))
{
//Print("Array Issue: Price Levels and Volumes don't match or are empty.");
return;
}
// Calculate total volume
double totalVolume = 0.0;
for(int i = 0; i < size; i++)
{
totalVolume += volumes[i];
}
// 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++)
{
if(volumes[i] > maxVolume)
{
maxVolume = volumes[i];
pocIndex = i;
}
}
// 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)
{
// Consider both directions and choose the one with larger volume
if(leftIndex >= 0 && (rightIndex >= size || volumes[leftIndex] >= volumes[rightIndex]))
{
cumulativeVolume += volumes[leftIndex];
valAreaLow = priceLevels[leftIndex];
leftIndex--;
}
else if(rightIndex < size)
{
cumulativeVolume += volumes[rightIndex];
valAreaHigh = priceLevels[rightIndex];
rightIndex++;
}
else
{
// No more price levels to consider
break;
}
}
}
////////////////CLOSING FUNCTIONS////////////////////////////////////
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseAllPositions()
{
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
if(PosInfo.SelectByIndex(i)) // select a position
{
trade.PositionClose(PosInfo.Ticket());
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CancelLimits(string comment)
{
for(int i = OrdersTotal()-1; i>= 0; i--)
if(OrdInfo.SelectByIndex(i) && PosInfo.Comment() == comment)
{
trade.OrderDelete(OrdInfo.Ticket());
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseByWinning()
{
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.PositionType() == POSITION_TYPE_BUY)
{
double thebuy = PosInfo.PriceOpen();
int theBuyTicket = PosInfo.Ticket();
for(int i = PositionsTotal() - 1; i >= 0; i--)
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.PositionType() == POSITION_TYPE_SELL)
{
double thesell = PosInfo.PriceOpen();
int theSellTicket = PosInfo.Ticket();
if(thesell - thebuy > 0)
{
trade.PositionCloseBy(theBuyTicket,theSellTicket);
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseByLosing()
{
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
if(PosInfo.SelectByIndex(i) && PosInfo.PositionType() == POSITION_TYPE_BUY)
{
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)
{
double thesell = PosInfo.PriceOpen();
int theSellTicket = PosInfo.Ticket();
if(thesell - thebuy < -Grid*_Point)
{
trade.PositionCloseBy(theBuyTicket,theSellTicket);
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseByWin()
{
int profitTicket;
double profit;
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.PositionType() == POSITION_TYPE_BUY)
{
if(PosInfo.Profit() > profit)
{
profit = PosInfo.Profit();
}
double thebuy = PosInfo.PriceOpen();
int theBuyTicket = PosInfo.Ticket();
for(int i = PositionsTotal() - 1; i >= 0; i--)
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.PositionType() == POSITION_TYPE_SELL)
{
double thesell = PosInfo.PriceOpen();
int theSellTicket = PosInfo.Ticket();
if(thesell - thebuy > 0)
{
trade.PositionCloseBy(theBuyTicket,theSellTicket);
}
}
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseByLoss()
{
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
if(PosInfo.SelectByIndex(i) && PosInfo.PositionType() == POSITION_TYPE_BUY)
{
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)
{
double thesell = PosInfo.PriceOpen();
int theSellTicket = PosInfo.Ticket();
if(thesell - thebuy < -Grid*_Point)
{
trade.PositionCloseBy(theBuyTicket,theSellTicket);
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseWinners()
{
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.Profit() > 0)
{
int Ticket = PosInfo.Ticket();
trade.PositionClose(Ticket);
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseLosers()
{
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.Profit() < 0)
{
int Ticket = PosInfo.Ticket();
trade.PositionClose(Ticket);
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseBuyWin()
{
double Profit;
int ProfitTicket;
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
{
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.PositionType() == POSITION_TYPE_BUY && PosInfo.Profit() > Profit && PosInfo.Profit() > 0)
{
Profit = PosInfo.Profit();
ProfitTicket = PosInfo.Ticket();
}
}
}
trade.PositionClose(ProfitTicket);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseSellWin()
{
double Profit;
int ProfitTicket;
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
{
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.Profit() > Profit && PosInfo.Profit() > 0)
{
Profit = PosInfo.Profit();
ProfitTicket = PosInfo.Ticket();
}
}
}
trade.PositionClose(ProfitTicket);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseBuyLoss()
{
double Profit;
int ProfitTicket;
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
{
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.PositionType() == POSITION_TYPE_BUY && PosInfo.Profit() < Profit && PosInfo.Profit() < 0)
{
Profit = PosInfo.Profit();
ProfitTicket = PosInfo.Ticket();
}
}
}
trade.PositionClose(ProfitTicket);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double HighestBuy()
{
double Price = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
{
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.PositionType() == POSITION_TYPE_BUY && PosInfo.PriceOpen() > Price)
{
Price = PosInfo.PriceOpen();
}
}
}
return Price;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double HighestSell()
{
double Price = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
{
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.PriceOpen() > Price)
{
Price = PosInfo.PriceOpen();
}
}
}
return Price;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double LowestBuy()
{
double Price = 2;
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
{
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.PositionType() == POSITION_TYPE_BUY && PosInfo.PriceOpen() < Price)
{
Price = PosInfo.PriceOpen();
}
}
}
return Price;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double LowestSell()
{
double Price = 2;
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
{
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.PriceOpen() < Price)
{
Price = PosInfo.PriceOpen();
}
}
}
return Price;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseSellLoss()
{
double Profit;
int ProfitTicket;
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
{
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.Profit() < Profit && PosInfo.Profit() < 0)
{
Profit = PosInfo.Profit();
ProfitTicket = PosInfo.Ticket();
}
}
}
trade.PositionClose(ProfitTicket);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void MAStopLoss()
{
int ProfitTicket;
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
{
if(PosInfo.SelectByIndex(i))
{
if(PosInfo.PositionType() == POSITION_TYPE_BUY && PosInfo.PriceOpen() > MAHigh[0] && PosInfo.PriceCurrent() < MALow[0])
{
ProfitTicket = PosInfo.Ticket();
trade.PositionClose(ProfitTicket);
}
if(PosInfo.PositionType() == POSITION_TYPE_SELL && PosInfo.PriceOpen() < MALow[0]&& PosInfo.PriceCurrent() > MAHigh[0])
{
ProfitTicket = PosInfo.Ticket();
trade.PositionClose(ProfitTicket);
}
}
}
}
///////////////////POSITIONS CHECK/////////////////////////
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool OtherBuyPosition(string comment)
{
bool other = false;
for(int i = PositionsTotal(); i >=0; i--)
{
ulong ticket = PositionGetTicket(i);
if(PosInfo.SelectByTicket(ticket))
{
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))
{
other = true;
break;
}
else
{
other = false;
}
}
}
return other;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool OtherSellPosition(string comment)
{
bool other = false;
for(int i = PositionsTotal(); i >=0; i--)
{
ulong ticket = PositionGetTicket(i);
if(PosInfo.SelectByTicket(ticket))
{
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))
{
other = true;
break;
}
else
{
other = false;
}
}
}
return other;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseBuys()
{
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
if(PosInfo.SelectByIndex(i) && PosInfo.PositionType() == POSITION_TYPE_BUY)
{
double thebuy = PosInfo.PriceOpen();
int theBuyTicket = PosInfo.Ticket();
trade.PositionClose(theBuyTicket);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseSells()
{
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
if(PosInfo.SelectByIndex(i) &&PosInfo.PositionType() == POSITION_TYPE_SELL)
{
double thesell = PosInfo.PriceOpen();
int theSellTicket = PosInfo.Ticket();
trade.PositionClose(theSellTicket);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseBuy()
{
double Profit;
int theBuyTicket = PosInfo.Ticket();
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
{
if(PosInfo.SelectByIndex(i) && PosInfo.PositionType() == POSITION_TYPE_BUY)
{
if(Profit>PosInfo.Profit())
{
Profit = PosInfo.Profit();
theBuyTicket = PosInfo.Ticket();
}
}
}
trade.PositionClose(theBuyTicket);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CloseSell()
{
double Profit;
int theSellTicket = PosInfo.Ticket();
for(int i = PositionsTotal() - 1; i >= 0; i--) // loop all Open Positions
{
if(PosInfo.SelectByIndex(i) && PosInfo.PositionType() == POSITION_TYPE_SELL)
{
if(Profit>PosInfo.Profit())
{
Profit = PosInfo.Profit();
theSellTicket = PosInfo.Ticket();
}
}
}
trade.PositionClose(theSellTicket);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void Trailing()
{
// 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--)
{
// 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"))
{
if(bid > PositionGetDouble(POSITION_PRICE_OPEN) + NormalizeDouble(_Point * Grid,_Digits))
{
trade.PositionModify(PositionTicket,NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN) + Grid*_Point,_Digits),PositionGetDouble(POSITION_TP));
}
}
if(trade_type == 1)// && (PositionGetString(POSITION_COMMENT) == "SellLimit"|| PositionGetString(POSITION_COMMENT) == "SellGrid"))
{
if(ask < PositionGetDouble(POSITION_PRICE_OPEN) - NormalizeDouble(_Point * Grid,_Digits))
{
trade.PositionModify(PositionTicket,NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN) - Grid*_Point,_Digits),PositionGetDouble(POSITION_TP));
}
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void TPmodify()
{
// 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--)
{
ulong PositionTicket = PositionGetTicket(i);
long trade_type = PositionGetInteger(POSITION_TYPE);
if(trade_type == 0 && PosInfo.TakeProfit() != meanEntryPriceBuy() + TakeProfitFactor*Grid*_Point && BuyPositionsCount() > PositionsThreshold)
{
trade.PositionModify(PositionTicket,PositionGetDouble(POSITION_SL),PositionGetDouble(POSITION_PRICE_OPEN) + TakeProfitFactor*Grid*_Point);
if(PosInfo.PriceCurrent() > meanEntryPriceBuy() + Grid*_Point)
CloseBuys();
}
if(trade_type == 1 && PosInfo.TakeProfit() != meanEntryPriceSell() - TakeProfitFactor*Grid*_Point && SellPositionsCount() > PositionsThreshold)
{
trade.PositionModify(PositionTicket,PositionGetDouble(POSITION_SL),PositionGetDouble(POSITION_PRICE_OPEN) - TakeProfitFactor*Grid*_Point);
if(PosInfo.PriceCurrent() < meanEntryPriceSell() - Grid*_Point)
CloseSells();
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void breakEven()
{
for(int i=PositionsTotal()-1; i>=0; i--)
{
double meanEntryBuy = meanEntryPriceBuy();
double meanEntrySell = meanEntryPriceSell();
ulong PositionTicket = PositionGetTicket(i);
long trade_type = PositionGetInteger(POSITION_TYPE);
if(trade_type == 0)
if( meanEntryBuy < ask - Grid*_Point && (PosInfo.StopLoss() < meanEntryBuy || PosInfo.StopLoss() == 0))
{
trade.PositionModify(PositionTicket,meanEntryBuy + 150*_Point,PositionGetDouble(POSITION_TP));
}
if(trade_type == 1)
if( meanEntrySell > bid + Grid*_Point && (PosInfo.StopLoss() > meanEntrySell || PosInfo.StopLoss() == 0))
{
trade.PositionModify(PositionTicket,meanEntrySell - 150*_Point,PositionGetDouble(POSITION_TP));
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void slStepUp()
{
for(int i=PositionsTotal()-1; i>=0; i--)
{
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"))
{
trade.PositionModify(PositionTicket,NormalizeDouble(PositionGetDouble(POSITION_SL) + Grid*_Point,_Digits),PositionGetDouble(POSITION_TP));
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void slStepDown()
{
for(int i=PositionsTotal()-1; i>=0; i--)
{
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"))
{
trade.PositionModify(PositionTicket,NormalizeDouble(PositionGetDouble(POSITION_SL) - Grid*_Point,_Digits),PositionGetDouble(POSITION_TP));
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void StoplossUpdate(string comment)
{
int buyCount = BuyPositionsCount();
int sellCount = SellPositionsCount();
double meanEntryBuy = meanEntryPrice("Buy");
double meanEntrySell = meanEntryPrice("Sell");
for(int i=PositionsTotal()-1; i>=0; i--)
{
ulong PositionTicket = PositionGetTicket(i);
long trade_type = PositionGetInteger(POSITION_TYPE);
if(trade_type == POSITION_TYPE_BUY && comment == "buy")
{
double newStopLoss;
if(ask < meanEntryBuy + TakeProfitFactor*Grid*_Point)
newStopLoss = StopLossBuy;
if(ask > meanEntryBuy + TakeProfitFactor*Grid*_Point)
newStopLoss = NormalizeDouble((((ask + meanEntryBuy)/2)+ask)/2, _Digits);
if(PositionGetDouble(POSITION_SL) < newStopLoss)
trade.PositionModify(PositionTicket,newStopLoss,PositionGetDouble(POSITION_TP));
}
if(trade_type == POSITION_TYPE_SELL && comment == "sell")
{
double newStopLoss;
if(bid > meanEntrySell - TakeProfitFactor*Grid*_Point)
newStopLoss = StopLossSell;
if(bid < meanEntrySell - TakeProfitFactor*Grid*_Point)
newStopLoss = NormalizeDouble((((bid + meanEntrySell)/2)+bid)/2, _Digits);
if(PositionGetDouble(POSITION_SL) > newStopLoss || PosInfo.StopLoss() == 0)
trade.PositionModify(PositionTicket,newStopLoss,PositionGetDouble(POSITION_TP));
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
string crossOver(double &Array1[], double &Array2[])
{
string crossOver;
if(Array1[1] > Array2[1] && Array1[2] < Array2[2])
{
crossOver = "up";
}
if(Array1[1] < Array2[1] && Array1[2] > Array2[2])
{
crossOver = "down";
}
else
{
crossOver = NULL;
}
return (crossOver);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int BuyPositionsCount()
{
int Buys = 0;
for(int i = PositionsTotal()-1; i>=0; i--)
{
PositionGetTicket(i);
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
Buys = Buys+1;
}
}
return Buys;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int SellPositionsCount()
{
int Sells = 0;
for(int i = PositionsTotal()-1; i>=0; i--)
{
PositionGetTicket(i);
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
Sells = Sells+1;
}
}
return Sells;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void SLmodify()
{
// 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--)
{
ulong PositionTicket = PositionGetTicket(i);
long trade_type = PositionGetInteger(POSITION_TYPE);
if(trade_type == 0
&& PosInfo.PriceCurrent() > meanEntryPriceBuy() + (0.5*Grid*_Point)
&& (PositionGetDouble(POSITION_SL) < PosInfo.PriceCurrent() - ((LowestBuy() + 0.5*Grid*_Point)-meanEntryPriceBuy()) || PositionGetDouble(POSITION_SL) == 0))
{
trade.PositionModify(PositionTicket,PosInfo.PriceCurrent() - ((LowestBuy() + 0.5*Grid*_Point)-meanEntryPriceBuy()),PositionGetDouble(POSITION_TP));
Print("Lowest buy: " + LowestBuy());
}
if(trade_type == 1
&& PosInfo.PriceCurrent() < meanEntryPriceSell() - (0.5*Grid*_Point)
&& (PositionGetDouble(POSITION_SL) > PosInfo.PriceCurrent() - ((HighestSell() - 0.5*Grid*_Point)-meanEntryPriceSell()) || PositionGetDouble(POSITION_SL) == 0))
{
trade.PositionModify(PositionTicket,PosInfo.PriceCurrent() - ((HighestSell() - 0.5*Grid*_Point)-meanEntryPriceSell()),PositionGetDouble(POSITION_TP));
Print("highest sell: " + HighestSell());
}
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double meanEntryPriceBuy()
{
double price = 0;
double volume = 0;
double entry;
for(int i = PositionsTotal()-1; i>=0; i--)
{
PositionGetTicket(i);
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
price = price + PosInfo.Volume()*PosInfo.PriceOpen();
}
}
for(int i = PositionsTotal()-1; i>=0; i--)
{
PositionGetTicket(i);
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
volume = volume + PosInfo.Volume();
}
}
entry = price / volume;
return entry;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double meanEntryPriceSell()
{
double price = 0;
double volume = 0;
double entry;
for(int i = PositionsTotal()-1; i>=0; i--)
{
PositionGetTicket(i);
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
price = price + PosInfo.Volume()*PosInfo.PriceOpen();
}
}
for(int i = PositionsTotal()-1; i>=0; i--)
{
PositionGetTicket(i);
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && PositionGetString(POSITION_SYMBOL) == _Symbol)
{
volume = volume + PosInfo.Volume();
}
}
entry = price / volume;
return entry;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+