NexusFi: Find Your Edge


Home Menu

 





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 10,866 views
    2. thumb_up 19 thanks given
    3. group 5 followers
    1. forum 64 posts
    2. attach_file 11 attachments




 
Search this Thread

Time and sales coding in ACSIL

  #51 (permalink)
liboro
Prague
 
Posts: 28 since Nov 2016
Thanks Given: 8
Thanks Received: 2

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

Can you help answer these questions
from other members on NexusFi?
Better Renko Gaps
The Elite Circle
Cheap historycal L1 data for stocks
Stocks and ETFs
Trade idea based off three indicators.
Traders Hideout
REcommedations for programming help
Sierra Chart
Pivot Indicator like the old SwingTemp by Big Mike
NinjaTrader
 
  #52 (permalink)
 Trembling Hand 
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
Posts: 246 since Jun 2011
Thanks Given: 28
Thanks Received: 360


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
Thanked by:
  #53 (permalink)
 Trembling Hand 
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
Posts: 246 since Jun 2011
Thanks Given: 28
Thanks Received: 360


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
Thanked by:
  #54 (permalink)
liboro
Prague
 
Posts: 28 since Nov 2016
Thanks Given: 8
Thanks Received: 2

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
  #55 (permalink)
 Trembling Hand 
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
Posts: 246 since Jun 2011
Thanks Given: 28
Thanks Received: 360


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
Thanked by:
  #56 (permalink)
 Trembling Hand 
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
Posts: 246 since Jun 2011
Thanks Given: 28
Thanks Received: 360

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
Thanked by:
  #57 (permalink)
 Trembling Hand 
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
Posts: 246 since Jun 2011
Thanks Given: 28
Thanks Received: 360

@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
Thanked by:
  #58 (permalink)
liboro
Prague
 
Posts: 28 since Nov 2016
Thanks Given: 8
Thanks Received: 2

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
  #59 (permalink)
liboro
Prague
 
Posts: 28 since Nov 2016
Thanks Given: 8
Thanks Received: 2

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
  #60 (permalink)
 Trembling Hand 
Melbourne, Land of Oz
 
Experience: Advanced
Platform: Sierra Chart, CQG
Broker: CQG
Trading: HSI
Posts: 246 since Jun 2011
Thanks Given: 28
Thanks Received: 360



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
Elite Membership required to download: VaP_SC_Filtered.Cht
Follow me on Twitter Reply With Quote




Last Updated on February 21, 2021


© 2024 NexusFi™, s.a., All Rights Reserved.
Av Ricardo J. Alfaro, Century Tower, Panama City, Panama, Ph: +507 833-9432 (Panama and Intl), +1 888-312-3001 (USA and Canada)
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.
About Us - Contact Us - Site Rules, Acceptable Use, and Terms and Conditions - Privacy Policy - Downloads - Top
no new posts