Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue with data sources parameters passing #284

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ jobs:
- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 1.7.1
virtualenvs-create: true
virtualenvs-in-project: true
#----------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*__pycache__/
*.py[cod]
*$py.class
.DS_Store

# C extensions
*.so
Expand Down
100 changes: 42 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
[![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!

###### Sponsors

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

Features:

* Indicators module: A collection of indicators and utility functions that can be used in your trading strategies.
* Indicators module: A collection of indicators and utility functions that can be used in your trading strategies.
* Order execution and tracking
* Broker and exchange connections through [ccxt](https://github.com/ccxt/ccxt)
* Backtesting and performance analysis reports [example](./examples/backtest_example)
Expand All @@ -36,23 +37,13 @@ Features:
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.

```python
import pathlib
import logging
from investing_algorithm_framework import create_app, PortfolioConfiguration, \
RESOURCE_DIRECTORY, TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
CCXTTickerMarketDataSource, MarketCredential, SYMBOLS

# Define the symbols you want to trade for optimization, otherwise the
# algorithm will check if you have orders and balances on all available
# symbols on the market
symbols = ["BTC/EUR"]
TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
CCXTTickerMarketDataSource, MarketCredential, DEFAULT_LOGGING_CONFIG

# Define resource directory and the symbols you want to trade
config = {
RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve(),
SYMBOLS: symbols
}
logging.config.dictConfig(DEFAULT_LOGGING_CONFIG)

# Define market data sources
# OHLCV data for candles
bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
identifier="BTC-ohlcv",
Expand All @@ -67,13 +58,10 @@ bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
market="BITVAVO",
symbol="BTC/EUR",
)
app = create_app(config=config)
app = create_app()
algorithm = Algorithm()
app.add_market_credential(MarketCredential(
market="bitvavo",
api_key="<your api key>",
secret_key="<your secret key>",
))
# Bitvavo market credentials are read from .env file
app.add_market_credential(MarketCredential(market="bitvavo"))
app.add_portfolio_configuration(
PortfolioConfiguration(
market="bitvavo",
Expand All @@ -83,42 +71,39 @@ app.add_portfolio_configuration(
)
app.add_algorithm(algorithm)

# Run every two hours and register the data sources
@algorithm.strategy(
# Run every two hours
time_unit=TimeUnit.HOUR,
interval=2,
# Specify market data sources that need to be passed to the strategy
time_unit=TimeUnit.HOUR,
interval=2,
market_data_sources=[bitvavo_btc_eur_ticker, bitvavo_btc_eur_ohlcv_2h]
)
def perform_strategy(algorithm: Algorithm, market_data: dict):
# By default, ohlcv data is passed as polars df in the form of
# {"<identifier>": <dataframe>} https://pola.rs/,
# call to_pandas() to convert to pandas
polars_df = market_data["BTC-ohlcv"]
print(f"I have access to {len(polars_df)} candles of ohlcv data")
# Access the data sources with the indentifier
polars_df = market_data["BTC-ohlcv"]

# Ticker data is passed as {"<identifier>": <ticker dict>}
# Convert the polars dataframe to a pandas dataframe
pandas_df = polars_df.to_pandas()
ticker_data = market_data["BTC-ticker"]
unallocated_balance = algorithm.get_unallocated()
positions = algorithm.get_positions()
trades = algorithm.get_trades()
open_trades = algorithm.get_open_trades()
closed_trades = algorithm.get_closed_trades()
# Create a buy oder

# Create a buy oder
algorithm.create_limit_order(
target_symbol="BTC/EUR",
order_side="buy",
amount=0.01,
price=ticker_data["ask"],
)

# Close a trade
algorithm.close_trade(trades[0].id)

# Close a position
algorithm.close_position(positions[0].get_symbol())

if __name__ == "__main__":
app.run()
```
Expand All @@ -136,14 +121,14 @@ To run a single backtest you can use the example code that can be found [here](.
You can use the ```pretty_print_backtest``` function to print a backtest report.
For example if you run the [moving average example trading bot](./examples/crossover_moving_average_trading_bot)
you will get the following backtesting report:

```bash

:%%%#+- .=*#%%% Backtest report
*%%%%%%%+------=*%%%%%%%- ---------------------------
*%%%%%%%%%%%%%%%%%%%%%%%- Start date: 2023-08-24 00:00:00
.%%%%%%%%%%%%%%%%%%%%%%# End date: 2023-12-02 00:00:00
#%%%####%%%%%%%%**#%%%+ Number of days: 100
#%%%####%%%%%%%%**#%%%+ Number of days: 100
.:-+*%%%%- -+..#%%%+.+- +%%%#*=-: Number of runs: 1201
.:-=*%%%%. += .%%# -+.-%%%%=-:.. Number of orders: 40
.:=+#%%%%%*###%%%%#*+#%%%%%%*+-: Initial balance: 400.0
Expand All @@ -156,10 +141,10 @@ you will get the following backtesting report:
.++- -%%%%%%%%%%%+= Percentage negative trades: 70.0%
.++- .%%%%%%%%%%%%%+= Average trade size: 100.9692 EUR
.++- *%%%%%%%%%%%%%*+: Average trade duration: 83.6 hours
.++- %%%%%%%%%%%%%%#+=
=++........:::%%%%%%%%%%%%%%*+-
.=++++++++++**#%%%%%%%%%%%%%++.
.++- %%%%%%%%%%%%%%#+=
=++........:::%%%%%%%%%%%%%%*+-
.=++++++++++**#%%%%%%%%%%%%%++.

Price noise

Positions overview
Expand Down Expand Up @@ -220,8 +205,8 @@ Trades overview

### Backtest experiments

The framework also supports backtest experiments. Backtest experiments allows you to
compare multiple algorithms and evaluate their performance. Ideally,
The framework also supports backtest experiments. Backtest experiments allows you to
compare multiple algorithms and evaluate their performance. Ideally,
you would do this by parameterizing your strategy and creating a factory function that
creates the algorithm with the different parameters. You can find an example of this
in the [backtest experiments example](./examples/backtest_experiment).
Expand All @@ -237,16 +222,15 @@ from investing_algorithm_framework import PortfolioConfiguration, \
app = create_app()
app.add_market_credential(
MarketCredential(
market="<your market>",
market="<your market>",
api_key="<your api key>",
secret_key="<your secret key>",
)
)
app.add_portfolio_configuration(
PortfolioConfiguration(
market="<your market>",
market="<your market>",
initial_balance=400,
track_from="01/01/2022",
trading_symbol="EUR"
)
)
Expand All @@ -267,27 +251,27 @@ pip install investing-algorithm-framework

## Disclaimer

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

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

Also, make sure that you read the source code of any plugin you use or
Also, make sure that you read the source code of any plugin you use or
implementation of an algorithm made with this framework.

## Documentation

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

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

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

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

### Contributing

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

Feel like the framework is missing a feature? We welcome your pull requests!
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).
You can pick up a task by assigning yourself to it.
You can pick up a task by assigning yourself to it.

**Note** before starting any major new feature work, *please open an issue describing what you are planning to do*.
This will ensure that interested parties can give valuable feedback on the feature, and let others know that you are working on it.
Expand Down
49 changes: 49 additions & 0 deletions examples/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from dotenv import load_dotenv

from investing_algorithm_framework import create_app, PortfolioConfiguration, \
TimeUnit, CCXTOHLCVMarketDataSource, Algorithm, \
CCXTTickerMarketDataSource, MarketCredential, AzureBlobStorageStateHandler

load_dotenv()

# Define market data sources
# OHLCV data for candles
bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
identifier="BTC-ohlcv",
market="BITVAVO",
symbol="BTC/EUR",
time_frame="2h",
window_size=200
)
# Ticker data for orders, trades and positions
bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
identifier="BTC-ticker",
market="BITVAVO",
symbol="BTC/EUR",
)
app = create_app(state_handler=AzureBlobStorageStateHandler())
app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
algorithm = Algorithm()
app.add_market_credential(MarketCredential(market="bitvavo"))
app.add_portfolio_configuration(
PortfolioConfiguration(
market="bitvavo",
trading_symbol="EUR",
initial_balance=20
)
)
app.add_algorithm(algorithm)

@algorithm.strategy(
# Run every two hours
time_unit=TimeUnit.HOUR,
interval=2,
# Specify market data sources that need to be passed to the strategy
market_data_sources=[bitvavo_btc_eur_ticker, "BTC-ohlcv"]
)
def perform_strategy(algorithm: Algorithm, market_data: dict):
# By default, ohlcv data is passed as polars df in the form of
# {"<identifier>": <dataframe>} https://pola.rs/,
# call to_pandas() to convert to pandas
polars_df = market_data["BTC-ohlcv"]
print(f"I have access to {len(polars_df)} candles of ohlcv data")
29 changes: 10 additions & 19 deletions examples/bitvavo_trading_bot/bitvavo.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
import os

from investing_algorithm_framework import MarketCredential, TimeUnit, \
CCXTOHLCVMarketDataSource, CCXTTickerMarketDataSource, TradingStrategy, \
create_app, PortfolioConfiguration, Algorithm, SYMBOLS, RESOURCE_DIRECTORY
create_app, PortfolioConfiguration, Algorithm

"""
Bitvavo trading bot example with market data sources of bitvavo.
Bitvavo does not requires you to have an API key and secret key to access
their market data. If you just want to backtest your strategy,
Bitvavo does not requires you to have an API key and secret key to access
their market data. If you just want to backtest your strategy,
you don't need to add a market credential. If your running your strategy live,
you need to add a market credential to the app, that accesses your
you need to add a market credential to the app, that accesses your
account on bitvavo.
"""


# Define your market credential for bitvavo
bitvavo_market_credential = MarketCredential(
api_key="<your_api_key>",
secret_key="<your_secret_key>",
market="bitvavo",
api_key="your_api_key",
secret_key="your_secret_key"
)
# Define your market data sources for coinbase
bitvavo_btc_eur_ohlcv_2h = CCXTOHLCVMarketDataSource(
identifier="BTC/EUR-ohlcv",
market="bitvavo",
symbol="BTC/EUR",
timeframe="2h",
time_frame="2h",
window_size=200
)
bitvavo_btc_eur_ticker = CCXTTickerMarketDataSource(
Expand All @@ -36,26 +33,20 @@


class BitvavoTradingStrategy(TradingStrategy):
time_unit = TimeUnit.HOUR
interval = 2
time_unit = TimeUnit.SECOND
interval = 10
market_data_sources = [bitvavo_btc_eur_ohlcv_2h, bitvavo_btc_eur_ticker]

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


config = {
SYMBOLS: ["BTC/EUR"],
RESOURCE_DIRECTORY: os.path.join(os.path.dirname(__file__), "resources")
}

# Create an algorithm and link your trading strategy to it
algorithm = Algorithm()
algorithm.add_strategy(BitvavoTradingStrategy)

# Create an app and add the market data sources and market credentials to it
app = create_app(config=config)
app = create_app()
app.add_market_credential(bitvavo_market_credential)
app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h)
app.add_market_data_source(bitvavo_btc_eur_ticker)
Expand Down
1 change: 1 addition & 0 deletions examples/deployments/azure_function/.funcignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Loading
Loading