-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
95 changed files
with
7,712 additions
and
11,537 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from investing_algorithm_framework import Algorithm | ||
from .strategy import CrossOverStrategy | ||
|
||
algorithm = Algorithm() | ||
algorithm.add_strategy(CrossOverStrategy) |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import tulipy as ti | ||
|
||
from investing_algorithm_framework import TimeUnit, TradingStrategy, \ | ||
Algorithm, OrderSide | ||
|
||
""" | ||
This strategy is based on the golden cross strategy. It will buy when the | ||
fast moving average crosses the slow moving average from below. It will sell | ||
when the fast moving average crosses the slow moving average from above. | ||
The strategy will also check if the fast moving average is above the trend | ||
moving average. If it is not above the trend moving average it will not buy. | ||
It uses tulipy indicators to calculate the metrics. You need to | ||
install this library in your environment to run this strategy. | ||
You can find instructions on how to install tulipy here: | ||
https://tulipindicators.org/ or go directly to the pypi page: | ||
https://pypi.org/project/tulipy/ | ||
""" | ||
def is_below_trend(fast_series, slow_series): | ||
return fast_series[-1] < slow_series[-1] | ||
|
||
|
||
def is_above_trend(fast_series, slow_series): | ||
return fast_series[-1] > slow_series[-1] | ||
|
||
|
||
def is_crossover(fast, slow): | ||
""" | ||
Expect df to have columns: Date, ma_<period_one>, ma_<period_two>. | ||
With the given date time it will check if the ma_<period_one> is a | ||
crossover with the ma_<period_two> | ||
""" | ||
return fast[-2] <= slow[-2] and fast[-1] > slow[-1] | ||
|
||
|
||
def is_crossunder(fast, slow): | ||
""" | ||
Expect df to have columns: Date, ma_<period_one>, ma_<period_two>. | ||
With the given date time it will check if the ma_<period_one> is a | ||
crossover with the ma_<period_two> | ||
""" | ||
return fast[-2] >= slow[-2] and fast[-1] < slow[-1] | ||
|
||
|
||
class CrossOverStrategy(TradingStrategy): | ||
time_unit = TimeUnit.HOUR | ||
interval = 2 | ||
market_data_sources = [ | ||
"BTC/EUR-ohlcv", | ||
"DOT/EUR-ohlcv", | ||
"BTC/EUR-ticker", | ||
"DOT/EUR-ticker" | ||
] | ||
symbols = ["BTC/EUR", "DOT/EUR"] | ||
fast = 9 | ||
slow = 50 | ||
trend = 100 | ||
|
||
def apply_strategy(self, algorithm: Algorithm, market_data): | ||
|
||
for symbol in self.symbols: | ||
target_symbol = symbol.split('/')[0] | ||
|
||
if algorithm.has_open_orders(target_symbol): | ||
continue | ||
|
||
df = market_data[f"{symbol}-ohlcv"] | ||
ticker_data = market_data[f"{symbol}-ticker"] | ||
fast = ti.sma(df['Close'].to_numpy(), 9) | ||
slow = ti.sma(df['Close'].to_numpy(), 50) | ||
trend = ti.sma(df['Close'].to_numpy(), 100) | ||
price = ticker_data['bid'] | ||
|
||
if not algorithm.has_position(target_symbol) \ | ||
and is_crossover(fast, slow) \ | ||
and is_above_trend(fast, trend): | ||
algorithm.create_limit_order( | ||
target_symbol=target_symbol, | ||
order_side=OrderSide.BUY, | ||
price=price, | ||
percentage_of_portfolio=25, | ||
precision=4, | ||
) | ||
|
||
if algorithm.has_position(target_symbol) \ | ||
and is_below_trend(fast, slow): | ||
|
||
open_trades = algorithm.get_open_trades( | ||
target_symbol=target_symbol | ||
) | ||
|
||
for trade in open_trades: | ||
algorithm.close_trade(trade) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,7 @@ | ||
import pathlib | ||
|
||
from data_sources import bitvavo_btc_eur_ohlcv_2h, bitvavo_dot_eur_ohlcv_2h, \ | ||
bitvavo_dot_eur_ticker, bitvavo_btc_eur_ticker | ||
from investing_algorithm_framework import create_app, RESOURCE_DIRECTORY | ||
|
||
app = create_app( | ||
config={RESOURCE_DIRECTORY: pathlib.Path(__file__).parent.resolve()} | ||
) | ||
app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h) | ||
app.add_market_data_source(bitvavo_dot_eur_ohlcv_2h) | ||
app.add_market_data_source(bitvavo_btc_eur_ticker) | ||
app.add_market_data_source(bitvavo_dot_eur_ticker) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
from datetime import datetime, timedelta | ||
|
||
from investing_algorithm_framework import PortfolioConfiguration, \ | ||
pretty_print_backtest | ||
|
||
from app import app | ||
from algorithm.algorithm import algorithm | ||
from algorithm.data_sources import bitvavo_btc_eur_ohlcv_2h, \ | ||
bitvavo_dot_eur_ohlcv_2h, bitvavo_dot_eur_ticker, bitvavo_btc_eur_ticker | ||
|
||
|
||
app.add_algorithm(algorithm) | ||
app.add_market_data_source(bitvavo_btc_eur_ohlcv_2h) | ||
app.add_market_data_source(bitvavo_dot_eur_ohlcv_2h) | ||
app.add_market_data_source(bitvavo_btc_eur_ticker) | ||
app.add_market_data_source(bitvavo_dot_eur_ticker) | ||
|
||
|
||
# Add a portfolio configuration of 400 euro initial balance | ||
app.add_portfolio_configuration( | ||
PortfolioConfiguration( | ||
market="BINANCE", | ||
trading_symbol="EUR", | ||
initial_balance=400, | ||
) | ||
) | ||
|
||
if __name__ == "__main__": | ||
end_date = datetime(2023, 12, 2) | ||
start_date = end_date - timedelta(days=100) | ||
backtest_report = app.run_backtest( | ||
algorithm=algorithm, | ||
start_date=start_date, | ||
end_date=end_date, | ||
pending_order_check_interval="2h", | ||
) | ||
pretty_print_backtest(backtest_report) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,4 @@ | ||
from .algorithm_one import algorithm as algorithm_one | ||
from .algorithm_two import algorithm as algorithm_two | ||
from .algorithm_three import algorithm as algorithm_three | ||
from .algorithm import create_algorithm | ||
|
||
|
||
__all__ = [ | ||
"algorithm_one", | ||
"algorithm_two", | ||
"algorithm_three", | ||
] | ||
__all__ = ["create_algorithm"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
from investing_algorithm_framework import Algorithm, TradingStrategy, \ | ||
TimeUnit, OrderSide | ||
import tulipy as ti | ||
|
||
def is_below_trend(fast_series, slow_series): | ||
return fast_series[-1] < slow_series[-1] | ||
|
||
|
||
def is_above_trend(fast_series, slow_series): | ||
return fast_series[-1] > slow_series[-1] | ||
|
||
|
||
def is_crossover(fast, slow): | ||
""" | ||
Expect df to have columns: Date, ma_<period_one>, ma_<period_two>. | ||
With the given date time it will check if the ma_<period_one> is a | ||
crossover with the ma_<period_two> | ||
""" | ||
return fast[-2] <= slow[-2] and fast[-1] > slow[-1] | ||
|
||
|
||
def is_crossunder(fast, slow): | ||
""" | ||
Expect df to have columns: Date, ma_<period_one>, ma_<period_two>. | ||
With the given date time it will check if the ma_<period_one> is a | ||
crossover with the ma_<period_two> | ||
""" | ||
return fast[-2] >= slow[-2] and fast[-1] < slow[-1] | ||
|
||
|
||
class Strategy(TradingStrategy): | ||
time_unit = TimeUnit.HOUR | ||
interval = 2 | ||
market_data_sources = [ | ||
"BTC/EUR-ohlcv", | ||
"DOT/EUR-ohlcv", | ||
"BTC/EUR-ticker", | ||
"DOT/EUR-ticker" | ||
] | ||
symbols = ["BTC/EUR", "DOT/EUR"] | ||
|
||
def __init__(self, fast, slow, trend): | ||
self.fast = fast | ||
self.slow = slow | ||
self.trend = trend | ||
super().__init__() | ||
|
||
def apply_strategy(self, algorithm: Algorithm, market_data): | ||
|
||
for symbol in self.symbols: | ||
target_symbol = symbol.split('/')[0] | ||
|
||
if algorithm.has_open_orders(target_symbol): | ||
continue | ||
|
||
df = market_data[f"{symbol}-ohlcv"] | ||
ticker_data = market_data[f"{symbol}-ticker"] | ||
fast = ti.sma(df['Close'].to_numpy(), self.fast) | ||
slow = ti.sma(df['Close'].to_numpy(), self.slow) | ||
trend = ti.sma(df['Close'].to_numpy(), self.trend) | ||
price = ticker_data['bid'] | ||
|
||
if not algorithm.has_position(target_symbol) \ | ||
and is_crossover(fast, slow) \ | ||
and is_above_trend(fast, trend): | ||
algorithm.create_limit_order( | ||
target_symbol=target_symbol, | ||
order_side=OrderSide.BUY, | ||
price=price, | ||
percentage_of_portfolio=25, | ||
precision=4, | ||
) | ||
|
||
if algorithm.has_position(target_symbol) \ | ||
and is_below_trend(fast, slow): | ||
|
||
open_trades = algorithm.get_open_trades( | ||
target_symbol=target_symbol | ||
) | ||
|
||
for trade in open_trades: | ||
algorithm.close_trade(trade) | ||
|
||
|
||
def create_algorithm( | ||
name, | ||
description, | ||
fast, | ||
slow, | ||
trend | ||
) -> Algorithm: | ||
algorithm = Algorithm( | ||
name=name, | ||
description=description | ||
) | ||
algorithm.add_strategy(Strategy(fast, slow, trend)) | ||
return algorithm |
This file was deleted.
Oops, something went wrong.
16 changes: 0 additions & 16 deletions
16
examples/backtest_expirement/algorithms/algorithm_three.py
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.