bplturner Can anyone tell me why these signals appear after I stop the backtest? They're the right signals that I want to use!
| Because your indicator is broken, and those signals only appear after the test on a chart refresh. |
-
RefreshRates();Unnecessary in a indicator as indicators can not sleep and predefined variables can not be out of date.
- int counted=prev_calculated;After the first run, counted = prev_calculated = Bars so limit is negative and you calculate nothing. See How to do your lookbacks correctly.
int limit = Bars - 1 - MathMax(RPeriod, counted);
:
return(rates_total); - if (limit < 1) limit = 1;Kluge because of #2. Remove!
- ExtMapBuffer1[limit] = Close[limit];You only want to initialize buffers once, when prev_calculated is zero.
ExtMapBuffer2[limit] = Close[limit]; - int limit = Bars - 1 - MathMax(RPeriod, counted);The look back for limit is maximum of one and lookback of DEst (whatever that is.) Not RPeriod.
int limit2 = Bars - 1 - MathMax(limit_RP, counted);
int limit3 = Bars - 1- MathMax(limit_dRP, counted);
:
double dimension_estimate = DEst(shift,N);
:
frama = alpha* Close[shift] + (1.0-alpha)* ExtMapBuffer1[shift+1];
:
ExtMapBuffer3[shift2] = ExtMapBuffer1[shift2] - ExtMapBuffer1[shift2+1];
:
ExtMapBuffer6[shift3]=iMAOnArray(ExtMapBuffer4, 0, dRPeriod, 0, MODE_EMA, shift3);
double dist = iATR(NULL,0,20,shift3)/2.0; - The look back for limit2 is lookback of limit plus one. Not limit_RP.
- The look back for limit3 is Maximum of 20, and lookback of limit2 plus dRPeriod-1.
- See How to do your lookbacks
correctly.
- ObjectDelete(ArrowsIdentifier+DoubleToString(Time[0]));Why are you deleting arrow zero and creating arrow shift3?
string name = ArrowsIdentifier+DoubleToString(Time[shift3]); - Why are you creating objects instead of using a arrow buffer?
- double FreeMargin = AccountFreeMargin();These are not changing. Assign them in OnTick
double lotMM = FreeMargin/OneLotMargin*Risk; - Margin has nothing to do with risk.
- You place the stop where it needs to be - where the reason for the trade is no longer valid. E.g. trading a support bounce the stop goes below the support.
- Account Balance * percent/100 = RISK = OrderLots * (|OrderOpenPrice - OrderStopLoss| * DeltaPerLot + CommissionPerLot) (Note OOP-OSL includes the SPREAD, and DeltaPerLot is usually around $10/pip but it takes account of the exchange rates of the pair vs. your account currency.)
- Do NOT use TickValue by itself - DeltaPerLot
- You must normalize lots
properly and check against min and max.
- You must also check FreeMargin to avoid stop out
- ATR = iCustom(Symbol(), 0, "ATR", RPeriod, 0, 0);Are you sure you want to look at bar zero and not all completed bars? Is there a difference between that indicator and iATR - Technical Indicators - MQL4 Reference?
X = iCustom(Symbol(),0, "FRAMA", RPeriod, multiplier, signal_multiplier, dRPeriod, check_slope_entry, Show_Arrow, ArrowsIdentifier, ArrowUpColor, ArrowDownColor, ArrowUpWidth, ArrowDownWidth, 7, 0); - You should write a self documenting function instead of calling iCustom directly, see Detailed explanation of iCustom - MQL4 forum
![MQL5 - Language of trade strategies built-in the MetaTrader 5 client terminal](https://c.mql5.com/i/registerlandings/logo-2.png)
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Hello,
I am having a strange problem. I watch the visual backtest and look at the signals, then when I stop it new signals appear that weren't there during the visual backtest? The ones that show once I stop are the right signals I want to use!
I have attached a picture showing the new signals that appear after I stop the backtest (in pink):
This is a simple fractal moving average EA that reads from a single indicator.
Here is the indicator source:
//+------------------------------------------------------------------+
// FractalAMA
//
// Description: Fractal Adaptive Moving Average - by John Ehlers
// Version 1.1 7/17/2006
//
// Heavily modified and reprogrammed by Matt Kennel (mbkennelfx@gmail.com)
//
// Notes:
// October 2005 Issue - "FRAMA - Fractal Adaptive Moving Average"
// Length will be forced to be an even number. Odd numbers will be bumped up to the
// next even number.
// Formula Parameters: Defaults:
// RPeriod 16
#property copyright "Copyright © 2005, MrPip " // and mbkennel
#property link "http://www.metaquotes.net/"
//---- indicator settings
#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1 Red
#property indicator_color2 Blue
#property indicator_color3 White
#property indicator_color4 White
#property indicator_color5 White
#property indicator_color6 White
#property indicator_color7 White
#property indicator_color8 White
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
double ExtMapBuffer5[];
double ExtMapBuffer6[];
double ExtMapBuffer7[];
double ExtMapBuffer8[];
extern int RPeriod = 16; //Averaging period
extern double multiplier = 4.6;
extern double signal_multiplier = 2.5;
extern int dRPeriod = 10; //Differential averaging period
extern int check_slope_entry = true;
//Arrow properties
extern bool Show_Arrow = true;
string ArrowsIdentifier = "EFTarrow";
color ArrowUpColor = Aqua;
color ArrowDownColor = Red;
int ArrowUpWidth = 1;
int ArrowDownWidth = 1;
int limit_RP = RPeriod+1;
int limit_RPd = limit_RP+1;
int limit_dRP = dRPeriod + limit_RPd;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//---- 1 additional buffers are used for counting.
IndicatorBuffers(8);
//---- drawing settings
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,2);
SetIndexShift(0,0);
SetIndexLabel(0, "FRAMA");
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,2);
SetIndexShift(1,0);
SetIndexLabel(1, "FRAMA Signal");
SetIndexBuffer(2,ExtMapBuffer3);
SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,1);
SetIndexShift(2,0);
SetIndexLabel(2, "dFRAMA");
SetIndexBuffer(3,ExtMapBuffer4);
SetIndexStyle(3,DRAW_LINE,STYLE_SOLID,1);
SetIndexShift(3,0);
SetIndexLabel(3, "dFRAMA+");
SetIndexBuffer(4,ExtMapBuffer5);
SetIndexStyle(4,DRAW_LINE,STYLE_SOLID,1);
SetIndexShift(4,0);
SetIndexLabel(4, "dFRAMA-");
SetIndexBuffer(5,ExtMapBuffer6);
SetIndexStyle(5,DRAW_LINE,STYLE_SOLID,1);
SetIndexShift(5,0);
SetIndexLabel(5, "dFRAMA+Avg");
SetIndexBuffer(6,ExtMapBuffer7);
SetIndexStyle(6,DRAW_LINE,STYLE_SOLID,1);
SetIndexShift(6,0);
SetIndexLabel(6, "dFRAMA-Avg");
SetIndexBuffer(7,ExtMapBuffer8);
SetIndexStyle(7,DRAW_LINE,STYLE_SOLID,1);
SetIndexShift(7,0);
SetIndexLabel(7, "Cross");
//---- initialization done
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime& time[],
const double& open[],
const double& high[],
const double& low[],
const double& close[],
const long& tick_volume[],
const long& volume[],
const int& spread[])
{
ArraySetAsSeries(time, true);
ArraySetAsSeries(open, true);
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
ArraySetAsSeries(tick_volume, true);
ArraySetAsSeries(volume, true);
ArraySetAsSeries(spread, true);
ArraySetAsSeries(ExtMapBuffer1, true);
ArraySetAsSeries(ExtMapBuffer2, true);
ArraySetAsSeries(ExtMapBuffer3, true);
ArraySetAsSeries(ExtMapBuffer4, true);
ArraySetAsSeries(ExtMapBuffer5, true);
ArraySetAsSeries(ExtMapBuffer6, true);
ArraySetAsSeries(ExtMapBuffer7, true);
ArraySetAsSeries(ExtMapBuffer8, true);
RefreshRates();
int counted=prev_calculated;
if (Bars < RPeriod) return(0);
//int maxshift = Bars-RPeriod-1;
//int limit= maxshift - counted_bars;
int limit = Bars - 1 - MathMax(RPeriod, counted);
int limit2 = Bars - 1 - MathMax(limit_RP, counted);
int limit3 = Bars - 1- MathMax(limit_dRP, counted);
if (limit < 1) limit = 1;
int N = MathFloor(RPeriod/2)*2; // Force N to even number
double frama = Close[limit];
double signal = frama;
ExtMapBuffer1[limit] = Close[limit];
ExtMapBuffer2[limit] = Close[limit];
for(int shift = limit; shift >= 0; shift--) {
double dimension_estimate = DEst(shift,N);
double alpha = MathExp(-multiplier*(dimension_estimate-1.0));
double alphas = MathExp(-signal_multiplier*(dimension_estimate-1.0));
if (alpha > 1.0) alpha = 1.0;
if (alpha < 0.01) alpha = 0.01;
if (alphas > 1.0) alphas = 1.0;
if (alphas < 0.01) alphas = 0.01;
frama = alpha* Close[shift] + (1.0-alpha)* ExtMapBuffer1[shift+1];
signal = alphas * frama + (1.0 - alphas)* ExtMapBuffer2[shift+1];
ExtMapBuffer1[shift] = frama;
ExtMapBuffer2[shift] = signal;
}
for(int shift2 = limit2; shift2>=0; shift2--) {
ExtMapBuffer3[shift2] = ExtMapBuffer1[shift2] - ExtMapBuffer1[shift2+1];
if(ExtMapBuffer3[shift2]> 0) {
ExtMapBuffer4[shift2] = ExtMapBuffer3[shift2];
ExtMapBuffer5[shift2] = 0;
} else if(ExtMapBuffer3[shift2]< 0) {
ExtMapBuffer5[shift2] = ExtMapBuffer3[shift2];
ExtMapBuffer4[shift2] = 0;
}
else {
ExtMapBuffer4[shift2] = 0;
ExtMapBuffer5[shift2] = 0;
}
//Cross
if(ExtMapBuffer1[shift2] > ExtMapBuffer2[shift2] && ExtMapBuffer1[shift2+1] <= ExtMapBuffer2[shift2+1]) {
ExtMapBuffer8[shift2] = -1;
}
else if(ExtMapBuffer1[shift2] < ExtMapBuffer2[shift2] && ExtMapBuffer1[shift2+1] >= ExtMapBuffer2[shift2+1]) {
ExtMapBuffer8[shift2] = 1;
}
else {
ExtMapBuffer8[shift2] = 0;
}
}
for(int shift3 = limit3; shift3>=0; shift3--) {
ExtMapBuffer6[shift3]=iMAOnArray(ExtMapBuffer4, 0, dRPeriod, 0, MODE_EMA, shift3);
ExtMapBuffer7[shift3]=iMAOnArray(ExtMapBuffer5, 0, dRPeriod, 0, MODE_EMA, shift3);
double check_slope = 1;
if(check_slope_entry) {
if(ExtMapBuffer6[shift3]>=ExtMapBuffer4[shift3] || ExtMapBuffer7[shift3]<=ExtMapBuffer5[shift3]) {
check_slope = 1;
} else {
check_slope = 0;
}
}
//Arrows
if (Show_Arrow)
{
double dist = iATR(NULL,0,20,shift3)/2.0;
ObjectDelete(ArrowsIdentifier+DoubleToString(Time[0]));
string name = ArrowsIdentifier+DoubleToString(Time[shift3]);
if (ExtMapBuffer8[shift3] == -1 && check_slope > 0)
{
ObjectCreate(name,OBJ_ARROW,0, Time[shift3],Low[shift3]-dist );
ObjectSet(name,OBJPROP_ARROWCODE,225);
ObjectSet(name,OBJPROP_COLOR,ArrowUpColor);
ObjectSet(name,OBJPROP_WIDTH,ArrowUpWidth);
}
else if(ExtMapBuffer8[shift3] == 1 && check_slope > 0)
{
ObjectCreate(name,OBJ_ARROW,0, Time[shift3],High[shift3]+dist );
ObjectSet(name,OBJPROP_ARROWCODE,226);
ObjectSet(name,OBJPROP_COLOR,ArrowDownColor);
ObjectSet(name,OBJPROP_WIDTH,ArrowDownWidth);
}
else
{
}
}
}
return(rates_total);
}
double DEst(int shift, int n) {
//
double R1, R2, R3;
int n2 = n/2;
R3 = Range(shift,n) / n;
R1 = Range(shift,n2) / n2;
R2 = Range(shift+n2,n2) / n2;
return( (MathLog(R1+R2)-MathLog(R3) )* 1.442695 ) ; // log_2(e) = 1.442694
}
double Range(int i, int k) {
return( High[Highest(NULL,0,MODE_HIGH,k,i)] - Low[Lowest(NULL,0,MODE_LOW,k,i)] );
}
And here is the EA source:
//+------------------------------------------------------------------+
//| MACD Sample.mq4 |
//| Copyright 2005-2014, MetaQuotes Software Corp. |
//| http://www.mql4.com |
//+------------------------------------------------------------------+
#property copyright "BPLTURNER"
#property link "NO."
extern int RPeriod = 16; //Averaging period
extern double multiplier = 4.6;
extern double signal_multiplier = 2.5;
extern int dRPeriod = 10; //Differential averaging period
extern int check_slope_entry = true;
//Arrow properties
extern bool Show_Arrow = true;
string ArrowsIdentifier = "EFTarrow";
color ArrowUpColor = Aqua;
color ArrowDownColor = Red;
int ArrowUpWidth = 1;
int ArrowDownWidth = 1;
//Risk management parameters
input string Risk_Parameters = "--- Risk Management ---";
input bool OpenNewBar = false;
input double StopLossM = 3;
input double TakeProfitM =0;
input double TrailingStopM =0.25;
input double Risk =0.1;
input double MaximumSlippage = 3;
input double MaximumOrders = 1;
double StopLoss = 0;
double TakeProfit = 0;
double TrailingStop = 0;
double X = 0;
double ATR = 0;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
static datetime _lastBarTime = 0; // DateTime of the last new bar which opened
double OneLotMargin = MarketInfo(Symbol(),MODE_MARGINREQUIRED);
double FreeMargin = AccountFreeMargin();
double lotMM = FreeMargin/OneLotMargin*Risk;
double LotStep = MarketInfo(Symbol(),MODE_LOTSTEP);
double Lots = NormalizeDouble(lotMM/LotStep,0)*LotStep;
void OnTick(void)
{
if(Bars<100)
{
Print("bars less than 100");
return;
}
int cnt,ticket,total;
//---
// initial data checks
// it is important to make sure that the expert works with a normal
// chart and the user did not make any mistakes setting external
// variables (Lots, StopLoss, TakeProfit,
// TrailingStop) in our case, we check TakeProfit
// on a chart of less than 100 bars
//---
// if(TakeProfit<10)
// {
// Print("TakeProfit less than 10");
// return;
// }
//--- to simplify the coding and speed up access data are put into internal variables
//Calculate our stop loss, trailing and profit using the ATR and multipliers
ATR = iCustom(Symbol(), 0, "ATR", RPeriod, 0, 0);
ATR = MathPow(ATR, 1.1);
StopLoss=StopLossM*ATR/Point;
TakeProfit=TakeProfitM*ATR/Point;
TrailingStop=TrailingStopM*ATR/Point;
RefreshRates();
X = iCustom(Symbol(),0, "FRAMA", RPeriod,multiplier,signal_multiplier,dRPeriod,check_slope_entry,Show_Arrow,ArrowsIdentifier,ArrowUpColor,ArrowDownColor,ArrowUpWidth,ArrowDownWidth, 7, 0);
//exit1=iCustom(Symbol(),0,"StochasticTrigger",K1,D1,S1,U1,L1,K2,D2,S2,U2,L2,6,0);
//exit2=iCustom(Symbol(),0,"StochasticTrigger",K1,D1,S1,U1,L1,K2,D2,S2,U2,L2,7,0);
//Price calculation parameters
PrintFormat("X: %f", X);
//Calculate buy/sell based on our signals
int bs = 0;
if(X<0)
{
bs=-1;
}
else if (X>0)
{
bs=1;
}
else
{
bs=0;
}
//Calculate our exit signals
int exitSell = 0;
int exitBuy = 0;
if(X<0) //Either we've cross under a long term stochastic, or we went back into overbought territory
{
exitSell = 1;
}
else if (X>0) //Either we've cross over a long term stochastic, or we went back into oversold territory
{
exitBuy = 1;
}
else
{
exitSell = 0;
exitBuy = 0;
}
//Debug information
//PrintFormat("StochX1: %f, StochX2: %f, BS: %f", stochX1, stochX2, bs);
//See if we're opening on new bars only
if(OpenNewBar && !NewBar()) {
bs = 0;
}
total=OrdersTotal();
//if(total<1 && total<MaximumOrders)
if(total<MaximumOrders)
{
//--- no opened orders identified
if(AccountFreeMargin()<(1000*Lots))
{
Print("We have no money. Free Margin = ",AccountFreeMargin());
return;
}
//--- check for long position (BUY) possibility
double stoplevel=0;
double profitlevel=0;
if(bs<0)
{
//If using stop loss
if(StopLoss>0)
{
stoplevel = Ask-StopLoss*Point;
}
else
{
stoplevel=0;
}
//If using take profit
if(TakeProfit>0)
{
profitlevel = Ask+TakeProfit*Point;
}
else
{
profitlevel=0;
}
ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,MaximumSlippage,stoplevel,profitlevel,"Money Volume",16384,0,Green);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("BUY Order Opened : ",OrderOpenPrice());
}
else
Print("Error Opening BUY Order : ",GetLastError());
return;
}
//--- check for short position (SELL) possibility
if(bs>0)
{
//If using stop loss
if(StopLoss>0)
{
stoplevel = Bid+StopLoss*Point;
}
else
{
stoplevel=0;
}
//If using take profit
if(TakeProfit>0)
{
profitlevel = Bid-TakeProfit*Point;
}
else
{
profitlevel=0;
}
ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,MaximumSlippage,stoplevel,profitlevel,"Money Volume",16384,0,Red);
if(ticket>0)
{
if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
Print("SELL Order Opened : ",OrderOpenPrice());
}
else
Print("Error Opening SELL Order : ",GetLastError());
}
//--- exit from the "no opened orders" block
return;
}
//--- it is important to enter the market correctly, but it is more important to exit it correctly...
for(cnt=0;cnt<total;cnt++)
{
if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
continue;
if(OrderType()<=OP_SELL && // check for opened position
OrderSymbol()==Symbol()) // check for symbol
{
//--- long position is opened
if(OrderType()==OP_BUY)
{
//--- should it be closed?
if(exitBuy > 0)
{
//--- close order and exit
if(!OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet))
Print("OrderClose error ",GetLastError());
return;
}
//--- check for trailing stop
if(TrailingStop>0)
{
if(Bid-OrderOpenPrice()>Point*TrailingStop)
{
if(OrderStopLoss()<Bid-Point*TrailingStop)
{
//--- modify order and exit
if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
Print("OrderModify error ",GetLastError());
return;
}
}
}
}
else // go to short position
{
//--- should it be closed?
if(exitSell > 0)
{
//--- close order and exit
if(!OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet))
Print("OrderClose error ",GetLastError());
return;
}
//--- check for trailing stop
if(TrailingStop>0)
{
if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
{
if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
{
//--- modify order and exit
if(!OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red))
Print("OrderModify error ",GetLastError());
return;
}
}
}
}
}
}
//---
}
//+------------------------------------------------------------------+
void OnInit()
{
_lastBarTime = iTime(Symbol(),0,0);
}
bool NewBar() {
if (iTime(Symbol(),Period(),0) != _lastBarTime) {
_lastBarTime = iTime(Symbol(), Period(),0);
return (true);
} else
return (false);
}
Can anyone tell me why these signals appear after I stop the backtest? They're the right signals that I want to use!