-
-
Save fatfingererr/c1a2a59dd5ab2877824bb89894f89e60 to your computer and use it in GitHub Desktop.
VolumeProfileCalculate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 完整来源 (Metatrader, MQL, 类似 C++): | |
// https://www.earnforex.com/metatrader-indicators/volume-profile/ | |
void VolumeProfileCalculate(){ | |
// 根据参数设置找到起始bar数 | |
int BarStart=iBarShift(Symbol(),VPTimeFrame,StartTime); | |
// 如果要整跟 KLINE 都做统计 (=Whole), 还是一根 KLINE 只统计 Close 或 Open | |
int PriceHighMode=MODE_CLOSE; | |
int PriceLowMode=MODE_CLOSE; | |
if(CalculationMode==CANDLE_WHOLE){ | |
PriceHighMode=MODE_HIGH; | |
PriceLowMode=MODE_LOW; | |
} | |
if(CalculationMode==CANDLE_CLOSE){ | |
PriceHighMode=MODE_CLOSE; | |
PriceLowMode=MODE_CLOSE; | |
} | |
if(CalculationMode==CANDLE_OPEN){ | |
PriceHighMode=MODE_OPEN; | |
PriceLowMode=MODE_OPEN; | |
} | |
// 找到当前时间范围内最低与最高价 | |
PriceMin=MathFloor(iLow(Symbol(),VPTimeFrame,iLowest(Symbol(),VPTimeFrame,(ENUM_SERIESMODE)PriceLowMode,BarsToScan,BarStart))/StepPoints)*StepPoints; | |
PriceMax=MathCeil(iHigh(Symbol(),VPTimeFrame,iHighest(Symbol(),VPTimeFrame,(ENUM_SERIESMODE)PriceHighMode,BarsToScan,BarStart))/StepPoints)*StepPoints; | |
// 计算 step 宽度, 也就是累计的 step, 太细也不会有太大差别 | |
Steps=(int)MathCeil((PriceMax-PriceMin)/StepPoints)+1; | |
ArrayResize(VolumeProfile,Steps); | |
ArrayInitialize(VolumeProfile,0); | |
// 从起始开始统计 | |
for(int i=0; i<BarsToScan; i++){ | |
int j=BarStart+i; | |
double MinPrice=0; | |
double MaxPrice=0; | |
double CandleSteps=0; | |
// 根据模式不同, 统计的基础不同 | |
if(CalculationMode==CANDLE_WHOLE){ | |
MinPrice=iLow(Symbol(),VPTimeFrame,j); | |
MaxPrice=iHigh(Symbol(),VPTimeFrame,j); | |
} | |
if(CalculationMode==CANDLE_CLOSE){ | |
MinPrice=iClose(Symbol(),VPTimeFrame,j); | |
MaxPrice=iClose(Symbol(),VPTimeFrame,j); | |
} | |
if(CalculationMode==CANDLE_OPEN){ | |
MinPrice=iOpen(Symbol(),VPTimeFrame,j); | |
MaxPrice=iOpen(Symbol(),VPTimeFrame,j); | |
} | |
MinPrice=MathFloor(MinPrice/StepPoints)*StepPoints; | |
MaxPrice=MathFloor(MaxPrice/StepPoints)*StepPoints; | |
CandleSteps=MathRound((MaxPrice-MinPrice)/StepPoints); | |
// 针对一根 KLINE 从底向上开始统计 | |
for(int k=0; k<=CandleSteps; k++){ | |
double CalcPrice=MinPrice+StepPoints*k; | |
int h=(int)MathRound((CalcPrice-PriceMin)/StepPoints); | |
long Weight=1; | |
if(UseVolume) Weight=iVolume(Symbol(),VPTimeFrame,j); | |
if(h>=Steps){ | |
MessageBox("Historical Data not loaded, please reload the indicator","WARNING",MB_OK); | |
Print("Error with historical data, please reload the indicator"); | |
continue; | |
} | |
// 在 profile 区间内疚做累计 | |
VolumeProfile[h]+=Weight; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment