twoWavesLimits/twoWavesLimits.mq5
super.admin 62a907ea44 convert
2025-05-30 16:34:23 +02:00

270 lines
11 KiB
MQL5

//+------------------------------------------------------------------+
//| twoWavesLimits.mq5 |
//| Copyright 2018, Benjamin Pillet |
//| |
//+------------------------------------------------------------------+
#include "JPBP.mqh"
enum limitPolicy
{
passthrough,//pass through
closeBeyond,//close beyond
};
enum limitUsed
{
wave1,//use wave 1 limit
wave2,//use wave 2 limit
};
//--- main input parameters
input double Lots = 0; //Lots, 0=compound
//--- Entry input parameters
input int MaxSpread = 0; //check spread and set a maximum, 0 = no check
input bool OnePos = false; //open only one position
input limitPolicy EntryPolicy = closeBeyond; //entry policy
//--- exit input parameters
input int SLpoints = 300;
//--- global variables
datetime expDate;
ulong currentOrderTickets[2];
bool orderStatus[2];
datetime baseStartTime;
double fprice;
double fsl;
double ftp;
double fvolume;
double prevBid;
double w1High;
double w1Low;
double w2High;
double w2Low;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//--- set variables
setVariables();
trade.SetExpertMagicNumber(MagicNumber);
arraySize = 0;
orderPlaced[0] = false;
orderPlaced[1] = false;
positionTotal = 0;
//--- recovery system
//set order placed and base start time
for(int i=0; i < OrdersTotal(); i++){
ulong oTicket = OrderGetTicket(i);
if(OrderSelect(oTicket)){
if(OrderGetInteger(ORDER_MAGIC) == MagicNumber && OrderGetString(ORDER_SYMBOL) == _Symbol){
baseStartTime = OrderGetInteger(ORDER_TIME_SETUP);
timeSet = true;
orderPlaced[0] = true;
orderPlaced[1] = true;
if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP){
currentOrderTickets[0] = oTicket;
}
else if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP){
currentOrderTickets[1] = oTicket;
}
}
}
}
//put position back into the system
for(int i=0; i< PositionsTotal(); i++){
if(PositionSelectByTicket(PositionGetTicket(i))){
if(PositionGetInteger(POSITION_MAGIC) == MagicNumber && PositionGetSymbol(i) == _Symbol){
positionTotal = positionTotal + 1;
AddPosition();
orderPlaced[0] = true;
orderPlaced[1] = true;
}
}
}
prevPositionTotal = positionTotal;
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//--- get market info
refreshVariables();
//--- count the number of position opened by this EA and add new position to trailing system
positionTotal = 0;
for(int i=0; i< PositionsTotal(); i++){
posTicket = PositionGetTicket(i);
if(PositionSelectByTicket(posTicket)){
if(PositionGetInteger(POSITION_MAGIC) == MagicNumber && PositionGetSymbol(i) == _Symbol){
positionTotal = positionTotal + 1;
//set parameters if a new position was opened
if(positionTotal > prevPositionTotal && (SafeMode || TrailingMode)){
AddPosition();
//adjust safe and trailing if not default policy
if(SafeSetup != TP_SLratio && SafeMode){
if(positionType == POSITION_TYPE_BUY){
safeActivationPrice[arrayIndex] = SetBuyProfitLimit(SafeSetup);
safeSL[arrayIndex] = NormalisePrice(positionOpenPrice + (positionOpenPrice-positionSL)*SafeSlRatio);
}
else if(positionType==POSITION_TYPE_SELL){
safeActivationPrice[arrayIndex] = SetSellProfitLimit(SafeSetup);
safeSL[arrayIndex] = NormalisePrice(positionOpenPrice - (positionSL-positionOpenPrice)*SafeSlRatio);
if(safeSL[arrayIndex]<0)safeSL[arrayIndex] = 0;
}
if(DrawLines){
ObjectMove(0,"Safe Activation #"+IntegerToString(positionTicket[arrayIndex]),0,0,safeActivationPrice[arrayIndex]);
}
}
if(TrailingSetup != TP_SLratio && TrailingMode){
if(positionType == POSITION_TYPE_BUY){
trailingActivationPrice[arrayIndex] = SetBuyProfitLimit(TrailingSetup);
trailingDistance[arrayIndex] = (trailingActivationPrice[arrayIndex]-positionOpenPrice)*(TrailingDistance/100);
}
else if(positionType==POSITION_TYPE_SELL){
trailingActivationPrice[arrayIndex] = SetSellProfitLimit(TrailingSetup);
trailingDistance[arrayIndex] = (positionOpenPrice - trailingActivationPrice[arrayIndex])*(TrailingDistance/100);
}
if(DrawLines){
ObjectMove(0,"Trailing Activation #"+IntegerToString(positionTicket[arrayIndex]),0,0,trailingActivationPrice[arrayIndex]);
}
}
}
}
}
}
//--- remove lines if a position was closed
if(positionTotal < prevPositionTotal){
HistorySelect(0,TimeCurrent());
for(int i=0; i<prevPositionTotal-positionTotal; i++){
histDealTicket = HistoryDealGetTicket((HistoryDealsTotal()-1)-i);
ObjectDelete(0,"Safe Activation #"+IntegerToString(HistoryDealGetInteger(histDealTicket,DEAL_POSITION_ID)));
ObjectDelete(0,"Trailing Activation #"+IntegerToString(HistoryDealGetInteger(histDealTicket,DEAL_POSITION_ID)));
}
}
prevPositionTotal = positionTotal;
//--- Calculate wave limits
//--- Define conditions for instant execution
//general conditions
bool onlyOneTrade;
if(OnePos) onlyOneTrade = positionTotal == 0; else onlyOneTrade = true;
//buy conditions
//sell conditions
//--- market execution
//buy
if(){
//set stoploss
//set take profit
//set volume of transaction
}
//--- safe mode and trailing mode
if((SafeMode || TrailingMode)){
//reset arrays if no position
if(positionTotal == 0 && arraySize > 0){
arraySize = 0;
prevPositionTotal = 0;
ArrayResize(positionTicket,arraySize,10);
ArrayResize(safeActivationPrice,arraySize,10);
ArrayResize(safeSL,arraySize,10);
ArrayResize(trailingActivationPrice,arraySize,10);
ArrayResize(trailingDistance,arraySize,10);
}
//if at least one position is open then follow up and place new SL if conditions are fulfilled
if(positionTotal > 0){
for(int i=0; i<arraySize; i++){
if(PositionSelectByTicket(positionTicket[i])){
//get information of the position
positionType = PositionGetInteger(POSITION_TYPE);
positionOpenPrice = PositionGetDouble(POSITION_PRICE_OPEN);
positionCurrentPrice = PositionGetDouble(POSITION_PRICE_CURRENT);
positionTP = PositionGetDouble(POSITION_TP);
positionSL = PositionGetDouble(POSITION_SL);
if(SafeMode){
if(positionType == POSITION_TYPE_BUY && positionCurrentPrice > safeActivationPrice[i] && positionSL < positionOpenPrice){
trade.PositionModify(PositionGetInteger(POSITION_TICKET),safeSL[i],positionTP);
positionSL = PositionGetDouble(POSITION_SL);
ObjectDelete(0,"Safe Activation #"+IntegerToString(positionTicket[i]));
if(orderStatus[1] && PositionGetInteger(POSITION_TIME) >= baseStartTime && CancelOrderOnSL){
trade.OrderDelete(currentOrderTickets[1]);
orderStatus[1] = false;
}
}
else if(positionType==POSITION_TYPE_SELL && positionCurrentPrice < safeActivationPrice[i] && positionSL > positionOpenPrice){
trade.PositionModify(PositionGetInteger(POSITION_TICKET),safeSL[i],positionTP);
positionSL = PositionGetDouble(POSITION_SL);
ObjectDelete(0,"Safe Activation #"+IntegerToString(positionTicket[i]));
if(orderStatus[0] && PositionGetInteger(POSITION_TIME) >= baseStartTime && CancelOrderOnSL){
trade.OrderDelete(currentOrderTickets[0]);
orderStatus[0] = false;
}
}
}
if(TrailingMode){
if(positionType == POSITION_TYPE_BUY){
trailingSL = NormalisePrice(positionCurrentPrice - trailingDistance[i]);
if(trailingSL<0)trailingSL = 0;
if(positionCurrentPrice > trailingActivationPrice[i] && positionSL<trailingSL){
trade.PositionModify(PositionGetInteger(POSITION_TICKET),trailingSL,positionTP);
positionSL = PositionGetDouble(POSITION_SL);
ObjectDelete(0,"Trailing Activation #"+IntegerToString(positionTicket[i]));
//remove second order
if(orderStatus[1] && PositionGetInteger(POSITION_TIME) >= baseStartTime && CancelOrderOnSL){
trade.OrderDelete(currentOrderTickets[1]);
orderStatus[1] = false;
}
}
}
else if(positionType==POSITION_TYPE_SELL){
trailingSL = NormalisePrice(positionCurrentPrice + trailingDistance[i]);
if(trailingSL<0)trailingSL = 0;
if(positionCurrentPrice < trailingActivationPrice[i] && positionSL>trailingSL){
trade.PositionModify(PositionGetInteger(POSITION_TICKET),trailingSL,positionTP);
positionSL = PositionGetDouble(POSITION_SL);
ObjectDelete(0,"Trailing Activation #"+IntegerToString(positionTicket[i]));
if(orderStatus[0] && PositionGetInteger(POSITION_TIME) >= baseStartTime && CancelOrderOnSL){
trade.OrderDelete(currentOrderTickets[0]);
orderStatus[0] =false;
}
}
}
}
}
}
}
}
}
//+------------------------------------------------------------------+