Plot trade events on bottom of chart pane


I'm trying to plot trade events on a chart pane, more specifically, on the bottom of the pane There are lots of examples showing the use of


to plot the trade events near to the H or L of the bar. I'm trying to plot it on the bottom of the chart pane. I can't use 0 as the value for yposition parameter, because it will then be plotted at the Y-axis 0-level, off-chart below the bottom. I've been looking at the AFL command


to get the current chart's minimum Y-axis value, and use it as the value for the PlotShape() yposition parameter. Something like this

    minY = status("axisminy");
    for( bar = 0; bar < BarCount; Buy[bar++] = false);
    for( bar = 0; bar < BarCount; bar++ )
       dateNumber = dateNumbers[bar];
       for( j = 0; ( buyDate = StrExtract( buyDates, j ) ) != ""; j++ )
         buyDateNumber = DateToNumber(buyDate);
         if( dateNumber == buyDateNumber )
           Buy[bar] = true;
    PlotShapes( IIf(Buy, shapeCircle, shapeNone), colorBrightGreen, 0, minY, 5 );

This works, and the event is plotted on the bottom of the chart. However, it is only correctly plotted after I click on the chart. If I don't click on the chart, it seems to use the cached "axisminy" from the previously displayed chart, and the event is plotted at the position corresponding to the previously displayed chart's minY value.

I've attached three charts showing this:
chart 1: previous chart with trade event
chart 2: current chart before clicking
chart 3: current chart after clicking

Is there a better way?




I’ve found a solution. Use the AFL function RequestTimedRefresh() to refresh the screen only once, and use the cached value of status(“axisminy”) on the second run.

Not elegant, but it works:

if( StaticVarGetText("ChartName") != Name() )
    RequestTimedRefresh( 1 );   // start screen refresh
    StaticVarSetText("ChartName", Name());
    RequestTimedRefresh( 0 );   // stop screen refresh
    for( bar = 0; bar < BarCount; Buy[bar++] = false);
    // Insert logic here to set Buy array
    PlotShapes( IIf(Buy, shapeCircle, shapeNone), colorBrightGreen, 0, minY, 5 );
1 Like

Hi @polomora,

That’d certainly be one way to go about it…

Unless you have some particular requirement for an event to be highlighted by plotting a specific shape, what you’re aiming for can be achieved by an other (if not better, then certainly simpler :wink: ) way by simply using the ‘Plot’ function with requisite arguments/ settings to plot an event information ribbon near the bottom of the pane. You’ll need to first define the required ‘event(s)’ in terms of colours. For e.g,

my_col = IIf(Buy, ColorGreen, IIf(Sell, ColorRed, ColorBlack));

The ‘ColorBlack’ arguement can be replaced by your chart background colour

Now simply leverage the ‘Plot’ function accordingly, for e.g,

Plot(2, "", my_col, styleOwnScale | styleArea | styleNoLabel, 0, 90);

The ‘styleOwnScale’ arguement in conjunction with ‘0’ (min value) and ‘90’ (max value) inputs will place the ribbon at the bottom of the chart pane. The ‘max value’ can be adjusted as per your liking

Try it and see if it works for you. If yes, then you can probably mark this as a ‘simpler solution’ to your query :smiley:

1 Like

@polomora - your code is simply wrong in many ways.

Charts are refreshed when needed and AmiBroker decides when, not you.

AmIBroker knows much better than you when to refresh chart. It refreshes chart when

  1. you scroll the chart
  2. you zoom the chart
  3. new real time data arrives
  4. symbol is changed
  5. linked chart is changed
  6. formula is modified
  7. chart parameters are modified
  8. plugin sends backfill “complete” event
  9. plugin sends partial backfill event
  10. a drawing tool was used or existing drawing modified

and on dozens of other occasions you simply naively ignored. And no, you don’t control refreshes and definitely can not “stop” refreshes by calling RequestTimedRefresh.

Many thanks for the tip!
I knew about this approach, but I like the ability to add up/down arrows, and other shapes, for example, to plot Earnings Dates.

Thanks for the reply.
As I mentioned in my original post:

  • This is not an elegant solution. It was necessary because status(“axisminy”) does not return the correct value. So it was a workaround to solve the problem.
  • You state that my code is “simply wrong in many ways”. It is not elegant, but it works. Have you a better solution?

Which value does it return in your opinion?

Buy= Cross( C, MA(C, 50) );
Sell= Cross(Ma(c, 50), C ) ;

minY = status("axisminy");

Plot( C, "Price", colorBlack, StyleBar ) ;
PlotShapes( IIf(Buy, shapeCircle, shapeNone), colorBrightGreen, 0, minY, 5 );