Alex you have been of great help and thank you for it.
Indeed using the “open” produces identical historical and live bars.
There is of course the disadvantage that on larger time frames the efs is lagging a lot from real time price fluctuations.
Is there any way at all that the efs can be tweaked to work with “close” instead of “open” and produce identical historical and live bars?
Or is it a rule that when using multi timeframe intervals the historic bars will differ from the live ones?
Could maybe something be done to the eSignal engine to resolve this?
Thank you in advance.
Announcement
Collapse
No announcement yet.
Problem with multi timeframe intervals custom efs
Collapse
X
-
Thank you Alex for your extensive reply and suggestions.
You are the man !
Will be trying to apply the points you made to the efs that I use with multi intervals, will test them when the markets are open and will revert.
Leave a comment:
-
gem2004
FWIW here are a few additional considerations on how to streamline/simplify your script taking better advantage of the functionality of EFS2
1) In each of the routines you calculate an RSI and use its values to populate an array which you then use to calculate its average. As an example here is your AAARoutine [Note that I am assuming that you set the rsi() function to use the Open and that you implemented the change I suggested earlier whereby the whole routine is running in the context of the interval being passed to it by the efsInternal() call. Also note that I omitted showing the declaration of global variables as that is not the point I am trying to make here]
PHP Code:function AAARoutine() {
if (bInitAAA == false) {
xStudyRSI = rsi(14, open());
bInitAAA = true;
}
nRSIVal = xStudyRSI.getValue(0);
if (nRSIVal == null) return;
nMALength = 3;
var nBarStateAAA = getBarState();
if (nBarStateAAA == BARSTATE_NEWBAR) {
vMAArray.unshift(nRSIVal);
}
vMAArray[0] = nRSIVal;
if (vMAArray[nMALength - 1] != null) {
var vSum = 0;
for (i = 0; i <= nMALength - 1; i++) {
vSum += vMAArray[i];
}
nRSIAAA = vSum / nMALength + 15;
} else return;
if (nRSIAAA < 0) {
nRSIAAA = 0;
} else if (nRSIAAA > 100) {
nRSIAAA = 100;
}
return nRSIAAA;
}
PHP Code:function AAARoutine() {
if (bInitAAA == false) {
xStudyRSI = sma(3, rsi(14, open()));
bInitAAA = true;
}
return xStudyRSI.getValue(0);
}
PHP Code:...
if (xStudyAAA == null) xStudyAAA = efsInternal("AAARoutine", inv(nInvA));//here you call the function
...
// AAA
if (getBarStateInterval(nInvA + "") == BARSTATE_NEWBAR) {
nRSIAAA = xStudyAAA.getValue(0);
nRSIPrevAAA = xStudyAAA.getValue(-1);
if (nRSIAAA == null || nRSIPrevAAA == null) return;
nRSIDiffAAA = nRSIAAA - nRSIPrevAAA;
}
a) You wrap the efsIntenal() call in the mom() function and set its length to 1
PHP Code:...
if (xStudyAAA == null) xStudyAAA = mom(1, efsInternal("AAARoutine", inv(nInvA)));
...
b) Alternatively you can calculate the Momentum in the separate function itself e.g
PHP Code:function AAARoutine() {
if (bInitAAA == false) {
xStudyRSI = mom(1,sma(3,rsi(14,open())));
bInitAAA = true;
}
return xStudyRSI.getValue(0);
}
3) Lastly your three routines (I am referring to the separate functions) are exactly the same which is redundant.
You can just use one separate function and call that multiple times using different efsInternal() calls. Each time it is called the separate function will run in the context of the parameters it is being passed ie as if it were a completely different function.
Following is your efs rewritten based on all of the above
PHP Code:var bInit = false;
var xStudyAAA = null;
var xStudyBBB = null;
var xStudyCCC = null;
function preMain() {
setStudyTitle("Multi_Intervals");
setPriceStudy(false);
setShowCursorLabel(true);
setShowTitleParameters(false);
setCursorLabelName("Multi", 0);
setDefaultBarThickness(3, 0);
setDefaultBarStyle(PS_SOLID, 0);
setPlotType(PLOTTYPE_LINE, 0);
}
function main() {
if (bInit == false) {
if (isWatchList()) return;
if (!isIntraday()) return;
if (getCurrentBarCount() <= 100) return;
var nInterval = getInterval();
var nTFCoeff = nInterval;
var nInvA = 1 * nTFCoeff;//does not need to be a global variable
var nInvB = 2 * nTFCoeff;//as above
var nInvC = 3 * nTFCoeff;//as above
if (xStudyAAA == null) xStudyAAA = mom(1, efsInternal("AAARoutine", inv(nInvA)));
if (xStudyBBB == null) xStudyBBB = mom(1, efsInternal("AAARoutine", inv(nInvB)));
if (xStudyCCC == null) xStudyCCC = mom(1, efsInternal("AAARoutine", inv(nInvC)));
/*alternatively you can use the following and calculate the Momenhtum in the separate function itself
if (xStudyAAA == null) xStudyAAA = efsInternal("AAARoutine", inv(nInvA));
if (xStudyBBB == null) xStudyBBB = efsInternal("AAARoutine", inv(nInvB));
if (xStudyCCC == null) xStudyCCC = efsInternal("AAARoutine", inv(nInvC));*/
bInit = true;
}
//add some null checks for xStudyAAA.getValue(0), etc here
var nSumOfDiffDoubled = (xStudyAAA.getValue(0) + xStudyBBB.getValue(0) + xStudyCCC.getValue(0)) * 2;
return nSumOfDiffDoubled;
}
var bInitAAA = false;
var xStudyRSI = null;
function AAARoutine() {
if (bInitAAA == false) {
xStudyRSI = sma(3,rsi(14,open()));
/*if you use the alternative method in the main function then use the following
xStudyRSI = mom(1, sma(3,rsi(14,open())));*/
bInitAAA = true;
}
//add null check for xStudyRSI.getValue(0) here
return xStudyRSI.getValue(0);
}
Here is how the efs will look
PHP Code:var bInit = false;
var xStudyAAA = null;
var xStudyBBB = null;
var xStudyCCC = null;
function preMain() {
setStudyTitle("Multi_Intervals");
setPriceStudy(false);
setShowCursorLabel(true);
setShowTitleParameters(false);
setCursorLabelName("Multi", 0);
setDefaultBarThickness(3, 0);
setDefaultBarStyle(PS_SOLID, 0);
setPlotType(PLOTTYPE_LINE, 0);
}
function main() {
if (bInit == false) {
if (isWatchList()) return;
if (!isIntraday()) return;
if (getCurrentBarCount() <= 100) return;
var nInterval = getInterval();
var nTFCoeff = nInterval;
var nInvA = 1 * nTFCoeff;//does not need to be a global variable
var nInvB = 2 * nTFCoeff;//as above
var nInvC = 3 * nTFCoeff;//as above
if (xStudyAAA == null) xStudyAAA = mom(1,sma(3,rsi(14,open(inv(nInvA)))));
if (xStudyBBB == null) xStudyBBB = mom(1,sma(3,rsi(14,open(inv(nInvB)))));
if (xStudyCCC == null) xStudyCCC = mom(1,sma(3,rsi(14,open(inv(nInvC)))));
bInit = true;
}
//add some null checks for xStudyAAA.getValue(0), etc here
var nSumOfDiffDoubled = (xStudyAAA.getValue(0) + xStudyBBB.getValue(0) + xStudyCCC.getValue(0)) * 2;
return nSumOfDiffDoubled;
}
Alex
Leave a comment:
-
Alex, thank you once again for the elucidations. Each line you write saves me hours of trial and error.
Will work on your suggestions and I am sure that I will get to where I want to go eventually.
Leave a comment:
-
gem2004
...if I modify the studies that are inside the multiple efsInternals that I use, like RSI, MACD etc to work with the open instead of the close of the bar, then both the historic and the live bars would be identical.
On a separate but related topic I see that you are passing the interval series object as the last parameter of each of your efsInternal() calls but then you are also passing the interval series object to each rsi() function within each called function
That is somewhat redundant since if you call a function (or a separate efs) using an efsInternal() (or efsExternal()) call and within that call you pass the interval (or symbol) series object as the last parameter the function you are calling will run in the context of the interval (or symbol) that is being passed to that function.
In other words the following code (note that this is just a very basic example to illustrate the concept)
PHP Code:function main(){
var x = efsInternal("calc",inv(30));
return x;
}
function calc(){
return rsi(14);
}
PHP Code:function main(){
var x = efsInternal("calc",inv(30));
return x;
}
function calc(interval){
return rsi(14,interval);
}
PHP Code:function main(){
var x = rsi(14,inv(30));
return x;
}
You can see more examples on the use of efsInternal() in this and this thread
Alex
Originally posted by gem2004 View PostThank you Alex for your prompt clarification. For over a decade now you have been of great help.
I do see the point you make.
If I understand it well, if I modify the studies that are inside the multiple efsInternals that I use, like RSI, MACD etc to work with the open instead of the close of the bar, then both the historic and the live bars would be identical.
By the way, I also tried using setComputeOnClose() but with multi timeframe intervals the live bars lag a few bars and I could not find a workaround to make them print on a bar the moment it closes.
Leave a comment:
-
Thank you Alex for your prompt clarification. For over a decade now you have been of great help.
I do see the point you make.
If I understand it well, if I modify the studies that are inside the multiple efsInternals that I use, like RSI, MACD etc to work with the open instead of the close of the bar, then both the historic and the live bars would be identical.
By the way, I also tried using setComputeOnClose() but with multi timeframe intervals the live bars lag a few bars and I could not find a workaround to make them print on a bar the moment it closes.
Leave a comment:
-
gem2004
The issue you are seeing is due to the fact that when running in real time you are calculating nRSIDiffAAA, nRSIDiffBBB and nRSIDiffCCC at BARSTATE_NEWBAR (for each interval) i.e. on the first tick of each corresponding bar using the values at the opening of those bars which is going to give you a different result than when you reload the chart and all of those same bars are now completed
Here is a very basic sample script that illustrates your issue
Run it on a chart and you will see that the value being returned in real time is essentially that of the Open of each bar even though I am retrieving the Close (because on the first tick of a bar the Close is the same as the Open).
If you let it run for some bars and then reload the script (or refresh the chart) you will see that all those "real time" values will change because they now return the value of the Close of the completed historical bars
Alex
Originally posted by gem2004 View PostHave been using a custom made efs with multiple timeframe intervals, with the great help that the forum and the knowledge base provide.
The problem that I face is that when it is loaded on a chart the first 300 historic bars differ substantially from the values that were shown when the same bars were run live. Despite all my efforts I cannot make them identical. So obviously I am missing something or doing it incorrectly.
I have created the following simplified version that incorporates the points that I wish to have included.
Any assistance will be highly appreciated, thanking you in advance.
Leave a comment:
-
Problem with multi timeframe intervals custom efs
Have been using a custom made efs with multiple timeframe intervals, with the great help that the forum and the knowledge base provide.
The problem that I face is that when it is loaded on a chart the first 300 historic bars differ substantially from the values that were shown when the same bars were run live. Despite all my efforts I cannot make them identical. So obviously I am missing something or doing it incorrectly.
I have created the following simplified version that incorporates the points that I wish to have included.
Any assistance will be highly appreciated, thanking you in advance.Attached FilesTags: None
Leave a comment: