Skip to content
This repository has been archived by the owner on Aug 27, 2024. It is now read-only.

Commit

Permalink
revert back to kraken
Browse files Browse the repository at this point in the history
add get max periods fn
add initial pre-caching
add check for periods vs max periods
widen plots
change date formatting
  • Loading branch information
CelestialCrafter committed Nov 29, 2023
1 parent 47a7ef3 commit aa60762
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 61 deletions.
11 changes: 7 additions & 4 deletions algorithms/bollinger_bands.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from talib import BBANDS
from price import get_periods
from price import get_periods, get_max_periods

def algorithm(prices, window_size=(20, 'days'), standard_deviations=2):
print(prices.shape[0])
print(get_periods(*window_size))
return BBANDS(prices, timeperiod=get_periods(*window_size), nbdevup=standard_deviations, nbdevdn=standard_deviations)
periods = get_periods(*window_size)

if get_max_periods() < periods:
raise Exception(f'Not Enough Datapoints for this Interval')

return BBANDS(prices, timeperiod=periods, nbdevup=standard_deviations, nbdevdn=standard_deviations)

def signal(prices, data):
upper_band, middle_band, lower_band = data
Expand Down
7 changes: 6 additions & 1 deletion algorithms/rsi.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
from talib import RSI
from price import get_periods
from price import get_periods, get_max_periods

def algorithm(prices, window_size=(14, 'days')):
periods = get_periods(*window_size)

if get_max_periods() < periods:
raise Exception(f'Not Enough Datapoints for this Interval')

return RSI(prices, timeperiod=get_periods(*window_size))

def signal(prices, data, high=70, low=30):
Expand Down
21 changes: 0 additions & 21 deletions plot.py

This file was deleted.

90 changes: 65 additions & 25 deletions price.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
load_dotenv()
redis = from_url(os.environ['REDIS_URI'])

# {60 300 900 3600 21600 86400}
# 1m 5m 15m 1h 6h 1d
# 5h 25h 3d3h 12d12h 2mo15d 10mo
# 1 5 15 30 60 240 1440 10080 21600
# 12h 2d12h 1w12h 2w1d 1mo 4mo 2y 14y 30y

point_count = 300
default_interval = 21600
cached_intervals = [300, 900, 3600, 21600]
supported_intervals = [60, 300, 900, 3600, 21600, 86400]
base_point_count = 720
pre_fetch_price_count = 1
point_count = base_point_count * (pre_fetch_price_count + 1)
default_interval = 240
cached_intervals = [30, 60, 240, 1440]
supported_intervals = [1, 5, 15, 30, 60, 240, 1440, 10080]

def is_supported_interval(interval):
global supported_intervals
Expand All @@ -42,16 +43,23 @@ def get_default_interval():
return int(interval)
return default_interval

def get_prices(pair='ETH-USD', interval='default'):
def get_prices(pair='ETH/USD', interval='default', base_timestamp=None):
if interval == 'default':
interval = get_default_interval()
if base_timestamp:
base_timestamp = int(base_timestamp)

ohlc = get(f'https://api.exchange.coinbase.com/products/{pair}/candles?granularity={interval}').json()
ohlc = get(
f'https://api.kraken.com/0/public/OHLC?pair={pair}&interval={interval}{f"&since={base_timestamp}" if base_timestamp else ""}'
).json()

prices = [point[4] for point in ohlc]
timestamps = [point[0] for point in ohlc]
if 'result' not in ohlc:
raise Exception(ohlc['error'][0])

return np.flip(prices), np.flip(timestamps)
timestamps = [point[0] for point in list(ohlc['result'].values())[0]]
prices = [float(point[4]) for point in list(ohlc['result'].values())[0]]

return np.array(prices).astype(float), np.array(timestamps).astype(float)

def get_cached_prices(interval='default'):
if interval == 'default':
Expand All @@ -73,37 +81,69 @@ def get_periods(period_size, period_type, interval='default'):
interval = get_default_interval()

if 'month' in period_type:
period_multiplier = 30 * 24 * 60 * 60
period_multiplier = 30 * 24 * 60
elif 'week' in period_type:
period_multiplier = 7 * 24 * 60 * 60
period_multiplier = 7 * 24 * 60
elif 'day' in period_type:
period_multiplier = 24 * 60 * 60
period_multiplier = 24 * 60
elif 'hour' in period_type:
period_multiplier = 60 * 60
elif 'minute' in period_type:
period_multiplier = 60
elif 'second' in period_type:
elif 'minute' in period_type:
period_multiplier = 1
period_seconds = period_size * period_multiplier

