A Real-Time Message FIFO

Real-time messages often appear on your screen only for the duration of a single chart-refresh interval and disappear before you have time to read them. The FIFO (First In First Out) n-line display presented here captures and scrolls messages in the chart Title so that they are easier to read. Logging messages to DebugView or the Interpretation window would require opening additional windows. Using the Title instead displays the messages right on the chart and is more space-efficient.

A typical application would be to display real-time system status, such as order status, TWS error messages, partial fills, account balance, profits, etc.

Since the chart Title does not support formatting, it is advisable to use a mono-spaced font, such as Lucida Console, and pad spaces to create columns. The integer part of the NumToStr() formatting parameter sets the overall length of the returned string and can be used to format columns. If you prefer more font and color options, you can use Gfx functions to display the messages.

To prevent Title wrapping, you can truncate messages using the StrLeft() function. This works well for TWS error messages that can be long but carry the important info at the left of the error message. The demo below uses a simple PadString() function to space short messages in columns.

The AddToFIFOTitle() function is called whenever you want to add a message to the table. Its first argument is the name of the static variable that contains the table, the second argument is the message you want to add to the table, and the third is the maximum number of lines in the table. Setting the third argument to zero clears the table.

To keep things simple, the code below uses Param functions to simulate real-time messages; in a real system, these messages would be generated by real-time events. To test the code, click any of the numbered Event Messages in the Parameter window.

clip_image002

The Title produced should look like this:

clip_image004

Note that messages in this example are padded to position the next column properly. The order of the messages is inverted to allow the last message to appear at the top of the message table. Whenever the maximum number of lines is exceeded, the oldest message is removed. To ensure that the table is updated at least once a second you should always include a RequestTimedRefresh(1) in your code.

Finally, in Automated Trading you don’t always need charts, and you may prefer to display only a status table. Since the table is stored in a global Static Variable, you can read the table from any pane or window using just two lines of code:

RequestTimedRefresh);
Title "\n"+StaticVarGetText("FIFOTitle");

If you use several scrolling displays in different panes, you should key the Static Variables as explained in Keying Static Variables. The complete demo code follows:

function padStringStringColWidth )
{
SpaceFill " ";
if( String == "{EMPTY}" String "";
SL StrLen(String);
NS StrLeft(SpaceFillColWidth-SL);
return string+NS;
}

function AddToFIFOTitleStrNameStrMaxItems )
{
// Add New item
NewString "";
PrevStr StaticVarGetTextStrName );
ItemCount Nz(StaticVarGet("NumberItems"));
if( MaxItems == )
{
StaticVarSetText(StrName"");
StaticVarSet("NumberItems",0);
S1 "";
}
else if( Str != "" )
{
StaticVarSet("NumberItems",++ItemCount);
NewTitle NumToStr(ItemCount,3.0,False)+". "+Str "\n"PrevStr;
for(s=0n=0S1=""; ( s2=StrMid(NewTitle,s,1) ) != "" AND &ltMaxItemss++ )
{
S1 S1 S2;
if( S2=="\n" n++;
}
}
else S1 PrevStr// come here when Str == ""
StaticVarSetText(StrNameS1);
return StaticVarGetText(StrName);
}

RequestTimedRefresh);
// Simulate Transient (Trigger) Events
Event1 ParamTrigger("Event Message 1""EVENT1");
Event2 ParamTrigger("Event Message 2""EVENT2");
// Simulate State events and convert to triggers
PrevEvent3 Nz(StaticVarGet("Event3") );
Event3 ParamToggle("Event Message 3""EVENT3OFF|EVENT3ON",0);
StaticVarSet("Event3",Event3);
Event3Trigger Event3 != PrevEvent3;
PrevEvent4 Nz(StaticVarGet("Event4") );
Event4 ParamToggle("Event Message 4""EVENT4OFF|EVENT4ON",0);
StaticVarSet("Event4",Event4);
Event4Trigger Event4 != PrevEvent4 ;
MaxEvents Param("Max. Number Events",5,0,20,1);
if( Event1 )
{
Msg1 PadString"EVENT1 MSG"15)+Now(2);
AddToFIFOTitle"FIFOTitle"MSG1MaxEvents );
}
if( Event2 )
{
Msg2 PadString"EVENT2 MSG"15)+Now(2);
AddToFIFOTitle"FIFOTitle"Msg2MaxEvents );
}
if( Event3Trigger )
{
Msg3 PadStringWriteIf(Event3,"E3-ON MSG","E3-OFF MSG"), 15)+Now(2);
AddToFIFOTitle"FIFOTitle"Msg3MaxEvents );
}
if( Event4Trigger )
{
Msg4 PadString(WriteIf(Event4,"EVENT4-ON MSG","EVENT4-OFF MSG"), 15)+Now(2);
AddToFIFOTitle"FIFOTitle"Msg4MaxEvents );
}
Title "\nFIFOTitle Demo\n\n"+AddToFIFOTitle"FIFOTitle"""MaxEvents);

Edited by Al Venosa

Comments are closed.