RiskLabAI 0.0.74__tar.gz → 0.0.78__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.
Files changed (110) hide show
  1. {RiskLabAI-0.0.74 → risklabai-0.0.78}/PKG-INFO +4 -1
  2. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/validation/purged_kfold.py +28 -21
  3. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/pde/equation.py +104 -10
  4. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/pde/model.py +157 -35
  5. risklabai-0.0.78/RiskLabAI/pde/solver.py +401 -0
  6. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI.egg-info/PKG-INFO +4 -1
  7. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI.egg-info/SOURCES.txt +1 -0
  8. risklabai-0.0.78/RiskLabAI.egg-info/requires.txt +3 -0
  9. {RiskLabAI-0.0.74 → risklabai-0.0.78}/setup.cfg +5 -1
  10. RiskLabAI-0.0.74/RiskLabAI/pde/solver.py +0 -173
  11. {RiskLabAI-0.0.74 → risklabai-0.0.78}/LICENSE +0 -0
  12. {RiskLabAI-0.0.74 → risklabai-0.0.78}/README.md +0 -0
  13. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/__init__.py +0 -0
  14. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/__init__.py +0 -0
  15. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/backtest_statistics.py +0 -0
  16. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/backtest_synthetic_data.py +0 -0
  17. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/backtset_overfitting_in_the_machine_learning_era_simulation.py +0 -0
  18. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/bet_sizing.py +0 -0
  19. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/probabilistic_sharpe_ratio.py +0 -0
  20. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/probability_of_backtest_overfitting.py +0 -0
  21. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/strategy_risk.py +0 -0
  22. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/test_set_overfitting.py +0 -0
  23. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/validation/__init__.py +0 -0
  24. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/validation/combinatorial_purged.py +0 -0
  25. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/validation/cross_validator_controller.py +0 -0
  26. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/validation/cross_validator_factory.py +0 -0
  27. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/validation/cross_validator_interface.py +0 -0
  28. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/validation/kfold.py +0 -0
  29. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/backtest/validation/walk_forward.py +0 -0
  30. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/cluster/__init__.py +0 -0
  31. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/cluster/clustering.py +0 -0
  32. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/controller/__init__.py +0 -0
  33. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/controller/bars_initializer.py +0 -0
  34. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/controller/data_structure_controller.py +0 -0
  35. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/__init__.py +0 -0
  36. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/denoise/__init__.py +0 -0
  37. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/denoise/denoising.py +0 -0
  38. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/differentiation/__init__.py +0 -0
  39. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/differentiation/differentiation.py +0 -0
  40. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/distance/__init__.py +0 -0
  41. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/distance/distance_metric.py +0 -0
  42. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/labeling/__init__.py +0 -0
  43. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/labeling/financial_labels.py +0 -0
  44. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/labeling/labeling.py +0 -0
  45. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/__init__.py +0 -0
  46. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/abstract_bars.py +0 -0
  47. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/abstract_imbalance_bars.py +0 -0
  48. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/abstract_information_driven_bars.py +0 -0
  49. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/abstract_run_bars.py +0 -0
  50. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/data_structures_lopez.py +0 -0
  51. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/filtering_lopez.py +0 -0
  52. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/hedging.py +0 -0
  53. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/imbalance_bars.py +0 -0
  54. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/infomation_driven_bars.py +0 -0
  55. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/run_bars.py +0 -0
  56. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/standard_bars.py +0 -0
  57. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/standard_bars_lopez.py +0 -0
  58. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/time_bars.py +0 -0
  59. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/structures/utilities_lopez.py +0 -0
  60. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/synthetic_data/__init__.py +0 -0
  61. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/synthetic_data/drift_burst_hypothesis.py +0 -0
  62. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/synthetic_data/synthetic_controlled_environment.py +0 -0
  63. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/weights/__init__.py +0 -0
  64. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/data/weights/sample_weights.py +0 -0
  65. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/ensemble/__init__.py +0 -0
  66. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/ensemble/bagging_classifier_accuracy.py +0 -0
  67. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/__init__.py +0 -0
  68. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/entropy_features/__init__.py +0 -0
  69. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/entropy_features/entropy.py +0 -0
  70. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/entropy_features/kontoyiannis.py +0 -0
  71. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/entropy_features/lempel_ziv.py +0 -0
  72. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/entropy_features/plug_in.py +0 -0
  73. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/entropy_features/pmf.py +0 -0
  74. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/entropy_features/shannon.py +0 -0
  75. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/feature_importance/__init__.py +0 -0
  76. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/feature_importance/clustered_feature_importance_mda.py +0 -0
  77. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/feature_importance/clustered_feature_importance_mdi.py +0 -0
  78. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/feature_importance/clustering.py +0 -0
  79. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/feature_importance/feature_importance_controller.py +0 -0
  80. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/feature_importance/feature_importance_factory.py +0 -0
  81. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/feature_importance/feature_importance_mda.py +0 -0
  82. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/feature_importance/feature_importance_mdi.py +0 -0
  83. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/feature_importance/feature_importance_sfi.py +0 -0
  84. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/feature_importance/feature_importance_strategy.py +0 -0
  85. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/feature_importance/generate_synthetic_data.py +0 -0
  86. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/feature_importance/orthogonal_features.py +0 -0
  87. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/feature_importance/weighted_tau.py +0 -0
  88. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/microstructural_features/__init__.py +0 -0
  89. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/microstructural_features/bekker_parkinson_volatility_estimator.py +0 -0
  90. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/microstructural_features/corwin_schultz.py +0 -0
  91. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/structural_breaks/__init__.py +0 -0
  92. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/features/structural_breaks/structural_breaks.py +0 -0
  93. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/hpc/__init__.py +0 -0
  94. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/hpc/hpc.py +0 -0
  95. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/modeling/__init__.py +0 -0
  96. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/modeling/optimization/__init__.py +0 -0
  97. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/modeling/optimization/hrp.py +0 -0
  98. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/modeling/optimization/hyper_parameter_tuning.py +0 -0
  99. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/modeling/optimization/nco.py +0 -0
  100. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/pde/__init__.py +0 -0
  101. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/utils/__init__.py +0 -0
  102. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/utils/constants.py +0 -0
  103. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/utils/ewma.py +0 -0
  104. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/utils/momentum_mean_reverting_strategy_sides.py +0 -0
  105. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/utils/progress.py +0 -0
  106. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI/utils/smoothing_average.py +0 -0
  107. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI.egg-info/dependency_links.txt +0 -0
  108. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI.egg-info/entry_points.txt +0 -0
  109. {RiskLabAI-0.0.74 → risklabai-0.0.78}/RiskLabAI.egg-info/top_level.txt +0 -0
  110. {RiskLabAI-0.0.74 → risklabai-0.0.78}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: RiskLabAI
