Time and sales coding in ACSIL - futures io
futures io futures trading



Time and sales coding in ACSIL


Discussion in Sierra Chart

Updated
      Top Posters
    1. looks_one Trembling Hand with 34 posts (15 thanks)
    2. looks_two liboro with 28 posts (2 thanks)
    3. looks_3 bobwest with 2 posts (1 thanks)
    4. looks_4 trendisyourfriend with 1 posts (0 thanks)
      Best Posters
    1. looks_one Big Mike with 1 thanks per post
    2. looks_two bobwest with 0.5 thanks per post
    3. looks_3 Trembling Hand with 0.4 thanks per post
    4. looks_4 liboro with 0.1 thanks per post
    1. trending_up 2,217 views
    2. thumb_up 19 thanks given
    3. group 3 followers
    1. forum 64 posts
    2. attach_file 11 attachments




Welcome to futures io: the largest futures trading community on the planet, with well over 125,000 members
  • Genuine reviews from real traders, not fake reviews from stealth vendors
  • Quality education from leading professional traders
  • We are a friendly, helpful, and positive community
  • We do not tolerate rude behavior, trolling, or vendors advertising in posts
  • We are here to help, just let us know what you need
You'll need to register in order to view the content of the threads and start contributing to our community.  It's free and simple.

-- Big Mike, Site Administrator

(If you already have an account, login at the top of the page)

 
Search this Thread
 

Time and sales coding in ACSIL

(login for full post details)
  #1 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

I need a code for Sierra Chart which is based on Time Sales data. The code would put ask/bid values on the relevant prices. The very same as volume at price, but based on TS. Only part of the code or help would be enough for me.

Anyone can help?

Reply With Quote

Can you help answer these questions
from other members on futures io?
Help Needed: TOS Options Chain IV & IMPL MOVE Calcul …
ThinkOrSwim
NT8 indicator to simulate a Funding Evaluation where to …
NinjaTrader
Indicators for pair trading MES and M2K
Platforms and Indicators
Improve current ZigZag indicator in NT8
NinjaTrader
ZigZag with Depth and Backstep
EasyLanguage Programming
 
Best Threads (Most Thanked)
in the last 7 days on futures io
Battlestations: Show us your trading desks!
124 thanks
Big Mike in Ecuador
37 thanks
Want your NinjaTrader indicator created, free?
30 thanks
Selling Options on Futures?
21 thanks
Saturday Morning Market Replay!
20 thanks
 
(login for full post details)
  #2 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received

Have a look at the code for these studies,

scsf_VolumeAtPriceArrayTest
scsf_VolumeAtPriceThresholdAlert
scsf_VolumeAtPriceThresholdAlertV2

in C:\SierraChart\ACS_Source\Studies8.cpp

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #3 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received


Thank you, but these studies are examples of VAP. I am trying to work with Time and Sales data in the way as VAP - put ASK/BID volume on the price levels in the current bar.


Trembling Hand View Post
Have a look at the code for these studies,

scsf_VolumeAtPriceArrayTest
scsf_VolumeAtPriceThresholdAlert
scsf_VolumeAtPriceThresholdAlertV2

in C:\SierraChart\ACS_Source\Studies8.cpp


Reply With Quote
 
(login for full post details)
  #4 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
Thank you, but these studies are examples of VAP. I am trying to work with Time and Sales data in the way as VAP - put ASK/BID volume on the price levels in the current bar.

So just to be clear what you are wanting is for example a bar that has a high of 105 and low of 100 you want to know how many bid trades at,
100,101,102,103,104,105

and the same for the ask trades?

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #5 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Yes, this is correct.



Trembling Hand View Post
So just to be clear what you are wanting is for example a bar that has a high of 105 and low of 100 you want to know how many bid trades at,
100,101,102,103,104,105

and the same for the ask trades?


Reply With Quote
 
(login for full post details)
  #6 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
Yes, this is correct.

Well thats the function you need I would think,

 
Code
SCSFExport scsf_VolumeAtPriceTest(SCStudyInterfaceRef sc)
{


	if (sc.SetDefaults)
	{
		// Set the configuration and defaults

		sc.GraphName = "Volume At Price Test";
		sc.StudyDescription = "This study tests the sc.VolumeAtPriceForBars array.";
		sc.AutoLoop = 1;
		sc.MaintainVolumeAtPriceData = 1;  // true


		return;
	}

	SCString DataString;

	if ((int)sc.VolumeAtPriceForBars->GetNumberOfBars() < sc.ArraySize)
		return;


	// Get the sum of the volumes from all of the prices at this bar
	unsigned int TotalVolume = 0;

	const s_VolumeAtPriceV2* p_VolumeAtPrice = NULL;
	int VAPSizeAtBarIndex = sc.VolumeAtPriceForBars->GetSizeAtBarIndex(sc.Index);
	for (int VAPIndex = 0; VAPIndex < VAPSizeAtBarIndex; VAPIndex++)
	{
		if (!sc.VolumeAtPriceForBars->GetVAPElementAtIndex(sc.Index, VAPIndex, &p_VolumeAtPrice))
			break;

		TotalVolume += p_VolumeAtPrice->Volume;

		//Calculate the price.  This requires multiplying p_VolumeAtPrice->PriceInTicks by the tick size
		float Price = p_VolumeAtPrice->PriceInTicks * sc.TickSize;

		//Other members available:
		unsigned int AskVolume = p_VolumeAtPrice->AskVolume;
		unsigned int BidVolume = p_VolumeAtPrice->BidVolume;
		unsigned int NumberOfTrades = p_VolumeAtPrice->NumberOfTrades;

		DataString.Format("Index: %d,  Price: %f, AskVolume: %d, BidVolume: %d, NumberOfTrades: %d", sc.Index, Price, AskVolume, BidVolume, NumberOfTrades);
		sc.AddMessageToLog(DataString, 0);
	}

}


2021-02-12 10_54_53-Window

Follow me on Twitter Reply With Quote
The following user says Thank You to Trembling Hand for this post:
 
(login for full post details)
  #7 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

This is great, thank you.

But I need the same system but data from TS as I mentioned earlier - I would like to code something like Large Volume Trade Indicator.

Do you think it is possible?

Reply With Quote
 
(login for full post details)
  #8 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
This is great, thank you.

But I need the same system but data from TS as I mentioned earlier - I would like to code something like Large Volume Trade Indicator.

Do you think it is possible?

Ok. So then you need one of these,

Time and Sales


Time and Sales for bar index

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #9 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Thank you.

Do you have any idea how
scGetTimeSalesArrayIndexesForBarIndex
works or for which purposes I should use it?

I tried to work with - limit "for loop" only for the "begin" and "end" index,
but with no success.

My code looks like this:

int BeginIndex = 0, EndIndex = 0;
sc.GetTimeSalesArrayIndexesForBarIndex(sc.UpdateStartIndex, BeginIndex, EndIndex);

...

c_SCTimeAndSalesArray TimeSales;
sc.GetTimeAndSales(TimeSales);

if (TimeSales.Size() == 0)
return; // No Time and Sales data available for the symbol

// Loop through the Time and Sales
int OutputArrayIndex = sc.ArraySize;
for (int TSIndex = BeginIndex; TSIndex <= EndIndex; ++TSIndex)
{
//Adjust timestamps to Sierra Chart TimeZone
SCDateTime AdjustedDateTime = TimeSales[TSIndex].DateTime;
AdjustedDateTime += sc.TimeScaleAdjustment;
}

But with no success.

And do you believe that I can achieve TS data for price levels in the bar
with these two functions?

Thank you for your help!

Reply With Quote
 
(login for full post details)
  #10 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


Yes I think it's very possible but I'm away from my computer til tomorrow I'll have another look then.

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #11 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Ok, thank you. I will be happy if you will let me know.



Trembling Hand View Post
Yes I think it's very possible but I'm away from my computer til tomorrow I'll have another look then.


Reply With Quote
 
(login for full post details)
  #12 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received

So here is a Study that will save the time and sales data to a txt file to C:\SierraChart\Data (modified from something on SC forum).
You can see some of the available data types commented out in the main loop.



 
Code
SCSFExport scsf_Save_TimeNSales(SCStudyGraphRef sc) {

    SCInputRef OutputFile = sc.Input[0];


    if (sc.SetDefaults) {

        // https://www.sierrachart.com/SupportBoard.php?ThreadID=36979

        sc.GraphName = "Save_TimeNSales";
        sc.StudyDescription = "Save Time and sales to file";
        sc.GraphRegion = 0;
        //sc.AutoLoop=true; 
        sc.FreeDLL = 1;

        OutputFile.Name = "The storage link";
        SCString OutputFileDefaultName;
        OutputFileDefaultName.Format("C:\\SierraChart\\Data\\1_%s.txt", sc.Symbol.GetSubString(2, 0).GetChars());
        OutputFile.SetString(OutputFileDefaultName);

    }

    std::ofstream file(OutputFile.GetString(), std::ios_base::app);

    if (!file) {

        SCString Buffer;
        Buffer.Format("Unable to open file %s", OutputFile.GetString());
        sc.AddMessageToLog(Buffer, 1);
        //return; 

    }



    if (sc.Index == sc.ArraySize - 1)
    {

        __int64& LastProcessedSequence = sc.GetPersistentInt64(1);
        c_SCTimeAndSalesArray TimeSales;
        sc.GetTimeAndSales(TimeSales);
        if (TimeSales.Size() == 0)
            return;


        if (LastProcessedSequence != 0)
        {
            for (int TSIndex = 0; TSIndex < TimeSales.Size(); ++TSIndex)
            {
                if (TimeSales[TSIndex].Sequence < LastProcessedSequence)
                    continue;

                if (TimeSales[TSIndex].Type == SC_TS_BID || TimeSales[TSIndex].Type == SC_TS_ASK)
                {
                    //int AskVol = TimeSales[TSIndex].AskSize;
                    //int TotalAsks = TimeSales[TSIndex].TotalAskDepth;
                    //int BidVol = TimeSales[TSIndex].BidSize;
                    //int TotalBids = TimeSales[TSIndex].TotalBidDepth;
                    float Price = TimeSales[TSIndex].Price;
                    int Vol = TimeSales[TSIndex].Volume;
                    int TradeType = TimeSales[TSIndex].Type; // at bid or ask



                    int ValueFormat = sc.BaseGraphValueFormat;
                    SCString formatString = " %i/%02i/%02i  %02i:%02i:%02i: %03i , Index: %i, Price: %0.4f, Vol: %i BidAsk: %i";
                    SCDateTime TradeDateTime = TimeSales[TSIndex].DateTime;
                    TradeDateTime += sc.TimeScaleAdjustment;
                    int Year, Month, Day, Hour, Minute, Second, MilliSecond;
                    TradeDateTime.GetDateTimeYMDHMS_MS(Year, Month, Day, Hour, Minute, Second, MilliSecond);


                    SCString BarDataString;
                    BarDataString.Format(formatString, Year, Month, Day, Hour, Minute, Second, MilliSecond, TSIndex, Price, Vol, TradeType);
                    file << BarDataString << std::endl;

                }

            }

        }

        LastProcessedSequence = TimeSales[TimeSales.Size() - 1].Sequence;

    }



}
Of course this only works with a live market connection.

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #13 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received

I probably should of asked before I took the step but do you want this to work on historical data then that is a totally different method!

From SC Docs about sc.GetTimeAndSales()

See Docs


Quoting 

Alternative Way For Obtaining Time and Sales Data

Open a chart that is set to 1 Number of Trades Per Bar for the symbol you want Time and Sales for.

Select Global Settings >> Data/Trade Service Settings and make sure the Intraday Data Storage Time Unit is set to 1 Tick.

Use the sc.GetChartArray and the sc.GetChartDateTimeArray functions to access the price, volume and DateTime arrays. Every element in these arrays is 1 trade. This may actually be a preferred way of accessing trade by trade data since there will be an abundant amount of history available.


Follow me on Twitter Reply With Quote
 
(login for full post details)
  #14 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
I would like to code something like Large Volume Trade Indicator.

Do you think it is possible?

LOL. I should have know being Sierra Chart they have already made a Study......

https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=390&Name=Large_Volume_Trade_Indicator

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #15 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Thank you for the codes and other help.

I understand the basics of the TS, but the crucial thing is how to work with the TS data within price leves in the bars - how these arrays would be allocated or how these arrays should look like (subgraphs arrays?)?

I know that SC has Large Volume Trade Indicator, but there is no source code available and I want to use it in my own way. That is the reason why I am trying to solve this.



Trembling Hand View Post


Reply With Quote
 
(login for full post details)
  #16 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received

What? I'm not sure what else you would need. If you are not able to use the above code samples then I guess you actually need to explain exactly what you are trying to do and maybe someone can do it for you. But every thing you have said so far is actually very short of what it seems like you really want.

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #17 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

PRICE 69.60 AV (from TS) = XY, BV (from TS) = XY
PRICE 69.61 AV (from TS) = XY, BV (from TS) = XY
PRICE 69.62 AV (from TS) = XY, BV (from TS) = XY
PRICE 69.63 AV (from TS) = XY, BV (from TS) = XY

Is it more clear now?

Put AV and BV to the relevant prices in the current bar.



Trembling Hand View Post
What? I'm not sure what else you would need. If you are not able to use the above code samples then I guess you actually need to explain exactly what you are trying to do and maybe someone can do it for you. But every thing you have said so far is actually very short of what it seems like you really want.


Reply With Quote
 
(login for full post details)
  #18 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
PRICE 69.60 AV (from TS) = XY, BV (from TS) = XY
PRICE 69.61 AV (from TS) = XY, BV (from TS) = XY
PRICE 69.62 AV (from TS) = XY, BV (from TS) = XY
PRICE 69.63 AV (from TS) = XY, BV (from TS) = XY

Is it more clear now?

Put AV and BV to the relevant prices in the current bar.

That's what the first study I wrote did in post #6!

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #19 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

I do understand the code in post #6, but as I mentioned, these data are from VAP function,
this is not the same as data in Time Sales data structure.

I believe there is no way how to use VAP for TS data.
Maybe I am wrong.



Trembling Hand View Post
That's what the first study I wrote did in post #6!


Reply With Quote
 
(login for full post details)
  #20 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
I do understand the code in post #6, but as I mentioned, these data are from VAP function,
this is not the same as data in Time Sales data structure.

I believe there is no way how to use VAP for TS data.
Maybe I am wrong.

I think you have a fundamental misunderstanding of what is going on here.

TS data is not a different data set from "other" data.

Could you explain why you think it is? Where does it come from?

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #21 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Could you build Large Volume Trade Indicator based on VAP function?

I do not think so and this is the reason why I am trying to do this.




Trembling Hand View Post
I think you have a fundamental misunderstanding of what is going on here.

TS data is not a different data set from "other" data.

Could you explain why you think it is? Where does it come from?


Reply With Quote
 
(login for full post details)
  #22 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
Could you build Large Volume Trade Indicator based on VAP function?

Yes. But as your details of exactly what you want are missing or confusing we are going in circles.

For example my post at #4 and yours at #17 are the same thing.

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #23 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Ok, could you please share with me how achieve filtering orders by their size in VAP?

I dont think that we are in the circles, maybe it is my fault that I wrongly assumed that I
cant filter order size in VAP. Sorry for that.



Trembling Hand View Post
Yes. But as your details of exactly what you want are missing or confusing we are going in circles.

For example my post at #4 and yours at #17 are the same thing.


Reply With Quote
 
(login for full post details)
  #24 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
Ok, could you please share with me how achieve filtering orders by their size in VAP?

I dont think that we are in the circles, maybe it is my fault that I wrongly assumed that I
cant filter order size in VAP. Sorry for that.

Firstly that's not what my post at 4 and yours at #17 is asking to do but rather break down ask/bid volume.

But
Filter order size by what? A threshold amount? A descending/ascending amount?

It may help if you can say what the SC large volume Trader study doesn't do what you want it to do.

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #25 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Here is my post #1:
I need a code for Sierra Chart which is based on Time Sales data. The code would put ask/bid values on the relevant prices. The very same as volume at price, but based on TS. Only part of the code or help would be enough for me.

So your post #4 is relevant to describe and understand price levels. The same is the #17, I always mentioned that volume on this levels should be from the TS, not VAP.

Filter order by threshold amount, that means for example only orders bigger than 5.



Trembling Hand View Post
Firstly that's not what my post at 4 and yours at #17 is asking to do but rather break down ask/bid volume.

But
Filter order size by what? A threshold amount? A descending/ascending amount?

It may help if you can say what the SC large volume Trader study doesn't do what you want it to do.


Reply With Quote
 
(login for full post details)
  #26 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
Here is my post #1:
I need a code for Sierra Chart which is based on Time Sales data. The code would put ask/bid values on the relevant prices. The very same as volume at price, but based on TS. Only part of the code or help would be enough for me.

So your post #4 is relevant to describe and understand price levels. The same is the #17, I always mentioned that volume on this levels should be from the TS, not VAP.

Filter order by threshold amount, that means for example only orders bigger than 5.

LOL!!

So back to my code at #12 all you have to do is decide how you want to represent that on the chart rather than save to txt

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #27 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

In this code I do not see any part which assign Ask/Bid volume to the prices.

In my opinion it is only the tape, trade by trade.

The crucial thing how to sum all ask/bid volume on the relevant prices,
think about it like you have reversal chart, price ticks one up, one down
and you need to sum all A/B volume on the concrete levels.


 
Code
SCSFExport scsf_Save_TimeNSales(SCStudyGraphRef sc) {

    SCInputRef OutputFile = sc.Input[0];


    if (sc.SetDefaults) {

        // https://www.sierrachart.com/SupportBoard.php?ThreadID=36979

        sc.GraphName = "Save_TimeNSales";
        sc.StudyDescription = "Save Time and sales to file";
        sc.GraphRegion = 0;
        //sc.AutoLoop=true; 
        sc.FreeDLL = 1;

        OutputFile.Name = "The storage link";
        SCString OutputFileDefaultName;
        OutputFileDefaultName.Format("C:\\SierraChart\\Data\\1_%s.txt", sc.Symbol.GetSubString(2, 0).GetChars());
        OutputFile.SetString(OutputFileDefaultName);

    }

    std::ofstream file(OutputFile.GetString(), std::ios_base::app);

    if (!file) {

        SCString Buffer;
        Buffer.Format("Unable to open file %s", OutputFile.GetString());
        sc.AddMessageToLog(Buffer, 1);
        //return; 

    }



    if (sc.Index == sc.ArraySize - 1)
    {

        __int64& LastProcessedSequence = sc.GetPersistentInt64(1);
        c_SCTimeAndSalesArray TimeSales;
        sc.GetTimeAndSales(TimeSales);
        if (TimeSales.Size() == 0)
            return;


        if (LastProcessedSequence != 0)
        {
            for (int TSIndex = 0; TSIndex < TimeSales.Size(); ++TSIndex)
            {
                if (TimeSales[TSIndex].Sequence < LastProcessedSequence)
                    continue;

                if (TimeSales[TSIndex].Type == SC_TS_BID || TimeSales[TSIndex].Type == SC_TS_ASK)
                {
                    //int AskVol = TimeSales[TSIndex].AskSize;
                    //int TotalAsks = TimeSales[TSIndex].TotalAskDepth;
                    //int BidVol = TimeSales[TSIndex].BidSize;
                    //int TotalBids = TimeSales[TSIndex].TotalBidDepth;
                    float Price = TimeSales[TSIndex].Price;
                    int Vol = TimeSales[TSIndex].Volume;
                    int TradeType = TimeSales[TSIndex].Type; // at bid or ask



                    int ValueFormat = sc.BaseGraphValueFormat;
                    SCString formatString = " %i/%02i/%02i  %02i:%02i:%02i: %03i , Index: %i, Price: %0.4f, Vol: %i BidAsk: %i";
                    SCDateTime TradeDateTime = TimeSales[TSIndex].DateTime;
                    TradeDateTime += sc.TimeScaleAdjustment;
                    int Year, Month, Day, Hour, Minute, Second, MilliSecond;
                    TradeDateTime.GetDateTimeYMDHMS_MS(Year, Month, Day, Hour, Minute, Second, MilliSecond);


                    SCString BarDataString;
                    BarDataString.Format(formatString, Year, Month, Day, Hour, Minute, Second, MilliSecond, TSIndex, Price, Vol, TradeType);
                    file << BarDataString << std::endl;

                }

            }

        }

        LastProcessedSequence = TimeSales[TimeSales.Size() - 1].Sequence;

    }



}



Trembling Hand View Post
LOL!!

So back to my code at #12 all you have to do is decide how you want to represent that on the chart rather than save to txt


Reply With Quote
 
(login for full post details)
  #28 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
In this code I do not see any part which assign Ask/Bid volume to the prices.

Mate I think you are lost here! This is the code that identifies the trade at bid or ask,

 
Code
int TradeType = TimeSales[TSIndex].Type; // at bid or ask
This is the code that identifies the price for that trade.
 
Code
float Price = TimeSales[TSIndex].Price;


liboro View Post
In my opinion it is only the tape, trade by trade.

The crucial thing how to sum all ask/bid volume on the relevant prices,
think about it like you have reversal chart, price ticks one up, one down
and you need to sum all A/B volume on the concrete levels.

Its up to you to either make it clearer what magic you want to happen with it. You are now talking about what I did in the first study code!!

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #29 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received

I'll give it one more shot to figure out what you are trying to do here.

Can I have an picture of a chart well annotated with what data/subgraphs/etc you want from what data. Use data like this and draw it on a chart,


liboro View Post
PRICE 69.60 AV (from TS) = XY, BV (from TS) = XY
PRICE 69.61 AV (from TS) = XY, BV (from TS) = XY
PRICE 69.62 AV (from TS) = XY, BV (from TS) = XY
PRICE 69.63 AV (from TS) = XY, BV (from TS) = XY


Follow me on Twitter Reply With Quote
 
(login for full post details)
  #30 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received

Because I like banging my head against a wall....


2021-02-14 15_48_55-Window


Here is an example code that will mark on each bar where the largest volume bid and ask trade occur. Not the greatest of studies nor the most efficient but just an example of using T&S data on a chart. And remember sc.GetTimeAndSales() only works on live connections & replay.


 
Code

SCSFExport scsf_TimeNSales(SCStudyGraphRef sc) {

    SCSubgraphRef BidHighVol = sc.Subgraph[0];
    SCSubgraphRef AskHighVol = sc.Subgraph[1];


    if (sc.SetDefaults) {

        sc.GraphName = "Highest_Bid_ASk_Vol";
        sc.StudyDescription = "Mark on each bar the highest bid & ask trade";
        sc.GraphRegion = 0;
        sc.AutoLoop=0; //Use manual looping

        BidHighVol.Name = "Bid High Vol";
        BidHighVol.DrawStyle = DRAWSTYLE_TRIANGLE_RIGHT;
        BidHighVol.DrawZeros = 0;
        BidHighVol.PrimaryColor = RGB(255, 147, 147);
        BidHighVol.LineWidth = 4;

        AskHighVol.Name = "AskHighVol";
        AskHighVol.DrawStyle = DRAWSTYLE_TRIANGLE_LEFT;
        AskHighVol.DrawZeros = 0;
        AskHighVol.PrimaryColor = RGB(128, 255, 128);
        AskHighVol.LineWidth = 4;

    }


    int& HigestBidVol = sc.GetPersistentInt(1);
    int& HigestAskVol = sc.GetPersistentInt(2);
    int& PriorArraySize = sc.GetPersistentInt(3);

    float& HigestBidVolPrice = sc.GetPersistentFloat(1);    
    float& HigestAskVolPrice = sc.GetPersistentFloat(2);     

    int64_t& LastProcessedSequence = sc.GetPersistentInt64(1);

    //This code depends upon manual looping being set
    for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; Index++)
    {
        if (Index == 0)
        {
            PriorArraySize = sc.ArraySize;
        }
        // If there are new bars added
        if (PriorArraySize < Index)
        {
            HigestAskVol = 0;
            HigestAskVolPrice = 0.0;
            HigestBidVol = 0;
            HigestBidVolPrice = 0.0;
           // sc.AddMessageToLog("********    NEW BAR *******************************************************************", 0);
            PriorArraySize = Index;
        }
                

        //reset the sequence number on a full recalculation so we start fresh for each full recalculation.
        if (sc.IsFullRecalculation && sc.UpdateStartIndex == 0) {

            BidHighVol[Index] = 0.0;
            AskHighVol[Index] = 0.0;
            LastProcessedSequence = 0;
        }
            

        // Get the Time and Sales
        c_SCTimeAndSalesArray TimeSales;
        sc.GetTimeAndSales(TimeSales);
        if (TimeSales.Size() == 0)
            return;  // No Time and Sales data available for the symbol

        //Set the initial sequence number
        if (LastProcessedSequence == 0)
            LastProcessedSequence = TimeSales[TimeSales.Size() - 1].Sequence;

        // Loop through the Time and Sales.
        for (int TSIndex = 0; TSIndex < TimeSales.Size(); ++TSIndex)
        {
            //do not reprocess previously processed sequence numbers.
            if (TimeSales[TSIndex].Sequence <= LastProcessedSequence)
                continue;

            //only interested in trade records
            if (TimeSales[TSIndex].Type == SC_TS_BID || TimeSales[TSIndex].Type == SC_TS_ASK)
            {

                /*int AskVol = TimeSales[TSIndex].AskSize;
                //int TotalAsks = TimeSales[TSIndex].TotalAskDepth;
                //int BidVol = TimeSales[TSIndex].BidSize;
                //int TotalBids = TimeSales[TSIndex].TotalBidDepth;
                float BidPrice = TimeSales[TSIndex].Bid;
                float AskPrice = TimeSales[TSIndex].Ask;

                SCDateTime RecordAdjustedDateTime = TimeSales[TSIndex].DateTime;
                // Apply the time zone offset for the chart. This will result in the actual date-time of the record in the charts time zone.
                RecordAdjustedDateTime += sc.TimeScaleAdjustment;*/

                float Price = TimeSales[TSIndex].Price;
                int Vol = TimeSales[TSIndex].Volume;
                int TradeType = TimeSales[TSIndex].Type; // at bid or ask

                // if last trade volume is the higest for current bar
                if (TimeSales[TSIndex].Type == SC_TS_BID && Vol > HigestBidVol) {
                    HigestBidVol = Vol;
                    HigestBidVolPrice = Price;
                }
                if (TimeSales[TSIndex].Type == SC_TS_ASK && Vol > HigestAskVol) {
                    HigestAskVol = Vol;
                    HigestAskVolPrice = Price;
                }

                

                /*SCString LargevolString;
                LargevolString.Format("LastProcessedSequence: %d, BarIndex: %d, TSIndex: %d, Largest Bid Vol: %d Price: %0.2f", LastProcessedSequence, sc.Index, TSIndex, HigestBidVol, HigestBidVolPrice);
                sc.AddMessageToLog(LargevolString, 0);*/


                LastProcessedSequence = TimeSales[TimeSales.Size() - 1].Sequence;
            }
        }

        BidHighVol[Index] = HigestBidVolPrice;
        AskHighVol[Index] = HigestAskVolPrice;
    }

}

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #31 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received

And this study will mark the price/tick level where highest combined bid/ask volume occurs for each bar. And will work with historical as well as live.


2021-02-14 16_56_39-Window



 
Code
SCSFExport scsf_HighsetBidAskLevels(SCStudyInterfaceRef sc)
{

	SCSubgraphRef BidHighVol = sc.Subgraph[0];
	SCSubgraphRef AskHighVol = sc.Subgraph[1];


	if (sc.SetDefaults)
	{
		// Set the configuration and defaults

		sc.GraphName = "Highset Bid Ask Levels";
		sc.StudyDescription = "Marks on each bar wher the higest price level bid/ask volume occurs";
		sc.AutoLoop = 1;
		sc.MaintainVolumeAtPriceData = 1;  // true

		BidHighVol.Name = "Bid High Vol";
		BidHighVol.DrawStyle = DRAWSTYLE_TRIANGLE_RIGHT;
		BidHighVol.DrawZeros = 0;
		BidHighVol.PrimaryColor = RGB(255, 147, 147);
		BidHighVol.LineWidth = 4;

		AskHighVol.Name = "AskHighVol";
		AskHighVol.DrawStyle = DRAWSTYLE_TRIANGLE_LEFT;
		AskHighVol.DrawZeros = 0;
		AskHighVol.PrimaryColor = RGB(128, 255, 128);
		AskHighVol.LineWidth = 4;


		return;
	}

	SCString DataString;
	int& HigestBidVol = sc.GetPersistentInt(1);
	int& HigestAskVol = sc.GetPersistentInt(2);
	int& PriorArraySize = sc.GetPersistentInt(3);

	float& HigestBidVolPrice = sc.GetPersistentFloat(1);
	float& HigestAskVolPrice = sc.GetPersistentFloat(2);

	if ((int)sc.VolumeAtPriceForBars->GetNumberOfBars() < sc.ArraySize)
		return;

	// reset higest levels on new bar
	if (sc.Index > PriorArraySize || sc.IsFullRecalculation)
	{
		HigestBidVol = 0;
		HigestAskVol = 0;
		PriorArraySize = sc.Index;

		HigestBidVolPrice = 0.0;
		HigestAskVolPrice = 0.0;
	}

	// Get the sum of the volumes from all of the prices at this bar
	unsigned int TotalVolume = 0;

	const s_VolumeAtPriceV2* p_VolumeAtPrice = NULL;
	int VAPSizeAtBarIndex = sc.VolumeAtPriceForBars->GetSizeAtBarIndex(sc.Index);
	for (int VAPIndex = 0; VAPIndex < VAPSizeAtBarIndex; VAPIndex++)
	{
		if (!sc.VolumeAtPriceForBars->GetVAPElementAtIndex(sc.Index, VAPIndex, &p_VolumeAtPrice))
			break;

		TotalVolume += p_VolumeAtPrice->Volume;

		//Calculate the price.  This requires multiplying p_VolumeAtPrice->PriceInTicks by the tick size
		float Price = p_VolumeAtPrice->PriceInTicks * sc.TickSize;

		//Other members available:
		unsigned int AskVolume = p_VolumeAtPrice->AskVolume;
		unsigned int BidVolume = p_VolumeAtPrice->BidVolume;
		unsigned int NumberOfTrades = p_VolumeAtPrice->NumberOfTrades;

		//DataString.Format("Index: %d,  Price: %f, AskVolume: %d, BidVolume: %d, NumberOfTrades: %d", sc.Index, Price, AskVolume, BidVolume, NumberOfTrades);
		//sc.AddMessageToLog(DataString, 0);

		if (AskVolume > HigestAskVol)
		{
			HigestAskVol = AskVolume;
			HigestAskVolPrice = Price;
		}
		if (BidVolume > HigestBidVol)
		{
			HigestBidVol = BidVolume;
			HigestBidVolPrice = Price;
		}


		BidHighVol[sc.Index] = HigestBidVolPrice;
		AskHighVol[sc.Index] = HigestAskVolPrice;


	}



}

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #32 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Great, I think we are getting forward, thank you.

This code is the way.

I will try on this describe what I am looking for.

Now we have these:

HigestAskVol = Vol;
HigestAskVolPrice = Price;
HigestBidVol = Vol;
HigestBidVolPrice = Price;

And now I need not only "Higest" volume, but volume for all prices in the bar. So I believe it is the work with the arrays or variables where I am lost.

And the second thing you need to sum a/b volume on these prices, because you get more than TS entries on one price.



Trembling Hand View Post
Because I like banging my head against a wall....


2021-02-14 15_48_55-Window


Here is an example code that will mark on each bar where the largest volume bid and ask trade occur. Not the greatest of studies nor the most efficient but just an example of using T&S data on a chart. And remember sc.GetTimeAndSales() only works on live connections & replay.


 
Code

SCSFExport scsf_TimeNSales(SCStudyGraphRef sc) {

    SCSubgraphRef BidHighVol = sc.Subgraph[0];
    SCSubgraphRef AskHighVol = sc.Subgraph[1];


    if (sc.SetDefaults) {

        sc.GraphName = "Highest_Bid_ASk_Vol";
        sc.StudyDescription = "Mark on each bar the highest bid & ask trade";
        sc.GraphRegion = 0;
        sc.AutoLoop=0; //Use manual looping

        BidHighVol.Name = "Bid High Vol";
        BidHighVol.DrawStyle = DRAWSTYLE_TRIANGLE_RIGHT;
        BidHighVol.DrawZeros = 0;
        BidHighVol.PrimaryColor = RGB(255, 147, 147);
        BidHighVol.LineWidth = 4;

        AskHighVol.Name = "AskHighVol";
        AskHighVol.DrawStyle = DRAWSTYLE_TRIANGLE_LEFT;
        AskHighVol.DrawZeros = 0;
        AskHighVol.PrimaryColor = RGB(128, 255, 128);
        AskHighVol.LineWidth = 4;

    }


    int& HigestBidVol = sc.GetPersistentInt(1);
    int& HigestAskVol = sc.GetPersistentInt(2);
    int& PriorArraySize = sc.GetPersistentInt(3);

    float& HigestBidVolPrice = sc.GetPersistentFloat(1);    
    float& HigestAskVolPrice = sc.GetPersistentFloat(2);     

    int64_t& LastProcessedSequence = sc.GetPersistentInt64(1);

    //This code depends upon manual looping being set
    for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; Index++)
    {
        if (Index == 0)
        {
            PriorArraySize = sc.ArraySize;
        }
        // If there are new bars added
        if (PriorArraySize < Index)
        {
            HigestAskVol = 0;
            HigestAskVolPrice = 0.0;
            HigestBidVol = 0;
            HigestBidVolPrice = 0.0;
           // sc.AddMessageToLog("********    NEW BAR *******************************************************************", 0);
            PriorArraySize = Index;
        }
                

        //reset the sequence number on a full recalculation so we start fresh for each full recalculation.
        if (sc.IsFullRecalculation && sc.UpdateStartIndex == 0) {

            BidHighVol[Index] = 0.0;
            AskHighVol[Index] = 0.0;
            LastProcessedSequence = 0;
        }
            

        // Get the Time and Sales
        c_SCTimeAndSalesArray TimeSales;
        sc.GetTimeAndSales(TimeSales);
        if (TimeSales.Size() == 0)
            return;  // No Time and Sales data available for the symbol

        //Set the initial sequence number
        if (LastProcessedSequence == 0)
            LastProcessedSequence = TimeSales[TimeSales.Size() - 1].Sequence;

        // Loop through the Time and Sales.
        for (int TSIndex = 0; TSIndex < TimeSales.Size(); ++TSIndex)
        {
            //do not reprocess previously processed sequence numbers.
            if (TimeSales[TSIndex].Sequence <= LastProcessedSequence)
                continue;

            //only interested in trade records
            if (TimeSales[TSIndex].Type == SC_TS_BID || TimeSales[TSIndex].Type == SC_TS_ASK)
            {

                /*int AskVol = TimeSales[TSIndex].AskSize;
                //int TotalAsks = TimeSales[TSIndex].TotalAskDepth;
                //int BidVol = TimeSales[TSIndex].BidSize;
                //int TotalBids = TimeSales[TSIndex].TotalBidDepth;
                float BidPrice = TimeSales[TSIndex].Bid;
                float AskPrice = TimeSales[TSIndex].Ask;

                SCDateTime RecordAdjustedDateTime = TimeSales[TSIndex].DateTime;
                // Apply the time zone offset for the chart. This will result in the actual date-time of the record in the charts time zone.
                RecordAdjustedDateTime += sc.TimeScaleAdjustment;*/

                float Price = TimeSales[TSIndex].Price;
                int Vol = TimeSales[TSIndex].Volume;
                int TradeType = TimeSales[TSIndex].Type; // at bid or ask

                // if last trade volume is the higest for current bar
                if (TimeSales[TSIndex].Type == SC_TS_BID && Vol > HigestBidVol) {
                    HigestBidVol = Vol;
                    HigestBidVolPrice = Price;
                }
                if (TimeSales[TSIndex].Type == SC_TS_ASK && Vol > HigestAskVol) {
                    HigestAskVol = Vol;
                    HigestAskVolPrice = Price;
                }

                

                /*SCString LargevolString;
                LargevolString.Format("LastProcessedSequence: %d, BarIndex: %d, TSIndex: %d, Largest Bid Vol: %d Price: %0.2f", LastProcessedSequence, sc.Index, TSIndex, HigestBidVol, HigestBidVolPrice);
                sc.AddMessageToLog(LargevolString, 0);*/


                LastProcessedSequence = TimeSales[TimeSales.Size() - 1].Sequence;
            }
        }

        BidHighVol[Index] = HigestBidVolPrice;
        AskHighVol[Index] = HigestAskVolPrice;
    }

}


Reply With Quote
 
(login for full post details)
  #33 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received

Unless you can write out some pseudo code or t&s data from one bar showing what you want done with it I'm lost as to any further action.

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #34 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Ok, understand.

This is what I trying to solve - assign TS volume on relevant prices and add volume if there is a new volume entries on the price.

Hope it is clear now.

 
Code
        for (int TSIndex = 0; TSIndex < TimeSales.Size(); ++TSIndex)
        {

	if (TimeSales[TSIndex].Type == SC_TS_BID || TimeSales[TSIndex].Type == SC_TS_ASK)
		{
			float Price = TimeSales[TSIndex].Price;
			sc.Subgraph[Price][sc.Index] += TimeSales[TSIndex].Volume;
		}
         }



Trembling Hand View Post
Unless you can write out some pseudo code or t&s data from one bar showing what you want done with it I'm lost as to any further action.


Reply With Quote
 
(login for full post details)
  #35 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
Ok, understand.

This is what I trying to solve - assign TS volume on relevant prices and add volume if there is a new volume entries on the price.

Hope it is clear now.

 
Code
        for (int TSIndex = 0; TSIndex < TimeSales.Size(); ++TSIndex)
        {

	if (TimeSales[TSIndex].Type == SC_TS_BID || TimeSales[TSIndex].Type == SC_TS_ASK)
		{
			float Price = TimeSales[TSIndex].Price;
			sc.Subgraph[Price][sc.Index] += TimeSales[TSIndex].Volume;
		}
         }

That won't work. You are assigning volume to a subgraph bar index using a float price variable. There is no subgraph for a Time and Sales prices. Does that even compile? If for example you price is 72.6 your adding volume to bar subgraph 72.6!

Chart subgraphs are equal and the same number bars as in a chart.

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #36 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

No, it cant be compiled, there is an error.

Do you have any idea how to code it?



Trembling Hand View Post
That won't work. You are assigning volume to a subgraph bar index using a float price variable. There is no subgraph for a Time and Sales prices. Does that even compile?

Chart subgraphs are equal and the same number bars as in a chart.


Reply With Quote
 
(login for full post details)
  #37 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
No, it cant be compiled, there is an error.

Do you have any idea how to code it?

Mate this is like pulling teeth.... but more painful!

After 37 posts you still haven't clearly explained what you are trying to do!

I'm sure it can be coded it's just some sort of vol at price study but the lack of a full explanation or example has me done.

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #38 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Actually, I do not understand what is not clear about that.

You post me a code that reads the tape, sequence by sequence.

Your code shows only one trade, the biggest in the bar.
But there could be more than one trade (sequence) on one price in the bar:

sequence price volume
1 49.80 15
2 49.80 20
3 49.80 7
4 49.90 10

sum for 49.80 is 42
sum for 49.90 is 10

I am trying to find a solution how to sum all trades on every price level in the bar - see above.

I believe it cant be more clearly described.




Trembling Hand View Post
Mate this is like pulling teeth.... but more painful!

After 37 posts you still haven't clearly explained what you are trying to do!

I'm sure it can be coded it's just some sort of vol at price study but the lack of a full explanation or example has me done.


Reply With Quote
 
(login for full post details)
  #39 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
sequence price volume
1 49.80 15
2 49.80 20
3 49.80 7
4 49.90 10

sum for 49.80 is 42
sum for 49.90 is 10

I am trying to find a solution how to sum all trades on every price level in the bar - see above.

I believe it cant be more clearly described.

OMG!!!!!!!

You cannot be serious?

THAT'S WHAT THE CODE IN POST 6 DOES!

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #40 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Code in post 6 do it based on VAP,
but not based od Time And Sales data.

Thats why I metioned Large Volume Trade Indicator as example,
filtering orders by order size.

YOU CANNOT DO THAT BY VAP.




Trembling Hand View Post
OMG!!!!!!!

You cannot be serious?

THAT'S WHAT THE CODE IN POST 6 DOES!


Reply With Quote
 
(login for full post details)
  #41 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
Code in post 6 do it based on VAP,
but not based od Time And Sales data.

Thats why I metioned Large Volume Trade Indicator as example,
filtering orders by order size.

YOU CANNOT DO THAT BY VAP.

I'll leave you to it. Good luck.

Follow me on Twitter Reply With Quote
The following 2 users say Thank You to Trembling Hand for this post:
 
(login for full post details)
  #42 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Ok, thank you for your effort.



Trembling Hand View Post
I'll leave you to it. Good luck.


Reply With Quote
The following user says Thank You to liboro for this post:
 
(login for full post details)
  #43 (permalink)
Site Moderator
Sarasota FL
 
Experience: Advanced
Platform: Sierra Chart
Trading: ES, YM
 
bobwest's Avatar
 
Posts: 6,368 since Jan 2013
Thanks: 48,516 given, 21,333 received


Trembling Hand View Post
I'll leave you to it. Good luck.


liboro View Post
Ok, thank you for your effort.

Whew. This was a long exchange that seems to not have gotten anywhere, I'm sorry to say.

Not to take sides, because I don't really understand the details and I don't want to add to the level of disagreement in the world, but I think that the moral of the story is that any request for coding help should be extremely and unambiguously detailed and clear, if possible with a chart picture of what is wanted, and coders should decline to take it on until they get that. Misunderstandings, often with no one at fault, are going to happen otherwise.

I am sorry that this didn't work out, and I hope that @liboro gets his idea implemented to his satisfaction.

Good luck to all going forward.

Bob.

When one door closes, another opens.
-- Cervantes, Don Quixote
Visit my futures io Trade Journal Reply With Quote
 
(login for full post details)
  #44 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Hi Bob,

thank your reply, you are completely right.
It is a valueable lesson for me for the next time.

Thank you!



bobwest View Post
Whew. This was a long exchange that seems to not have gotten anywhere, I'm sorry to say.

Not to take sides, because I don't really understand the details and I don't want to add to the level of disagreement in the world, but I think that the moral of the story is that any request for coding help should be extremely and unambiguously detailed and clear, if possible with a chart picture of what is wanted, and coders should decline to take it on until they get that. Misunderstandings, often with no one at fault, are going to happen otherwise.

I am sorry that this didn't work out, and I hope that @liboro gets his idea implemented to his satisfaction.

Good luck to all going forward.

Bob.


Reply With Quote
The following user says Thank You to liboro for this post:
 
(login for full post details)
  #45 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


bobwest View Post
Whew. This was a long exchange that seems to not have gotten anywhere, I'm sorry to say..

Funny thing is at the end of it all I now have a understanding of what's liboro wants.

A custom Filtered Volume at Price based on threshold trade volume.


It cannot be done with standard ASCIL, VAP container or collecting T&s data and subgraph

But

it can be with custom c++ and sc.Usetool()

Not sure how performant it would be because you need to print to chart a custom drawing for every price level at every bar above the threshold vol. Might have another quick crack at it later.

Follow me on Twitter Reply With Quote
The following 2 users say Thank You to Trembling Hand for this post:
 
(login for full post details)
  #46 (permalink)
Market Wizard
Quebec
 
Experience: Intermediate
Platform: NinjaTrader wt Rancho Dinero's profiling tools
Broker: AMP/CQG
Trading: ES, NQ, YM
 
trendisyourfriend's Avatar
 
Posts: 3,983 since Oct 2009
Thanks: 3,657 given, 5,120 received


Trembling Hand View Post
Funny thing is at the end of it all I now have a understanding of what's liboro wants.

A custom Filtered Volume at Price based on threshold trade volume.


It cannot be done with standard ASCIL, VAP container or collecting T&s data and subgraph

But

it can be with custom c++ and sc.Usetool()

Not sure how performant it would be because you need to print to chart a custom drawing for every price level at every bar above the threshold vol. Might have another quick crack at it later.

I have not read the whole thread but is it something like that:

Reply With Quote
 
(login for full post details)
  #47 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


trendisyourfriend View Post
I have not read the whole thread but is it something like that:

Yep that looks like what I think @liboro wants. Where did that pic come from?

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #48 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Yeah. But what I see on the pic, the threshold here is based on the total ask+bid volume on the price levels. IMO there is no order size filtering. I like the way of plotting/charting, it is a great reference.



Trembling Hand View Post
Yep that looks like what I think @liboro wants. Where did that pic come from?


Reply With Quote
 
(login for full post details)
  #49 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Anyway, what kind of limitation you see that there is only way to code it i C++?

Thank you!



Trembling Hand View Post
Yep that looks like what I think @liboro wants. Where did that pic come from?


Reply With Quote
 
(login for full post details)
  #50 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
Yeah. But what I see on the pic, the threshold here is based on the total ask+bid volume on the price levels. IMO there is no order size filtering. I like the way of plotting/charting, it is a great reference.

Yeah I understand. You want to only include trades where the volume is greater than X amount


liboro View Post
Anyway, what kind of limitation you see that there is only way to code it i C++?

Thank you!

You need a structure to hold the collected data, in this case each trade above a threshold at every bar at every price. As you can never know how many price levels you will need for the chart you cannot use Subgraphs because,
they can only plot 1 data point per bar.
You cannot dynamically alot them.
If you have a chart with a High/Low range of 200-500 ticks you would need that many Subgraphs!!! Which is far more than the max.

You cannot use persistent Variables because you can only have 1000 again not enough to store. 100 bars * avg 10 ticks per bar and you have run out.

So its a custom C++ container is the only way I see to go. Unless SC makes the VAP container customisable.

Follow me on Twitter Reply With Quote
 
(login for full post details)
  #51 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Ok, thank you.

As far as I am aware limit 1000 keys for persistent variables is valid only for fast persistent variables. For each data type, up to 50000 persistent variables are supported.

But I am not a programmer, just hit my eyes in SC documentation.

Thank you.



Trembling Hand View Post
Yeah I understand. You want to only include trades where the volume is greater than X amount



You need a structure to hold the collected data, in this case each trade above a threshold at every bar at every price. As you can never know how many price levels you will need for the chart you cannot use Subgraphs because,
they can only plot 1 data point per bar.
You cannot dynamically alot them.
If you have a chart with a High/Low range of 200-500 ticks you would need that many Subgraphs!!! Which is far more than the max.

You cannot use persistent Variables because you can only have 1000 again not enough to store. 100 bars * avg 10 ticks per bar and you have run out.

So its a custom C++ container is the only way I see to go. Unless SC makes the VAP container customisable.


Reply With Quote
 
(login for full post details)
  #52 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
As far as I am aware limit 1000 keys for persistent variables is valid only for fast persistent variables. For each data type, up to 50000 persistent variables are supported.

Yeah thats probably right but its not a easy way to store values as you have to dynamically create and name them then store the name to recall them. Far easier containers to use like C++ map

Follow me on Twitter Reply With Quote
The following user says Thank You to Trembling Hand for this post:
 
(login for full post details)
  #53 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received

So a VERY rough play around and it seems to be working better than expected for a first try at saving to a map.




Follow me on Twitter Reply With Quote
The following 2 users say Thank You to Trembling Hand for this post:
 
(login for full post details)
  #54 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Looks great! Sorry I am curious, from where do you take data and filter them if it is not from TS?




Trembling Hand View Post
So a VERY rough play around and it seems to be working better than expected for a first try at saving to a map.





Reply With Quote
 
(login for full post details)
  #55 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
Looks great! Sorry I am curious, from where do you take data and filter them if it is not from TS?

It is from T&S.

I'm building my own VAP.

If the trade is above the threshold it goes into the VAP container. If its below it doesn't.

Follow me on Twitter Reply With Quote
The following 2 users say Thank You to Trembling Hand for this post:
 
(login for full post details)
  #56 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received

Ok I'm going to dump what I have done on this. Its very much a test of concept rather than end product but here it its,




Now a couple of things,
  • Being T&S data it only works on live connection or replay
  • If you change settings etc the plotted data will be lost
  • In a fast market like the open of the ES there are just far too many trades to process using sc.GetTimeAndSales(), anything over 100ish trades per second seems unreliable
  • Given the above point I would actually look at using either sc.ReadIntradayFileRecordAtIndex() and reading the scid file directly or I suspect the best way would be sc.GetChartArray() set to Number of Trades Per Bar 1 as per SC Here and then it would work on historical data as well.
  • To get the best performance for a fast high vol instrument I had to use Chart Settings>Advanced Settings 2>Volume Filter Exclude set to same as threshold and tick Filter Trade Completely then overlay another chart using OverlayBar see pic



But any way there it is for now. And again test of concept rather than end product

 
Code
#include  "sierrachart.h" 

SCDLLName("TnS_Filtered");


std::map<std::pair<int, int>, int> mapIndexPriceVols;
std::map<std::pair<int, int>, int>::iterator itr;

SCSFExport scsf_VolumeFilter(SCStudyInterfaceRef sc)
{

    SCInputRef Volumethreshold = sc.Input[0];



    if (sc.SetDefaults)
    {
        sc.GraphName = "Volume Filter";
        sc.AutoLoop = 0;

        Volumethreshold.Name = "Volume greater than threshold";
        Volumethreshold.SetInt(5);

        sc.Input[1].Name = "Ask Top 25% Color";
        sc.Input[1].SetColor(RGB(0, 149, 0));

        sc.Input[2].Name = "Ask mid 50% Color";
        sc.Input[2].SetColor(RGB(108, 255, 146));

        sc.Input[3].Name = "Ask bottom 25% Color";
        sc.Input[3].SetColor(RGB(198, 255, 255));

        sc.Input[4].Name = "Threshold";
        sc.Input[4].SetColor(RGB(255, 255, 174));

        sc.Input[5].Name = "Bid bottom 25% Color";
        sc.Input[5].SetColor(RGB(255, 137, 81));

        sc.Input[6].Name = "Bid mid 50% Color";
        sc.Input[6].SetColor(RGB(234, 77, 0));

        sc.Input[7].Name = "Bid Top 25% Color";
        sc.Input[7].SetColor(RGB(164, 0, 0));

       


        return;
    }


    int64_t& r_LineNumber = sc.GetPersistentInt64(0);
    int64_t& LastProcessedSequence = sc.GetPersistentInt64(1);
    int newVol;


    SCString ToolString;
    s_UseTool Tool;
    Tool.AddMethod = UTAM_ADD_OR_ADJUST;


    //This code depends upon manual looping being set
    for (int Index = sc.UpdateStartIndex; Index < sc.ArraySize; Index++)
    {
        if (Index == 0)
        {            
            mapIndexPriceVols[std::make_pair(Index, 0)] = 0;
        }

        //reset the sequence number on a full recalculation so we start fresh for each full recalculation.
        if (sc.IsFullRecalculation && sc.UpdateStartIndex == 0) {
            LastProcessedSequence = 0;
            mapIndexPriceVols.clear();
            mapIndexPriceVols[std::make_pair(Index, 0)] = 0;
        }

        // Get the Time and Sales
        c_SCTimeAndSalesArray TimeSales;
        sc.GetTimeAndSales(TimeSales);
        if (TimeSales.Size() == 0)
            return;  // No Time and Sales data available for the symbol

        //Set the initial sequence number
        if (LastProcessedSequence == 0)
            LastProcessedSequence = TimeSales[TimeSales.Size() - 1].Sequence;

        // Loop through the Time and Sales.
        for (int TSIndex = 0; TSIndex < TimeSales.Size(); ++TSIndex)
        {
            //do not reprocess previously processed sequence numbers.
            if (TimeSales[TSIndex].Sequence <= LastProcessedSequence)
                continue;

            //only interested in trade records
            if (TimeSales[TSIndex].Type == SC_TS_BID || TimeSales[TSIndex].Type == SC_TS_ASK)
            {

                float Price = TimeSales[TSIndex].Price;
                int ticks = sc.PriceValueToTicks(Price); // Price / sc.TickSize;
                int Vol = TimeSales[TSIndex].Volume;
                int TradeType = TimeSales[TSIndex].Type; // at bid or ask

                
                if (Vol > Volumethreshold.GetInt())
                {
                    if (TradeType == 2) {
                        itr = mapIndexPriceVols.find(std::make_pair(Index, ticks));
                        if (itr != mapIndexPriceVols.end()) {
                            newVol = mapIndexPriceVols[std::make_pair(Index, ticks)] + Vol;
                            mapIndexPriceVols[std::make_pair(Index, ticks)] = newVol;
                            ToolString.Format(" %d", newVol);
                        }
                        else {
                            newVol = Vol;
                            mapIndexPriceVols[std::make_pair(Index, ticks)] = Vol;
                            ToolString.Format(" %d",  Vol);
                        }
                    }
                    else {
                        itr = mapIndexPriceVols.find(std::make_pair(Index, ticks * -1));
                        if (itr != mapIndexPriceVols.end()) {
                            newVol = mapIndexPriceVols[std::make_pair(Index, ticks * -1)] + Vol;
                            mapIndexPriceVols[std::make_pair(Index, ticks * -1)] = newVol;
                            ToolString.Format("%d ", newVol);
                        }
                        else {
                            newVol = Vol;
                            mapIndexPriceVols[std::make_pair(Index, ticks * -1)] = Vol;
                            ToolString.Format("%d ",Vol);
                        }
                    }


                    Tool.ChartNumber = sc.ChartNumber;
                    Tool.DrawingType = DRAWING_TEXT;
                    Tool.FontSize = 9;
                    Tool.FontBold = 1;
                    Tool.ReverseTextColor = 1;                    
                    Tool.BeginDateTime = sc.BaseDateTimeIn[Index];
                    Tool.BeginValue = Price;

                    if (TradeType == 1) {
                        r_LineNumber = (Index*1000)+  ticks;
                        Tool.TextAlignment = DT_RIGHT;

                        if (newVol > (Volumethreshold.GetInt() * 8)) Tool.Color = sc.Input[7].GetColor();
                        else if (newVol > (Volumethreshold.GetInt() * 5)) Tool.Color = sc.Input[6].GetColor();
                        else if (newVol > (Volumethreshold.GetInt() * 3)) Tool.Color = sc.Input[5].GetColor();
                        else  Tool.Color = sc.Input[4].GetColor();
                    }
                    else {
                        r_LineNumber = (Index * -1000) - ticks;
                        Tool.TextAlignment = DT_LEFT;

                        if (newVol > (Volumethreshold.GetInt() * 8)) Tool.Color = sc.Input[1].GetColor();
                        else if (newVol > (Volumethreshold.GetInt() * 5)) Tool.Color = sc.Input[2].GetColor();
                        else if (newVol > (Volumethreshold.GetInt() * 3)) Tool.Color = sc.Input[3].GetColor();
                        else  Tool.Color = sc.Input[4].GetColor();
                    }

                    Tool.Text = ToolString;
                    Tool.LineNumber = r_LineNumber;

                    sc.UseTool(Tool);


                }

                
            }

            LastProcessedSequence = TimeSales[TimeSales.Size() - 1].Sequence;
        }


    }



}

Follow me on Twitter Reply With Quote
The following 3 users say Thank You to Trembling Hand for this post:
 
(login for full post details)
  #57 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received

@liboro now that I have figured out how the Advance Chart Setting > volume filter works why not just use that set to filter out the vol you don't want and the standard SC VAP study?

details here

Follow me on Twitter Reply With Quote
The following user says Thank You to Trembling Hand for this post:
 
(login for full post details)
  #58 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

First of all: great work!!! I am really impressed by your attitude and your knowledge.

I will test it and let you know.

Why there is unreability of high speed frequency of trades per seconds? Do you think it is because of the C++ map container? Or thank to use use_tool?

Thank you!



Trembling Hand View Post
@liboro now that I have figured out how the Advance Chart Setting > volume filter works why not just use that set to filter out the vol you don't want and the standard SC VAP study?

details here


Reply With Quote
 
(login for full post details)
  #59 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

I am in the middle of the testing and I am getting weird numbers of volume.
See attachment - threshold is set to 0 (if I do understand it right, in this case it should plot all a/b volume on the price levels).

On the top of the bar you can see delta of the bar - so numbers on the price levels should be definetely bigger.


Reply With Quote
 
(login for full post details)
  #60 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
I am in the middle of the testing and I am getting weird numbers of volume.
See attachment - threshold is set to 0 (if I do understand it right, in this case it should plot all a/b volume on the price levels).

On the top of the bar you can see delta of the bar - so numbers on the price levels should be definetely bigger.

I wouldn't worry about my code. I don't think that implementation is looping through all T&S when it moves fast. Needs more work that I haven't got time to do at the moment. But SC has a built in solutions that works perfectly. Try this .cht file. Its exactly the solution I'd use.




Attached Files
Register to download File Type: cht VaP_SC_Filtered.Cht (4.0 KB, 3 views)
Follow me on Twitter Reply With Quote
 
(login for full post details)
  #61 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

Great idea, thank you indeed!

Are you going to explore more the way based on TS? I went through your code yesterday and I couldnt find any reason to cause unreability. Everything makes sense there.


Trembling Hand View Post
I wouldn't worry about my code. I don't think that implementation is looping through all T&S when it moves fast. Needs more work that I haven't got time to do at the moment. But SC has a built in solutions that works perfectly. Try this .cht file. Its exactly the solution I'd use.


Reply With Quote
 
(login for full post details)
  #62 (permalink)
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
 
Posts: 170 since Jun 2011
Thanks: 14 given, 243 received


liboro View Post
Great idea, thank you indeed!

Are you going to explore more the way based on TS? I went through your code yesterday and I couldnt find any reason to cause unreability. Everything makes sense there.


I had the chart on a fast refresh rate but now think a slower one makes sense.

May work better by slowing it down to a 1000 ms. I haven't tried it yet but suspect that it can loop through the t&s pretty fast but takes a good few ms to initiate the call. By that time it is getting behind and another call to refresh is happening.... Maybe. Will test tomorrow
.

Follow me on Twitter Reply With Quote
The following user says Thank You to Trembling Hand for this post:
 
(login for full post details)
  #63 (permalink)
Prague
 
 
Posts: 28 since Nov 2016
Thanks: 8 given, 2 received

The best way is to use FileRecordIndexOfLastDataRecordInChart as mentioned earlier. I am pretty sure now. If you put Large Volume Indicator from SC to the chart you can see that it is reading scid file.



Trembling Hand View Post
I had the chart on a fast refresh rate but now think a slower one makes sense.

May work better by slowing it down to a 1000 ms. I haven't tried it yet but suspect that it can loop through the t&s pretty fast but takes a good few ms to initiate the call. By that time it is getting behind and another call to refresh is happening.... Maybe. Will test tomorrow
.


Reply With Quote
 
(login for full post details)
  #64 (permalink)
Site Moderator
Sarasota FL
 
Experience: Advanced
Platform: Sierra Chart
Trading: ES, YM
 
bobwest's Avatar
 
Posts: 6,368 since Jan 2013
Thanks: 48,516 given, 21,333 received

FYI, I just fixed the title of this thread, from "Time and sales coding in ASCIL" to read "Time and sales coding in ACSIL." (Switched the order of the S and C.) I kept wondering what was bugging me about the title, until I said it out loud. It's short for "Advanced Custom Study/System Interface and Language (ACSIL)," which is a dumb name, but it's what they use.

Very easy to get it wrong.

Bob.

-----------------

Edit: I see that it's right now in most places, but it's still "ASCIL" in the heading at the top of the page. I'll check with Mike how to fix that.

Computer systems are always having new little quirks.

When one door closes, another opens.
-- Cervantes, Don Quixote
Visit my futures io Trade Journal Reply With Quote
The following user says Thank You to bobwest for this post:
 
(login for full post details)
  #65 (permalink)
Site Administrator
Swing Trader
Data Scientist & DevOps
Manta, Ecuador
 
Experience: Advanced
Platform: My own custom solution
Trading: Emini Futures
 
Big Mike's Avatar
 
Posts: 49,792 since Jun 2009
Thanks: 32,314 given, 97,615 received


bobwest View Post
Edit: I see that it's right now in most places, but it's still "ASCIL" in the heading at the top of the page. I'll check with Mike how to fix that.

Computer systems are always having new little quirks.

That banner is updated once a minute

Mike

We're here to help -- just ask

For the best trading education, watch our webinars
Searching for trading reviews? Review this list

Follow us on Twitter, YouTube, and Facebook

Support our community as an Elite Member:
https://futures.io/elite/
Follow me on Twitter Visit my futures io Trade Journal Reply With Quote
The following user says Thank You to Big Mike for this post:


futures io Trading Community Platforms and Indicators Sierra Chart > Time and sales coding in ACSIL


Last Updated on February 21, 2021


Upcoming Webinars and Events
 

NinjaTrader Indicator Challenge!

Ongoing
 

Battlestations! Show us your trading desk - $1,500 in prizes!

March
 

Importance of Finding Your Own Way w/Adam Grimes

Elite only
 

Journal Challenge w/Jigsaw

April
     



Copyright © 2021 by futures io, s.a., Av Ricardo J. Alfaro, Century Tower, Panama, +507 833-9432, info@futures.io
All information is for educational use only and is not investment advice.
There is a substantial risk of loss in trading commodity futures, stocks, options and foreign exchange products. Past performance is not indicative of future results.
no new posts