Guest User

ay-MarketProfileDWM.v1.31.rev1

a guest
Jan 25th, 2021
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 36.01 KB | None | 0 0
  1. //+------------------------------------------------------------------+
  2. //|                                             ay-MarketProfile.mq4 |
  3. //|                      Copyright © 2010, MetaQuotes Software Corp. |
  4. //|                                        http://www.metaquotes.net |
  5. //+------------------------------------------------------------------+
  6. #property copyright "Copyright © 2011, [email protected]"
  7. #property link      "[email protected]"
  8.  
  9. #property indicator_chart_window
  10. /*
  11. v1.1        cleaning the code
  12.             add ShowOpenCloseArrow
  13.             add VATPOPercent
  14. v1.2        use 1 pip for pricing step and tpo calculating      
  15. v1.3        add Volume Profile feature
  16. v1.31       add DayStartHour, ShowPriceHistogram, ShowValueArea, ShowVAHVALLines            
  17. v1.31.rev1  add Ticksize, VolAmplitudePercent
  18.             bug fix :
  19.             - Profile High and Low misscalculated when high or low of the day
  20.               occured at first m30 candle.
  21.             - Open and Close Arrow Location
  22.             - profile missing when DayStartHour not exist on the chart
  23.               like Hour 0 not exist on some days on #YMH1 chart (fxpro);
  24.              
  25. */
  26.  
  27. #define PRICEIDX        0
  28. #define TPOIDX          1
  29. #define VOLIDX          2
  30.  
  31. //---extern vars
  32. extern int        LookBack                = 6;
  33. extern bool       UseVolumeProfile        = true;
  34. extern string     ProfileTimeframeInfo    = "use D, W, or M";
  35. extern string     ProfileTimeframe        = "D";
  36. extern int        DayStartHour            = 0;
  37. extern double     VATPOPercent            = 70.0;
  38. extern int        TickSize                = 1;
  39. extern int        ExtendedPocLines        = 5;
  40.  
  41. extern string     spr0                    = "on/off settings..";
  42. extern bool       ShowPriceHistogram      = true;
  43. extern bool       ShowValueArea           = true;
  44. extern bool       ShowVAHVALLines         = true;
  45. extern bool       ShowOpenCloseArrow      = true;
  46.  
  47. extern string     spr1                    = "design & colors..";
  48. extern double     VolAmplitudePercent     = 40.0;
  49. extern int        HistoHeight             = 2;
  50. extern color      HistoColor1             = C'55,100,135';
  51. extern color      HistoColor2             = C'45,90,125';
  52. extern color      OpenColor               = DarkGreen;
  53. extern color      CloseColor              = Peru;
  54. extern color      POCColor                = Peru;
  55. extern color      VirginPOCColor          = Yellow;
  56. extern color      VAColor                 = C'16,16,16';
  57. extern color      VALinesColor            = C'64,64,64';
  58. extern color      InfoColor               = Lime;
  59.  
  60. extern string     spr2                    = "Profile Data.............";
  61. extern int        DailyProfileDataTf      = 30;
  62. extern int        WeeklyProfileDataTf     = 60;
  63. extern int        MonthlyProfileDataTf    = 240;
  64.  
  65. //---global vars
  66. string            gsPref                  = "ay.mp.";
  67. double            fpoint
  68.                 , gdOneTick
  69.                 , gdHistoRange;
  70. int               fdigits
  71.                 , giStep
  72.                 , giProfileTf             = PERIOD_D1
  73.                 , giDataTf                = 0;
  74.  
  75. //+------------------------------------------------------------------+
  76. //| Custom indicator initialization function                         |
  77. //+------------------------------------------------------------------+
  78. int init()
  79. {      
  80.      
  81.    giDataTf = Period(); //default
  82.    
  83.    if (Point == 0.001 || Point == 0.00001)
  84.    { fpoint = Point*10; fdigits = Digits - 1; }
  85.    else
  86.    { fpoint = Point; fdigits = Digits; }    
  87.      
  88.    
  89.    if (ProfileTimeframe == "M" )  
  90.    {
  91.       gsPref      = gsPref + "2.0." + ProfileTimeframe + ".";
  92.       giProfileTf = PERIOD_MN1;    
  93.       HistoHeight = MathMax(HistoHeight, 8);
  94.       giDataTf    = MonthlyProfileDataTf;
  95.    }  
  96.    else if (ProfileTimeframe == "W" )
  97.    {
  98.       gsPref      = gsPref + "3.0." + ProfileTimeframe + ".";
  99.       giProfileTf = PERIOD_W1;    
  100.       HistoHeight = MathMax(HistoHeight, 3);
  101.       giDataTf    = WeeklyProfileDataTf;
  102.  
  103.    }
  104.    else //default D1
  105.    {
  106.       gsPref      = gsPref + "4.0." + ProfileTimeframe + ".";
  107.       giProfileTf = PERIOD_D1;
  108.       HistoHeight = MathMax(HistoHeight, 1);
  109.       giDataTf    = DailyProfileDataTf;
  110.    }
  111.    //----
  112.    HistoHeight    = MathMax(HistoHeight, TickSize);
  113.    gdOneTick      = TickSize/(MathPow(10,fdigits));
  114.    gdHistoRange   = HistoHeight/(MathPow(10,fdigits));
  115.    giStep         = HistoHeight;
  116.    
  117.    return(0);
  118. }
  119. //+------------------------------------------------------------------+
  120. //| Custom indicator deinitialization function                       |
  121. //+------------------------------------------------------------------+
  122. int deinit()
  123. {
  124.    delObjs();
  125.    return(0);
  126. }
  127. //+------------------------------------------------------------------+
  128. //| Custom indicator iteration function                              |
  129. //+------------------------------------------------------------------+
  130. int start()
  131. {
  132.  
  133.    
  134.    if ( !isOK() ) return(0);
  135.    
  136.    LookBack = MathMin( LookBack, iBarShift(NULL, giProfileTf, Time[Bars-1]) - 1 );
  137.    LookBack = MathMin( LookBack, iBarShift(NULL, giProfileTf, iTime(NULL, giDataTf, iBars(NULL, giDataTf) - 1)) );
  138.  
  139.    int ibar.proftf = 0, endbar.proftf = 0;  
  140.        
  141.    //---create all profile on startup/new tfsrc bar
  142.    //---and then only update the last tfsrc profile
  143.    
  144.    if ( newBarProfileTf() ) { delObjs(); endbar.proftf = LookBack-1; }
  145.    
  146.    double     aprice.step[][3]             // [ 3-->{price, count tpo, count vol} ]
  147.             , hh, ll                       // profile
  148.             , maxvol
  149.             , vah                          // Value Area High
  150.             , val                          // Value Area Low
  151.             , totaltpo                     // Total TPO
  152.             , totalvol;                    // Total Vol
  153.    datetime   dt.proftf;
  154.    int        startbar                     // startbar on giDataTf
  155.             , endbar                       // endbar on giDataTf
  156.             , countps
  157.             , vahidx
  158.             , validx  
  159.             , maxtpo
  160.             , maxtpoidx
  161.             , maxvolidx;  
  162.  
  163.            
  164.     //---main loop --> day by day, week by week, month by month...        
  165.    for (ibar.proftf = endbar.proftf; ibar.proftf >= 0; ibar.proftf--)      
  166.    {
  167.      
  168.       ArrayResize(aprice.step, 0);
  169.      
  170.       getStartAndEndBar(ibar.proftf, startbar, endbar);          
  171.      
  172.       if (startbar == -1) continue;
  173.                          
  174.       getHHLL(startbar, endbar, hh, ll);
  175.                            
  176.       getPriceTPO
  177.          ( startbar, endbar, hh, ll, aprice.step, countps, maxtpo,
  178.            maxtpoidx, totaltpo, maxvol, maxvolidx, totalvol );                        
  179.      
  180.       //continue;    
  181.       drawPriceHistoAndPOCLines
  182.          ( startbar, endbar, ibar.proftf, countps, aprice.step, maxtpo,
  183.            maxtpoidx, maxvol, maxvolidx );
  184.                                  
  185.       //continue;
  186.       getValueArea
  187.          ( countps, aprice.step, maxtpo, maxtpoidx, totaltpo, maxvol,
  188.            maxvolidx, totalvol, vah, vahidx, val, validx );      
  189.          
  190.       //continue;
  191.       drawValueArea
  192.          ( startbar, endbar, ibar.proftf, countps, aprice.step, vah,
  193.            vahidx, val, validx );
  194.  
  195.    }//end for (ibartf = endbartf; ibartf >= 0; ibartf--)    
  196.    
  197.    //update time ExtendedPocLines  
  198.    if (newBar())
  199.    {
  200.       for (int i=1; i<=ExtendedPocLines; i++)
  201.       {
  202.          ObjectSet(gsPref + "#" + i +".1.1.poc",       OBJPROP_TIME2, Time[0] + 10*Period()*60 );    
  203.          ObjectSet(gsPref + "#" + i +".1.0.poc.price", OBJPROP_TIME1, Time[0] + 13*Period()*60 );
  204.       }  
  205.    }
  206.    
  207.    drawInfo();
  208.  
  209.    
  210.    //---delay 5 seconds      
  211.    Sleep(5000);
  212.    
  213.    return(0);
  214.    
  215. }
  216. //+------------------------------------------------------------------+
  217. //| isOK                                                             |
  218. //+------------------------------------------------------------------+
  219. bool isOK()
  220. {  
  221.    switch (Period())
  222.    {
  223.       case PERIOD_M1:        
  224.       case PERIOD_M5:        
  225.       case PERIOD_M15:
  226.          if (giProfileTf == PERIOD_D1) return(true);
  227.          break;      
  228.       case PERIOD_M30:
  229.          if (giProfileTf <= PERIOD_W1) return(true);
  230.          break;          
  231.       case PERIOD_H1:  
  232.          return(true);
  233.          break;            
  234.       case PERIOD_H4:
  235.       case PERIOD_D1:
  236.          if (giProfileTf >= PERIOD_W1) return(true);
  237.          break;
  238.       default:
  239.          return(false);              
  240.          break;
  241.    }          
  242.    
  243.    return(false);
  244. }
  245.  
  246. //+------------------------------------------------------------------+
  247. //| getStartAndEndBar                                                |
  248. //+------------------------------------------------------------------+
  249. void getStartAndEndBar(int ibar.proftf, int &startbar, int &endbar)
  250. {      
  251.    
  252.    int i, j;
  253.    datetime dt.proftf;    
  254.    datetime dt.proftf.next;
  255.      
  256.    switch (giProfileTf)
  257.    {
  258.       case PERIOD_D1:
  259.          int oneday = PERIOD_D1*60;
  260.          int iday = -1;
  261.          datetime dt;
  262.          startbar = 0; endbar = 0;        
  263.          
  264.          if (DayStartHour == 0)
  265.          {
  266.            dt.proftf       = iTime( NULL, giProfileTf, ibar.proftf );
  267.            dt.proftf.next  = iTime( NULL, giProfileTf, ibar.proftf - 1 );        
  268.            startbar        = iBarShift ( NULL, giDataTf, dt.proftf);
  269.            endbar          = iBarShift ( NULL, giDataTf, dt.proftf.next - (giDataTf * 60) );  
  270.             //current day        
  271.            if (dt.proftf.next < dt.proftf) endbar = 0;        
  272.             // fix ibarshift on month\week start
  273.            if ( iTime(NULL, giDataTf, startbar) < dt.proftf ) startbar--;
  274.            
  275.            if (TimeDayOfWeek(iTime( NULL, giDataTf, startbar )) == 0) startbar = -1;
  276.                
  277.            break;
  278.          }        
  279.          
  280.          for (i=0; i<iBars(NULL, giDataTf); i++)
  281.          {
  282.             dt = iTime(NULL, giDataTf, i);
  283.             if (TimeHour(dt) == DayStartHour && TimeMinute(dt) == 0 )
  284.             {
  285.                iday++;
  286.                if (iday == ibar.proftf)
  287.                {
  288.                   startbar = i;        
  289.                   if (ibar.proftf !=0)
  290.                   {
  291.                      endbar  = iBarShift( NULL, giDataTf, dt + oneday - (giDataTf * 60) );                
  292.                      if ( iTime(NULL, giDataTf, endbar) < dt + oneday - (giDataTf * 60) )
  293.                      {
  294.                         endbar++;
  295.                         for (j=endbar; j>=0; j--)
  296.                         {
  297.                            dt = iTime(NULL, giDataTf, j);
  298.                            if (TimeHour(dt) == DayStartHour && TimeMinute(dt) == 0 )
  299.                            {
  300.                               endbar = j+1;
  301.                               break;
  302.                            }                            
  303.                         }// end for j
  304.                      }
  305.                   }
  306.                   else endbar = 0;
  307.                  
  308.                   break;
  309.                }
  310.             }
  311.          }// end for i
  312.          
  313.          if (iday == -1) {startbar = -1; endbar = -1;}
  314.                  
  315.          break;
  316.          
  317.       default:
  318.          dt.proftf      = iTime( NULL, giProfileTf, ibar.proftf );
  319.          dt.proftf.next = iTime( NULL, giProfileTf, ibar.proftf - 1 );
  320.          
  321.          startbar  = iBarShift ( NULL, giDataTf, dt.proftf);
  322.          endbar    = iBarShift ( NULL, giDataTf, dt.proftf.next - (giDataTf * 60) );
  323.          //current week.Month        
  324.          if (dt.proftf.next < dt.proftf) endbar = 0;        
  325.          // fix ibarshift on month\week start
  326.          if ( iTime(NULL, giDataTf, startbar) < dt.proftf ) startbar--;    
  327.                            
  328.          break;
  329.    }        
  330. }
  331. //+------------------------------------------------------------------+
  332. //| getHHLL                                                          |
  333. //+------------------------------------------------------------------+
  334. void getHHLL(int startbar, int endbar, double &hh, double &ll)
  335. {
  336.    hh = iHigh ( NULL, giDataTf, iHighest(NULL, giDataTf, MODE_HIGH, (startbar - endbar)+1, endbar) );
  337.    ll = iLow  ( NULL, giDataTf, iLowest (NULL, giDataTf, MODE_LOW,  (startbar - endbar)+1, endbar) );
  338.    hh = NormalizeDouble(hh, fdigits);
  339.    ll = NormalizeDouble(ll, fdigits);
  340. }
  341.  
  342. //+------------------------------------------------------------------+
  343. //| drawInfo                                                         |
  344. //+------------------------------------------------------------------+
  345. void drawInfo()
  346. {
  347.    
  348.    string info = "Volume Profile";
  349.    if (!UseVolumeProfile) info = "TPO Profile";
  350.    
  351.    if (ObjectFind(gsPref+"lblinfo1") == -1)
  352.     ObjectCreate (gsPref+"lblinfo1", OBJ_LABEL,0,0,0);
  353.    
  354.    ObjectSet    (gsPref+"lblinfo1", OBJPROP_CORNER, 3);
  355.    ObjectSetText(gsPref+"lblinfo1", info, 8, "Tahoma", InfoColor);
  356.    ObjectSet    (gsPref+"lblinfo1", OBJPROP_XDISTANCE, 10);
  357.    ObjectSet    (gsPref+"lblinfo1", OBJPROP_YDISTANCE, 20);
  358.    
  359.    if (giProfileTf == PERIOD_D1)
  360.    {
  361.       if (ObjectFind(gsPref+"lblinfo2") == -1)      
  362.         ObjectCreate (gsPref+"lblinfo2", OBJ_LABEL,0,0,0);
  363.      
  364.       ObjectSet    (gsPref+"lblinfo2", OBJPROP_CORNER, 3);
  365.       ObjectSetText(gsPref+"lblinfo2", "DayStartHour: " + DayStartHour, 8, "Tahoma", InfoColor);
  366.       ObjectSet    (gsPref+"lblinfo2", OBJPROP_XDISTANCE, 10);
  367.       ObjectSet    (gsPref+"lblinfo2", OBJPROP_YDISTANCE, 5);            
  368.    }
  369.    
  370.    
  371. }
  372. //+------------------------------------------------------------------+
  373. //| getPriceTPO                                                      |
  374. //+------------------------------------------------------------------+
  375. void getPriceTPO
  376. (
  377.      int       startbar
  378.    , int       endbar
  379.    , double    hh
  380.    , double    ll
  381.    , double    &aprice.step[][3]
  382.    , int       &countps
  383.    , int       &maxtpo
  384.    , int       &maxtpoidx
  385.    , double    &totaltpo
  386.    , double    &maxvol
  387.    , int       &maxvolidx  
  388.    , double    &totalvol
  389. )
  390. {
  391.  
  392.    maxtpo        = 0;
  393.    maxtpoidx     = 0;
  394.    totaltpo      = 0.0;
  395.    maxvol        = 0.000001;
  396.    maxvolidx     = 0;
  397.    totalvol      = 0.0;
  398.    
  399.    double     shh = hh; //start hh
  400.    double     profile.range       = MathMax(hh - ll, gdOneTick)
  401.             , mid.profile.price   = hh - (0.5 * profile.range);  
  402.            
  403.    //--- populate price level    
  404.    countps  = 0;          
  405.    while (shh >= ll)
  406.    {  
  407.       ArrayResize(aprice.step, countps+1);  
  408.       aprice.step [countps][PRICEIDX] = shh;
  409.       aprice.step [countps][TPOIDX]   = 0.0;
  410.       aprice.step [countps][VOLIDX]   = 0.0;
  411.      
  412.       shh -= gdOneTick;
  413.       countps  ++;
  414.  
  415.    } // while (shh >= ll)  
  416.    //--- end populate price level                
  417.    
  418.    //--- Counting tpo    
  419.    int      i, j;
  420.    double   price.step;
  421.    
  422.    for (i=0; i<countps; i++)
  423.    {
  424.       price.step = aprice.step[i][PRICEIDX];
  425.       j = startbar;
  426.       while ( j >= endbar)
  427.       {            
  428.          double hp        = iHigh  (NULL, giDataTf, j);
  429.          double lp        = iLow   (NULL, giDataTf, j);        
  430.          double bar.vol   = iVolume(NULL, giDataTf, j);
  431.          double bar.range = MathMax( (hp - lp) / fpoint, gdOneTick );
  432.          double pip.vol   = bar.vol / bar.range;        
  433.          
  434.          if (  price.step >= lp && price.step <= hp )  
  435.          {
  436.             aprice.step[i][TPOIDX] += 1;  
  437.             aprice.step[i][VOLIDX] += pip.vol;
  438.             totaltpo += 1;
  439.             totalvol += pip.vol;
  440.             // save maxtpo
  441.             if (aprice.step[i][TPOIDX] > maxtpo)
  442.             {
  443.                maxtpo    = aprice.step[i][TPOIDX];
  444.                maxtpoidx = i;              
  445.             }
  446.            
  447.             if (aprice.step[i][TPOIDX] == maxtpo)
  448.             {
  449.                // take the closes to the middle of profile range
  450.                if (   MathAbs(mid.profile.price - aprice.step[i][PRICEIDX])
  451.                     < MathAbs(mid.profile.price - aprice.step[maxtpoidx][PRICEIDX])
  452.                    )
  453.                {
  454.                   maxtpo    = aprice.step[i][TPOIDX];
  455.                   maxtpoidx = i;
  456.                }
  457.             }
  458.             // end save maxtpo
  459.            
  460.             // save maxvol
  461.             if (aprice.step[i][VOLIDX] > maxvol)
  462.             {
  463.                maxvol    = aprice.step[i][VOLIDX];
  464.                maxvolidx = i;              
  465.             }
  466.            
  467.             if (aprice.step[i][VOLIDX] == maxvol)
  468.             {
  469.                // take the closes to the middle of profile range
  470.                if (   MathAbs(mid.profile.price - aprice.step[i][PRICEIDX])
  471.                     < MathAbs(mid.profile.price - aprice.step[maxvolidx][PRICEIDX])
  472.                    )
  473.                {
  474.                   maxvol    = aprice.step[i][VOLIDX];
  475.                   maxvolidx = i;
  476.                }
  477.             }
  478.             // end save maxtpo                                        
  479.          } // end if (price-gdHistoRange <= High[j] && price >= Low[j])  
  480.          
  481.          j--;
  482.       } // end while ( iBarShift(NULL, giProfileTf, Time[j]) == itfsource )
  483.      
  484.       //----end Counting tpo    
  485.      
  486.    }// end for (i=0; i<countps; i++)  
  487.    
  488. }
  489.  
  490. //+------------------------------------------------------------------+
  491. //| drawPriceHistoAndPOCLines                                        |
  492. //+------------------------------------------------------------------+
  493. void drawPriceHistoAndPOCLines
  494. (
  495.      int    startbar
  496.    , int    endbar  
  497.    , int    ibar.proftf  
  498.    , int    countps
  499.    , double aprice.step[][]
  500.    , int    maxtpo
  501.    , int    maxtpoidx
  502.    , double maxvol
  503.    , int    maxvolidx
  504. )
  505. {
  506.    double   price1, price2, dstep;
  507.    int      numtpo;
  508.    double   numvol;
  509.    int      step, i;
  510.    int      chart.startbar = iBarShift( NULL, 0, iTime(NULL, giDataTf, startbar) );
  511.    int      chart.endbar   = iBarShift( NULL, 0, iTime(NULL, giDataTf, endbar) );
  512.    int      numbar         = chart.startbar - chart.endbar;
  513.    color    clr;
  514.    datetime t1 = Time[chart.startbar], t2;
  515.    string   strdt.proftf = TimeToStr (iTime (NULL, giProfileTf, ibar.proftf), TIME_DATE);
  516.    double   lprice = aprice.step[countps-1][0];
  517.    
  518.    
  519.    //--- draw price histo
  520.    if (ShowPriceHistogram)
  521.    {  
  522.      
  523.       if (ibar.proftf == 0)
  524.       {
  525.          if (UseVolumeProfile)
  526.             delObjs( gsPref + "#" + ibar.proftf + ".histovol.");  
  527.          else
  528.             delObjs( gsPref + "#" + ibar.proftf + ".histotpo.");
  529.       }
  530.        
  531.       for (step=0; step<countps; step += giStep)      
  532.       {
  533.          price1   = aprice.step[step][PRICEIDX];
  534.          price2   = aprice.step[step+(giStep)][PRICEIDX];
  535.      
  536.          if (MathCeil(dstep/2) == dstep/2) clr = HistoColor1;
  537.          else clr = HistoColor2;
  538.      
  539.          if (!UseVolumeProfile)
  540.          {
  541.             numtpo   = 0;
  542.      
  543.             for (i=step; i < step+giStep; i++)
  544.                numtpo = MathMax( numtpo, aprice.step[i][TPOIDX] );
  545.      
  546.             double x2 = ((giDataTf/1.0)/Period()) * numtpo;
  547.            
  548.             numtpo = MathCeil( x2 ) ;
  549.            
  550.             t2 = Time[chart.startbar - numtpo] ;
  551.                  
  552.             if (t2<=t1) t2 = t1 + (Period()*60);        
  553.      
  554.             createRect( "#" + ibar.proftf + ".histotpo." + DoubleToStr(price1,fdigits)
  555.                , price1,                  t1
  556.                , MathMax(price2, lprice), t2
  557.                , clr );
  558.          }  
  559.          else
  560.          {            
  561.             numvol = 0.0;
  562.             for (i=step; i< step+giStep; i++)
  563.               numvol   = MathMax(numvol, (aprice.step[i][VOLIDX] / maxvol) * numbar );  
  564.      
  565.             //numtpo vol;  
  566.             numtpo = MathCeil((VolAmplitudePercent/100.0)*numvol);  
  567.      
  568.             t2 = Time[chart.startbar - numtpo] ;
  569.             createRect( "#" + ibar.proftf + ".histovol." + DoubleToStr(price1,fdigits)
  570.                , price1,                  t1
  571.                , MathMax(price2, lprice), t2
  572.                , clr );            
  573.          }  
  574.          
  575.          dstep += 1.0;                                        
  576.       }      
  577.      
  578.    }
  579.      
  580.    //--end draw price histo
  581.      
  582.    //--- draw poc lines
  583.    t2 = Time[chart.startbar] + (2 * giProfileTf * 60);
  584.  
  585.    int idx = maxvolidx;
  586.    
  587.    string spoc = ".POC ";
  588.    
  589.    if (!UseVolumeProfile) idx   = maxtpoidx;
  590.    
  591.    clr = POCColor;
  592.    if ( ibar.proftf != 0 )
  593.    {
  594.       double hh, ll;
  595.       getHHLL(endbar-1, 0, hh, ll);
  596.      
  597.       if ( (aprice.step[ idx ][PRICEIDX] > hh && aprice.step[ idx ][PRICEIDX] > ll)
  598.          ||(aprice.step[ idx ][PRICEIDX] < hh && aprice.step[ idx ][PRICEIDX] < ll) )
  599.       {
  600.          clr = VirginPOCColor;
  601.          spoc = ".VPOC ";
  602.       }
  603.    }  
  604.    
  605.    
  606.    if (ibar.proftf <= ExtendedPocLines || ibar.proftf == 0)
  607.    {
  608.       t2 = Time[0] + 10*Period()*60;
  609.      
  610.       createText( "#" + ibar.proftf +".1.1.poc.price"  
  611.          , t2 + (3 * Period() * 60)
  612.          , aprice.step[ idx ][PRICEIDX]
  613.          , addStr(
  614.             ProfileTimeframe + "#" + ibar.proftf + spoc
  615.             + StringSubstr( strdt.proftf, 2, 8 )+" "
  616.             + DoubleToStr( aprice.step[ idx ][PRICEIDX], fdigits )
  617.             , " ", 60
  618.             )
  619.          , 8, "Arial Narrow", clr
  620.          );                      
  621.    }    
  622.  
  623.    bool backg = true;
  624.    if (spoc == ".VPOC ") backg = false;
  625.    createTl("#" + ibar.proftf + ".1.1.poc"
  626.       , t1, aprice.step[ idx ][PRICEIDX]
  627.       , t2, aprice.step[ idx ][PRICEIDX]
  628.       , clr, STYLE_SOLID, 1, backg
  629.       );  
  630.    
  631.    //--- draw open and close
  632.    if (ShowOpenCloseArrow)
  633.    {
  634.    
  635.       double dopen  = iOpen (NULL, giDataTf, startbar);
  636.       double dclose = iClose(NULL, giDataTf, endbar);
  637.       createArw("#0.0.0.0" + ibar.proftf + ".open", dopen
  638.          , Time[chart.startbar], 2, OpenColor);
  639.    
  640.       createArw("#0.0.0.0" + ibar.proftf + ".close", dclose
  641.          , Time[chart.startbar], 2, CloseColor);
  642.    }        
  643.  
  644. }
  645. //+------------------------------------------------------------------+
  646. //| getValueArea                                                     |
  647. //+------------------------------------------------------------------+
  648. void getValueArea
  649. (
  650.      int      countps
  651.    , double   aprice.step[][]
  652.    , int      maxtpo
  653.    , int      maxtpoidx      
  654.    , double   totaltpo
  655.    , int      maxvol
  656.    , int      maxvolidx
  657.    , double   totalvol
  658.    , double   &vah
  659.    , int      &vahidx
  660.    , double   &val
  661.    , int      &validx
  662. )
  663. {
  664.  
  665.    int   idx      = maxvolidx;
  666.    int   idx2     = VOLIDX;
  667.    double total   = totalvol;
  668.    if (!UseVolumeProfile)
  669.    {  
  670.       idx   = maxtpoidx;
  671.       idx2  = TPOIDX;
  672.       total = totaltpo;
  673.    }
  674.    
  675.    double vatpo  = (VATPOPercent/100) * total;      
  676.    double tpo    = aprice.step[ idx ][ idx2 ];  
  677.    double tpo2upper, tpo2lower;
  678.    int    upperidx = 1, lastupperidx = 1;
  679.    int    loweridx = 1, lastloweridx = 1;
  680.  
  681.    while (tpo <= vatpo)
  682.    {
  683.  
  684.       double utpo1 = aprice.step[ idx - upperidx ][idx2];
  685.       double ltpo1 = aprice.step[ idx + loweridx ][idx2];
  686.       double utpo2 = aprice.step[ idx - (upperidx+1) ][idx2];
  687.       double ltpo2 = aprice.step[ idx + (loweridx+1) ][idx2];
  688.      
  689.       //check if vatpo reached by a single step                  
  690.       if ( utpo1 >= ltpo1 && tpo + utpo1 >= vatpo )
  691.       {
  692.          lastupperidx = upperidx;
  693.          tpo += utpo1;
  694.          break;
  695.       }
  696.       else
  697.       if ( ltpo1 > utpo1 && tpo + ltpo1 >= vatpo )
  698.       {
  699.          lastloweridx = loweridx;
  700.          tpo += ltpo1;
  701.          break;        
  702.       }
  703.      
  704.       //2 step price
  705.       tpo2upper = utpo1 + utpo2;
  706.       tpo2lower = ltpo1 + ltpo2;
  707.                        
  708.       if (tpo2upper >= tpo2lower)
  709.       {
  710.          lastupperidx = upperidx+1;
  711.          if (idx-lastupperidx < 0) lastupperidx--;
  712.          upperidx +=2;
  713.          tpo += tpo2upper;
  714.       }
  715.       else
  716.       {
  717.          lastloweridx = loweridx+1;
  718.          if (idx+lastloweridx > countps-1) lastloweridx--;
  719.          loweridx +=2;
  720.          tpo += tpo2lower;        
  721.       }        
  722.    }//end  while (tpo <= vatpo)
  723.    
  724.    vahidx = idx - lastupperidx;
  725.    validx = idx + lastloweridx;
  726.    vah    = aprice.step[ idx-(lastupperidx) ][0];
  727.    val    = aprice.step[ idx+(lastloweridx) ][0];
  728.  
  729. }
  730. //+------------------------------------------------------------------+
  731. //| drawValueArea                                                    |
  732. //+------------------------------------------------------------------+
  733. void drawValueArea
  734. (
  735.      int    startbar
  736.    , int    endbar
  737.    , int    ibar.proftf
  738.    , int    countps
  739.    , double aprice.step[][]
  740.    , double vah
  741.    , int    vahidx
  742.    , double val
  743.    , int    validx
  744. )
  745. {
  746.    int      chart.startbar = iBarShift( NULL, 0, iTime(NULL, giDataTf, startbar) );
  747.    int      chart.endbar   = iBarShift( NULL, 0, iTime(NULL, giDataTf, endbar - 1) ) ;  
  748.    int      numtpo;
  749.    int      step;
  750.    datetime dtva1          = Time[chart.startbar];
  751.    datetime dtva2          = Time[chart.endbar]; //iTime(NULL, giProfileTf, ibar.proftf-1);
  752.    double   lprice         = aprice.step[countps-1][0];    
  753.  
  754.    //current profile  
  755.    if (endbar == 0 ) dtva2 = Time[0] + 10*Period()*60;
  756.    
  757.    int      argb[3];
  758.    intToRGB(VAColor, argb);      
  759.  
  760.    if (ibar.proftf == 0)
  761.    {
  762.       delObjs( gsPref + "#" + ibar.proftf + ".0.0.0.va.");
  763.       //ObjectDelete( gsPref + "#" + ibar.proftf + ".0.0.0.vah");
  764.       //ObjectDelete( gsPref + "#" + ibar.proftf + ".0.0.0.val");
  765.    }
  766.  
  767.    int      iclr, i, shiftx;  
  768.    double   price1, price2;
  769.    int      midvaidx    = vahidx + MathCeil((validx-vahidx)/2);  
  770.    int      vaidx       = 0;      
  771.    
  772.    // show value area
  773.    if (ShowValueArea)  
  774.    {
  775.       for (step=0; step<countps; step += giStep)      
  776.       {
  777.  
  778.          if ( step > validx ) break;
  779.          //if ( step < vahidx ) continue;
  780.      
  781.          price1   = aprice.step[ step ][0];
  782.          price2   = aprice.step[ step+giStep ][0];
  783.          
  784.          if (price2 > vah) continue;
  785.            
  786.          dtva1  = MathMax(
  787.               ObjectGet(gsPref + "#" + ibar.proftf + ".histotpo." + DoubleToStr(price1, fdigits), OBJPROP_TIME2 )
  788.             , ObjectGet(gsPref + "#" + ibar.proftf + ".histovol." + DoubleToStr(price1, fdigits), OBJPROP_TIME2 )
  789.             );
  790.          //shadow effect
  791.          //dtva1 += (Period() * 60);
  792.      
  793.          if ( dtva1 < Time[chart.startbar] ) dtva1 = Time[0] + Period()*60;  
  794.          if ( !ShowPriceHistogram ) dtva1 = Time[chart.startbar];      
  795.          //if ( dtva2 < dtva1 ) dtva2  = Time[0] + 10*Period()*60;
  796.      
  797.          //rect @vah
  798.          if (vah <= price1 && vah >= price2) price1 = vah;
  799.      
  800.          createRect("#" + ibar.proftf + ".0.0.0.va." + vaidx
  801.             , price1, dtva1
  802.             , MathMax(price2, val), dtva2
  803.             , RGB(argb[0]+iclr, argb[1]+iclr, argb[2]+iclr)
  804.             );  
  805.      
  806.          if (step <= midvaidx)
  807.          {      
  808.             if (giProfileTf == PERIOD_MN1) iclr +=1;
  809.             if (giProfileTf == PERIOD_W1)  iclr +=2;
  810.             else iclr += 3;
  811.          }
  812.          else
  813.          {
  814.             if (giProfileTf == PERIOD_MN1) iclr -=1;
  815.             if (giProfileTf == PERIOD_W1)  iclr -=2;
  816.             else iclr -= 3;      
  817.          }
  818.      
  819.          vaidx ++;                                      
  820.       }            
  821.    }// end show value area
  822.    
  823.    //draw vah and val lines
  824.    if (ShowVAHVALLines)
  825.    {
  826.       if(dtva2 < Time[chart.startbar]) dtva2 = Time[0] + (10*Period()*60);
  827.      
  828.       int width = 1;
  829.       if (!ShowValueArea) width = 2;
  830.    
  831.       createTl("#" + ibar.proftf + ".0.0.0.vah"
  832.          , Time[chart.startbar], aprice.step[ vahidx ][PRICEIDX]
  833.          , dtva2,                aprice.step[ vahidx ][PRICEIDX]
  834.          , VALinesColor, STYLE_SOLID, width
  835.          );      
  836.          
  837.       createTl("#" + ibar.proftf + ".0.0.0.val"
  838.          , Time[chart.startbar], aprice.step[ validx ][PRICEIDX]
  839.          , dtva2,                aprice.step[ validx ][PRICEIDX]
  840.          , VALinesColor, STYLE_SOLID, width
  841.          );          
  842.    }
  843. }
  844.  
  845. //+------------------------------------------------------------------+
  846. //|add char at beginning or end of text                              |
  847. //+------------------------------------------------------------------+
  848. string addStr(string str, string char, int maxlength, bool atbeginning = true)
  849. {
  850.    int l = maxlength - StringLen(str);
  851.    for (int i=0; i<l; i++)
  852.    {
  853.       if (atbeginning) str = char + str;
  854.       else str = str + char;
  855.    }
  856.      
  857.    return(str);
  858. }  
  859. //+------------------------------------------------------------------+
  860. //| createRect                                                       |
  861. //+------------------------------------------------------------------+  
  862. void createRect(string objname, double p1, datetime t1, double p2, datetime t2, color clr, bool back=true)
  863. {
  864.  
  865.    objname = gsPref + objname;
  866.    if(ObjectFind(objname) != 0)    
  867.       ObjectCreate(objname, OBJ_RECTANGLE, 0, 0, 0, 0, 0);
  868.    
  869.    ObjectSet(objname, OBJPROP_PRICE1, p1);
  870.    ObjectSet(objname, OBJPROP_TIME1,  t1);
  871.    ObjectSet(objname, OBJPROP_PRICE2, p2);
  872.    ObjectSet(objname, OBJPROP_TIME2,  t2);
  873.    ObjectSet(objname, OBJPROP_COLOR,  clr);
  874.    ObjectSet(objname, OBJPROP_BACK,   back);
  875. }  
  876. //+------------------------------------------------------------------+
  877. //| createArw                                                        |
  878. //+------------------------------------------------------------------+
  879. void createArw(string objname, double p1, datetime t1, int ac,
  880.    color clr)
  881. {
  882.    objname = gsPref + objname;
  883.    if(ObjectFind(objname) != 0)    
  884.       ObjectCreate(objname, OBJ_ARROW, 0, 0, 0, 0, 0);
  885.    
  886.    ObjectSet(objname, OBJPROP_PRICE1,     p1);
  887.    ObjectSet(objname, OBJPROP_TIME1,      t1);  
  888.    ObjectSet(objname, OBJPROP_ARROWCODE,  ac);  
  889.    ObjectSet(objname, OBJPROP_COLOR,      clr);  
  890.    
  891. }
  892. //+------------------------------------------------------------------+
  893. //| createText                                                       |
  894. //+------------------------------------------------------------------+
  895. void createText(string name, datetime t, double p, string text
  896.    , int size=8, string font="Arial", color c=White)
  897. {
  898.    name = gsPref + name;
  899.    
  900.    if (ObjectFind(name) != 0)
  901.       ObjectCreate (name,OBJ_TEXT,0,0,0);
  902.    
  903.    ObjectSet    (name,OBJPROP_TIME1,  t);
  904.    ObjectSet    (name,OBJPROP_PRICE1, p);
  905.    ObjectSetText(name,text,size,font, c);
  906.  
  907. }
  908. //+------------------------------------------------------------------+
  909. //| createTl                                                         |
  910. //+------------------------------------------------------------------+
  911. void createTl(string tlname, datetime t1, double v1, datetime t2, double v2,
  912.      color tlColor, int style = STYLE_SOLID, int width = 1, bool back=true, string desc="")
  913. {
  914.    tlname = gsPref + tlname;
  915.    if(ObjectFind(tlname) != 0)
  916.    {
  917.       ObjectCreate(
  918.             tlname
  919.             , OBJ_TREND
  920.             , 0
  921.             , t1
  922.             , v1
  923.             , t2
  924.             , v2
  925.             );      
  926.    }else
  927.    {
  928.       ObjectMove(tlname, 0, t1, v1);  
  929.       ObjectMove(tlname, 1, t2, v2);
  930.    }
  931.    ObjectSet(tlname, OBJPROP_COLOR, tlColor);
  932.    ObjectSet(tlname, OBJPROP_RAY,   false);
  933.    ObjectSet(tlname, OBJPROP_STYLE, style);
  934.    ObjectSet(tlname, OBJPROP_WIDTH, width);
  935.    ObjectSet(tlname, OBJPROP_BACK,  back);
  936.    ObjectSetText(tlname, desc);
  937. }
  938.  
  939. //+------------------------------------------------------------------+
  940. //| newBarProfileTf                                                  |
  941. //+------------------------------------------------------------------+
  942. bool newBarProfileTf()
  943. {
  944.    
  945.    static datetime LastProfile;
  946.    datetime CurrProfile;
  947.    string strdate;
  948.    int oneperiod = giProfileTf*60;
  949.    
  950.    switch (giProfileTf)
  951.    {
  952.       case PERIOD_D1:
  953.          strdate     = TimeToStr(Time[0],TIME_DATE);
  954.          CurrProfile = StrToTime(strdate) + (DayStartHour * PERIOD_H1 * 60);
  955.          if (Time[0] < CurrProfile) CurrProfile -= oneperiod;
  956.          //string str = StringConcatenate("Currtime ", TimeToStr(Time[0]), "\nLastProfile ", TimeToStr(LastProfile), "\nCurrProfile ", TimeToStr(CurrProfile), "\nlastbar!=currbar ", (LastProfile != CurrProfile));                            
  957.          break;
  958.          
  959.       default: //weekly and montly
  960.          CurrProfile = iTime(NULL, giProfileTf, iBarShift(NULL, giProfileTf, Time[0]));
  961.          break;
  962.    }
  963.  
  964.    if(LastProfile != CurrProfile)
  965.    {
  966.      LastProfile = CurrProfile;
  967.      return (true);
  968.    }
  969.    
  970.    return(false);    
  971.    
  972. }
  973. //+------------------------------------------------------------------+
  974. //| newBar                                                           |
  975. //+------------------------------------------------------------------+  
  976.  
  977. bool newBar()
  978. {
  979.  static datetime LastBar;
  980.  datetime CurrBar = Time[0];
  981.  
  982.  if(LastBar != CurrBar)
  983.  {
  984.    LastBar = CurrBar;
  985.    return (true);
  986.  }
  987.  
  988.  return(false);    
  989. }  
  990.  
  991. //+------------------------------------------------------------------+
  992. //| secondDiff                                                       |
  993. //+------------------------------------------------------------------+
  994. /*
  995. bool secondDiff(int sec = 10)
  996. {
  997.    static datetime lasttime ;
  998.    int diff = TimeCurrent() - lasttime ;
  999.  
  1000.    if (diff > sec )
  1001.    {
  1002.       lasttime = TimeCurrent();
  1003.       return (true);
  1004.    }
  1005.    
  1006.    return (false);
  1007.    
  1008. }  
  1009. */
  1010.  
  1011.  
  1012. //+------------------------------------------------------------------+
  1013. //| delObjs function                                                 |
  1014. //+------------------------------------------------------------------+
  1015. void delObjs(string s="")
  1016. {
  1017.    int objs = ObjectsTotal();
  1018.    if (StringLen(s) == 0) s = gsPref;
  1019.    
  1020.    string name;
  1021.    for(int cnt=ObjectsTotal()-1;cnt>=0;cnt--)
  1022.    {
  1023.       name=ObjectName(cnt);
  1024.       if (StringSubstr(name,0,StringLen(s)) == s)      
  1025.          ObjectDelete(name);
  1026.    }  
  1027. }
  1028.  
  1029. //+------------------------------------------------------------------+
  1030. //| convert red, green and blue values to color                      |
  1031. //+------------------------------------------------------------------+
  1032. int RGB(int red_value,int green_value,int blue_value)
  1033. {
  1034.    //---- check parameters
  1035.    if(red_value<0)     red_value   = 0;
  1036.    if(red_value>255)   red_value   = 255;
  1037.    if(green_value<0)   green_value = 0;
  1038.    if(green_value>255) green_value = 255;
  1039.    if(blue_value<0)    blue_value  = 0;
  1040.    if(blue_value>255)  blue_value  = 255;
  1041.    //----
  1042.    green_value<<=8;
  1043.    blue_value<<=16;
  1044.    return(red_value+green_value+blue_value);
  1045. }
  1046. //+------------------------------------------------------------------+
  1047. //| convert color to red, green and blue values                      |
  1048. //+------------------------------------------------------------------+  
  1049. void intToRGB(int clr, int &argb[] )
  1050. {  
  1051.    int red   = (clr % 0x1000000 / 0x10000);  
  1052.    int green = (clr % 0x10000 / 0x100);  
  1053.    int blue  = (clr % 0x100);
  1054.  
  1055.    argb[0] = red;
  1056.    argb[1] = green;
  1057.    argb[2] = blue;
  1058.      
  1059. }  
  1060. //+------------------------------------------------------------------+
  1061.  
  1062. /*
  1063. sugestions v1.31
  1064. http://www.forexfactory.com/showpost.php?p=4432129&postcount=629
  1065. @mima
  1066. Very good, I like that histogram can be false/true...VA is 1st standard deviation...so there is need for 2nd , 3rd and extremes(excesses)...Hopefully it will be in next revision. Thank you.
  1067.  
  1068. http://www.forexfactory.com/showpost.php?p=4432111&postcount=628
  1069. @kave
  1070. PS: One thing i notice that if the POC & VPC is align the POC overlay onto the VPC as shown here, (those 2 POC of 23rd & 24th). Since the 24th Feb qualifies as a VPC, is it possible let the VPC line to be overlayed on top instead??
  1071. http://www.forexfactory.com/showpost.php?p=4433083&postcount=634
  1072. @jamie
  1073. One comment, for the volume based profile is it possible to reduce the amplitude of the profile so that it doesn't extend so far to the right?
  1074.  
  1075. */
Advertisement
Add Comment
Please, Sign In to add comment