2022-05-23 19:05:05 +00:00
|
|
|
|
2022-05-30 09:37:05 +00:00
|
|
|
import copy
|
2022-05-23 19:05:05 +00:00
|
|
|
import json
|
|
|
|
import logging
|
|
|
|
from pathlib import Path
|
|
|
|
from typing import Any, Dict, Tuple
|
|
|
|
|
|
|
|
# import pickle as pk
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class FreqaiDataDrawer:
|
|
|
|
"""
|
|
|
|
Class aimed at holding all pair models/info in memory for better inferencing/retrainig/saving
|
|
|
|
/loading to/from disk.
|
|
|
|
This object remains persistent throughout live/dry, unlike FreqaiDataKitchen, which is
|
|
|
|
reinstantiated for each coin.
|
|
|
|
"""
|
2022-05-24 13:28:38 +00:00
|
|
|
def __init__(self, full_path: Path, pair_whitelist):
|
2022-05-23 19:05:05 +00:00
|
|
|
|
|
|
|
# dictionary holding all pair metadata necessary to load in from disk
|
|
|
|
self.pair_dict: Dict[str, Any] = {}
|
|
|
|
# dictionary holding all actively inferenced models in memory given a model filename
|
|
|
|
self.model_dictionary: Dict[str, Any] = {}
|
2022-05-30 09:37:05 +00:00
|
|
|
self.model_return_values: Dict[str, Any] = {}
|
2022-05-24 10:01:01 +00:00
|
|
|
self.pair_data_dict: Dict[str, Any] = {}
|
2022-05-23 19:05:05 +00:00
|
|
|
self.full_path = full_path
|
|
|
|
self.load_drawer_from_disk()
|
2022-05-24 13:28:38 +00:00
|
|
|
self.training_queue: Dict[str, int] = {}
|
2022-05-28 16:26:19 +00:00
|
|
|
# self.create_training_queue(pair_whitelist)
|
2022-05-23 19:05:05 +00:00
|
|
|
|
|
|
|
def load_drawer_from_disk(self):
|
|
|
|
exists = Path(self.full_path / str('pair_dictionary.json')).resolve().exists()
|
|
|
|
if exists:
|
|
|
|
with open(self.full_path / str('pair_dictionary.json'), "r") as fp:
|
|
|
|
self.pair_dict = json.load(fp)
|
|
|
|
else:
|
|
|
|
logger.info("Could not find existing datadrawer, starting from scratch")
|
|
|
|
return exists
|
|
|
|
|
|
|
|
def save_drawer_to_disk(self):
|
|
|
|
with open(self.full_path / str('pair_dictionary.json'), "w") as fp:
|
|
|
|
json.dump(self.pair_dict, fp, default=self.np_encoder)
|
|
|
|
|
|
|
|
def np_encoder(self, object):
|
|
|
|
if isinstance(object, np.generic):
|
|
|
|
return object.item()
|
|
|
|
|
|
|
|
def get_pair_dict_info(self, metadata: dict) -> Tuple[str, int, bool]:
|
|
|
|
pair_in_dict = self.pair_dict.get(metadata['pair'])
|
|
|
|
if pair_in_dict:
|
|
|
|
model_filename = self.pair_dict[metadata['pair']]['model_filename']
|
|
|
|
trained_timestamp = self.pair_dict[metadata['pair']]['trained_timestamp']
|
|
|
|
coin_first = self.pair_dict[metadata['pair']]['first']
|
|
|
|
else:
|
|
|
|
self.pair_dict[metadata['pair']] = {}
|
|
|
|
model_filename = self.pair_dict[metadata['pair']]['model_filename'] = ''
|
|
|
|
coin_first = self.pair_dict[metadata['pair']]['first'] = True
|
|
|
|
trained_timestamp = self.pair_dict[metadata['pair']]['trained_timestamp'] = 0
|
|
|
|
|
|
|
|
return model_filename, trained_timestamp, coin_first
|
2022-05-24 10:58:53 +00:00
|
|
|
|
|
|
|
def set_pair_dict_info(self, metadata: dict) -> None:
|
|
|
|
pair_in_dict = self.pair_dict.get(metadata['pair'])
|
|
|
|
if pair_in_dict:
|
|
|
|
return
|
|
|
|
else:
|
|
|
|
self.pair_dict[metadata['pair']] = {}
|
|
|
|
self.pair_dict[metadata['pair']]['model_filename'] = ''
|
|
|
|
self.pair_dict[metadata['pair']]['first'] = True
|
|
|
|
self.pair_dict[metadata['pair']]['trained_timestamp'] = 0
|
2022-05-28 16:26:19 +00:00
|
|
|
self.pair_dict[metadata['pair']]['priority'] = len(self.pair_dict)
|
2022-05-24 10:58:53 +00:00
|
|
|
return
|
2022-05-24 13:28:38 +00:00
|
|
|
|
2022-05-28 16:26:19 +00:00
|
|
|
# def create_training_queue(self, pairs: list) -> None:
|
|
|
|
# for i, pair in enumerate(pairs):
|
|
|
|
# self.training_queue[pair] = i + 1
|
2022-05-24 13:28:38 +00:00
|
|
|
|
|
|
|
def pair_to_end_of_training_queue(self, pair: str) -> None:
|
|
|
|
# march all pairs up in the queue
|
2022-05-28 16:26:19 +00:00
|
|
|
for p in self.pair_dict:
|
|
|
|
self.pair_dict[p]['priority'] -= 1
|
2022-05-24 13:28:38 +00:00
|
|
|
# send pair to end of queue
|
2022-05-28 16:26:19 +00:00
|
|
|
self.pair_dict[pair]['priority'] = len(self.pair_dict)
|
2022-05-30 09:37:05 +00:00
|
|
|
|
2022-05-30 10:48:22 +00:00
|
|
|
def set_initial_return_values(self, pair: str, dh):
|
|
|
|
|
2022-05-30 09:37:05 +00:00
|
|
|
self.model_return_values[pair] = {}
|
|
|
|
self.model_return_values[pair]['predictions'] = dh.full_predictions
|
|
|
|
self.model_return_values[pair]['do_preds'] = dh.full_do_predict
|
|
|
|
self.model_return_values[pair]['target_mean'] = dh.full_target_mean
|
|
|
|
self.model_return_values[pair]['target_std'] = dh.full_target_std
|
|
|
|
|
2022-05-30 10:48:22 +00:00
|
|
|
def append_model_predictions(self, pair: str, predictions, do_preds,
|
2022-05-30 09:37:05 +00:00
|
|
|
target_mean, target_std, dh) -> None:
|
|
|
|
|
|
|
|
pred_store = self.model_return_values[pair]['predictions']
|
|
|
|
do_pred_store = self.model_return_values[pair]['do_preds']
|
|
|
|
tm_store = self.model_return_values[pair]['target_mean']
|
|
|
|
ts_store = self.model_return_values[pair]['target_std']
|
|
|
|
pred_store = np.append(pred_store[1:], predictions[-1])
|
|
|
|
do_pred_store = np.append(do_pred_store[1:], do_preds[-1])
|
|
|
|
tm_store = np.append(tm_store[1:], target_mean)
|
|
|
|
ts_store = np.append(ts_store[1:], target_std)
|
|
|
|
|
|
|
|
dh.full_predictions = copy.deepcopy(pred_store)
|
|
|
|
dh.full_do_predict = copy.deepcopy(do_pred_store)
|
|
|
|
dh.full_target_mean = copy.deepcopy(tm_store)
|
|
|
|
dh.full_target_std = copy.deepcopy(ts_store)
|