Support Board
Date/Time: Sat, 23 Nov 2024 14:30:40 +0000
Post From: Time of Day Adjusted Volume :: User Discussion
[2013-07-08 07:44:29] |
Kiwi - Posts: 375 |
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
|
kiwi13.dll - Attached On 2013-07-08 07:43:32 UTC - Size: 23 KB - 669 views TwoVolumes.StdyCollct - Attached On 2013-07-08 07:43:45 UTC - Size: 18.68 KB - 637 views |