Login Page - Create Account

Support Board


Date/Time: Thu, 28 Mar 2024 14:07:48 +0000



[User Discussion] - Time of Day Adjusted Volume :: User Discussion

View Count: 1925

[2013-07-07 00:04:02]
Kiwi - Posts: 372
Just to let those who were interested know I have restarted my project to build a general version of this.

http://www.sierrachart.com/supportboard/showthread.php?t=39127


I anticipate finishing this week (you may well laugh).
[2013-07-08 07:44:29]
Kiwi - Posts: 372
So,

I have finished a generalized version. I commented out a few things that I used that are perhaps not generally relevant but you can edit the code yourself if you wish to add more to it.

#include "sierrachart.h"

SCDLLInit("Kiwi's Stuff 2013 (kiwi13.dll)")


/****************************************************************************/
SCSFExport scsf_KiwiAdjVol(SCStudyInterfaceRef sc)
{
/*
This function assumes that there are enough days open on the chart
to create an array of 1 bar per time interval.
It accumulates volume for each time segment along with a total number
and then compares it with the average per segment to generate an
adjustment for live volume based on historical periods.
Smoothing is optional.
*/
SCSubgraphRef vol = sc.Subgraph[0], vraw = sc.Subgraph[2],
   o1 = sc.Subgraph[10], o2 = sc.Subgraph[11], o3 = sc.Subgraph[12],
vSmooth = sc.Subgraph[4], vMult = sc.Subgraph[5], vSum = sc.Subgraph[6],
vHour = sc.Subgraph[7], vMin = sc.Subgraph[8], vTime = sc.Subgraph[9];

if (sc.SetDefaults)
{
sc.GraphName = "AdjVol";
sc.StudyDescription = "Kiwi's Adjusted Volume Study";
vol.Name = "Volume";
    vol.DrawStyle = DRAWSTYLE_BAR;
//sc.Subgraph[1].Name = " ";
    //sc.Subgraph[1].DrawStyle = DRAWSTYLE_DONOTDRAW;
vraw.Name = " ";
    vraw.DrawStyle = DRAWSTYLE_IGNORE;
o1.Name = "o1";
o2.Name = "o2";
o3.Name = "o3";
vSmooth.Name = "vSmooth";
vMult.Name = "vMult";
vSum.Name = "vSum";
vHour.Name = "vHour";
vMin.Name = "vMin";
vTime.Name = "vTime";
sc.Subgraph[0].SecondaryColorUsed = 1;
sc.Subgraph[1].SecondaryColorUsed = 1;

sc.Input[1].Name = "Bars to Smooth Volume adjustment";
sc.Input[1].SetInt(0);
//sc.Input[2].Name = "Get Range from ... bars ";
//sc.Input[2].SetInt(20);
//sc.Input[3].Name = "Max Size of Vol Bar ";
//sc.Input[3].SetInt(9000000);
//sc.Input[4].Name = "Use only two colours";
//sc.Input[4].ValueType = YESNO_VALUE;
    sc.FreeDLL = 0;
return;
}

int i, j, as=sc.ArraySize-1;
int& sizeVarray = sc.PersistVars->i1;
int& firstBarCounted = sc.PersistVars->i2;
int& lastBarCounted = sc.PersistVars->i3;
int& lowest_time = sc.PersistVars->i4;
int& highest_time = sc.PersistVars->i5;
int& i_time = sc.PersistVars->i6;
  int& top = sc.PersistVars->i9;
int temp = sc.Input[2].IntValue+1;
  int& smooth_by = sc.Input[1].IntValue;

if(sc.UpdateStartIndex == 0) {
    int first_date = sc.BaseDateTimeIn[0].GetDate();
    int last_date = sc.BaseDateTimeIn[as].GetDate();
    firstBarCounted = lastBarCounted = 0;
    lowest_time = 99999, highest_time = 0;
    // establish lowest and highest times of day
    // and bars to start and finish bar volume counts
    for(j = 0; j < sc.ArraySize-1; j++) {
      lowest_time = min(lowest_time, sc.BaseDateTimeIn[j].GetTime());
      highest_time = max(highest_time, sc.BaseDateTimeIn[j].GetTime());
      if(firstBarCounted == 0 && sc.BaseDateTimeIn[j].GetDate() > first_date)
        firstBarCounted = j;
      else if(lastBarCounted == 0 && sc.BaseDateTimeIn[j].GetDate() >= last_date)
        lastBarCounted = j - 1;
    }
    // Initialize sum and time arrays for chart
    sizeVarray = ((highest_time - lowest_time) / sc.SecondsPerBar) + 1;
    if(sizeVarray >= as) return; // but nothing to do if too few bars
    for(j = 0; j <= sizeVarray; j++) {
        vSum[j] = 0;
        vTime[j] = lowest_time + j * sc.SecondsPerBar;
        vHour[j] = int(vTime[j] / 3600);
        vMin[j] = int(vTime[j] / 60) - (vHour[j] * 60);
    }
    // Sum volumes for all bar periods
    i = 0;
    for(j = firstBarCounted; j <= lastBarCounted;) {
      if(sc.BaseDateTimeIn[j].GetTime() == vTime[i]) {
        vSum[i] += sc.BaseDataIn[4][j];
        j++; i++;
      }
      else if(sc.BaseDateTimeIn[j].GetTime() > highest_time )
        ++j; // if > highest time skip
      else if(sc.BaseDateTimeIn[j].GetTime() > vTime[i])
        ++i; // if > current bucket time, next bucket
      else if(sc.BaseDateTimeIn[j].GetTime() < vTime[i])
        i = 0; // if < current bucket time, restart buckets
    }
    float totalVolume = 0.0;
    for(j = 0; j < sizeVarray; j++)
      totalVolume += vSum[j];
    float avgVolume = totalVolume / sizeVarray;
    // Multiplier for each time slot = avg sum vol per bar / sum for this bar
    for(j = 0; j < sizeVarray; j++)
      if(vSum[j] > 0)
        vMult[j] = avgVolume / vSum[j];
      else
        // if there is a lunch break hold the last value for smoothing
        vMult[j] = vMult[j - 1];
    for(j = 0; j < sizeVarray; j++)
      sc.SimpleMovAvg(vMult, vSmooth, j, smooth_by);
  }

  
  // Now apply multipliers to volume bars. Use smoothing if > zero
  i_time = 0;
  for ( i = sc.UpdateStartIndex; i < sc.ArraySize;)
  {
    int p = i - 1;

    if(sc.BaseDateTimeIn[i].GetTime() == vTime[i_time]) {
      if(smooth_by)
        vol[i] = int(sc.BaseDataIn[4][i] * vSmooth[i_time]);
      else
        vol[i] = int(sc.BaseDataIn[4][i] * vMult[i_time]);
      i++; i_time++;
    }
    else if(sc.BaseDateTimeIn[i].GetTime() > highest_time )
      ++i; // if > highest time skip
    else if(sc.BaseDateTimeIn[i].GetTime() > vTime[i_time])
      ++i_time; // if > current bucket time, next bucket
    else if(sc.BaseDateTimeIn[i].GetTime() < vTime[i_time])
      i_time = 0; // if < current bucket time, restart buckets
    
    if( sc.BaseDataIn[3][i] > sc.BaseDataIn[3][p] )
      {sc.Subgraph[0].DataColor[i] = sc.Subgraph[0].PrimaryColor;}
    else if( sc.BaseDataIn[3][i] < sc.BaseDataIn[3][p] )
      {sc.Subgraph[0].DataColor[i] = sc.Subgraph[0].SecondaryColor;}
    else { sc.Subgraph[0].DataColor[i] = sc.Subgraph[0].DataColor[p]; }

    //sc.Subgraph[1][i] = 0.0000000001;
    //vol[i] = fabs(vraw[i]);
    if(top > 0 && vol[i] > top) {
      vol.DataColor[i] = sc.Subgraph[1].SecondaryColor;
    }
  }


  //if( recycle !=0 )
  //{
    //i = sc.IndexOfLastVisibleBar;
    //vrange = sc.Subgraph[0][i];
    //int start = i - temp;
    //for( ; i > start; i--)
    //{ if(sc.Subgraph[0][i] > vrange) vrange = sc.Subgraph[0][i]; }
    //sc.ScaleRangeType = SCALE_USERDEFINED;
    //sc.ScaleRangeBottom = 0;
    //top = min(vrange,sc.Input[3].GetInt());
    //sc.ScaleRangeTop = top;
  //}

//s_UseTool Note; char output[20]; // ctemp[10],
//Note.Clear(); // reset tool structure for our next use
//Note.ChartNumber = sc.ChartNumber;
//Note.Region = sc.GraphRegion;
//Note.Tool = TOOL_TEXT;
//Note.LineNumber = 8199;
//Note.BeginDateTime = sc.BaseDateTimeIn[sc.ActiveToolIndex-3];
//Note.BeginValue = sc.Input[3].GetInt()/6;
//Note.Color = 0;
//Note.FontSize = 10;
//Note.FontBold = 1;
//Note.AddMethod = UTAM_ADD_OR_ADJUST;
//itoa((int)sc.Subgraph[0][sc.ActiveToolIndex],output,10);
//Note.Text.Format("%s\n", output);
//sc.UseTool(Note);
}

I include a study collection just to start you up with adjusted volume and normal volume showing. Also a picture.

http://i.imgur.com/4a4w8Nk.png

Date Time Of Last Edit: 2013-07-08 07:46:45
attachmentkiwi13.dll - Attached On 2013-07-08 07:43:32 UTC - Size: 23 KB - 515 views
attachmentTwoVolumes.StdyCollct - Attached On 2013-07-08 07:43:45 UTC - Size: 18.68 KB - 488 views

To post a message in this thread, you need to log in with your Sierra Chart account:

Login

Login Page - Create Account