Date and Time to Number Conversions

Code developed and kindly donated by Murthy Suresh.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function Date_To_Num( aaaammdd )
{
    dd_ = StrToNum( StrRight( aaaammdd, 2 ) );	//printf(WriteVal(dd_) + " "  );
    mm_ = StrToNum( StrMid( aaaammdd, 4, 2 ) );	//printf(WriteVal(mm_) + " "  );
    aa_ = StrToNum( StrLeft( aaaammdd, 4 ) );	//printf(WriteVal(aa_) + " " + "\n" );
    Date_Num = ( 10000 * ( aa_ - 1900 ) ) + ( 100 * mm_ ) + dd_;
    RESULT = Date_Num;
    return RESULT;
}
 
function Time_To_Num( strTime ) // format for time is hh:mm:ss
{
    /*
    //do something to raise alert  if length does not match
    ????PopupWindow("Current time is: " + Now(),"Alert", 2,
    640*mtRandom(), 480*mtRandom());
    */
    hh_t = StrToNum( StrLeft( strTime, 2 ) );	//printf(WriteVal( hh_t ) + " "  );
    mm_t = StrToNum( StrMid( strTime, 3, 2 ) );	//printf(WriteVal( mm_t ) + " "  );
    ss_t = StrToNum( StrRight( strTime, 2 ) );	//printf(WriteVal( ss_t ) + " "  + "\n"  );
    Time_Num = 10000 * hh_t + 100 * mm_t + ss_t;
    RESULT = Time_Num;
    return RESULT;
}
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

Popup Window: Preventing pile-ups

By Dennis Brown

The popup window is a great tool in debugging and can help you to keep track of what your code is doing or it can be used to alert you to special situations in your normally running formula. A common problem is that if you call PopupWindow() from a loop or if one gets generated on every AFL pass, you can get hundreds or even thousands of pop-ups piling up on your screen. Tomasz posted a simple work-around on the AmiBroker Feedback Center that took care of the problem in some cases (Suggestion 1528):

The following is a more complete version of this solution that adds a popupID to keep track of each individual popup window and re-enable the popup after its specified timeout period, or if any of the displayed text changes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function GetSecondNum()
{
    Time = Now( 4 );
    Seconds = int( Time % 100 );
    Minutes = int( Time / 100 % 100 );
    Hours = int( Time / 10000 % 100 );
    SecondNum = int( Hours * 60 * 60 + Minutes * 60 + Seconds );
    return SecondNum;
}
 
function PopupWindowEx( popupID, bodytext, captiontext, timeout, left, top )
{
    displayText = bodytext + captiontext;
    if ( ( StaticVarGetText( "prevPopup" + popupID ) != displayText) OR ( StaticVarGet( "prevPopupTime" + popupID ) < GetSecondNum() ) )
    {
        StaticVarSetText( "prevPopup" + popupID, displayText);
        StaticVarSet( "prevPopupTime" + popupID, GetSecondNum() + timeout );
        PopupWindow( bodytext, Captiontext + popupID, timeout, Left, top );
    }
}
 
PopupWindowEx( "ID:1", "testing", "test alert ", 5, -1, -1 );
PopupWindowEx( "ID:2", "testing", "test alert ", 5, 0, 0 );
1 Star2 Stars3 Stars4 Stars5 Stars (3 votes, average: 5 out of 5)
Loading ... Loading ...

Restore Last Used Range

When starting up AmiBroker the chart range defaults to the last number of bars set in Preferences. This means that in virtually all cases you have to manually zoom and restore the chart range you were previously working with. This post presents a function that will restore the last used range before you shut down AmiBroker. If you like to use this function routinely, you can copy the functions below to your default #Include file and place this call at the top of your code:

1
RestoreLastUsedRange();

This function checks the contents of a static variable named “StartUp”+ChartIDStr. This static variable will return a NULL the first time it is called. When this happens, the ZoomToIndex() is called. This function retrieves the last used range for the current chartID from your hard disk and zooms to this range. The Plot() and Title statements are added to help you verify proper operation. You can also uncomment the two _TRACE() commands and start up DebugView for further diagnostic purposes.

If you do not have it yet, be sure to create a folder for the PersistentVariables, as shown at the top of the code. This is where the First and Last Indexes, which point to the start and end of the range being restored, are saved in a small file. You can open these with Notepad to help debugging operations.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
\\Pay attention to the double slashes in the path line. They need to be there.
PersistentPath = "C:\\Program Files\\AmiBroker\\PersistentVariables\\";
 
function PersistentVarGet( VarName )
{
    global PersistentPath;
    fh = fopen( PersistentPath + VarName + ".pva", "r" );
 
    if ( fh )
    {
        String = fgets( fh );
        fclose( fh );
    }
    else
        string = "";
 
    Number = StrToNum( String );
 
    return Number;
}
 
function PersistentVarSet( VarName, Number )
{
    global PersistentPath;
    String = NumToStr( Number, 1.3, False );
    fh = fopen( PersistentPath + VarName + ".pva", "w" );
 
    if ( fh )
    {
        fputs( String, fh );
        fclose( fh );
    }
 
    return fh;
}
 
procedure ZoomToIndex( FirstBarIndex, LastBarIndex )
{
    StaticVarSet( "FirstBarIndex", FirstBarIndex );
    StaticVarSet( "LastBarIndex", LastBarIndex );
    DT = DateTime();
    BI = BarIndex();
    LastDateTime = LastValue( ValueWhen( LastBarIndex == BI, DT ) );
    FirstDateTime = LastValue( ValueWhen( FirstBarIndex == BI, DT ) );
    LastDateTimestr = DateTimeToStr( LastDateTime );
    FirstDateTimestr = DateTimeToStr( FirstDateTime );
    AB = CreateObject( "Broker.Application" );
    AW = AB.ActiveWindow;
    AW.ZoomToRange( FirstDateTimestr, LastDateTimestr );
}
 
function RestoreLastUsedRange()
{
    if ( Status( "Action" ) == 1 )
    {
        ChartIDStr = NumToStr( GetChartID(), 1.0, False );
        PrevFirstBarIndex = PersistentVarGet( "FirstBarIndex" + ChartIDStr );
        PrevLastBarIndex = PersistentVarGet( "LastBarIndex" + ChartIDStr );
 
        if ( IsNull( StaticVarGet( "StartUp" + ChartIDStr ) ) )
        {
            ZoomToIndex( PrevFirstBarIndex, PrevLastBarIndex );
            StaticVarSet( "StartUp" + ChartIDStr, True );
            //_TRACE( "# StartUp: CID: " + ChartIDStr + ", PFBI: " + PrevFirstBarIndex + ", PLBI: " + PrevLastBarIndex );
        }
 
        FirstBarIndex = Status( "firstvisiblebarindex" );
 
        LastBarIndex = Status( "lastvisiblebarindex" );
 
        if ( PrevFirstBarIndex != FirstBarIndex OR PrevLastBarIndex != LastBarIndex )
        {
            PersistentVarSet( "FirstBarIndex" + ChartIDStr, FirstBarIndex );
            PersistentVarSet( "LastBarIndex" + ChartIDStr, LastBarIndex );
            //_TRACE( "# UpdateRange: CID: " + ChartIDStr + ", FBI: " + FirstBarIndex + ", LBI: " + LastBarIndex );
        }
    }
}

///// All code above this line can be placed in an Include file /////

1
2
3
4
5
6
7
Plot( C, "", 1, 128 );
RestoreLastUsedRange();
 
Title = "\n" +
        "ChartIDStr: " + NumToStr( GetChartID(), 1.0, False ) + "\n" +
        "FirstIndex: " + Status( "firstvisiblebarindex" ) + "\n" +
        " LastIndex: " + Status( "Lastvisiblebarindex" );

Edited by Al Venosa.

1 Star2 Stars3 Stars4 Stars5 Stars (4 votes, average: 4.75 out of 5)
Loading ... Loading ...

Deleting Tickers and Composites

Creating composites is a lot of fun and can provide useful information about market and sector movements. However, when creating many composites, you will sooner or later find that your database is bloated with obsolete composites. The first requirement is to create a function to delete composites. Dingo kindly provided the following example code, which will be used to provide a variety of other useful functions. Note that the functions below can be used to delete both tickers and composites; the procedure is the same. The formula is designed to be run as an indicator but can be adapted to run in a scan, etc.

Deleting a list of Tickers or Composites

1
2
3
4
5
6
7
8
9
10
11
12
DeleteTickers = ParamTrigger("Delete Tickers", "Click Here To Delete Tickers"); 
TickerList = ParamStr("Tickers to Delete","ALY,CALM,FCX,GLF,PNCL,RS,SCHN,STLD,WNR,X"); 
if ( DeleteTickers ) 
{ 
oAB = CreateObject( "Broker.Application" ); 
oStocks = oAB.Stocks(); 
for( n=0; (Ticker=StrExtract( TickerList, n))!= ""; n++) 
{ 
oStocks.Remove( Ticker ); 
} 
oAB.RefreshAll(); 
}

When testing this code be sure to use a test database to prevent deleting important tickers. It is always best to develop code that creates and deletes tickers on a test database. To test the above code create a new test database and copy-n-paste the TickerList into a Watchlist using Symbol -> Watchlist -> Type in Symbols. There is no need to backfill the tickers with data. Next open your workspace and display the Watchlist. Next, if you click Click Here To Delete Tickers, you’ll see the ticker disappearing from your Symbol Workspace.

Deleting a Single Ticker or Composite

The above code can easily be trimmed to provide a function to delete a single ticker:

1
2
3
4
5
6
7
8
9
10
11
function DeleteComposite( CompositeName ) 
{ 
oAB = CreateObject( "Broker.Application" ); 
oStocks = oAB.Stocks(); 
oStocks.Remove( CompositeName ); 
oAB.RefreshAll(); 
} 
 
DeleteTicker = ParamTrigger("Delete Ticker", "Click Here To Delete Ticker"); 
Ticker = ParamStr("Ticker to Delete","ALY"); 
if( DeleteTicker ) DeleteComposite( Ticker );

Deleting All Tickers in a Watchlist

A slight modification of the above code will let you delete all tickers in a Watchlist:

1
2
3
4
5
6
7
8
9
10
11
12
13
WatchListNum = Param("Watchlist Number",0,0,64,1); 
DeleteTickers = ParamTrigger("Delete Tickers in Watchlist", "Delete Tickers"); 
TickerList = GetCategorySymbols( categoryWatchlist, WatchListNum ); 
if ( DeleteTickers ) 
{ 
oAB = CreateObject( "Broker.Application" ); 
oStocks = oAB.Stocks(); 
for( n=0; (Ticker=StrExtract( TickerList, n))!= ""; n++) 
{ 
oStocks.Remove( Ticker ); 
} 
oAB.RefreshAll(); 
}

Deleting all Composites in Group 253

Composites are normally stored in Group 253. To delete all composites in this group replace the categorywatchlist with categorygroup:

1
2
3
4
5
6
7
8
9
10
11
12
13
GroupNum = Param("Group Nbr",253,0,255,1); 
DeleteTickers = ParamTrigger("Delete Composites", "Click Here To Delete Composites"); 
TickerList = GetCategorySymbols( categoryGroup, GroupNum ); 
if ( DeleteTickers ) 
{ 
oAB = CreateObject( "Broker.Application" ); 
oStocks = oAB.Stocks(); 
for( n=0; (Ticker=StrExtract( TickerList, n))!= ""; n++) 
{ 
oStocks.Remove( Ticker ); 
} 
oAB.RefreshAll(); 
}

OLE Code written by dingo.

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

Introduction to the ATC

The AddToComposite() (ATC) is an extremely powerful function. Topics in this category will not repeat ATC topics covered elsewhere, so be sure to follow the following links for more information and applications:

The AmiBroker AFL Reference: ADDTOCOMPOSITE
Calculating multiple-security statistics with AddToComposite function
Introduction to AddToComposite
Multiple time-frame indicators
Search this users’ Knowledge Base for applications

Also be sure to browse the applications listed at the bottom of the AFL Reference for the ATC.

1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5 out of 5)
Loading ... Loading ...

Zoom-to-Range Applications

This post offers a variety of zoom functions to help you analyze charts better. For example, you can zoom in on the cursor-selected bar, or you can step forward and backward from signal to signal or over custom price conditions. These functions are made possible by the ZoomToRange OLE function, which lets you zoom in on a specific date range.

To exercise and test the functions below, copy and Insert the code to an Indicator pane, open the Param window, and click on various options to see how the functions work. For demo purposes, three zoom events are provided: Buy, Sell, and Mondays. In your own application, you would assign other conditions to the event variable, such as, for example, gaps, price patterns, etc. Stepping from Event to Event would allow you to visually analyze the chart surrounding events. The Param window looks like this:

Zoom Increment is the number of bars added to the display with each zoom in/out action. WindowWidth is the number of bars displayed when jumping from event to event.
The program uses a FocusBar to which zoom dimensions are referenced. Yellow text is attached to the FocusBar on the chart to identify it. You can add other information to this PlotText(). For example, if you were analyzing buy, sell, short, and cover signals, you could add trade prices and indicator values, if you so desired. The Green histogram at the bottom of the chart indicates where the selected events occur. See an example chart below showing buy signals. The green histogram bar occurs just before the green buy arrow on the chart.

Descriptions for the function below are presented ahead of the functions themselves so that you can copy all the code in one step.

ZoomToIndex( FirstBarIndex, LastBarIndex)
Calling the ZoomToIndex() will zoom your chart to display a window ranging from the first argument (FirstBarIndex) to the second argument (LastBarIndex). While you cannot zoom in closer than ten bars using the Zoom In/Out buttons on your AB Toolbar, this function lets you zoom all the way down to a two-bar window. Since most Indicators use periods expressed in bars and not in dates, the function uses the BarIndex to set the window width.

ZoomToCursor( ZoomWidth )
This function lets you zoom in to the cursor position and display the number of bars assigned to ZoomWidth. The values of important variables are displayed in the chart Title for educational purposes.

ZoomOut( ZoomWidth )
This function zooms out by increasing the number of bars displayed by ZoomWidth bars.

ZoomIn( ZoomWidth )
This function zooms in by reducing the number of bars displayed by ZoomWidth bars.

ZoomToNext( Event, ZoomWidth )
This function lets you jump to the next occurrence of a TRUE value in the Event Array. It also focuses on the event with a window of ZoomWidth bars. The most important application for this function would probably be to analyze trades by stepping from signal to signal and to visually inspect custom events or price patterns.

ZoomToPrev( Event, ZoomWidth )

This function is similar to the one above, but it jumps (retreats) to the previous event.

MarkFocus()
This function places the Yellow text at the FocusBar. You may want to customize the text displayed.

ZoomAllOut()
This function zooms out to display all bars in the database.

RightJustifyChart
When trading Real-Time, your signals are generated by prices from the Last Bar whether this bar is visible or not. If, during intense trading, you miss the fact that your Chart is not fully right justified, you may see and hear orders going out while no actions show on your Chart. While such confusion usually doesn’t last long, it could delay discretionary trades and even trick you into thinking there may be a coding problem, causing you to initiate debugging code. This function right-justifies your chart, and if it is triggered at the start of your session, it will prevent you from working with a shifted chart.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
procedure ZoomToIndex( FirstBarIndex, LastBarIndex)
{
StaticVarSet("FirstBarIndex",FirstBarIndex);
StaticVarSet("LastBarIndex",LastBarIndex);
DT = DateTime();
BI = BarIndex();
LastDateTime = LastValue(ValueWhen( LastBarIndex == BI, DT ));
FirstDateTime = LastValue(ValueWhen( FirstBarIndex == BI, DT ));
LastDateTimestr = DateTimeToStr( LastDateTime );
FirstDateTimestr = DateTimeToStr( FirstDateTime );
AB = CreateObject("Broker.Application");
AW = AB.ActiveWindow;
AW.ZoomToRange( FirstDateTimestr, LastDateTimestr );
}
1
2
3
4
5
6
7
8
9
10
11
procedure ZoomToCursor( ZoomWidth )
{
local ZoomWidth;
BI = BarIndex();
SBI = SelectedValue(BI);
LBI = LastValue(BI);
CursorIndex= Nz(StaticVarGet("CursorIndex"));
FirstBarIndex = Max(0,SBI - ZoomWidth);
LastBarIndex = Min( LBI, SBI + ZoomWidth );
ZoomToIndex( FirstBarIndex, LastBarIndex);
}
1
2
3
4
5
6
7
8
9
10
11
procedure ZoomOut( ZoomWidth )
{
local ZoomWidth;
BI = BarIndex();
LBI = LastValue(BI);
LastVisiblebar = Status("LastVisibleBar");
FirstVisibleBar= Status("FirstVisibleBar");
FirstBarIndex = Max( 0, FirstVisibleBar - ZoomWidth);
LastBarIndex = Min( LBI, LastVisibleBar + ZoomWidth );
ZoomToIndex( FirstBarIndex, LastBarIndex);
}
1
2
3
4
5
6
7
8
9
10
11
12
procedure ZoomIn( ZoomWidth )
{
local ZoomWidth;
_TRACE("##");
BI = BarIndex();
LBI = LastValue(BI);
LastVisiblebar = Status("LastVisibleBar");
FirstVisibleBar= Status("FirstVisibleBar");
FirstBarIndex = Max( 0, FirstVisibleBar + ZoomWidth);
LastBarIndex = Min( LBI, LastVisibleBar - ZoomWidth );
ZoomToIndex( FirstBarIndex, LastBarIndex);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure ZoomToNext( Event, ZoomWidth )
{
local Event, Zoomwidth;
EventNum = Cum(Event);
BI = BarIndex();
LBI = LastValue(BI);
DT=DateTime();
NextEventNum = Min(Nz(StaticVarGet("EventNumber"))+1, LastValue(EventNum));
NextEventIndex = LastValue(ValueWhen(EventNum == NextEventNum, BI));
StaticVarSet("EventNumber",Max(1, NextEventNum));
FirstBarIndex = Max( 0, NextEventIndex - ZoomWidth );
LastBarIndex = Min( BarCount-1, NextEventIndex + ZoomWidth);
ZoomToIndex( FirstBarIndex, LastBarIndex);
StaticVarSet("FocusIndex",NextEventIndex);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
procedure ZoomToPrev(  Event, ZoomWidth )
{
local Event, Zoomwidth;
EventNum = Cum(Event);
BI = BarIndex();
LBI = LastValue(BI);
LastEventNum = LastValue(EventNum);
NextEventNum = Max(1,Nz(StaticVarGet("EventNumber"))-1);
NextEventIndex = LastValue(ValueWhen(EventNum == NextEventNum, BI,1));
StaticVarSet("EventNumber",NextEventNum);
FirstBarIndex = Max( 0, NextEventIndex - ZoomWidth );
LastBarIndex = Min( BarCount-1, NextEventIndex + ZoomWidth);
ZoomToIndex( FirstBarIndex, LastBarIndex);
StaticVarSet("FocusIndex",NextEventIndex);
}
1
2
3
4
5
6
7
8
9
10
11
12
procedure MarkFocus()
{
global EventNum;
DT=DateTime();
BI = BarIndex();
LBI = LastValue(BI);
FirstBarIndex = Nz(StaticVarGet("FirstBarIndex"));
FocusIndex = Min(LBI,Nz(StaticVarGet("FocusIndex"))+1);
FocusDateStr = NumToStr(DT[FocusIndex],formatDateTime);
ENStr = NumToStr(EventNum[FocusIndex],1.0,False);
PlotText("\n\nFocus\n"+FocusDateStr+"\n"+ENStr,FocusIndex,C[FocusIndex],colorYellow);
}
1
2
3
4
5
6
7
8
procedure ZoomAllOut()
{
BI = BarIndex();
LBI = LastValue(BI);
FirstBarIndex = 0;
LastBarIndex = LBI;
ZoomToIndex( FirstBarIndex, LastBarIndex);
}
1
2
3
4
5
6
7
8
9
10
11
procedure RightJustifyChart( ChartWidth )
{
DT = DateTime();
BI = BarIndex();
FirstDateTime = LastValue( Nz(Ref( DT,-Max(2, ChartWidth) ) ) );
FirstDateTimestr = DateTimeToStr( FirstDateTime );
LastDateTimestr = DateTimeToStr( LastValue(DT) );
AB = CreateObject("Broker.Application");
AW = AB.ActiveWindow;
AW.ZoomToRange( FirstDateTimestr, LastDateTimestr );
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
SetBarsRequired(1000000,1000000);
GraphXSpace = 20;
_SECTION_BEGIN("ZOOM");
FocusTrigger= ParamTrigger("Focus on Cursor","FOCUS");// zoom out by ZoomIncrement
ZoomInTrigger= ParamTrigger("Zoom in","IN");// zoom in by ZoomIncrement
ZoomOutTrigger= ParamTrigger("Zoom out","OUT");// zoom in by ZoomIncrement
ZoomAllTrigger = ParamTrigger("Zoom max. out","ALL");// zoom out to all bars
ZoomPrevTrigger= ParamTrigger("Go to Next Event","NEXT");// Jump to next event
ZoomNextTrigger= ParamTrigger("Go to Previous Event","PREVIOUS");// Jump to previous event
RJTrigger= ParamTrigger("Right Justify Chart","JUSTIFY");
ZoomIncrement= Param("Zoom Increment",10,1,1000,2);
ZoomWidth= Param("Window Width",20,2,1000,1);
_SECTION_END();
_SECTION_BEGIN("TEST SIGNALS");
ZoomEvent= ParamList("Zoom Event","MONDAY|RSI-BUY|RSI-SELL|TARGET",1);// Test events
ProfitTarget= Param("Profit Target",0.1,0,2,0.01);// Profit target
_SECTION_END(); 
 
PrevZoomWidth= Nz(StaticVarGet("ZoomWidth"));
ZoomChange= PrevZoomWidth != ZoomWidth; 
StaticVarSet("ZoomWidth",ZoomWidth); 
 
ZoomAction = FocusTrigger OR ZoomOutTrigger OR ZoomAllTrigger OR ZoomNextTrigger OR ZoomPrevTrigger OR ZoomChange OR ZoomInTrigger OR RJTrigger; 
 
if( ZoomEvent == "MONDAY" ) Event = DayOfWeek() == 1;
else if( ZoomEvent == "RSI-BUY" ) 
{ 
Event = Cross(30,RSI());// Buy rule to investigate
PlotShapes(IIf(Event,shapeSmallUpTriangle, shapeNone),5,0,C,0);
Sell = 0; 
}
else if( ZoomEvent == "RSI-SELL" ) 
{ 
Event = Cross(RSI(),70);// sell rule to investigate 
PlotShapes(IIf(Event,shapeHollowDownTriangle, shapeNone),4,0,C,0);
Buy = 0; 
}
else if( Zoomevent == "TARGET" ) 
{
Target = Ref(C,1) - C;// Profit target to analyze
Event = Target > ProfitTarget;
PlotShapes(IIf(Event,shapeSmallUpTriangle, shapeNone),5,0,C,0);
}
else Event = 0; 
 
Plot(C,"",1,128);
EventNum = Cum(Event);
FVBI = Status("FirstVisibleBarIndex");
LVBI = Status("LastVisibleBarIndex");
BI = BarIndex();
SBI = SelectedValue(BI);
LBI = LastValue(BI); 
 
FirstVisibleBar = Status( "FirstVisibleBar" );
Lastvisiblebar = Status("LastVisibleBar");
for( b = Firstvisiblebar; b < Lastvisiblebar AND b < BarCount; b++)
{
if( Event[b] ) PlotText("\n\n\n\nEvent\n"+NumToStr(EventNum[b],1.0,False),b,L[b],1);
} 
 
if( GetCursorMouseButtons() == 1 ) 
{
StaticVarSet("CursorIndex",SBI);
EventNum = Cum(Event);
StaticVarSet("EventNumber",SelectedValue(EventNum));
StaticVarSet("FocusIndex",SBI-1);
}
CursorIndex= Nz(StaticVarGet("CursorIndex")); 
 
if( ZoomAction )
{
CurrentRange= LastVisiblebar-FirstVisibleBar;
VisibleCenter= int((LastVisibleBar + FirstVisibleBar)/2);
PrevEventIndex = LastValue(ValueWhen(Event,BI,1));
NextEventIndex = LastValue(ValueWhen(Event,BI,-1));
FirstBarIndex = Nz(StaticVarGet("FirstBarIndex"));
LastBarIndex = Nz(StaticVarGet("LastBarIndex")); 
 
if( FocusTrigger) ZoomToCursor( ZoomWidth );
else if( ZoomInTrigger ) ZoomIn( ZoomWidth );
else if( ZoomOutTrigger ) ZoomOut( ZoomWidth );
else if( ZoomNextTrigger ) ZoomToPrev( Event, ZoomWidth );
else if( ZoomPrevTrigger ) ZoomToNext( Event, ZoomWidth );
else if( ZoomAllTrigger ) ZoomAllOut();
else if( RJTrigger ) RightJustifyChart( ZoomWidth );
} 
 
MArkFocus(); 
 
Plot(Event,"",5,styleArea|styleOwnScale|styleNoLabel,0,10);
CursorIndex = StaticVarGet("CursorIndex");
EventNumber= StaticVarGet("EventNumber");
Title = "\n"+
"Cursor Index: "+NumToStr(CursorIndex,1.0,False)+"\n"+
"EventNumber: "+NumToStr(EventNumber,1.0,False)+"\n";

Edited by Al Venosa

1 Star2 Stars3 Stars4 Stars5 Stars (9 votes, average: 4.44 out of 5)
Loading ... Loading ...

Plotting Trade-Lines

A useful application is to plot straight lines between entry- and exit-signals, giving you the ability to view at a glance the location and magnitude of profits and losses of your trading system. The LineArray() function enables you to draw straight lines from one event or condition to another. In the chart below, which shows a reversal trading system, note how the lines begin and end at the exact trade prices, green being long and red being short. This gives you a quick impression of the profitability and location of individual trades:

Chart with Trade-Lines

Because the LineArray() performs many calculations, it is preferred to restrict the plotting loop to the visible chart only.

Other applications would be plotting of custom ZigZag lines, price channels, trendlines, breakouts, etc.

// Dummy system to generate some signals
Buy = Cross( MACD(), Signal() );
Sell = Cross( Signal(), MACD() );
PlotShapes(IIf(Buy, shapeUpTriangle, shapeNone),colorBrightGreen,0,BuyPrice,0);
PlotShapes(IIf(Sell, shapeDownTriangle, shapeNone),colorRed,0,SellPrice,0);
Plot(C,"",1,128);
// Plot the Trade Lines
Sig = Buy OR Sell;
y0 = 0;
y1 = C[0];
TPrice = C;
FirstVisibleBar = Status( "FirstVisibleBar" );
Lastvisiblebar = Status( "LastVisibleBar" );
for( b = Firstvisiblebar; b <= Lastvisiblebar AND b < BarCount; b++)
{
if( Buy[b] ) Co = colorRed;
if( Sell[b] ) Co = colorBrightGreen;
if(Sig[b])
{
x0 = y0;
x1 = y1;
y0 = b;
y1 = TPrice[b];
Plot(LineArray(x0,x1,y0, y1),"",Co,1);
}
}

Edited by Al Venosa

1 Star2 Stars3 Stars4 Stars5 Stars (5 votes, average: 5 out of 5)
Loading ... Loading ...