PureBytes Links
Trading Reference Links
|
Thank you Tomasz, the daily
plot in intraday databse working fine now.
Cheers,Graham<A
href="">http://groups.msn.com/ASXShareTrading<A
href="">http://groups.msn.com/FMSAustralia
<FONT
face=Tahoma size=2>-----Original Message-----From: Tomasz Janeczko
[mailto:amibroker@xxxxxx] Sent: Thursday, 23 October 2003 11:47
PMTo: amibroker@xxxxxxxxxxxxxxxSubject: [amibroker]
AmiBroker 4.46.1 BETA released<FONT
size=2>Hello,A new beta version (4.46.1) of AmiBroker has just been
released.Includes enhancements allowing to auto-adjust data from Yahoo
andability to display tommorrows trades recommendations in portfolio
backtesterwhen using one bar delay.It is available for registered
users only from the members area at:<A
href=""><FONT
size=2>http://www.amibroker.com/members/bin/ab4461beta.exe<FONT
size=2>and<A
href=""><FONT
size=2>http://www.amibroker.net/members/bin/ab4461beta.exe<FONT
size=2>(File size: 516 350 bytes, 516 KB)If you forgot your user
name / password to the members areayou can use automatic reminder service
at: <FONT
size=2>http://www.amibroker.com/login.htmlThe
highlight of this new version is multiple time frame support in
AFL.The instructions are available below and in the "ReadMe" file(
Help->Read Me menu from AmiBroker )
CHANGES FOR VERSION 4.46.1 (as compared to 4.46.0)
scoreNoRotate now works again
small fix in regarding month boundary handling in "Use local time for
daily compression" mode.
AA settings, new switch: "Add artificial future bar". When checked
AmiBroker adds tommorrow's bar and this enables you to see tommorrow's (or
next bar) trade recommendations when your system uses one bar delay.
Artificial future bar is a copy of last available data bar but has of course
incremented date and volume set to zero.
two functions (where present in 4.46.0 but not
documented)IsFavourite() - returns 'true' if current symbol belongs to
favoritesIsIndex() - returns 'true' if current symbol belongs to index
category
CHANGES FOR VERSION 4.46.0 (as compared to 4.45.0)
New AFL functions
added NumToStr as synonum of WriteVal (as this
function did not 'write' anything, just returned string)
added StrToNum( string ) - converts string to numbe
added StrFind( string, substring ) - finds first
occurrence of substring in string. returns 0 if not found, otherwise
returns character index (one-based) of first occurrence
added StrFormat( formatstr, ... ) that performs
sprintf-like formatting and returns string
CategoryGetName( category, number) function - returns
name of category (market/group/sector/industry/watchlist)
CategoryGetSymbols( category, number ) added -
synonym to GetCategorySymbols
CategoryAddSymbol( symbol, category, number ); - adds
the symbol to given category, note that for markets, groups, industries
'adding' means moving from one category to another, since the symbol is
assigned always to one and only one market, group, industry and sector.
This limitation does not apply to watchlists, favorites, and index
categories. When symbol string is empty ("") then current symbol is used.
CategoryRemoveSymbol( symbol, category, number ); -
removes the symbol to given category, note that for markets, groups,
industries 'removing' means moving from given category to category with
number zero, since the symbol is assigned always to one and only one
market, group, industry and sector. This limitation does not apply to
watchlists, favorites, and index categories. When symbol string is empty
("") then current symbol is used.
added new AFL functions for output/file handling (almost exactly like in
C run-time):
printf( formatstr, ... ) - output formatted text to
the commentary/interpretation (note 1: for numbers always use %f, %e or %g
formatting, %d or %x will not work because there are no integers in AFL,
note 2: as of now only numbers and arrays can now be printed. For arrays
'selected value' is printed)
fopen( filename, mode ) - opens file, returns
filehandle . Mode can be "r" - for reading, "w" for writing, "a" for
appending (and all other regular C-runtime library modes)
fclose( filehandle ); - closes file
fputs( string, filehandle ) - puts (writes) string to
file
fgets( filehandle ) - gets (reads) string from file
(returns string)
feof( filehandle ) - detects end-of-file marker (
gives True - if end of file reached )
PositionScore table is now shifted according to buy trade delay in
regular mode too. (it was shifted so in rotational mode already). Caveat:
make sure to set long and short delays to the same values if you are trading
both long and short sides, otherwise only long trades get correct ranks.
Note 2: PositionSize is not and was never shifted with trade delaysto
allow code for purchasing N stocks working with any delay, example
PositionSize = 5 * BuyPrice
added new option to File->Database Settings->Intraday settings
"Use local time for daily compression".All previous versions used
exchange or data vendor time to do build daily bars (this means that
regardless of your time shift settings daily bars looked the same because
they used exchange or data source time (for example if you are using
QuoteTracker it was US EST time) - this caused problems for Australian users
using QuoteTracker as data source because QuoteTracker reported ASX quotes
with US time that lead to invalid daily bars. Now if you check "Use local
time for daily compression" AmiBroker will use your local time (according to
'time shift' setting) to build daily bars. Note that switching this on means
that daily bars may look different when you change time zone (i.e. time
shift setting)
ASCII importer: support for importing unadjusted Yahoo data performing
adjustment on the fly:
new field ADJCLOSE - to read adj. close column from
Yahoo. Works _only_ in conjunction with CLOSE field. When both CLOSE and
ADJCLOSE are present in the ASCII format definition then importer
calculates split factor by dividing ADJCLOSE/CLOSE. It then multiples
OPEN, HIGH, LOW and CLOSE fields by this factor and divides VOLUME field
by this factor. This effectively converts unadjusted prices to split
adjusted prices. Split ratio gets locked once ADJCLOSE drops below
0.05.
new command $ROUNDADJ decimaldigits - causes
split-adjusted prices (see above) to be rounded to 'decimaldigits'
precision. By default no rounding is done.
new command $RECALCSPLITS 1 - (off by default) causes
that splits are recalculated by AmiBrokerby the algorithm that tries
to construct correct adjusted price, based on inaccurate information
provided by Yahoo.Note that Yahoo provides only 2 decimal digits in
adj. close field therefore the more adj. close approaches zero due to
adjustements the error grows. The option $RECALCSPLITS 1 is intended to
address this problem (at least partially).It works as follows:1.
for each bar ratio ADJCLOSE/CLOSE is calculated2. if the ratio changes
in two consecutive bars by more than 10% it means thatsplit happened
that bar. True split ratio is guessed by matching true fractionin the
format of X/Y, where X and Y = 1..9, to the change in ratios.3. Then
true split ratio is used to adjust all past bars until new split is
detected.
new command $RAWCLOSE2OI 1 - (off by default) -
causes that OpenInterest field gets assigned CLOSE (raw close) field value
multiplied by 100
new aqh.format file included in "formats" subfolder using new ASCII
importer commands to import and adjust prices from Yahoo. Compatible with
existing AmiQuote versions. Best regards,Tomasz
JaneczkoHope this helps.
AmiBroker 4.46.1 Beta Read Me
October 23, 2003 17:38
THIS IS A BETA VERSION OF THE SOFTWARE. EXPECT BUGS !!!
Backup your data files and entire AmiBroker folder
first!
INSTALLATION INSTRUCTIONS
IMPORTANT: This archive is update-only. You have to install full
version 4.40 first.
Just run the installer and follow the instructions.
Then run AmiBroker. You should see "AmiBroker 4.46.1 beta" written in the
About box.
See CHANGE LOG below for detailed list of changes.
HELP ON NEW FEATURES
New backtest report
New report is hugely enhanced compared to old one. It includes separate
statistics for all, long and short sides as well as large number of new
metrics. You can get short help on given figure by hovering your mouse over
given field name. You will see the description in the tooltip. Short
explanations are provided also below:
Exposure % - modified since last release
-'Market exposure of the trading system calculated on bar by bar basis. Sum of
bar exposures divided by number of bars. Single bar exposure is the value of
open positions divided by portfolio equity.
Net Risk Adjusted Return % - Net profit % divided by
Exposure %
Annual Return % - Compounded Annual Return % (CAR)
Risk Adjusted Return % - Annual return % divided by
Exposure %
Avg. Profit/Loss - (Profit of winners + Loss of
losers)/(number of trades)
Avg. Profit/Loss % - '(% Profit of winners + % Loss of
losers)/(number of trades)
Avg. Bars Held - sum of bars in trades / number of
trades
Max. trade drawdown - The largest peak to valley decline
experienced in any single trade
Max. trade % drawdown - The largest peak to valley
percentage decline experienced in any single trade
Max. system drawdown - The largest peak to valley decline
experienced in portfolio equity
Max. system % drawdown - The largest peak to valley
percentage decline experienced in portfolio equityRecovery
Factor - Net profit divided by Max. system
drawdownCAR/MaxDD - Compound Annual % Return divided
by Max. system % drawdown
RAR/MaxDD - Risk Adjusted Return divided by Max. system %
drawdown
Profit Factor - Profit of winners divided by loss of
losers
Payoff Ratio - Ratio average win / average
lossStandard Error - Standard error measures
chopiness of equity line. The lower the better.
Risk-Reward Ratio - Measure of the relation between the
risk inherent in a trading the system compared to its potential gain. Higher
is better. Calculated as slope of equity line (expected annual return) divided
by its standard error.
Ulcer Index - Square root of sum of squared drawdowns
divided by number of bars
Ulcer Performance Index - (Annual profit - Tresury notes
profit)/Ulcer Index'>Ulcer Performance Index. Currently tresury notes
profit is hardcoded at 5.4. In future version there will be user-setting for
this.
Sharpe Ratio of trades - Measure of risk adjusted return
of investment. Above 1.0 is good, more than 2.0 is very good. More information
<A
href="">http://www.stanford.edu/~wfsharpe/art/sr/sr.htm
. Calculation: first average percentage return and standard deviation of
returns is calculated. Then these two figures are annualized by multipling
them by ratio (NumberOfBarsPerYear)/(AvgNumberOfBarsPerTrade). Then the risk
free rate of return is subtracted (currently hard-coded 5) from annualized
average return and then divided by annualized standard deviation of
returns.K-Ratio - Detects inconsistency in returns.
Should be 1.0 or more. The higher K ratio is the more consistent return you
may expect from the system. Linear regression slope of equity line multiplied
by square root of sum of squared deviations of bar number divided by standard
error of equity line multiplied by square root of number of bars. More
information: Stocks & Commodities V14:3 (115-118): Measuring System
Performance by Lars N. Kestner
Optimization in new portfolio backtester
From version 4.43.0 BETA AmiBroker is able to perform optimizations on
portfolio level. The portfolio optimization uses familar function Optimize and
allows upto 10 variables to be optimized. You are able not only to optimize
parameters of indicators but you can also optimize portfolio-level settings
like maximum number of open positions, portfolio level position sizing, etc.
These settings are available via SetOption() function. New fields accepted by
SetOption include: SetOption("MaxOpenPositions"), SetOption("MinShares"). More
are on the way.
Also the portfolio optimizer gives much more statistics than old one
including metrics like Sharpe ratio, Risk Reward ratio, etc.
New portfolio backtester
IMPORTANT: Since the new backtester is not yet
complete. If you think that there is a bug please report it to <A
href="">bugs@xxxxxxxxxxxxx with all details you
can give including: the formula, HTML report generated by AmiBroker, trade
list or detailed log, etc.
From version 4.42.0 BETA through some future betas there will be TWO
backtesters. The OLD one that is triggered by pressing "Backtest" or
"Optimize" button in the Automatic Analysis window. And NEW one,
portfolio-level backtester that is triggered by pressing "Portfolio BackTest"
or "Portfolio Optimize" button in Automatic Analysis window.
Old backtester is untouched and it works exactly the same way as in
pre-4.42 versions. I have decided to leave it for a while so you can
continue using old your own formulas, results, etc while checking out new
backtester.
New backtester is not complete yet, but already provides substantial amount
of functionality to make it worthwhile to check it out.
New backtester works on PORTFOLIO LEVEL, it means that
there is single portfolio equity and position sizing refers to portfolio
equity. Portfolio equity is equal to available cash plus sum of all
simultaneously open positions at given time.
IMPORTANT: to enable more than one symbol to be traded you
have to add PositionSize variable to your formula, so less than 100% of funds
are invested in single security:
PositionSize = -25; // invest 25% of portfolio equity in single
security
or
PositionSize = 5000; // invest $5000 into single security
You can use new PositionScore variable to decide which trades should be
entered if there are more entry signals on different securities than maximum
allowable number of open positions or available funds. In such case AmiBroker
will use the absolute value of PositionScore variable to decide which trades
are preferred. See the code below. It implements simple MA crossover system,
but with additional flavour of preferring entering trades on symbols that have
low RSI value. If more buy signals occur than available cash/max. positions
then the stock with lower RSI will be preferred. You can watch selection
process if you backtest with "Detailed log" report mode turned on.
The code below includes also the example how to find optimum number of
simultaneously open positions using new Optimization in Porfolio mode.
/******* REGULAR PORTFOLIO mode ** This sample
optimization** finds what is optimum number of positions open
simultaneously** ****/
SetOption("InitialEquity", 20000
);SetTradeDelays(1,1,1,1);RoundLotSize = 1;
posqty = Optimize("PosQty", 4, 1, 20, 1
);SetOption("MaxOpenPositions", posqty);
// desired position size is 100% portfolio equity// divided by
PosQty positionsPositionSize = -100/posqty;
// The system is very simple...// MA parameters
could be optimized too...p1 = 10;p2 = 22;// simple MA
crossoverShort=Cross( MA(C,p1) , MA(C,p2) );Buy=Cross( MA(C,p2) ,
MA(C,p1) );// always in the market Sell=Short;
Cover=Buy;
// now additional score // that is used to rank equities //
when there are more ENTRY signals that available//
positions/cashPositionScore = 100-RSI(); // prefer stocks that have low
RSI;
Things NOT IMPLEMENTED yet in new portfolio backtester, to be done
soon
futures support (point value, margin deposit, ticksize)
calculation of interest earnings
pyramiding
intra-bar detailed timing
OLE interface
etc...
Automatic Analysis Settings - Portfolio page
- Max. Open Positions (previously known as "Max. traded") - the maximum
number of simultaneously open positions. .Settable also using
SetOption("MaxOpenPositions", number ) function.
- Max. # of signals tracked per bar- the maximum number of
buy/sell/short/cover signals per single bar that AmiBroker will track. Should
be set to at least 2 * (Max. Open Positions) or more. Default of 100 should be
fine for most applications. May be removed in the future. Settable also using
SetOption("MaxTracked", number ) function.
- Report mode - Trade list - shows regular trade list (as old backtester),
Detailed log - shows very detailed bar-by-bar log with scores, each entry and
exit separately reported, etc.
- Min. shares - the minimum number of shares that are allowed to buy/short.
Backtester will not enter trades below that limit. Default = 1 is good for
stocks.
Known differencies between statistics produced by 'old' and 'new'
(portfolio) backtester
Old backtester
New (portfolio) backtester
System and trade drawdown calculations based on
Open/Close/H-L range (worst case) selectable in settings
Close price only (regardless of settings) - subject to change
Max. % trade drawdown
Calculated based on total equity
Calculated based on ACTUAL trade value at entry point.
Stats available
for all trades only
separately for long, short and all trades
Futures backtesting (MarginDeposit, TickSize, PointValue)
Supported
Not yet available
Interest earnings calculation
Supported
Not yet available
PositionSizing
Based on individual symbol equity
Based on portfolio equity.
PositionSize = -25;
will enter 25% of current porfolio equity
Trade statistics
Include only closed trades, open trade is reported separately
Include all trades (closed and those still open at the end of
analysis period). Any open trades are closed out at 'close' price
always.
Positions taken
Uses "Positions" selector in the Settings to include long, short or
both positions
From version 4.43.0 portfolio backtest behaves the same (uses
"positions" selector)
Exposure
calculated regardless of position size (no matter on what is
position size if trade is taken for particular bar it assumes 100%
exposure at that bar)
calculations include now (in 4.43.0) the total amount of open
positions compared to total portfolio equity. Exposure is calculated on
bar by bar basis so if only 50% funds are in open trade, then exposure
for this bar is 0.5. Then individual bar exposures are summed up and
divided by number of bars to produce exposure figure. This way true
market exposure is calculated.
Multiple security testing
N independent accounts (multiple single equity)
Portfolio equity common to all symbols under
test
Multiple time frame support
Release 4.41 brings ability to use multiple time frames (bar intervals) in
single formula. The time frame functions can be divided into 3 functional
groups:
switching time frame of build-in O, H, L, C, V, OI, Avg arrays:
TimeFrameSet, TimeFrameRestore
compressing/expanding single arrays to/from specified interval:
TimeFrameCompress, TimeFrameExpand
immediate access to price/volume arrays in different time frame:
TimeFrameGetPrice
First group is used when your formula needs to perform
some calculations on indicators in different time frame than currently
selected one. For example if you need to calculate 13-bar moving average on 5
minute data and 9 bar exponential avarage from hourly data while current
interval is 1 minute you would write:
TimeFrameSet( in5Minute ); // switch to 5 minute
frame
/* MA now operates on 5 minute data, ma5_13 holds time-compressed 13
bar MA of 5min bars */
ma5_13 = MA( C, 13 );
TimeFrameSet( inHourly ); // switch now
to hourly
mah_9 = EMA( C, 9 ); // 9 bar moving average from hourly
data
TimeFrameRestore(); // restore time frame to
original
Plot( Close, "Price", colorWhite, styleCandle );
// plot expanded average
Plot( TimeFrameExpand( ma5_13, in5Minute), "13 bar
moving average from 5 min bars", colorRed );Plot(
TimeFrameExpand( mah_9, inHourly), "9 bar moving average from
hourly bars", colorRed );
TimeFrameSet( interval ) - replaces
current built-in price/volume arrays: open, high, low, close, volume, openint,
avg with time-compressed bars of specified interval once you switched to a
different time frame all calculations and built-in indicators operate on
selected time frame. To get back to original interval call TimeFrameRestore()
funciton. Interval is time frame interval in seconds. For example: 60 is one
minute bar. You should use convenient constants for common intervals:
in1Minute, in5Minute, in15Minute, inHourly, inDaily, inWeekly, inMonthly.
TimeFrameRestore() - restores price arrays replaced by
SetTimeFrame.Note that only OHLC, V, OI and Avg built-in variables are
restored to original time frame when you call TimeFrameRestore().All other
variables created when being in different time frame remain compressed. To
de-compress them to original interval you have to use TimeFrameExpand.
Once you switch the time frame using TimeFrameSet, all AFL functions
operate on this time frame until you switch back the time frame to original
interval using TimeFrameRestore or set to different interval again using
TimeFrameSet. It is good idea to ALWAYS call TimeFrameRestore when you are
done with processing in other time frames.
When time frame is switched to other than original interval the results of
all functions called since TimeFrameSet are time-compressed too. If you want
to display them in original time frame you would need to 'expand' them as
described later. Variables created and assigned before call to TimeFrameSet()
remain in the time frame they were created. This behaviour allows mixing
unlimited different time frames in single formula.
Please note that you can only compress data from shorter interval to longer
interval. So when working with 1-minute data you can compress to 2, 3, 4, 5,
6, ....N-minute data. But when working with 15 minute data you can not get
1-minute data bars. In a similar way if you have only EOD data you can not
access intraday time frames.
Second group: TimeFrameCompress/TimeFrameExpand allow to
compress and expand single arrays to / from different time frames. Especially
worth mentioning is TimeFrameExpand that is used to decompress array variables
that were created in different time frame. Decompressing is required to
properly display the array created in different time frame. For example if you
want to display weekly moving average it must be 'expanded' so the data of one
weekly bar covers five daily bars (Monday-Friday) of corresponding week.
TimeFrameExpand( array, interval, mode = expandLast ) -
expands time-compressed array from 'interval' time frame to base time frame
('interval' must match the value used in TimeFrameCompress or
TimeFrameSet)Available modes:expandLast - the compressed value is
expanded starting from last bar within given period (so for example weekly
close/high/low is available on Friday's bar)expandFirst - the compressed
value is expanded starting from first bar within given period (so for example
weekly open is available from Monday's bar)expandPoint - the resulting
array gets not empty values only for the last bar within given period (all
remaining bars are Null (empty)).
Caveat: expandFirst used on price different than open may look into the
future. For example if you create weekly HIGH series, expanding it to daily
interval using expandFirst will enable you to know on MONDAY what was the high
for entire week.
TimeFrameCompress is provided for completeness and it can be used when you
want to compress single array without affecting built-in OHLC,V arrays. If you
call TimeFrameCompress it does not affect results of other functions.
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 );
During this formula the time frame remained at original setting we only
compressed single array.
TimeFrameCompress( array, interval, mode = compressLast
)- compresses single array to given interval using given compression mode
available modes:compressLast - last (close) value of the array within
intervalcompressOpen - open value of the array within
intervalcompressHigh - highest value of the array within
intervalcompressLow - lowest value of the array within
intervalcompressVolume - sum of values of the array within
interval
graph0 = TimeFrameExpand( TimeFrameCompress( Close, inWeekly,
compressLast ), inWeekly, expandLast );graph1 = TimeFrameExpand(
TimeFrameCompress( Open, inWeekly, compressOpen ), inWeekly, expandFirst
);
Third group consist of just one useful function:
TimeFrameGetPrice which allows to reference price and volume from other time
frames without switching /compressing/expanding time frames. Just one function
call to retrieve price from higher time frame. It allows also to reference not
only current but past bars from different time frames.
TimeFrameGetPrice( pricefield, interval, shift = 0, mode =
expandFirst );- references OHLCV fields from other time frames. This works
immediatelly without need to call TimeFrameSet at all.Price field is one
of the following: "O", "H", "L", "C", "V", "I" (open interest). Interval is
bar interval in seconds. shift allows to reference past (negative values) and
future (positive values) data in higher time frame. For example -1 gives
previous bar's data (like in Ref function but this works in higher time
frame).
Examples:
TimeFrameGetPrice( "O", inWeekly, -1 ) - gives you previous
week OPEN priceTimeFrameGetPrice( "C", inWeekly, -3 ) - gives
you weekly Close price 3 weeks agoTimeFrameGetPrice( "H", inWeekly,
-2 ) - gives you weekly High price 2 weeks
agoTimeFrameGetPrice( "O", inWeekly, 0 ) - gives you this
week open price.
TimeFrameGetPrice( "H", inDaily, -1 ) - gives previous day
high when working on intraday data
Shift works as in Ref() function but it is applied to compressed time
frame.
Note these functions work like these 3 nested
functionsTimeFrameExpand( Ref( TimeFrameCompress( array, interval,
compress(depending on field used) ), shift ), interval, expandFirst
)therefore if shift = 0 compressed data may look into the future (
weekly high can be known on monday ). If you want to write a trading system
using this function please make sure to reference PAST data by using negative
shift value.The only difference is that TimeFrameGetPrice is 2x faster
than nested Expand/Compress.
Note on performance of TimeFrame functions:a)
Measurements done on Athlon 1.46GHz, 18500 daily bars compressed to weekly
time frameTimeFrameGetPrice( "C", inWeekly, 0 ) - 0.0098 sec (9.8
milliseconds)TimeFrameSet( inWeekly ) - 0.012 sec (12
milliseconds)TimeFrameRestore( ) - 0.006 sec (6
milliseconds)TimeFrameCompress( Close, inWeekly, compressLast ); -
0.0097 sec (9.7 milliseconds)TimeFrameExpand( array, inWeekly,
expandLast ); - 0.0098 sec (9.8 milliseconds)
b) Measurements done on Athlon 1.46GHz, 1000 daily bars compressed to
weekly time frameall functions below 0.0007 sec (0.7
millisecond)
EXAMPLES
EXAMPLE 1: Plotting weekly MACD and cross arrows from daily data
TimeFrameSet( inWeekly );m = MACD(12, 26 ); // MACD from WEEKLY
dataTimeFrameRestore();
m1 = TimeFrameExpand( m, inWeekly );
Plot( m1, "Weekly MACD", colorRed );PlotShapes( Cross( m1, 0 )
* shapeUpArrow, colorGreen );PlotShapes( Cross( 0, m1 ) * shapeDownArrow,
colorGreen );
EXAMPLE 2: weekly candlestick chart overlaid on line daily price
chart
wo = TimeFrameGetPrice( "O", inWeekly, 0, expandPoint );wh
= TimeFrameGetPrice( "H", inWeekly, 0, expandPoint );wl =
TimeFrameGetPrice( "L", inWeekly, 0, expandPoint );wc = TimeFrameGetPrice(
"C", inWeekly, 0, expandPoint );
PlotOHLC( wo, wh, wl, wc, "Weekly Close", colorWhite, styleCandle
);Plot( Close, "Daily Close", colorBlue );
EXAMPLE 3: Simplified Triple screen system
/* switch to weekly time frame */TimeFrameSet( inWeekly
);whist = MACD( 12, 26 ) - Signal( 12, 26, 9 );wtrend = ROC( whist, 1
); // weekly trend - one week change of weekly macd
histogramTimeFrameRestore();
/* expand calculated MACD to daily so we can use it with daily
signals */wtrend = TimeFrameExpand( wtrend, inWeekly );
/* elder ray */bullpower= High -
ema(Close,13);bearpower= Low - ema(Close,13);
Buy = wtrend > 0 /* 1st screen: positive weekly trend
*/ANDbearpower < 0 and bearpower > Ref( bearpower, -1 ) /* 2nd
screen bear power negative but rising */ANDH > Ref( H, -1 ); /* 3rd
screen, if prices make a new high */
BuyPrice = Ref( H, -1 ); // buy stop level;
Sell = 0 ; // exit only by stopsApplyStop( stopTypeProfit,
stopModePercent, 30, True );ApplyStop( stopTypeTrailing, stopModePercent,
20, True );
CHANGE LOG
CHANGES FOR VERSION 4.46.1 (as compared to 4.46.0)
scoreNoRotate now works again
small fix in regarding month boundary handling in "Use local time for
daily compression" mode.
AA settings, new switch: "Add artificial future bar". When checked
AmiBroker adds tommorrow's bar and this enables you to see tommorrow's (or
next bar) trade recommendations when your system uses one bar delay.
Artificial future bar is a copy of last available data bar but has of course
incremented date and volume set to zero.
two functions (where present in 4.46.0 but not
documented)IsFavourite() - returns 'true' if current symbol belongs to
favoritesIsIndex() - returns 'true' if current symbol belongs to index
category
CHANGES FOR VERSION 4.46.0 (as compared to 4.45.0)
New AFL functions
added NumToStr as synonum of WriteVal (as this
function did not 'write' anything, just returned string)
added StrToNum( string ) - converts string to numbe
added StrFind( string, substring ) - finds first
occurrence of substring in string. returns 0 if not found, otherwise
returns character index (one-based) of first occurrence
added StrFormat( formatstr, ... ) that performs
sprintf-like formatting and returns string
CategoryGetName( category, number) function - returns
name of category (market/group/sector/industry/watchlist)
CategoryGetSymbols( category, number ) added -
synonym to GetCategorySymbols
CategoryAddSymbol( symbol, category, number ); - adds
the symbol to given category, note that for markets, groups, industries
'adding' means moving from one category to another, since the symbol is
assigned always to one and only one market, group, industry and sector.
This limitation does not apply to watchlists, favorites, and index
categories. When symbol string is empty ("") then current symbol is used.
CategoryRemoveSymbol( symbol, category, number ); -
removes the symbol to given category, note that for markets, groups,
industries 'removing' means moving from given category to category with
number zero, since the symbol is assigned always to one and only one
market, group, industry and sector. This limitation does not apply to
watchlists, favorites, and index categories. When symbol string is empty
("") then current symbol is used.
added new AFL functions for output/file handling (almost exactly like in
C run-time):
printf( formatstr, ... ) - output formatted text to
the commentary/interpretation (note 1: for numbers always use %f, %e or %g
formatting, %d or %x will not work because there are no integers in AFL,
note 2: as of now only numbers and arrays can now be printed. For arrays
'selected value' is printed)
fopen( filename, mode ) - opens file, returns
filehandle . Mode can be "r" - for reading, "w" for writing, "a" for
appending (and all other regular C-runtime library modes)
fclose( filehandle ); - closes file
fputs( string, filehandle ) - puts (writes) string to
file
fgets( filehandle ) - gets (reads) string from file
(returns string)
feof( filehandle ) - detects end-of-file marker (
gives True - if end of file reached )
PositionScore table is now shifted according to buy trade delay in
regular mode too. (it was shifted so in rotational mode already). Caveat:
make sure to set long and short delays to the same values if you are trading
both long and short sides, otherwise only long trades get correct ranks.
Note 2: PositionSize is not and was never shifted with trade delaysto
allow code for purchasing N stocks working with any delay, example
PositionSize = 5 * BuyPrice
added new option to File->Database Settings->Intraday settings
"Use local time for daily compression".All previous versions used
exchange or data vendor time to do build daily bars (this means that
regardless of your time shift settings daily bars looked the same because
they used exchange or data source time (for example if you are using
QuoteTracker it was US EST time) - this caused problems for Australian users
using QuoteTracker as data source because QuoteTracker reported ASX quotes
with US time that lead to invalid daily bars. Now if you check "Use local
time for daily compression" AmiBroker will use your local time (according to
'time shift' setting) to build daily bars. Note that switching this on means
that daily bars may look different when you change time zone (i.e. time
shift setting)
ASCII importer: support for importing unadjusted Yahoo data performing
adjustment on the fly:
new field ADJCLOSE - to read adj. close column from
Yahoo. Works _only_ in conjunction with CLOSE field. When both CLOSE and
ADJCLOSE are present in the ASCII format definition then importer
calculates split factor by dividing ADJCLOSE/CLOSE. It then multiples
OPEN, HIGH, LOW and CLOSE fields by this factor and divides VOLUME field
by this factor. This effectively converts unadjusted prices to split
adjusted prices. Split ratio gets locked once ADJCLOSE drops below
0.05.
new command $ROUNDADJ decimaldigits - causes
split-adjusted prices (see above) to be rounded to 'decimaldigits'
precision. By default no rounding is done.
new command $RECALCSPLITS 1 - (off by default) causes
that splits are recalculated by AmiBrokerby the algorithm that tries
to construct correct adjusted price, based on inaccurate information
provided by Yahoo.Note that Yahoo provides only 2 decimal digits in
adj. close field therefore the more adj. close approaches zero due to
adjustements the error grows. The option $RECALCSPLITS 1 is intended to
address this problem (at least partially).It works as follows:1.
for each bar ratio ADJCLOSE/CLOSE is calculated2. if the ratio changes
in two consecutive bars by more than 10% it means thatsplit happened
that bar. True split ratio is guessed by matching true fractionin the
format of X/Y, where X and Y = 1..9, to the change in ratios.3. Then
true split ratio is used to adjust all past bars until new split is
detected.
new command $RAWCLOSE2OI 1 - (off by default) -
causes that OpenInterest field gets assigned CLOSE (raw close) field value
multiplied by 100
new aqh.format file included in "formats" subfolder using new ASCII
importer commands to import and adjust prices from Yahoo. Compatible with
existing AmiQuote versions.
CHANGES FOR VERSION 4.45.0 (as compared to 4.44.1)
score of 999999 is no longer recognized. Use constant scoreNoRotate
instead.
UI simplification:Rotational mode: separate settings for rotational
mode trade price and delay and worst rank held have been
removed.Rotational mode now uses buy price and buy delay settings from
"Trade" tab. You can also set delay from the code SetTradeDelays( 1, 1, 1, 1
); will give you one bar delay. To set 'worst rank held' use SetOption
function in your formula:SetOption("WorstRankHeld", 5 );
stops implemented in rotational trading mode (limitation: stops in
rotational mode can only be static, they can not change'stop amount'
from symbol to symbol or from bar to bar like in regular mode)
re-entry delay implemented for all kind of stops
user interface added in the settings for n-bar stops
ApplyStop function now takes 6 parameters:ApplyStop( Type, Mode,
Amount, ExitAtStop = True, Volatile = False, ReentryDelay = 0 )
rotational mode docs moved to <A
href=""
target=_blank>this page
CHANGES FOR VERSION 4.44.1 (as compared to 4.44.0)
fixed problem with rotational mode, trading price: open
CHANGES FOR VERSION 4.44.0 (as compared to
4.43.2)
fixed crash with 'detail mode' and large number of open positions/ranks
used
max. in-memory cache size can be set now to 20000 (please note that
this large cache requires lots of RAM (more than
512MB))
listview copy to clipboard feature now copies also column header
names
SetForeign( ticker, fixup = True, tradeprices = False) and
RestorePriceArrays( tradeprices = False ) have new flag now:
tradeprices (False by default)
when tradeprices is set to TRUE, then not only OHLC, V, OI, Avg arrays
are set to foreign symbol values, but also BuyPrice, SellPrice, ShortPrice,
CoverPrice, PointValue, TickSize, RoundLotSize, MarginDeposit variables are
set to correspond to foreign security.
This allows Equity() to work well with
SetForeign.
Example:
// your rulesbuy = ...sel = ...SetForeign("MSFT",
True, True );e = Equity(); // backtest on MSFTRestorePriceArrays(
True ); // <- should match parameter used in
SetForeign
Name(), FullName(), GetExtraData() work well with SetForeign() (i.e.
give foreign name/data instead of currently
selected)
SetOption("PriceBoundChecking", False ); - disables checking and
adjusting buyprice/sellprice/coverprice/shortprice arrays to current symbol
High-Low range.
% profit added to detailed log mode
fixed bug in portfolio backtester occuring when 'allow same bar exit'
was turned off and 'immediate stops' was turned on 2 buys and 2 sells
occurred the in 2 bars in row
Auto Analysis/Settings,setting modified "portfolio report mode: trade
list/detailed log" moved to "report" tab
Auto Analysis/Settings, rotational mode: added selection of trade price
and trade delay to portfolio settings page
Auto Analysis/Settings, portfolio backtester (both regular and
rotational modes): added ability to pad and align all symbols to reference
symbol. Note: by default this setting is OFF. Use responsibly. It may slow
down backtest and introduce some slight changes to indicator values when
your data has holes and holes are filled with previous bar data. The feature
is intended to be used ONLY when your system uses general market timing
(generates global signals based on data and/or indicators calculated using
Foreign from 'reference' symbol). Note 2: if reference symbol does not
exist, data won't be padded.
Auto Analysis/Settings, report tab: added ability to define risk-free
rates for Sharpe and Ulcer Performance Index
calculations.
CHANGES FOR VERSION 4.43.2 (as compared to
4.43.0)
backtester generates now error message when someone attempts to use
buy/sell/short/cover signals in rotational mode
column headings fixed in AA porfolio backtest report
CHANGES FOR VERSION 4.43.0 (as compared to
4.42.0)
Portfolio Optimize mode added
in regular backtest mode now it is possible to specify the score of the
symbol (on bar-by-bar basis) via PositionScore variable. In this mode the
score is used only at trade ENTRY to decide which securities should be
traded in case when there are more simultaneous entry signals than max.
allowable positions or available funds. AmiBroker will 'prefer' securities
with higher absolute value of the score. If PositionScore is not used then
it is assumed to be 1 for all securities.
NOTE: regular mode must be used for all your backtesting except the
cases when you want rotational-trading (fund switching). Only regular mode
uses buy/sell/short/cover signals.
rotational-trading mode must now be turned on by calling new
EnableRotationalTrading() function at the top of your
formula.
AA / Settings / Portfolio:1. Max. Traded renamed to more
meaningfull "Max. Open Positions" - defines the maximum number of positions
(trades) that can be open simultaneously (at any time)2. Max. Ranked
renamed to more meaningfull "Worst Rank Held" (rotational trading mode only)
- must be equal or greater than max. open positions, if it is greater than
Max. open positions then once a position is taken in a security it will not
be exited until the ranking of that security drops below "Worst Rank
Held"
"Allow same day exit (single bar trade)" now affects Portfolio test
too.
SetOption() calls affect Portfolio backtest now
added:SetOption("MaxOpenPositions")
SetOption("WorstRankHeld")SetOption("MinShares")
fixed Avg Profit/Loss figures in "all trades" section of portfolio
report
added average PERCENT profit/loss figures
internal accuracy of calculations of LinearReg, LinRegSlope,
LinRegIntercept, StdErr, TSF raised from 32 bit floating point to 64 bit
floating point
fix: rotational trading mode does not enter position when score is
999999
fixed column setup in AA
other minor fixes
as a temporary solution for people using Rx new version now uses
HTMLView2.exe (that is shipped with the beta) to display the portfolio
report.
CHANGES FOR VERSION 4.42.0 (as compared to
4.41.2)
first (incomplete) early beta version of the portfolio
backtester
fixed plot of Null arrays using styleArea
fixed display problem with % progress in single-stock optimization
other minor fixes
CHANGES FOR VERSION 4.41.2 (as compared to 4.41.1)
now Sum produces values for periods upto and including BarCount, so
Sum( array, BarCount ) gives the value instead of Null
fixed problem with saving parameters on exit when the user did not
specify default value for string parameter using ParamStr("name", "")
fixed 38-byte memory leak when returning values from user-defined
functions
real-time mode: after AFL syntax error commentary AFL editor is not
refreshed until error is fixed and user presses 'apply'
eSignal 1.6.0 plugin (available separately from<A
href="">
http://www.amibroker.com/bin/eSignal160.exe):
much quicker backfills
implemented force-reconnect feature in eSignal plugin
fixed minor timing issue in eSignal plugin
implemented workaround to invalid tick numbers sent sometimes by
eSignal's data manager.
thanks to all users for reporting errors and helping ironing out
outstanding issues.
CHANGES FOR VERSION 4.41.1 (as compared to 4.41.0)
fixed chart refresh locking that happened when user was drawing some
object and abandonend it by pressing ESC key.
View->Refresh and View->Refresh All menus now reset internal
chart refresh lock flag just in case.
plugin status is refreshed more often
maximum number of chart sheets increased to 60 (Caveat: when you
increase the number of sheets you would not be able to use the layouts with
OLDER versions of the software)
TimeFrameSet() now affects result of Interval() AFL function.
TimeFrameRestore() resets it back.
Plot() makes copies of OHL arrays when styleCandle or styleBar is used
so statements likeSetForeign("AAPL");Plot( C, "Price",
colorYellow, styleCandle );SetForeign("MSFT");Plot( C, "Price 2",
colorBlue, styleCandle );plot correctly. Previously one would
need to use PlotOHLC() or PlotForeign()
separate heap for syntax tree walker implemented, so larger AFL
programs like PortfolioTrader should execute faster while retaining the
speed improvement gained in 4.40.4 for small formulas.
CHANGES FOR VERSION 4.41.0 (as compared to 4.40.4)
legacy 'stoch()' function removed. Use StochK and StochD instead.
weekly / monthly charts are not affected by intraday compression
settingsin preferences any more and always use last available day date for
time stamp of time-compressed bar.
Pref: Misc: auto-hide timeout field: added check for allowed values
from 1...32
TimeFrameSet( interval ) function implemented-
replaces current price/volume arrays: open, high, low, close, volume,
openint, avg with time-compressed bars of specified interval once you
switched to a different time frame all calculations and built-in indicators
operate on selected time frame. To get back to original interval call
TimeFrameRestore() funciton.
TimeFrameRestore()- restores price arrays replaced
by SetTimeFrame.
Note that only OHLC, V, OI and Avg built-in variables are restored to
original time frame when you call TimeFrameRestore(). All other variables
created when being in different time frame remain compressed. To de-compress
them to original interval use TimeFrameExpand
TimeFrameCompress( array, interval, mode =
compressLast )- compresses single array to given interval using given
mode, available modes:compressLast - last (close) value of the array
within intervalcompressOpen - open value of the array within
intervalcompressHigh - highest value of the array within
intervalcompressLow - lowest value of the array within
intervalcompressVolume - sum values of the array within
interval
TimeFrameExpand( array, interval, mode = expandLast
)- expands time-compressed array from 'interval' time
frame('interval' must match the value used in TimeFrameCompress or
TimeFrameSet)Available modes:
expandLast - the compressed value is expanded starting from last bar
within given period (so for example weekly close/high/low is available on
Friday's bar)
expandFirst - the compressed value is expanded starting from first
bar within given period(so for example weekly open is available from
Monday's bar)
expandPoint - the resulting array gets not empty values only for the
last bar within given period (all remaining bars are Null
(empty))Caveat: expandFirst used on price different than open may look
into the future.For example if you create weekly HIGH series,
expanding it to daily interval using expandFirst will enable you to know
on MONDAY what was the high for entire week.graph0 =
TimeFrameExpand( TimeFrameCompress( Close, inWeekly, compressLast ),
inWeekly, expandLast );graph1 = TimeFrameExpand( TimeFrameCompress(
Open, inWeekly, compressOpen ), inWeekly, expandFirst
);
TimeFrameGetPrice( pricefield, interval, shift = 0,
mode = expandFirst );- references OHLCV fields from other time
frames.This works immediatelly without need to call
TimeFrameSetTimeFrameGetPrice( "O", inWeekly, -1 )
- gives you previous week OPEN priceTimeFrameGetPrice( "C",
inWeekly, -3 ) - gives you weekly Close price 3 weeks
agoTimeFrameGetPrice( "H", inWeekly, -2 ) - gives you
weekly High price 2 weeks agoTimeFrameGetPrice( "O", inWeekly, 0
) - gives you this week open price.TimeFrameGetPrice( "H",
inDaily, -1 ) - gives previous day high when working on intraday
dataPrice field is one of the following"O", "H", "L", "C",
"V", "I" (open interest)Shift works as in Ref() function but it is
applied to compressed time frame.Note these functions work like these 3
nested functionsTimeFrameExpand( Ref( TimeFrameCompress( array,
interval, compress(depending on field used) ), shift ), interval,
expandFirst )therefore if shift = 0 compressed data may look into
the future ( weekly high can be known on monday ). If you want to write a
trading system using this function please make sure to reference PAST data
by using negative shift value.The only difference is that
TimeFrameGetPrice is 2x faster than nested Expand/Compress.
new interval / timeframe constants:in1Minute =
60in5Minute = 5 * 60 in15Minute =
15 * 60 inHourly = 3600 inDaily =
24 * 3600inWeekly = 5 * 24 * 3600
inMonthly = 25 * 24 * 3600
compressLast = 0
compressOpen = 1 compressHigh = 2
compressLow = 3 compressVolume = 4
expandLast = 0 expandFirst = 1
expandPoint = 2
SetForeign( 'ticker' )- replaces current
price/volume arrays with those of foreign security, returns True if ticker
exists, False otherwise.If ticker does not exist (and function returns
false) price arrays are not changed at all.Equivalent to the
following sequence:C = Foreign( "ticker", "C" );O = Foreign(
"ticker", "O" );H = Foreign( "ticker", "H" );L = Foreign( "ticker",
"L" );V = Foreign( "ticker", "V" );OI = Foreign( "ticker", "I"
);Avg = ( C + H + L )/3;but 6x faster (SetForeign takes
about the same time as single foreign). To restore original prices
callRestorePriceArrays();EXAMPLE:SetForeign( "MSFT"
);dm = MACD(); // dm holds MACD of MSFT regardless of currently selected
symbolRestorePriceArrays();Plot( dm, "MACD of MSFT", colorRed
);Plot( MACD(), "MACD of " + Name(), colorBlue );
RestorePriceArrays();restores arrays overwritten
by SetForeign/TimeFrameSet
HOW TO REPORT BUGS
If you experience any problem with this beta version please send detailed
description of the problem (especially the steps needed to reproduce it) to <A
href="">bugs@xxxxxxxxxxxxx Send
BUG REPORTS to bugs@xxxxxxxxxxxxxSend SUGGESTIONS to
suggest@xxxxxxxxxxxxx-----------------------------------------Post
AmiQuote-related messages ONLY to: amiquote@xxxxxxxxxxxxxxx (Web page: <A
href="">http://groups.yahoo.com/group/amiquote/messages/)--------------------------------------------Check
group FAQ at: <A
href="">http://groups.yahoo.com/group/amibroker/files/groupfaq.html
Your use of Yahoo! Groups is subject to the <A
href="">Yahoo! Terms of Service.
Yahoo! Groups Sponsor
ADVERTISEMENT
Send BUG REPORTS to bugs@xxxxxxxxxxxxx
Send SUGGESTIONS to suggest@xxxxxxxxxxxxx
-----------------------------------------
Post AmiQuote-related messages ONLY to: amiquote@xxxxxxxxxxxxxxx
(Web page: http://groups.yahoo.com/group/amiquote/messages/)
--------------------------------------------
Check group FAQ at: http://groups.yahoo.com/group/amibroker/files/groupfaq.html
Your use of Yahoo! Groups is subject to the Yahoo! Terms of Service.
|