advanced config
On AILidex script, similarly to TradingView pinescript, a trading strategy is a python async function that will be called at new price data.
async def strategy(ctx):
# your strategy content
In most cases, a strategy will:
Read price data
Use technical evaluators or statistics
Decide to take (or not take) action depending on its configuration
Create / cancel or edit orders (see Creating orders)
As AILidex script strategies are meant for backtesting, it is possible to create a strategy in 2 ways:
Pre-computed strategies
Pre-computed are only possible in backtesting: since the data is already known, when dealing with technical evaluator based strategies, it is possible to compute the values of the evaluators for the whole backtest at once. This approach is faster than iterative strategies as evaluators call only called once.
Warning: when writing a pre-computed strategy, always make sure to associate the evaluator values to the right time otherwise you might be reading data from the past of the future when running the strategy.
config = {
“period”: 10,
“rsi_value_buy_threshold”: 28,
}
run_data = {
“entries”: None,
}
async def strategy(ctx):
if run_data[“entries”] is None:
# 1. Read price data
closes = await obs.Close(ctx, max_history=True)
times = await obs.Time(ctx, max_history=True, use_close_time=True)
# 2. Use technical evaluators or statistics
rsi_v = tulipy.rsi(closes, period=ctx.tentacle.trading_config[“period”])
delta = len(closes) – len(rsi_v)
# 3. Decide to take (or not take) action depending on its configuration
run_data[“entries”] = {
times[index + delta]
for index, rsi_val in enumerate(rsi_v)
if rsi_val < ctx.tentacle.trading_config[“rsi_value_buy_threshold”]
}
await obs.plot_indicator(ctx, “RSI”, times[delta:], rsi_v, run_data[“entries”])
if obs.current_live_time(ctx) in run_data[“entries”]:
# 4. Create / cancel or edit orders
await obs.market(ctx, “buy”, amount=”10%”, stop_loss_offset=”-15%”, take_profit_offset=”25%”)
This pre-computed strategy computes entries using the RSI: times of favorable entries are stored into run_data[“entries”] which is defined outside on the strategy function in order to keep its values throughout iterations.
Please note the max_history=True in obs.Close and obs.Time keywords. This is allowing to select data using the whole run available data and only call tulipy.rsi once and populate run_data[“entries”] only once.
In each subsequent call, run_data[“entries”] is None will be True and only the last 2 lines of the strategy will be executed.
Iterative strategies
config = {
“period”: 10,
“rsi_value_buy_threshold”: 28,
}
async def strategy(ctx):
# 1. Read price data
close = await obs.Close(ctx)
if len(close) <= ctx.tentacle.trading_config[“period”]:
# not enough data to compute RSI
return
# 2. Use technical evaluators or statistics
rsi_v = tulipy.rsi(close, period=ctx.tentacle.trading_config[“period”])
# 3. Decide to take (or not take) action depending on its configuration
if rsi_v[-1] < ctx.tentacle.trading_config[“rsi_value_buy_threshold”]:
# 4. Create / cancel or edit orders
await obs.market(ctx, “buy”, amount=”10%”, stop_loss_offset=”-15%”, take_profit_offset=”25%”)
This iterative strategy is similar to the above pre-computed strategy except that it is evaluating the RSI at each candle to know if an entry should be created.
This type of strategy is simpler to create than a pre-computed strategy and can be used in AILidex live trading.
Running a strategy
When running a backtest, a strategy should be referenced alongside:
The data it should be run on using obs.run:
Its configuration (a dict in above examples, it could be anything)
res = await obs.run(data, strategy, config)
Have a look at the demo script for a full example of how to run a strategy within a python script.
Creating Trading Orders
Creating trading orders
Orders can be created using the following keywords:
market
limit
stop_loss
trailing_market
Amount
Each order accept the following optional arguments:
amount: for spot and futures trading
target_position: futures trading only: create the associated order to update to position size to the given value. Uses the same format as the order amount.
To specify the amount per order, use the following syntax:
0.1 to trade 0.1 BTC on BTC/USD
2% to trade 2% of the total portfolio value
12%a to trade 12% of the available holdings
create a buy market order using 10% of the total portfolio
await obs.market(ctx, “buy”, amount=”10%”)
Price
Orders set their price using the offset argument.
To specify the order price, use the following syntax:
10 to set the price 10 USD above the current BTC/USD market price
2% to set the price 2% USD above the current BTC/USD market price
@15555 to set the price at exactly 15555 USD regardless of the current BTC/USD market price
create a buy limit order of 0.2 units (BTC when trading BTC/USD)
with a price at 1% below the current price
await obs.limit(ctx, “buy”, amount=”0.2″, offset=”-1%”)
Note: market orders do not accept the offset argument.
Automated take profit and stop losses
When creating orders, it is possible to automate the associated stop loss and / or take profits. When doing to, the associated take profit/stop loss will have the same amount as the initial order.
Their price can be set according to the same rules as the initial order price (the offset argument) using the following optional argument:
stop_loss_offset: automate a stop loss creation when the initial order is filled and set the stop loss price
take_profit_offset: automate a take profit creation when the initial order is filled and set the take profit price
create a buy limit order of 0.2 units (BTC when trading BTC/USD) with:
– price at 1% below the current price
– stop loss at 10% loss
– take profit at 15% profit
await obs.limit(ctx, “buy”, amount=”0.2″, offset=”-1%”, stop_loss_offset=”-10%”, take_profit_offset=”15%”)
When using both stop_loss_offset and take_profit_offset, two orders will be created after the initial order fill. Those two orders will be grouped together, meaning that if one is cancelled or filled, the other will be cancelled.
Futures trading
Opening a position
Use regular orders to open a position. When the order is filled, the associated position will be created, updated or closed.
A sell order will open a short position if your balance becomes negative after filling this order.
Closing a position
Set the position size to 0 to close it. You can do it either by:
Filling an order with the same amount as the position size and an opposite side
Or using target_position=0 as order parameters
Updating leverage
Use set_leverage to update the current leverage value when trading futures.
await obs.set_leverage(ctx, 5)