Support Board
Date/Time: Mon, 25 Nov 2024 19:42:17 +0000
[Programming Help] - Volume at Price
View Count: 220
[2024-02-21 16:27:52] |
ertrader - Posts: 672 |
When using a VbP study and sc.GetVolumeAtPriceDataForStudyProfile to get: 1) Volume at Price 2) Ask volume at Price 3) Bid volume at Price Below is code that works fine but seems very inefficient. The first for loop uses sc.GetVolumeAtPriceDataForStudyProfile to get the required information at price, then the second for loop compares the last price, gets the index and then this is used to locate the data elements. A few things: 1) VolumeAtPrice.PriceInTicks is an integer from VAPContainer.h. and is what is needed to find the values at the last price. When ticks per volume bar in the VbP study is NOT 1, the correct value can have a fraction. Therefore, the round function is used and some precision is lost. 2) The need to find an index to get the current last price values (Ask, bid and Volume at price) seems inefficient. 3) sc.GetStudyProfileInformation works fine but returns summary values for the profile rather than values at the last price. Is this the best way to get this information at the last price or is there a more efficient and simpler method? #include "sierrachart.h" SCDLLName("VBPDataExample") SCSFExport scsf_VBPDataExample(SCStudyInterfaceRef sc) { SCSubgraphRef ImbalancePercent = sc.Subgraph[0]; SCSubgraphRef TotalVolume = sc.Subgraph[1]; SCSubgraphRef TotalAskBidDelta = sc.Subgraph[2]; SCSubgraphRef AskBidDeltaAtPrice = sc.Subgraph[3]; SCSubgraphRef VolumeAtPriceData = sc.Subgraph[4]; SCSubgraphRef VolumeAtPricePercent = sc.Subgraph[5]; SCSubgraphRef VolumeTimesPriceTicks = sc.Subgraph[6]; SCInputRef INStudyID = sc.Input[0]; SCInputRef INProfileIndex = sc.Input[1]; SCInputRef INTicksPerVolume = sc.Input[2]; if (sc.SetDefaults) { sc.GraphName = "VbP Example"; sc.AutoLoop = true; sc.GraphRegion = 1; INStudyID.Name="Study ID"; INStudyID.SetInt(0); INStudyID.SetIntLimits(0,10000); INProfileIndex.Name="Profile Index"; INProfileIndex.SetInt(0); INProfileIndex.SetIntLimits(0,10000); INTicksPerVolume.Name="Ticks Per Volume"; INTicksPerVolume.SetInt(1); INTicksPerVolume.SetIntLimits(1,10); TotalAskBidDelta.Name = "Total Ask-Bid Delta"; TotalAskBidDelta.DrawStyle = DRAWSTYLE_IGNORE; TotalAskBidDelta.LineWidth = 2; ImbalancePercent.Name = "Imbalance Percent"; ImbalancePercent.DrawStyle = DRAWSTYLE_IGNORE; ImbalancePercent.LineWidth = 2; TotalVolume.Name = "Total Volume"; TotalVolume.DrawStyle = DRAWSTYLE_IGNORE; TotalVolume.LineWidth = 2; AskBidDeltaAtPrice.Name = "AskBid Delta At Price"; AskBidDeltaAtPrice.DrawStyle = DRAWSTYLE_IGNORE; AskBidDeltaAtPrice.LineWidth = 2; VolumeAtPriceData.Name = "Volume At Price Data"; VolumeAtPriceData.DrawStyle = DRAWSTYLE_IGNORE; VolumeAtPriceData.LineWidth = 2; VolumeAtPricePercent.Name = "Volume At Price Percent"; VolumeAtPricePercent.DrawStyle = DRAWSTYLE_IGNORE; VolumeAtPricePercent.LineWidth = 2; VolumeTimesPriceTicks.Name = "Volume Times Price in Ticks"; VolumeTimesPriceTicks.DrawStyle = DRAWSTYLE_IGNORE; VolumeTimesPriceTicks.LineWidth = 2; sc.MaintainVolumeAtPriceData = true; return; } const int StudyID = INStudyID.GetInt(); const int ProfileIndex = INProfileIndex.GetInt(); const int TicksPerVolume = INTicksPerVolume.GetInt(); int PricesCount = sc.GetNumPriceLevelsForStudyProfile(StudyID, 0); int FindIndex; float Imbalance, TotalVolumeValue, TotalAskBidValue, VolumeAtPriceValue, RoundedPriceLast, VolumeTimesPriceTicksValue; SCFloatArrayRef BidVolume = sc.Subgraph[1].Arrays[0]; SCFloatArrayRef AskVolume = sc.Subgraph[1].Arrays[1]; SCFloatArrayRef AskBidDelta = sc.Subgraph[1].Arrays[2]; SCFloatArrayRef PriceValueInTicks = sc.Subgraph[1].Arrays[3]; SCFloatArrayRef VolumeAP = sc.Subgraph[1].Arrays[4]; for (int PriceIndex = 0; PriceIndex < PricesCount; PriceIndex++) { s_VolumeAtPriceV2 VolumeAtPrice; int Result = sc.GetVolumeAtPriceDataForStudyProfile (StudyID , 0 , PriceIndex , VolumeAtPrice ); BidVolume[PriceIndex] = VolumeAtPrice.BidVolume; AskVolume[PriceIndex] = VolumeAtPrice.AskVolume; PriceValueInTicks[PriceIndex] = VolumeAtPrice.PriceInTicks; VolumeAP[PriceIndex] = VolumeAtPrice.Volume; } RoundedPriceLast = sc.Round(sc.BaseData[SC_LAST][sc.Index] * ((1 / sc.TickSize) / TicksPerVolume)); for (int PriceFindIndex = 0; PriceFindIndex < PricesCount; PriceFindIndex++) { if (RoundedPriceLast == PriceValueInTicks[PriceFindIndex]) { FindIndex = PriceFindIndex; break; } } n_ACSIL::s_StudyProfileInformation StudyProfileInformation; if(sc.GetStudyProfileInformation(StudyID, ProfileIndex, StudyProfileInformation)) { Imbalance = StudyProfileInformation.m_POCAboveBelowVolumeImbalancePercent; TotalVolumeValue = StudyProfileInformation.m_Volume; TotalAskBidValue = StudyProfileInformation.m_AskVolume - StudyProfileInformation.m_BidVolume; VolumeTimesPriceTicksValue = StudyProfileInformation.m_VolumeTimesPriceInTicks; } ImbalancePercent[sc.Index] = Imbalance; TotalVolume[sc.Index] = TotalVolumeValue; TotalAskBidDelta[sc.Index] = TotalAskBidValue; VolumeAtPriceData[sc.Index] = VolumeAP[FindIndex]; AskBidDeltaAtPrice[sc.Index] = AskVolume[FindIndex] - BidVolume[FindIndex]; VolumeAtPricePercent[sc.Index] = 100*VolumeAP[FindIndex]/TotalVolumeValue; VolumeTimesPriceTicks[sc.Index] = VolumeTimesPriceTicksValue; if (sc.Index < sc.ArraySize) return; } References: sc.GetVolumeAtPriceDataForStudyProfile() sc.GetStudyProfileInformation Date Time Of Last Edit: 2024-02-21 16:33:55
|
To post a message in this thread, you need to log in with your Sierra Chart account: