Login Page - Create Account

Support Board


Date/Time: Sun, 02 Nov 2025 02:56:46 +0000



[Programming Help] - ASCIL use time and sales on multiple studies

View Count: 203

[2025-09-24 11:17:12]
Smitty7_NZ - Posts: 5
Im working on a study that pulls time and sales data to construct a volume profile with cumulative last trade size in the general purpose columns of the DOM. I've identified a few issues.

1. Currently I have the study on an MES and an ES dom, the ES dom is showing the time and sales data from the MES DOM?
(I have checked TAS and it is showing the data originating from the MES time and sales only), MES was the first dom I
applied the study to.
2. All other DOMS with the study do not show anything, initially I thought this was a rounding error due to different
tick formats but I ran on an NQ dom which has the same tick size as MES of 0.25 and it did not work either.

What I have tried:
1. I have tried sc.GetTimeAndSalesForSymbol instead of sc.GetTimeAndSales, passing the symbol for the applied chart. Did not work
2. I normalized prices into indexes to avoid possible rounding errors. Did not work

Is it the case that I cannot pull TAS data for 2 markets at once?
study attached

Cheers
Attachment Deleted.
Private File
[2025-09-25 03:45:16]
Sierra_Chart Engineering - Posts: 21273
Refer to this Chart Setting:
Chart Settings: Use as Trade Only Symbol (Chart >> Chart Settings >> Symbol >> Symbol menu)

Also, since you are using Teton order routing, you will need to multiply the time and sales prices by the real-time multiplier:
ACSIL Interface Members - Variables and Arrays: sc.RealTimePriceMultiplier
Sierra Chart Support - Engineering Level

Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy:
https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation

For the most reliable, advanced, and zero cost futures order routing, use the Teton service:
Sierra Chart Teton Futures Order Routing
Date Time Of Last Edit: 2025-09-25 03:45:40
[2025-09-25 05:59:10]
Smitty7_NZ - Posts: 5
I am already using real time price multiplier.

What shall I do with the trade only symbol? I have tried setting the second quote/trade symbol to the same symbol as the dom, with trade only both enabled and disabled, neither worked.

I have tried setting the symbol in the study for GetTimeAndSalesForSymbol to the trade only symbol as well.

I added the following


msg.Format("Trade @ %.2f, size=%d, g_CumLastVol=%d", tradePrice, tradeSize, g_CumLastVol);
sc.AddMessageToLog(msg, 1);

And found that it was puling time and sales data for nasdaq/NQ.
I do not have an NQ DOM or chart open in any chartbook

I'm not sure how to dictate where its pulling the data from

at a bit of a loss at this point

Thanks
Date Time Of Last Edit: 2025-09-25 05:59:58
[2025-09-25 08:40:14]
User431178 - Posts: 805
You must be doing something wrong in your code.
If you want help with it post it here or send message if you'd rather keep it private.

The very basic study below pulls T&S data for up to 4 symbols simultaneously (the current chart and 3 others).
It prints the last 3 records for each and repeats 10 times.
If no T&S data is available for the symbol it subscribes to market data for that symbol.



#include "sierrachart.h"
#include <array>

SCSFExport scsf_TimeAndSalesSymbols(SCStudyInterfaceRef sc)
{
  if (sc.SetDefaults)
  {
    sc.GraphName = "T&S for Symbols";
    sc.AutoLoop = 0;
    sc.GraphRegion = 0;

    sc.Input[0].Name = "Symbol #1";
    sc.Input[0].SetSymbol("");

    sc.Input[1].Name = "Symbol #2";
    sc.Input[1].SetSymbol("");

    sc.Input[2].Name = "Symbol #3";
    sc.Input[2].SetSymbol("");

    return;
  }

  auto& r_Count = sc.GetPersistentInt(0);

  if (sc.UpdateStartIndex == 0)
    r_Count = 0;

  if (r_Count >= 10)
    return;

  auto symbols = std::array<SCString, 4>{};

  symbols[0] = sc.Symbol;
  symbols[1] = sc.Input[0].GetSymbol();
  symbols[2] = sc.Input[1].GetSymbol();
  symbols[3] = sc.Input[2].GetSymbol();

  auto ts = c_SCTimeAndSalesArray{};

  sc.GetTimeAndSales(ts);

  if (ts.Size() > 0)
  {
    for (auto i = ts.Size() - 1; i >= 0 && i >= ts.Size() - 3; --i)
    {
      const auto& record = ts[i];

      auto msg = SCString{};

      msg.Format("Symbol: %s, DateTime: %s, Price: %.2f, Volume: %u, Type: %d"
            , sc.Symbol.GetChars()
            , sc.FormatDateTime(record.DateTime).GetChars()
            , record.Price * sc.RealTimePriceMultiplier
            , record.Volume
            , record.Type);

      sc.AddMessageToLog(msg, 0);
    }
  }

  for (auto s = 1; s < symbols.size(); ++s)
  {
    if (symbols[s].GetLength() == 0)
      continue;

    auto tss = c_SCTimeAndSalesArray{};

    sc.GetTimeAndSalesForSymbol(symbols[s], tss);

    if (tss.Size() > 0)
    {
      for (auto i = tss.Size() - 1; i >= 0 && i >= tss.Size() - 3; --i)
      {
        const auto& record = tss[i];
        auto msg = SCString{};
        msg.Format("Symbol: %s, DateTime: %s, Price: %.2f, Volume: %u, Type: %d"
              , symbols[s].GetChars()
              , sc.FormatDateTime(record.DateTime).GetChars()
              , record.Price * sc.RealTimePriceMultiplier
              , record.Volume
              , record.Type);

        sc.AddMessageToLog(msg, 0);
      }
    }
    else
    {
      auto msg = SCString{};
      msg.Format("Symbol: %s, No T&S data, subscribing to symbol data feed", symbols[s].GetChars());
      sc.AddMessageToLog(msg, 0);

      const auto val = sc.GetSymbolDataValue(SymbolDataValuesEnum::SYMBOL_DATA_LAST_TRADE_PRICE
                          , symbols[s]
                          , true
                          , false);
    }
  }

  r_Count++;
}

[2025-09-25 09:57:35]
Smitty7_NZ - Posts: 5
this is with a user defined symbol


SCSFExport scsf_VAPInLabel(SCStudyInterfaceRef sc)
{



SCInputRef i_FontSize = sc.Input[0];
SCInputRef i_BoldFont = sc.Input[1];
SCInputRef i_TextColor = sc.Input[2];
SCInputRef i_Background = sc.Input[3];
SCInputRef i_xOffset = sc.Input[4];
SCInputRef i_yOffset = sc.Input[5];
SCInputRef i_NumDigits = sc.Input[6];
SCInputRef i_LastTradeFg = sc.Input[7];
SCInputRef i_LastTradeBg = sc.Input[8];
SCInputRef i_TargetColumn = sc.Input[9];
SCInputRef i_GridlineColor = sc.Input[10];
SCInputRef i_OverallYOffset= sc.Input[11];
SCInputRef i_LastFontSize = sc.Input[12];
SCInputRef i_LastBold = sc.Input[13];
  SCInputRef i_Symbol = sc.Input[14];

if (sc.SetDefaults)
{
sc.GraphName = "SVAP";
sc.GraphRegion = 0;

i_FontSize.Name = "Font Size"; i_FontSize.SetInt(18);
i_BoldFont.Name = "Bold"; i_BoldFont.SetYesNo(0);
i_TextColor.Name = "Text Color"; i_TextColor.SetColor(RGB(0,0,0));
i_Background.Name = "Default Background"; i_Background.SetColor(RGB(240,240,240));
i_xOffset.Name = "X Offset"; i_xOffset.SetInt(8);
i_yOffset.Name = "Y Offset"; i_yOffset.SetInt(0);
i_NumDigits.Name = "Digits"; i_NumDigits.SetInt(0);
i_LastTradeFg.Name = "Last Trade Text"; i_LastTradeFg.SetColor(RGB(0,0,0));
i_LastTradeBg.Name = "Last Trade Neutral Background"; i_LastTradeBg.SetColor(RGB(200,200,200));
i_TargetColumn.Name = "Target Column";
i_TargetColumn.SetCustomInputStrings("Label;General Purpose 1;General Purpose 2;");
i_TargetColumn.SetCustomInputIndex(0);
i_GridlineColor.Name = "Gridline"; i_GridlineColor.SetColor(RGB(192,192,192));
i_OverallYOffset.Name = "Overall Y-Offset"; i_OverallYOffset.SetInt(15);
i_LastFontSize.Name = "Last Trade Font Size"; i_LastFontSize.SetInt(20);
i_LastBold.Name = "Last Trade Bold"; i_LastBold.SetYesNo(1);
  i_Symbol.Name = "Symbol"; i_Symbol.SetString("ESZ25-CME");
return;
}



SCString Symbol = sc.Input[14].GetString();


c_SCTimeAndSalesArray TSArray;
sc.GetTimeAndSalesForSymbol(Symbol, TSArray);

for (int i = 0; i < TSArray.Size(); ++i)
{
const s_TimeAndSales& ts = TSArray[i];
if (ts.Sequence <= g_LastProcessedSeq)
continue;

if (ts.Type == SC_TS_BID || ts.Type == SC_TS_ASK)
{
double tradePrice = sc.RoundToTickSize(ts.Price * sc.RealTimePriceMultiplier, sc.TickSize);
int tradeSize = (int)ts.Volume;

VolumeAtPrice& vap = g_VolumeAtPrice[tradePrice];
if (ts.Type == SC_TS_BID)
vap.BidVol += tradeSize;
else
vap.AskVol += tradeSize;


if (tradePrice != g_LastPrice)
{
g_PreviousLastPrice = g_LastPrice;
g_LastPrice = tradePrice;
g_CumLastVol = tradeSize;
        g_IsFirstTradeAtNewPrice = true;
}
else
{
g_CumLastVol += tradeSize;
        g_IsFirstTradeAtNewPrice = false;
}
      
      SCString msg;
      msg.Format("Trade @ %.2f, size=%d, g_CumLastVol=%d", tradePrice, tradeSize, g_CumLastVol);
      sc.AddMessageToLog(msg, 1);
}

g_LastProcessedSeq = ts.Sequence;
    
    
}

sc.p_GDIFunction = DrawToChart;
}

[2025-09-25 10:16:24]
User431178 - Posts: 805

this is with a user defined symbol

As is part of the working example I posted.
In your case is ESZ25-CME actually connected to the feed? If not, it won't work.


In your first post you wrote this:

Is it the case that I cannot pull TAS data for 2 markets at once?

Looking at your code, which is not complete, it is scattered with global variables - that is obviously going to be a problem if you are reusing for different symbols.
Consider using persistent variables instead, as they are per study, not per dll.
ACSIL Interface Members - Functions: Persistent Variable Functions
Date Time Of Last Edit: 2025-09-25 10:17:30
[2025-09-25 10:55:26]
Smitty7_NZ - Posts: 5
ahh, my VAP struct was global.
I didn't realize the dll was shared between charts, should probably brush up on the docs ;)

Cheers, thanks for your help

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

Login

Login Page - Create Account