Skip to content

Commit

Permalink
Private End Points
Browse files Browse the repository at this point in the history
Support for using any private non unified end point on any exchange
  • Loading branch information
Dave-Vallance committed Sep 7, 2018
1 parent 15df84b commit 5e87921
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 6 deletions.
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Check out the example script to see how to setup and run on Kraken.
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 manual as and when
you want the information.
you want the information.

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

Expand All @@ -51,6 +51,29 @@ Check out the example script to see how to setup and run on Kraken.
}
```

- 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.
Expand Down Expand Up @@ -79,6 +102,8 @@ A store is initialized in a similar way to other backtrader stores. e.g
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.
Expand Down
37 changes: 32 additions & 5 deletions ccxtbt/ccxtbroker.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ class CCXTBroker(with_metaclass(MetaCCXTBroker, BrokerBase)):
'value':1}
}
}
Added new private_end_point method to allow using any private non-unified end point
'''

order_types = {Order.Market: 'market',
Expand Down Expand Up @@ -156,7 +159,6 @@ def getposition(self, data, clone=True):
pos = self.positions[data._dataname]
if clone:
pos = pos.clone()

return pos

def next(self):
Expand Down Expand Up @@ -208,10 +210,10 @@ def cancel(self, order):
return order

ccxt_order = self.store.cancel_order(oID)
print('CCXT Order')
print(ccxt_order)
print('Value Received: {}'.format(ccxt_order[self.mappings['canceled_order']['key']]))
print('Value Expected: {}'.format(self.mappings['canceled_order']['value']))
#print('CCXT Order')
#print(ccxt_order)
#print('Value Received: {}'.format(ccxt_order[self.mappings['canceled_order']['key']]))
#print('Value Expected: {}'.format(self.mappings['canceled_order']['value']))

if ccxt_order[self.mappings['canceled_order']['key']] == self.mappings['canceled_order']['value']:
self.open_orders.remove(order)
Expand All @@ -221,3 +223,28 @@ def cancel(self, order):

def get_orders_open(self, safe=False):
return self.store.fetch_open_orders()

def private_end_point(self, type, endpoint, params):
'''
Open method to allow calls to be made to any private end point.
See here: https://github.com/ccxt/ccxt/wiki/Manual#implicit-api-methods
- type: String, 'Get', 'Post','Put' or 'Delete'.
- endpoint = String containing the endpoint address eg. 'order/{id}/cancel'
- Params: Dict: An implicit method takes a dictionary of parameters, sends
the request to the exchange and returns an exchange-specific JSON
result from the API as is, unparsed.
To get a list of all available methods with an exchange instance,
including implicit methods and unified methods you can simply do the
following:
print(dir(ccxt.hitbtc()))
'''
endpoint_str = endpoint.replace('/','_')
endpoint_str = endpoint_str.replace('{','')
endpoint_str = endpoint_str.replace('}','')

method_str = 'private_' + type.lower() + endpoint_str.lower()

return self.store.private_end_point(type=type, endpoint=method_str, params=params)
24 changes: 24 additions & 0 deletions ccxtbt/ccxtstore.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import backtrader as bt
from backtrader.metabase import MetaParams
from backtrader.utils.py3 import queue, with_metaclass
import json

class MetaSingleton(MetaParams):
'''Metaclass to make a metaclassed class a singleton'''
Expand All @@ -51,6 +52,8 @@ class CCXTStore(with_metaclass(MetaSingleton, object)):
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
Added new private_end_point method to allow using any private non-unified end point
'''

# Supported granularities
Expand All @@ -63,6 +66,7 @@ class CCXTStore(with_metaclass(MetaSingleton, object)):
(bt.TimeFrame.Minutes, 60): '1h',
(bt.TimeFrame.Minutes, 90): '90m',
(bt.TimeFrame.Minutes, 120): '2h',
(bt.TimeFrame.Minutes, 180): '3h',
(bt.TimeFrame.Minutes, 240): '4h',
(bt.TimeFrame.Minutes, 360): '6h',
(bt.TimeFrame.Minutes, 480): '8h',
Expand Down Expand Up @@ -176,3 +180,23 @@ def fetch_order(self, oid):
@retry
def fetch_open_orders(self):
return self.exchange.fetchOpenOrders()

@retry
def private_end_point(self, type, endpoint, params):
'''
Open method to allow calls to be made to any private end point.
See here: https://github.com/ccxt/ccxt/wiki/Manual#implicit-api-methods
- type: String, 'Get', 'Post','Put' or 'Delete'.
- endpoint = String containing the endpoint address eg. 'order/{id}/cancel'
- Params: Dict: An implicit method takes a dictionary of parameters, sends
the request to the exchange and returns an exchange-specific JSON
result from the API as is, unparsed.
To get a list of all available methods with an exchange instance,
including implicit methods and unified methods you can simply do the
following:
print(dir(ccxt.hitbtc()))
'''
return getattr(self.exchange, endpoint)(params)

0 comments on commit 5e87921

Please sign in to comment.