3
- Version: 0.0.74
3
+ Version: 0.0.78
4
4
  Summary: Financial AI using Python.
5
5
  Home-page: https://github.com/RiskLabAI/RiskLabAI.py
6
6
  Author: RiskLab
@@ -12,3 +12,6 @@ Classifier: License :: OSI Approved :: BSD License
12
12
  Classifier: Intended Audience :: Developers
13
13
  Description-Content-Type: text/markdown
14
14
  License-File: LICENSE
15
+ Requires-Dist: scipy
16
+ Requires-Dist: ta
17
+ Requires-Dist: quantecon
@@ -45,36 +45,43 @@ class PurgedKFold(CrossValidator):
45
45
 
46
46
  indices_to_drop: Set[int] = set()
47
47
  embargo_length = int(len(data_info_range) * embargo_fraction)
48
+ sorted_test_time_range = test_time_range.sort_index().copy()
48
49
 
49
- effective_test_time_range = test_time_range if not continous_test_times else pd.Series(test_time_range.iloc[-1], index=[test_time_range.index[0]])
50
+ if not continous_test_times:
51
+ sorted_test_time_range = pd.DataFrame({
52
+ 'start' : sorted_test_time_range.index,
53
+ 'end' : sorted_test_time_range.values
54
+ })
55
+ # Identify where the new range starts immediately after or before the previous range ends
56
+ gaps = sorted_test_time_range['start'] > sorted_test_time_range['end'].shift(1)
57
+ # Cumulative sum to identify contiguous blocks
58
+ blocks = gaps.cumsum()
59
+ # Aggregate to find the min start and max end for each block
60
+ effective_test_time_range = sorted_test_time_range.groupby(blocks).agg({'start': 'min', 'end': 'max'})
61
+ effective_test_time_range = pd.Series(effective_test_time_range['end'].values, index=effective_test_time_range['start'])
62
+
63
+ else:
64
+ effective_test_time_range = pd.Series(sorted_test_time_range.iloc[-1], index=[sorted_test_time_range.index[0]])
50
65
 
51
66
  if embargo_length == 0:
52
- embargoed_data_info_range = pd.Series(test_time_range.values, index=test_time_range.values)
67
+ embargoed_data_info_range = pd.Series(effective_test_time_range.values, index=effective_test_time_range.values)
53
68
 
54
69
  else:
55
- effective_sample = data_info_range.loc[test_time_range.index.min():].copy().drop_duplicates()
70
+ effective_sample = data_info_range.loc[effective_test_time_range.index.min():].copy().drop_duplicates()
56
71
  embargoed_data_info_range = pd.Series(effective_sample.values, index=effective_sample.values)
57
- embargoed_data_info_range = embargoed_data_info_range.shift(-embargo_length).fillna(embargoed_data_info_range.values[-1])
58
-
59
- for start_ix, end_ix in effective_test_time_range.items():
60
- # Adding the embargo period
61
- end_ix_embargoed = embargoed_data_info_range.loc[end_ix]
62
-
63
- overlapping_start = data_info_range[
64
- (start_ix <= data_info_range.index) & (data_info_range.index <= end_ix_embargoed)
65
- ].index
72
+ embargoed_data_info_range = embargoed_data_info_range.shift(-embargo_length).fillna(embargoed_data_info_range.values[-1])
66
73
 
67
- overlapping_end = data_info_range[
68
- (start_ix <= data_info_range) & (data_info_range <= end_ix_embargoed)
69
- ].index
74
+ effective_ranges = pd.Series(embargoed_data_info_range.loc[effective_test_time_range].values, index=effective_test_time_range.index)
70
75
 
71
- enveloping = data_info_range[
72
- (data_info_range.index <= start_ix) & (end_ix_embargoed <= data_info_range)
73
- ].index
76
+ for start_ix, end_ix_embargoed in effective_ranges.items():
74
77
 
75
- indices_to_drop.update(overlapping_start)
76
- indices_to_drop.update(overlapping_end)
77
- indices_to_drop.update(enveloping)
78
+ indices_to_drop.update(
79
+ data_info_range[
80
+ ((start_ix <= data_info_range.index) & (data_info_range.index <= end_ix_embargoed)) |
81
+ ((start_ix <= data_info_range) & (data_info_range <= end_ix_embargoed)) |
82
+ ((data_info_range.index <= start_ix) & (end_ix_embargoed <= data_info_range))
83
+ ].index
84
+ )
78
85
 
79
86
  return data_info_range.drop(indices_to_drop)
80
87
 
@@ -89,8 +89,8 @@ class Equation:
89
89
  Tensor: tensor of size [batch_size, 1] containing terminal values
90
90
  """
91
91
  raise NotImplementedError
92
-
93
-
92
+
93
+
94
94
  class PricingDefaultRisk(Equation):
95
95
  """
96
96
  Args:
@@ -127,7 +127,7 @@ class PricingDefaultRisk(Equation):
127
127
  x_sample[:, :, 0] = np.ones([num_sample, self.dim]) * self.x_init
128
128
  for i in range(self.num_time_interval):
129
129
  x_sample[:, :, i + 1] = (1 + self.mu_bar * self.delta_t) * x_sample[:, :, i] + (
130
- self.sigma * x_sample[:, :, i] * dw_sample[:, :, i])
130
+ self.sigma_matrix(x_sample[:, :, i]) * dw_sample[:, :, i])
131
131
  return dw_sample, x_sample
132
132
 
133
133
  def r_u(self, t, x, y, z)-> torch.Tensor:
@@ -161,7 +161,10 @@ class PricingDefaultRisk(Equation):
161
161
  torch.Tensor: tensor of size [batch_size, 1] containing H(z)
162
162
  """
163
163
  return torch.zeros((x.size()[0],1))
164
-
164
+
165
+ def sigma_matrix(self,x):
166
+ return self.sigma * x
167
+
165
168
 
166
169
  def terminal(self, t, x)-> torch.Tensor:
167
170
  """
@@ -187,7 +190,95 @@ class PricingDefaultRisk(Equation):
187
190
  """
188
191
  return nn.ReLU()(torch.min(x, 2 , keepdim= True)[0])
189
192
 
190
-
193
+
194
+ class HJBLQ(Equation):
195
+ """
196
+
197
+ Args:
198
+ eqn_config (dict): dictionary containing PDE configuration parameters
199
+ """
200
+
201
+ def __init__(self, eqn_config: dict):
202
+ super().__init__(eqn_config)
203
+
204
+ self.x_init = np.zeros(self.dim)
205
+ self.sigma = np.sqrt(2.0)
206
+ self.lambd = 1.0
207
+
208
+ def sample(self, num_sample: int) -> tuple:
209
+ """
210
+ Sample forward SDE.
211
+
212
+ Args:
213
+ num_sample (int): number of samples to generate
214
+
215
+ Returns:
216
+ tuple: tuple of two tensors: dw_sample of size [num_sample, dim, num_time_interval] and
217
+ x_sample of size [num_sample, dim, num_time_interval+1]
218
+ """
219
+ dw_sample = np.random.normal(size=[num_sample, self.dim, self.num_time_interval]) * self.sqrt_delta_t
220
+ x_sample = np.zeros([num_sample, self.dim, self.num_time_interval + 1])
221
+ x_sample[:, :, 0] = np.ones([num_sample, self.dim]) * self.x_init
222
+ for i in range(self.num_time_interval):
223
+ x_sample[:, :, i + 1] = x_sample[:, :, i] + self.sigma * dw_sample[:, :, i]
224
+ return dw_sample, x_sample
225
+
226
+ def r_u(self, t: float, x: torch.Tensor, y: torch.Tensor, z: torch.Tensor) -> torch.Tensor:
227
+ """
228
+ Interest rate in the PDE.
229
+
230
+ Args:
231
+ t (float): current time
232
+ x (torch.Tensor): tensor of size [batch_size, dim] containing space coordinates
233
+ y (torch.Tensor): tensor of size [batch_size, 1] containing function values
234
+ z (torch.Tensor): tensor of size [batch_size, dim] containing gradients
235
+
236
+ Returns:
237
+ torch.Tensor: tensor of size [batch_size, 1] containing generator values
238
+ """
239
+ return torch.ones((x.size()[0],)) * 0
240
+
241
+ def h_z(self, t: float, x: torch.Tensor,y: torch.Tensor, z: torch.Tensor) -> torch.Tensor:
242
+ """
243
+ Function to compute <h,z> in the PDE.
244
+
245
+ Args:
246
+ t (float): current time
247
+ x (torch.Tensor): tensor of size [batch_size, dim] containing space coordinates
248
+ y (torch.Tensor): tensor of size [batch_size, 1] containing function value
249
+ z (torch.Tensor): tensor of size [batch_size, dim] containing gradients
250
+
251
+ Returns:
252
+ torch.Tensor: tensor of size [batch_size, 1] containing H(z)
253
+ """
254
+ return torch.sum(torch.square(z), dim=1)/ (self.sigma**2)
255
+
256
+ def terminal(self, t: float, x: torch.Tensor) -> torch.Tensor:
257
+ """
258
+ Terminal condition of the PDE.
259
+
260
+ Args:
261
+ t (float): current time
262
+ x (torch.Tensor): tensor of size [batch_size, dim] containing space coordinates
263
+
264
+ Returns:
265
+ torch.Tensor: tensor of size [batch_size, 1] containing terminal values
266
+ """
267
+ return torch.log(0.5 * (1 + torch.norm(x, dim=1)**2))
268
+ def sigma_matrix(self,x):
269
+ return self.sigma
270
+ def terminal_for_sample(self, x)-> torch.Tensor:
271
+ """
272
+ Terminal condition of the PDE.
273
+
274
+ Args:
275
+ x (torch.Tensor): tensor of size [num_sample,batch_size, dim] containing space coordinates
276
+
277
+ Returns:
278
+ torch.Tensor: tensor of size [num_sample ,batch_size, 1] containing terminal values
279
+ """
280
+ return torch.sum(x ** 2, dim=2 ,keepdim=True )
281
+
191
282
  class BlackScholesBarenblatt(Equation):
192
283
  """
193
284
 
@@ -218,7 +309,7 @@ class BlackScholesBarenblatt(Equation):
218
309
  x_sample[:, :, 0] = np.ones((num_sample, self.dim)) * self.x_init
219
310
  for i in range(self.num_time_interval):
220
311
  x_sample[:, :, i + 1] = (1 + self.mu_bar * self.delta_t) * x_sample[:, :, i] + (
221
- self.sigma * x_sample[:, :, i] * dw_sample[:, :, i])
312
+ self.sigma_matrix(x_sample[:, :, i]) * dw_sample[:, :, i])
222
313
  return dw_sample, x_sample
223
314
 
224
315
  def r_u(self, t: float, x: torch.Tensor, y: torch.Tensor, z: torch.Tensor) -> torch.Tensor:
@@ -263,7 +354,9 @@ class BlackScholesBarenblatt(Equation):
263
354
  torch.Tensor: tensor of size [batch_size, 1] containing terminal values
264
355
  """
265
356
  return torch.sum(x ** 2, dim=1)
266
- def terminal_for_sample(self, x)-> torch.Tensor:
357
+ def sigma_matrix(self,x):
358
+ return self.sigma * x
359
+ def terminal_for_sample(self, x)-> torch.Tensor:
267
360
  """
268
361
  Terminal condition of the PDE.
269
362
 
@@ -274,6 +367,7 @@ def terminal_for_sample(self, x)-> torch.Tensor:
274
367
  torch.Tensor: tensor of size [num_sample ,batch_size, 1] containing terminal values
275
368
  """
276
369
  return torch.sum(x ** 2, dim=2 ,keepdim=True )
370
+
277
371
  class PricingDiffRate(Equation):
278
372
  """
279
373
  Nonlinear Black-Scholes equation with different interest rates for borrowing and lending
@@ -319,8 +413,9 @@ class PricingDiffRate(Equation):
319
413
 
320
414
  def terminal(self, t, x):
321
415
  temp = torch.max(x, 1)[0]
322
- return torch.maximum(temp - 120, torch.tensor(0))
323
-
416
+ return nn.ReLU()(temp - 120) - 2*nn.ReLU()(temp - 150)
417
+ def sigma_matrix(self,x):
418
+ return self.sigma * x
324
419
  def terminal_for_sample(self, x)-> torch.Tensor:
325
420
  """
326
421
  Terminal condition of the PDE.
@@ -333,4 +428,3 @@ class PricingDiffRate(Equation):
333
428
  """
334
429
  temp = torch.max(x, 2 , keep_dim = True)[0]
335
430
  return torch.maximum(temp - 120, torch.tensor(0))
336
-
@@ -6,7 +6,7 @@ class TimeNet(Module):
6
6
  Neural network model for time dimension
7
7
  """
8
8
  def __init__(
9
- self,
9
+ self,
10
10
  output_dim: int
11
11
  ):
12
12
  """
@@ -27,9 +27,10 @@ class TimeNet(Module):
27
27
  self.tanh3 = Tanh()
28
28
  self.tanh4 = Tanh()
29
29
  self.tanh5 = Tanh()
30
+ self.tanh6 = Tanh()
30
31
 
31
32
  def forward(
32
- self,
33
+ self,
33
34
  x: torch.Tensor
34
35
  ) -> torch.Tensor:
35
36
  """
@@ -51,6 +52,7 @@ class TimeNet(Module):
51
52
  x = self.layer5(x)
52
53
  x = self.tanh5(x)
53
54
  x = self.layer6(x)
55
+ x = self.tanh6(x)
54
56
  return x
55
57
 
56
58
 
@@ -59,8 +61,8 @@ class Net1(Module):
59
61
  A class for defining a neural network with a single linear layer.
60
62
  """
61
63
  def __init__(
62
- self,
63
- input_dim: int,
64
+ self,
65
+ input_dim: int,
64
66
  output_dim: int
65
67
  ):
66
68
  """
@@ -76,7 +78,7 @@ class Net1(Module):
76
78
  self.bn = BatchNorm1d(output_dim)
77
79
 
78
80
  def forward(
79
- self,
81
+ self,
80
82
  x: torch.Tensor
81
83
  ) -> torch.Tensor:
82
84
  """
@@ -99,11 +101,11 @@ For implementing Deep-Time-SetTransformer we have used code written by authors o
99
101
 
100
102
  class MAB(nn.Module):
101
103
  def __init__(
102
- self,
103
- dim_q: int,
104
- dim_k: int,
105
- dim_v: int,
106
- num_heads: int,
104
+ self,
105
+ dim_q: int,
106
+ dim_k: int,
107
+ dim_v: int,
108
+ num_heads: int,
107
109
  ln: bool = False
108
110
  ):
109
111
  """
@@ -127,8 +129,8 @@ class MAB(nn.Module):
127
129
  self.fc_o = nn.Linear(dim_v, dim_v)
128
130
 
129
131
  def forward(
130
- self,
131
- q: torch.Tensor,
132
+ self,
133
+ q: torch.Tensor,
132
134
  k: torch.Tensor
133
135
  ) -> torch.Tensor:
134
136
  """
@@ -155,10 +157,10 @@ class MAB(nn.Module):
155
157
 
156
158
  class SAB(nn.Module):
157
159
  def __init__(
158
- self,
159
- dim_in: int,
160
- dim_out: int,
161
- num_heads: int,
160
+ self,
161
+ dim_in: int,
162
+ dim_out: int,
163
+ num_heads: int,
162
164
  ln: bool = False
163
165
  ):
164
166
  """
@@ -173,7 +175,7 @@ class SAB(nn.Module):
173
175
  self.mab = MAB(dim_in, dim_in, dim_out, num_heads, ln=ln)
174
176
 
175
177
  def forward(
176
- self,
178
+ self,
177
179
  x: torch.Tensor
178
180
  ) -> torch.Tensor:
179
181
  """
@@ -186,11 +188,11 @@ class SAB(nn.Module):
186
188
 
187
189
  class ISAB(nn.Module):
188
190
  def __init__(
189
- self,
190
- dim_in: int,
191
- dim_out: int,
192
- num_heads: int,
193
- num_inds: int,
191
+ self,
192
+ dim_in: int,
193
+ dim_out: int,
194
+ num_heads: int,
195
+ num_inds: int,
194
196
  ln: bool = False
195
197
  ):
196
198
  """
@@ -209,7 +211,7 @@ class ISAB(nn.Module):
209
211
  self.mab1 = MAB(dim_in, dim_out, dim_out, num_heads, ln=ln)
210
212
 
211
213
  def forward(
212
- self,
214
+ self,
213
215
  x: torch.Tensor
214
216
  ) -> torch.Tensor:
215
217
  """
@@ -223,10 +225,10 @@ class ISAB(nn.Module):
223
225
 
224
226
  class PMA(nn.Module):
225
227
  def __init__(
226
- self,
227
- dim: int,
228
- num_heads: int,
229
- num_seeds: int,
228
+ self,
229
+ dim: int,
230
+ num_heads: int,
231
+ num_seeds: int,
230
232
  ln: bool = False
231
233
  ):
232
234
  """
@@ -243,7 +245,7 @@ class PMA(nn.Module):
243
245
  self.mab = MAB(dim, dim, dim, num_heads, ln=ln)
244
246
 
245
247
  def forward(
246
- self,
248
+ self,
247
249
  x: torch.Tensor
248
250
  ) -> torch.Tensor:
249
251
  """
@@ -375,12 +377,128 @@ class DeepTimeSetTransformer(nn.Module):
375
377
  output = self.time_layer4(t, output)
376
378
  output = nn.ReLU()(output)
377
379
  output = self.time_layer5(t, output)
378
-
380
+
379
381
 
380
382
  return output
381
383
  import torch
382
384
  import torch.nn as nn
383
385
 
386
+
387
+
388
+ class FBSNNNetwork(nn.Module):
389
+ def __init__(
390
+ self,
391
+ layersize: list[int]
392
+ ):
393
+ """
394
+ Initializes a neural network with multiple blocks.
395
+
396
+ Args:
397
+ - indim (int): input dimension
398
+ - layersize (List[int]): list of sizes of hidden layers
399
+ - outdim (int): output dimension
400
+ """
401
+ super(FBSNNNetwork, self).__init__()
402
+
403
+ # initialize first set of layers
404
+
405
+ self.n_layer = len(layersize) - 1
406
+ # create input layer
407
+
408
+ self.layers = nn.ModuleList([])
409
+ # create hidden layers
410
+ for i in range(len(layersize) - 1):
411
+ self.layers.append(nn.Linear(layersize[i], layersize[i + 1]))
412
+
413
+ def forward(
414
+ self,
415
+ x: torch.Tensor) -> torch.Tensor:
416
+ """
417
+ Passes the input through the neural network.
418
+
419
+ Args:
420
+ - x (torch.Tensor): input tensor
421
+
422
+ Returns:
423
+ - torch.Tensor: output tensor
424
+ """
425
+
426
+ for i in range(self.n_layer):
427
+
428
+
429
+
430
+ # apply layer to tensor
431
+ x = self.layers[i](x)
432
+ if i < self.n_layer - 1 :
433
+ x =torch.sin(x)
434
+
435
+ # apply output layer to tensor
436
+
437
+
438
+ return x
439
+
440
+
441
+ class DeepBSDE(nn.Module):
442
+ def __init__(
443
+ self,
444
+ layersize: list[int]
445
+ ):
446
+ """
447
+ Initializes a neural network with multiple blocks.
448
+
449
+ Args:
450
+ - indim (int): input dimension
451
+ - layersize (List[int]): list of sizes of hidden layers
452
+ - outdim (int): output dimension
453
+ """
454
+ super(DeepBSDE, self).__init__()
455
+
456
+ # initialize first set of layers
457
+
458
+ self.n_layer = len(layersize) - 1
459
+ # create input layer
460
+
461
+ self.layers = nn.ModuleList([])
462
+ self.batch_layer = nn.ModuleList([])
463
+ # create hidden layers
464
+ for i in range(len(layersize) - 1):
465
+ self.layers.append(nn.Linear(layersize[i], layersize[i + 1] , bias=False))
466
+ self.batch_layer.append(nn.BatchNorm1d(layersize[i] , eps=1e-06, momentum=0.01))
467
+
468
+
469
+ self.batch_layer.append(nn.BatchNorm1d(layersize[-1] , eps=1e-06, momentum=0.01))
470
+
471
+ def forward(
472
+ self,
473
+ x: torch.Tensor) -> torch.Tensor:
474
+ """
475
+ Passes the input through the neural network.
476
+
477
+ Args:
478
+ - x (torch.Tensor): input tensor
479
+
480
+ Returns:
481
+ - torch.Tensor: output tensor
482
+ """
483
+ #x = self.batch_layer[0](x)
484
+ for i in range(self.n_layer - 1):
485
+
486
+ # apply layer to tensor
487
+ x = self.layers[i](x)
488
+ #x = self.batch_layer[i+1](x)
489
+
490
+
491
+ x =nn.ReLU()(x)
492
+
493
+
494
+ # apply output layer to tensor
495
+ x = self.layers[-1](x)
496
+ #x = self.batch_layer[-1](x)
497
+
498
+
499
+ return x
500
+
501
+
384
502
  class TimeDependentNetwork(nn.Module):
