Giter Club home page Giter Club logo

bt-ccxt-store's Introduction

bt-ccxt-store

A fork of Ed Bartosh's CCXT Store Work with some additions added for a projects I have been working on.

Some additions have been made to this repo that I find useful. Your mileage may vary.

Check out the example script to see how to setup and run on Kraken.

Additions / Changes

CCXTBroker

  • Added check for broker fills (complete notification, Cancel notification). Note that some exchanges may send different notification data

  • Broker mapping added as I noticed that there differences between the expected order_types and retuned status's from canceling an order

  • Added a new mappings parameter to the script with defaults.

  • Added a new get_wallet_balance method. This will allow manual checking of the balance. The method will allow setting parameters. Useful for getting margin balances

  • Modified getcash() and getvalue(): Backtrader will call getcash and getvalue before and after next, slowing things down with rest calls. As such, these will just return the last values called from getbalance(). Because getbalance() will not be called by cerebro, you need to do this manually as and when
    you want the information.

  • Note: The broker mapping should contain a new dict for order_types and mappings like below:

  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}
              }
      }
  • Added new private_end_point method to allow using any private non-unified end point. An example for getting a list of postions and then closing them on Bitfinex is below:
      # NOTE - THIS CLOSES A LONG POSITION. TO CLOSE A SHORT, REMOVE THE '-' FROM
      # -self.position.size
      type = 'Post'
      endpoint = '/positions'
      params = {}
      positions = self.broker.private_end_point(type=type, endpoint=endpoint, params=params)
      for position in positions:
          id = position['id']
          type = 'Post'
          endpoint = '/position/close'
          params = {'position_id': id}
          result = self.broker.private_end_point(type=type, endpoint=endpoint, params=params)
          _pos = self.broker.getposition(data, clone=False)
          # A Price of NONE is returned form the close position endpoint!
          _pos.update(-self.position.size, None)

CCXTStore

Redesigned the way that the store is intialized, data and brokers are requested. The store now uses metaparams and has methods for getbroker() and getdata(). A store is initialized in a similar way to other backtrader stores. e.g

# Create a cerebro
  cerebro = bt.Cerebro()

  config = {'urls': {'api': 'https://testnet.bitmex.com'},
                   'apiKey': apikey,
                   'secret': secret,
                   'enableRateLimit': enableRateLimit,
                  }

  # Create data feeds
  store = CCXTStore(exchange='bitmex', currency=currency, config=config, retries=5, debug=False)

  broker = store.getbroker()
  cerebro.setbroker(broker)

  hist_start_date = datetime.utcnow() - timedelta(minutes=fromMinutes)
  data = store.getdata(dataname=symbol, name="LTF",
                           timeframe=get_timeframe(timeframe), fromdate=hist_start_date,
                           compression=1, ohlcv_limit=50, fetch_ohlcv_params = {'partial': False}) #, historical=True)
  • Added new private_end_point method to allow using any private non-unified end point. For an example, see broker section above.

CCXTFeed

  • Added option to send some additional fetch_ohlcv_params. Some exchanges (e.g Bitmex) support sending some additional fetch parameters.
  • Added drop_newest option to avoid loading incomplete candles where exchanges do not support sending ohlcv params to prevent returning partial data
  • Added Debug option to enable some additional prints

bt-ccxt-store's People

Contributors

dave-vallance avatar obiben avatar qinwang-ai avatar sandroboehme avatar viper7882 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bt-ccxt-store's Issues

can't resample data

Hi there,

I'm trying to add 1 minute data to CCXTFeed, and then resample it to 5 minutes, so I can get MACD of 1m and 5m. But failed.

Here's the code:

# !/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
import sys
import time
from datetime import datetime, timedelta

import backtrader as bt
from ccxtbt import CCXTFeed

class TestStrategy(bt.Strategy):
    params = (
        ('printlog', True),
    )

    def log(self, txt, dt=None, doprint=False):
        ''' Logging function fot this strategy'''
        if self.params.printlog or doprint:
            dt = dt or bt.num2date(self.data.datetime[0])
            print('%s, %s' % (dt, txt))

    def start(self):
        self.counter = 0
        print('START')

    def prenext(self):
        self.counter += 1
        print('prenext len %d - counter %d' % (len(self), self.counter))

    def __init__(self):
        self.macd = bt.indicators.MACDHisto(self.datas[0])
        self.macd2 = bt.indicators.MACDHisto(self.datas[1])


    def next(self):
        self.counter += 1
        price_txt = "Counter: " + str(self.counter) + " Open/Close/High/Low/Volume: " + str(self.data0.open[0]) + " - "+ str(self.data0.close[0]) + " - " + str(self.data0.high[0]) + " - " + str(self.data0.low[0])  + " - " + str(self.data0.volume[0]) + " Len: "+ str(len(self.data0))# + " Time Frame:" + bt.TimeFrame.getname(self.data0._timeframe) + " Len: "+ str(len(self.data0))
        self.log(price_txt)
        macd_txt = "MACD: {:.2f}, Histo: {:.2f}".format(self.macd.macd[0],self.macd.histo[0])
        self.log("MACD#1: " + macd_txt)
        macd2_txt = "MACD: {:.2f}, Histo: {:.2f}".format(self.macd2.macd[0],self.macd2.histo[0])
        self.log("MACD#2: " + macd2_txt)
    
    def notify_data(self, data, status, *args, **kwargs):
        dn = data._name
        dt = datetime.now()
        msg= 'Data Status: {}'.format(data._getstatusname(status))
        print(dt,dn,msg)
        if data._getstatusname(status) == 'LIVE':
            self.live_data = True
        else:
            self.live_data = False

if __name__ == '__main__':
    #cerebro = bt.Cerebro(quicknotify=True)
    cerebro = bt.Cerebro()

    

    #exchange = sys.argv[1] if len(sys.argv) > 1 else 'gdax'
    exchange = sys.argv[1] if len(sys.argv) > 1 else 'binance'
    symbol = sys.argv[2] if len(sys.argv) > 2 else 'ETH/USDT'

    #store = CCXTStore(exchange=exchange, currency='LTC', config=config, retries=5, debug=False)

    hist_start_date = datetime.utcnow() - timedelta(minutes=10)
    print('UTC NOW: ', datetime.utcnow())
    print('hist_start_data: ', hist_start_date)
    print('Using symbol: ', symbol)

    data = CCXTFeed(exchange=exchange,
                             dataname=symbol,
                             timeframe=bt.TimeFrame.Minutes,
                             fromdate=hist_start_date,
                             #todate=datetime(2019, 1, 1, 0, 2),
                             compression=1,
                             ohlcv_limit=2,
                             currency='USDT',
                             retries=5,

                             # 'apiKey' and 'secret' are skipped
                             config={'enableRateLimit': True, 'nonce': lambda: str(int(time.time() * 1000))})

    cerebro.adddata(data)
    cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes, compression=2)

    cerebro.addstrategy(TestStrategy)
    # Run the strategy
    cerebro.run()

And here's the output:

python ccxtbttest.py             
UTC NOW:  2019-06-21 07:19:54.687534
hist_start_data:  2019-06-21 07:09:54.687358
Using symbol:  ETH/USDT
START
2019-06-21 15:20:01.656669 ETH/USDT Data Status: DELAYED
prenext len 1 - counter 1
prenext len 2 - counter 2
2019-06-21 15:20:03.363956 ETH/USDT Data Status: LIVE
prenext len 3 - counter 3
prenext len 4 - counter 4
prenext len 5 - counter 5
prenext len 6 - counter 6
prenext len 7 - counter 7
prenext len 8 - counter 8
prenext len 9 - counter 9
prenext len 10 - counter 10
prenext len 11 - counter 11
prenext len 12 - counter 12
Traceback (most recent call last):
  File "ccxtbttest.py", line 90, in <module>
    cerebro.run()
  File "/Users/michael/.venv/bt-ccxt-store/lib/python3.6/site-packages/backtrader-1.9.74.123-py3.6.egg/backtrader/cerebro.py", line 1127, in run
    runstrat = self.runstrategies(iterstrat)
  File "/Users/michael/.venv/bt-ccxt-store/lib/python3.6/site-packages/backtrader-1.9.74.123-py3.6.egg/backtrader/cerebro.py", line 1298, in runstrategies
    self._runnext(runstrats)
  File "/Users/michael/.venv/bt-ccxt-store/lib/python3.6/site-packages/backtrader-1.9.74.123-py3.6.egg/backtrader/cerebro.py", line 1557, in _runnext
    dt0 = min((d for i, d in enumerate(dts)
ValueError: min() arg is an empty sequence

Any idea?

Thank you.

Binance v3 API forbids 'created' parameter

Hi

During live trading against Binance, I am met with the error message:

"code":-1104,"msg":"Not all sent parameters were read; read '9' parameter(s) but was sent '10'."

It seems Binance is a bit strict, discarding order-requests if they transmit unknown parameters.
The 'created' parameter is outside Binance's v3 API, hence all trading orders are discarded.

Removing this line, should fix it:

params['created'] = created # Add timestamp of order creation for backtesting

if self.live_data is already true, why am I still in the history?

Hi ccxtbt,

I found something I don't understand while playing with ccxtbt. I think if self.live_data is true I should be getting the current data instead of still being in the history. Am I understanding it incorrectly? Some logs and codes to illustrate:

If self.live_data is not designed to provide this, and I'd like to determine if I'm at current data or still in the history, what's the suggested way to do so?

......
2022-01-16 19:00:00 < 2022-01-17 06:30:43.861385
2022-01-16 20:00:00 < 2022-01-17 06:30:43.862211
2022-01-16 21:00:00 < 2022-01-17 06:30:43.862751
2022-01-16 22:00:00 < 2022-01-17 06:30:43.863443
2022-01-16 23:00:00 < 2022-01-17 06:30:43.864055
2022-01-17 00:00:00 < 2022-01-17 06:30:43.864785
2022-01-17 00:30:44.886290 BTCUSDT Data Status: LIVE
2022-01-17 01:00:00 == 2022-01-17 06:30:44.886652   why still in the history when self.live_data is already true
2022-01-17 02:00:00 == 2022-01-17 06:30:45.833513   why still in the history when self.live_data is already true
2022-01-17 03:00:00 == 2022-01-17 06:30:46.081778   why still in the history when self.live_data is already true
2022-01-17 04:00:00 == 2022-01-17 06:30:47.166631   why still in the history when self.live_data is already true
2022-01-17 05:00:00 == 2022-01-17 06:30:47.680394   shouldn't self.live_data=true be at this line?
import datetime

import backtrader as bt
import ccxtbt


class TestStrategy(bt.Strategy):
    def next(self):
        if self.live_data:
            print(f"{self.data.datetime.datetime()} == {datetime.datetime.utcnow()}")
        else:
            print(f"{self.data.datetime.datetime()} < {datetime.datetime.utcnow()}")

    def notify_data(self, data, status, *args, **kwargs):
        dn = data._name
        dt = datetime.datetime.now()
        msg = 'Data Status: {}'.format(data._getstatusname(status))
        print(dt, dn, msg)
        if data._getstatusname(status) == 'LIVE':
            self.live_data = True
        else:
            self.live_data = False


cerebro = bt.Cerebro(quicknotify=True)
cerebro.addstrategy(TestStrategy)
store = ccxtbt.CCXTStore(exchange='binance', currency='USDT', retries=5, debug=False,
                         config={'enableRateLimit': True, 'options': {'defaultType': 'future'}})
cerebro.setbroker(store.getbroker())
cerebro.adddata(store.getdata(
    dataname=f'BTC/USDT', name=f'BTCUSDT', timeframe=bt.TimeFrame.Minutes,
    fromdate=datetime.datetime.utcnow()-datetime.timedelta(hours=1505),
    compression=60, ohlcv_limit=1505, drop_newest=True))
cerebro.run()

CCXTFeed _fetch_ohlcv() infinite loop

Please see details in the pull request associated with this issue.
#13
Could you please merge that one line fix into the master repository so I can try reinstalling the module with the fix.
Thank you for your assistance with this it is greatly appreciated.

Implementing set_sandbox_mode from ccxt

Hello,
Thank you for working on this library. However, I would like to be able to use the set_sandbox_mode(params) from ccxt with the CCXTStore to easily interact with test nets. I have tried implementing it myself, but I am having trouble doing so.

I get this error:

return cls.BrokerCls(*args, **kwargs)

TypeError: 'NoneType' object is not callable

ccxt_order price data returns zero

I tried the fork for binance exchange. ccxt_order price info returns zero. Thus, backtrader's order.executed.price method returns zero.

Starting Portfolio Value: 0.00034142
Base strategy initialized
DELAYED
LIVE
LIVE DATA - Ready to trade
Buy ordered: $0.02 True
{'_active': True,
 '_limitoffset': 0.0,
 '_plimit': None,
 'broker': None,
 'ccxt_order': {'amount': 0.013,
                'average': 0.021913846153846155,
                'cost': 0.00028488,
                'datetime': '2019-07-30T23:33:45.185Z',
                'fee': None,
                'filled': 0.013,
                'id': '445093341',
                'info': {'clientOrderId': 'Kp9arC7BR9UZsPTQDr3J9K',
                         'cummulativeQuoteQty': '0.00028488',
                         'executedQty': '0.01300000',
                         'icebergQty': '0.00000000',
                         'isWorking': True,
                         'orderId': 445093341,
                         'origQty': '0.01300000',
                         'price': '0.00000000',
                         'side': 'BUY',
                         'status': 'FILLED',
                         'stopPrice': '0.00000000',
                         'symbol': 'ETHBTC',
                         'time': 1564529625185,
                         'timeInForce': 'GTC',
                         'type': 'MARKET',
                         'updateTime': 1564529625185},
                'lastTradeTimestamp': None,
                'price': 0.021913846153846155,
                'remaining': 0.0,
                'side': 'buy',
                'status': 'closed',
                'symbol': 'ETH/BTC',
                'timestamp': 1564529625185,
                'trades': None,
                'type': 'market'},
 'comminfo': None,
 'created': <backtrader.order.OrderData object at 0x7f7d1826c160>,
 'data': <ccxtbt.ccxtfeed.CCXTFeed object at 0x7f7d06a752b0>,
 'dteos': 737250.9999999999,
 'exectype': 0,
 'executed': <backtrader.order.OrderData object at 0x7f7d076b8c50>,
 'info': AutoOrderedDict(),
 'ordtype': 0,
 'owner': <live_strategy.bt_bandtrader_v3_trend.Strategy object at 0x7f7d06ae5f98>,
 'p': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7f7d06a75518>,
 'params': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7f7d06a75518>,
 'position': 0,
 'ref': 1,
 'size': 0.013,
 'status': 4,
 'triggered': False}
BUY EXECUTED, Price: 0.00000000, Cost: 0.00000000, Comm 0.00000000 True

I guess this bug causes the issue below. "Position variables returns zero"

ENV=  production

Starting Portfolio Value: 0.00333707
DELAYED
LIVE
{'broker': None, '_plimit': None, 'owner': <strategies.basic_rsi.BasicRSI object at 0x7fdd939dfe80>, 'params': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7fdd939df400>, 'p': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7fdd939df400>, 'info': AutoOrderedDict(), 'ref': 1, '_limitoffset': 0.0, 'position': 0, 'exectype': 0, 'ccxt_order': {'fee': None, 'trades': None, 'datetime': '2019-07-20T20:23:28.948Z', 'lastTradeTimestamp': None, 'status': 'closed', 'info': {'executedQty': '0.12300000', 'icebergQty': '0.00000000', 'price': '0.00000000', 'origQty': '0.12300000', 'orderId': 436039847, 'isWorking': True, 'status': 'FILLED', 'timeInForce': 'GTC', 'updateTime': 1563654208948, 'time': 1563654208948, 'symbol': 'ETHBTC', 'type': 'MARKET', 'clientOrderId': '3MwUQaNQMyuMzK3HyZkCv2', 'side': 'BUY', 'stopPrice': '0.00000000', 'cummulativeQuoteQty': '0.00260747'}, 'filled': 0.123, 'amount': 0.123, 'id': '436039847', 'symbol': 'ETH/BTC', 'price': 0.021198943089430895, 'remaining': 0.0, 'average': 0.021198943089430895, 'type': 'market', 'cost': 0.00260747, 'side': 'buy', 'timestamp': 1563654208948}, 'size': 0.123, 'comminfo': None, 'created': <backtrader.order.OrderData object at 0x7fdd939dfcc0>, 'data': <ccxtbt.ccxtfeed.CCXTFeed object at 0x7fdd939dfa58>, 'triggered': False, '_active': True, 'dteos': 737240.9999999999, 'executed': <backtrader.order.OrderData object at 0x7fdd9386bcc0>, 'status': 4, 'ordtype': 0}
{'broker': None, '_plimit': None, 'owner': <strategies.basic_rsi.BasicRSI object at 0x7fdd939dfe80>, 'params': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7fdd939df400>, 'p': <backtrader.metabase.AutoInfoClass_OrderBase_CCXTOrder object at 0x7fdd939df400>, 'info': AutoOrderedDict(), 'ref': 1, '_limitoffset': 0.0, 'position': 0, 'exectype': 0, 'ccxt_order': {'fee': None, 'trades': None, 'datetime': '2019-07-20T20:23:28.948Z', 'lastTradeTimestamp': None, 'status': 'closed', 'info': {'executedQty': '0.12300000', 'icebergQty': '0.00000000', 'price': '0.00000000', 'origQty': '0.12300000', 'orderId': 436039847, 'isWorking': True, 'status': 'FILLED', 'timeInForce': 'GTC', 'updateTime': 1563654208948, 'time': 1563654208948, 'symbol': 'ETHBTC', 'type': 'MARKET', 'clientOrderId': '3MwUQaNQMyuMzK3HyZkCv2', 'side': 'BUY', 'stopPrice': '0.00000000', 'cummulativeQuoteQty': '0.00260747'}, 'filled': 0.123, 'amount': 0.123, 'id': '436039847', 'symbol': 'ETH/BTC', 'price': 0.021198943089430895, 'remaining': 0.0, 'average': 0.021198943089430895, 'type': 'market', 'cost': 0.00260747, 'side': 'buy', 'timestamp': 1563654208948}, 'size': 0.123, 'comminfo': None, 'created': <backtrader.order.OrderData object at 0x7fdd939dfcc0>, 'data': <ccxtbt.ccxtfeed.CCXTFeed object at 0x7fdd939dfa58>, 'triggered': False, '_active': True, 'dteos': 737240.9999999999, 'executed': <backtrader.order.OrderData object at 0x7fdd9386bcc0>, 'status': 4, 'ordtype': 0}
Finished with error:  unsupported operand type(s) for *: 'NoneType' and 'float'
Traceback (most recent call last):
  File "/home/tunc/PycharmProjects/btlivebot/main.py", line 107, in <module>
    main()
  File "/home/tunc/PycharmProjects/btlivebot/main.py", line 92, in main
    result = cerebro.run()
  File "/usr/local/lib/python3.5/dist-packages/backtrader/cerebro.py", line 1127, in run
    runstrat = self.runstrategies(iterstrat)
  File "/usr/local/lib/python3.5/dist-packages/backtrader/cerebro.py", line 1298, in runstrategies
    self._runnext(runstrats)
  File "/usr/local/lib/python3.5/dist-packages/backtrader/cerebro.py", line 1623, in _runnext
    self._brokernotify()
  File "/usr/local/lib/python3.5/dist-packages/backtrader/cerebro.py", line 1360, in _brokernotify
    self._broker.next()
  File "/usr/local/lib/python3.5/dist-packages/ccxtbt/ccxtbroker.py", line 203, in next
    pos.update(o_order.size, o_order.price)
  File "/usr/local/lib/python3.5/dist-packages/backtrader/position.py", line 179, in update
    self.price = (self.price * oldsize + size * price) / self.size
TypeError: unsupported operand type(s) for *: 'NoneType' and 'float'

Process finished with exit code 1

How to add timezone in feeds.CCXT?

The default is UTC time. How can I change the timezone to another timezone?
I use the following code, but it doesn't work.

data_min = bt.feeds.CCXT(exchange='binance', symbol="BTC/USDT", name="btc_usd_min", fromdate=hist_start_date,
                             timeframe=bt.TimeFrame.Minutes, tz=pytz.timezone('Asia/Shanghai'))

1104 error when create order in biance sandbox

CCXTBroker._submit() should be updated to not use 'created' parameter.

Traceback (most recent call last):
File "./main.py", line 132, in
main()
File "./main.py", line 117, in main
result = cerebro.run()
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/backtrader/cerebro.py", line 1127, in run
runstrat = self.runstrategies(iterstrat)
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/backtrader/cerebro.py", line 1298, in runstrategies
self._runnext(runstrats)
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/backtrader/cerebro.py", line 1630, in _runnext
strat._next()
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/backtrader/strategy.py", line 347, in _next
super(Strategy, self)._next()
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/backtrader/lineiterator.py", line 271, in _next
self.next()
File "/home/wdog/cellboost/strategies/basic_rsi.py", line 46, in next
self.long()
File "/home/wdog/cellboost/strategies/base.py", line 61, in long
return self.buy(size=amount)
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/backtrader/strategy.py", line 933, in buy
return self.broker.buy(
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/ccxtbt/ccxtbroker.py", line 244, in buy
return self._submit(owner, data, exectype, 'buy', size, price, kwargs)
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/ccxtbt/ccxtbroker.py", line 226, in _submit
ret_ord = self.store.create_order(symbol=data.p.dataname, order_type=order_type, side=side,
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/ccxtbt/ccxtstore.py", line 142, in retry_method
return method(self, *args, **kwargs)
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/ccxtbt/ccxtstore.py", line 172, in create_order
return self.exchange.create_order(symbol=symbol, type=order_type, side=side,
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/ccxt/binance.py", line 1911, in create_order
response = getattr(self, method)(self.extend(request, params))
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/ccxt/base/exchange.py", line 470, in inner
return entry(_self, **inner_kwargs)
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/ccxt/binance.py", line 2907, in request
response = self.fetch2(path, api, method, params, headers, body)
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/ccxt/base/exchange.py", line 491, in fetch2
return self.fetch(request['url'], request['method'], request['headers'], request['body'])
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/ccxt/base/exchange.py", line 618, in fetch
self.handle_errors(http_status_code, http_status_text, url, method, headers, http_response, json_response, request_headers, request_body)
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/ccxt/binance.py", line 2901, in handle_errors
self.throw_exactly_matched_exception(self.exceptions, error, feedback)
File "/home/wdog/anaconda3/envs/cell/lib/python3.8/site-packages/ccxt/base/exchange.py", line 509, in throw_exactly_matched_exception
raise exactstring
ccxt.base.errors.BadRequest: binance {"code":-1104,"msg":"Not all sent parameters were read; read '9' parameter(s) but was sent '10'."}

DEBUG:ccxt.base.exchange:POST https://testnet.binance.vision/api/v3/order, Request: {'X-MBX-APIKEY': '', 'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': 'python-requests/2.21.0', 'Accept-Encoding': 'gzip, deflate'} timestamp=1617953716986&recvWindow=5000&symbol=BTCUSDT&type=MARKET&side=BUY&newClientOrderId=x-R4BD3S82c6b4080059babf27962668&newOrderRespType=FULL&quantity=1.1&created=1617874020000&signature=912c3bf95905f2cf2cd66fcd4d5eefe61c7a584ab14c3990be158ae9b1ff157a
DEBUG:urllib3.connectionpool:https://testnet.binance.vision:443 "POST /api/v3/order HTTP/1.1" 400 98
DEBUG:ccxt.base.exchange:POST https://testnet.binance.vision/api/v3/order, Response: 400 {'Content-Type': 'application/json;charset=UTF-8', 'Content-Length': '98', 'Connection': 'keep-alive', 'Date': 'Fri, 09 Apr 2021 07:35:17 GMT', 'Server': 'nginx', 'x-mbx-uuid': '0e33c5e5-d105-49fa-8d58-8ff5cb6c2f07', 'x-mbx-used-weight': '33', 'x-mbx-used-weight-1m': '33', 'Strict-Transport-Security': 'max-age=31536000; includeSubdomains', 'X-Frame-Options': 'SAMEORIGIN', 'X-Xss-Protection': '1; mode=block', 'X-Content-Type-Options': 'nosniff', 'Content-Security-Policy': "default-src 'self'", 'X-Content-Security-Policy': "default-src 'self'", 'X-WebKit-CSP': "default-src 'self'", 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'X-Cache': 'Error from cloudfront', 'Via': '1.1 eb66232d6b1e64b4346cf2ac56fa1bd5.cloudfront.net (CloudFront)', 'X-Amz-Cf-Pop': 'NRT20-C2', 'X-Amz-Cf-Id': 'W_6cdF_R2isHiq9bKB3c6QRfbxdDnNulBpOxpXikxWZZIU0mEn4kPA=='} {"code":-1104,"msg":"Not all sent parameters were read; read '9' parameter(s) but was sent '10'."}

for fill in ccxt_order['trades']: TypeError: 'NoneType' object is not iterable

@Dave-Vallance first, thank you

Im using testnet from bitmex. This is the result from fetch_order,

{'info': {'orderID': '5621672a-a590-4c96-b81e-4a1632c631fe', 'clOrdID': '', 'clOrdLinkID': '', 'account': 348254, 'symbol': 'XBTUSD', 'side': 'Buy', 'simpleOrderQty': None, 'orderQty': 1, 'price': 55257, 'displayQty': None, 'stopPx': None, 'pegOffsetValue': None, 'pegPriceType': '', 'currency': 'USD', 'settlCurrency': 'XBt', 'ordType': 'Market', 'timeInForce': 'ImmediateOrCancel', 'execInst': '', 'contingencyType': '', 'exDestination': 'XBME', 'ordStatus': 'Filled', 'triggered': '', 'workingIndicator': False, 'ordRejReason': '', 'simpleLeavesQty': None, 'leavesQty': 0, 'simpleCumQty': None, 'cumQty': 1, 'avgPx': 55248.5, 'multiLegReportingType': 'SingleSecurity', 'text': 'Submitted via API.', 'transactTime': '2021-02-22T09:37:59.255Z', 'timestamp': '2021-02-22T09:37:59.255Z'}, 'id': '5621672a-a590-4c96-b81e-4a1632c631fe', 'clientOrderId': '', 'timestamp': 1613986679255, 'datetime': '2021-02-22T09:37:59.255Z', 'lastTradeTimestamp': 1613986679255, 'symbol': 'BTC/USD', 'type': 'market', 'timeInForce': 'IOC', 'postOnly': False, 'side': 'buy', 'price': 55257.0, 'stopPrice': None, 'amount': 1.0, 'cost': 55248.5, 'average': 55248.5, 'filled': 1.0, 'remaining': 0.0, 'status': 'closed', 'fee': None, 'trades': None}

So 'trades' contains nothing. How should I approach this?

Binance Problem

Dear Sir,

I found problem when trying to trade on binance. Here is the following detail.

Error when try to trade buy / sell / order_target
the error I found is ccxt.base.errors.ExchangeError: binance {"code":-1104,"msg":"Not all sent parameters were read; read '8' parameter(s) but was sent '9'."}

I look into the code and found out that ccxtbroker._submit add 'created' to params which course this problem. I comment that line out and it's work.

ccxt_order['trades'] is none in ccxtbroker.next
binance return ccxt_order with 'trades' key but none value in it which course error Line 199. I check for not null in line 198 and it's work again

Sorry for not issue pull requests, I don't know how to do it. I will try to learn and may be send you a pull requests later.

Best Regards,
Chet Chetchaiyan

Duplicate data points

Hello there,

I am using the library with Bitmex, to get the hourly bars of Etherium, in Live environment. After a couple of hours of running, I notice that some duplicate bars start to appear in the log.

2020-03-21 19:00:00, close price:133.05  Rsi:51.004983696776364 Volume:4799960.0
2020-03-21 20:00:00, close price:135.45 Rsi:55.39222359889011 Volume:6666773.0

2020-03-21 21:00:00, close price:133.2  Rsi:50.79964969434447 Volume:11179735.0

2020-03-21 22:00:00, close price:132.95  Rsi:50.30062400737818 Volume:6394664.0

2020-03-21 21:00:00, close price:133.2 Rsi:45.92777223117949 Volume:11179735.0

2020-03-21 22:00:00, close price:132.95  Rsi:45.45493183926012 Volume:6394664.0

2020-03-21 23:00:00, close price:133.0 Rsi:45.57561520012476 Volume:3941874.0

no matching distribution for CCXTBT ?

I can't locate CCXTBT module where to find? I have CCXT already.

ERROR: Could not find a version that satisfies the requirement ccxtbt (from versions: none)
ERROR: No matching distribution found for ccxtbt

ModuleNotFoundError: No module named 'binance'

Hi team,
I just finished to install python-binance and wanted to test it with a simple line of code:

from binance.client import Client

but i got this error message like i did not install it at all:

ModuleNotFoundError: No module named 'binance'

i'm using spyder(Python 3.6). the installation was done as follow:
!pip install python-binance

Any thought please?

How to use function notify_trade in live trading?

This function never work in live mode

    def notify_trade(self, trade):
        print('-' * 50, 'TRADE BEGIN', datetime.datetime.now())
        print(trade)
        print('-' * 50, 'TRADE END')

How we can use trades and calculate mfe\mae for open position for each bar?

drop_newest=False not working properly

I want to watch open candles to be able to exit on fixed and indicator-based stop-loss levels in live mode. However, when I set drop_newest to False, only the first event is passed to the next() method.

I expect to have several events of incomplete candles delivered to the next() method, but I only receive one event (the first one) in the desired timeframe.

I also tried to use the replay feature, but nothing changed.

What should I do?

Thanks in advance.

Support for starting positions

Am I missing something or is there no support for loading current positions from account before starting to execute a strategy?

I'm currently making an attempt to connect backtrader to my (in-house) stock trading platform by implementing a python exchange and the web API at the same time.

Starting positions are one of the last pieces of the puzzle before I can at least start paper trading with it, then it's all up to me to connect the web API to actual trading.

getposition() method returns empty object

Hi,
Many thanks for your great work in integrating CCXT into Backtrader for trading live.

I was just wondering if this bug has been fixed. When i use the self.getposition() i receive empty object where I should get a list of my open positions:

Positions --- Position Begin

  • Size: 0
  • Price: 0.0
  • Price orig: 0.0
  • Closed: 0
  • Opened: 0
  • Adjbase: None
    --- Position End

Also, is there equivalent methods existing in Backtrader to similar to CCXT api:

fetchOrders()
fetchOpenOrders()
fetchClosedOrders()

Many thanks.

Hitting API rate limit after some minutes

Even though that I've set enableRateLimit to True in the exchange config, the library hits the rate limit of the exchange.

I enabled logging and I saw that the library is requesting data too much frequently, i.e. one or even two requests in each second.

What I want to achieve is that the library makes requests every 15 seconds or so. How can I set that?

Thanks in advance.

How to get current price in Strategy's next?

Hi there,

I need to get current market price in the next function to make decisions.

Tried to change ccxt/ccxtstore.py, add some code to get fetch_ticket information.

def __init__(self, exchange, currency, config, retries, debug=False, sandbox=False):
        self.exchange = getattr(ccxt, exchange)(config)
        # print("self.exchange",self.exchange)
        print("self.exchange.fetch_ticker", self.exchange.fetch_ticker('USDT/HUSD'))

Here's the output:

self.exchange.fetch_ticker {'symbol': 'USDT/HUSD', 'timestamp': 1615448013555, 'datetime': '2021-03-11T07:33:33.555Z', 'high': 1.0006, 'low': 0.9995, 'bid': 0.9997, 'bidVolume': 42300.4802, 'ask': 0.9998, 'askVolume': 136145.3142, 'vwap': 1.000125720339054, 'open': 1.0004, 'close': 0.9997, 'last': 0.9997, 'previousClose': None, 'change': -0.0006999999999999229, 'percentage': -0.06997201119551409, 'average': 1.0000499999999999, 'baseVolume': 105604769.11847508, 'quoteVolume': 105618045.78585435, 'info': {'amount': 105604769.11847508, 'open': 1.0004, 'close': 0.9997, 'high': 1.0006, 'id': 208846147104, 'count': 79494, 'low': 0.9995, 'version': 208846147104, 'ask': [0.9998, 136145.3142], 'vol': 105618045.78585435, 'bid': [0.9997, 42300.4802]}}
2021-03-11 15:33:42.040526 USDTHUSD Data Status: DELAYED, Order Status: 3
2021-03-11 15:33:44.140944 USDTHUSD Data Status: LIVE, Order Status: 4
2021-03-11, DIFF = HIGH - SMA30: 0.0

But I'm confused how should I call it in the Strategy's next function.

Any suggestions?

Thanks a lot.

Broker feed stuck with compression

I am using the bitfinex. The exchange returns a feed of one minute. My bot uses a time-frame of 30 minutes, but it stuck with a compression different of 1.

Code:

hist_start_date = dt.datetime.utcnow() - dt.timedelta(minutes=50)
data = store.getdata(dataname='BTC/USDT', name="BTCUSDT",
	timeframe=bt.TimeFrame.Minutes, fromdate=hist_start_date,
	compression=30, ohlcv_limit=999, drop_newest=True)

I also tried to use cerebro.resampledata(data, timeframe=bt.TimeFrame.Minutes, compression=30) with compression 1 in store. But does not work too.

With compression=1, the feed works fine. And next() function is triggered.

Feed returns wrong ohlcv values and makes many `fetch_ohlcv()` requests to the exchange

  1. As reproduceable in this gist the CCXTFeed continuously fetches ohlcv data from the exchange and thus consumes additional downstream data volume.
    Is that really needed for something or is that an error?
  2. Sometimes the same value for ohlc is returned which is most probably wrong. The output from the above gist looks like that in this case:
---- NEW REQUEST ----
2019-03-12 19:10:03.585799 - Requesting: Since TS 1552417740000 Since date 2019-03-12 19:09:00 granularity 1m, limit 2, params
2019-03-12 19:10:04.374471 - Data 0: 2019-03-12 19:09:00 - TS 1552417740000 Time 1552417804374.4797
2019-03-12 19:10:04.374536 - Data 1: 2019-03-12 19:10:00 - TS 1552417800000 Time 1552417804374.5388
---- REQUEST END ----
----     LOAD    ----
2019-03-12 19:10:04.374660 Load OHLCV Returning: True
2019-03-12T19:10:00 open: 15.0262
2019-03-12T19:10:00 high: 15.0262
2019-03-12T19:10:00 low: 15.0262
2019-03-12T19:10:00 close: 15.0262

When I set a conditional breakpoint in binance.py:fetch_ohlcv() after publicGetKlines() I can inspect the variables for this scenario but it's still not clear to me where that comes from.
The breakpoint condition I use is: len(response) == 2 and response[1][1] == response[1][2] and response[1][2] == response[1][3] and response[1][3] == response[1][4]

To make the gist work the code from the #5 pull request needs to be used to avoid needing a Binance API key.

Bracket Order Parameters

When creating a buy and sell order, some exchanges (Binance) can return an error if Backtrader's Bracket order kwargs parent and transmit are present in the request.

The current workaround is to delete the kwargs before submitting the order. However, this might limit integration of bracket orders in the future.

As such, a more elegant solution would be good.

Example of deletion in current code base:

def buy(self, owner, data, size, price=None, plimit=None,
            exectype=None, valid=None, tradeid=0, oco=None,
            trailamount=None, trailpercent=None,
            **kwargs):

        del kwargs['parent']
        del kwargs['transmit']

        return self._submit(owner, data, exectype, 'buy', size, price, kwargs)

Reference to pull request: #2

more than one datafeed

Hi,

I have tried to get a strategy with 2 data feeds working. eg. hourly and daily.
However even after both feeds have live data the strategy next() function is not called.

Is this a bug or does anyone know how to achieve it?

Crypto-coins errors on sell and buy

Hi fox,
i'm coding a scanner bot for short term profit however since the prices are different from coins to coins i got exceptions when buying and selling,i'm 99.9 sure that it has a relation with decimals and the way the function round() is doing the rounding. Here is a block of code:

        m1=client.get_klines(symbol=mycoin, interval='1m')
        tim=datetime.fromtimestamp(int(m1[-1][0])/1000)
        xlslog['Entred time'].append(tim)
        EnterPrice=round(float(m1[-1][4]),7)
        xlslog['inPrice'].append(EnterPrice)
        stoprsi=False
        buystat=True
        xt+=1
        Ploss=(float(EnterPrice)*0.08)/100
        divrsi=(float(EnterPrice)*0.6)/100
        Ploss=float(EnterPrice)-Ploss
        divrsi=round(float(EnterPrice)+divrsi,7)
        inprice=round(float(EnterPrice),7)
        qnt=round(float(15/inprice),4)
        try:
            buyorder = client.order_market_buy(symbol=mycoin,quantity=qnt)
        except BinanceAPIException as e:
            
            # error handling goes here
            qnt=int(qnt)
            buyorder = client.order_market_buy(symbol=mycoin,quantity=qnt)

Can any experienced coder that dealed with this issue before advise on an idea of how to solve it please?
Thank you in advance,

Regards,

How to set the instrument to the OKEX Contracts?

OKEX Contracts has the contracts with additional parameters, suck like: base_coin='eth', quote_coin='usd', and contractType = 'quarter', but how to set such instrument into data?
Could you give a simple sample, thanks.

Plotting issues

I can't figure out what needs to be done for trades to show up on plot, as well as cash balance.
My strategies execute fine, for now my backend autofills any order at current bid/ask:

def fill(order):
    if 'trades' not in order:
        order['trades'] = []

    order['original_amount'] = order['quantity']
    order['executed_amount'] = order['quantity']
    order['remaining_amount'] = 0
    try:
        order['cost'] = int(order['quantity']) * float(order['price'])
    except:
        pass

    try:
        fee = int(order['quantity']) * 0.0005
    except:
        fee = 0.0

    order['trades'].append({
        'order_id': order['order_id'],
        'market': order['symbol'],
        'side': order['side'],
        'price': order['price'],
        'quantity': order['quantity'],
        'timestamp': time.time(),
        'fee_amount': fee,
        'fee_currency': 'CAD'
    })

Positions seem to update fine - I'm buying and selling according to position.

But when I stop the strategy, I can see my data feeds, signals and a flat line for account balance (at the number of the balance at the start) and no buy/sell markets on the feed.

Is it just that that's not supported?

TypeError: unsupported operand type(s) for *: 'NoneType' and 'float'

Hi,

I'm having this error with Bitfinex:

Traceback (most recent call last):
  File "/home/user/.vscode/extensions/ms-python.python-2019.1.0/pythonFiles/ptvsd_launcher.py", line 45, in <module>
    main(ptvsdArgs)
  File "/home/user/.vscode/extensions/ms-python.python-2019.1.0/pythonFiles/lib/python/ptvsd/__main__.py", line 348, in main
    run()
  File "/home/user/.vscode/extensions/ms-python.python-2019.1.0/pythonFiles/lib/python/ptvsd/__main__.py", line 253, in run_file
    runpy.run_path(target, run_name='__main__')
  File "/usr/lib/python3.6/runpy.py", line 263, in run_path
    pkg_name=pkg_name, script_name=fname)
  File "/usr/lib/python3.6/runpy.py", line 96, in _run_module_code
    mod_name, mod_spec, pkg_name, script_name)
  File "/usr/lib/python3.6/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/user/TEST/my_test_ccxt/bot_bitfinex.py", line 107, in <module>
    cerebro.run(exactbars=0) #https://www.backtrader.com/docu/memory-savings/memory-savings.html
  File "/home/user/.local/lib/python3.6/site-packages/backtrader/cerebro.py", line 1127, in run
    runstrat = self.runstrategies(iterstrat)
  File "/home/user/.local/lib/python3.6/site-packages/backtrader/cerebro.py", line 1298, in runstrategies
    self._runnext(runstrats)
  File "/home/user/.local/lib/python3.6/site-packages/backtrader/cerebro.py", line 1623, in _runnext
    self._brokernotify()
  File "/home/user/.local/lib/python3.6/site-packages/backtrader/cerebro.py", line 1360, in _brokernotify
    self._broker.next()
  File "/usr/local/lib/python3.6/dist-packages/bt_ccxt_store-1.0-py3.6.egg/ccxtbt/ccxtbroker.py", line 199, in next
  File "/home/user/.local/lib/python3.6/site-packages/backtrader/position.py", line 193, in update
    self.price = (self.price * oldsize + size * price) / self.size
TypeError: unsupported operand type(s) for *: 'NoneType' and 'float'

it happens after this:

2019-02-18 15:32:57.065339 - fetch_open_orders - Attempt 0
2019-02-18 15:33:17.162320 - create_order - Attempt 0
2019-02-18 15:33:27.426503 - fetch_order - Attempt 0
2019-02-18 15:33:37.524229 - fetch_ohlcv - Attempt 0
2019-02-18 15:33:47.613561 - fetch_ohlcv - Attempt 0
2019-02-18 15:33:57.695672 - fetch_order - Attempt 0

is happening in with:
self.price = (self.price * oldsize + size * price) / self.size

the error is "TypeError: unsupported operand type(s) for *: 'NoneType' and 'float'"
Any clue?
Thanks

Fix that significantly improved live datafeed

Hi @Dave-Vallance and user of bt-ccxt-store,

In the event you've noticed the live datafeed while using bt-ccxt-store is slow after it switched from HISTORICAL state to LIVE state, I share the same sentiment with you.

After spending a couple of hours in front of screen debugging into it, I've managed to root cause the issue and made a fix that significantly improved live datafeed @ PR4. Basically the fix is to selectively load _fetch_ohlcv only when it is required and when _fetch_ohlcv is running, it will always look forward for next date instead of from the previous date.

Unfortunately, I've also made other changes on top of my branch and unable to pull request directly into Dave's branch. Hence I'm leaving the fix as it is @ PR4. Anyone (including Dave) interested could feel free to pick it up and use it.

Thank you for your attention and happy trading.

self.live_data is not accessible.

AttributeError: 'Lines_LineSeries_LineIterator_DataAccessor_Strateg' object has no attribute 'live_data'

So how can I know it's historical or live data?

how to buy and sell in backtest?

I am a newer in quant,I see that when you do a live trading, the code use buy method from ccxt, so when doing a backrest, which buy method should I use,the method from ccxt or backtrader.These method in ccxt and backtrader have different parameters,so it means I should write two different version for backtest and live trading?

Question: BrokerCls and DataCls

In ccxtstore.py, there's comments saying DataCls and BrokerCls will auto register. How does that happen? I've tried implementing a basic exchange to use my own data and eventually backtest executions using current bid/ask on Canadian markets.

I've edited ccxtstore.py with this addition:

from jack import jack
ccxt.jack = jack
ccxt.exchanges.append('jack')

Where jack is my exchange.

However whenever I call store.getbroker() or store.getdata(), I get a TypeError: 'NoneType' object is not callable where DataCls and BrokerCls are None.

Would you happen to have a clear idea what I'm doing wrong?

Problems with creating conditional Orders on bybit

Hello, thx for your CCXT-Store

i wanna know how can i create conditional orders in bybit?

i dont know how that mapping works, but it seems its not correct for bybit

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': 'status',
'value': 'canceled'
}
}
}

My questions are:
How can i create a conditional Market orders ( StopMarket ) in bybit ?
How can i add SL/TP to a Limit or Market order ?
Where i can find the right Mapping formats for each exchange (Binance, Bitmex, OKX, etc...)

Incompatible with optstrategy?

I run into an error when developing my bot.
This is the minimum code that reproduce the error.

Could you help me?

import time
from datetime import datetime

import backtrader as bt

from ccxtbt import CCXTFeed


def main():
    class TestStrategy(bt.Strategy):
        params = (
            ('maperiod', 10),
        )

        def __init__(self):
            self.next_runs = 0

        def next(self, dt=None):
            dt = dt or self.datas[0].datetime.datetime(0)
            print('%s closing price: %s' % (dt.isoformat(), self.datas[0].close[0]))
            self.next_runs += 1

    cerebro = bt.Cerebro()

    # cerebro.addstrategy(TestStrategy)
    cerebro.optstrategy(TestStrategy, maperiod=[10,11], printlog=True)

    # Add the feed
    cerebro.adddata(CCXTFeed(exchange='binance',
                             dataname='BNB/USDT',
                             timeframe=bt.TimeFrame.Minutes,
                             fromdate=datetime(2019, 1, 1, 0, 0),
                             todate=datetime(2019, 1, 1, 0, 2),
                             compression=1,
                             ohlcv_limit=2,
                             currency='BNB',
                             retries=5,
                            config={'enableRateLimit': True, 'nonce': lambda: str(int(time.time() * 1000))}))

    # Run the strategy
    cerebro.run(maxcups=1)


if __name__ == '__main__':
    main()

Error

Traceback (most recent call last):
  File "PATH_TO_CODE/sam-app/app/btccxt.py", line 45, in <module>
    main()
  File "PATH_TO_CODE/sam-app/app/btccxt.py", line 41, in main
    cerebro.run(maxcups=1)
  File "PATH_TO_CODE\venv\lib\site-packages\backtrader\cerebro.py", line 1143, in run
    for r in pool.imap(self, iterstrats):
  File "PATH_TO_PYTHON\lib\multiprocessing\pool.py", line 748, in next
    raise value
  File "PATH_TO_PYTHON\lib\multiprocessing\pool.py", line 431, in _handle_tasks
    put(task)
  File "PATH_TO_PYTHON\lib\multiprocessing\connection.py", line 206, in send
    self._send_bytes(_ForkingPickler.dumps(obj))
  File "PATH_TO_PYTHON\lib\multiprocessing\reduction.py", line 51, in dumps
    cls(buf, protocol).dump(obj)
AttributeError: Can't pickle local object 'main.<locals>.<lambda>'

Enhance the broker mappings and store them for multiple exchanges

This is about three aspects of the broker mappings.

  1. Currently the user of the library would need to figure out by himself what the correct broker mappings for his exchange are. But we already have this settings in the code here and there. And in my case I always have to figure out which one are the correct ones. This is why I suggest to move them out into a JSON file and commit them.

  2. Having a separate file would make it easy to store the mappings per exchange to have a single source of truth for multiple exchanges.

  3. For Binance I need additional properties to be mapped. E.g. the parameter for the stop price is different between Backtrader and what Binance expects. Additionally Binance differentiates its stop-limit order types further by having

I can implement that for Binance in way compatible with other exchanges and make a pull request if you don't have a veto @Dave-Vallance .

Is it safe to use this repo?

Hi
Guys I'm a bit scared to use this repo, since it will have access to my api key and secret key, now i can make my own, but i just don't want to reinvent the wheel if this repo and it's creator is trustworthy.
please share you thoughts!

Responses to orders are sometimes None

I've seen this with binance and ftx. No error message, just a None response to the call to self.buy or self.sell. No open order at the exchange either. As if nothing happened. I'm not even sure if this is a problem with the bt-ccxt-store or with ccxt.

Is there anything that I can do to either make the requests more robust or to debug the issue?

How to get all the orders from Binance

I am struggling with the self.position because every time errors happens and after re-connection I cannot use"self.position" to continue with previous actions.
Then I want to use the latest_order to replace this "self.position' judgement.
Could you please help with " how can I get all the orders on Binance" through bt-ccxt-store?
Many thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.