Donnee.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. from Config.paths import SysExploite
  2. if SysExploite == "linux" :
  3. from Model.My_Redis import *
  4. from Model.Action import *
  5. from Config.DEBUG import *
  6. from Model.profil import profile
  7. import yfinance as yf
  8. import pandas as pd
  9. import numpy as np
  10. from svgelements import Close
  11. from ta import add_all_ta_features
  12. from datetime import datetime, timedelta, date
  13. import json
  14. from bisect import bisect_left
  15. import pickle
  16. def to_date(x):
  17. if isinstance(x, str):
  18. return datetime.strptime(x, "%Y-%m-%d").date()
  19. return x
  20. class CL_Donnee:
  21. def __init__(self, date_debut, nb_jours, Parametre):
  22. self.valeurCloture = {}
  23. self.listeDonne = {}
  24. self.listeAction = listeAction()
  25. if DEBUGpickle == 1 :
  26. UUID = Parametre.UUIDRAM(date_debut,nb_jours)
  27. pickle_path = f"RAM_cache_{UUID}.pkl"
  28. if not os.path.exists(pickle_path):
  29. with open(pickle_path, "wb") as f:
  30. self.RAMDonne(date_debut, nb_jours, Parametre)
  31. data = {"valeurCloture": self.valeurCloture,"listeDonne": self.listeDonne}
  32. pickle.dump(data, f)
  33. else :
  34. with open(pickle_path, "rb") as f:
  35. data = pickle.load(f)
  36. self.valeurCloture = data["valeurCloture"]
  37. self.listeDonne = data["listeDonne"]
  38. else:
  39. self.RAMDonne(date_debut, nb_jours, Parametre)
  40. self.Preprocess()
  41. @profile
  42. def RAMDonne(self, date_debut, nb_jours, Parametre):
  43. date_depart = datetime.strptime(date_debut, "%Y-%m-%d").date() - timedelta(days=Parametre.NbJourRecul * 2)
  44. for action in self.listeAction:
  45. self.listeDonne[action] = {}
  46. self.valeurCloture[action] = {}
  47. listejour = ListeJour(date_depart, nb_jours + Parametre.NbJourRecul * 2)
  48. for date in listejour:
  49. valeur = LireRedis(action, date)
  50. if valeur is not None:
  51. self.listeDonne[action][date] = json.loads(valeur)
  52. self.valeurCloture[action][date] = json.loads(valeur).get('Close')
  53. @profile
  54. def ValeurDate(self, Action, Date):
  55. return self.valeurCloture[Action][Date]
  56. @profile
  57. def ResultatGlobal(self, Date, nbJour):
  58. listeJour = ListeJour(Date, nbJour)
  59. Open = 0
  60. Close = 0
  61. for action in self.listeAction:
  62. Open += self.LireUneDonnee(action, listeJour[0]).get('Open')
  63. Close += self.LireUneDonnee(action, listeJour[-1]).get('Close')
  64. return (Close) / Open
  65. @profile
  66. def Preprocess(self):
  67. self.dataTriee = {}
  68. for action, data in self.listeDonne.items():
  69. jours = [to_date(d) for d in data.keys()]
  70. valeurs = list(data.values())
  71. tri = sorted(zip(jours, valeurs))
  72. self.dataTriee[action] = {
  73. "jours": [x[0] for x in tri],
  74. "valeurs": [x[1] for x in tri]
  75. }
  76. @profile
  77. def LireUneDonnee(self, Action, Date):
  78. cible = to_date(Date)
  79. data = self.dataTriee[Action]
  80. jours = data["jours"]
  81. valeurs = data["valeurs"]
  82. i = bisect_left(jours, cible)
  83. if i >= len(jours):
  84. return valeurs[-1]
  85. return valeurs[i]
  86. @profile
  87. def LireUneDonneeTry(self, Action, Date):
  88. try:
  89. return self.listeDonne[Action][Date]
  90. except (KeyError, IndexError, TypeError):
  91. return None
  92. @profile
  93. def DecalerJour(self, Date, Horizon):
  94. date_obj = datetime.strptime(Date, "%Y-%m-%d")
  95. nouvelle_date = date_obj + timedelta(days=Horizon)
  96. return nouvelle_date.strftime("%Y-%m-%d")
  97. @profile
  98. def PreparationDonnee(self, Date, nbJourRecule, Analysis, Horizon, ListeActions):
  99. listeJour = self.ListeJourInverse(Date, nbJourRecule)
  100. ListeReturn = []
  101. rendement_futur = []
  102. for action in ListeActions:
  103. # ===== HISTORIQUE (comme avant) =====
  104. for jour in listeJour:
  105. res = self.LireUneDonnee(action, jour)
  106. for param in Analysis:
  107. ListeReturn.append(res.get(param))
  108. # ===== TARGET (nouveau) =====
  109. prix_actuel = self.LireUneDonnee(action, Date).get("Close")
  110. prix_futur = self.LireUneDonnee(action, self.DecalerJour(Date, Horizon)).get("Close")
  111. rendement = (prix_futur - prix_actuel) / prix_actuel
  112. rendement_futur.append(rendement)
  113. # ===== reshape historique =====
  114. historique_indicateurs = np.array(ListeReturn).reshape(
  115. (1, len(ListeActions), nbJourRecule, len(Analysis))
  116. )
  117. # ===== normalisation =====
  118. mean = historique_indicateurs.mean(axis=(0, 2), keepdims=True)
  119. std = historique_indicateurs.std(axis=(0, 2), keepdims=True)
  120. historique_indicateurs = (historique_indicateurs - mean) / (std + 1e-8)
  121. # ===== reshape target =====
  122. rendement_futur = np.array(rendement_futur).reshape((1, len(ListeActions)))
  123. return historique_indicateurs, rendement_futur
  124. def PreparationJours(self, StartDay, NBJoursEntrainement, Parametre, Var_listeAction):
  125. liste_Entree = []
  126. liste_Target = []
  127. listeJours = ListeJour(StartDay, NBJoursEntrainement)
  128. for jour in listeJours:
  129. Entree, target = self.PreparationDonnee(jour, Parametre.NbJourRecul, Parametre.Analysis, Parametre.Horizon,
  130. Var_listeAction)
  131. Entree = np.asarray(Entree)
  132. target = np.asarray(target)
  133. if Entree.ndim == 4 and Entree.shape[0] == 1:
  134. Entree = Entree[0]
  135. liste_Entree.append(Entree)
  136. liste_Target.append(target)
  137. Entree = np.stack(liste_Entree, axis=0)
  138. target = np.stack(liste_Target, axis=0)
  139. target = target.reshape(target.shape[0], target.shape[2])
  140. resGlobal = self.ResultatGlobal(StartDay, NBJoursEntrainement)
  141. return Entree, target, resGlobal, listeJours
  142. @profile
  143. def ListeJourInverse(self, Date, NbJour):
  144. liste = []
  145. date_obj = datetime.strptime(Date, "%Y-%m-%d").date()
  146. i = 1
  147. while (i < NbJour + 1):
  148. date_obj = date_obj + timedelta(days=-1)
  149. valeur1 = self.LireUneDonneeTry("MT.AS", date_obj.strftime("%Y-%m-%d"))
  150. valeur2 = self.LireUneDonneeTry("AC.PA", date_obj.strftime("%Y-%m-%d"))
  151. if valeur1 is not None and valeur2 is not None:
  152. liste.insert(0, date_obj.strftime("%Y-%m-%d"))
  153. i = i + 1
  154. return liste
  155. def DataPickelData(self, StartDay, NBJoursEntrainement, Parametre, Var_listeAction):
  156. pickle_path = f"data_cache_{Parametre.UUIDData(StartDay, NBJoursEntrainement)}.pkl"
  157. if os.path.exists(pickle_path):
  158. with open(pickle_path, "rb") as f:
  159. Entree, Target, resGlobal, listeJours = pickle.load(f)
  160. else:
  161. Entree, Target, resGlobal, listeJours = self.PreparationJours(StartDay, NBJoursEntrainement, Parametre,
  162. Var_listeAction)
  163. with open(pickle_path, "wb") as f:
  164. pickle.dump((Entree, Target, resGlobal, listeJours), f)
  165. return Entree, Target, resGlobal, listeJours