vaquum-limen 2.5.5__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 (378) hide show
  1. vaquum_limen-2.5.5/LICENSE +21 -0
  2. vaquum_limen-2.5.5/PKG-INFO +148 -0
  3. vaquum_limen-2.5.5/README.md +117 -0
  4. vaquum_limen-2.5.5/limen/__init__.py +42 -0
  5. vaquum_limen-2.5.5/limen/backtest/__init__.py +0 -0
  6. vaquum_limen-2.5.5/limen/backtest/backtest_sequential.py +116 -0
  7. vaquum_limen-2.5.5/limen/backtest/backtest_snapshot.py +181 -0
  8. vaquum_limen-2.5.5/limen/cohort/__init__.py +7 -0
  9. vaquum_limen-2.5.5/limen/cohort/cohort.py +553 -0
  10. vaquum_limen-2.5.5/limen/cohort/regime_pools.py +473 -0
  11. vaquum_limen-2.5.5/limen/data/__init__.py +7 -0
  12. vaquum_limen-2.5.5/limen/data/_internal/binance_file_to_polars.py +32 -0
  13. vaquum_limen-2.5.5/limen/data/bars/__init__.py +7 -0
  14. vaquum_limen-2.5.5/limen/data/bars/standard_bars.py +147 -0
  15. vaquum_limen-2.5.5/limen/data/historical_data.py +499 -0
  16. vaquum_limen-2.5.5/limen/data/utils/__init__.py +16 -0
  17. vaquum_limen-2.5.5/limen/data/utils/compute_data_bars.py +40 -0
  18. vaquum_limen-2.5.5/limen/data/utils/random_slice.py +37 -0
  19. vaquum_limen-2.5.5/limen/data/utils/splits.py +137 -0
  20. vaquum_limen-2.5.5/limen/experiment/__init__.py +19 -0
  21. vaquum_limen-2.5.5/limen/experiment/checkpoint_manager.py +302 -0
  22. vaquum_limen-2.5.5/limen/experiment/experiment_core.py +962 -0
  23. vaquum_limen-2.5.5/limen/experiment/feedback_controller.py +387 -0
  24. vaquum_limen-2.5.5/limen/experiment/manifest_core.py +1199 -0
  25. vaquum_limen-2.5.5/limen/experiment/msq.py +489 -0
  26. vaquum_limen-2.5.5/limen/experiment/param_domain.py +323 -0
  27. vaquum_limen-2.5.5/limen/experiment/param_search/__init__.py +11 -0
  28. vaquum_limen-2.5.5/limen/experiment/param_search/grid_strategy.py +169 -0
  29. vaquum_limen-2.5.5/limen/experiment/param_search/random_strategy.py +76 -0
  30. vaquum_limen-2.5.5/limen/experiment/param_search/registry.py +10 -0
  31. vaquum_limen-2.5.5/limen/experiment/param_search/search_strategy.py +202 -0
  32. vaquum_limen-2.5.5/limen/experiment/reducer/__init__.py +31 -0
  33. vaquum_limen-2.5.5/limen/experiment/reducer/budget_reducer.py +299 -0
  34. vaquum_limen-2.5.5/limen/experiment/reducer/correlation_reducer.py +328 -0
  35. vaquum_limen-2.5.5/limen/experiment/reducer/filter_types.py +64 -0
  36. vaquum_limen-2.5.5/limen/experiment/reducer/focus_reducer.py +415 -0
  37. vaquum_limen-2.5.5/limen/experiment/reducer/pruning_strategy.py +82 -0
  38. vaquum_limen-2.5.5/limen/experiment/reducer/registry.py +14 -0
  39. vaquum_limen-2.5.5/limen/experiment/reducer/sanity_reducer.py +229 -0
  40. vaquum_limen-2.5.5/limen/experiment/reducer/saturation_reducer.py +173 -0
  41. vaquum_limen-2.5.5/limen/experiment/trainer/__init__.py +9 -0
  42. vaquum_limen-2.5.5/limen/experiment/trainer/errors.py +3 -0
  43. vaquum_limen-2.5.5/limen/experiment/trainer/sensor.py +88 -0
  44. vaquum_limen-2.5.5/limen/experiment/trainer/trainer.py +326 -0
  45. vaquum_limen-2.5.5/limen/features/__init__.py +119 -0
  46. vaquum_limen-2.5.5/limen/features/absorption_intensity.py +40 -0
  47. vaquum_limen-2.5.5/limen/features/active_lines.py +47 -0
  48. vaquum_limen-2.5.5/limen/features/active_quantile_count.py +46 -0
  49. vaquum_limen-2.5.5/limen/features/amihud_illiquidity.py +30 -0
  50. vaquum_limen-2.5.5/limen/features/atr_percent_sma.py +37 -0
  51. vaquum_limen-2.5.5/limen/features/atr_sma.py +36 -0
  52. vaquum_limen-2.5.5/limen/features/body_to_range.py +31 -0
  53. vaquum_limen-2.5.5/limen/features/breakout_features.py +161 -0
  54. vaquum_limen-2.5.5/limen/features/breakout_percentile_regime.py +31 -0
  55. vaquum_limen-2.5.5/limen/features/calendar_time_features.py +35 -0
  56. vaquum_limen-2.5.5/limen/features/close_position.py +16 -0
  57. vaquum_limen-2.5.5/limen/features/close_to_extremes.py +19 -0
  58. vaquum_limen-2.5.5/limen/features/conserved_flux_renormalization.py +122 -0
  59. vaquum_limen-2.5.5/limen/features/cyclical_time_features.py +61 -0
  60. vaquum_limen-2.5.5/limen/features/distance_from_high.py +20 -0
  61. vaquum_limen-2.5.5/limen/features/distance_from_low.py +20 -0
  62. vaquum_limen-2.5.5/limen/features/dollar_volume.py +22 -0
  63. vaquum_limen-2.5.5/limen/features/dynamic_stop_loss.py +28 -0
  64. vaquum_limen-2.5.5/limen/features/dynamic_target.py +28 -0
  65. vaquum_limen-2.5.5/limen/features/ema_alignment.py +28 -0
  66. vaquum_limen-2.5.5/limen/features/ema_breakout.py +35 -0
  67. vaquum_limen-2.5.5/limen/features/entry_score_microstructure.py +94 -0
  68. vaquum_limen-2.5.5/limen/features/exit_quality.py +30 -0
  69. vaquum_limen-2.5.5/limen/features/feature_aliases.py +36 -0
  70. vaquum_limen-2.5.5/limen/features/forward_breakout_target.py +37 -0
  71. vaquum_limen-2.5.5/limen/features/fractional_diff.py +192 -0
  72. vaquum_limen-2.5.5/limen/features/gap_high.py +16 -0
  73. vaquum_limen-2.5.5/limen/features/garman_klass_volatility.py +46 -0
  74. vaquum_limen-2.5.5/limen/features/hh_hl_structure_regime.py +31 -0
  75. vaquum_limen-2.5.5/limen/features/hours_since_big_move.py +43 -0
  76. vaquum_limen-2.5.5/limen/features/hours_since_quantile_line.py +43 -0
  77. vaquum_limen-2.5.5/limen/features/ichimoku_cloud.py +44 -0
  78. vaquum_limen-2.5.5/limen/features/illiquidity_shock.py +38 -0
  79. vaquum_limen-2.5.5/limen/features/jump_variation_proxy.py +50 -0
  80. vaquum_limen-2.5.5/limen/features/kline_imbalance.py +30 -0
  81. vaquum_limen-2.5.5/limen/features/lagged_features.py +107 -0
  82. vaquum_limen-2.5.5/limen/features/log_returns.py +19 -0
  83. vaquum_limen-2.5.5/limen/features/ma_slope_regime.py +32 -0
  84. vaquum_limen-2.5.5/limen/features/market_regime.py +58 -0
  85. vaquum_limen-2.5.5/limen/features/micro_momentum.py +19 -0
  86. vaquum_limen-2.5.5/limen/features/momentum_confirmation.py +37 -0
  87. vaquum_limen-2.5.5/limen/features/momentum_periods.py +28 -0
  88. vaquum_limen-2.5.5/limen/features/momentum_weight.py +22 -0
  89. vaquum_limen-2.5.5/limen/features/parkinson_volatility.py +41 -0
  90. vaquum_limen-2.5.5/limen/features/position_in_candle.py +23 -0
  91. vaquum_limen-2.5.5/limen/features/position_in_range.py +20 -0
  92. vaquum_limen-2.5.5/limen/features/price_range_position.py +24 -0
  93. vaquum_limen-2.5.5/limen/features/price_vs_band_regime.py +38 -0
  94. vaquum_limen-2.5.5/limen/features/quantile_flag.py +35 -0
  95. vaquum_limen-2.5.5/limen/features/quantile_line_density.py +42 -0
  96. vaquum_limen-2.5.5/limen/features/range_overlap.py +31 -0
  97. vaquum_limen-2.5.5/limen/features/range_pct.py +16 -0
  98. vaquum_limen-2.5.5/limen/features/range_per_dollar_volume.py +33 -0
  99. vaquum_limen-2.5.5/limen/features/realized_kurtosis.py +57 -0
  100. vaquum_limen-2.5.5/limen/features/realized_semivariance.py +42 -0
  101. vaquum_limen-2.5.5/limen/features/realized_skewness.py +54 -0
  102. vaquum_limen-2.5.5/limen/features/regime_multiplier.py +30 -0
  103. vaquum_limen-2.5.5/limen/features/rejection_intensity.py +40 -0
  104. vaquum_limen-2.5.5/limen/features/relative_range_seasonality.py +59 -0
  105. vaquum_limen-2.5.5/limen/features/relative_volatility_seasonality.py +55 -0
  106. vaquum_limen-2.5.5/limen/features/relative_volume_seasonality.py +53 -0
  107. vaquum_limen-2.5.5/limen/features/return_per_dollar_volume.py +28 -0
  108. vaquum_limen-2.5.5/limen/features/returns_lags.py +26 -0
  109. vaquum_limen-2.5.5/limen/features/risk_reward_ratio.py +22 -0
  110. vaquum_limen-2.5.5/limen/features/rogers_satchell_volatility.py +45 -0
  111. vaquum_limen-2.5.5/limen/features/sma_crossover.py +49 -0
  112. vaquum_limen-2.5.5/limen/features/sma_ratios.py +37 -0
  113. vaquum_limen-2.5.5/limen/features/spread.py +17 -0
  114. vaquum_limen-2.5.5/limen/features/spread_percent.py +19 -0
  115. vaquum_limen-2.5.5/limen/features/tail_event_intensity.py +37 -0
  116. vaquum_limen-2.5.5/limen/features/trend_coherence.py +32 -0
  117. vaquum_limen-2.5.5/limen/features/trend_strength.py +28 -0
  118. vaquum_limen-2.5.5/limen/features/volatility_1h.py +18 -0
  119. vaquum_limen-2.5.5/limen/features/volatility_measure.py +19 -0
  120. vaquum_limen-2.5.5/limen/features/volatility_of_volatility.py +34 -0
  121. vaquum_limen-2.5.5/limen/features/volatility_term_structure.py +52 -0
  122. vaquum_limen-2.5.5/limen/features/volatility_weight.py +37 -0
  123. vaquum_limen-2.5.5/limen/features/volume_ratio.py +26 -0
  124. vaquum_limen-2.5.5/limen/features/volume_regime.py +27 -0
  125. vaquum_limen-2.5.5/limen/features/volume_spike.py +27 -0
  126. vaquum_limen-2.5.5/limen/features/volume_trend.py +32 -0
  127. vaquum_limen-2.5.5/limen/features/volume_weight.py +30 -0
  128. vaquum_limen-2.5.5/limen/features/vwap.py +40 -0
  129. vaquum_limen-2.5.5/limen/features/wick_imbalance.py +33 -0
  130. vaquum_limen-2.5.5/limen/features/window_return_regime.py +30 -0
  131. vaquum_limen-2.5.5/limen/features/yang_zhang_volatility.py +63 -0
  132. vaquum_limen-2.5.5/limen/indicators/__init__.py +237 -0
  133. vaquum_limen-2.5.5/limen/indicators/_atr.py +49 -0
  134. vaquum_limen-2.5.5/limen/indicators/_bbands.py +85 -0
  135. vaquum_limen-2.5.5/limen/indicators/_ema.py +45 -0
  136. vaquum_limen-2.5.5/limen/indicators/_hilbert.py +40 -0
  137. vaquum_limen-2.5.5/limen/indicators/ad.py +38 -0
  138. vaquum_limen-2.5.5/limen/indicators/adosc.py +71 -0
  139. vaquum_limen-2.5.5/limen/indicators/apo.py +62 -0
  140. vaquum_limen-2.5.5/limen/indicators/atr.py +47 -0
  141. vaquum_limen-2.5.5/limen/indicators/avgprice.py +33 -0
  142. vaquum_limen-2.5.5/limen/indicators/bbands.py +108 -0
  143. vaquum_limen-2.5.5/limen/indicators/body_pct.py +16 -0
  144. vaquum_limen-2.5.5/limen/indicators/bollinger_bands.py +42 -0
  145. vaquum_limen-2.5.5/limen/indicators/bollinger_position.py +28 -0
  146. vaquum_limen-2.5.5/limen/indicators/bop.py +37 -0
  147. vaquum_limen-2.5.5/limen/indicators/cci.py +82 -0
  148. vaquum_limen-2.5.5/limen/indicators/cdl2crows.py +117 -0
  149. vaquum_limen-2.5.5/limen/indicators/cdl3blackcrows.py +116 -0
  150. vaquum_limen-2.5.5/limen/indicators/cdl3inside.py +125 -0
  151. vaquum_limen-2.5.5/limen/indicators/cdl3linestrike.py +123 -0
  152. vaquum_limen-2.5.5/limen/indicators/cdl3starsinsouth.py +175 -0
  153. vaquum_limen-2.5.5/limen/indicators/cdl3whitesoldiers.py +180 -0
  154. vaquum_limen-2.5.5/limen/indicators/cdlabandonedbaby.py +168 -0
  155. vaquum_limen-2.5.5/limen/indicators/cdladvancedblock.py +253 -0
  156. vaquum_limen-2.5.5/limen/indicators/cdlbelthold.py +117 -0
  157. vaquum_limen-2.5.5/limen/indicators/cdlclosingmarubozu.py +117 -0
  158. vaquum_limen-2.5.5/limen/indicators/cdlconcealbabyswall.py +124 -0
  159. vaquum_limen-2.5.5/limen/indicators/cdlcounterattack.py +123 -0
  160. vaquum_limen-2.5.5/limen/indicators/cdldarkcloudcover.py +110 -0
  161. vaquum_limen-2.5.5/limen/indicators/cdldoji.py +93 -0
  162. vaquum_limen-2.5.5/limen/indicators/cdldragonflydoji.py +118 -0
  163. vaquum_limen-2.5.5/limen/indicators/cdlengulfing.py +93 -0
  164. vaquum_limen-2.5.5/limen/indicators/cdlgravestonedoji.py +118 -0
  165. vaquum_limen-2.5.5/limen/indicators/cdlhammer.py +160 -0
  166. vaquum_limen-2.5.5/limen/indicators/cdlhangingman.py +160 -0
  167. vaquum_limen-2.5.5/limen/indicators/cdlharami.py +116 -0
  168. vaquum_limen-2.5.5/limen/indicators/cdlharamicross.py +119 -0
  169. vaquum_limen-2.5.5/limen/indicators/cdlhighwave.py +120 -0
  170. vaquum_limen-2.5.5/limen/indicators/cdlhikkake.py +115 -0
  171. vaquum_limen-2.5.5/limen/indicators/cdlhikkakemod.py +161 -0
  172. vaquum_limen-2.5.5/limen/indicators/cdlhomingpigeon.py +116 -0
  173. vaquum_limen-2.5.5/limen/indicators/cdlidentical3crows.py +138 -0
  174. vaquum_limen-2.5.5/limen/indicators/cdlinvertedhammer.py +140 -0
  175. vaquum_limen-2.5.5/limen/indicators/cdlladderbottom.py +112 -0
  176. vaquum_limen-2.5.5/limen/indicators/cdllongleggeddoji.py +117 -0
  177. vaquum_limen-2.5.5/limen/indicators/cdllongline.py +120 -0
  178. vaquum_limen-2.5.5/limen/indicators/cdlmarubozu.py +118 -0
  179. vaquum_limen-2.5.5/limen/indicators/cdlmatchinglow.py +99 -0
  180. vaquum_limen-2.5.5/limen/indicators/cdlmathold.py +153 -0
  181. vaquum_limen-2.5.5/limen/indicators/cdlonneck.py +118 -0
  182. vaquum_limen-2.5.5/limen/indicators/cdlpiercing.py +104 -0
  183. vaquum_limen-2.5.5/limen/indicators/cdlrickshawman.py +146 -0
  184. vaquum_limen-2.5.5/limen/indicators/cdlrisefall3methods.py +147 -0
  185. vaquum_limen-2.5.5/limen/indicators/cdlseparatinglines.py +142 -0
  186. vaquum_limen-2.5.5/limen/indicators/cdlshootingstar.py +140 -0
  187. vaquum_limen-2.5.5/limen/indicators/cdlshortline.py +120 -0
  188. vaquum_limen-2.5.5/limen/indicators/cdlspinningtop.py +98 -0
  189. vaquum_limen-2.5.5/limen/indicators/cdlstalledpattern.py +167 -0
  190. vaquum_limen-2.5.5/limen/indicators/cdlsticksandwich.py +102 -0
  191. vaquum_limen-2.5.5/limen/indicators/cdltakuri.py +140 -0
  192. vaquum_limen-2.5.5/limen/indicators/cdlthrusting.py +119 -0
  193. vaquum_limen-2.5.5/limen/indicators/cdltristar.py +111 -0
  194. vaquum_limen-2.5.5/limen/indicators/cdlunique3river.py +123 -0
  195. vaquum_limen-2.5.5/limen/indicators/cmo.py +109 -0
  196. vaquum_limen-2.5.5/limen/indicators/dema.py +69 -0
  197. vaquum_limen-2.5.5/limen/indicators/ema.py +57 -0
  198. vaquum_limen-2.5.5/limen/indicators/ht_dcperiod.py +220 -0
  199. vaquum_limen-2.5.5/limen/indicators/ht_dcphase.py +266 -0
  200. vaquum_limen-2.5.5/limen/indicators/ht_phasor.py +235 -0
  201. vaquum_limen-2.5.5/limen/indicators/ht_sine.py +280 -0
  202. vaquum_limen-2.5.5/limen/indicators/ht_trendline.py +252 -0
  203. vaquum_limen-2.5.5/limen/indicators/ht_trendmode.py +326 -0
  204. vaquum_limen-2.5.5/limen/indicators/kama.py +133 -0
  205. vaquum_limen-2.5.5/limen/indicators/linearreg.py +75 -0
  206. vaquum_limen-2.5.5/limen/indicators/linearreg_angle.py +76 -0
  207. vaquum_limen-2.5.5/limen/indicators/linearreg_intercept.py +74 -0
  208. vaquum_limen-2.5.5/limen/indicators/linearreg_slope.py +73 -0
  209. vaquum_limen-2.5.5/limen/indicators/ma.py +146 -0
  210. vaquum_limen-2.5.5/limen/indicators/macd.py +97 -0
  211. vaquum_limen-2.5.5/limen/indicators/macdext.py +185 -0
  212. vaquum_limen-2.5.5/limen/indicators/macdfix.py +95 -0
  213. vaquum_limen-2.5.5/limen/indicators/mama.py +274 -0
  214. vaquum_limen-2.5.5/limen/indicators/medprice.py +27 -0
  215. vaquum_limen-2.5.5/limen/indicators/mfi.py +87 -0
  216. vaquum_limen-2.5.5/limen/indicators/midpoint.py +69 -0
  217. vaquum_limen-2.5.5/limen/indicators/midprice.py +71 -0
  218. vaquum_limen-2.5.5/limen/indicators/mom.py +34 -0
  219. vaquum_limen-2.5.5/limen/indicators/natr.py +66 -0
  220. vaquum_limen-2.5.5/limen/indicators/obv.py +32 -0
  221. vaquum_limen-2.5.5/limen/indicators/ppo.py +72 -0
  222. vaquum_limen-2.5.5/limen/indicators/price_change_pct.py +23 -0
  223. vaquum_limen-2.5.5/limen/indicators/returns.py +16 -0
  224. vaquum_limen-2.5.5/limen/indicators/roc.py +37 -0
  225. vaquum_limen-2.5.5/limen/indicators/rocp.py +37 -0
  226. vaquum_limen-2.5.5/limen/indicators/rocr.py +37 -0
  227. vaquum_limen-2.5.5/limen/indicators/rocr100.py +37 -0
  228. vaquum_limen-2.5.5/limen/indicators/rolling_volatility.py +22 -0
  229. vaquum_limen-2.5.5/limen/indicators/rsi.py +89 -0
  230. vaquum_limen-2.5.5/limen/indicators/rsi_sma.py +37 -0
  231. vaquum_limen-2.5.5/limen/indicators/sar.py +157 -0
  232. vaquum_limen-2.5.5/limen/indicators/sarext.py +218 -0
  233. vaquum_limen-2.5.5/limen/indicators/sma.py +78 -0
  234. vaquum_limen-2.5.5/limen/indicators/sma_deviation_std.py +36 -0
  235. vaquum_limen-2.5.5/limen/indicators/stddev.py +101 -0
  236. vaquum_limen-2.5.5/limen/indicators/stoch.py +203 -0
  237. vaquum_limen-2.5.5/limen/indicators/stochastic_oscillator.py +43 -0
  238. vaquum_limen-2.5.5/limen/indicators/stochf.py +179 -0
  239. vaquum_limen-2.5.5/limen/indicators/stochrsi.py +91 -0
  240. vaquum_limen-2.5.5/limen/indicators/t3.py +157 -0
  241. vaquum_limen-2.5.5/limen/indicators/tema.py +69 -0
  242. vaquum_limen-2.5.5/limen/indicators/trange.py +37 -0
  243. vaquum_limen-2.5.5/limen/indicators/trima.py +160 -0
  244. vaquum_limen-2.5.5/limen/indicators/trix.py +76 -0
  245. vaquum_limen-2.5.5/limen/indicators/tsf.py +75 -0
  246. vaquum_limen-2.5.5/limen/indicators/typprice.py +30 -0
  247. vaquum_limen-2.5.5/limen/indicators/ultosc.py +164 -0
  248. vaquum_limen-2.5.5/limen/indicators/var.py +92 -0
  249. vaquum_limen-2.5.5/limen/indicators/wclprice.py +30 -0
  250. vaquum_limen-2.5.5/limen/indicators/wilder_rsi.py +35 -0
  251. vaquum_limen-2.5.5/limen/indicators/willr.py +48 -0
  252. vaquum_limen-2.5.5/limen/indicators/window_return.py +20 -0
  253. vaquum_limen-2.5.5/limen/indicators/wma.py +92 -0
  254. vaquum_limen-2.5.5/limen/log/__init__.py +13 -0
  255. vaquum_limen-2.5.5/limen/log/_experiment_backtest_results.py +109 -0
  256. vaquum_limen-2.5.5/limen/log/_experiment_confusion_metrics.py +32 -0
  257. vaquum_limen-2.5.5/limen/log/_experiment_parameter_correlation.py +172 -0
  258. vaquum_limen-2.5.5/limen/log/_permutation_confusion_metrics.py +232 -0
  259. vaquum_limen-2.5.5/limen/log/_permutation_prediction_performance.py +38 -0
  260. vaquum_limen-2.5.5/limen/log/_read_from_file.py +44 -0
  261. vaquum_limen-2.5.5/limen/log/log.py +109 -0
  262. vaquum_limen-2.5.5/limen/metrics/__init__.py +16 -0
  263. vaquum_limen-2.5.5/limen/metrics/balanced_metric.py +29 -0
  264. vaquum_limen-2.5.5/limen/metrics/binary_metrics.py +25 -0
  265. vaquum_limen-2.5.5/limen/metrics/continuous_metrics.py +37 -0
  266. vaquum_limen-2.5.5/limen/metrics/multiclass_metrics.py +27 -0
  267. vaquum_limen-2.5.5/limen/metrics/rule_based_metrics.py +74 -0
  268. vaquum_limen-2.5.5/limen/metrics/safe_ovr_auc.py +29 -0
  269. vaquum_limen-2.5.5/limen/scalers/__init__.py +13 -0
  270. vaquum_limen-2.5.5/limen/scalers/linear_scaler.py +196 -0
  271. vaquum_limen-2.5.5/limen/scalers/logreg_scaler.py +133 -0
  272. vaquum_limen-2.5.5/limen/scalers/rank_gauss_scaler.py +124 -0
  273. vaquum_limen-2.5.5/limen/scalers/registry.py +11 -0
  274. vaquum_limen-2.5.5/limen/scalers/robust_scaler.py +96 -0
  275. vaquum_limen-2.5.5/limen/sfd/__init__.py +13 -0
  276. vaquum_limen-2.5.5/limen/sfd/foundational_sfd/__init__.py +18 -0
  277. vaquum_limen-2.5.5/limen/sfd/foundational_sfd/logreg_binary.py +72 -0
  278. vaquum_limen-2.5.5/limen/sfd/foundational_sfd/random_binary.py +40 -0
  279. vaquum_limen-2.5.5/limen/sfd/foundational_sfd/rule_based.py +58 -0
  280. vaquum_limen-2.5.5/limen/sfd/foundational_sfd/tabpfn_binary.py +80 -0
  281. vaquum_limen-2.5.5/limen/sfd/foundational_sfd/xgboost_regressor.py +85 -0
  282. vaquum_limen-2.5.5/limen/sfd/loop/__init__.py +10 -0
  283. vaquum_limen-2.5.5/limen/sfd/loop/loop_sfd.py +562 -0
  284. vaquum_limen-2.5.5/limen/sfd/loop/meta.py +103 -0
  285. vaquum_limen-2.5.5/limen/sfd/loop/progress.py +65 -0
  286. vaquum_limen-2.5.5/limen/sfd/loop/registry.py +46 -0
  287. vaquum_limen-2.5.5/limen/sfd/loop/run.py +311 -0
  288. vaquum_limen-2.5.5/limen/sfd/reference_architecture/__init__.py +31 -0
  289. vaquum_limen-2.5.5/limen/sfd/reference_architecture/base.py +158 -0
  290. vaquum_limen-2.5.5/limen/sfd/reference_architecture/logreg_binary.py +138 -0
  291. vaquum_limen-2.5.5/limen/sfd/reference_architecture/random_binary.py +100 -0
  292. vaquum_limen-2.5.5/limen/sfd/reference_architecture/rule_based.py +149 -0
  293. vaquum_limen-2.5.5/limen/sfd/reference_architecture/tabpfn_binary.py +174 -0
  294. vaquum_limen-2.5.5/limen/sfd/reference_architecture/xgboost_regressor.py +150 -0
  295. vaquum_limen-2.5.5/limen/sfd/rule_based/__init__.py +4 -0
  296. vaquum_limen-2.5.5/limen/sfd/rule_based/config.py +107 -0
  297. vaquum_limen-2.5.5/limen/sfd/rule_based/predicates.py +254 -0
  298. vaquum_limen-2.5.5/limen/trading/__init__.py +5 -0
  299. vaquum_limen-2.5.5/limen/trading/account.py +179 -0
  300. vaquum_limen-2.5.5/limen/transforms/__init__.py +17 -0
  301. vaquum_limen-2.5.5/limen/transforms/calibrate_classifier.py +29 -0
  302. vaquum_limen-2.5.5/limen/transforms/mad_transform.py +34 -0
  303. vaquum_limen-2.5.5/limen/transforms/optimize_binary_threshold.py +51 -0
  304. vaquum_limen-2.5.5/limen/transforms/quantile_trim_transform.py +41 -0
  305. vaquum_limen-2.5.5/limen/transforms/shift_column_transform.py +20 -0
  306. vaquum_limen-2.5.5/limen/transforms/winsorize_transform.py +42 -0
  307. vaquum_limen-2.5.5/limen/transforms/zscore_transform.py +38 -0
  308. vaquum_limen-2.5.5/limen/utils/__init__.py +23 -0
  309. vaquum_limen-2.5.5/limen/utils/adf_test.py +60 -0
  310. vaquum_limen-2.5.5/limen/utils/confidence_filtering_system.py +185 -0
  311. vaquum_limen-2.5.5/limen/utils/data_dict_to_numpy.py +23 -0
  312. vaquum_limen-2.5.5/limen/utils/param_space.py +137 -0
  313. vaquum_limen-2.5.5/limen/utils/reporting.py +45 -0
  314. vaquum_limen-2.5.5/pyproject.toml +136 -0
  315. vaquum_limen-2.5.5/setup.cfg +4 -0
  316. vaquum_limen-2.5.5/tests/test_account_conviction.py +264 -0
  317. vaquum_limen-2.5.5/tests/test_backtest_conviction.py +267 -0
  318. vaquum_limen-2.5.5/tests/test_bars.py +152 -0
  319. vaquum_limen-2.5.5/tests/test_budget_reducer.py +415 -0
  320. vaquum_limen-2.5.5/tests/test_checkpoint_manager.py +522 -0
  321. vaquum_limen-2.5.5/tests/test_confidence_filtering_system.py +181 -0
  322. vaquum_limen-2.5.5/tests/test_conserved_flux_renormalization.py +14 -0
  323. vaquum_limen-2.5.5/tests/test_correlation_reducer.py +213 -0
  324. vaquum_limen-2.5.5/tests/test_experiment_core_msq.py +596 -0
  325. vaquum_limen-2.5.5/tests/test_experiment_core_standard_csv.py +173 -0
  326. vaquum_limen-2.5.5/tests/test_feature_library_candle_structure.py +34 -0
  327. vaquum_limen-2.5.5/tests/test_feature_library_composites.py +198 -0
  328. vaquum_limen-2.5.5/tests/test_feature_library_context.py +107 -0
  329. vaquum_limen-2.5.5/tests/test_feature_library_cross_timescale.py +30 -0
  330. vaquum_limen-2.5.5/tests/test_feature_library_liquidity.py +54 -0
  331. vaquum_limen-2.5.5/tests/test_feature_library_primitives.py +139 -0
  332. vaquum_limen-2.5.5/tests/test_feature_library_range_volatility.py +76 -0
  333. vaquum_limen-2.5.5/tests/test_feature_library_realized_risk.py +77 -0
  334. vaquum_limen-2.5.5/tests/test_feature_library_regimes.py +296 -0
  335. vaquum_limen-2.5.5/tests/test_feature_library_seasonality.py +79 -0
  336. vaquum_limen-2.5.5/tests/test_feature_perturbation.py +269 -0
  337. vaquum_limen-2.5.5/tests/test_feedback_controller.py +446 -0
  338. vaquum_limen-2.5.5/tests/test_focus_reducer.py +434 -0
  339. vaquum_limen-2.5.5/tests/test_foundational_sfd.py +79 -0
  340. vaquum_limen-2.5.5/tests/test_fractional_diff.py +181 -0
  341. vaquum_limen-2.5.5/tests/test_historical_data.py +173 -0
  342. vaquum_limen-2.5.5/tests/test_indicator_and_data_helpers.py +319 -0
  343. vaquum_limen-2.5.5/tests/test_indicator_api.py +30 -0
  344. vaquum_limen-2.5.5/tests/test_indicators_vs_talib.py +1990 -0
  345. vaquum_limen-2.5.5/tests/test_inline_metrics.py +96 -0
  346. vaquum_limen-2.5.5/tests/test_klines_data_maker_fields.py +35 -0
  347. vaquum_limen-2.5.5/tests/test_large_param_space.py +48 -0
  348. vaquum_limen-2.5.5/tests/test_log_read_from_file.py +68 -0
  349. vaquum_limen-2.5.5/tests/test_loop_sfd.py +1072 -0
  350. vaquum_limen-2.5.5/tests/test_manifest_pre_split_random_selector.py +47 -0
  351. vaquum_limen-2.5.5/tests/test_manifest_prepare_data.py +264 -0
  352. vaquum_limen-2.5.5/tests/test_manifest_rule_based.py +105 -0
  353. vaquum_limen-2.5.5/tests/test_metrics_and_log_helpers.py +499 -0
  354. vaquum_limen-2.5.5/tests/test_msq.py +401 -0
  355. vaquum_limen-2.5.5/tests/test_param_domain.py +266 -0
  356. vaquum_limen-2.5.5/tests/test_param_space.py +218 -0
  357. vaquum_limen-2.5.5/tests/test_predicates.py +141 -0
  358. vaquum_limen-2.5.5/tests/test_proto_cohort.py +837 -0
  359. vaquum_limen-2.5.5/tests/test_pruning_strategy.py +34 -0
  360. vaquum_limen-2.5.5/tests/test_reducer_factory.py +34 -0
  361. vaquum_limen-2.5.5/tests/test_reference_architecture.py +286 -0
  362. vaquum_limen-2.5.5/tests/test_regime_diversified_opinion_pools.py +86 -0
  363. vaquum_limen-2.5.5/tests/test_regime_pools_helpers.py +262 -0
  364. vaquum_limen-2.5.5/tests/test_rule_based_metrics.py +85 -0
  365. vaquum_limen-2.5.5/tests/test_runtime_tracking.py +194 -0
  366. vaquum_limen-2.5.5/tests/test_sanity_reducer.py +237 -0
  367. vaquum_limen-2.5.5/tests/test_saturation_reducer.py +218 -0
  368. vaquum_limen-2.5.5/tests/test_scalers.py +238 -0
  369. vaquum_limen-2.5.5/tests/test_search_strategies.py +289 -0
  370. vaquum_limen-2.5.5/tests/test_splits.py +48 -0
  371. vaquum_limen-2.5.5/tests/test_tabpfn.py +52 -0
  372. vaquum_limen-2.5.5/tests/test_trainer.py +484 -0
  373. vaquum_limen-2.5.5/tests/test_transforms.py +114 -0
  374. vaquum_limen-2.5.5/vaquum_limen.egg-info/PKG-INFO +148 -0
  375. vaquum_limen-2.5.5/vaquum_limen.egg-info/SOURCES.txt +376 -0
  376. vaquum_limen-2.5.5/vaquum_limen.egg-info/dependency_links.txt +1 -0
  377. vaquum_limen-2.5.5/vaquum_limen.egg-info/requires.txt +17 -0
  378. vaquum_limen-2.5.5/vaquum_limen.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Vaquum
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,148 @@
1
+ Metadata-Version: 2.4
2
+ Name: vaquum_limen
3
+ Version: 2.5.5
4
+ Summary: Bitcoin-first research and trading platform.
5
+ Author: Prasenjit Dey, Arun Raguraman, Jatin Thakur, Soujanyaa Boruah, Ng Wei Da
6
+ Author-email: Mikko Kotila <mailme@mikkokotila.com>
7
+ License: MIT
8
+ Project-URL: Homepage, https://vaquum.fi
9
+ Project-URL: Documentation, https://docs.vaquum.fi/limen/
10
+ Project-URL: Repository, https://github.com/vaquum/limen
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: pandas>=2.3.1
15
+ Requires-Dist: polars>=1.0.0
16
+ Requires-Dist: scikit-learn>=1.6.1
17
+ Requires-Dist: tqdm>=4.67.0
18
+ Requires-Dist: xgboost
19
+ Requires-Dist: python-dotenv
20
+ Requires-Dist: scipy
21
+ Requires-Dist: statsmodels
22
+ Requires-Dist: tslearn
23
+ Requires-Dist: lightgbm
24
+ Requires-Dist: pyarrow
25
+ Requires-Dist: numpy>=2.2.6
26
+ Requires-Dist: ta-lib
27
+ Requires-Dist: requests
28
+ Provides-Extra: tabpfn
29
+ Requires-Dist: tabpfn>=6; extra == "tabpfn"
30
+ Dynamic: license-file
31
+
32
+ <div align="center">
33
+ <br />
34
+ <a href="https://github.com/Vaquum"><img src="https://github.com/Vaquum/Home/raw/main/assets/Logo.png" alt="Vaquum" width="150" /></a>
35
+ <br />
36
+ </div>
37
+ <br />
38
+ <div align="center"><strong>Vaquum Limen turns Bitcoin market data into searchable signals, backtested outcomes, and decoder cohorts.</strong></div>
39
+
40
+ <div align="center">
41
+ <a href="#limen">Limen</a> •
42
+ <a href="#what-limen-is-not">What Limen Is Not</a> •
43
+ <a href="#capabilities">Capabilities</a> •
44
+ <a href="#first-experiment">First Experiment</a> •
45
+ <a href="#learn-more">Learn More</a>
46
+ </div>
47
+ <br />
48
+ <div align="center">
49
+ <a href="https://www.bestpractices.dev/projects/11898"><img src="https://www.bestpractices.dev/projects/11898/badge" alt="OpenSSF Best Practices" /></a>
50
+ <a href="https://scorecard.dev/viewer/?uri=github.com/Vaquum/Limen"><img src="https://img.shields.io/ossf-scorecard/github.com/Vaquum/Limen?label=openssf+scorecard&amp;style=flat" alt="OpenSSF Scorecard" /></a>
51
+ </div>
52
+
53
+ <hr />
54
+
55
+ <a id="limen"></a>
56
+
57
+ # Limen — The Research Engine
58
+
59
+ *Manifest-driven Bitcoin alpha research engine that turns market data into searchable signals, backtested outcomes, and decoder cohorts.*
60
+
61
+ Limen unifies parameter search across machine learning and rule-based strategies, with built-in analytics that show not just what works, but why it works. It evolves from Talos, the hyperparameter optimization framework for TensorFlow and Keras cited in over 1,000 scientific papers with zero breaking bugs in six years.
62
+
63
+ ## What Limen Is Not
64
+
65
+ Limen is not:
66
+
67
+ - a trade execution system
68
+ - a downstream trade decision engine
69
+ - a generic multi-asset research platform
70
+
71
+ In the wider Vaquum architecture, Origo sits upstream as the data layer. Nexus, Praxis, and Veritas sit downstream for decisioning, execution, and oversight.
72
+
73
+ ## Capabilities
74
+
75
+ - Manifest-driven experiment pipelines
76
+ - Search across models, rules, features, targets, and hyperparameters
77
+ - Extensive built-in indicator and feature library for Bitcoin research
78
+ - Support for both machine learning and rule-based strategy research
79
+ - Bitcoin-native transforms, scaling, and target construction
80
+ - Leakage-safe train, validation, and test workflows
81
+ - Built-in backtesting, confusion analytics, and parameter diagnostics
82
+ - Decoder cohort construction and regime-diversified model pooling
83
+ - Reproducible runs with checkpointing, resumption, and retraining
84
+
85
+ ## First Experiment
86
+
87
+ The fastest first success is a small parameter sweep on the bundled BTC/USDT kline dataset with the built-in logistic-regression decoder.
88
+
89
+ 1. Install the package:
90
+
91
+ ```bash
92
+ pip install vaquum_limen
93
+ ```
94
+
95
+ 2. Load data and run a first experiment:
96
+
97
+ ```python
98
+ import limen
99
+
100
+ historical = limen.HistoricalData()
101
+ data = historical.get_spot_klines(kline_size=7200, n_rows=2000)
102
+
103
+ uel = limen.UniversalExperimentLoop(data=data, sfd=limen.sfd.logreg_binary)
104
+
105
+ uel.run(
106
+ experiment_name="logreg-first",
107
+ n_permutations=25,
108
+ prep_each_round=True,
109
+ )
110
+ ```
111
+
112
+ 3. Inspect the core outputs:
113
+
114
+ - `uel.experiment_log` for the parameter sweep results
115
+ - `uel.experiment_confusion_metrics` for confusion analytics
116
+ - `uel.experiment_backtest_results` for backtest results
117
+
118
+ That path is the simplest way to get a real Limen run on your machine without relying on repo-local fixture files. If you want richer run directories, checkpoints, resumability, and stored round artefacts, continue into the UEL documentation below.
119
+
120
+ ## Learn More
121
+
122
+ - Start with the full docs hub in [docs/README.md](docs/README.md)
123
+ - Define research units in [docs/Single-File-Decoder.md](docs/Single-File-Decoder.md), [docs/Built-In-SFDs.md](docs/Built-In-SFDs.md), and [docs/Experiment-Manifest.md](docs/Experiment-Manifest.md)
124
+ - Run experiments in [docs/Universal-Experiment-Loop.md](docs/Universal-Experiment-Loop.md) and extend the artifact-rich path through [docs/Advanced-Search.md](docs/Advanced-Search.md) and [docs/Reducers-And-Feedback.md](docs/Reducers-And-Feedback.md)
125
+ - Analyze results in [docs/Log.md](docs/Log.md), [docs/Benchmark.md](docs/Benchmark.md), and [docs/Backtest.md](docs/Backtest.md)
126
+ - Understand the model layer in [docs/Reference-Architecture.md](docs/Reference-Architecture.md) and the helper layer in [docs/Utilities.md](docs/Utilities.md)
127
+ - Promote finished runs into reusable outputs with [docs/Trainer.md](docs/Trainer.md) and [docs/Regime-Diversified-Opinion-Pools.md](docs/Regime-Diversified-Opinion-Pools.md)
128
+ - Contribute through [docs/Developer/README.md](docs/Developer/README.md)
129
+
130
+ ## Contributing
131
+
132
+ The simplest way to start contributing is by [joining an open discussion](https://github.com/Vaquum/Limen/issues?q=is%3Aissue%20state%3Aopen%20label%3Aquestion%2Fdiscussion), contributing to [the docs](https://github.com/Vaquum/Limen/tree/main/docs), or by [picking up an open issue](https://github.com/Vaquum/Limen/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug%20OR%20label%3Aenhancement%20OR%20label%3A%22good%20first%20issue%22%20OR%20label%3A%22help%20wanted%22%20OR%20label%3APriority%20OR%20label%3Aprocess).
133
+
134
+ Before contributing, start with [docs/Developer/README.md](docs/Developer/README.md).
135
+
136
+ ## Vulnerabilities
137
+
138
+ Report vulnerabilities privately through [GitHub Security Advisories](https://github.com/Vaquum/Limen/security/advisories/new).
139
+
140
+ ## Citations
141
+
142
+ If you use Limen for published work, please cite:
143
+
144
+ Vaquum Limen [Computer software]. (2026). Retrieved from https://github.com/Vaquum/Limen.
145
+
146
+ ## License
147
+
148
+ [MIT License](https://github.com/Vaquum/Limen/blob/main/LICENSE).
@@ -0,0 +1,117 @@
1
+ <div align="center">
2
+ <br />
3
+ <a href="https://github.com/Vaquum"><img src="https://github.com/Vaquum/Home/raw/main/assets/Logo.png" alt="Vaquum" width="150" /></a>
4
+ <br />
5
+ </div>
6
+ <br />
7
+ <div align="center"><strong>Vaquum Limen turns Bitcoin market data into searchable signals, backtested outcomes, and decoder cohorts.</strong></div>
8
+
9
+ <div align="center">
10
+ <a href="#limen">Limen</a> •
11
+ <a href="#what-limen-is-not">What Limen Is Not</a> •
12
+ <a href="#capabilities">Capabilities</a> •
13
+ <a href="#first-experiment">First Experiment</a> •
14
+ <a href="#learn-more">Learn More</a>
15
+ </div>
16
+ <br />
17
+ <div align="center">
18
+ <a href="https://www.bestpractices.dev/projects/11898"><img src="https://www.bestpractices.dev/projects/11898/badge" alt="OpenSSF Best Practices" /></a>
19
+ <a href="https://scorecard.dev/viewer/?uri=github.com/Vaquum/Limen"><img src="https://img.shields.io/ossf-scorecard/github.com/Vaquum/Limen?label=openssf+scorecard&amp;style=flat" alt="OpenSSF Scorecard" /></a>
20
+ </div>
21
+
22
+ <hr />
23
+
24
+ <a id="limen"></a>
25
+
26
+ # Limen — The Research Engine
27
+
28
+ *Manifest-driven Bitcoin alpha research engine that turns market data into searchable signals, backtested outcomes, and decoder cohorts.*
29
+
30
+ Limen unifies parameter search across machine learning and rule-based strategies, with built-in analytics that show not just what works, but why it works. It evolves from Talos, the hyperparameter optimization framework for TensorFlow and Keras cited in over 1,000 scientific papers with zero breaking bugs in six years.
31
+
32
+ ## What Limen Is Not
33
+
34
+ Limen is not:
35
+
36
+ - a trade execution system
37
+ - a downstream trade decision engine
38
+ - a generic multi-asset research platform
39
+
40
+ In the wider Vaquum architecture, Origo sits upstream as the data layer. Nexus, Praxis, and Veritas sit downstream for decisioning, execution, and oversight.
41
+
42
+ ## Capabilities
43
+
44
+ - Manifest-driven experiment pipelines
45
+ - Search across models, rules, features, targets, and hyperparameters
46
+ - Extensive built-in indicator and feature library for Bitcoin research
47
+ - Support for both machine learning and rule-based strategy research
48
+ - Bitcoin-native transforms, scaling, and target construction
49
+ - Leakage-safe train, validation, and test workflows
50
+ - Built-in backtesting, confusion analytics, and parameter diagnostics
51
+ - Decoder cohort construction and regime-diversified model pooling
52
+ - Reproducible runs with checkpointing, resumption, and retraining
53
+
54
+ ## First Experiment
55
+
56
+ The fastest first success is a small parameter sweep on the bundled BTC/USDT kline dataset with the built-in logistic-regression decoder.
57
+
58
+ 1. Install the package:
59
+
60
+ ```bash
61
+ pip install vaquum_limen
62
+ ```
63
+
64
+ 2. Load data and run a first experiment:
65
+
66
+ ```python
67
+ import limen
68
+
69
+ historical = limen.HistoricalData()
70
+ data = historical.get_spot_klines(kline_size=7200, n_rows=2000)
71
+
72
+ uel = limen.UniversalExperimentLoop(data=data, sfd=limen.sfd.logreg_binary)
73
+
74
+ uel.run(
75
+ experiment_name="logreg-first",
76
+ n_permutations=25,
77
+ prep_each_round=True,
78
+ )
79
+ ```
80
+
81
+ 3. Inspect the core outputs:
82
+
83
+ - `uel.experiment_log` for the parameter sweep results
84
+ - `uel.experiment_confusion_metrics` for confusion analytics
85
+ - `uel.experiment_backtest_results` for backtest results
86
+
87
+ That path is the simplest way to get a real Limen run on your machine without relying on repo-local fixture files. If you want richer run directories, checkpoints, resumability, and stored round artefacts, continue into the UEL documentation below.
88
+
89
+ ## Learn More
90
+
91
+ - Start with the full docs hub in [docs/README.md](docs/README.md)
92
+ - Define research units in [docs/Single-File-Decoder.md](docs/Single-File-Decoder.md), [docs/Built-In-SFDs.md](docs/Built-In-SFDs.md), and [docs/Experiment-Manifest.md](docs/Experiment-Manifest.md)
93
+ - Run experiments in [docs/Universal-Experiment-Loop.md](docs/Universal-Experiment-Loop.md) and extend the artifact-rich path through [docs/Advanced-Search.md](docs/Advanced-Search.md) and [docs/Reducers-And-Feedback.md](docs/Reducers-And-Feedback.md)
94
+ - Analyze results in [docs/Log.md](docs/Log.md), [docs/Benchmark.md](docs/Benchmark.md), and [docs/Backtest.md](docs/Backtest.md)
95
+ - Understand the model layer in [docs/Reference-Architecture.md](docs/Reference-Architecture.md) and the helper layer in [docs/Utilities.md](docs/Utilities.md)
96
+ - Promote finished runs into reusable outputs with [docs/Trainer.md](docs/Trainer.md) and [docs/Regime-Diversified-Opinion-Pools.md](docs/Regime-Diversified-Opinion-Pools.md)
97
+ - Contribute through [docs/Developer/README.md](docs/Developer/README.md)
98
+
99
+ ## Contributing
100
+
101
+ The simplest way to start contributing is by [joining an open discussion](https://github.com/Vaquum/Limen/issues?q=is%3Aissue%20state%3Aopen%20label%3Aquestion%2Fdiscussion), contributing to [the docs](https://github.com/Vaquum/Limen/tree/main/docs), or by [picking up an open issue](https://github.com/Vaquum/Limen/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug%20OR%20label%3Aenhancement%20OR%20label%3A%22good%20first%20issue%22%20OR%20label%3A%22help%20wanted%22%20OR%20label%3APriority%20OR%20label%3Aprocess).
102
+
103
+ Before contributing, start with [docs/Developer/README.md](docs/Developer/README.md).
104
+
105
+ ## Vulnerabilities
106
+
107
+ Report vulnerabilities privately through [GitHub Security Advisories](https://github.com/Vaquum/Limen/security/advisories/new).
108
+
109
+ ## Citations
110
+
111
+ If you use Limen for published work, please cite:
112
+
113
+ Vaquum Limen [Computer software]. (2026). Retrieved from https://github.com/Vaquum/Limen.
114
+
115
+ ## License
116
+
117
+ [MIT License](https://github.com/Vaquum/Limen/blob/main/LICENSE).
@@ -0,0 +1,42 @@
1
+ from limen.data import HistoricalData
2
+ from limen.log.log import Log
3
+ from limen.trading import Account
4
+ from limen.backtest.backtest_sequential import BacktestSequential
5
+ from limen.experiment import Manifest
6
+ from limen.experiment import ReconstructionError
7
+ from limen.experiment import Sensor
8
+ from limen.experiment import Trainer
9
+ from limen.experiment import UniversalExperimentLoop
10
+ from limen.cohort import Cohort
11
+ from limen.cohort import RegimeDiversifiedOpinionPools
12
+
13
+ from limen import features
14
+ from limen import indicators
15
+ from limen import metrics
16
+ from limen import sfd
17
+ from limen import scalers
18
+ from limen import transforms
19
+ from limen import utils
20
+ from limen import log
21
+
22
+ __all__ = [
23
+ 'Account',
24
+ 'BacktestSequential',
25
+ 'Cohort',
26
+ 'HistoricalData',
27
+ 'Log',
28
+ 'Manifest',
29
+ 'ReconstructionError',
30
+ 'RegimeDiversifiedOpinionPools',
31
+ 'Sensor',
32
+ 'Trainer',
33
+ 'UniversalExperimentLoop',
34
+ 'features',
35
+ 'indicators',
36
+ 'log',
37
+ 'metrics',
38
+ 'scalers',
39
+ 'sfd',
40
+ 'transforms',
41
+ 'utils'
42
+ ]
File without changes
@@ -0,0 +1,116 @@
1
+ import math
2
+ from collections.abc import Sequence
3
+ from limen.trading import Account
4
+
5
+ class BacktestSequential:
6
+
7
+ def __init__(self, start_usdt: float = 30000) -> None:
8
+
9
+ self.fee_rate = 0.001
10
+
11
+ self.account = Account(start_usdt)
12
+ self.start_usdt = start_usdt
13
+ self.trades = []
14
+ self.equity_curve = []
15
+
16
+ def run(self,
17
+ actual: Sequence[int | float],
18
+ prediction: Sequence[int | float],
19
+ price_change: Sequence[float],
20
+ open_prices: Sequence[float],
21
+ close_prices: Sequence[float]) -> dict:
22
+
23
+ if not all(len(arr) == len(actual) for arr in [prediction, price_change, open_prices, close_prices]):
24
+ raise ValueError('ERROR: Arrays must have same length')
25
+
26
+ for i in range(len(actual)):
27
+ pred = prediction[i]
28
+ act = actual[i]
29
+ open_price = open_prices[i]
30
+ close_price = close_prices[i]
31
+
32
+ if open_price <= 0 or close_price <= 0:
33
+ continue
34
+
35
+ current_usdt = self.account.account['total_usdt'][-1]
36
+
37
+ if pred == 1 and current_usdt > 1:
38
+ buy_fee = current_usdt * self.fee_rate
39
+ usdt_after_buy_fee = current_usdt - buy_fee
40
+ if usdt_after_buy_fee <= 0:
41
+ continue
42
+ self.account.update_account('buy', usdt_after_buy_fee, open_price)
43
+ btc_held = self.account.long_position
44
+ gross_sell_amount = btc_held * close_price
45
+ sell_fee = gross_sell_amount * self.fee_rate
46
+ net_sell_amount = gross_sell_amount - sell_fee
47
+ self.account.update_account('sell', net_sell_amount, close_price)
48
+ final_usdt = self.account.account['total_usdt'][-1]
49
+ profit = final_usdt - current_usdt
50
+ self.trades.append({'type': 'long', 'hit': act == pred, 'pnl': profit, 'volume': usdt_after_buy_fee})
51
+ self.equity_curve.append(final_usdt)
52
+
53
+ return self._calculate_metrics()
54
+
55
+ def _calculate_metrics(self) -> dict:
56
+
57
+ if not self.trades:
58
+ return {
59
+ 'PnL': 0,
60
+ 'win_rate': 0,
61
+ 'max_drawdown': 0,
62
+ 'expected_value': 0,
63
+ 'sharpe_ratio': 0,
64
+ 'net_long_volume': 0,
65
+ 'net_short_volume': 0,
66
+ 'net_trade_volume': 0
67
+ }
68
+
69
+ final_usdt = self.account.account['total_usdt'][-1]
70
+ pnl = final_usdt - self.start_usdt
71
+
72
+ wins = sum(1 for t in self.trades if t['pnl'] > 0)
73
+ total_trades = len(self.trades)
74
+ win_rate = wins / total_trades if total_trades > 0 else 0
75
+
76
+ max_drawdown = 0
77
+ if self.equity_curve:
78
+ peak = self.equity_curve[0]
79
+ for equity in self.equity_curve:
80
+ peak = max(peak, equity)
81
+ drawdown = (peak - equity) / peak
82
+ max_drawdown = max(max_drawdown, drawdown)
83
+
84
+ expected_value = sum(t['pnl'] for t in self.trades) / total_trades if total_trades > 0 else 0
85
+
86
+ net_long_volume = sum(t['volume'] for t in self.trades if t['type'] == 'long')
87
+ net_short_volume = sum(t['volume'] for t in self.trades if t['type'] == 'short')
88
+ net_trade_volume = net_long_volume + net_short_volume
89
+
90
+ returns = []
91
+ if len(self.equity_curve) > 1:
92
+ prev_equity = self.start_usdt
93
+ for equity in self.equity_curve:
94
+ if prev_equity != 0:
95
+ returns.append((equity - prev_equity) / prev_equity)
96
+ prev_equity = equity
97
+
98
+ if len(returns) > 1:
99
+ mean_return = sum(returns) / len(returns)
100
+ variance = sum((r - mean_return) ** 2 for r in returns) / (len(returns) - 1)
101
+ std_return = math.sqrt(variance)
102
+ sharpe_ratio = mean_return / std_return if std_return != 0 else 0
103
+ else:
104
+ sharpe_ratio = 0
105
+
106
+ # NOTE: These must all be rounded to 2 decimal places.
107
+ return {
108
+ 'PnL': round(pnl, 2),
109
+ 'win_rate': round(win_rate, 2),
110
+ 'max_drawdown': round(max_drawdown, 2),
111
+ 'expected_value': round(expected_value, 2),
112
+ 'sharpe_ratio': round(sharpe_ratio, 2),
113
+ 'net_long_volume': round(net_long_volume, 2),
114
+ 'net_short_volume': round(net_short_volume, 2),
115
+ 'net_trade_volume': round(net_trade_volume, 2)
116
+ }
@@ -0,0 +1,181 @@
1
+ import numpy as np
2
+ import pandas as pd
3
+
4
+ PRICE_CHANGE_RTOL = 1e-09
5
+ PRICE_CHANGE_ATOL = 1e-12
6
+
7
+ def backtest_snapshot(df: pd.DataFrame,
8
+ *,
9
+ pred_col: str = 'predictions',
10
+ open_col: str = 'open',
11
+ close_col: str = 'close',
12
+ price_change_col: str = 'price_change',
13
+ execution_lag_bars: int = 1,
14
+ fee_bps: float = 5.0,
15
+ slip_bps: float = 5.0) -> pd.DataFrame:
16
+
17
+ '''
18
+ Long-only, HOLD-WHILE-1 evaluation using pre-aligned intrabar returns.
19
+ All percentage fields are in % units (not fractions). Sharpe is per bar (unitless).
20
+
21
+ Takes in output of log.permutation_prediction_performance and returns backtest results.
22
+
23
+ Logic
24
+ - Predictions are shifted forward by `execution_lag_bars` onto the execution bar sequence.
25
+ - Position pos = 1 wherever the lagged predictions==1 on a tradable execution row.
26
+ - Price columns must be numeric; missing price rows are treated as non-tradable gaps.
27
+ - Entry bar gross return: r_entry = price_change / open (≈ close/open - 1).
28
+ - Continuation bar gross return: r_cont = close_t / close_{t-1} - 1 (holding across bars).
29
+ - Fee/slippage costs are applied multiplicatively on entry and exit fills.
30
+ - Trade metrics are computed from compounded consecutive 1-run returns.
31
+ - Equity compounds over R_net; drawdown is computed from net equity.
32
+
33
+ Returns a one-row DataFrame with columns (in order):
34
+ [
35
+ 'trade_win_rate_pct',
36
+ 'trade_expectancy_pct',
37
+ 'max_drawdown_pct',
38
+ 'total_return_gross_pct',
39
+ 'total_return_net_pct',
40
+ 'trade_return_mean_win_pct',
41
+ 'trade_return_mean_loss_pct',
42
+ 'mean_kelly_pct',
43
+ 'bars_total',
44
+ 'sharpe_per_bar',
45
+ 'bars_in_market_pct',
46
+ 'trades_count',
47
+ 'cost_round_trip_bps',
48
+ ]
49
+ '''
50
+
51
+ df = df.copy()
52
+
53
+ if df.empty:
54
+ raise ValueError('backtest_snapshot requires at least one row')
55
+
56
+ if execution_lag_bars < 0:
57
+ raise ValueError('execution_lag_bars must be >= 0')
58
+
59
+ try:
60
+ pred = pd.to_numeric(df[pred_col], errors='raise')
61
+ except (TypeError, ValueError) as exc:
62
+ raise ValueError('predictions must contain only 0 or 1') from exc
63
+
64
+ if pred.isna().any() or (~pred.isin([0, 1])).any():
65
+ raise ValueError('predictions must contain only 0 or 1')
66
+
67
+ pred = pred.astype(int)
68
+ try:
69
+ open_px = pd.to_numeric(df[open_col], errors='raise')
70
+ close_px = pd.to_numeric(df[close_col], errors='raise')
71
+ dpx = pd.to_numeric(df[price_change_col], errors='raise')
72
+ except (TypeError, ValueError) as exc:
73
+ raise ValueError('open, close, and price_change must be numeric') from exc
74
+
75
+ price_check_mask = open_px.notna() & close_px.notna() & dpx.notna()
76
+ expected_dpx = close_px - open_px
77
+
78
+ if price_check_mask.any() and not np.isclose(
79
+ dpx[price_check_mask],
80
+ expected_dpx[price_check_mask],
81
+ rtol=PRICE_CHANGE_RTOL,
82
+ atol=PRICE_CHANGE_ATOL,
83
+ ).all():
84
+ raise ValueError('price_change must equal close - open')
85
+
86
+ tradable = open_px.notna() & close_px.notna() & dpx.notna() & (open_px != 0)
87
+ execution_rows = pd.Series(False, index=df.index)
88
+ if execution_lag_bars < len(df):
89
+ execution_rows.iloc[execution_lag_bars:] = True
90
+
91
+ pred = pred.shift(execution_lag_bars, fill_value=0)
92
+ eval_mask = execution_rows & tradable
93
+ pos = (pred == 1) & eval_mask
94
+
95
+ bars_total = int(eval_mask.sum())
96
+ bars_in_market_pct = float((pos.sum() / bars_total) * 100.0) if bars_total else np.nan
97
+
98
+ entry_mask = pos & (~pos.shift(1, fill_value=False))
99
+ cont_mask = pos & ( pos.shift(1, fill_value=False))
100
+
101
+ trades_count = int(entry_mask.sum())
102
+
103
+ r_entry = dpx / open_px
104
+ r_cont = (close_px / close_px.shift(1)) - 1.0
105
+
106
+ R_gross = np.where(entry_mask, r_entry, 0.0) + np.where(cont_mask, r_cont, 0.0)
107
+ R_gross = pd.Series(R_gross, index=df.index).fillna(0.0)
108
+
109
+ fee = fee_bps / 10_000.0
110
+ slip = slip_bps / 10_000.0
111
+ entry_mult = (1.0 - fee) / (1.0 + slip)
112
+ exit_mult = (1.0 - fee) * (1.0 - slip)
113
+
114
+ exit_mask = pos & (~pos.shift(-1, fill_value=False))
115
+ cost_mult = pd.Series(1.0, index=df.index)
116
+ cost_mult.loc[entry_mask] *= entry_mult
117
+ cost_mult.loc[exit_mask] *= exit_mult
118
+
119
+ R_net = (((1.0 + R_gross) * cost_mult) - 1.0).fillna(0.0)
120
+ eq_gross = (1.0 + R_gross).cumprod()
121
+ eq_net = (1.0 + R_net).cumprod()
122
+
123
+ peak = eq_net.cummax().clip(lower=1.0)
124
+ max_drawdown_pct = float((eq_net / peak - 1.0).min() * 100.0)
125
+
126
+ total_return_gross_pct = float((eq_gross.iloc[-1] - 1.0) * 100.0)
127
+ total_return_net_pct = float((eq_net.iloc[-1] - 1.0) * 100.0)
128
+
129
+ run_ids = entry_mask.cumsum()
130
+ trade_returns = (
131
+ (1.0 + R_net[pos]).groupby(run_ids[pos]).prod() - 1.0
132
+ ) if entry_mask.any() else pd.Series(dtype=float)
133
+
134
+ if trade_returns.size:
135
+ wins = trade_returns[trade_returns > 0]
136
+ losses = trade_returns[trade_returns < 0]
137
+ trade_win_rate_pct = float((wins.size / trade_returns.size) * 100.0)
138
+ trade_expectancy_pct = float(trade_returns.mean() * 100.0)
139
+ trade_return_mean_win_pct = float(wins.mean() * 100.0) if wins.size else np.nan
140
+ trade_return_mean_loss_pct = float(losses.mean() * 100.0) if losses.size else np.nan
141
+ else:
142
+ trade_win_rate_pct = trade_expectancy_pct = np.nan
143
+ trade_return_mean_win_pct = trade_return_mean_loss_pct = np.nan
144
+
145
+ kelly_returns = trade_returns
146
+
147
+ kelly_wins = kelly_returns[kelly_returns > 0]
148
+ kelly_losses = kelly_returns[kelly_returns < 0]
149
+ if kelly_wins.size and kelly_losses.size:
150
+ win_rate = float(kelly_wins.size / kelly_returns.size)
151
+ loss_rate = float(kelly_losses.size / kelly_returns.size)
152
+ avg_win = float(kelly_wins.mean())
153
+ avg_loss = abs(float(kelly_losses.mean()))
154
+ payout_ratio = avg_win / avg_loss if avg_loss > 0 else np.nan
155
+ mean_kelly_pct = float((win_rate - (loss_rate / payout_ratio)) * 100.0) if payout_ratio > 0 else np.nan
156
+ else:
157
+ mean_kelly_pct = np.nan
158
+
159
+ eval_returns = R_net[eval_mask]
160
+ mu = float(eval_returns.mean()) if eval_returns.size else np.nan
161
+ sd = float(eval_returns.std(ddof=1)) if eval_returns.size > 1 else np.nan
162
+
163
+ sharpe_per_bar = float(mu / sd) if sd > 0 else np.nan
164
+
165
+ data = pd.DataFrame.from_records([{
166
+ 'trade_win_rate_pct': round(trade_win_rate_pct, 1),
167
+ 'trade_expectancy_pct': round(trade_expectancy_pct, 3),
168
+ 'max_drawdown_pct': round(max_drawdown_pct, 1),
169
+ 'total_return_gross_pct': round(total_return_gross_pct, 1),
170
+ 'total_return_net_pct': round(total_return_net_pct, 1),
171
+ 'trade_return_mean_win_pct': round(trade_return_mean_win_pct, 1),
172
+ 'trade_return_mean_loss_pct': round(trade_return_mean_loss_pct, 1),
173
+ 'mean_kelly_pct': round(mean_kelly_pct, 3),
174
+ 'bars_total': int(bars_total),
175
+ 'sharpe_per_bar': round(sharpe_per_bar, 2),
176
+ 'bars_in_market_pct': round(bars_in_market_pct, 1),
177
+ 'trades_count': int(trades_count),
178
+ 'cost_round_trip_bps': round((1.0 - (entry_mult * exit_mult)) * 10_000),
179
+ }])
180
+
181
+ return data
@@ -0,0 +1,7 @@
1
+ from limen.cohort.cohort import Cohort
2
+ from limen.cohort.regime_pools import RegimeDiversifiedOpinionPools
3
+
4
+ __all__ = [
5
+ 'Cohort',
6
+ 'RegimeDiversifiedOpinionPools',
7
+ ]