有您的持续关注
我们会做得更好

充满艺术性的MT4指标四度空间PriceBand



PriceBand指标有人命名为四度空间,创作者将枯燥的MT4盘面设计到如此充满艺术性,不得不让人折服。喜欢的朋友可以多研究多总结用法。

PriceBand指标图表效果如下:PriceBand指标

PriceBand指标源码如下:

//+------------------------------------------------------------------+
//|                                                    PriceBand.mq4 |
//|                                     Copyright 2016, QQ:125808047 |
//+------------------------------------------------------------------+
#property copyright "www.125808047.com"
#property link      "http://www.125808047.com/"

//---- indicator settings
#property  indicator_chart_window

#property  indicator_buffers  0

//---- defines

//---- indicator parameters
extern int    nBar             = 0;         
extern bool   bLeftOrigin      = false;     
extern double priceStep        = 0.00;     
extern bool   bVolumeDiffusion = true;     
extern int    volumeTimeFrame  = 0;        
extern bool   bColorize        = true;    
extern bool   bShowScale       = true;     
extern int    nScale           = 256;     
extern bool   bBuiltinColorize = false;    
extern bool   bNegativeColor   = false;    
extern bool   bHSVInterp       = true;    
extern color  colBandMax       = Orange;   
extern color  colBandMin       = Black;    
extern double bandMaxLength    = 1.00;    
extern double bandHeightRatio  = 1.00;     
extern int    maxBand          = 500;     
extern double point            = 0;       

//---- indicator buffers

//---- vars
string sIndicatorName;
double g_vol[];

//----------------------------------------------------------------------
int init()
{
    sIndicatorName = "00-PriceBand";

    IndicatorShortName(sIndicatorName);
    
    if (volumeTimeFrame == 0) {
    volumeTimeFrame = Period();
    }
    
    if (point == 0) {
    if (Point == 0 || Symbol() == "GOLD") {
        point = 0.10;
    } else {
        point = Point;
    }
    }
    
    if (priceStep == 0) {
    
    switch (Period()) {
    case PERIOD_M1:
    case PERIOD_M5:
    case PERIOD_M15:
    case PERIOD_M30:
        priceStep = point;
        break;
        
    case PERIOD_H1:
    case PERIOD_H4:
        priceStep = point * 2;
        break;
        
    case PERIOD_D1:
        priceStep = point * 4;
        break;
        
    case PERIOD_W1:
    default:
        priceStep = point * 8;
        break;
    }
    }
    
    ArrayResize(g_vol, maxBand);

    if (bNegativeColor) {
    colBandMax ^= 0xffffff;
    colBandMin ^= 0xffffff;
    }
    
    Print("Point= ", Point, ", point= ", point, ", priceStep= ", priceStep);
return(0);
}

//----------------------------------------------------------------------
string getBandName(int i)
{
    return(sIndicatorName + " Band" + i);
}

//----------------------------------------------------------------------
string getScaleSepName()
{
    return(sIndicatorName + " ScaleSep");
}

//----------------------------------------------------------------------
string getScaleUnitName(int i)
{
    return(sIndicatorName + " ScaleUnit" + i);
}

//----------------------------------------------------------------------
void objInit(bool bInit)
{
    int i;
    string s;
    
    // for band
    for (i = 0; i < maxBand; i++) {
    s = getBandName(i);
    if (bInit) {
        ObjectCreate(s, OBJ_RECTANGLE, 0, 0, 0);
    } else {
        ObjectDelete(s);
    }
    }
    
    // for scale
    if (bShowScale) {
    s = getScaleSepName();
    if (bInit) {
        ObjectCreate(s, OBJ_RECTANGLE, 0, 0, 0);
        ObjectSet(s, OBJPROP_BACK, false);
    } else {
        ObjectDelete(s);
    }
    for (i = 0; i < nScale; i++) {
        s = getScaleUnitName(i);
        if (bInit) {
        ObjectCreate(s, OBJ_RECTANGLE, 0, 0, 0);
        } else {
        ObjectDelete(s);
        }
    }
    }
}

//----------------------------------------------------------------------
void deinit()
{
    objInit(false);
}

//----------------------------------------------------------------------
int getR(color col)
{
    return((col >> 0) & 0xff);
}

//----------------------------------------------------------------------
int getG(color col)
{
    return((col >> 8) & 0xff);
}

//----------------------------------------------------------------------
int getB(color col)
{
    return((col >> 16) & 0xff);
}

//----------------------------------------------------------------------
void getRgb(color col, int &r, int &g, int &b)
{
    r = getR(col);
    g = getG(col);
    b = getB(col);
}

//----------------------------------------------------------------------
int clip255(double c)
{
    return(MathMin(MathMax(MathRound(c), 0), 255));
}

//----------------------------------------------------------------------
double clip1(double v)
{
    return(MathMin(MathMax(v, 0.0), 1.0));
}

//----------------------------------------------------------------------
color rgbToColor(double r, double g, double b)
{
    return((clip255(b) << 16) | (clip255(g) << 8) | clip255(r));
}

//----------------------------------------------------------------------
void colorToHsv(color col, double &h, double &s, double &v)
{
    int r = getR(col);
    int g = getG(col);
    int b = getB(col);
    
    int max = MathMax(MathMax(r, g), b);
    int min = MathMin(MathMin(r, g), b);
    double d = max - min;
    
    if (d <= 0) {
    h = 0;
    } else {
    if (max == r) {
        h = 60.0 * (g - b) / d;
    } else if (max == g) {
        h = 60.0 * (b - r) / d + 120;
    } else {
        h = 60.0 * (r - g) / d + 240;
    }
    }
    
    s = d / 255.0;
    
    v = max / 255.0;
}

//----------------------------------------------------------------------
color hsvToColor(double h, double s, double v)
{
    if (h < 0) {
    h += MathCeil(-h / 360) * 360;
    }
    
    int ih = MathFloor(h / 60);
    ih %= 6;
    double f = h / 60.0 - ih;
    double p = v * (1.0 - s) * 255;
    double q = v * (1.0 - f * s) * 255;
    double t = v * (1.0 - (1.0 - f) * s) * 255;
    
    v *= 255;
    
    double r, g, b;
    
    switch (ih) {
    case 0: r = v; g = t; b = p; break;
    case 1: r = q; g = v; b = p; break;
    case 2: r = p; g = v; b = t; break;
    case 3: r = p; g = q; b = v; break;
    case 4: r = t; g = p; b = v; break;
    case 5: r = v; g = p; b = q; break;
    }
    
    return(rgbToColor(r, g, b));
}

//----------------------------------------------------------------------
color getBandColor(double vol)
{
    if (!bColorize) {
    // mono tone
    
    return(colBandMax);
    }
    
    vol = clip1(vol);
    
    // limit in nScale colors
    vol = MathRound(vol * (nScale - 1)) / (nScale - 1);
    
    double r, g, b;
    
    if (!bBuiltinColorize) {
    if (bHSVInterp) {
        // HSV interpolation from colBandMin to colBandMax
        double hMin, sMin, vMin;
        double hMax, sMax, vMax;
        colorToHsv(colBandMin, hMin, sMin, vMin);
        colorToHsv(colBandMax, hMax, sMax, vMax);
        
        double h = (hMax - hMin) * vol + hMin;
        double s = (sMax - sMin) * vol + sMin;
        double v = (vMax - vMin) * vol + vMin;
        
        return(hsvToColor(h, s, v));
    } else {
        // RGB interpolation from colBandMin to colBandMax
        int rMin, gMin, bMin;
        int rMax, gMax, bMax;
        getRgb(colBandMin, rMin, gMin, bMin);
        getRgb(colBandMax, rMax, gMax, bMax);
        
        r = (rMax - rMin) * vol + rMin;
        g = (gMax - gMin) * vol + gMin;
        b = (bMax - bMin) * vol + bMin;
        
        return(rgbToColor(r, g, b));
    }
    }
    
    // built-in colorize
    double c;
    if (vol <= 0.25) {
    c = vol / 0.25;
    r = 239 * c + 16;
    g = 64 * c + 4;
    b = 0;
    } else if (vol <= 0.5) {
    c = (vol - 0.25) / 0.25;
    r = 255 - 255 * c;
    g = 64;
    b = 255 * c;
    } else if (vol <= 0.75) {
    c = (vol - 0.50) / 0.25;
    r = 0;
    g = 64 + (255 - 64) * c;
    b = 255;
    } else {
    c = (vol - 0.75) / 0.25;
    r = 255 * c;
    g = 255;
    b = 255;
    }
    
    if (bNegativeColor) {
    r = 255 - r;
    g = 255 - g;
    b = 255 - b;
    }
    
    return(rgbToColor(r, g, b));
}

