### Example: Automated Backtest Workflow Source: https://www.amibroker.com/guide/objects.html A JScript example demonstrating how to open an analysis project, start a backtest asynchronously, wait for completion, export results, and close the analysis document. ```APIDOC ## Automated Backtest Example (JScript) ### Description This example demonstrates a complete workflow for running an automated backtest using the AnalysisDoc object. ### Steps: 1. Create an AmiBroker object. 2. Open a previously saved analysis project file (.apx). 3. Start a backtest asynchronously using the Run() method. 4. Periodically check the IsBusy property to wait for the backtest to complete. 5. Export the results to an HTML file. 6. Close the analysis document. ### Code Example ```javascript AB = new ActiveXObject( "Broker.Application" ); try { NewA = AB.AnalysisDocs.Open( "C:\\analysis1.apx" ); // opens previously saved analysis project file // NewA represents the instance of New Analysis document/window if ( NewA ) { NewA.Run( 2 ); // start backtest asynchronously (Action = 2 for Portfolio Backtest) while ( NewA.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second NewA.Export( "test.html" ); // export result list to HTML file WScript.echo( "Completed" ); NewA.Close(); // close new Analysis } } catch ( err ) { WScript.echo( "Exception: " + err.message ); // display error that may occur } ``` ### Notes: - Ensure the analysis project file (e.g., `C:\analysis1.apx`) exists and is correctly configured. - The `Action` parameter in `Run()` determines the type of analysis. `2` is for Portfolio Backtest. - `WScript.Sleep(500)` pauses the script for 500 milliseconds (0.5 seconds) to avoid excessive polling of `IsBusy`. ``` -------------------------------- ### Example import.types File Source: https://www.amibroker.com/guide/d_ascii.html An example of an import.types file showing various ASCII data formats and their associated filters and definition files. ```plaintext Default ASCII (*.*)|*.*|default.format Yahoo's CSV (*.csv)|*.csv|yahoo.format Metastock ASCII (*.mst)|*.mst|metastock.format Omega SC ASCII (*.txt)|*.txt|omega.format S-Files (s*.*)|s*.*|sfile.format C-Files (c*.*)|c*.*|cfile.format Sharenet DAT (*.dat)|*.dat|dat.format ``` -------------------------------- ### Combined Example Usage Source: https://www.amibroker.com/guide/afl/say.html This example demonstrates the practical application of the SayOnce and SayNotTooOften helper functions. It shows how to speak the current instrument's name once and how to ensure a message is not spoken more often than every 60 seconds. ```afl SayOnce("Testing " + Name() ); SayNotTooOften( "Say not more often than every 60 seconds", 60 ); ``` -------------------------------- ### Customizable Indicator Example with Param Functions Source: https://www.amibroker.com/guide/h_dragdrop.html This example demonstrates how to use ParamField, ParamColor, ParamStyle, and ParamToggle to create a customizable indicator. Settings can be adjusted directly from the Parameters dialog. ```afl **Buy** = Cross(MACD(), Signal() ); **Sell** = Cross(Signal(), MACD() ); pricefield = ParamField("Price Field", 2); Color = ParamColor("color",**colorRed**); style = ParamStyle("style",**styleLine**,maskAll); arrows = ParamToggle("Display arrows", "No|Yes",0); Plot(pricefield,"My Indicator",Color,style); **if**(arrows) {   PlotShapes(**Buy*****shapeUpArrow**+**Sell*****shapeDownArrow**,IIf(**Buy**,**colorGreen**,**colorRed**) ); } ``` -------------------------------- ### AmiBroker Flip Function Example Source: https://www.amibroker.com/guide/afl/flip.html This example demonstrates how to use the Flip function to revert the process of ExRem, allowing multiple signals to be considered again. Ensure 'buy' and 'sell' arrays are properly defined before use. ```afl buy = ExRem( buy, sell ); buy = Flip( buy, sell ); // this essentially reverts the process of ExRem - multiple signals are back again ``` -------------------------------- ### PlotVAPOverlayA - Complex Example with Parameters Source: https://www.amibroker.com/guide/afl/plotvapoverlaya.html A more complex example demonstrating how to use PlotVAPOverlayA with various customizable parameters. This includes setting lines, width, color, and style (fill/lines, on top/behind) using Param functions for user control. ```afl _SECTION_BEGIN("Price"); SetChartOptions(0,chartShowArrows|chartShowDates); _N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) )); Plot( C, "Close", ParamColor("Color", colorBlack ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() ); _SECTION_END(); _SECTION_BEGIN("VAP"); segments = IIf( Interval() < inDaily, Day(), Month() ); segments = segments != Ref( segments , -1 ); PlotVAPOverlayA( segments , Param("Lines", 300, 100, 1000, 1 ), Param("Width", 80, 1, 100, 1 ), ParamColor("Color", colorGold ), ParamToggle("Side", "Left|Right" ) | 2 * ParamToggle("Style", "Fill|Lines", 0) | 4*ParamToggle("Z-order", "On top|Behind", 1 ) ); Plot(segments, "", colorLightGrey, styleHistogram | styleOwnScale ); _SECTION_END(); ``` -------------------------------- ### Select Stock Object Example - AmiBroker AFL Source: https://www.amibroker.com/guide/afl/gfxselectstockobject.html This example demonstrates how to select a hollow brush using GfxSelectStockObject(5) and then draw a circle with it. It also shows the preceding selection of a pen using GfxSelectPen. ```afl GfxSelectPen( colorOrange, 4 ); GfxSelectStockObject( 5 ); // hollow brush GfxCircle(100, 100, 20 ); ``` -------------------------------- ### AmiBroker GFX Overlay Sample with Pixel Conversion Source: https://www.amibroker.com/guide/afl/status.html This example demonstrates how to use Status() to get chart dimensions and axis limits for low-level graphic overlays. It includes functions to convert bar indices and data values to pixel coordinates for custom drawing. ```afl _SECTION_BEGIN("GfxOverlaySampleNew"); function GetVisibleBarCount() { lvb = Status("lastvisiblebar"); fvb = Status("firstvisiblebar"); return Min( lvb - fvb, BarCount - fvb ); } function GfxConvertBarToPixelX( bar ) { lvb = Status("lastvisiblebar"); fvb = Status("firstvisiblebar"); pxchartleft = Status("pxchartleft"); pxchartwidth = Status("pxchartwidth"); return pxchartleft + bar * pxchartwidth / ( lvb - fvb + 1 ); } function GfxConvertValueToPixelY( Value ) { local Miny, Maxy, pxchartbottom, pxchartheight; Miny = Status("axisminy"); Maxy = Status("axismaxy"); pxchartbottom = Status("pxchartbottom"); pxchartheight = Status("pxchartheight"); return pxchartbottom - floor( 0.5 + ( Value - Miny ) * pxchartheight/ ( Maxy - Miny ) ); } Plot( C, "Price", colorBlack, styleHistogram ); GfxSetOverlayMode(0); GfxSelectSolidBrush( colorRed ); GfxSelectPen( colorRed ); AllVisibleBars = GetVisibleBarCount(); fvb = Status("firstvisiblebar"); for( i = 0; i < AllVisibleBars ; i++ ) { x = GfxConvertBarToPixelX( i ); y = GfxConvertValueToPixelY( C[ i + fvb ] ); GfxRectangle( x-1, y-1, x + 2, y+1 ); } //SetChartBkGradientFill( ColorRGB(200,200,200), ColorRGB( 255,255,255) ); _SECTION_END(); ``` -------------------------------- ### Original Chart Formula Example Source: https://www.amibroker.com/guide/h_dragdrop.html This is an example of a standard chart formula before being processed by AmiBroker's drag-and-drop mechanism. ```plaintext P = ParamField("Price field",-1); Periods = Param("Periods", 15, 2, 200, 1, 10 ); Plot( MA( P, Periods ), _DEFAULT_NAME(), ParamColor( "Color", colorCycle ), ParamStyle("Style") ); ``` -------------------------------- ### S-File Data Format Example Source: https://www.amibroker.com/guide/d_ascii.html Example of data structure for S-files, highlighting useful fields like date, ticker, close price, and turnover. ```plaintext 0,29-02-00,12:05,MIDWIG,1069.1,,,+1.2,336002000, 0,29-02-00,12:05,NIF,48.6,,,+0.8,1763000, 0,29-02-00,12:05,WIG20,2300.3,,,+1.1,336002000, 0,29-02-00,12:05,WIG,21536.8,,,+0.2,336002000, 0,29-02-00,12:05,WIRR,2732.8,,,+1.6,16373000, 1,29-02-00,12:05,AGORA,144.00,,,+4.7,15802000, 1,29-02-00,12:05,AGROS,40.00,nk,72,+5.0,840000, 1,29-02-00,12:05,AMERBANK,28.00,,,+3.7,22000, 1,29-02-00,12:05,AMICA,41.50,nk,99,+2.2,564000, ``` -------------------------------- ### GetExtraData Example: Briefing Text Source: https://www.amibroker.com/guide/afl/getextradata.html Retrieves the briefing text for a symbol. This example demonstrates fetching string data. ```AFL GetExtraData("briefing"); /* gives briefing text (STRING) */ ``` -------------------------------- ### Example: Creating a Custom Index with AddToComposite Source: https://www.amibroker.com/guide/a_addtocomposite.html This example shows how to create a custom index by adding the Close price of multiple securities to the 'C' field and a count of 1 to the 'I' field of a composite ticker '~MyIndex'. The average price is then calculated using Foreign calls. ```afl /* AddToComposite statements are for analysis -> Scan */ /* add Close price to our index OHLC fields */ AddToComposite(Close, "~MyIndex", "X" ); /* add one to open interest field (we use this field as a counter) */ AddToComposite( 1, "~MyIndex", "I" ); buy = 0; // required by scan mode /* this part is for Indicator */ graph0 = Foreign( "~MyIndex", "C" )/Foreign( "~MyIndex", "I" ); ``` -------------------------------- ### Printf with WriteIf Example Source: https://www.amibroker.com/guide/afl/writeif.html This example shows how to use Printf to display the string returned by WriteIf within a function. This is necessary because WriteIf, when called inside a function, operates at a local scope and its return value needs explicit printing. ```afl function comment(indicator) { printf( "\nComment...\n" ); printf( WriteIf(1, "TrueText", "FalseText") ); printf( WriteVal(indicator) + "\n" ); } ``` -------------------------------- ### Report Time Since System Start with GetPerformanceCounter Source: https://www.amibroker.com/guide/afl/getperformancecounter.html Retrieves the time elapsed since the system started and formats it into days, hours, minutes, seconds, and milliseconds. This demonstrates using the counter without resetting it. ```AFL elapsed=GetPerformanceCounter(); StrFormat("Time since system start %.0f days, %.0f hours, %.0f minutes, %.0f seconds, %.0f milliseconds ", floor(elapsed/(24*60*60*1000)), floor( elapsed/(60*60*1000) ) % 24, floor( elapsed/(60*1000) ) % 60, floor( elapsed/1000 ) % 60, elapsed % 1000 ); ``` -------------------------------- ### PlotVAPOverlayA - Simplest Example Source: https://www.amibroker.com/guide/afl/plotvapoverlaya.html This is the simplest example of using PlotVAPOverlayA. It plots daily or monthly VAP segments based on the current display interval. Ensure the 'segments' array is correctly formatted with alternating 0s and 1s. ```afl Plot( C, "Close", colorBlack, styleCandle ); segments = IIf( Interval() < inDaily, Day(), Month() ); segments = segments != Ref( segments , -1 ); PlotVAPOverlayA( segments ); ``` -------------------------------- ### ASCII Importer Definition File Example Source: https://www.amibroker.com/guide/d_ascii.html An example of an ASCII importer definition file demonstrating various commands for parsing tick data, including skip lines, separator, continuous import, grouping, auto-add, debug, and tick mode. ```AFL $FORMAT Ticker, Skip, Date_YMD, Time, Open, High, Low, Close, Volume $SKIPLINES 1 $SEPARATOR , $CONT 1 $GROUP 255 $AUTOADD 1 $DEBUG 1 $TICKMODE 1 ``` -------------------------------- ### Get Start and End Values and Calculate Percentage Change Source: https://www.amibroker.com/guide/afl/beginvalue.html This snippet demonstrates how to use BeginValue() and EndValue() to get the start and end values of the DateTime and Close arrays. It then calculates and displays the percentage change of the closing price over the selected range. ```afl WriteVal( BeginValue( DateTime() ), formatDateTime ); WriteVal( EndValue( DateTime() ), formatDateTime ); "Precentage change of close is " + WriteVal( 100 * (EndValue( Close ) - BeginValue( Close ))/BeginValue( Close ) ) + "%" ``` -------------------------------- ### Example: N-Volume Bar Usage Source: https://www.amibroker.com/guide/afl/timeframemode.html Demonstrates setting up 50,000 share bars using TimeFrameMode and TimeFrameSet, followed by custom processing and restoring the original time frame. ```afl TimeFrameMode( 2 ); TimeFrameSet( 50000 ); // 50'000 share bars.. //...do something ... TimeFrameRestore(); ``` -------------------------------- ### Full GUI Control Example with Event Handling Source: https://www.amibroker.com/guide/h_gui.html Demonstrates creating a slider and buttons, initializing slider properties, and handling button clicks to enable, disable, show, or hide the slider. This example also shows how to update the chart title with the slider's current value. ```afl // control identifiers idSlider = 1; idEnable = 2; idDisable = 3; idShow = 4; idHide = 5; **function** CreateGUI() {      **if** ( GuiSlider( idSlider, 10, 30, 200, 30, **notifyEditChange** ) == guiNew )      {         // init values on control creation         GuiSetValue( idSlider, 5 );         GuiSetRange( idSlider, 1, 100, 0.1, 100 );      }      GuiButton( "enable", idEnable, 10, 60, 100, 30, **notifyClicked** );      GuiButton( "disable", idDisable, 110, 60, 100, 30, **notifyClicked** );      GuiButton( "show", idShow, 10, 90, 100, 30, **notifyClicked** );      GuiButton( "hide", idHide, 110, 90, 100, 30, **notifyClicked** ); } **function** HandleEvents() {     **for**( n = 0; id = GuiGetEvent( n, 0 ); n++ )     {        **switch** ( id )        {           **case** idEnable:              GuiEnable( idSlider, **True** );              **break**;           **case** idDisable:              GuiEnable( idSlider, **False** );              **break**;           **case** idShow:              GuiSetVisible( idSlider, **True** );              **break**;           **case** idHide:              GuiSetVisible( idSlider, **False** );              **break**;        }     } } CreateGUI(); HandleEvents(); **Title** = "Value = " + GuiGetValue( idSlider ); ``` -------------------------------- ### Get Day of Month in AmiBroker AFL Source: https://www.amibroker.com/guide/afl/day.html Use the Day() function to get the current day of the month. This example demonstrates conditional logic based on whether the day is within the first three days of the month. ```afl writeif( day() < 3, "Beginning of the month", "The rest of the month" ); ``` -------------------------------- ### Get ASCII Code of Character with Asc() Source: https://www.amibroker.com/guide/afl/asc.html Use Asc() to get the ASCII code of a character. If the position is not specified, the first character is used. Negative positions count from the end of the string. This example shows how to display 'B' for Buy signals and 'S' for Sell signals. ```afl **Buy** = Cross(MACD(),Signal()); **Sell** = Cross(Signal(),MACD()); **Filter** = **Buy** **OR** **Sell**; AddColumn( IIf( **Buy**, Asc("B"), Asc("S")), "Signal", **formatChar** ); ``` -------------------------------- ### PriceVolDistribution Demo Source: https://www.amibroker.com/guide/afl/pricevoldistribution.html This example demonstrates re-implementing a Volume At Price (VAP) overlay using PriceVolDistribution and low-level graphics. It calculates the distribution, then draws lines representing relative volume at different price levels. Ensure necessary variables like H, L, V, colorRed, C, colorDefault, and styleBar are defined or imported. ```afl // a demo showing // re-implementation of VAP overlay using // PriceVolDistribution and low-level graphics bi = BarIndex(); fvb = FirstVisibleValue( bi ); lvb = LastVisibleValue( bi ); mx = PriceVolDistribution( H, L, V, 100, False, fvb, lvb ); GfxSetCoordsMode( 1 ); GfxSelectPen( colorRed ); bins = MxGetSize( mx, 0 ); for( i = 0; i < bins; i++ ) { price = mx[ i ][ 0 ]; // price level relvolume = mx[ i ][ 1 ]; // relative volume 0..1 relbar = relvolume * (lvb-fvb+1); GfxMoveTo( fvb, price ); GfxLineTo( fvb + relbar, price ); } Plot( C, "Price", colorDefault, styleBar ); if( ParamToggle("BuildinVAP", "No|Yes") ) PlotVAPOverlay( 100, 100, colorGreen, 2 ); ``` -------------------------------- ### Normal Ranking Mode Example Source: https://www.amibroker.com/guide/h_ranking.html Performs normal ranking where ties are numbered equally. Ranks start from one. Use this when the `toprank` argument is zero. ```afl symlist = "C,CAT,DD,GE,IBM,INTC,MSFT"; // delete static variables StaticVarRemove( "ItemScore*" ); // fill input static arrays **for** ( i = 0; ( sym = StrExtract( symlist, i ) ) != ""; i++ ) {     SetForeign( sym );      Value = ROC( **C**, 10 );     RestorePriceArrays();     StaticVarSet( "ItemScore" + sym, Value ); } // perform ranking StaticVarGenerateRanks( "rank", "ItemScore", 0, 1224 ); // normal rank mode // read ranking **for** ( i = 0; ( sym = StrExtract( symlist, i ) ) != ""; i++ ) {     Plot( StaticVarGet( "RankItemScore" + sym ), sym, **colorCustom10** + i ); } ``` -------------------------------- ### Calculate Cumulative Sum with Cum() Source: https://www.amibroker.com/guide/afl/cum.html Calculates a cumulative sum of an array. This example shows how to get a cumulative sum of 1 for each bar, equivalent to the bar number. ```afl cum( 1 ) ``` -------------------------------- ### Execute a file with ShellExecute Source: https://www.amibroker.com/guide/afl/shellexecute.html Use ShellExecute to open a file or run an executable. This example demonstrates running Notepad. ```afl ShellExecute("notepad.exe", "", "" ); ``` -------------------------------- ### Interactive GUI Control Sample with Mouse Events Source: https://www.amibroker.com/guide/afl/getcursormousebuttons.html This comprehensive example demonstrates drawing buttons, handling various mouse clicks and states (left, right, middle, hover), and implementing event callbacks using AmiBroker's GFX functions and mouse event handlers. Requires AmiBroker version 5.04 or higher. ```AFL /////////////////////////////////////////////////// // Low-level graphic + Interactive GUI control sample // This example shows: //  1. how to draw "buttons" //  2. how to handle mouse clicks //  3. how to implement event call-backs /////////////////////////////////////////////////// Version( 5.04 ); // requires 5.04 or higher //////////////////////////////////////////////////// // Part 1: DRAWING TABLE OF BUTTONS ////////////////////////////////////////////////// GfxSetOverlayMode( 2 ); // formatted text output sample via low-level gfx // functions CellHeight = 20; CellWidth = 100; GfxSelectFont( "Tahoma", CellHeight/2 ); GfxSetBkMode( 1 ); **function** PrintInCell( string, row, Col ) { GfxDrawText( string, Col * CellWidth, row * CellHeight, (Col + 1 ) * CellWidth, (row + 1 ) * CellHeight, 0 ); } GfxSelectPen( **colorBlue** ); **for**( i = 0; i < 10 && i < **BarCount**; i++ ) { **for**( k = 0; k < 5; k++ ) {    PrintInCell( "Button " + i + "," + k, i, k ); } GfxMoveTo( 0, i * CellHeight ); GfxLineTo( 5 * CellWidth, i * CellHeight ); } GfxMoveTo( 0, i * CellHeight ); GfxLineTo( 5 * CellWidth, i * CellHeight ); **for**( Col = 1; Col < 6; Col++ ) { GfxMoveTo( Col * CellWidth, 0); GfxLineTo( Col * CellWidth, 10 * CellHeight ); } ///////////////////////////////////////////////////////// // Part 2: MOUSE BUTTON CALL BACKS ////////////////////////////////////////////////////////// **Title**=""; **function** DrawButton( px, py, Clr1, Clr2, text ) {      Col = floor( px / CellWidth );      Row = floor( py / CellHeight );          GfxGradientRect( Col * CellWidth, row * CellHeight, (Col + 1 ) * CellWidth, (row + 1 ) * CellHeight,               Clr1, Clr2 );      PrintInCell( text + " " + row + "," + Col, row, Col ); } **function** OnLMouseButton(x, y, px, py) {     _TRACE("LButton x = " + DateTimeToStr( x ) + " y = " + y );      DrawButton( px, py, ColorHSB( 50, 255, 255 ), ColorHSB( 90, 255, 255 ), "just clicked" ); } **function** OnRMouseButton(x, y, px, py) {     _TRACE("RButton x = " + DateTimeToStr( x ) + " y = " + y ); } **function** OnMMouseButton(x, y, px, py) {     _TRACE("MButton x = " + DateTimeToStr( x ) + " y = " + y ); } **function** OnHoverMouse(x, y, px, py) {     _TRACE("LButton x = " + DateTimeToStr( x ) + " y = " + y );        DrawButton( px, py, ColorRGB( 230, 230, 230 ), ColorRGB( 255, 255, 255 ), "mouse over" ); } **function** OnLButtonIsDown(x, y, px, py) {     _TRACE("LButton x = " + DateTimeToStr( x ) + " y = " + y );        DrawButton( px, py, ColorHSB( 190, 255, 255 ), ColorHSB( 210, 255, 255 ), "down" ); } ///////////////////////////////////////////////////////// // Part 3: GENERAL PURPOSE EVENT HANDLER (reusable! - may be put into "include" file) //////////////////////////////////////////////////////// **function** EventHandler() { **local** b, x, y, px, py; b = GetCursorMouseButtons(); // retrieve co-ordinates in date/value units x = GetCursorXPosition(0); y = GetCursorYPosition(0); // retrieve co-ordinates in pixel units px = GetCursorXPosition(1); ``` -------------------------------- ### Composite Creation using StaticVarRemove Source: https://www.amibroker.com/guide/whatsnew.html Example of how to remove any earlier composite values before creating a new one using StaticVarRemove, typically used at the start of processing. ```AFL if( status("stocknum") == 0 ) { // remove any earlier composite values StaticVarRemove("~Composite"); } ``` -------------------------------- ### SetCustomBacktestProc Example Source: https://www.amibroker.com/guide/afl/setcustombacktestproc.html Use this function to specify an external AFL file for custom backtesting. Ensure the specified file path is correct relative to your AmiBroker installation. ```afl SetCustomBacktestProc( "Formulas\MyCustomBacktest.afl", **True** ); ``` -------------------------------- ### Run AmiBroker Analysis Project and Export Results (JScript) Source: https://www.amibroker.com/guide/objects.html This JScript example demonstrates opening an analysis project, running a backtest asynchronously, waiting for completion using the IsBusy flag, exporting the results, and closing the analysis document. Ensure the analysis project file (.apx) exists at the specified path. ```javascript AB = new ActiveXObject( "Broker.Application" ); try { NewA = AB.AnalysisDocs.Open( "C:\\analysis1.apx" ); // opens previously saved analysis project file // NewA represents the instance of New Analysis document/window if ( NewA ) { NewA.Run( 2 ); // start backtest asynchronously while ( NewA.IsBusy ) WScript.Sleep( 500 ); // check IsBusy every 0.5 second NewA.Export( "test.html" ); // export result list to HTML file WScript.echo( "Completed" ); NewA.Close(); // close new Analysis } } catch ( err ) { WScript.echo( "Exception: " + err.message ); // display error that may occur } ``` -------------------------------- ### Optimize with Custom Array Index in AmiBroker AFL Source: https://www.amibroker.com/guide/afl/optimize.html This example shows how to use the Optimize function to get an index for a custom array, such as Fibonacci numbers. Ensure the index is within the bounds of the array. ```afl FB[0] = 0.0; FB[1] = 23.6; FB[2] = 38.2; FB[3] = 50.0; FB[4] = 61.8; FB[5] = 100; FB[6] = 161.8; FB[7] = 261.8; FB[8] = 423.6; FBindex = Optimize("FBindex",0,0,8,1); FibNum = FB[FBindex]; ``` -------------------------------- ### Example of Setting Multiple Options Source: https://www.amibroker.com/guide/afl/setoption.html Demonstrates setting initial equity, allowing position shrinking, and limiting the maximum number of open positions. Note that changing options on a per-symbol basis can distort composite results. ```AFL SetOption("InitialEquity", 5000 ); SetOption("AllowPositionShrinking", True ); SetOption("MaxOpenPositions", 5 ); PositionSize = -100/5; ``` -------------------------------- ### Get Fundamental Data for a Symbol (AFL) Source: https://www.amibroker.com/guide/afl/getfndataforeign.html Use GetFnDataForeign to retrieve fundamental data like EPS for a specific symbol. This example shows how to calculate and display current and estimated P/E ratios for MSFT. ```afl AddColumn( Foreign( "MSFT", "C" ) / GetFnDataForeign( "EPS", "MSFT" ) , "MSFT Current P/E ratio" ); AddColumn( Foreign( "MSFT", "C" ) / GetFnDataForeign( "EPSEstNextYear", "MSFT" ) , "MSFT Est. Next Year P/E ratio" ); Filter = Status("lastbarinrange"); ``` -------------------------------- ### Basic $FORMAT Examples Source: https://www.amibroker.com/guide/d_ascii.html Illustrates different ways to use the $FORMAT command to define how data fields like Ticker, Date, Open, High, Low, Close, and Volume are parsed from an ASCII file. ```AmiBroker Formula Language $FORMAT TICKER DATE_MDY OPEN HIGH LOW CLOSE VOLUME ``` ```AmiBroker Formula Language $FORMAT TICKER, DATE_INT, CLOSE, VOLUME ``` ```AmiBroker Formula Language $FORMAT SKIP, TICKER, SKIP, SKIP, DATE_INT, OPEN, HIGH, LOW, CLOSE, TURNOVER ``` -------------------------------- ### Count Substring Occurrences with StrCount Source: https://www.amibroker.com/guide/afl/strcount.html Use StrCount to determine the number of times a substring appears in a string. This example counts the number of commas in a comma-separated list, adding 1 to get the total number of items. ```afl tickers = "AAPL,MSFT,INTC"; numtickers = 1 + StrCount( tickers, "," ); ``` -------------------------------- ### Import GICS Codes with $GICS and $FORMAT Source: https://www.amibroker.com/guide/d_ascii.html This example demonstrates how to import GICS (Global Industry Category System) codes for symbols using the $FORMAT command in conjunction with the $GICS argument. It also shows the necessary import settings like $OVERWRITE, $SEPARATOR, $CONT, $GROUP, and $AUTOADD. ```AmiBroker Formula Language $FORMAT Ticker,FullName,GICS $OVERWRITE 1 $SEPARATOR , $CONT 1 $GROUP 255 $AUTOADD 1 $NOQUOTES 1 ``` -------------------------------- ### Get Rectangular Block from Matrix using MxGetBlock Source: https://www.amibroker.com/guide/afl/mxgetblock.html Demonstrates how to use MxGetBlock to extract a block of data from a matrix. The first example retrieves the entire matrix as a regular array, while the second retrieves a smaller submatrix. ```afl z = Matrix( 2, 20, 0 ); // first row z = MxSetBlock( z, 0, 0, 0, 19, Close ); // second row z = MxSetBlock( z, 1, 1, 0, 19, RSI( 5 ) ); printf("Matrix z "); printf( MxToString( z ) ); x = MxGetBlock( z, 0, 1, 0, 19, True ); printf("Items are now in regular array (data series): " ); for( i = 0; i < 20; i++ ) printf( NumToStr( x[ i ] ) + " " ); z = MxGetBlock( z, 0, 1, 0, 1 ); // retrieve upper 2x2 submatrix printf("Upper submatrix z "); printf( MxToString( z ) ); ``` -------------------------------- ### Create and Use a Map in AFL Source: https://www.amibroker.com/guide/afl/mapcreate.html Demonstrates how to create a map with a specified hash size, assign values using string keys, and access values by key. It also shows how to check for the existence of a key and print its associated value or a 'not found' message. ```afl // Map creation // larger hash table size improves performance should be prime number larger than number of elements expected m = MapCreate( 997 ); // assigning values m["MSFT"] = 1; m["NVDA"] = 2; m["CSCO"] = 3; // accessing value by key value = m[ Name() ]; // using function return value as a key value2 = m[ "MSFT" ]; // literal key // checking for key existence value = m[ Name() ]; if (IsNull(value)) { printf("Key not found in Map"); } else { printf("%g", value); } ``` -------------------------------- ### Get Current Bar's Hour and Construct Time Source: https://www.amibroker.com/guide/afl/hour.html This example demonstrates how to use the Hour() function along with Minute() and Second() to create a numerical representation of the current time. This is useful for time-based analysis or logging. ```afl Hour()*10000 + Minute() * 100 + Second() ``` -------------------------------- ### Compress and Expand Sparse Data with SparseCompress Source: https://www.amibroker.com/guide/afl/sparsecompress.html This example demonstrates how to use SparseCompress to extract and compress data from even months, then calculate a moving average and expand it back. It shows a practical application of sparse data manipulation. ```afl only_when = ( Month() % 2 ) == 0; // even months only x = SparseCompress( only_when, **Close** ); // compact sparse data y = MA( x, 10 ); // regular calculation y = SparseExpand( only_when, y ); // expand sparse data Plot( **C**, "Price", **colorDefault**, **styleBar** ); Plot( y, "Sparse MA from even months", **colorRed** ); ``` -------------------------------- ### Get Last OS Error After Internet Connection Failure Source: https://www.amibroker.com/guide/afl/getlastoserror.html This example shows how to use GetLastOSError to diagnose issues when establishing an internet connection. It checks the result of InternetOpenUrl and displays the OS error if the connection fails. ```afl // Example 2: ih = InternetOpenUrl("http://non_existing_host.com" ); if( ! ih ) { printf("Internet connection can not be open because: %s", GetLastOSError() ); } ``` -------------------------------- ### Get Last OS Error After File Open Failure Source: https://www.amibroker.com/guide/afl/getlastoserror.html This example demonstrates how to use GetLastOSError to report why a file could not be opened. It checks the return value of fopen and prints the error message if the file handle is invalid. ```afl // Example 1: fh = fopen("non_existing_file.txt", "r" ); if( ! fh ) { printf("File can not be open because: %s", GetLastOSError() ); } ``` -------------------------------- ### Get ICB Category Information with IcbID Source: https://www.amibroker.com/guide/afl/icbid.html Use IcbID with different modes to retrieve the ICB code, category name, or both for the current symbol. The example also demonstrates iterating through potential ICB codes using StrFormat and checking their existence with InIcb. ```afl printf( "ICB(0) = " + IcbID( 0 ) ); printf( "ICB(1) = " + IcbID( 1 ) ); printf( "ICB(2) = " + IcbID( 2 ) ); **for**( i = 10; i < 90; i+= 1 ) { ICB_code = StrFormat("%02.0f", i ); printf("In ICB '"+ ICB_code + "' = %gn", InIcb( ICB_code ) ); } ``` -------------------------------- ### Using SetForeign with Equity Function for Backtesting Source: https://www.amibroker.com/guide/afl/setforeign.html This example demonstrates using SetForeign with the Equity function for backtesting on a foreign security. Set the fixup and tradeprices parameters to True to include trade prices and fill data holes. Remember to match the RestorePriceArrays() parameter with the SetForeign() parameter used. ```afl SetForeign("MSFT", True, True ); Buy = Cross( MACD(), Signal()); Sell = Cross( Signal(), MACD()); e = Equity(); // backtest on MSFT RestorePriceArrays( True ); // <- should match parameter used in SetForeign ``` -------------------------------- ### Get Fundamental Data (EPS, P/E Ratio) Source: https://www.amibroker.com/guide/afl/getfndata.html Use GetFnData to retrieve fundamental data like Earnings Per Share (EPS) or calculate P/E ratios. Ensure the 'field' parameter is a valid fundamental data identifier. This example calculates current and estimated next year P/E ratios. ```afl AddColumn( Close / GetFnData( "EPS" ) , "Current P/E ratio" ); AddColumn( Close / GetFnData( "EPSEstNextYear" ) , "Est. Next Year P/E ratio" ); Filter = Status("lastbarinrange"); ``` -------------------------------- ### SetPositionSize: Scaling Out Example Source: https://www.amibroker.com/guide/afl/setpositionsize.html Illustrates liquidating 50% of a position using spsPercentOfPosition when the Buy signal indicates a scale-out. ```afl SetPositionSize( 50, spsPercentOfPosition * ( Buy == sigScaleOut ) ); ``` -------------------------------- ### Get Market ID or Name using MarketID() Source: https://www.amibroker.com/guide/afl/marketid.html Use MarketID() to get the numerical market ID (default) or MarketID(1) to get the market name. This is useful for filtering or displaying market-specific information. ```afl Filter = MarketID() == 7 OR MarketID() == 9; AddTextColumn( MarketID( 1 ), "Market name" ); ``` -------------------------------- ### Run Simple Backtest using ActiveXObject (JScript) Source: https://www.amibroker.com/guide/objects.html This example shows how to automate a simple backtest using AmiBroker's ActiveXObject. It opens an analysis project, runs the backtest, exports results, and handles potential exceptions. ```javascript AB = new ActiveXObject( "Broker.Application" ); try { NewA = AB.AnalysisDocs.Open( "C:\\analysis1.apx" ); // NewA represents the instance of New Analysis document/window if ( NewA ) { NewA.Run( 2 ); while ( NewA.IsBusy ) WScript.Sleep( 500 ); NewA.Export( "test.html" ); WScript.echo( "Completed" ); NewA.Close(); } } catch ( err ) { WScript.echo( "Exception: " + err.message ); ``` -------------------------------- ### Get Sector ID and Name using SectorID() Source: https://www.amibroker.com/guide/afl/sectorid.html Use SectorID() with mode 0 (default) to get the numerical sector ID for filtering. Use mode 1 to get the sector name for display purposes. ```afl Filter = SectorID() == 7 OR SectorID() == 9; AddTextColumn( SectorID( 1 ), "Sector name" ); ``` -------------------------------- ### Low-Level GFX Demo: Color Wheel, Animated Text, Chord, Polygon Source: https://www.amibroker.com/guide/h_lowlevelgfx.html Demonstrates various low-level GFX capabilities including drawing a color wheel with animated lines, displaying text with dynamic positioning, drawing a chord, and a polygon. Uses GfxSetOverlayMode(1) for background GFX, ColorHSB, GfxSelectPen, GfxLineTo, GfxTextOut, GfxChord, and GfxPolygon. ```AFL // overlay mode = 1 means that // Low-level gfx stuff should come in background GfxSetOverlayMode(1); Plot(**C**, "Close", **colorBlack**, **styleCandle** ); PI = 3.1415926; k = (GetPerformanceCounter()/100)%256; **for**( i = 0; i < 256; i++ ) {    x = 2 * PI * i / 256;      GfxMoveTo( 100+k, 100 );   GfxSelectPen( ColorHSB( ( i + k ) % 256, 255, 255 ), 4 );   GfxLineTo( 100 +k+ 100 * sin( x  ), 100 + 100 * cos( x  ) ); } GfxSelectFont("Tahoma", 20, 700 ); GfxSetBkMode(1); GfxSetTextColor(**colorBrown**); GfxTextOut("Testing graphic capabilites", 20, 128-k/2 ); GfxSelectPen( **colorRed** ); GfxSelectSolidBrush( **colorBlue** ); GfxChord(100,0,200,100,150,0,200,50); //GfxPie(100,0,200,100,150,0,200,50); GfxSelectPen( **colorGreen**, 2 ); GfxSelectSolidBrush( **colorYellow** ); GfxPolygon(250,200,200,200,250,0,200,50); RequestTimedRefresh(1); ``` -------------------------------- ### Matrix Initialization and Element-wise Operations Source: https://www.amibroker.com/guide/a_language.html Demonstrates creating matrices, performing element-wise arithmetic operations between matrices of the same dimensions, and accessing individual elements. Ensure matrices have identical dimensions for arithmetic operations. ```AmiBroker Formula Language x = Matrix( 5, 6, 9 ); // matrix 5 rows 6 columns, initial value 9 y = Matrix( 5, 6, 10 ); // matrix 5 rows 6 columns, initial value 10 z = y - x; // will give you matrix 5 rows and 6 columns filled with elements holding value 1 (difference between 10 and 9). ``` -------------------------------- ### AFL Arithmetic Operators Examples Source: https://www.amibroker.com/guide/a_language.html Shows examples of using arithmetic operators (+, -, *, /) in AFL formulas for calculations involving price data. ```afl var1 = ( H + L ) / 2; var2 = MA(C,10)-MA(C,20) / (H + L + C); var3 = Close + ((1.02 * High)-High); ``` -------------------------------- ### Example: Display Interval in Seconds Source: https://www.amibroker.com/guide/afl/interval.html Demonstrates how to use the Interval() function and WriteVal() to display the bar interval in seconds as a string. ```afl "Interval in seconds " + WriteVal( Interval() ); ``` -------------------------------- ### AmiBroker FFT Example for Price Pattern Detection Source: https://www.amibroker.com/guide/afl/fft.html This example shows how to use the FFT function to analyze price data, de-trend it, and then plot the amplitude and dominant cycle. It includes parameters for FFT length, dominant cycle selection, and an option to skip the DC component. ```afl SetBarsRequired(100000,100000); Len = Param("FFT Length", 1024, 64, 10000, 10 ); Len = Min( Len, BarCount ); x = BarIndex(); x1 = x - BarCount + Len; input = C; a = LastValue( LinRegIntercept( input, Len - 1 ) ); b = LastValue( LinRegSlope( input, Len - 1 ) ); Lr = a + b * x1; data = input - Lr;// de-trending ffc = FFT(data,Len); for( i = 0; i < Len - 1; i = i + 2 ) { amp[ i ] = amp[ i + 1] = sqrt(ffc[ i ]^ 2 + ffc[ i + 1]^2); phase[ i ] = phase[ i + 1] = atan2( ffc[ i + 1], ffc[ i ] ); } auto = ParamToggle("Auto dominant cycle", "No|Yes", 1 ); sbar = Param( "Which FFT bin", 1, 0, 50 ); skipbin1 = ParamToggle("Skip 1st FFT bin", "No|Yes", 1 ); if( auto ) { sbar = int( LastValue(ValueWhen( amp == LastValue(Highest( IIf( skipbin1 AND x < 4, 0 , amp ) )), x / 2 )) ); } fv = Status("firstvisiblebar"); thisbar = Ref( int(x/2) == sbar, -fv); Plot( Ref(amp,-fv), "amplitude (bin " + Ref( int(x/2), -fv ) +")", IIf( thisbar, colorRed, colorBlack ),styleArea); Plot( IIf( BarCount - BarIndex() < Len, data, Null ) , "de-trended input ("+Len+" bars)", colorOrange, styleLeftAxisScale ); Plot( cos( phase[ sbar * 2 ] + (sbar) * x1 * 2 * 3.1415926 / Len ), " dominant cycle "+ Len/(sbar) + "(" + sbar + " bin) bars", colorBlue, styleOwnScale ); GraphZOrder=1; GraphXSpace = 10; ``` -------------------------------- ### WriteIf Basic Usage Example Source: https://www.amibroker.com/guide/afl/writeif.html This example demonstrates how to use WriteIf to conditionally display text based on whether the closing price is above the 200-period moving average. ```afl writeif( c > mov(c,200,s), "The close is above the 200-period moving average.","The close is below the 200-period moving average." ) ``` -------------------------------- ### GetExtraData Example: Quotes Plus Relative Strength Source: https://www.amibroker.com/guide/afl/getextradata.html Retrieves the Quotes Plus relative strength data for a symbol. This example demonstrates fetching array data. ```AFL graph0 = GetExtraData("QRS"); /*gives Quotes Plus relative strength (ARRAY) */ ``` -------------------------------- ### Expand Compressed Weekly MA to Daily Chart Source: https://www.amibroker.com/guide/afl/timeframeexpand.html This example demonstrates how to compress closing prices to a weekly timeframe, calculate a 14-period moving average on the compressed weekly data, and then expand it back to the daily timeframe for plotting. It shows the difference between a daily MA and a weekly MA displayed on a daily chart. ```afl wc = TimeFrameCompress( Close, inWeekly ); /* now the time frame is still unchanged (say daily) and our MA will operate on daily data */ dailyma = MA( C, 14 ); /* but if we call MA on compressed array, it will give MA from other time frame */ weeklyma = MA( wc, 14 ); // note that argument is time-compressed array Plot( dailyma, "DailyMA", colorRed ); weeklyma = TimeFrameExpand( weeklyma, inWeekly ); // expand for display Plot( weeklyma, "WeeklyMA", colorBlue ); ```