The general code structure of an indicator ‘module’ looks like this:
HELPER_FUNCTION_DEFINITIONS, DECORATED_HELPER_FUNCTION_DEFINITIONS, CLASS_DEFINITIONS and MAIN_FUNCTION_OR_CLASS_DEFINITION can go in any order.
Syntactically, Indie code is Python code. But, there are some
differences that you may want to be aware of.
Comment directives are special comments that have some effect on how Indie’s compiler and/or runtime works.
At the moment there is only one comment directive which is:
and it declares the language version of the source code of the indicator.
Imports
The IMPORTS section consists of several import statements. Every import statement tells Indie the runtime to import
(or connect) one or more symbols from libraries. After that these symbols may
be used in the indicator code.
Like in Python, there are several different forms of imports:
Also in every from form you are allowed to use lists of symbols, for example:
One note about the aliases. Do not use them if you do not really need them. And you most certainly will need them in two
cases:
- You have a name clash of two symbols from different libraries. Add an alias to one or both of the symbols to
resolve the clash. For example:
Obviously, when you try to call the imported function foobar_func() afterwards, it is unclear which one of the two
imported functions should be called. Such code cannot be run and produces an error.
Same example with a name clash resolved:
- You import a symbol with a long name, and it is very uncomfortable to use that long name in the code:
Instead, it is better to use an alias:
Helper function definitions
Indicator algorithms can be quite complex, so it is a good coding style to extract blocks of code into
helper functions with some meaningful names. The minimal function that accepts no arguments, does nothing
(Python keyword pass is about that) and returns nothing (None) looks like this:
Obviously there will be not much help of such a helper function like minimal_helper_func, it’s just an example.
Here is a more realistic example of a function that calculates a maximum of given two integers:
At the moment, it is mandatory to declare type hints for every argument as well as for the return value of all the
functions (except for the Main function and @sec_context-decorated functions). Read more about typing in the
Data types in Indie chapter.
Decorated helper function definitions
There are two decorators that can be applied to helper functions: @algorithm and @sec_context. Both of them are
syntactic sugar decorators which help a lot in making indicator code compact and readable.
The @algorithm decorator is a syntactic sugar for making your own
series processing algorithm like indie.algorithms.Sma.
The @sec_context decorator is a syntactic sugar for making an extra entry point function (like a secondary Main) for
additional instrument that indicator may request. This function should be used in combination with a Context.calc_on
function. Read more about it in Request additional instruments.
Class definitions
From Indie v4 the language partially supports OOP and this
support is going to be expanded. At the moment this means that Indie has a class keyword that allows you to declare classes,
just like in Python.
For example the Main entry point could be declared not as a function, but as a class, like this:
Constructor (the __init__ method) could be optionally added too. It is very useful because it is a good place for some
initialization code that must be executed only once. For example:
Secondary contexts can be declared as classes (instead of using @sec_context decorator on a func) in a similar way,
for example:
Finally, algorithms (instead of using @algorithm decorator on a func) can be declared as classes too, for example:
Main function or class definition
The Main entry point of the whole indicator is mandatory. It is called every time the indicator receives a candle data
update and it should return an indicator result for that piece of data. It must have at least one parameter self which
is a reference to an object of the Main class (inherited from MainContext type).
Function or class Main must also be decorated with a @indicator decorator. But
also other decorators could be added here, for example: