dquant 1.2.2__tar.gz → 1.2.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dquant
3
- Version: 1.2.2
3
+ Version: 1.2.4
4
4
  Summary: DQuant is an open-source Python library for automated volatility forecasting of financial time series. It handles all stages of model construction, from raw prices to the final forecast.
5
5
  Author: Denis Makarov
6
6
  Project-URL: Homepage, https://dquant.space
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dquant"
7
- version = "1.2.2"
7
+ version = "1.2.4"
8
8
  authors = [
9
9
  { name="Denis Makarov" },
10
10
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dquant
3
- Version: 1.2.2
3
+ Version: 1.2.4
4
4
  Summary: DQuant is an open-source Python library for automated volatility forecasting of financial time series. It handles all stages of model construction, from raw prices to the final forecast.
5
5
  Author: Denis Makarov
6
6
  Project-URL: Homepage, https://dquant.space
@@ -2,7 +2,7 @@ import numpy as np
2
2
 
3
3
 
4
4
  def qlike_score(y_true, y_pred):
5
- sigma2_true = y_true ** 2
5
+ sigma2_true = y_true
6
6
  sigma2_pred = np.maximum(y_pred, 1e-10)
7
7
  return np.mean(np.log(sigma2_pred) + sigma2_true / sigma2_pred)
8
8
 
@@ -557,8 +557,14 @@ class FichEn:
557
557
  X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, shuffle=False, random_state=42)
558
558
  X_scaled = self.scaler.fit_transform(X_train)
559
559
  X_test_scaled = self.scaler.transform(X_test)
560
- Y_scaled = self.scaler_y.fit_transform(y_train)
561
- Y_test_scaled = self.scaler_y.transform(y_test)
560
+ #Y_scaled = self.scaler_y.fit_transform(y_train)
561
+ #Y_test_scaled = self.scaler_y.transform(y_test)
562
+ """if hasattr(y, 'ndim') and y.ndim == 1:
563
+ self.X_shape = 1
564
+ #y_2d = y.values.reshape(-1, 1) if hasattr(y, 'values') else y.reshape(-1, 1)
565
+ else:
566
+ self.X_shape = y.shape[1]"""
567
+
562
568
  self.X_shape = x.shape[1]
563
569
 
564
570
  self.train_errors = []
@@ -594,17 +600,18 @@ class FichEn:
594
600
  horizon_list = list(range(horizon))
595
601
  else:
596
602
  horizon_list = horizon
597
- if len(Y_scaled.shape) == 2 and Y_scaled.shape[1] > 0:
603
+ if len(y_train.shape) == 2 and y_train.shape[1] > 0:
598
604
  for h_idx, h in enumerate(horizon_list):
599
- if h_idx >= Y_scaled.shape[1]:
605
+ if h_idx >= y_train.shape[1]:
600
606
  self.dquantprint(f"Warning: horizon {h} extends beyond y, skipping")
601
607
  continue
602
608
 
603
- y_h = Y_scaled.iloc[:, h_idx] if hasattr(Y_scaled, 'iloc') else Y_scaled[:, h_idx]
609
+ y_h = y_train.iloc[:, h_idx] if hasattr(y_train, 'iloc') else y_train[:, h_idx]
604
610
 
605
611
  valid_mask = ~pd.isna(y_h) if hasattr(y_h, 'isna') else ~np.isnan(y_h)
606
612
  X_h = X_scaled[valid_mask]
607
613
  y_h_clean = y_h[valid_mask]
614
+ #y_h_clean_orig = self.scaler_y.inverse_transform(y_h_clean.reshape(-1, 1)).ravel()
608
615
 
609
616
  if i != 1:
610
617
  self.models[h_idx].set_params(n_estimators=i)
@@ -615,29 +622,38 @@ class FichEn:
615
622
  model.fit(X_h, y_h_clean)
616
623
  self.models.append(model)
617
624
 
618
- y_h_v = Y_test_scaled.iloc[:, h_idx] if hasattr(Y_test_scaled, 'iloc') else Y_test_scaled[:, h_idx]
625
+ y_h_v = y_test.iloc[:, h_idx] if hasattr(y_test, 'iloc') else y_test[:, h_idx]
619
626
 
620
627
  valid_mask = ~pd.isna(y_h_v) if hasattr(y_h_v, 'isna') else ~np.isnan(y_h_v)
621
628
  X_h_v = X_test_scaled[valid_mask]
622
629
  y_h_v_clean = y_h_v[valid_mask]
630
+ #y_h_v_clean_orig = self.scaler_y.inverse_transform(y_h_v_clean.reshape(-1, 1)).ravel()
623
631
  if i != 1:
624
- t_error += mean_squared_error(y_h_clean, self.models[h_idx].predict(X_h))
625
- v_error += mean_squared_error(y_h_v_clean, self.models[h_idx].predict(X_h_v))
626
- t_mae += mean_absolute_error(y_h_clean, self.models[h_idx].predict(X_h))
627
- v_mae += mean_absolute_error(y_h_v_clean, self.models[h_idx].predict(X_h_v))
628
- t_qlike += qlike_score(y_h_clean, self.models[h_idx].predict(X_h))
629
- v_qlike += qlike_score(y_h_v_clean, self.models[h_idx].predict(X_h_v))
630
- t_r2 += r2_score(y_h_clean, self.models[h_idx].predict(X_h))
631
- v_r2 += r2_score(y_h_v_clean, self.models[h_idx].predict(X_h_v))
632
+ pred_train = self.models[h_idx].predict(X_h)
633
+ pred_val = self.models[h_idx].predict(X_h_v)
634
+ #pred_train_orig = self.scaler_y.inverse_transform(pred_train.reshape(-1, 1)).ravel()
635
+ #pred_val_orig = self.scaler_y.inverse_transform(pred_val.reshape(-1, 1)).ravel()
636
+ t_error += mean_squared_error(y_h_clean, pred_train)
637
+ v_error += mean_squared_error(y_h_v_clean, pred_val)
638
+ t_mae += mean_absolute_error(y_h_clean, pred_train)
639
+ v_mae += mean_absolute_error(y_h_v_clean, pred_val)
640
+ t_qlike += qlike_score(y_h_clean, pred_train)
641
+ v_qlike += qlike_score(y_h_v_clean, pred_val)
642
+ t_r2 += r2_score(y_h_clean, pred_train)
643
+ v_r2 += r2_score(y_h_v_clean, pred_val)
632
644
  else:
633
- t_error += mean_squared_error(y_h_clean, model.predict(X_h))
634
- v_error += mean_squared_error(y_h_v_clean, model.predict(X_h_v))
635
- t_mae += mean_absolute_error(y_h_clean, model.predict(X_h))
636
- v_mae += mean_absolute_error(y_h_v_clean, model.predict(X_h_v))
637
- t_qlike += qlike_score(y_h_clean, model.predict(X_h))
638
- v_qlike += qlike_score(y_h_v_clean, model.predict(X_h_v))
639
- t_r2 += r2_score(y_h_clean, model.predict(X_h))
640
- v_r2 += r2_score(y_h_v_clean, model.predict(X_h_v))
645
+ pred_train = model.predict(X_h)
646
+ pred_val = model.predict(X_h_v)
647
+ #pred_train_orig = self.scaler_y.inverse_transform(pred_train.reshape(-1, 1)).ravel()
648
+ #pred_val_orig = self.scaler_y.inverse_transform(pred_val.reshape(-1, 1)).ravel()
649
+ t_error += mean_squared_error(y_h_clean, pred_train)
650
+ v_error += mean_squared_error(y_h_v_clean, pred_val)
651
+ t_mae += mean_absolute_error(y_h_clean, pred_train)
652
+ v_mae += mean_absolute_error(y_h_v_clean, pred_val)
653
+ t_qlike += qlike_score(y_h_clean, pred_train)
654
+ v_qlike += qlike_score(y_h_v_clean, pred_val)
655
+ t_r2 += r2_score(y_h_clean, pred_train)
656
+ v_r2 += r2_score(y_h_v_clean, pred_val)
641
657
 
642
658
 
643
659
  var_test_error = float(t_error)/horizon
@@ -738,7 +754,7 @@ class FichEn:
738
754
  pred_array = pred_array.T
739
755
  elif pred_array.shape[0] > 1 and pred_array.shape[1] == 30:
740
756
  pred_array = pred_array[0:1, :]
741
- predictions = self.scaler_y.inverse_transform(pred_array).flatten()
757
+ predictions = pred_array.flatten()
742
758
 
743
759
  if show:
744
760
  epsilon = 1e-10
@@ -782,7 +798,7 @@ class FichEn:
782
798
  pred_array = pred_array.T
783
799
  elif pred_array.shape[0] > 1 and pred_array.shape[1] == 30:
784
800
  pred_array = pred_array[0:1, :]
785
- predictions = self.scaler_y.inverse_transform(pred_array).flatten()
801
+ predictions = pred_array.flatten()
786
802
 
787
803
  if show:
788
804
  epsilon = 1e-10
@@ -816,13 +832,13 @@ class FichEn:
816
832
  mean_str = ','.join(str(x) for x in scaler_data['mean'])
817
833
  std_str = ','.join(str(x) for x in scaler_data['std'])
818
834
 
819
- scaler_data_y = {
835
+ """scaler_data_y = {
820
836
  "mean": self.scaler_y.mean_.tolist() if self.scaler_y.mean_ is not None else [],
821
837
  "std": self.scaler_y.scale_.tolist() if self.scaler_y.scale_ is not None else [],
822
838
  "var": self.scaler_y.var_.tolist() if self.scaler_y.var_ is not None else []
823
839
  }
824
840
  mean_str_y = ','.join(str(x) for x in scaler_data_y['mean'])
825
- std_str_y = ','.join(str(x) for x in scaler_data_y['std'])
841
+ std_str_y = ','.join(str(x) for x in scaler_data_y['std'])"""
826
842
 
827
843
 
828
844
  os.makedirs(name, exist_ok=True)
@@ -854,8 +870,8 @@ class FichEn:
854
870
  f.write(f"double mean_[] = {{{mean_str}}};\n\n")
855
871
  f.write(f"double std_[] = {{{std_str}}};\n\n")
856
872
 
857
- f.write(f"double mean_y[] = {{{mean_str_y}}};\n\n")
858
- f.write(f"double std_y[] = {{{std_str_y}}};\n\n")
873
+ #f.write(f"double mean_y[] = {{{mean_str_y}}};\n\n")
874
+ #f.write(f"double std_y[] = {{{std_str_y}}};\n\n")
859
875
 
860
876
  f.write("//--- indicator buffers\n")
861
877
  f.write("double past_vol[];\n")
@@ -1469,7 +1485,7 @@ class VolClustGB(FichEn):
1469
1485
  self.output = output
1470
1486
  self.models = []
1471
1487
  self.scaler = StandardScaler()
1472
- self.scaler_y = StandardScaler()
1488
+ #self.scaler_y = StandardScaler()
1473
1489
  self.X_shape = 0
1474
1490
  self.is_fitted = False
1475
1491
  self.onnx_load = False
@@ -1520,9 +1536,9 @@ class VolClustGB(FichEn):
1520
1536
  scaler_path = os.path.join(name, f"{name}_scaler.pkl")
1521
1537
  joblib.dump(self.scaler, scaler_path)
1522
1538
 
1523
- if hasattr(self, 'scaler_y'):
1539
+ """if hasattr(self, 'scaler_y'):
1524
1540
  scaler_path = os.path.join(name, f"{name}_scaler_y.pkl")
1525
- joblib.dump(self.scaler_y, scaler_path)
1541
+ joblib.dump(self.scaler_y, scaler_path)"""
1526
1542
 
1527
1543
  for i in range(len(self.models)):
1528
1544
  onx = convert_sklearn(self.models[i], initial_types=initial_type, target_opset=12)
@@ -1544,10 +1560,10 @@ class VolClustGB(FichEn):
1544
1560
  joblib.dump(self.scaler, scaler_path)
1545
1561
  self.dquantprint(f"Scaler is saved in {scaler_path}")
1546
1562
 
1547
- if hasattr(self, 'scaler_y') and self.scaler_y is not None:
1563
+ """if hasattr(self, 'scaler_y') and self.scaler_y is not None:
1548
1564
  scaler_path = os.path.join(onnx_dir, f"{name}_scaler_y.pkl")
1549
1565
  joblib.dump(self.scaler_y, scaler_path)
1550
- self.dquantprint(f"Scalery is saved in {scaler_path}")
1566
+ self.dquantprint(f"Scalery is saved in {scaler_path}")"""
1551
1567
 
1552
1568
  for i in range(len(self.models)):
1553
1569
  onx = convert_sklearn(self.models[i], initial_types=initial_type, target_opset=12)
@@ -1589,10 +1605,10 @@ class VolClustGB(FichEn):
1589
1605
  scaler_path = os.path.join(name, scaler_files[0])
1590
1606
  self.scaler = joblib.load(scaler_path)
1591
1607
 
1592
- scaler_files = [f for f in os.listdir(name) if f.endswith('_scaler_y.pkl')]
1608
+ """scaler_files = [f for f in os.listdir(name) if f.endswith('_scaler_y.pkl')]
1593
1609
  if scaler_files:
1594
- scaler_path = os.path.join(name, scaler_files[0])
1595
- self.scaler_y = joblib.load(scaler_path)
1610
+ scaler_path = os.path.join(name, scaler_files[0])"""
1611
+ #self.scaler_y = joblib.load(scaler_path)
1596
1612
 
1597
1613
  model_files = [f for f in os.listdir(name) if f.endswith('.onnx')]
1598
1614
 
@@ -1631,7 +1647,7 @@ class VolClustXGB(FichEn):
1631
1647
  self.output = output
1632
1648
  self.models = []
1633
1649
  self.scaler = StandardScaler()
1634
- self.scaler_y = StandardScaler()
1650
+ #self.scaler_y = StandardScaler()
1635
1651
  self.X_shape = 0
1636
1652
  self.is_fitted = False
1637
1653
  self.onnx_load = False
@@ -1701,9 +1717,9 @@ class VolClustXGB(FichEn):
1701
1717
  scaler_path = os.path.join(name, f"{name}_scaler.pkl")
1702
1718
  joblib.dump(self.scaler, scaler_path)
1703
1719
 
1704
- if hasattr(self, 'scaler_y'):
1720
+ """if hasattr(self, 'scaler_y'):
1705
1721
  scaler_path = os.path.join(name, f"{name}_scaler_y.pkl")
1706
- joblib.dump(self.scaler_y, scaler_path)
1722
+ joblib.dump(self.scaler_y, scaler_path)"""
1707
1723
 
1708
1724
  for i in range(len(self.models)):
1709
1725
  onx = onnxmltools.convert_xgboost(self.models[i], initial_types=initial_type, target_opset=12)
@@ -1723,10 +1739,10 @@ class VolClustXGB(FichEn):
1723
1739
  joblib.dump(self.scaler, scaler_path)
1724
1740
  self.dquantprint(f"Scaler is saved in {scaler_path}")
1725
1741
 
1726
- if hasattr(self, 'scaler_y') and self.scaler_y is not None:
1742
+ """if hasattr(self, 'scaler_y') and self.scaler_y is not None:
1727
1743
  scaler_path = os.path.join(onnx_dir, f"{name}_scaler_y.pkl")
1728
1744
  joblib.dump(self.scaler_y, scaler_path)
1729
- self.dquantprint(f"Scalery is saved in {scaler_path}")
1745
+ self.dquantprint(f"Scalery is saved in {scaler_path}")"""
1730
1746
 
1731
1747
  for i in range(len(self.models)):
1732
1748
  onx = onnxmltools.convert_xgboost(self.models[i], initial_types=initial_type, target_opset=9)
@@ -1768,10 +1784,10 @@ class VolClustXGB(FichEn):
1768
1784
  scaler_path = os.path.join(name, scaler_files[0])
1769
1785
  self.scaler = joblib.load(scaler_path)
1770
1786
 
1771
- scaler_files = [f for f in os.listdir(name) if f.endswith('_scaler_y.pkl')]
1787
+ """scaler_files = [f for f in os.listdir(name) if f.endswith('_scaler_y.pkl')]
1772
1788
  if scaler_files:
1773
1789
  scaler_path = os.path.join(name, scaler_files[0])
1774
- self.scaler_y = joblib.load(scaler_path)
1790
+ #self.scaler_y = joblib.load(scaler_path)"""
1775
1791
 
1776
1792
  model_files = [f for f in os.listdir(name) if f.endswith('.onnx')]
1777
1793
 
@@ -1808,7 +1824,7 @@ class VolClustLightGBM(FichEn):
1808
1824
  self.output = output
1809
1825
  self.models = []
1810
1826
  self.scaler = StandardScaler()
1811
- self.scaler_y = StandardScaler()
1827
+ #self.scaler_y = StandardScaler()
1812
1828
  self.X_shape = 0
1813
1829
  self.is_fitted = False
1814
1830
  self.onnx_load = False
@@ -1880,9 +1896,9 @@ class VolClustLightGBM(FichEn):
1880
1896
  scaler_path = os.path.join(name, f"{name}_scaler.pkl")
1881
1897
  joblib.dump(self.scaler, scaler_path)
1882
1898
 
1883
- if hasattr(self, 'scaler_y'):
1899
+ """if hasattr(self, 'scaler_y'):
1884
1900
  scaler_path = os.path.join(name, f"{name}_scaler_y.pkl")
1885
- joblib.dump(self.scaler_y, scaler_path)
1901
+ joblib.dump(self.scaler_y, scaler_path)"""
1886
1902
 
1887
1903
  for i in range(len(self.models)):
1888
1904
  onx = onnxmltools.convert_lightgbm(self.models[i], initial_types=initial_type, zipmap=False,
@@ -1902,10 +1918,10 @@ class VolClustLightGBM(FichEn):
1902
1918
  joblib.dump(self.scaler, scaler_path)
1903
1919
  self.dquantprint(f"Scaler is saved in {scaler_path}")
1904
1920
 
1905
- if hasattr(self, 'scaler_y') and self.scaler_y is not None:
1921
+ """if hasattr(self, 'scaler_y') and self.scaler_y is not None:
1906
1922
  scaler_path = os.path.join(onnx_dir, f"{name}_scaler_y.pkl")
1907
1923
  joblib.dump(self.scaler_y, scaler_path)
1908
- self.dquantprint(f"Scalery is saved in {scaler_path}")
1924
+ self.dquantprint(f"Scalery is saved in {scaler_path}")"""
1909
1925
 
1910
1926
  for i in range(len(self.models)):
1911
1927
  onx = onnxmltools.convert_lightgbm(self.models[i], initial_types=initial_type, zipmap=False,
@@ -1947,10 +1963,10 @@ class VolClustLightGBM(FichEn):
1947
1963
  scaler_path = os.path.join(name, scaler_files[0])
1948
1964
  self.scaler = joblib.load(scaler_path)
1949
1965
 
1950
- scaler_files = [f for f in os.listdir(name) if f.endswith('_scaler_y.pkl')]
1966
+ """scaler_files = [f for f in os.listdir(name) if f.endswith('_scaler_y.pkl')]
1951
1967
  if scaler_files:
1952
1968
  scaler_path = os.path.join(name, scaler_files[0])
1953
- self.scaler_y = joblib.load(scaler_path)
1969
+ #self.scaler_y = joblib.load(scaler_path)"""
1954
1970
 
1955
1971
  model_files = [f for f in os.listdir(name) if f.endswith('.onnx')]
1956
1972
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes