Price Data Components
0
Views
0
Downloads
0
Favorites
Price_Distribution
//+------------------------------------------------------------------+
//| Price_Distribution.mq4 |
//| Copyright © 2006, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net"
#define SECONDS_IN_MINUTE 60
#define SECONDS_IN_HOUR 3600
#define SECONDS_IN_DAY 86400
#define OBJNAME_PREPEND "ValueInRange"
#property indicator_chart_window
extern string BoxStart = "10:00";
extern string BoxEnd = "23:59";
extern string LineEnd = "10:00";
extern double PlotMagnification = 300.0;
extern color BoxColor = C'17,28,28';
extern color LineColor = DarkSlateGray;
extern color PlotColor = SlateGray;
extern int DaysToPlot = 10;
int init() {
}
int deinit() {
DeleteObjects(OBJNAME_PREPEND);
return(0);
}
int start() {
int iPlots = 0;
// Determine how far back to iterate
// Always recalc last complete bar
int iBarsToCalc = Bars - IndicatorCounted();
if (iBarsToCalc < Bars) iBarsToCalc++;
// Determine start time for current (or just closed) box
datetime dtBoxStart = StrToTime(TimeToStr(TimeCurrent(),TIME_DATE) + " " + BoxStart);
if (dtBoxStart > TimeCurrent()) dtBoxStart -= SECONDS_IN_DAY;
// Determine end time for current (or just closed) box
datetime dtBoxEnd = StrToTime(TimeToStr(dtBoxStart,TIME_DATE) + " " + BoxEnd);
if (dtBoxEnd < dtBoxStart) dtBoxEnd += SECONDS_IN_DAY;
// Simply loop, there are multiple ways to break
// While the box close time is after the oldest bar which needs calculation,
// calculate the box then add a day and repeat
while (true) {
// If the box close time is before the oldest bar which needs calculation, exit
if (dtBoxEnd < Time[iBarsToCalc]) return(0);
// If max number of iterations reached, exit
if (iPlots >= DaysToPlot) return(0);
// If the range to be plotted has data, plot it
if (iBarShift(NULL,PERIOD_M1,dtBoxStart,false) != iBarShift(NULL,PERIOD_M1,dtBoxEnd,false)) {
Print(TimeToStr(dtBoxStart), " ", TimeToStr(dtBoxEnd));
doCalcValueInRange(dtBoxStart);
iPlots++;
}
else {
Print("No data for ", TimeToStr(dtBoxStart), " ", TimeToStr(dtBoxEnd));
}
// Decrement dates
dtBoxStart -= SECONDS_IN_DAY;
dtBoxEnd -= SECONDS_IN_DAY;
}
}
void doCalcValueInRange(datetime dtBoxStart) {
// Determine box end time based on box start time
// Insure it's after box start
datetime dtBoxEnd = StrToTime(TimeToStr(dtBoxStart,TIME_DATE) + " " + BoxEnd);
if (dtBoxEnd < dtBoxStart) dtBoxEnd += SECONDS_IN_DAY;
// Determine line end time based on box end time
// Insure it's after box end
datetime dtLineEnd = StrToTime(TimeToStr(dtBoxEnd,TIME_DATE) + " " + LineEnd);
if (dtLineEnd < dtBoxEnd) dtLineEnd += SECONDS_IN_DAY;
// Figure out start and end bars for box on the minute chart
// Make sure the timestamp of start bar is >= box start time
int iStart = iBarShift(NULL,PERIOD_M1,dtBoxStart,false);
int iEnd = iBarShift(NULL,PERIOD_M1,dtBoxEnd,false);
while (iTime(NULL,PERIOD_M1,iStart) < dtBoxStart) iStart--;
// Get the high and low prices for the day
double dHigh = iHigh(NULL,PERIOD_M1,iHighest(NULL,PERIOD_M1,MODE_HIGH,iStart-iEnd,iEnd));
double dLow = iLow (NULL,PERIOD_M1,iLowest (NULL,PERIOD_M1,MODE_LOW ,iStart-iEnd,iEnd));
// Draw the box
doDrawBox(dtBoxStart,dtBoxEnd,dHigh,dLow);
// Draw the high/low lines
doDrawRangeLines(dtBoxStart,dtLineEnd,dHigh,dLow);
// Draw the price distribution
doDrawDistribution(dtBoxStart,dtLineEnd,dHigh,dLow);
}
void doDrawBox(datetime dtStart, datetime dtEnd, double dHigh, double dLow) {
// Draw the box
string sObjName = OBJNAME_PREPEND + " " + TimeToStr(dtStart);
ObjectCreate(sObjName,OBJ_RECTANGLE,0,dtStart,dHigh,dtEnd,dLow);
ObjectSet(sObjName,OBJPROP_COLOR,BoxColor);
}
void doDrawRangeLines(datetime dtStart, datetime dtEnd, double dHigh, double dLow) {
string sObjName;
// Draw range high
sObjName = OBJNAME_PREPEND + " " + TimeToStr(dtStart) + " " + "High";
ObjectCreate(sObjName,OBJ_TREND,0,dtStart,dHigh,dtEnd,dHigh);
ObjectSet(sObjName,OBJPROP_RAY,false);
ObjectSet(sObjName,OBJPROP_COLOR,LineColor);
// Draw range low
sObjName = OBJNAME_PREPEND + " " + TimeToStr(dtStart) + " " + "Low";
ObjectCreate(sObjName,OBJ_TREND,0,dtStart,dLow,dtEnd,dLow);
ObjectSet(sObjName,OBJPROP_RAY,false);
ObjectSet(sObjName,OBJPROP_COLOR,LineColor);
}
void doDrawDistribution(datetime dtStart, datetime dtEnd, double dHigh, double dLow) {
// Buckets to place 'ticks' into.
double dBuckets[50];
ArrayInitialize(dBuckets,0.0);
// Var to tally total 'ticks'
int iTicks = 0;
// Figure out the value to use to "split" prices into different buckets
double dSplitter = (dHigh - dLow) / ArraySize(dBuckets);
// Get the offset for the first minute bar of the range.
double iStartBar = iBarShift(NULL,PERIOD_M1,dtStart,false);
while (iTime(NULL,PERIOD_M1,iStartBar) < dtStart) iStartBar--;
// Get the offset for the last minute bar of the range.
double iEndBar = iBarShift(NULL,PERIOD_M1,dtEnd,false);
// Iterate all minutes of the day and place a 'tick' in each bucket
// that price touched
for (int i=iStartBar;i>=iEndBar;i--) {
for (int j=0;j<=ArraySize(dBuckets)-1;j++) {
double dBucketHigh = dHigh - (j) *dSplitter;
double dBucketLow = dHigh - (j+1)*dSplitter;
// If price was above bucket range, no tick
if (iLow(NULL,PERIOD_M1,i) > dBucketHigh)
continue;
// If price was below bucket range, no tick
if (iHigh(NULL,PERIOD_M1,i) <= dBucketLow)
continue;
// bucket gets a tick
dBuckets[j] += 1;
iTicks++;
}
}
//string sObjName = OBJNAME_PREPEND + " " + TimeToStr(dtStart) + " TickTotal";
//ObjectCreate(sObjName,OBJ_TEXT,0,dtStart,(dHigh+dLow)*0.5);
//ObjectSetText(sObjName,"Ticks: " + iTicks);
// Draw Bucket Lines
for (j=0;j<=ArraySize(dBuckets)-1;j++) {
dBucketHigh = dHigh - (j) *dSplitter;
dBucketLow = dHigh - (j+1)*dSplitter;
// Create a name for the bucket object
string sObjName = OBJNAME_PREPEND + " " + TimeToStr(dtStart) + " Bucket " + j+1;
// Determine how many bars long it will be. Each bar indicates bucket contained 5% of the price action
int iObjLength = 1;
if (iTicks > 0) iObjLength = (dBuckets[j]/iTicks)*PlotMagnification;
ObjectCreate(sObjName,OBJ_RECTANGLE,0,dtStart,dBucketHigh,dtStart+Period()*60*iObjLength,dBucketLow);
ObjectSet(sObjName,OBJPROP_COLOR,PlotColor);
}
}
void DeleteObjects(string sObjNamePrepend) {
// delete objects
for (int i=ObjectsTotal()-1;i>=0;i--) {
string sObjName = ObjectName(i);
if (StringFind(sObjName,sObjNamePrepend) == 0)
ObjectDelete(sObjName);
}
}
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---