125 lines
4.3 KiB
MQL5
125 lines
4.3 KiB
MQL5
|
//+------------------------------------------------------------------+
|
||
|
//| MTBalancer.mqh |
|
||
|
//| Copyright 2018, MetaQuotes Software Corp. |
|
||
|
//| https://www.mql5.com |
|
||
|
//+------------------------------------------------------------------+
|
||
|
#property version "1.3.2"
|
||
|
#include "MTUtils.mqh"
|
||
|
|
||
|
enum BalancerTrigger
|
||
|
{
|
||
|
mtb_position = 0,
|
||
|
mtb_volume = 1
|
||
|
};
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| |
|
||
|
//+------------------------------------------------------------------+
|
||
|
class MTBalancer
|
||
|
{
|
||
|
public:
|
||
|
BalancerTrigger balancer_type;
|
||
|
int positions_trigger;
|
||
|
double volume_difference;
|
||
|
bool enable_trade_on_limit;
|
||
|
|
||
|
protected:
|
||
|
double base_volume;
|
||
|
double balancing_volume;
|
||
|
|
||
|
public:
|
||
|
void setBaseVolume(double ibase_volume=0.1) {base_volume = ibase_volume;}
|
||
|
void setBalancingVolume(double balance) {balancing_volume = balance;};
|
||
|
void doBalancing(double ask,double bid,int take_profit);
|
||
|
void doBalancingByPositions(double ask,double bid,int take_profit);
|
||
|
void doBalancingByVolume(double ask,double bid,double take_profit);
|
||
|
|
||
|
|
||
|
};
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void MTBalancer::doBalancing(double ask, double bid, int take_profit)
|
||
|
{
|
||
|
//uint count_pos = PositionsTotal();
|
||
|
//if(count_pos == 0)
|
||
|
// {
|
||
|
// /*This is a safeguard for not "early stage" trading sessions */
|
||
|
// return;
|
||
|
// }
|
||
|
|
||
|
switch(balancer_type)
|
||
|
{
|
||
|
case mtb_volume:
|
||
|
if(GetVolumeDifference() >= volume_difference)
|
||
|
{
|
||
|
doBalancingByVolume(ask,bid,take_profit);
|
||
|
}
|
||
|
break;
|
||
|
case mtb_position:
|
||
|
if(PositionDifferenceByType() > positions_trigger)
|
||
|
{
|
||
|
doBalancingByPositions(ask,bid,take_profit);
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void MTBalancer::doBalancingByVolume(double ask,double bid,double take_profit)
|
||
|
{
|
||
|
double top_edge = GetHigestPositionOpenPrice(); /*This needs to be check for error (-1)*/
|
||
|
double bottom_edge = GetLowestPositionOpenPrice(); /*This needs to be check for error (-1)*/
|
||
|
|
||
|
if(((ask >= top_edge) || (!enable_trade_on_limit)) && (GetVolumeDifference(true) < 0))
|
||
|
{
|
||
|
int current_difference = fabs(GetVolumeDifference()/base_volume);
|
||
|
int unbalancer_value = fabs(balancing_volume/base_volume);
|
||
|
place_a_long(ask, take_profit, current_difference + unbalancer_value);
|
||
|
}
|
||
|
|
||
|
|
||
|
if(((bid <= bottom_edge) || (!enable_trade_on_limit)) && (GetVolumeDifference(true) > 0))
|
||
|
{
|
||
|
int current_difference = fabs(GetVolumeDifference()/base_volume);
|
||
|
int unbalancer_value = fabs(balancing_volume/base_volume);
|
||
|
place_a_short(bid,take_profit, current_difference + unbalancer_value);
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
|
||
|
|
||
|
//+------------------------------------------------------------------+
|
||
|
//| |
|
||
|
//+------------------------------------------------------------------+
|
||
|
void MTBalancer::doBalancingByPositions(double ask,double bid,int take_profit)
|
||
|
{
|
||
|
double top_edge = GetHigestPositionOpenPrice();
|
||
|
double bottom_edge = GetLowestPositionOpenPrice();
|
||
|
int position_difference = PositionDifferenceByType(true);
|
||
|
|
||
|
if((ask >= top_edge) && (position_difference>0))
|
||
|
{
|
||
|
place_a_long(ASK, take_profit);
|
||
|
}
|
||
|
else
|
||
|
if((bid <= bottom_edge) && (position_difference < 0))
|
||
|
{
|
||
|
place_a_short(BID, take_profit);
|
||
|
}
|
||
|
}
|
||
|
//+------------------------------------------------------------------+
|