Jeff_Max_Trading/Reference/Multitrade_w_Levels.mq5

237 lines
7.7 KiB
MQL5
Raw Permalink Normal View History

2025-05-30 15:02:04 +02:00
//+------------------------------------------------------------------+
//| Multitrade_w_Levels.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
input int max_band_size = 10;
input int number_of_levels = 2;
input double testing_volume = 0.1;
input double win_multiplier = 0.5;
input double lose_multiplier = 0.5;
input int box_height = 10;
input int box_length = 5;
#define BASE_MULT 0.5
#define POS_W_SHORT 1
#define POS_W_LONG 2
#define POS_W_BASE 0
struct Band
{
double top;
double bottom;
int number_levels;
int quanta; // @Init : round(max_band_size/ number of levels)
bool reset_limits;
double base_price;
};
struct Box
{
double top;
double bottom;
int length;
bool first_box;
};
//+------------------------------------------------------------------+
//| Global Space |
//+------------------------------------------------------------------+
Band band;
Box box;
CTrade trader;
double Ask;
double Bid;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnInit()
{
// init the Bands
band.top = max_band_size;
band.bottom = max_band_size;
band.number_levels = number_of_levels;
band.quanta = round(max_band_size/number_of_levels);
band.reset_limits = true;
box.first_box = true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnTick()
{
//---
Ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);
Bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);
double price = NormalizeDouble((Ask + Bid) / 2, _Digits);
if(box.first_box)
{
update_box(price);
update_bands(price);
band.reset_limits = true;
box.first_box = false;
}
if(Ask>=box.top)
{
place_long(Ask, round(box_height*win_multiplier));
update_box(Ask, POS_W_LONG);
} // guide box goes long
else
if(Bid <= box.bottom)
{
place_short(Bid,round(box_height*win_multiplier));
update_box(Bid, POS_W_SHORT);
} // guide box goes short
else
if(box.length<= 0)
{
update_box(price, POS_W_BASE);
} // box needs update
if(price >= band.top || price <= band.bottom)
{
close_all_open_trades();
} // price left the max_side (from either side)
else
if(band.reset_limits)
{
place_all_trade_levels(price);
} // all positions where closed (Set levels UP!)
box.length--;
Comment("Band: Top= "+band.top+" Bottom= "+band.bottom+" Quant= "+band.quanta+"\n"
+"Box: Top= "+box.top+" Bottom= "+box.bottom);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void place_all_trade_levels(double price, double volume=0.1)
{
for(int i=1; i<band.number_levels; i++)
{
place_long(price+(band.quanta*i*_Point), band.quanta*(i+1), volume*(band.number_levels-i), false); // place the long
place_short(price-(band.quanta*i*_Point), band.quanta*(i+1), volume*(band.number_levels-i), false); // place the short
}
update_bands(price);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void place_long(double price, int take_profit, double volume=0.1, bool is_stop=true)
{
if(is_stop)
{
trader.Buy(volume, NULL, price, 0, price+(take_profit*_Point), NULL);
}
else
{
trader.BuyStop(volume, price, NULL, 0, price+take_profit*_Point, ORDER_TIME_GTC, 0, NULL);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void place_short(double price, int take_profit, double volume=0.1, bool is_stop=true)
{
if(is_stop)
{
trader.Sell(volume, NULL, price, 0, price-(take_profit*_Point), NULL);
}
else
{
trader.SellStop(volume, price, NULL, 0, price-take_profit*_Point, ORDER_TIME_GTC, 0, NULL);
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void close_all_open_trades()
{
for(int i=0; i<PositionsTotal(); i++)
{
ulong position_ticket = PositionGetTicket(i);
trader.PositionClose(position_ticket);
}
for(int j=0; j<OrdersTotal(); j++)
{
ulong order_ticket = OrderGetTicket(j);
trader.OrderDelete(order_ticket);
}
band.reset_limits = true;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void update_bands(double price)
{
band.top = price + NormalizeDouble(max_band_size*_Point, _Digits);
band.bottom = price - NormalizeDouble(max_band_size*_Point, _Digits);
band.reset_limits = false;
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void update_box(double price, int direction=POS_W_BASE)
{
double top_mult;
double bottom_mult;
switch(direction)
{
case POS_W_BASE:
top_mult = BASE_MULT;
bottom_mult = BASE_MULT;
break;
case POS_W_LONG:
top_mult = win_multiplier;
bottom_mult = lose_multiplier;
break;
case POS_W_SHORT:
top_mult = lose_multiplier;
bottom_mult = win_multiplier;
break;
}
box.top = price + NormalizeDouble(top_mult*box_height*_Point, _Digits);
box.bottom = price - NormalizeDouble(bottom_mult*box_height*_Point, _Digits);
box.length = box_length;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+