//+------------------------------------------------------------------+
//| Money Management.mq5 |
//| Copyright 2020, Etrid |
//| https://www.etrid.pro |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, Etrid"
#property link "https://www.etrid.pro"
#property version "1.00"
//--- input parameters
input group "Volume Management"
input int InpCoefficient = 100; // Volume coeficient
input double InpVolumeStep = 0.01; // Volume step
input double InpInpMaximumVolume = 0.01; // Maximum volume
input double InpMinimumVolume = 0.01; // Minimum using volume
input double InpMaximumVolume = 0.1; // Maximum using volume
input bool InpUseIntegerVolume = false; // Set true ifyou need use only integer volume (1,2,5,10)
input group "Position Management"
input bool InpMarginCall = true; // Use close position if position have fixed minus
input bool InpUseLong = true; // Can we use long position?
input bool InpUseShort = true; // Can we use short position?
input double InpMaxMinusForMarginCall = 0.3; // Maximum minus for closing position, 1 - 100%
//--- other parameters
double Balance = AccountInfoDouble(ACCOUNT_BALANCE); // Account balance
double StartBalance = Balance; // Balance on start work
double Volume = MathFloor(Balance/InpCoefficient) * InpVolumeStep; // Total using volume
long OrderMagic = 0000070; // Order magic
bool CanOpenOrder = true; // Set on false if we have margin call (InpMarginCall)
//+------------------------------------------------------------------+
//| Main action |
//+------------------------------------------------------------------+
void OnTick()
{
GetVolume();
CheckMarginCallPosition();
}
//+------------------------------------------------------------------+
//| Set using volume |
//+------------------------------------------------------------------+
void GetVolume()
{
//---
Balance = AccountInfoDouble(ACCOUNT_BALANCE);
if(Balance < InpCoefficient)
{
Balance = InpCoefficient;
}
//---
Volume = MathFloor(Balance/InpCoefficient) * InpVolumeStep;
if(InpUseIntegerVolume)
{
Volume = MathFloor(Volume);
}
//---
if(Volume > InpInpMaximumVolume)
{
Volume = InpInpMaximumVolume;
}
if(Volume < InpMinimumVolume)
{
Volume = InpMinimumVolume;
}
//---
if(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_LIQUIDITY_RATE) * Volume > Balance)
{
Volume = MathFloor(Balance/(SymbolInfoDouble(_Symbol,SYMBOL_TRADE_LIQUIDITY_RATE) * Volume)) * InpVolumeStep;
if(InpUseIntegerVolume)
{
Volume = MathFloor(Volume);
}
if(Volume < InpMinimumVolume)
{
Print("");
Print("Error!");
Print("Used unavailable volume: ",Volume);
Print("Minimum volume is: ",InpMinimumVolume);
Print("");
Volume = 0;
}
}
//---
}
//+------------------------------------------------------------------+
//| Margin Call position if it need |
//+------------------------------------------------------------------+
void CheckMarginCallPosition()
{
if(InpMarginCall)
{
//--- Select total profit
double profit = 0; // total profit of all positions
for(int i = 0 ; i < PositionsTotal();i++)
{
ulong ticket = PositionGetTicket(i);
PositionSelectByTicket(ticket);
profit = profit + PositionGetDouble(POSITION_PROFIT);
}
//--- Margin call all positions if profit > InpMaxMinusForMarginCall
double persent = (StartBalance - profit) / StartBalance - 1;
if(persent * -1 >= InpMaxMinusForMarginCall)
{
CanOpenOrder = false;
for(int i = 0 ; i < PositionsTotal();i++)
{
ulong ticket = PositionGetTicket(i);
PositionSelectByTicket(ticket);
CloseOrder(PositionGetDouble(POSITION_VOLUME), ticket);
}
}
//---
}
}
//+------------------------------------------------------------------+
//| Empty OpenOrder method |
//+------------------------------------------------------------------+
void OpenOrder(string type)
{
if(CanOpenOrder)
{
// some code for open position
}
}
//+------------------------------------------------------------------+
//| Empty CloseOrder method |
//+------------------------------------------------------------------+
void CloseOrder(double Volumes, ulong PositionTicket)
{
// some code for close position
}
Comments