Dave-Vallance / bt-ccxt-store

Fork of Ed Bartosh's CCXT Store Work
MIT License
424 stars 187 forks source link

Enhance the broker mappings and store them for multiple exchanges #7

Open sandroboehme opened 5 years ago

sandroboehme commented 5 years ago

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 .

sandroboehme commented 5 years ago

On the other hand, maybe there is a more object oriented approach where we only overwrite methods that are different for a specific exchange. This way we would be more flexible because the mapping file could grow arbitrarily complex.

sandroboehme commented 5 years ago

I guess I'll need to understand CCXT better first.

sandroboehme commented 5 years ago

ccxt currently unifies market and limit orders only

Ok, so at least we have to unify stop orders ourselves somehow.

Dave-Vallance commented 5 years ago

@sandroboehme

Good thinking...

I agree that a more user friendly way of handling the mappings would be helpful. In the last commit, I tried to add more debugs to help this but it isn't really a good solution. More of stop gap until a better approach is found.

Regarding number 3 - As a temporary workaround, you might be able to use the private end point function. This is useful for the special order types that are not supported in backtrader.

Of course, if we can think of a nice way to include the things you need without breaking things for others, that would be ideal.

On BitFinex I used a private end point to completely close a position. This is because Backtrader tries to close positions using a buy/sell market order with the correct size but if I remember correctly, the size was not perfect as commissions were taken out leaving me with a little bit left. In the end, using the private endpoint worked.

                    # Manually close a position using the private method
                    # 1 Get open positions with private_post_positions()
                    # 2 Parse the position ID
                    # 3 Cancel the position
                    # 4 Update position pos.update(o_order.size, o_order.price)
                    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(d, clone=False)
                        # A Price of NONE is returned form the close position endpoint!
                        _pos.update(-self.position.size, None)
sandroboehme commented 5 years ago

@Dave-Vallance Ah ok thanks for the example that's good to know! Judging from what I currently know I target a hybrid solution. Using the broker mapping file for simple mappings but also allow to call a method e.g. for Binance stop-limit orders to handle mappings that would be too hard to describe generically in a JSON file. I don't know yet how to do it exactly but I guess I'll find a way :-).

BTW: My personal driver for that is that I currently have a Backtrader Strategy that uses Binance specific parameters for stop-limit orders. This prevents that I can backtest the Strategy with Backtrader as it is as it expects different parameters.

pfederra commented 5 years ago

@Dave-Vallance Thanks for the example above. However, I have not been able to figure out how to use the private end point for Binance to get the list of open positions. I get the error message that says private_post_positions() does not exists. Do I need to implement this function in in the CCXT broker for specific broker? Also, if I place market_order after the order executed where can I see the result of the order exception including the price and the time? Is this something that is already implemented in Backtrader+CCXT or needs to be implemented.