Using AmiPy with Python Jupyter Notebooks

I vastly prefer Amibroker to Python for my backtesting, but I do really like the Python Jupyter Notebook as a way to document my research. I noticed this Amibroker Forum Post awhile back as well, so I guess it's not just me.

The way I have been doing my backtesting in Amibroker but recording research in Jupyter Notebook is as follows:

  1. Backtest in Amibroker
  2. Write equity curves to CSV files
  3. Import CSV files into Jupyter Notebook as a pandas dataframe
  4. Plot the data in the pandas dataframe in Jupyter Notebook

Though this serves my purpose, it is several steps and is pretty cumbersome. With the availability of AmiPy now, I was wondering if it is possible to do this all in one step? I can see how I could do this with a .py file, by using PyLoadFromFile and PyEvalFunction, and then coding the plotting in the .py file, but is there anyway to get the output directly into a Jupyter Notebook?

Thank you.

1 Like

i do not know about Jupiter but you can directly put data from Amibroker into a Pandas dataframe in Python.

I made an example here below. It shows how you can transfer data from Amibroker to a Python Pandas dataframe


Thank you. What you've done is essentially the rough steps I had for implementation in my head (though yours is without a doubt more elegant and I will shamelessly use yours as a base when building mine).

Unfortunately the step that is sticking me is how to get the chart into Jupyter Notebook. It's not really the plot itself I'm after, since I've already got the plot in Amibroker. I had also figured out the base steps to get the .py file to plot the chart using pandas dataframe, but the step that was/is really sticking me is getting it into the Jupyter Notebook.

Nevertheless, thank you very much for the example, as I said, I will copy shamelessly to build my own code (for personal purposes - if I ever wind up publishing said code on any forum for example, I will obviously credit you).

I played with Jupyter briefly but actually know nothing about it. But I hope you succeed and show us how it can be used once you figured it out

1 Like

Thank you. I've actually just found out that there may be a Python module that can help me: nbformat

I will slowly (trust me, everything I do is slow) figure out how to use it, and then try to build something that can write the plot to the Notebook. If I am successful I will share the code here. Thanks again for the advice.


Hi, I think I've got something. Happy to be sharing it with the community, as I've had many questions of mine answered here, so hopefully finally able to give something back. The answer was the nbformat module I mentioned earlier. The code isn't really plug and play, but should be enough there for someone who understands a little bit of afl and little bit of Python to use it.

Amibroker code here, must be run as a scan using Apply to: *Current on the ~~~EQUITY curve you want to export. I would recommend changing the name of the ~~~EQUITY ticker to something of note, I have used ~Research28 in my example. My plan is to use a unique project (.apx) file and code (.afl) file also called Research28, so I will be able to always have a cross reference between the equity curve I am viewing in my Jupyter Notebook and the AB code and settings that were used to generate it.

PyLoadFromFile( "ExportCurve", "C:\\Sample Code\\" );

//	Make up a parameter where we can enter the notebook name was want the curve inserted into, this must be a notebook that is already created
notebookname = ParamStr( "Notebook Name", StrTrim( Name(), "~", 1 ) );	
//	Since when backtesting I create my own Composite tickers to store equity curves and preface with a tilda (~), the default name for the note book is just the symbol name less the tilda

path = "C:\\Sample Code\\" + StrTrim( Name(), "~", 1 ) + ".csv";

//	Below is the code we use to write the equity curve data to a CSV file.
//	By writing it to a CSV file, the data is always there and we can use the Jupyter notebook regarless of whether AB is open

Code for writing a CSV file taken from "Quantitative Technical Analysis" written by Dr. Howard Bandy and published bSample Codey Blue Owl Press, Inc.
Copyright  2014 Howard Bandy

Author: Howard Bandy
Blue Owl Press, Inc.

//	First check if the file exists, as we do not want to overwrite an existing file.
filestatus = fgetstatus( path, 3 );

if ( IsNull(filestatus) )
	_TRACE("This file does not exist, ok to create it.");

	fh = fopen( path, "w" );

	if ( fh )
		fputs( "Ticker,Date,Hr:Min,Open,High,Low,Close,Volume\n",
			   fh );
		nm = Name();
		y = Year();
		m = Month();
		d = Day();
		Hr = Hour();
		Mn = Minute();

		for ( i = 0; i < BarCount; i++ )
			ns = nm + ",";
			fputs( ns, fh );
			ds = StrFormat( "%02.0f-%02.0f-%02.0f,",
							y[ i ], m[ i ], d[ i ] );
			fputs( ds, fh );
			ts = StrFormat( "%02.0f:%02.0f,",
							hr[ i ], mn[ i ] );
			fputs( ts, fh );
			qs = StrFormat( "%.4f, %.4f, %.4f, %.4f, %.0f\n",
							O[ i ], H[ i ], L[ i ], C[ i ], V[ i ] );
			fputs( qs, fh );

		fclose( fh );
	_TRACE("File of the same name already exists, please delete file before proceeding.");

PyEvalFunction( "ExportCurve", "WriteToJupyter", StrTrim( Name(), "~", 1 ), notebookname );

This also writes the equity curve to a csv file on the hard drive, so that the data is always there and we can use the Jupyter Notebook later independently without having AB open.

Then the python code. Note that the Jupyter notebook must already have been created. For me this isn't an issue because I will have one already created with a heading, aim, introduction, etc, I don't just want a chart at the start of my notebook.

import AmiPy
import nbformat

def WriteToJupyter( csvfilename, notebookname ):

    # assume that the Jupyter notebook already exists
    notebook ="C:\\Sample Code\\" + notebookname + ".ipynb", as_version=4)

    path = "C:\\Sample Code\\" + csvfilename + ".csv"
    # These blocks make up the code for the written text
    text1 = "This equity curve is taken from the equity curve data in the CSV file: "
    text2 = path
    text3 = ". To trace back the construction of the equity curve, note that an Amibroker project (apx) and code (afl) file have been named with the same name."
    # These blocks make up the code to plot the equity curve
    code1 = "import pandas as pd\nimport datetime as dt\nimport matplotlib.pyplot as plt\n%matplotlib inline\ndf = pd.read_csv( '"
    code2 = path
    code3 = "')\ndf = df.set_index('Date', inplace=False)\ndf.index = pd.to_datetime( df.index )\ndf.drop( columns = ['Ticker', 'Hr:Min' ], inplace=True )\n"
    code4 = "df.rename( columns = {'Close': 'Closed Profit', 'Open': 'Open Profit', 'Low': 'Open Trade Count', 'High': 'Capital In Trades', 'Volume': 'Closed Drawdown'}, inplace=True)\n"
    code5 = "df['Open Drawdown'] = df['Open Profit'] - df['Open Profit'].cummax()\nfig, (ax1, ax2 ) = plt.subplots(2, 1, gridspec_kw={'height_ratios': [2.5, 1] }, sharex=True, figsize=(20,15) )\n"
    code6 = "ax1.plot( df.index, df['Open Profit'], color='green' )\nax2.plot( df.index, df['Open Drawdown'], color='red')\nax1.grid()\nax2.grid()\"
    # Make the text and code fragments a list, for entry into nbformat
    text = [ text1, text2, text3 ]
    code = [ code1, code2, code3, code4, code5, code6 ]

    cells = [nbformat.v4.new_markdown_cell(text), nbformat.v4.new_code_cell(code)]

    nbformat.write(notebook,'C:\\Sample Code\\' + notebookname + '.ipynb')

Excuse the novice formatting of the code, it's well because I'm a novice. Hopefully this might be useful for someone else like me that loves the power and usability of Amibroker, but has become accustomed to using Jupyter Notebooks to record research.


Here is what the chart looks like in Amibroker (SPY with a 10,200 MA crossover just for example):


And here is the output in the Jupyter notebook:


Obviously, all this messy code an be cleaned up using functions, but for transparency I've left everything without using functions.


Big thank you to @empottasch , I didn't end up using his code directly as I thought I would, but his ideas were very helpful in leading me towards finding a solution that worked for me.

1 Like

thanks for the feedback. I will have a look in some more detail a bit later or in the weekend

1 Like