Support Board
Date/Time: Mon, 07 Jul 2025 03:33:18 +0000
Post From: Horizontal Volume by Price Feature Request .....
[2025-07-03 17:48:51] |
Tony - Posts: 610 |
[post edited as one solution was found] We have access to VbP data by using something called "sc.VolumeAtPriceForBars" in Sierra's toolbox. Link To Documentation One of the solution is to draw a Subgraph, as it is showed in the attached animated 20-second screenshot, (ES mini July-01 2025, right after market open, around 09:31 Eastern), chart bar space has to be 1 to have a smooth looking of the distribution curve. Unfortunately there are a few issues, not all VbP values are accurate; and my study's recalculating time went from 3ms to 80ms after adding this Subgraph; also Sierra crashes after using this study for about 5 to 10 minutes, it is basically not usable, I just don't have time to find out what is wrong. This is pretty much as far as I can go, I am a very low level armature coder. Hopefully you would be able to optimize it. (the code below just to give you a rough idea, not ready for copy and paste, because some functions and variables are claimed somewhere else), "ProfileLine" is a subgraph. ProfileRange[0]/ProfileRange[1] are lowest and highest prices of profile/trading day Good luck BTW, you didn't explain the reason why you need a view VbP with different angle, maybe you could elaborate when you have time ... besides having whole lot of fun, I don't see any other reasons. if (sc.SetDefaults) { sc.GraphName = "My Custom Study"; sc.GraphRegion = 0; sc.AutoLoop = 1; sc.UpdateAlways = 1; sc.MaintainVolumeAtPriceData = 1; return; } //std::vector <int> ProfileValues; //ProfileValues.clear(); //for (double LevelCount {ProfileRange[0]}; LevelCount<=ProfileRange[1]; LevelCount+=0.25) //ProfileValues.push_back(0); int TotalLevels = (int)((ProfileRange[1] - ProfileRange[0]) / 0.25) + 1; int ProfileValues[400] {}; for (int IndexCount {ProfileStartIndex}; IndexCount<=ProfileEndIndex; IndexCount++) { const s_VolumeAtPriceV2 *p_VolumeAtPrice=NULL; int VAPSizeAtBarIndex = sc.VolumeAtPriceForBars->GetSizeAtBarIndex(IndexCount); for (int VAPIndex {0} ; VAPIndex<VAPSizeAtBarIndex; VAPIndex++) { if (!sc.VolumeAtPriceForBars->GetVAPElementAtIndex(IndexCount, VAPIndex, &p_VolumeAtPrice)) break; int IndexID {(int)((sc.Low[IndexCount] + 0.25*VAPIndex - ProfileRange[0]) / 0.25)}; ProfileValues[IndexID] += p_VolumeAtPrice->Volume; } } //DebuggingText.Format("Result:\n\n"); int HighestVolume {0}; for (int IndexCount {0}; IndexCount<TotalLevels; IndexCount++) { //DebuggingText.AppendFormat("%d\n", ProfileValues[IndexCount]); if (ProfileValues[IndexCount] > HighestVolume) HighestVolume = ProfileValues[IndexCount]; } //DebuggingText.AppendFormat("HighestVolume: %d", HighestVolume); int HorizShift = sc.IndexOfFirstVisibleBar + 137; int BaseLine = (ProfileRange[0] + ProfileRange[1]) / 2.0 - 17.0; for (int IndexCount{HorizShift}; IndexCount<TotalLevels+HorizShift; IndexCount++) ProfileLine[IndexCount] = BaseLine + 20.0*ProfileValues[IndexCount-HorizShift]/HighestVolume; AddDrawing(sc, UniqueNumber++, 1, HorizShift, TotalLevels+HorizShift, DRAWING_LINE, BaseLine, BaseLine, RGB(37,37,37), 1, ""); int IndexOfLastPrice {(int)((sc.Close[sc.Index] - ProfileRange[0]) / 0.25) + HorizShift}; AddDrawing(sc, UniqueNumber++, 0, IndexOfLastPrice, IndexOfLastPrice, DRAWING_LINE, BaseLine, BaseLine+20, RGB(37,37,37), 1, ""); Date Time Of Last Edit: 2025-07-07 00:52:24
|