Quickstart

Ready to get started ? This page gives a good introduction on how to get started with Basana.

Installation

Basana requires Python 3.10 or above and to install the package you can use the following command:

$ pip install basana[charts]

The examples at GitHub take advantage of TALIpp, Pandas and statsmodels. These can be installed using the following command:

$ pip install talipp pandas statsmodels

Backtesting

Most of the examples that follow are structured like this:

  • A trading strategy that implements the set of rules that define when to enter or exit a position based on market conditions. Strategies generate events, called trading signals, to notify a switch in position for one or more trading pairs.

  • A position manager that is responsible for executing trades in response to trading signals generated by the strategy. The examples include a backtesting position manager and a Binance position manager. These position managers are using market orders to keep examples short, but you’ll probably want to use limit orders when writing your own position managers.

Note

These examples are provided for educational purposes only. Use at your own risk, specially the live trading ones.

The way the examples are structured is just one way to do it. You’re free to structure the code in any other way.

The strategy that we’re going to use for backtesting is based on Bollinger Bands and the purpose of this example is just to give you an overview on how to connect the different pieces together.

The first thing we’ll need in order to execute the backtest is historical data. Use the following command to download bars from Binance:

$ python -m basana.external.binance.tools.download_bars -c BTC/USDT -p 1d -s 2021-01-01 -e 2021-12-31 -o binance_btcusdt_day.csv

There are two types of events taking place in this example:

  • Bar (OHLC) events generated by the exchange.

  • Trading signals generated by the strategy.

When a new bar is received by the strategy, a technical indicator will be fed using the bar’s closing price. If the technical indicator is ready, the strategy will check the values to determine if a switch in position should take place, and in that case a trading signal will be pushed.

When the trading signal is received by the position manager, a buy or sell market order will be submitted to the exchange in order to open or close a position.

This is how all the pieces are put together:

event_dispatcher = bs.backtesting_dispatcher()
pair = bs.Pair("BTC", "USDT")
position_amount = Decimal(1000)
stop_loss_pct = Decimal(5)

# We'll be opening short positions so we need to set a lending strategy when initializing the exchange.
lending_strategy = lending.MarginLoans(
    pair.quote_symbol, Decimal("0.5"),
    default_conditions=lending.MarginLoanConditions(
        interest_symbol=pair.quote_symbol, interest_percentage=Decimal("7"),
        interest_period=datetime.timedelta(days=365), min_interest=Decimal("0.01"),
    )
)
exchange = backtesting_exchange.Exchange(
    event_dispatcher,
    initial_balances={pair.quote_symbol: Decimal(1200)},
    fee_strategy=backtesting_fees.Percentage(percentage=Decimal("0.1"), min_fee=Decimal("0.01")),
    lending_strategy=lending_strategy,
    immediate_order_processing=True
)
exchange.set_symbol_precision(pair.base_symbol, 8)
exchange.set_symbol_precision(pair.quote_symbol, 2)
exchange.add_bar_source(csv.BarSource(pair, "binance_btcusdt_day.csv", "1d"))

# Connect the strategy to the bar events from the exchange.
strategy = bbands.Strategy(event_dispatcher, period=30, std_dev=2)
exchange.subscribe_to_bar_events(pair, strategy.on_bar_event)

# Connect the position manager to different types of events.
position_mgr = position_manager.PositionManager(
    exchange, position_amount, pair.quote_symbol, stop_loss_pct
)
strategy.subscribe_to_trading_signals(position_mgr.on_trading_signal)
exchange.subscribe_to_bar_events(pair, position_mgr.on_bar_event)
exchange.subscribe_to_order_events(position_mgr.on_order_event)

The full source code for this example can be found here, and if you fork the repository, or download and unzip samples, you can execute the backtest using the following command:

$ python -m samples.backtest_bbands

A chart similar to this one should open in a browser:

_images/backtesting_bbands.png

Live trading

The strategy that we’re going to use for live trading is the exact same one that we used for backtesting, but instead of using a backtesting exchange we’ll use Binance crypto currency exchange.

event_dispatcher = bs.realtime_dispatcher()
pair = bs.Pair("ETH", "USDT")
position_amount = Decimal(100)
stop_loss_pct = Decimal(5)
checkpoint_fname = "binance_bbands_positions.json"
api_key = "YOUR_API_KEY"
api_secret = "YOUR_API_SECRET"

exchange = binance_exchange.Exchange(event_dispatcher, api_key=api_key, api_secret=api_secret)

# Connect the strategy to the bar events from the exchange.
strategy = bbands.Strategy(event_dispatcher, period=20, std_dev=1.5)
exchange.subscribe_to_bar_events(pair, "1m", strategy.on_bar_event)

# We'll be using the spot account, so there will be no short positions opened.
position_mgr = position_manager.SpotAccountPositionManager(
    exchange, position_amount, pair.quote_symbol, stop_loss_pct, checkpoint_fname
)
# Connect the position manager to different types of events.
strategy.subscribe_to_trading_signals(position_mgr.on_trading_signal)
exchange.subscribe_to_bar_events(pair, "1m", position_mgr.on_bar_event)
exchange.spot_account.subscribe_to_order_events(position_mgr.on_order_event)

Note

These examples provided are for educational purposes only.

If you decide to execute them with real credentials you are doing that AT YOUR OWN RISK.

You can start live trading using the following command:

$ python -m samples.binance_bbands

Next steps

The examples presented here, and many others, can be found at the examples folder at GitHub.