return max(ceil(period_seconds / interval), 2)
return ceil(period_seconds / interval)

def get_max_periods(interval='default'):
if interval == 'default':
interval = get_default_interval()

return ceil(base_point_count * interval)

# Price Caching
def cache_prices():
def update_cached_prices():
for interval in cached_intervals:
print(f'Caching prices for {interval}')
cached_prices, cached_timestamps = get_cached_prices(interval)
prices, timestamps = get_prices(interval=interval)

redis.delete(f'prices:{interval}')
redis.lpush(f'prices:{interval}', *prices.tolist())
mask = np.isin(timestamps, cached_timestamps)
prices = prices[mask]
timestamps = timestamps[mask]

redis.rpush(f'prices:{interval}', *prices.tolist())
redis.rpush(f'timestamps:{interval}', *timestamps.tolist())

def initial_cache():
global point_count

for interval in cached_intervals:
redis.delete(f'prices:{interval}')
redis.delete(f'timestamps:{interval}')
redis.lpush(f'timestamps:{interval}', *timestamps.tolist())

schedule.every(3).minutes.do(cache_prices)
full_prices, full_timestamps = get_prices(interval=interval)
initial_base_timestamp = full_timestamps[0]

for i in range(1, pre_fetch_price_count + 1):
print(f'Caching {interval}.{i} (Initial)')
base_timestamp = initial_base_timestamp - (interval * base_point_count * i)

prices, timestamps = get_prices(interval=interval, base_timestamp=base_timestamp)

mask = np.isin(timestamps, full_timestamps)
prices = prices[mask]
timestamps = timestamps[mask]

full_prices = np.concatenate((full_prices, prices))
full_timestamps = np.concatenate((full_timestamps, timestamps))

redis.lpush(f'prices:{interval}', *full_prices.tolist())
redis.lpush(f'timestamps:{interval}', *full_timestamps.tolist())

initial_cache()
schedule.every(3).minutes.do(update_cached_prices)

def job_loop():
schedule.run_all()
while True:
schedule.run_pending()
time.sleep(1)
Expand Down
31 changes: 21 additions & 10 deletions views/plot.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import io
import matplotlib
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.dates as md
import numpy as np
Expand All @@ -9,7 +9,10 @@
from price import get_cached_prices, get_prices, is_cached_interval, is_supported_interval, get_default_interval
from utils import get_algorithms

matplotlib.use('Agg')
mpl.use('Agg')

figure_size = mpl.rcParams['figure.figsize']
figure_size[0] = figure_size[0] * 1.5

def plot(algorithm):
interval = int(request.args.get('interval'))
Expand All @@ -28,23 +31,31 @@ def plot(algorithm):

# Even out timestamps so plotting algos works
timestamps = timestamps.astype('datetime64[s]')
interval_timedelta = np.timedelta64(get_default_interval(), 's')
timestamps = np.arange(timestamps[0], timestamps[0] + interval_timedelta * 300, interval_timedelta)
interval_timedelta = np.timedelta64(get_default_interval(), 'm')
timestamps = np.arange(timestamps[-1] - interval_timedelta * timestamps.shape[0], timestamps[-1], interval_timedelta)

import_module(f'plots.{algorithm}').plot(prices, timestamps)
try:
import_module(f'plots.{algorithm}').plot(prices, timestamps)
except Exception as error:
return str(error), 400

axes = plt.gcf().get_axes()
for axis in axes:
axis.tick_params(color=colors.outline(), labelcolor=colors.outline())
for spine in axis.spines.values():
spine.set_edgecolor(colors.outline())
if interval <= 3600:
xfmt = md.DateFormatter('%d')
elif interval <= 21600:
if interval >= 10080:
xfmt = md.DateFormatter(fmt='%Y')
elif interval >= 1440:
xfmt = md.DateFormatter('%y/%m')
elif interval >= 240:
xfmt = md.DateFormatter('%m/%d')
elif interval >= 15:
xfmt = md.DateFormatter('%d')
else:
xfmt = md.DateFormatter('%m')
axis.xaxis.set_major_formatter(xfmt)
xfmt = md.DateFormatter('%H')

axis.xaxis.set_major_formatter(formatter=xfmt)

plt.tight_layout()

Expand Down

0 comments on commit aa60762

Please sign in to comment.