Skip to content

Add Bitvavo broker support and paper trading#20

Open
AJ-Smart-Solutions wants to merge 2 commits into
garagesteve1155:mainfrom
AJ-Smart-Solutions:feature/bitvavo-broker-support
Open

Add Bitvavo broker support and paper trading#20
AJ-Smart-Solutions wants to merge 2 commits into
garagesteve1155:mainfrom
AJ-Smart-Solutions:feature/bitvavo-broker-support

Conversation

@AJ-Smart-Solutions

Copy link
Copy Markdown

Summary

  • Adds broker abstraction layer allowing multiple exchange integrations
  • Implements Bitvavo broker using official python-bitvavo-api SDK
  • Adds paper trading mode for testing strategies without real money

Features

Bitvavo Integration

  • Full Bitvavo API support with EUR trading pairs (BTC-EUR, ETH-EUR, etc.)
  • Broker selection dropdown in GUI settings
  • Bitvavo API setup wizard for easy credential configuration
  • Maintains full backwards compatibility with Robinhood

Paper Trading

  • Simulate trades without using real money
  • Uses real market prices for realistic testing
  • Persists state (survives restarts)
  • Configurable starting balance
  • Track virtual P&L and trade history

Files Changed

  • brokers/base.py - Abstract broker interface
  • brokers/robinhood.py - Robinhood implementation (extracted from pt_trader.py)
  • brokers/bitvavo.py - Bitvavo implementation using official SDK
  • brokers/paper.py - Paper trading simulator
  • brokers/__init__.py - Factory function with paper trading support
  • pt_trader.py - Updated to use broker abstraction
  • pt_hub.py - Added broker selection, Bitvavo setup, and paper trading toggle
  • requirements.txt - Added python-bitvavo-api

Test plan

  • Test Robinhood trading (backwards compatibility)
  • Test Bitvavo API connection
  • Test EUR pair trading on Bitvavo
  • Test paper trading mode
  • Verify GUI settings save correctly

apeer added 2 commits January 2, 2026 19:52
- Add broker abstraction layer (brokers/ module)
- Implement RobinhoodBroker and BitvavoBroker classes
- Add broker selection dropdown in GUI settings
- Add Bitvavo API setup wizard in settings dialog
- Update pt_trader.py to use broker interface
- Add python-bitvavo-api to requirements.txt

Supports EUR trading pairs for Bitvavo (BTC-EUR, ETH-EUR, etc.)
while maintaining full Robinhood compatibility (USD pairs).
- Add PaperBroker class for simulated trading without real money
- Uses real market prices but executes virtual trades
- Persists state to paper_trading_state.json (survives restarts)
- Add paper trading toggle and balance setting in GUI
- Track virtual balance, holdings, and trade history
- Calculate performance metrics (P&L, win rate)

Perfect for testing strategies before using real funds.
@albuckley

Copy link
Copy Markdown

I had a quick look at your abstraction implementation. A few short comments....

  1. Initialization

I see what you did with the init file. I think executing these methods during import obscures this functionality.
It would be best to implement an init() method in the base class itself, and have the init and configuration operations performed when the object is created.

  1. Abstraction

I would not say that abstraction has been properly achieved here. It is still rather brute force, what you have done is implement a selector switch that runs during import. Adding more exchanges would be increasing this list of methods.

You have _create_robinhood_broker() and _create_bitvavo_broker()
Instead there should be just a single _create_broker() method that is passed an argument 'exchange', or loaded internally from a config file. _create_broker(exchange = 'kraken')

Otherwise I can see that broker implementations do suitably inherit from the BrokerAPI.
May comments may be more in the direction of factory implementation which could be done a few different ways..

  1. Encapsulation.

A good start to creating a base class. The base class should have all the methods that are common to each instance. Child classes then implement the specifics and subtle differences. Declaring abstract methods in the base class then forces the implementation in the child class.

For example the base class can declare a method get_price(token) and then implementing a new interface would require the child class to define the implementation.

Lets say I want to add the Kraken exchange. I would define a new class KrakenInterface and it would inherit from and extend the Broker base class, and it would implement the get_price() method for Kraken.

I can see this structure in your code. I recommend creating some folders to separate things hierarchically.
broker/broker.py <-- is the base class
broker/exchanges/bitvavo.py
broker/exchanges/robinhood.py
broker/exchanges/kraken.py
broker/exchanges/config/bitvavo.yaml

  1. High cohesion and low coupling. Put like with like and separate concerns.

As you can see in the main branch, there are a couple of files that are many thousands of lines of code, implementing mixture of many functions and methods that are unrelated and in random order. It is in desperate need of breaking up into to pieces and smaller supporting classes. Implementing an abstract interface likely will grow in complexity, so thought should be given to defining it as a composition of various components, and then implementing those component in subclasses.

As an example you have 'factory functions' in the init file. A good base class should implement all of the high level methods required for interacting with an object and its data. Self initialisation and configuration is common. However if that itself became complex enough, separating the creation could make sense so the init() method does not grow to be too large and complex. This would be an appropriate time to implement a factory class that can be used by the top level application. The factory class would handle everything required to be done to create and configure a Broker() object.

main() --> calls factory create broker
Factory --> instantiates a Broker object, calls any methods not handled in Broker init(). Can do things like create connection, authenticate, do health checks etc. or do things like activate data streaming.
Broker --> maps base methods to implementation, ex. KrakenInterface
Interface --> defines low level details

It may further be best to break this down some more. For example create a Interface base class.
Why? The Broker may do some higher level abstract operations that are more related to application runtime operation than just act a a library of interface methods. For example the interface may be polling or streaming over a socket.
Streaming is preferable in applications where you don't want latency in the data.
The mechanics of these interactions are application layer concerns. So it would be good to have a middle man between the application and the interface to handle these issues.

In this example the Broker would be performing the information arbitrage between the Application and the Interface.
Here we would also do things like health monitoring or handling errors gracefully. If the connection is lost or data is corrupted, then the Broker would know that and deal with it accordingly and may attempt to regain connection if possible. If this session management work is done on its own isolated layer, then the whole application doesn't have to come crashing down due to an error in transmission or network connection (which will happen with certainty).

In some works the session and interface could all be in one class, but this kind of stuff is sensitive enough that it will grow in size considerably, so implementing the separation of concern from the start is best. Like, you could try and implement both a polling and streaming interface from the application and you would see quickly that a component would be required to handle the runtime operations as its main focus.

  1. Little things
  • Create a config folder for config files. robbinhood.config bitvavo.config etc (or YAML etc)
  • add *.pyc to git ignore file, we don't need your IDE temp files

Overall the abstraction is there at the lower level, but I would think about further abstracting the relationship between the application on the broker side. Also would be best to take the code out of the init file and build a separate factory. I would accept the PR given the assumption development of the interface would continue.

@sjackson0109 sjackson0109 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've got a sister project underway here https://github.com/sjackson0109/PowerTraderAI

If you are interested, i'd like to PR your branch, and support you in joining a couple of us working on this together.

As much as we love @garagesteve1155 for the project he has on offer; he's made his position clear, that he is happy to let other members manage their own forks. So that is what i'm doing. You're welcome to come along...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants