Disliked{quote} If you attach a picture or screen print, I'll have a look to code what you're askingIgnored
//==============================
this is the .mq4 file in Expert Advisor
//| Copyright 2021. JuliefaFX. |
//| https://disqus.com/by/nic_colito |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021. JuliefaFX."
#property link "https://disqus.com/by/nic_colito"
#property version "1.01"
#property strict
#include "10k-50k Common.mqh"
==============================================
this file is for common .mqh file in Expert Advisor
//| Copyright 2021. JuliefaFX. |
//| https://disqus.com/by/nic_colito |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021. JuliefaFX."
#property link "https://disqus.com/by/nic_colito"
#property version "1.01"
#property strict
#include "10k-50k Class.mqh" //get source functions from '10k-50k Class.mqh' file
//inputs indicators
// bollinger band
input int InpBandsPeriods = 20; //bband periods
input double InpBandsDeviation = 2.0; // bband deviation
input ENUM_APPLIED_PRICE InpBandsAppliedPrice = PRICE_CLOSE; //bband applied price
// moving average line
input int InpMaPeriods = 9; //ma periods
input ENUM_MA_METHOD InpMaMethod = MODE_SMA; //ma method
input ENUM_APPLIED_PRICE InpMaAppliedPrice = PRICE_CLOSE; //ma applied price
// the standard inputs
input double InpPLRatio = 1.0; // profit/loss ratio
input int InpMagicNumber0 = 210613; //magic number part1
int InpMagicNumber1 = InpMagicNumber0+1; //magic number
input string InpTradeComment = "10k-50k"; //trade comment
input double InpTradeVolume0 = 0.02; //volume per trade
input double InpTradeVolume1 = 0.01; //volume per trade
CCurrentTrade *CurrentTrade[2];
int OnInit()
{
CurrentTrade[0] = new CCurrentTrade(InpMaPeriods, InpMaMethod, InpMaAppliedPrice,
InpBandsPeriods, InpBandsDeviation, InpBandsAppliedPrice,
InpPLRatio, InpMagicNumber0, InpTradeComment, InpTradeVolume0, 0);
if (CurrentTrade[0].InitStatus()!=INIT_SUCCEEDED) return(CurrentTrade[0].InitStatus());
CurrentTrade[1] = new CCurrentTrade(InpMaPeriods, InpMaMethod, InpMaAppliedPrice,
InpBandsPeriods, InpBandsDeviation, InpBandsAppliedPrice,
InpPLRatio, InpMagicNumber1, InpTradeComment, InpTradeVolume1, 1);
if (CurrentTrade[1].InitStatus()!=INIT_SUCCEEDED) return(CurrentTrade[1].InitStatus());
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason) {
delete CurrentTrade[0];
delete CurrentTrade[1];
}
void OnTick() {
// 3 things to consider here
// 1. part 0 must not open a trade if there is a trade still open from part 0 or part 1
// 2. when part 0 opens a trade part 1 must also open a trade
// 3. when part 0 trade closes part 1 must move to break even
CurrentTrade[1].CheckIfClosed();
if (CurrentTrade[0].CurrentTicket()>0) { // there is an open ticket here
CurrentTrade[0].CheckIfClosed(); //update if the ticket was closed since last loop
if (CurrentTrade[0].CurrentTicket()==0) { // zero here means the ticket has just closed
CurrentTrade[1].SetBreakEven(); //move the other leg to break even
}
}
// now open if ther are no open tickets
if (NewBar() && CurrentTrade[0].CurrentTicket()==0 && CurrentTrade[1].CurrentTicket()==0) {
CurrentTrade[0].UpdateIndicators();
CurrentTrade[1].UpdateIndicators();
int condition = CurrentTrade[0].GetOpenCondition();
if (condition!=0) {
CurrentTrade[0].OpenOnCondition(condition);
CurrentTrade[1].OpenOnCondition(condition);
}
}
}
// just detect if a new bar has opened since the last time this was called
// this will ignore the current bar when the function is first called
bool NewBar() {
datetime now = iTime(Symbol(), Period(), 0);
static datetime prev = now;
if (prev==now) return(false);
prev = now;
return(true);
}
//===============================
this is the class .mqh file in Expert Advisor
//| Copyright 2021. JuliefaFX. |
//| https://disqus.com/by/nic_colito |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021. JuliefaFX."
#property link "https://disqus.com/by/nic_colito"
#property version "1.01"
#property strict
#ifdef __MQL5__
#include <Trade/Trade.mqh>
CTrade Trade;
CPositionInfo PositionInfo;
#endif
class CCurrentTrade {
private:
int mMaPeriods;
ENUM_MA_METHOD mMaMethod;
ENUM_APPLIED_PRICE mMaAppliedPrice;
int mBandsPeriods;
double mBandsDeviation;
ENUM_APPLIED_PRICE mBandsAppliedPrice;
double mPLRatio;
int mMagicNumber;
double mTradeComment;
double mTradeVolume;
int mLeg;
int mInitStatus;
ulong mCurrentTicket;
//indicator values - can now be set by a common function
double mMa;
double mBandUpper1;
double mBandUpper2;
double mBandLower1;
double mBandLower2;
double mBandMid;
double mClose1;
double mClose2;
double mBid;
double mAsk;
#ifdef __MQL5__
int HandleMa;
double BufferMa[];
int HandleBands;
double BufferBandsUpper[];
double BufferBandsLower[];
double BufferBandsMid[];
#endif
public:
int InitStatus() { return(mInitStatus); }
ulong CurrentTicket() { return(mCurrentTicket); }
public:
CCurrentTrade(int maPeriods, ENUM_MA_METHOD maMethod, ENUM_APPLIED_PRICE maAppliedPrice,
int bandsPeriods, double bandsDeviation, ENUM_APPLIED_PRICE bandsAppliedPrice,
double plRatio, int magicNumber, string tradeComment, double tradeVolume,
int leg) {
mMaPeriods = maPeriods;
mMaMethod = maMethod;
mMaAppliedPrice = maAppliedPrice;
mBandsPeriods = bandsPeriods;
mBandsDeviation = bandsDeviation;
mBandsAppliedPrice = bandsAppliedPrice;
mPLRatio = plRatio;
mMagicNumber = magicNumber;
mTradeComment = tradeComment;
mTradeVolume = tradeVolume;
mLeg = leg;
#ifdef __MQL5__
//init the indicator handles
// and set the buffers to series
HandleMa = iMA(Symbol(), Period(); mMaPeriods, 0, mMaMetod, mMaAppliedPrice);
Print("Could not create MA Handle");
mInitStatus - INIT_FAILED);
return;
}
ArraySetAsSeries(BufferMa, true);
HandleBands = iBands(Symbol(), Period(), mBandsPeriods, 0, mBandsDeviation, mBandsAppliedPrice);
if (HandleBands==INVALID_HANDLE) {
Print("Could not create Bands Handle");
mInitStatus = INIT_FAILED;
return;
}
ArraySetAsSeries(BufferBandsUpper, true);
ArraySetAsSeries(BufferBandsLower, true);
ArraySetAsSeries(BufferBandsMid, true);
// one time set the magic number
Trade. SetExpertMagicNumber(mMagicNumber);
##endif
FindCurrentTicket();
mInitStatus = INIT_SUCCEEDED;
}
~CCurrentTrade() {
#ifdef __MQL5__
IndicatorRelease(HandleMa);
IndicatorRelease(HandleBands);
#endif
}
// If already tracking a ticket check if still open\
// set to zero if closed
void CheckIfClosed() {
// if already tracking a ticket check if stil open
// if the ticket is still open then exit with nothing more to do
if (mCurrentTicket>0) {
if (IsTicketOpen(mCurrentTicket)) return;
// at this point i should be able to just assume there are not tickets
mCurrentTicket = 0;
}
} // end CheckIfClosed()
// function to update the current indicator values
void UpdateIndicators() {
#ifdef __MQL4__
mMa = iMA(Symbol(), Period(), mMaPeriods, 0, mMaMethod, mMaAppliedPrice, 1);
mBandUpper1 = iBands(Symbol(), Period(), mBandsPeriods, mBandsDeviation, 0, mBandsAppliedPrice, MODE_UPPER, 1);
mBandUpper2 = iBands(Symbol(), Period(), mBandsPeriods, mBandsDeviation, 0, mBandsAppliedPrice, MODE_UPPER, 2);
mBandLower1 = iBands(Symbol(), Period(), mBandsPeriods, mBandsDeviation, 0, mBandsAppliedPrice, MODE_LOWER, 1);
mBandLower2 = iBands(Symbol(), Period(), mBandsPeriods, mBandsDeviation, 0, mBandsAppliedPrice, MODE_LOWER, 2);
mBandMid = iBands(Symbol(), Period(), mBandsPeriods, mBandsDeviation, 0, mBandsAppliedPrice, MODE_MAIN, 1);
#endif
#ifdef __MQL5__
if (!FillBuffers()) return;
mMa = BufferMa[1];
mBandUpper1 = BufferBandsUpper[1];
mBandUpper2 = BufferBandsUpper[2];
mBandLower1 = BufferBandsLower[1];
mBandLower2 = BufferBandsLower[2];
mBandMid = BufferBandsMid[1];
#endif
mClose1 = iClose(Symbol(), Period(), 1);
mClose2 = iClose(Symbol(), Period(), 2);
mBid = SymbolBid(Symbol());
mAsk = SymbolAsk(Symbol());
} // end UpdateIndicators()
int GetOpenCondition() {
if ( (mClose2>mBandUpper2 && mClose2<mBandUpper1) // closed inside from above after being outside
&& (mMa>mBandMid) // ma above band mid for high side
&& (mMa<mBid) // price must be higher than ma
) {
return(-1); // sell
}
if ( (mClose2<mBandUpper2 && mClose2>mBandUpper1) // closed inside from below after being outside
&& (mMa<mBandMid) // ma below band mid for low side
&& (mMa>mAsk) // price must be lower than ma
) {
return(1); // buy
}
return(0); // nothing
} // end GetOpenCondition
// main processing loop
void OpenOnCondition(int condition) {
double tp = (mLeg==0) ? mMa : mBandMid;
double sl = 0;
if ( condition>0 ) { // BUY
// TP WILL DEPEND ON LEG NUMBER
// SL WILL BE RATIO FROM THE MA, SO SAME SL FOR BOTH LEGS
sl = mAsk-((mMa-mAsk) /mPLRatio);
OpenTrade(ORDER_TYPE_BUY, mAsk, sl, tp);
return;
}
if ( condition<0 ) { // SELL
// TP WILL DEPEND ON LEG NUMBER
// SL WILL BE RATIO FROM THE MA, SO SAME SL FOR BOTH LEGS
sl = mBid+((mBid-mMa) /mPLRatio);
OpenTrade(ORDER_TYPE_SELL, mBid, sl, tp);
return;
}
}
#ifdef __MQL4__
void SetBreakEven() {
if (mCurrentTicket<=0) return;
if (!OrderSelect((int)mCurrentTicket, SELECT_BY_TICKET)) return;
bool result = OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice(), OrderTakeProfit(), OrderExpiration());
}
void OpenTrade(ENUM_ORDER_TYPE type, double price, double sl, double tp) {
int ticket = OrderSend(Symbol(), type, mTradeVolume, price, 0, sl, tp, mTradeComment, mMagicNumber);
if (ticket>0) {
mCurrentTicket = ticket;
}
}
bool IsTicketOpen(ulong ticket) {
if (!OrderSelect((int)ticket, SELECT_BY_TICKET)) return(false);
if (OrderCloseTime()>0) return(false);
return(true);
}
// find a ticket for this EA if there is already one open
void FindCurrentTicket() {
mCurrentTicket =0;
int cnt = OrdersTotal();
for (int i=cnt-1; i>=0; i--) {
if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) continue;
if (OrderSymbol()==Symbol() && OrderMagicNumber()==mMagicNumber) {
mCurrentTicket = OrderTicket();
return;
}
}
}
#endif
#ifdef __MQL5__
bool FillBuffers() {
int maCount = CopyBuffer(HandleMa, 0, 0, 3, BufferMa);
int upperCount = CopyBuffer(HandleBands, UPPER_BAND, 0, 3, BufferBandsUpper);
int lowerCount = CopyBuffer(HandleBands, LOWER_BAND, 0, 3, BufferBandsLower);
int midCount = CopyBuffer(HandleBands, BASE_LINE, 0, 3, BufferBandsMid);
if (maCount<3 || upperCount<3 || lowerCount<3 || midCount<3) return(false);
return(true);
}
void BreakEven() {
if (!PositionSelectByTicket(mCurrentTicket)) return;
Trade.PositionModify(mCurrentTicket, PositionInfo.PriceOpen(); PositionInfo.TakeProfit());
}
void OpenTrade(ENUM_ORDER_TYPE type, double price, double sl, double tp) {
if (Trade.PositionOpen(Symbol(), type, mTradeVolume, price, sl, tp, mTradeComment)) {
mCurrentTicket = Trade.ResultOrder();
}
}
bool IsTicketOpen(long ticket) {
if (!PositionSelectByTicket(ticket)) return(false);
return(true);
}
//find a ticket for this EA if there is already one open
void FindCurrentTicket() {
mCurrentTicket = 0;
if (PositionInfo.SelectByMagic(Symbol(), mMagicNumber)) {
mCurrentTicket = PositionInfo.Ticket();
}
}
#endif
double SymbolAsk(string symbol) { return(SymbolInfoDouble(symbol, SYMBOL_ASK)); }
double SymbolBid(string symbol) { return(SymbolInfoDouble(symbol, SYMBOL_BID)); }
};