Support Board
Date/Time: Tue, 26 Aug 2025 08:50:51 +0000
[Programming Help] - ACSIL help
View Count: 213
[2025-07-17 05:48:49] |
User781731 - Posts: 70 |
I'm trying to calculate "Finish Ask Volume Bid Volume Difference (Finish AskVol BidVol Diff)" in my custom study. My script correctly identifies the "Ask Volume Bid Volume Difference High" and "Ask Volume Bid Volume Difference Low"; which are the two elements needed for "Finish Ask Volume Bid Volume Difference (Finish AskVol BidVol Diff)" - see below. These are the two formulas, one of which must be used to calculate the Finish value: If the Ask Volume Bid Volume Difference High was more recently increased as compared to the Ask Volume Bid Volume Difference Low being more recently decreased, then Finish AskVol BidVol Diff equals the Ask Volume Bid Volume Difference for the bar minus the Ask Volume Bid Volume Difference High for the bar.
Otherwise, if the Ask Volume Bid Volume Difference Low was more recently decreased as compared to the Ask Volume Bid Volume Difference High being more recently increased, then Finish AskVol BidVol Diff equals the Ask Volume Bid Volume Difference for the bar minus the Ask Volume Bid Volume Difference Low for the bar. Knowing which formula to use depends on which of the following two conditions is true: - Ask Volume Bid Volume Difference High was more recently increased as compared to the Ask Volume Bid Volume Difference Low being more recently decreased - Ask Volume Bid Volume Difference Low was more recently decreased as compared to the Ask Volume Bid Volume Difference High being more recently increased This is what I'm unsure about. Can anyone help? Here is the code: #include "sierrachart.h"
SCDLLName("A-Finish") // A-Finish: Tick-by-tick Finish Delta via Time & Sales only SCSFExport scsf_AFinish(SCStudyInterfaceRef sc) { SCSubgraphRef Finish = sc.Subgraph[0]; SCSubgraphRef MaxDelta = sc.Subgraph[1]; SCSubgraphRef MinDelta = sc.Subgraph[2]; SCInputRef Lookback = sc.Input[0]; if (sc.SetDefaults) { sc.GraphName = "A-Finish"; sc.StudyDescription = "Finish Delta using only Time & Sales data."; sc.AutoLoop = 0; sc.UpdateAlways = 1; sc.MaintainAdditionalChartDataArrays = 1; sc.GraphRegion = 0; Finish.Name = "Finish"; Finish.DrawStyle = DRAWSTYLE_LINE; Finish.PrimaryColor = RGB(255,128,0); MaxDelta.Name = "Max Delta"; MaxDelta.DrawStyle = DRAWSTYLE_IGNORE; MinDelta.Name = "Min Delta"; MinDelta.DrawStyle = DRAWSTYLE_IGNORE; Lookback.Name = "Bars to Log"; Lookback.SetInt(10); Lookback.SetIntLimits(1,100); return; } if (sc.IsFullRecalculation) { // Process all historical bars except the last (still forming) for (int barToProcess = 0; barToProcess < sc.ArraySize - 1; ++barToProcess) { float runningDelta = 0.0f; float maxDelta = 0.0f; float minDelta = 0.0f; int lastMaxIndex = -1; int lastMinIndex = -1; float totalAskVol = 0.0f; float totalBidVol = 0.0f; s_IntradayRecord record; int subIndex = 0; int readSuccess = 1; bool firstIteration = true; while (readSuccess) { IntradayFileLockActionEnum lockAction = IFLA_NO_CHANGE; if (firstIteration) { lockAction = IFLA_LOCK_READ_HOLD; firstIteration = false; } readSuccess = sc.ReadIntradayFileRecordForBarIndexAndSubIndex(barToProcess, subIndex, record, lockAction); if (readSuccess) { runningDelta += record.AskVolume; runningDelta -= record.BidVolume; totalAskVol += record.AskVolume; totalBidVol += record.BidVolume; if (subIndex == 0 || runningDelta > maxDelta) { maxDelta = runningDelta; lastMaxIndex = subIndex; } if (subIndex == 0 || runningDelta < minDelta) { minDelta = runningDelta; lastMinIndex = subIndex; } ++subIndex; } } sc.ReadIntradayFileRecordForBarIndexAndSubIndex(-1, -1, record, IFLA_RELEASE_AFTER_READ); MaxDelta[barToProcess] = maxDelta; MinDelta[barToProcess] = minDelta; float finalDelta = totalAskVol - totalBidVol; float finishValue = 0.0f; if (finalDelta > 0) finishValue = finalDelta - maxDelta; else if (finalDelta < 0) finishValue = finalDelta - minDelta; else finishValue = 0.0f; Finish[barToProcess] = finishValue; } } else { // Real-time: only process the most recent closed bar static int lastProcessedBar = -1; int currentIndex = sc.Index; if (sc.GetBarHasClosedStatus(currentIndex - 1) != BHCS_BAR_HAS_CLOSED) return; int barToProcess = currentIndex - 1; if (barToProcess == lastProcessedBar) return; lastProcessedBar = barToProcess; float runningDelta = 0.0f; float maxDelta = 0.0f; float minDelta = 0.0f; int lastMaxIndex = -1; int lastMinIndex = -1; float totalAskVol = 0.0f; float totalBidVol = 0.0f; s_IntradayRecord record; int subIndex = 0; int readSuccess = 1; bool firstIteration = true; while (readSuccess) { IntradayFileLockActionEnum lockAction = IFLA_NO_CHANGE; if (firstIteration) { lockAction = IFLA_LOCK_READ_HOLD; firstIteration = false; } readSuccess = sc.ReadIntradayFileRecordForBarIndexAndSubIndex(barToProcess, subIndex, record, lockAction); if (readSuccess) { runningDelta += record.AskVolume; runningDelta -= record.BidVolume; totalAskVol += record.AskVolume; totalBidVol += record.BidVolume; if (subIndex == 0 || runningDelta > maxDelta) { maxDelta = runningDelta; lastMaxIndex = subIndex; } if (subIndex == 0 || runningDelta < minDelta) { minDelta = runningDelta; lastMinIndex = subIndex; } ++subIndex; } } sc.ReadIntradayFileRecordForBarIndexAndSubIndex(-1, -1, record, IFLA_RELEASE_AFTER_READ); MaxDelta[barToProcess] = maxDelta; MinDelta[barToProcess] = minDelta; float finalDelta = totalAskVol - totalBidVol; float finishValue = 0.0f; if (finalDelta > 0) finishValue = finalDelta - maxDelta; else if (finalDelta < 0) finishValue = finalDelta - minDelta; else finishValue = 0.0f; Finish[barToProcess] = finishValue; } // Log for last N bars (show correct values for all processed bars) int N = Lookback.GetInt(); int currentIndex = sc.Index; int startBar = max(0, currentIndex - N); for (int b = startBar; b < currentIndex; ++b) { // Calculate Delta for the bar (total AskVol - BidVol) float delta = Finish[b]; // Default to Finish for backward compatibility if (b < sc.ArraySize) { // Recalculate delta for the bar if possible float totalAskVol = 0.0f; float totalBidVol = 0.0f; s_IntradayRecord record; int subIndex = 0; int readSuccess = 1; bool firstIteration = true; while (readSuccess) { IntradayFileLockActionEnum lockAction = IFLA_NO_CHANGE; if (firstIteration) { lockAction = IFLA_LOCK_READ_HOLD; firstIteration = false; } readSuccess = sc.ReadIntradayFileRecordForBarIndexAndSubIndex(b, subIndex, record, lockAction); if (readSuccess) { totalAskVol += record.AskVolume; totalBidVol += record.BidVolume; ++subIndex; } } sc.ReadIntradayFileRecordForBarIndexAndSubIndex(-1, -1, record, IFLA_RELEASE_AFTER_READ); delta = totalAskVol - totalBidVol; } // Calculate Finish % float finish = Finish[b]; float finishPercent = 0.0f; if (finish < 0 && MaxDelta[b] != 0) finishPercent = (fabsf(finish) / fabsf(MaxDelta[b])) * 100.0f; else if (finish > 0 && MinDelta[b] != 0) finishPercent = (fabsf(finish) / fabsf(MinDelta[b])) * 100.0f; // If finish is 0 or divisor is 0, percent remains 0 SCString msg; msg.Format("%s, Delta: %.0f, Max: %.0f, Min: %.0f, Finish: %.0f, Finish %%: %.0f", sc.FormatDateTime(sc.BaseDateTimeIn[b]).GetChars(), delta, MaxDelta[b], MinDelta[b], finish, finishPercent); sc.AddMessageToLog(msg, 0); } } Date Time Of Last Edit: 2025-07-17 12:04:08
|
[2025-07-17 07:17:16] |
User781731 - Posts: 70 |
I tried this for the main Finish value: If Delta > 0: Finish = Delta - Max Delta If Delta < 0: Finish = Delta - Min Delta If Delta == 0: Finish = 0 And often it matches the Finish values found on the Numbers Bars Calculated Values study, but not always. Similarly, the formula I used to calculate Finish % produces values which sometimes match the NBCV study values, but not always. So I'm back to the drawing board. I need a way to identify which of the following conditions is true: - Ask Volume Bid Volume Difference High was more recently increased as compared to the Ask Volume Bid Volume Difference Low being more recently decreased - Ask Volume Bid Volume Difference Low was more recently decreased as compared to the Ask Volume Bid Volume Difference High being more recently increased Date Time Of Last Edit: 2025-07-17 12:08:01
|
[2025-07-17 14:22:38] |
cmet - Posts: 719 |
I need a way to identify which of the following conditions is true:
- Ask Volume Bid Volume Difference High was more recently increased as compared to the Ask Volume Bid Volume Difference Low being more recently decreased - Ask Volume Bid Volume Difference Low was more recently decreased as compared to the Ask Volume Bid Volume Difference High being more recently increased After a quick look, have you tried using lastMaxIndex and lastMinIndex? For finish values: if (lastMaxIndex > lastMinIndex)
finishValue = finalDelta - maxDelta; else if (lastMinIndex > lastMaxIndex) finishValue = finalDelta - minDelta; else finishValue = 0.0f; For %: if (lastMaxIndex > lastMinIndex && fabsf(maxDelta) != 0.0f)
finishPercent = fabsf(finish) / fabsf(maxDelta) * 100.0f; else if (lastMinIndex > lastMaxIndex && fabsf(minDelta) != 0.0f) finishPercent = fabsf(finish) / fabsf(minDelta) * 100.0f; else finishPercent = 0.0f; |
[2025-07-17 15:10:50] |
User431178 - Posts: 763 |
If you need only this: I'm trying to calculate "Finish Ask Volume Bid Volume Difference (Finish AskVol BidVol Diff)" in my custom study. My script correctly identifies the "Ask Volume Bid Volume Difference High" and "Ask Volume Bid Volume Difference Low"; which are the two elements needed for "Finish Ask Volume Bid Volume Difference (Finish AskVol BidVol Diff)" - see below. Then you are probably making the whole thing way more complicated than it needs to be. Set this in sc.SetDefaults sc.MaintainAdditionalChartDataArrays = 1; The get delta finish like this: const auto delta = sc.AskVolume[index] - sc.BidVolume[index]; if (sc.BaseDataIn[SC_ASK_BID_VOL_DIFF_MOST_RECENT_CHANGE][index] > 0) DeltaFinish[index] = sc.BaseDataIn[SC_ASKBID_DIFF_HIGH][index] - delta; else if (sc.BaseDataIn[SC_ASK_BID_VOL_DIFF_MOST_RECENT_CHANGE][index] < 0) DeltaFinish[index] = sc.BaseDataIn[SC_ASKBID_DIFF_LOW][index] - delta; else DeltaFinish[index] = 0.0f; Problem solved? For definitions of data arrays used, you can check here: ACSIL Interface Members - Variables and Arrays: sc.BaseDataIn[][] / sc.BaseData[][] Of course, if there is some reason why you want to calculate it yourself from the underlying data, then I'll go away now. Date Time Of Last Edit: 2025-07-17 15:11:57
|
[2025-07-18 03:20:18] |
User781731 - Posts: 70 |
Thanks both. cmet I tried yours first and it worked!
|
To post a message in this thread, you need to log in with your Sierra Chart account: