amibroker

HomeKnowledge Base

How to export chart image to a file

Charts can be exported as GIF or PNG files either manually or programmatically.

To export chart image manually, simply use Edit->Image->Export to file menu. Instead of exporting you can also copy the image to Windows clipboard (Edit->Image->Copy As Bitmap – this will copy bitmap image or Edit->Image->Copy As Metafile – this will copy vector/scalable graphic).

In order to export image in programmatic manner (from external program), you can use OLE automation interface described here http://www.amibroker.com/guide/objects.html

Below is a sample JScript code that shows how to use OLE interface from the script:

AB = new ActiveXObject("Broker.Application");
AW AB.ActiveWindow;
AW.ExportImage"C:\\example.gif"640480 ); // 640, 480 are pixel dimension

The code is intended to be used from the outside of AmiBroker.

To use above code follow these steps:

  1. Open Notepad
  2. Copy-paste above the code
  3. Save the file with .JS extension (which means that system will treat this as JScript code)
  4. Make sure that AmiBroker is running with desired chart as active one
  5. Double click on .JS file to execute the JScript code

After doing so, resulting example.gif image file can be found on C: drive.

OLE automation can also be used from any other COM/OLE-aware programs/languages.

Time compression of data retrieved from another symbol

AmiBroker’s Time-Frame functions (http://www.amibroker.com/guide/h_timeframe.html) allow to use multiple intervals within a single formula and combine them together. Another set of functions in AFL (Foreign and SetForeign) allow us to retrieve data of another symbol from the database, so we can implement strategies where rules are based on multiple symbols.

This article shows how to combine these two features together and properly use Time-Frame functions on data retrieved from another symbol. Let us consider an example of a strategy, which works on daily data, but uses an additional filter based on weekly readings of S&P500 index.

The following sequence is required to code such conditions properly:

  1. switch to the other symbol with SetForeign
  2. compress data into higher interval with TimeFrameSet
  3. store the weekly values / conditions in custom variables
  4. with TimeFrameRestore() or RestorePriceArrays() functions restore the original arrays of the tested symbol (in the original time-frame)
  5. use custom variables assigned in step (3) expanded to original time-frame using TimeFrameExpand()

Here is the AFL formula, which implements the above conditions:

// first switch to ^GSPC symbol
SetForeign"^GSPC" );
//
// compress data to weekly interval
TimeFrameSetinWeekly );
//
// assign weekly values to custom variables
indexWeeklyClose Close;
indexWeeklyMA =  MAClose52 );
indexWeeklyFilter Close MAClose52 );
//
// restore original arrays (back to the primary symbol)
// RestorePriceArrays() function is an equivalent
TimeFrameRestore();
//
// align data back to original interval
indexFilterExpanded TimeFrameExpandindexWeeklyFilterinWeekly );
//
// exploration shows the results, note that all weekly values
// need to be expanded if we haven't done it yet
//
Filter 1;
AddColumnClose"Close AAPL" );
AddColumnTimeFrameExpandindexWeeklyCloseinWeekly ), "Weekly close ^GSPC" );
AddColumnTimeFrameExpandindexWeeklyMAinWeekly ), "Weekly MA ^GSPC" );
AddColumnindexFilterExpanded"Weekly index filter")

Let us compare the readings obtained from the code with a sample chart – both ^GSPC raw reading and 52-week MA values match the chart and the condition is properly aligned to the bars starting on 2011-10-28 and extends until new weekly bar is formed.

TimeFrame + Foreign

There is also an alternative method we can use:

  1. retrieve values from ^GSPC using Foreign() function
  2. compress these readings into weekly interval using TimeFrameCompress
  3. perform calculations on weekly compressed array
  4. expand the compressed data back to the original timeframe using timeFrameExpand
indexClose Foreign("^GSPC","C");
indexWeeklyClose2 TimeFrameCompressindexCloseinWeekly );
indexWeeklyMA2 MAindexWeeklyClose252 );
indexWeeklyFilter2 indexWeeklyClose2 indexWeeklyMA2;
//
Filter 1;
AddColumnClose"Close AAPL" );
AddColumnTimeFrameExpandindexWeeklyClose2inWeekly ), "Weekly close ^GSPC" );
AddColumnTimeFrameExpandindexWeeklyMA2inWeekly ), "Weekly MA ^GSPC" );
AddColumnTimeFrameExpandindexWeeklyFilter2inWeekly ), "Weekly index filter")

How to customize list-view columns

A list-view is a view that displays a list of scrollable items in a table-like format. List-views are used in Real-Time quote window, Analysis window, Symbol list, etc. The columns in any list-view in AmiBroker can be customized in various ways to better match our needs and display the required statistics and readings the way we find it most useful. For the sake of example let us consider Analysis window result list.

Many of the customization actions can be performed directly on the column headers. It is possible to re-order the columns by dragging them with mouse cursor:

Column drag

and their width can be re-sized by dragging the divider lines between columns (double-clicking on that area will auto-resize the columns to match their contents).

Column resize

Hint: You can auto-resize all columns to their content at once by holding down Ctrl key and pressing + (plus sign) key on the numeric keypad.

For more operations it is possible to use Setup Columns… menu available from the context menu, which displays after right-clicking on the headers.

Column resize

Setup Columns dialog allows to re-order, hide/show selected columns.

Column setup

To hide a column uncheck the box, to show it back again, check the box. To re-arrange columns, select a column and click Move Up/Move Down buttons.

It is important to remember that the set of columns will depend on the last run mode, so it will be different for Scan, for the Backtest Trade List, for Summary type of report or Optimization.

Column setup 2

Further customization options are available programmatically. Custom Backtest interface allows to add your own metrics to the backtest report (more info: http://www.amibroker.com/guide/a_custommetrics.html)

We can also define in our code where those additional columns are positioned in the report (this includes both custom metrics added to the report or optimized parameter values in the Optimization). By default they would be listed at the very end, but SetOption() function allows to set different position, for example:

SetOption("ExtraColumnsLocation")

Using price levels with ApplyStop function

ApplyStop function by default requires us to provide stop amount (expressed in either dollar or percentage distance from entry price). Therefore, if we want to place stop at certain price level, then we need to calculate the corresponding stop amount in our code.

This example shows how to place stops at previous bar Low (for long trades) and previous bar High (for short trades).

Stop amount parameter is simply the distance between entry price and desired trigger price (exit point). For long trade it is entry price minus stop level, while for short trade it is trigger (exit) price minus entry price. Additionally we may check if calculated distance is at least 1-tick large. We can distinguish between long and short entry by checking if one of entry signals is present (if a Buy signal is active then it is long entry, otherwise short). We only need to take care about the fact that if we are using trade delays we need to get delayed Buy signal as shown in the code below:

TradeDelay 1// set it to 0 for no delays

SetTradeDelaysTradeDelayTradeDelayTradeDelayTradeDelay );
TickSize 0.01;

// sample entry rules
Buy CrossMACD(), Signal() );
Short CrossSignal(), MACD() );
Sell Cover 0// no other exit conditions, just stops

BuyPrice SellPrice ShortPrice CoverPrice Close;

// define stop level
stopLevelLong RefL, -); // use previous bar low
stopLevelShort RefH, -); // use previous bar high

// calculate stop amount
stopAmountLong BuyPrice stopLevelLong;
stopAmountShort stopLevelShort ShortPrice;

// make sure stop-amount is at least one tick
stopAmountLong MaxTickSizeBuyPrice stopLevelLong );
stopAmountShort MaxTickSizestopLevelShort ShortPrice );

// assign stop amount conditionally by checking if there is a Buy signal on given bar
IsLong RefBuy, -TradeDelay );
stopAmount IIfIsLongstopAmountLongstopAmountShort );
ApplyStopstopTypeLossstopModePointstopAmountTrue )

How to combine data from multiple input files

Sometimes it is useful to update existing database with quotes from other source and sometimes we just want to update one data field, leaving other unaffected. For example we may want to import data into Aux1 and Aux2 fields leaving regular OHLC prices untouched.

This post will show how to use $HYBRID mode of ASCII importer to combine data from multiple input files.

When we use Import Wizard / Import ASCII features to import quotations, by default the importer expects Close prices to be present in the imported data. There are some situations however when it would be convenient to import data just to one field (e.g. Aux1) if we have some additional values that we want to store in the database.

Of course, one way would be to combine all these quotes in a single file before the import and process in one run – but ASCII importer allows also to use special $HYBRID mode to import such partial data.

As an example, let us consider a situation where we already have adjusted OHLC quotes imported into the database and we have a file containing unadjusted quotes in the following format:

Ticker,Date,Aux1
AAPL,13-10-2014,99.81
AAPL,10-10-2014,100.73
AAPL,09-10-2014,101.02
AAPL,08-10-2014,100.80
AAPL,07-10-2014,98.75
AAPL,06-10-2014,99.62
AAPL,03-10-2014,99.62
AAPL,02-10-2014,99.90
AAPL,01-10-2014,99.18
AAPL,30-09-2014,100.75
AAPL,29-09-2014,100.11

In order to import those quotes into Aux1 field and combine with existing data, go to File->Import Wizard menu, pick the file and define format the following way:

ASCII import wizard

First we need to define columns so they match the format of input data (in this case set first three columns to Ticker, DMY, Aux1 and the rest to Skip).

To activate special hybrid mode we need to type:

$HYBRID 1

into Additional Commands box and since we are not importing regular prices that include Close array, we also need to mark Allow negative prices.

If instead of using the wizard we create import definition file manually, then it should contain:

$HYBRID 1
$ALLOWNEG 1

Now we can verify the results in Symbol->Quote Editor. The OHLC fields still contain adjusted values, while additional data has been properly stored in Aux1 field without affecting the other fields.

Quote Editor

For more information about Import Wizard and ASCII importer please check the following parts of the User’s Guide:
http://www.amibroker.com/guide/w_impwizard.html
http://www.amibroker.com/guide/d_ascii.html

Per-symbol profit/loss in a portfolio backtest

Backtesting engine in AmiBroker allows to add custom metrics to the report, both in the summary report and in the trade list. This is possible with Custom Backtester Interface, which allows to modify the execution of portfolio-level phase of the test and (among many other features) adjust report generation.

The example presented below shows how to retrieve individual profit/loss figures for each traded symbol in a portfolio test and add the results as custom metrics to the report. The code performs backtest, then iterates through the list of trades and stores each symbol profit in separate variables. Variables are created with VarSet function, which allows to build variable names dynamically, based on the symbol name. There are 2 variables generated per symbol, one holding profit for long trades and one for short trades. In the last part the code reads the created variables and adds input into the backtest report.

function ProcessTradetrade )
{
  global 
tradedSymbols;
  
symbol trade.Symbol;
  
//
  
if( ! StrFindtradedSymbols"," symbol "," ) )
  {
    
tradedSymbols += symbol ",";
  }
  
//
  // HINT: you may replace it with GetPercentProfit if you wish
  
profit trade.GetProfit();
  
//
  
if( trade.IsLong() )
  {
      
varname "long_" symbol;
      
VarSetvarnameNzVarGetvarname ) ) + profit );
  }
  else
  {
      
varname "short_" symbol;
      
VarSetvarnameNzVarGetvarname ) ) + profit );
  }
}
//
SetCustomBacktestProc"" );
//
/* Now custom-backtest procedure follows */
//
if ( Status"action" ) == actionPortfolio )
{
    
bo GetBacktesterObject();
    
//
    
bo.Backtest(); // run default backtest procedure
    //
    
tradedSymbols ",";
    
//
    //iterate through closed trades
    
for ( trade bo.GetFirstTrade( ); tradetrade bo.GetNextTrade( ) )
    {
        
ProcessTradetrade );
    }
    
//
    //iterate through open positions
    
for ( trade bo.GetFirstOpenPos( ); tradetrade bo.GetNextOpenPos( ) )
    {
        
ProcessTradetrade );
    }
    
//
    //iterate through the list of traded symbols and generate custom metrics
    
for ( 1; ( sym StrExtracttradedSymbols) ) != ""i++ )
    {
        
longprofit VarGet"long_" sym );
        
shortprofit VarGet"short_" sym );
        
allprofit Nzlongprofit ) + Nzshortprofit );
        
// metric uses 2 decimal points and
        // 3 (calculate sum) as a "combine method" for walk forward out-of-sample
        
bo.AddCustomMetric"Profit for " symallprofitlongprofitshortprofit2);
    }
}
//
SetOption"MaxOpenPositions"10 );
//
Buy CrossMACD(), Signal() );
Sell CrossSignal(), MACD() );
Short Sell;
Cover Buy;
SetPositionSize10spsPercentOfEquity 

Once we run the Backtest, we will get the following output in the report, showing individual profit/loss figures for each symbol in test.

Per-symbol profit

If you prefer percent profits instead of dollar profits, just replace GetProfit() call with GetPercentProfit().

Position sizing based on risk

One of most popular position sizing techniques is Van Tharp risk-based method. Van Tharp defines risk as the maximum amount that can be lost in a trade. Typically you limit your loses by setting up a maximum loss stop.

The amount risked should not be confused with amount invested. If your stop is 15% away from entry price, in worst case you risk losing 15% of the position size (amount invested), not the entire amount. So risk practically means the amount of maximum loss stop.

Now, imagine that we only allow to lose 1% of entire portfolio equity in single trade. If our stop is placed 15% away, it means that to risk just 1% of entire equity we can put 1/15 part of our available equity into this trade. As we can see desired position size is inversely proportional to stop amount.

Buy CrossCMAC20 ) ); // some trading rules
Sell CrossMAC20 ), );
//
PositionRisk 1// how much (in percent of equity) we risk in single position
TradeRisk 15// trade risk in percent equals to max. loss percentage stop
PctSize 100 PositionRisk TradeRisk;
//
ApplyStopstopTypeLossstopModePercentTradeRiskTrue );
SetPositionSizePctSizespsPercentOfEquity )

Let us see how it works, say we have equity of $60,000, and we only want to risk 1% in single trade ($600). We set our protective stop to 15%. If stock entry price is say $20, we would put our protective stop at $20-15% = $17, so we will risk $3 per share. Given the fact that we want to risk only $600 in that trade, we could buy 200 shares (position risk 200 * $3 = $600). 200 shares @ $20 each gives position value of $4000. $4000 represents 6.667% of $60,000 and this is actual percentage position size we would open. As we can clearly see 6.667% is what we would get if we divide 1 (percent position risk) by 15 (percent loss amount): 1/15 = 6.667%

Instead of setting our stop as fixed percentage, we can use more sophisticated methods. For example we can adjust our maximum loss (so the risk) dynamically, using average true range, so it will get wider if stock is volatile and narrower if stock prices move in a narrow range. Say we want to set our stop to twice the amount of ATR( 20 ) at the entry bar and risk 3% of portfolio equity in a single trade:

Buy CrossCMAC20 ) ); // some trading rules
Sell CrossMAC20 ), );
//
RiskPerShare =  ATR20 );
ApplyStopstopTypeLossstopModePointRiskPerShareTrue );
//
// risk 3% of entire equity on single trade
PositionRisk 3;
//
// position size calculation
PctSize =  PositionRisk BuyPrice RiskPerShare;
SetPositionSizePctSizespsPercentOfEquity )

This time our maximum loss (so the risk per share) is expressed in dollars not in percents. Let us verify the above calculation. Assume that our equity is $90,000, stock price is $18, ATR(20) is $1. Now risk per share (the stop amount) equals 2 * $1 = $2, so our calculated position size (required % of equity) from the above formula would be:

PctSize = 3 * $18 / $2 = 27%

27% of $90,000 means trade size of $24,300, i.e. 1350 shares (@ $18 each). Since we risk $2 on each share, the total risk is $2 * 1350 shares = $2700, which is exactly 3% of our total equity ($90,000 * 3%).

In case of futures, we would need to take into account the fact that our position size depends on Margin Deposit, while the stop size (expressed in dollars) depends on the Point Value, so the position sizing formula would need to be modified.

Buy CrossCMAC20 ) ); // some trading rules
Sell CrossMAC20 ), );
//
RiskPerContract ATR20 );
ApplyStopstopTypeLossstopModePointRiskPerContractTrue );
//
// risk 1% of entire equity on single trade
PositionRisk 1;
PctSize =  PositionRisk MarginDeposit  / ( RiskPerContract PointValue );
SetPositionSizePctSizespsPercentOfEquity )

Let us assume that we are trading a contract with $5000 margin deposit, point value $50, our equity is 1 million and ATR(20) is equal 5 big points. Risk per contract is then 10 big points. Now the above formula would give us:

PctSize = 1% * $5000 / ( 10 * $50 ) = 10%

10% of our 1 million equity is $100K, which allows us to buy 20 contracts (20 * $5000 each). Since our risk is 10 big points and each big point has a value of $50 we are risking 10 * $50 = $500 per contract. We have 20 contracts so entire position represents a risk 20 * $500 = $10,000 which is 1% of our 1 million equity.

How to draw regression channel programatically

Built-in drawing tool allows to place regression channel on the chart manually and the study works on regular Close array as input. The power of AFL allows to automate this task and draw a customizable regression channel automatically in the chart or choose any custom array for calculation.

Here is a sample coding solution showing how to code Standard Deviation based channel. The Parameters dialog allows to control the array the channel is based upon, number of periods used for calculation, position and width of the channel.

lookback Param"Look back"201200);
shift Param"Shift"0020);
multiplier Param"Width"10.2550.25 );
color ParamColor"Color"colorRed );
style ParamStyle"Style"styleLine styleDots );
pricestyle ParamStyle"Price style"styleBar styleThickmaskPrice );
//
// price chart
PlotClose"Close"colorDefaultpricestyle );
//
array = ParamField"Price field", -);
//
BarIndex() + 1;
lastx LastValue) - shift;
//
// compute linear regression coefficients
aa LastValueRefLinRegIntercept( array, lookback ), -shift ) );
bb LastValueRefLinRegSlope( array, lookback ), -shift ) );
//
// the equation for straight line
Aa bb * ( - ( Lastx lookback ) );
//
width LastValueRefStDev( array, lookback ), -shift ) );
//
drawit > ( lastx lookback ) AND BarIndex() < Lastx;
//
// draw regression line...
PlotIIfdrawityNull ), "LinReg"colorstyle );
// ... and channel
PlotIIfdrawitwidth*multiplier Null ), "LinReg UP"colorstyle );
PlotIIfdrawitwidth*multiplier Null ), "LinReg DN"colorstyle )

Here is the picture that shows how it looks:

Regression in AFL

How to get support most efficiently

As a customer you want to have your questions and issues resolved most quickly and it is also our goal. In order to allow us to serve you the best possible answer in shortest possible time you need to provide some essential information that we can not collect without your help.

The most essential things you need to tell us when contacting support are:

  1. AmiBroker version you are running
  2. Data source you are using
  3. Exact error message you are getting, or screenshot if problem is of “visual” type
  4. The AFL formula that you are using (if question/issue is formula-related)
    and the settings (if you want help on backtest/optimization results)

  5. … and pretty please do not yell that you found a bug (there are 99.9% chances you did not).

If we counted the hours spent on e-mail exchange that was just asking for those details it would sum up to years. Please provide those in front. We really don’t know what you are running on your end.

There are countless examples when knowledge of these details would save hours of time (not only our but your time too). For example we write a formula for somebody, then he responds “it does not work” then we ask for details on what exactly does not not work and after some hours and e-mail exchanges it turns out that the customer is using old version of the software, while our formula used a function that was introduced lately.

Version numbers

When specifying AmiBroker version number please tell the number, not just “I am using latest version”, because latest means different thing for you and different for us. Your “latest” may mean latest official release and we may mean latest BETA that we just released a couple of minutes ago, so you are not even aware of it. So to remove doubt, please tell us exact number such as “I am running v5.85.0 32-bit”. You can find exact version number in the Help->About window.

Sometimes it also helps to know Windows version. For example we have seen cases when execution speed was different on XP and Windows 7 or when some feature did not work correctly on Windows XP because of Windows bug. So if you are reporting a problem/bug please include Windows version too. In this case you don’t need to tell us exact version, so “I am running Windows XP” or “Windows 7 64-bit” is perfectly fine.

The data source

Telling us a Data source is important when you are using plugin-driven data source. Pretty often 3rd party data sources that are plugin driven can cause bizzarre issues that can not be reproduced unless we know the data source.

Tell us what the error is or how it looks

It goes without saying that knowing the actual text of error message you get is essential for us. Please quote the message precisely as sometimes actual wording differs and there may be two similar messages yet they are different and resolution is also different. For any kind of “visual” problems it is best to send a screenshot. To make a screenshot, press PRINT SCREEN key on the keyboard (to make a short of entire screen), or ALT+PRTSCREEN (to make a screenshot of just active window). This puts a screenshot to the clipboard. Now you can paste it to MS Paint, MS Word, or any other graphic application. Some e-mail clients such as Thunderbird, allows pasting such image directly from clipboard into message (Edit->Paste, or Ctrl+V).

Sometimes it may not be obvious what is wrong on the screenshot so please describe what is wrong and/or annotate graphics. It helps tremendously.

The magical formula

As far as AFL-related problems are considered, knowing the formula is essential. If we can paste your formula to editor and reproduce reported behaviour on our end helping you becomes much easier and faster. An enormous amount of time could be gained if formula in question is sent to us. If for some reason you can not send us actual formula that you are using, please try to write a small one that just demonstrates the same problematic behavior. It is even better to have such minimalistic formula as it is quicker to find problem area in shorter one. When you are reporing problem with the backtest or optimization please also include the settings. Instead of sending formula and settings separately, consider sending APX file (Analysis Project). The analysis project file has both settings and formula included and can be saved using File->Save As when Analysis window is open.

When something is bugging you

Now here it comes, the last but certainly not least hint. When you are having problems with our software, please do not claim you have found a bug unless you are very, very sure of your ground. Remember, there are many other users that are not experiencing your problem. Otherwise you would have learned about it while reading the documentation and searching the Web (you did do that before complaining, didn’t you?). This means that very probably it is you who are doing something wrong, not the software. In fact in 99.9% of past cases a suspected “bug” was a user mistake.

We put an enormous effort and engineering skills to make our software working as well as possible. If you claim you have found a bug, you will be impugning our competence, which will offend some of us even if you are correct. It is especially undiplomatic to yell bug in the Subject line.

When asking your question, it is best to write as though you assume you are doing something wrong, even if you are privately pretty sure you have found an actual bug. If there really is a bug, you will hear about it in the answer.

All of the above has one goal – enabling us to help you better and quicker. By following the guidelines above you will get your answers delivered faster and more efficiently. Thanks!

Relationship between chart panes

In order to explain possible relationships between chart panes in AmiBroker, let us first introduce two important attributes associated with each chart pane, these are Chart ID and File path.

To see these attributes, we need to right-click on the chart and choose Parameters, then Axes&Grid tab:

Parameters window

The File path defines physical AFL file on your hard-drive that contains the indicator code used to generate charts. The Chart ID is an index to AmiBroker’s internal chart table. The chart table holds chart settings such as those seen in Axes&Grid tab, including the File path. So knowing the Chart ID, AmiBroker knows everything about the chart. The Chart ID uniquely identifies the chart.

Chart ID plays important role in the following areas:

  1. Chart parameters are keyed by Chart ID so two different charts may have same names of parameters, yet parameters are independent if those charts have different ChartID.
  2. Hand-drawn studies are stored wih Chart ID assigned to it, so they “belong” to given chart and can be referenced from other formulas using Study() function
  3. Chart IDs are stored in the layout files so AmiBroker knows which charts should be loaded when layout is loaded.

When we compare two charts, then the following relations are possible:

  1. if both Chart IDs and File paths are different, then charts are completely independent. This will happen if we use Insert option from the Charts window to create a new chart pane or when we double-click on the given formula (double-click works as Insert), because AmiBroker then would create new Chart ID and independent copy of the formula as described in manual http://www.amibroker.com/guide/h_dragdrop.html

    Insert

  2. if Chart IDs are different in both chart panes but File Path is the same, then these are different charts, yet they share same formula file. In such case hand-drawn studies will not get transferred and parameters will not be shared, but drag&drop operations and changes in the formula will affect both charts. This situation will occur if we use Insert Linked option from the Charts window to create a new chart pane directly linked to the original formula.

    Insert linked

  3. if Chart ID is the same for both – then it is essentially the very same chart. It means that all the hand-drawn studies and parameters are common for both charts (changes in one chart pane will affect the other) and all the drag&drop operations or formula changes affect both charts – that is because as a result of dragging and dropping indicators the underlying code is being modified (new sections are added). Such relationship between chart panes will happen when we open another chart window that uses the same chart template as the previous window (e.g. using File->New->Default Chart) or save chart template and load it from the other window.

There is also a functionality in AmiBroker, which allows to copy-paste the selected chart pane and define which elements are pasted. To do that click on the pane you want to copy, choose Edit->Copy from the menu, then switch to the place where you want to paste it and choose Edit->Paste Special

Paste Special

Choosing first option creates new Chart ID, and creates a copy of formula, so resulted chart is independent from source chart. Choosing second option creates new Chart ID, but links it to same formula as original, so the formula is shared. Choosing third option inserts a pane that uses same Chart ID (identical chart, everything shared).

Paste Special window

« Previous PageNext Page »