Skip to content

Instantly share code, notes, and snippets.

@izikeros
Forked from rodrigo-brito/main.py
Last active March 14, 2024 09:58
Show Gist options
  • Save izikeros/684a76ffb77268772b25d5c0e5191cc9 to your computer and use it in GitHub Desktop.
Save izikeros/684a76ffb77268772b25d5c0e5191cc9 to your computer and use it in GitHub Desktop.
[Trading on Binance] using Backtrader and CCXT #crypto

Backtrader integration with Binance

Backtrader does not allows natively for trading on Binance however it supports CCXT which is an universal interface to multiple exchanges. This example uses CCXT to allow Backtrader perform trades on this exchange.

Requirements

Create virtualenv, install ccxt store for backtrader:

pip install git+git://github.com/Dave-Vallance/bt-ccxt-store@master#bt-ccxt-store

and backtrader package

Usage

In Binance generate API key that can be used for trading, provide apiKey and secret in broker_config dict.

Credits

original gist by Rodrigo Brito

found via post in bt community page: https://community.backtrader.com/topic/1689/example-code-for-live-trading-using-binance/5

#!/usr/bin/env python3
import time
import backtrader as bt
import datetime as dt
from ccxtbt import CCXTStore
DEBUG = True
class CustomStrategy(bt.Strategy):
def __init__(self):
self.order = None
self.last_operation = "BUY"
self.status = "DISCONNECTED"
def notify_data(self, data, status, *args, **kwargs):
self.status = data._getstatusname(status)
if status == data.LIVE:
self.log("LIVE DATA - Ready to trade")
else:
print(dt.datetime.now().strftime("%d-%m-%y %H:%M"), "NOT LIVE - %s" % self.status)
def next(self):
if self.status != "LIVE":
self.log("%s - $%.2f" % (self.status, self.data0.close[0]))
return
if self.order:
return
print('*' * 5, 'NEXT:', bt.num2date(self.data0.datetime[0]), self.data0.close[0])
def notify_order(self, order):
if order.status in [order.Submitted, order.Accepted]:
return
if order.status in [order.Completed]:
if order.isbuy():
self.log(
'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
(order.executed.price,
order.executed.value,
order.executed.comm))
self.buyprice = order.executed.price
self.buycomm = order.executed.comm
else:
self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
(order.executed.price,
order.executed.value,
order.executed.comm))
self.bar_executed = len(self)
elif order.status in [order.Canceled, order.Margin, order.Rejected]:
self.log('Order Canceled/Margin/Rejected %s' % order.status)
self.last_operation = None
# Write down: no pending order
self.order = None
def notify_trade(self, trade):
if not trade.isclosed:
return
color = 'green'
if trade.pnl < 0:
color = 'red'
self.log(colored('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm), color))
def log(self, txt):
if not DEBUG:
return
dt = self.data0.datetime.datetime()
print('[%s] %s' % (dt.strftime("%d-%m-%y %H:%M"), txt))
def main():
cerebro = bt.Cerebro(quicknotify=True)
broker_config = {
'apiKey': "*****************",
'secret': "*****************",
'nonce': lambda: str(int(time.time() * 1000)),
'enableRateLimit': True,
}
store = CCXTStore(exchange='binance', currency='BTC', config=broker_config, retries=5, debug=True)
broker_mapping = {
'order_types': {
bt.Order.Market: 'market',
bt.Order.Limit: 'limit',
bt.Order.Stop: 'stop-loss', # stop-loss for kraken, stop for bitmex
bt.Order.StopLimit: 'stop limit'
},
'mappings': {
'closed_order': {
'key': 'status',
'value': 'closed'
},
'canceled_order': {
'key': 'result',
'value': 1
}
}
}
broker = store.getbroker(broker_mapping=broker_mapping)
cerebro.setbroker(broker)
hist_start_date = dt.datetime.utcnow() - dt.timedelta(minutes=2000)
data = store.getdata(
dataname='BTC/USDT',
name="BTC/USDT",
timeframe=bt.TimeFrame.Minutes,
fromdate=hist_start_date,
compression=30,
ohlcv_limit=99999
)
cerebro.adddata(data)
cerebro.addstrategy(CustomStrategy)
initial_value = cerebro.broker.getvalue()
print('Starting Portfolio Value: %.2f' % initial_value)
result = cerebro.run()
final_value = cerebro.broker.getvalue()
print('Final Portfolio Value: %.2f' % final_value)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("finished by user.")
time = dt.datetime.now().strftime("%d-%m-%y %H:%M")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment