Login Page - Create Account

Support Board


Date/Time: Tue, 26 Nov 2024 17:45:37 +0000



Post From: GDI w/2551 and study updates (manual vs auto looping implications)

[2023-11-11 00:58:11]
User133994 - Posts: 80
Support,

Great update to the GDI interface! Excellent.

I've succeeded in getting the GDI example to work inside some of my custom studies, however, I am interested in knowing some 'best practices' concerning updating variables.

Basically, I'm using GDIExample.cpp and it works for static information. However, market data is always changing along with many other variables. What is the best practice, for example, for showing the current sc.Index which changes with every bar?

I've succeeded in using autoloop=1, but it is obviously not the most efficient use of GDI--as the GDI text is constantly being repainted. The most efficient use would to only paint the text 1x upon a variable update, but I'm not quite finding a way to do this. That explicitly means GDI paints only 1x per bar, as the sc.Index is only updated 1x per bar. Perhaps that is part of the challenge of using GDI vs builtin drawing capability.

If anyone has a working sample of how to display the current sc.Index as text (just for a simple example) as the chart is painting using GDI, I would appreciate seeing how that would work. I know manual looping is more efficient in many ways, but don't know if there are other considerations for GDI and interaction with SC that would prohibit using a certain approach.

Yes, I already can do this using autoloop = 1, but that is inefficient as I described above. I'm looking for the 'best practice' for this use case, if you can help with that.

Thanks!

Ok, here is my sample code that shows the 're-painting' when using autoloop=1 :

//%{{% for SC post full GDI example
// Drawing function declaration
void DrawToChart(HWND WindowHandle, HDC DeviceContext, SCStudyInterfaceRef sc);


/*==========================================================================*/
SCSFExport scsf_DrawToChartExample(SCStudyInterfaceRef sc)
{
  if (sc.SetDefaults)
  {
    // Set the configuration and defaults

    sc.GraphName = "Draw To Chart Example";
    sc.GraphRegion = 0;

    sc.AutoLoop = 1;
    return;
  }


  // This is where we specify the drawing function. This function will be called
  // when the study graph is drawn on the chart. We are placing this after
  // if (sc.SetDefaults). So in case the study DLL is unloaded and reloaded,
  // this will continue to be set to the correct address.
  sc.p_GDIFunction = DrawToChart;


}
/*==========================================================================*/

void DrawToChart(HWND WindowHandle, HDC DeviceContext, SCStudyInterfaceRef sc )
{
//%{{% demo showing repaints

auto& someNum = sc.GetPersistentInt(26); // this reveals repaints
if (sc.IsFullRecalculation && sc.Index == 0){
//%{{% initial value
someNum = 1; // starting y position
return;
//%}}%
}

  sc.Graphics.SetTextAlign(TA_NOUPDATECP);

  n_ACSIL::s_GraphicsFont GraphicsFont;

  GraphicsFont.m_Height = 16;
  GraphicsFont.m_Weight = FW_BOLD;
  sc.Graphics.SetTextFont(GraphicsFont);

  n_ACSIL::s_GraphicsColor GraphicsColor;
  GraphicsColor.SetRGB(64, 128, 0);

  sc.Graphics.SetBackgroundColor(GraphicsColor);

SCString text;
text.Format("Hello %d", someNum++);

  sc.Graphics.DrawTextAt(text, 350, 200);


  return;
//%}}%
}
//%}}%

So you add this custom study to a non-updating chart (i.e. on Saturday when the market is off) and the numbers keep counting...even though no bars are painting, etc. I know it is part of the autoloop--which is why I'm asking for help; I don't know how to prevent GDI from repainting even though there are no updates occurring on an autoloop--while still allowing for updates to repaint (only when required, not every second or every tick, etc.). Said another way, the goal is to only paint the current sc.Index (on a weekend chart) 1x, and then on Sunday nite when the market opens, that should be the next 're-paint' because a new bar caused the index to increment. Hope this makes sense.

Yes, I know if I use sc.Index instead of someNum variable (in the above autoloop example) then the painted number won't change until Sunday, but it WILL repaint the same sc.Index over and over and over--the same number (even though our eyes wouldn't be able to detect it); I want to eliminate all that redundant painting...wasting precious CPU/memory cycles.

thanks again