Login Page - Create Account

Support Board


Date/Time: Tue, 22 Apr 2025 18:36:23 +0000



[Programming Help] - How to count the number of imbalance in a candle using Acsil

View Count: 265

[2025-01-01 02:48:09]
User669552 - Posts: 26
Using Acsil i want to create a custom study that would require me to Count The number of selling imbalances. I can set them to 300% which is my optimise imbalance level but i do know how to access the numbers bar study and count them using acsil programming
[2025-01-01 03:40:21]
cmet - Posts: 690
Here is a custom study that counts the number of imbalances in each bar and plots them in a subgraph. Threshold defaults to 2 (2x). Change to increase the imbalance you're looking for. Minimum Volume allows you to filter for size. Can choose Same Price or Diagonal comparison.

#include "sierrachart.h"

SCDLLName("Numbers Bar Buy/Sell Imbalances Counter");

SCSFExport scsf_BuySellImbalanceCounter(SCStudyInterfaceRef sc)
{
SCSubgraphRef Subgraph_BuyImbalanceCount = sc.Subgraph[0]; // Subgraph for buy imbalances
SCSubgraphRef Subgraph_SellImbalanceCount = sc.Subgraph[1]; // Subgraph for sell imbalances
SCInputRef Input_ImbalanceThreshold = sc.Input[0]; // User input for imbalance threshold
SCInputRef Input_MinimumVolume = sc.Input[1]; // User input for minimum bid/ask volume
SCInputRef Input_ImbalanceBasedOn = sc.Input[2]; // Dropdown for "Same Price" or "Diagonal"

if (sc.SetDefaults)
{
sc.GraphName = "Numbers Bar Buy/Sell Imbalances Counter";
sc.StudyDescription = "Counts buy and sell imbalances with options for same price or diagonal comparison.";

// Subgraph configuration for buy imbalances
Subgraph_BuyImbalanceCount.Name = "Buy Imbalance Count";
Subgraph_BuyImbalanceCount.PrimaryColor = RGB(0, 255, 0); // Green
Subgraph_BuyImbalanceCount.DrawStyle = DRAWSTYLE_BAR;
Subgraph_BuyImbalanceCount.DrawZeros = true;

// Subgraph configuration for sell imbalances
Subgraph_SellImbalanceCount.Name = "Sell Imbalance Count";
Subgraph_SellImbalanceCount.PrimaryColor = RGB(255, 0, 0); // Red
Subgraph_SellImbalanceCount.DrawStyle = DRAWSTYLE_BAR;
Subgraph_SellImbalanceCount.DrawZeros = true;

// Input configuration
Input_ImbalanceThreshold.Name = "Imbalance Threshold (Multiplier)";
Input_ImbalanceThreshold.SetFloat(2.0f); // Default 2.0

Input_MinimumVolume.Name = "Minimum Volume for Imbalance";
Input_MinimumVolume.SetFloat(10.0f); // Default minimum volume

Input_ImbalanceBasedOn.Name = "Imbalance Based On";
Input_ImbalanceBasedOn.SetCustomInputStrings("Same Price;Diagonal");
Input_ImbalanceBasedOn.SetCustomInputIndex(1); // Default to Diagonal

sc.AutoLoop = 1; // Enable AutoLoop
sc.MaintainVolumeAtPriceData = 1; // Maintain Volume At Price data

return;
}

if (sc.VolumeAtPriceForBars == nullptr)
{
Subgraph_BuyImbalanceCount[sc.Index] = 0; // No data
Subgraph_SellImbalanceCount[sc.Index] = 0;
return;
}

int VAPSizeAtBarIndex = sc.VolumeAtPriceForBars->GetSizeAtBarIndex(sc.Index);
if (VAPSizeAtBarIndex == 0)
{
Subgraph_BuyImbalanceCount[sc.Index] = 0; // No data
Subgraph_SellImbalanceCount[sc.Index] = 0;
return;
}

int buyImbalanceCount = 0;
int sellImbalanceCount = 0;
float imbalanceThreshold = Input_ImbalanceThreshold.GetFloat(); // User-defined threshold
float minimumVolume = Input_MinimumVolume.GetFloat(); // User-defined minimum volume
int imbalanceBasedOn = Input_ImbalanceBasedOn.GetIndex(); // 0 = Same Price, 1 = Diagonal

// Iterate through the VAP data for the current bar
for (int VAPIndex = 0; VAPIndex < VAPSizeAtBarIndex; VAPIndex++)
{
const s_VolumeAtPriceV2* p_VolumeAtPrice = nullptr;

if (!sc.VolumeAtPriceForBars->GetVAPElementAtIndex(sc.Index, VAPIndex, &p_VolumeAtPrice) || p_VolumeAtPrice == nullptr)
{
continue;
}

float bidVolume = static_cast<float>(p_VolumeAtPrice->BidVolume);
float askVolume = static_cast<float>(p_VolumeAtPrice->AskVolume);

if (bidVolume < minimumVolume || askVolume < minimumVolume)
{
continue; // Skip levels with low volume
}

if (imbalanceBasedOn == 0) // Same Price
{
if (askVolume >= imbalanceThreshold * bidVolume)
{
buyImbalanceCount++;
}
if (bidVolume >= imbalanceThreshold * askVolume)
{
sellImbalanceCount++;
}
}
else if (imbalanceBasedOn == 1) // Diagonal
{
const s_VolumeAtPriceV2* p_DiagonalVAP = nullptr;

// Diagonal Buy Imbalance (Ask vs Lower Bid)
if (VAPIndex > 0)
{
sc.VolumeAtPriceForBars->GetVAPElementAtIndex(sc.Index, VAPIndex - 1, &p_DiagonalVAP);

if (p_DiagonalVAP != nullptr)
{
float diagonalBidVolume = static_cast<float>(p_DiagonalVAP->BidVolume);
if (askVolume >= imbalanceThreshold * diagonalBidVolume)
{
buyImbalanceCount++;
}
}
}

// Diagonal Sell Imbalance (Bid vs Higher Ask)
if (VAPIndex + 1 < VAPSizeAtBarIndex)
{
sc.VolumeAtPriceForBars->GetVAPElementAtIndex(sc.Index, VAPIndex + 1, &p_DiagonalVAP);

if (p_DiagonalVAP != nullptr)
{
float diagonalAskVolume = static_cast<float>(p_DiagonalVAP->AskVolume);
if (bidVolume >= imbalanceThreshold * diagonalAskVolume)
{
sellImbalanceCount++;
}
}
}
}
}

// Update subgraphs with counts
Subgraph_BuyImbalanceCount[sc.Index] = static_cast<float>(buyImbalanceCount);
Subgraph_SellImbalanceCount[sc.Index] = static_cast<float>(sellImbalanceCount);
}

Date Time Of Last Edit: 2025-01-02 00:57:04

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

Login

Login Page - Create Account