//----------------------------------------------------------------------
void addVolume(double pStart, double pEnd, double dv, double pMin)
{
    int p0 = MathRound(pStart / point);
    int p1 = MathRound(pEnd / point);
    int dir = 1;
    if (p0 > p1) {
    dir = -1;
    }
    for (int i = p0; i != p1; i += dir) {
    int iBand = MathRound((i * point - pMin) / priceStep);
    if (iBand >= 0 && iBand < maxBand) {
        g_vol[iBand] += dv;
    }
    }
}

//----------------------------------------------------------------------
int start()
{
    int xs0 = WindowFirstVisibleBar();
    int n0 = MathMin(WindowBarsPerChart() + 1, xs0 + 1);
    int bandBars = n0;
    int xs1, n1;
    
    if (nBar > 0) {
    if (!bLeftOrigin) {
        xs0 = xs0 - n0 + nBar;
    }
    bandBars = MathMin(n0, nBar);
    if (nBar >= n0) {
        bandMaxLength = 1.0;
    }
    n0 = nBar;
    }
    
    if (volumeTimeFrame == Period()) {
    xs1 = xs0;
    n1 = n0;
    } else {
    xs1 = iBarShift(NULL, volumeTimeFrame, Time[xs0]);
    n1 = MathCeil(n0 * Period() / volumeTimeFrame);
    if (xs1 - n1 + 1 < 0) {
        n1 = xs1 + 1;
    }
    }
    
    double pMin = Low[iLowest(NULL, 0, MODE_LOW, n0, xs0 - n0 + 1)] - point * 0.1;
    double pMax = High[iHighest(NULL, 0, MODE_HIGH, n0, xs0 - n0 + 1)] + point * 0.1;
    
    double pDiff = pMax - pMin;
    int nBand = MathMin(MathCeil(pDiff / priceStep), maxBand);
    int i, iBar, iBand;
    
    ArrayInitialize(g_vol, 0);
    
    for (i = 0, iBar = xs1; i < n1; i++, iBar--) {
    double pOpen  = iOpen(NULL, volumeTimeFrame, iBar);
    double pHi    = iHigh(NULL, volumeTimeFrame, iBar);
    double pLo    = iLow(NULL, volumeTimeFrame, iBar);
    double pClose = iClose(NULL, volumeTimeFrame, iBar);
    double pVol   = iVolume(NULL, volumeTimeFrame, iBar);
    if (!bVolumeDiffusion) {
        addVolume(pClose, pClose + point, pVol, pMin);
    } else {
        int nPoint;
        double dVol;
        if (pOpen <= pClose) {
        // 
        // h 7  +       *
        //      |     * *
        // c 5 +-+    *   *
        //     | |    *
        // o 3 +-+  * *
        //      |   * *
        // l 1  +     *
        // 
        nPoint = MathRound((pOpen + 2 * pHi - 2 * pLo - pClose + 1) / point);
        dVol = pVol / nPoint;
        addVolume(pOpen, pLo, dVol, pMin);
        addVolume(pLo, pHi, dVol, pMin);
        addVolume(pHi, pClose, dVol, pMin);
        addVolume(pClose, pClose - point, dVol, pMin);
        } else {
        // 
        // h 7  +     *
        //      |   * *
        // o 5 +-+  * *
        //     | |    *
        // c 3 +-+    *   *
        //      |     * *
        // l 1  +       *
        // 
        nPoint = MathRound((pClose + 2 * pHi - 2 * pLo - pOpen + 1) / point);
        dVol = pVol / nPoint;
        addVolume(pOpen, pHi, dVol, pMin);
        addVolume(pHi, pLo, dVol, pMin);
        addVolume(pLo, pClose, dVol, pMin);
        addVolume(pClose, pClose + point, dVol, pMin);
        }
    }
    }
    
    // scale g_vol[] to 0.0 .. 1.0
    double rvMax = g_vol[ArrayMaximum(g_vol)];
    if (rvMax > 0) {
    rvMax = 1.0 / rvMax;
    for (iBand = 0; iBand < maxBand; iBand++) {
        g_vol[iBand] *= rvMax;
    }
    }
    
    objInit(true);
    
    string s;
    int bs, be;
    double d, lo, hi, vol;
    for (iBand = 0; iBand < maxBand; iBand++) {
    s = getBandName(iBand);
    lo = pMin + (iBand - 0.5 + (1 - bandHeightRatio) / 2.0) * priceStep;
    hi = lo + priceStep * bandHeightRatio;
    vol = g_vol[iBand];
    d = (bandBars - 1) * bandMaxLength;
    if (bLeftOrigin) {
        bs = xs0;
        be = MathRound(MathMax(bs - vol * d, 0));
    } else {
        bs = MathRound(MathMax(xs0 - n0 + 1, 0));
        be = MathRound(MathMax(bs + vol * d, 0));
    }
    ObjectMove(s, 0, Time[bs], lo);
    ObjectMove(s, 1, Time[be], hi);
    ObjectSet(s, OBJPROP_COLOR, getBandColor(vol));
    }
    
    if (bShowScale) {
    d = 1.0 / nScale * (bandBars - 1) * bandMaxLength;
    
    // scale separator
    if (bLeftOrigin) {
        bs = xs0;
        be = MathRound(MathMax(bs - nScale * d, 0));
    } else {
        bs = MathRound(MathMax(xs0 - n0 + 1, 0));
        be = MathRound(MathMax(bs + nScale * d, 0));
    }
    s = getScaleSepName();
    ObjectMove(s, 0, Time[bs], pMin);
    ObjectMove(s, 1, Time[be], pMin);
    ObjectSet(s, OBJPROP_COLOR, 0xe0e0e0);
    
    // scale units
    for (int iScale = 0; iScale < nScale; iScale++) {
        s = getScaleUnitName(iScale);
        if (bLeftOrigin) {
        bs = MathRound(MathMax(xs0 - iScale * d, 0));
        be = MathRound(MathMax(xs0 - (iScale + 1) * d, 0));
        } else {
        bs = MathRound(MathMax(xs0 - n0 + 1 + iScale * d, 0));
        be = MathRound(MathMax(xs0 - n0 + 1 + (iScale + 1) * d, 0));
        }
        hi = pMin;
        lo = pMin - MathMax((WindowPriceMax() - WindowPriceMin()) * 0.05, priceStep * 2);
        vol = (iScale * 1.0) / (nScale - 1);
        ObjectMove(s, 0, Time[bs], lo);
        ObjectMove(s, 1, Time[be], hi);
        ObjectSet(s, OBJPROP_COLOR, getBandColor(vol));
    }
    }
    
    WindowRedraw();
return(0);
}
如您喜欢此文章请点下面分享按钮↴峰汇在线 » 充满艺术性的MT4指标四度空间PriceBand
上一篇:
下一篇:
分享到:更多 ()