Skip to content

Commit beceba9

Browse files
authored
Fix issue with data sources parameters passing (#284)
* Fix issue with data sources parameters passing * Fix flake8 issues * Add azure storage state handler support * Fix flake8 warnings * Add poetry lock * Pin poetry version to 1.7.1 * Fix failing tests * Fix flake 8 warnings * Fix flask test base
1 parent 4c269aa commit beceba9

File tree

101 files changed

+5050
-3647
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+5050
-3647
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ jobs:
6969
- name: Install Poetry
7070
uses: snok/install-poetry@v1
7171
with:
72+
version: 1.7.1
7273
virtualenvs-create: true
7374
virtualenvs-in-project: true
7475
#----------------------------------------------

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
### Python template
33
# Byte-compiled / optimized / DLL files
44
__pycache__/
5+
*__pycache__/
56
*.py[cod]
67
*$py.class
8+
.DS_Store
79

810
# C extensions
911
*.so

README.md

Lines changed: 42 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
[![GitHub stars](https://img.shields.io/github/stars/coding-kitties/investing-algorithm-framework.svg?style=social&label=Star&maxAge=1)](https://github.com/SeaQL/sea-orm/stargazers/) If you like what we do, consider starring, sharing and contributing!
88

99
###### Sponsors
10+
1011
<p align="left">
1112
<a href="https://finterion.com">
1213
<img alt="Finterion" src="static/sponsors/finterion.png" width="200px" />
@@ -19,7 +20,7 @@ The Investing Algorithm Framework is a Python framework that enables swift and e
1920

2021
Features:
2122

22-
* Indicators module: A collection of indicators and utility functions that can be used in your trading strategies.
23+
* Indicators module: A collection of indicators and utility functions that can be used in your trading strategies.
2324
* Order execution and tracking
2425
* Broker and exchange connections through [ccxt](https://github.com/ccxt/ccxt)
2526
* Backtesting and performance analysis reports [example](./examples/backtest_example)
@@ -36,23 +37,13 @@ Features:
3637
The following algorithm connects to binance and buys BTC every 5 seconds. It also exposes an REST API that allows you to interact with the algorithm.
3738

3839
```python
39-
import pathlib
40+
import logging
4041
from investing_algorithm_framework import create_app, PortfolioConfiguration, \
41-
RESOURCE_DIRECTORY, TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
42-
CCXTTickerMarketDataSource, MarketCredential, SYMBOLS
43-
44-
# Define the symbols you want to trade for optimization, otherwise the
45-
# algorithm will check if you have orders and balances on all available
46-
# symbols on the market
47-
symbols = ["BTC/EUR"]
42+
TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
43+
CCXTTickerMarketDataSource, MarketCredential, DEFAULT_LOGGING_CONFIG
4844

49-
# Define resource directory and the symbols you want to trade
50-
config = {
51-
RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve(),
52-
SYMBOLS: symbols
53-
}
45+
logging.config.dictConfig(DEFAULT_LOGGING_CONFIG)
5446

55-
# Define market data sources
5647
# OHLCV data for candles
5748
bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
5849
identifier="BTC-ohlcv",
@@ -67,13 +58,10 @@ bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
6758
market="BITVAVO",
6859
symbol="BTC/EUR",
6960
)
70-
app = create_app(config=config)
61+
app = create_app()
7162
algorithm = Algorithm()
72-
app.add_market_credential(MarketCredential(
73-
market="bitvavo",
74-
api_key="<your api key>",
75-
secret_key="<your secret key>",
76-
))
63+
# Bitvavo market credentials are read from .env file
64+
app.add_market_credential(MarketCredential(market="bitvavo"))
7765
app.add_portfolio_configuration(
7866
PortfolioConfiguration(
7967
market="bitvavo",
@@ -83,42 +71,39 @@ app.add_portfolio_configuration(
8371
)
8472
app.add_algorithm(algorithm)
8573

74+
# Run every two hours and register the data sources
8675
@algorithm.strategy(
87-
# Run every two hours
88-
time_unit=TimeUnit.HOUR,
89-
interval=2,
90-
# Specify market data sources that need to be passed to the strategy
76+
time_unit=TimeUnit.HOUR,
77+
interval=2,
9178
market_data_sources=[bitvavo_btc_eur_ticker, bitvavo_btc_eur_ohlcv_2h]
9279
)
9380
def perform_strategy(algorithm: Algorithm, market_data: dict):
94-
# By default, ohlcv data is passed as polars df in the form of
95-
# {"<identifier>": <dataframe>} https://pola.rs/,
96-
# call to_pandas() to convert to pandas
97-
polars_df = market_data["BTC-ohlcv"]
98-
print(f"I have access to {len(polars_df)} candles of ohlcv data")
81+
# Access the data sources with the indentifier
82+
polars_df = market_data["BTC-ohlcv"]
9983

100-
# Ticker data is passed as {"<identifier>": <ticker dict>}
84+
# Convert the polars dataframe to a pandas dataframe
85+
pandas_df = polars_df.to_pandas()
10186
ticker_data = market_data["BTC-ticker"]
10287
unallocated_balance = algorithm.get_unallocated()
10388
positions = algorithm.get_positions()
10489
trades = algorithm.get_trades()
10590
open_trades = algorithm.get_open_trades()
10691
closed_trades = algorithm.get_closed_trades()
107-
108-
# Create a buy oder
92+
93+
# Create a buy oder
10994
algorithm.create_limit_order(
11095
target_symbol="BTC/EUR",
11196
order_side="buy",
11297
amount=0.01,
11398
price=ticker_data["ask"],
11499
)
115-
100+
116101
# Close a trade
117102
algorithm.close_trade(trades[0].id)
118-
103+
119104
# Close a position
120105
algorithm.close_position(positions[0].get_symbol())
121-
106+
122107
if __name__ == "__main__":
123108
app.run()
124109
```
@@ -136,14 +121,14 @@ To run a single backtest you can use the example code that can be found [here](.
136121
You can use the ```pretty_print_backtest``` function to print a backtest report.
137122
For example if you run the [moving average example trading bot](./examples/crossover_moving_average_trading_bot)
138123
you will get the following backtesting report:
139-
124+
140125
```bash
141126

142127
:%%%#+- .=*#%%% Backtest report
143128
*%%%%%%%+------=*%%%%%%%- ---------------------------
144129
*%%%%%%%%%%%%%%%%%%%%%%%- Start date: 2023-08-24 00:00:00
145130
.%%%%%%%%%%%%%%%%%%%%%%# End date: 2023-12-02 00:00:00
146-
#%%%####%%%%%%%%**#%%%+ Number of days: 100
131+
#%%%####%%%%%%%%**#%%%+ Number of days: 100
147132
.:-+*%%%%- -+..#%%%+.+- +%%%#*=-: Number of runs: 1201
148133
.:-=*%%%%. += .%%# -+.-%%%%=-:.. Number of orders: 40
149134
.:=+#%%%%%*###%%%%#*+#%%%%%%*+-: Initial balance: 400.0
@@ -156,10 +141,10 @@ you will get the following backtesting report:
156141
.++- -%%%%%%%%%%%+= Percentage negative trades: 70.0%
157142
.++- .%%%%%%%%%%%%%+= Average trade size: 100.9692 EUR
158143
.++- *%%%%%%%%%%%%%*+: Average trade duration: 83.6 hours
159-
.++- %%%%%%%%%%%%%%#+=
160-
=++........:::%%%%%%%%%%%%%%*+-
161-
.=++++++++++**#%%%%%%%%%%%%%++.
162-
144+
.++- %%%%%%%%%%%%%%#+=
145+
=++........:::%%%%%%%%%%%%%%*+-
146+
.=++++++++++**#%%%%%%%%%%%%%++.
147+
163148
Price noise
164149

165150
Positions overview
@@ -220,8 +205,8 @@ Trades overview
220205

221206
### Backtest experiments
222207

223-
The framework also supports backtest experiments. Backtest experiments allows you to
224-
compare multiple algorithms and evaluate their performance. Ideally,
208+
The framework also supports backtest experiments. Backtest experiments allows you to
209+
compare multiple algorithms and evaluate their performance. Ideally,
225210
you would do this by parameterizing your strategy and creating a factory function that
226211
creates the algorithm with the different parameters. You can find an example of this
227212
in the [backtest experiments example](./examples/backtest_experiment).
@@ -237,16 +222,15 @@ from investing_algorithm_framework import PortfolioConfiguration, \
237222
app = create_app()
238223
app.add_market_credential(
239224
MarketCredential(
240-
market="<your market>",
225+
market="<your market>",
241226
api_key="<your api key>",
242227
secret_key="<your secret key>",
243228
)
244229
)
245230
app.add_portfolio_configuration(
246231
PortfolioConfiguration(
247-
market="<your market>",
232+
market="<your market>",
248233
initial_balance=400,
249-
track_from="01/01/2022",
250234
trading_symbol="EUR"
251235
)
252236
)
@@ -267,27 +251,27 @@ pip install investing-algorithm-framework
267251

268252
## Disclaimer
269253

270-
If you use this framework for your investments, do not risk money
271-
which you are afraid to lose, until you have clear understanding how
254+
If you use this framework for your investments, do not risk money
255+
which you are afraid to lose, until you have clear understanding how
272256
the framework works. We can't stress this enough:
273257

274-
BEFORE YOU START USING MONEY WITH THE FRAMEWORK, MAKE SURE THAT YOU TESTED
275-
YOUR COMPONENTS THOROUGHLY. USE THE SOFTWARE AT YOUR OWN RISK.
258+
BEFORE YOU START USING MONEY WITH THE FRAMEWORK, MAKE SURE THAT YOU TESTED
259+
YOUR COMPONENTS THOROUGHLY. USE THE SOFTWARE AT YOUR OWN RISK.
276260
THE AUTHORS AND ALL AFFILIATES ASSUME NO RESPONSIBILITY FOR YOUR INVESTMENT RESULTS.
277261

278-
Also, make sure that you read the source code of any plugin you use or
262+
Also, make sure that you read the source code of any plugin you use or
279263
implementation of an algorithm made with this framework.
280264

281265
## Documentation
282266

283-
All the documentation can be found online
267+
All the documentation can be found online
284268
at the [documentation webstie](https://investing-algorithm-framework.com)
285269

286-
In most cases, you'll probably never have to change code on this repo directly
287-
if you are building your algorithm/bot. But if you do, check out the
270+
In most cases, you'll probably never have to change code on this repo directly
271+
if you are building your algorithm/bot. But if you do, check out the
288272
contributing page at the website.
289273

290-
If you'd like to chat with investing-algorithm-framework users
274+
If you'd like to chat with investing-algorithm-framework users
291275
and developers, [join us on Slack](https://inv-algo-framework.slack.com) or [join us on reddit](https://www.reddit.com/r/InvestingBots/)
292276

293277
## Acknowledgements
@@ -302,12 +286,12 @@ first. If it hasn't been reported, please [create a new issue](https://github.co
302286

303287
### Contributing
304288

305-
The investing algorithm framework is a community driven project.
289+
The investing algorithm framework is a community driven project.
306290
We welcome you to participate, contribute and together help build the future trading bots developed in python.
307291

308292
Feel like the framework is missing a feature? We welcome your pull requests!
309293
If you want to contribute to the project roadmap, please take a look at the [project board](https://github.com/coding-kitties/investing-algorithm-framework/projects?query=is%3Aopen).
310-
You can pick up a task by assigning yourself to it.
294+
You can pick up a task by assigning yourself to it.
311295

312296
**Note** before starting any major new feature work, *please open an issue describing what you are planning to do*.
313297
This will ensure that interested parties can give valuable feedback on the feature, and let others know that you are working on it.

examples/app.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from dotenv import load_dotenv
2+
3+
from investing_algorithm_framework import create_app, PortfolioConfiguration, \
4+
TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
5+
CCXTTickerMarketDataSource, MarketCredential, AzureBlobStorageStateHandler
6+
7+
load_dotenv()
8+
9+
# Define market data sources
10+
# OHLCV data for candles
11+
bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
12+
identifier="BTC-ohlcv",
13+
market="BITVAVO",
14+
symbol="BTC/EUR",
15+
time_frame="2h",
16+
window_size=200
17+
)
18+
# Ticker data for orders, trades and positions
19+
bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
20+
identifier="BTC-ticker",
21+
market="BITVAVO",
22+
symbol="BTC/EUR",
23+
)
24+
app = create_app(state_handler=AzureBlobStorageStateHandler())
25+
app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
26+
algorithm = Algorithm()
27+
app.add_market_credential(MarketCredential(market="bitvavo"))
28+
app.add_portfolio_configuration(
29+
PortfolioConfiguration(
30+
market="bitvavo",
31+
trading_symbol="EUR",
32+
initial_balance=20
33+
)
34+
)
35+
app.add_algorithm(algorithm)
36+
37+
@algorithm.strategy(
38+
# Run every two hours
39+
time_unit=TimeUnit.HOUR,
40+
interval=2,
41+
# Specify market data sources that need to be passed to the strategy
42+
market_data_sources=[bitvavo_btc_eur_ticker, "BTC-ohlcv"]
43+
)
44+
def perform_strategy(algorithm: Algorithm, market_data: dict):
45+
# By default, ohlcv data is passed as polars df in the form of
46+
# {"<identifier>": <dataframe>} https://pola.rs/,
47+
# call to_pandas() to convert to pandas
48+
polars_df = market_data["BTC-ohlcv"]
49+
print(f"I have access to {len(polars_df)} candles of ohlcv data")

examples/bitvavo_trading_bot/bitvavo.py

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,28 @@
1-
import os
2-
31
from investing_algorithm_framework import MarketCredential, TimeUnit, \
42
CCXTOHLCVMarketDataSource, CCXTTickerMarketDataSource, TradingStrategy, \
5-
create_app, PortfolioConfiguration, Algorithm, SYMBOLS, RESOURCE_DIRECTORY
3+
create_app, PortfolioConfiguration, Algorithm
64

75
"""
86
Bitvavo trading bot example with market data sources of bitvavo.
9-
Bitvavo does not requires you to have an API key and secret key to access
10-
their market data. If you just want to backtest your strategy,
7+
Bitvavo does not requires you to have an API key and secret key to access
8+
their market data. If you just want to backtest your strategy,
119
you don't need to add a market credential. If your running your strategy live,
12-
you need to add a market credential to the app, that accesses your
10+
you need to add a market credential to the app, that accesses your
1311
account on bitvavo.
1412
"""
1513

16-
1714
# Define your market credential for bitvavo
1815
bitvavo_market_credential = MarketCredential(
19-
api_key="<your_api_key>",
20-
secret_key="<your_secret_key>",
2116
market="bitvavo",
17+
api_key="your_api_key",
18+
secret_key="your_secret_key"
2219
)
2320
# Define your market data sources for coinbase
2421
bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
2522
identifier="BTC/EUR-ohlcv",
2623
market="bitvavo",
2724
symbol="BTC/EUR",
28-
timeframe="2h",
25+
time_frame="2h",
2926
window_size=200
3027
)
3128
bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
@@ -36,26 +33,20 @@
3633

3734

3835
class BitvavoTradingStrategy(TradingStrategy):
39-
time_unit = TimeUnit.HOUR
40-
interval = 2
36+
time_unit = TimeUnit.SECOND
37+
interval = 10
4138
market_data_sources = [bitvavo_btc_eur_ohlcv_2h, bitvavo_btc_eur_ticker]
4239

4340
def apply_strategy(self, algorithm, market_data):
4441
print(market_data["BTC/EUR-ohlcv"])
4542
print(market_data["BTC/EUR-ticker"])
4643

47-
48-
config = {
49-
SYMBOLS: ["BTC/EUR"],
50-
RESOURCE_DIRECTORY: os.path.join(os.path.dirname(__file__), "resources")
51-
}
52-
5344
# Create an algorithm and link your trading strategy to it
5445
algorithm = Algorithm()
5546
algorithm.add_strategy(BitvavoTradingStrategy)
5647

5748
# Create an app and add the market data sources and market credentials to it
58-
app = create_app(config=config)
49+
app = create_app()
5950
app.add_market_credential(bitvavo_market_credential)
6051
app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
6152
app.add_market_data_source(bitvavo_btc_eur_ticker)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

0 commit comments

Comments
 (0)