NOTE: if you can't see the 3D graphs and file attachements at the end of this post, please LOG IN
Well finally I have done it.
I had to rewrite the code from scratch to incorporate several new ideas into the concept that take the whole thing a littlebit further.
First of all, there are three figures that explain how the Zones are treated within the statistics. The
Zone is defined as an area either
above or
below the particular percentage. The percentage is calculated from the extreme prices of the bar (high & low) to the inside of the bar.
Have a look at
Figure 1 below:
This was the initially tested setup with the 50% Zones. The only difference is that now the area in between the upper Zone and the Lower Zone is considered to be of "no Zone" regardless of the previous bar's Zone.
Now have a look at
Figure 2:
What we did was that we changed the setting from the
50% Zone (the originally tested MidPoint) to
30% Zone. The bar's close price is considered to be in this 30 % Zone only if it closes above the 30 % boundary (above 1.2770 price) or below the 30 % boundary (below 1.2730 price). So for example, if it closes at 1.2770, 1.2750 or 1.2730, it has closed in the
no Zone area (I'm almost tempted to call it a twilight Zone
If you now look at
Figure 3, then it starts to get really hot:
We are now examining whether the bar's close was
outside the previous bar's range and
at least 20% off of either previous bar's high or low. I call this a
-20% Zone.
You can examine any percentage setting from minus infinity to +50%. Why the +50% is the maximum setting? Because above 50% the Zones would overlap. If you set the Zone % to zero (0 %), then you are examining whether the bar closed anywhere above or below the previous bar's range.
Now imagine that you will run stats with not only one Zone percentage setting, but with a whole range from -150% to +50%. This was what I did and you are encouraged to do further experimentation with my code (attached below). I've set the resolution (the smallest step) to be 10%, so the examined percentages were -150%, -140% ... to +50%.
Just a little refresher here, the statistics counts what is the probability of the next bar to close in the same Zone as the current bar did if we know how many consecutive bars (including the current one) has had the close in this Zone (either upper Zone or the lower Zone).
The statistics plots the Zone percentages on one axis, the number of consecutive bars so far on the second axis and the probability in % that the next bar will stay in the same Zone on the third axis. To illustrate, let's have a look at the following table and notice the highlighted cell in the middle:
It shows that in EURUSD 15 min statistics, there is a
26.96% probability that the next bar will close in the same Zone (0 % Zone - outside of the previous bar, row
0 in the table) if the bar has closed in this 0% Zone for 4 consecutive bars already (column
4 in the table). Keep in mind that the results are additive, so that if there is a 26.96% probability that the next bar
will close in the same Zone, then there is also a 73.04% (100 - 26.96) probability that the next bar
won't close in the same Zone after 4 consecutive closes in the current Zone. (Why? Well because the bar has to close somewhere after all and it only may close either in the present Zone or outside the present Zone).
For the bar's close to be considered in the same Zone, it has to close on the
same side of the previous bar, i.e. either in the
upper Zone or in the
lower Zone.
Instead of the probabilities, you may also choose the program to print the number of cases (observations) by changing the
iPrintProbOrCases parameter. This means that you will see in the output table how many times there was a case when the bar closed in the particular Zone for a particular number of consecutive bars. To illustrate, have a look at the following table:
It shows that there were
2018 cases in the data sample of EURUSD 15 min where the bar closed on the same side and outside the previous bar completely (0% Zone, row
0) for a total of 3 consecutive bars, including the current one (column
3). You see, using the statistics is pretty simple.
Of course, there's more to the stats than just plain boring excel sheets
You wouldn't get a general view of what's going on behind the scenes by just observing the plain numbers in the spreadsheet. Thus, attached you will find 3D graphs with probabilities and number of cases for several example symbol/timeframe combinations. Go ahaed and use my program to export the data by yourself and create similar 3D graphs in excel with a single click of your mouse for the symbol/timeframe/settings of your wish.
Please keep in mind that if you want to change the program settings, you need to do this manually by hand right in the first section of the program labelled "global declarations". I'm sorry for this inconvenience, but unfortunately, EasyLanguage doesn't support dynamically allocated multidimensional arrays nor does it support assinging the static array boundaries via inputs
All the parameters are well commented by me in the code, so you shouldn't have any problem changing them by hand. If so, feel free to contact me and I'll help you. After all, if you don't want to change any settings, just leave the code alone and apply it to the chart, it will work as is.
What's the conslusion from this research? There are clearly detectable and statistically signifiant tendencies in this concept. If you focus on refining and incorporating these statistics into your system development, it may bring you real money.
After all, everything you need as a foundation for a successful trading system is a phenomenon which occurs with other than 50% probability consistently and its occurence is statistically significant. This research uncovers such a phenomenon
Have a very nice day!
Michal
Attached:
- ELD file
- 3D graphs
- sample output statistics in zip file
code:
Code: Select all
{
program name: 3DZone statistics
last change: Jun/03/2006
version: 5.23
author: Michal Kreslik
email: michal.kreslik @ kreslik.com
website: http:// kreslik.com
comments: prints 3D Zone statistics
}
{ ***** begin global declarations ***** }
vars: { inputs }
iZonePercentStart( -150 ),
{ first % Zone to be examined, you may use negative % }
iZonePercentEnd( 50 ),
{ last % Zone to be examined, max: 50% }
iTotalNumberOfZones( 21 ),
{ how many Zones }
iMaxConsecutiveBars( 12 ),
{ max number of consecutive bars in the same Zone }
iMinNumOfCases( 50 ),
{ minumim number of observations to deem the results statistically significant }
iFileFolder( "c:\data\temp" ),
{ directory to save the resulting files(s) to }
iPercentDecPrecision( 2 ),
{ number of decimal places to use for the export of % proabbilities }
iStatInsignChar( -1 ),
{ character or number to use for a statistically insignificant value }
iAppendMode( false ),
{ if set to true, then append the results to the existing file
if set to false, create a brand new file for every test }
iRepeatCells( true ),
{ repeat columns in the output file to allow for more homogenous 3D display }
iPrintProbOrCases( 0 );
{ print the restuls either as
- % probabilities (set this variable to 0)
- the number of cases/observations (set this variable to 1) }
{ ***** begin array inputs
WARNING! you must set the following array boundaries by hand since EasyLanguage
does not allow for array boundaries to be set by an input variable! ***** }
arrays: { inputs }
anCasesOfStay[21, 12]( 0 ), { main array }
anCasesOfAbandonment[21, 12]( 0 ), { main array }
anUpperZoneBndaries[21]( 0 ),
anLowerZoneBndaries[21]( 0 ),
anZoneState[21]( 0 ), { -1 = lower Zone, 0 = no Zone, 1 = upper Zone}
anZoneStayCounter[21]( 0 ), { always >= 1 }
anZonePercentages[21]( 0 ),
abRunStatsFThisZone[21]( false ),
abZoneAbandoned[21]( false );
{ ***** end array inputs **** }
vars: { numerical }
nZonePercentageStep( 0 ),
nTradingDays( 0 ),
nRealMaxConsecBars( 0 ),
nRepeatCellCount( 0 );
vars: { string & temporary}
sStartDate( "" ),
tZoneIndex( 0 );
vars: { boolean }
bMaxBarsExceeded( false ),
intrabarpersist bFirstRun( true );
{ ***** end global declarations ***** }
{ ***** begin program ***** }
if iZonePercentEnd <= 50 AND iMinNumOfCases > 0 then
begin
{ ***** begin data collection ***** }
if BarNumber = 1 then
begin
sStartDate = DateToString(DateToJulian(date));
nZonePercentageStep = (iZonePercentEnd - iZonePercentStart)/(iTotalNumberOfZones - 1);
for tZoneIndex = 1 to iTotalNumberOfZones
begin
anZonePercentages[tZoneIndex] = iZonePercentStart + (tZoneIndex - 1)*nZonePercentageStep;
end;
end;
if date <> date[1] then
nTradingDays = nTradingDays + 1;
for tZoneIndex = 1 to iTotalNumberOfZones
begin
abZoneAbandoned[tZoneIndex] = false;
anUpperZoneBndaries[tZoneIndex] = high - (high - low)*anZonePercentages[tZoneIndex]/100;
anLowerZoneBndaries[tZoneIndex] = low + (high - low)*anZonePercentages[tZoneIndex]/100;
if close > anUpperZoneBndaries[tZoneIndex][1] then
anZoneState[tZoneIndex] = 1
else if close < anLowerZoneBndaries[tZoneIndex][1] then
anZoneState[tZoneIndex] = -1
else if close >=anLowerZoneBndaries[tZoneIndex][1] AND
close <= anUpperZoneBndaries[tZoneIndex][1] then
anZoneState[tZoneIndex] = 0;
if anZoneState[tZoneIndex] <> anZoneState[tZoneIndex][1] then
begin
abZoneAbandoned[tZoneIndex] = true;
anZoneStayCounter[tZoneIndex] = 1;
end
else
anZoneStayCounter[tZoneIndex] = anZoneStayCounter[tZoneIndex] + 1;
if abRunStatsFThisZone[tZoneIndex] = false
AND abZoneAbandoned[tZoneIndex]
AND anZoneState[tZoneIndex] <> 0
AND BarNumber > 1 then
abRunStatsFThisZone[tZoneIndex] = true;
if abRunStatsFThisZone[tZoneIndex][1]
AND anZoneState[tZoneIndex][1] <> 0 then
begin
nRealMaxConsecBars = MaxList(nRealMaxConsecBars, anZoneStayCounter[tZoneIndex][1]);
if anZoneStayCounter[tZoneIndex][1] <= iMaxConsecutiveBars then
begin
if abZoneAbandoned[tZoneIndex] then
anCasesOfAbandonment[tZoneIndex, anZoneStayCounter[tZoneIndex][1]]
= anCasesOfAbandonment[tZoneIndex, anZoneStayCounter[tZoneIndex][1]] + 1
else
anCasesOfStay[tZoneIndex, anZoneStayCounter[tZoneIndex][1]]
= anCasesOfStay[tZoneIndex, anZoneStayCounter[tZoneIndex][1]] + 1;
end
else
bMaxBarsExceeded = true;
end;
end; { for tZoneIndex = 1 to iTotalNumberOfZones }
{ ***** end data collecion ***** }
{ ***** begin analysis **** }
if LastBarOnChart AND bFirstRun then
begin
bFirstRun = false;
if iRepeatCells then
nRepeatCellCount = round(iTotalNumberOfZones/iMaxConsecutiveBars, 0)
else
nRepeatCellCount = 1;
{ ***** begin local declarations ***** }
vars: { string }
sHeader( "" ),
sTimeFrame( "" ),
sFileName( "" ),
sPrintCell( "" ),
sExtension( "" ),
sFileNameProb( "" ),
sFileNameCases( "" );
vars: { numerical & temporary }
nTotalCases( 0 ),
tConsecBarIndex( 0 ),
tRepeatCell( 0 );
arrays: { string arrays }
asTimeFrames[4]( "" ),
asHeaderRows[]( "" );
{ ***** end local declarations ***** }
{ ***** begin set up the strings *****}
sExtension = ".csv";
sFileNameProb = "3D_Zone_Stat_Probabilities";
sFileNameCases = "3D_Zone_Stat_Cases";
asTimeFrames[0] = NumToStr(BarInterval, 0) + "_ticks";
asTimeFrames[1] = NumToStr(BarInterval, 0) + "_min";
asTimeFrames[2] = "daily";
asTimeFrames[3] = "weekly";
asTimeFrames[4] = "monthly";
sTimeFrame = asTimeFrames[datacompression];
sHeader = "";
sHeader = sHeader + "3DZone statistics by michal.kreslik @ kreslik.com" + NewLine;
sHeader = sHeader + "website: www.kreslik.com" + NewLine;
sHeader = sHeader + "*****" + NewLine;
sHeader = sHeader + "Zone start: " + NumToStr(iZonePercentStart, 0) + "%" + NewLine;
sHeader = sHeader + "Zone end: " + NumToStr(iZonePercentEnd, 0) + "%" + NewLine;
sHeader = sHeader + "Zone count: " + NumToStr(iTotalNumberOfZones, 0) + " zones" + NewLine;
sHeader = sHeader + "Zone step: " + NumToStr(nZonePercentageStep, 0) + "%" + NewLine;
sHeader = sHeader + "*****" + NewLine;
sHeader = sHeader + "Max consecutive bars setting: " + NumToStr(iMaxConsecutiveBars, 0) + " bars" + NewLine;
sHeader = sHeader + "Max consecutive bars exceeded: " + IffString(bMaxBarsExceeded, "yes", "no") + NewLine;
sHeader = sHeader + "Max consecutive bars necessary: " + NumToStr(nRealMaxConsecBars, 0) + NewLine;
sHeader = sHeader + "*****" + NewLine;
sHeader = sHeader + "Total bars examined: " + NumToStr(BarNumber, 0) + NewLine;
sHeader = sHeader + "Time period: " + sStartDate + " to " + DateToString(DateToJulian(date)) + NewLine;
sHeader = sHeader + "Trading days: " + NumToStr(nTradingDays, 0) + NewLine;
sHeader = sHeader + "*****" + NewLine;
sHeader = sHeader + "Exchange: " + GetExchangeName + NewLine;
sHeader = sHeader + "Symbol: " + GetSymbolName + NewLine;
sHeader = sHeader + "Timeframe: " + sTimeFrame + NewLine;
sHeader = sHeader + "*****" + NewLine;
sHeader = sHeader + "Repeat cells: " + IffString(iRepeatCells, "yes", "no") + NewLine;
sHeader = sHeader + "Stat. validity - min # of cases setting: " + NumToStr(iMinNumOfCases, 0) + NewLine;
sHeader = sHeader + "Printing: " + IffString(iPrintProbOrCases = 0, "probabilities of stay", "number of cases") + NewLine;
sHeader = sHeader + NewLine;
{ ***** end set up the strings *****}
{ ***** begin print to file section ***** }
if iAppendMode then
if iPrintProbOrCases = 0 then
sFileName = iFileFolder + "\" + sFileNameProb + sExtension
else
sFileName = iFileFolder + "\" + sFileNameCases + sExtension
else
begin
sFileName = iFileFolder + "\"
+ GetSymbolName + "_"
+ sTimeFrame + "_"
+ IffString(iPrintProbOrCases = 0, sFileNameProb + sExtension, sFileNameCases + sExtension);
FileDelete(sFileName);
end;
FileAppend(sFileName, sHeader);
for tZoneIndex = 1 to iMaxConsecutiveBars
begin
for tRepeatCell = 1 to nRepeatCellCount
begin
FileAppend(sFileName, "," + NumToStr(tZoneIndex, 0));
end;
end;
for tZoneIndex = 1 to iTotalNumberOfZones
begin
FileAppend(sFileName, NewLine + NumToStr(anZonePercentages[tZoneIndex], 0));
for tConsecBarIndex = 1 to iMaxConsecutiveBars
begin
nTotalCases = anCasesOfStay[tZoneIndex, tConsecBarIndex]
+ anCasesOfAbandonment[tZoneIndex, tConsecBarIndex];
if nTotalCases >= iMinNumOfCases then
if iPrintProbOrCases = 0 then
sPrintCell = "," + NumToStr(anCasesOfStay[tZoneIndex, tConsecBarIndex]/nTotalCases*100, iPercentDecPrecision)
else sPrintCell = "," + NumToStr(nTotalCases, 0)
else
sPrintCell = "," + NumToStr(iStatInsignChar, 0);
for tRepeatCell = 1 to nRepeatCellCount
begin
FileAppend(sFileName, sPrintCell);
end;
end;
end;
FileAppend(sFileName, NewLine + NewLine);
{ ***** end print to file section ***** }
end; { if LastBarOnChart AND bFirstRun then }
end; { if iZonePercentEnd <= 50 AND iMinNumOfCases > 0 then }
{ ***** end program ***** }