Python is the most popular interactive script language, created by Guido van Rossum and first released in 1991. Spaces, tabs and line feeds matter in Python code, and enforce a clean code style with correct indentations. Python is interpreted and thus slow compared to compiled languages like C. So it is not suited for high-speed strategies, but its strengths are a simple and modern syntax, and access to all sorts of libraries for machine learning and data analysis. Many tasks can be solved in the same way in lite-C as well as in Python, but Python often has already a dedicated command implemented or library available for that.
There are two methods to run Python code from Zorro. The Python bridge allows directly calling Python functions from a Zorro script and using their results for trade signals. A script can start a Python session, send price data or indicator values to it, and use Python machine learning packages for training and prediction. Alternatively, Zorro can directly call the Python interpreter pythonw.exe and exchange data via files. This method is slower, but works even when the used Python library does not support embedded Python. Examples for both methods are can be found below.
Make sure that any needed Python module is installed to your Python folder (don't use the pip --user option). Afterwards the module can be mounted with the import statement. Please read the remarks about issues with particular modules.
The following functions are available via Python bridge for sending data to Python, performing computations, and receiving data back:
Filename |
Name of a .py file in the Strategy folder containing all needed Python functions and variables (f.i. "MySource.py"), or 0 for not loading a file. |
Mode |
A combination of the following flags, otherwise 0. |
Code | Python code to be executed. Separate lines with \n and mind whitespace indentations. |
Name | Name of the Python variable to be set (see remarks). |
i | int value to be assigned to a Python integer variable. |
d | var value to be assigned to a Python floating point variable. |
s | char* string to be assigned to a Python Unicode string variable. |
v | Pointer of the var array or series to be assigned to a Python list. |
elements | Length of the vector or series. Make sure to give the exact number of elements. |
Name | Name of a Python variable, previously defined by pyX or pySet (see remarks). |
v | Pointer of the var array to be filled with the Python list. |
elements | Number of elements of the vector; must be identical in the Python code and in the lite-C script. |
// run some Python code function main() { if(!pyStart(0,1)) { printf("Error - Python won't start!"); return; } var Vec[5] = { 0,1,2,3,4 }; pySet("PyVec",Vec,5); pyX("for i in range(5): PyVec[i] *= 10\n"); pyVec("PyVec",Vec,5); int i; printf("\nReturned: "); for(i=0; i<5; i++) printf("%.0f ",Vec[i]); // test a function pyX("def PySum(V):\n Sum = 0.0\n for X in V:\n Sum += X\n return Sum\n\n"); pyX("Result = PySum(PyVec)"); printf("\nSum: %.0f",pyVar("Result")); }
// run a Python function function main() { if(!pyStart("MyPythonScript.py",1)) { printf("Error - Python script won't start!"); return; } pyX("Result = MyPythonFunction()"); var Result = pyVar("Result"); printf("\nResult: %.2f",Result); }
// trade by a Python signal function run() { if(is(INITRUN)) if(!pyStart("MyPythonScript.py",1)) return quit("Error - Python script won't start!"); asset(Asset); pySet("Price",priceC()); // send current price to Python pyX("Signal = PythonTradeAlgorithm(Price)"); int Signal = pyInt("Signal"); // received trade signal if(Signal > 0) enterLong(); else if(Signal < 0) enterShort(); }
// start Python interpreter and process a data array // Python side: -------------------------------- #read signals from file Signals = [] with open("Data/In.txt","r") as File: for Line in File: Signals.append(float(Line)) # process signals and write result back to file Processed = processMyData(Signals) with open("Data/Out.txt","w") as File: for Line in Processed: File.write(str(Line)) File.write('\n') // Zorro side: -------------------------------- / send signals to file string Content = zalloc(NumSignals*32); for(i=0; i<NumSignals; i++) strcat(Content,strf("%.4f\n",Signals[i])); file_write("Data\\In.txt",Content,0); // call the Python interpreter string PythonPath = "MyPythonPath\\Pythonw"; exec(PythonPath,"Strategy/MyPython.py",1); // get returned signals file_read("Data\\Out.txt",Content,NumSignals*32); Signals[0] = atof(strtok(Content,"\n")); for(i=1; i<NumSignals; i++) Signals[i] = atof(strtok(0,"\n")); ...