385
503
  def __init__(
386
504
  self,
@@ -406,18 +524,20 @@ class TimeDependentNetwork(nn.Module):
406
524
  # create input layer
407
525
  self.layers.append(Net1(indim, layersize[0]))
408
526
  self.time_layer.append(TimeNet(indim))
409
- self.batch_layer.append(nn.BatchNorm1d(indim))
410
- self.batch_layer.append(nn.BatchNorm1d(layersize[0]))
527
+ self.batch_layer.append(nn.BatchNorm1d(indim , eps=1e-06, momentum=0.01))
528
+ self.batch_layer.append(nn.BatchNorm1d(layersize[0],eps=1e-06, momentum=0.01))
411
529
 
412
530
  # create hidden layers
413
531
  for i in range(len(layersize) - 1):
414
532
  self.layers.append(Net1(layersize[i], layersize[i + 1]))
415
533
  self.time_layer.append(TimeNet(layersize[i]))
416
- self.batch_layer.append(nn.BatchNorm1d(layersize[i + 1]))
534
+ self.batch_layer.append(nn.BatchNorm1d(layersize[i + 1] , eps=1e-06, momentum=0.01))
417
535
 
418
536
  # create output layer
419
537
  self.time_layer.append(TimeNet(outdim))
420
538
  self.linear = nn.Linear(layersize[-1], outdim)
539
+ self.batch_layer.append(nn.BatchNorm1d(outdim , eps=1e-06, momentum=0.01))
540
+
421
541
 
422
542
  def forward(
423
543
  self,
@@ -433,21 +553,23 @@ class TimeDependentNetwork(nn.Module):
433
553
  Returns:
434
554
  - torch.Tensor: output tensor
435
555
  """
436
-
437
556
  for i in range(self.n_layer):
438
557
  # apply time-based weights to input tensor
439
558
  time = self.time_layer[i](torch.cat((t, t**2, t**3, torch.exp(t)), 1))
559
+ x = self.batch_layer[i](x)
560
+
440
561
 
441
562
  x = x * (1 + time)
442
- # x = self.batch_layer[i](x)
443
563
 
444
564
  # apply layer to tensor
445
565
  x = self.layers[i](x)
446
- x = nn.ReLU()(x)
566
+
567
+ x = torch.sin(x)
447
568
 
448
569
  # apply output layer to tensor
449
570
 
450
571
  x = self.linear(x)
572
+ #x = self.batch_layer[-1](x)
451
573
 
452
574
  return x
453
575