mainsequence 2.0.0__py3-none-any.whl

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. mainsequence/__init__.py +0 -0
  2. mainsequence/__main__.py +9 -0
  3. mainsequence/cli/__init__.py +1 -0
  4. mainsequence/cli/api.py +157 -0
  5. mainsequence/cli/cli.py +442 -0
  6. mainsequence/cli/config.py +78 -0
  7. mainsequence/cli/ssh_utils.py +126 -0
  8. mainsequence/client/__init__.py +17 -0
  9. mainsequence/client/base.py +431 -0
  10. mainsequence/client/data_sources_interfaces/__init__.py +0 -0
  11. mainsequence/client/data_sources_interfaces/duckdb.py +1468 -0
  12. mainsequence/client/data_sources_interfaces/timescale.py +479 -0
  13. mainsequence/client/models_helpers.py +113 -0
  14. mainsequence/client/models_report_studio.py +412 -0
  15. mainsequence/client/models_tdag.py +2276 -0
  16. mainsequence/client/models_vam.py +1983 -0
  17. mainsequence/client/utils.py +387 -0
  18. mainsequence/dashboards/__init__.py +0 -0
  19. mainsequence/dashboards/streamlit/__init__.py +0 -0
  20. mainsequence/dashboards/streamlit/assets/config.toml +12 -0
  21. mainsequence/dashboards/streamlit/assets/favicon.png +0 -0
  22. mainsequence/dashboards/streamlit/assets/logo.png +0 -0
  23. mainsequence/dashboards/streamlit/core/__init__.py +0 -0
  24. mainsequence/dashboards/streamlit/core/theme.py +212 -0
  25. mainsequence/dashboards/streamlit/pages/__init__.py +0 -0
  26. mainsequence/dashboards/streamlit/scaffold.py +220 -0
  27. mainsequence/instrumentation/__init__.py +7 -0
  28. mainsequence/instrumentation/utils.py +101 -0
  29. mainsequence/instruments/__init__.py +1 -0
  30. mainsequence/instruments/data_interface/__init__.py +10 -0
  31. mainsequence/instruments/data_interface/data_interface.py +361 -0
  32. mainsequence/instruments/instruments/__init__.py +3 -0
  33. mainsequence/instruments/instruments/base_instrument.py +85 -0
  34. mainsequence/instruments/instruments/bond.py +447 -0
  35. mainsequence/instruments/instruments/european_option.py +74 -0
  36. mainsequence/instruments/instruments/interest_rate_swap.py +217 -0
  37. mainsequence/instruments/instruments/json_codec.py +585 -0
  38. mainsequence/instruments/instruments/knockout_fx_option.py +146 -0
  39. mainsequence/instruments/instruments/position.py +475 -0
  40. mainsequence/instruments/instruments/ql_fields.py +239 -0
  41. mainsequence/instruments/instruments/vanilla_fx_option.py +107 -0
  42. mainsequence/instruments/pricing_models/__init__.py +0 -0
  43. mainsequence/instruments/pricing_models/black_scholes.py +49 -0
  44. mainsequence/instruments/pricing_models/bond_pricer.py +182 -0
  45. mainsequence/instruments/pricing_models/fx_option_pricer.py +90 -0
  46. mainsequence/instruments/pricing_models/indices.py +350 -0
  47. mainsequence/instruments/pricing_models/knockout_fx_pricer.py +209 -0
  48. mainsequence/instruments/pricing_models/swap_pricer.py +502 -0
  49. mainsequence/instruments/settings.py +175 -0
  50. mainsequence/instruments/utils.py +29 -0
  51. mainsequence/logconf.py +284 -0
  52. mainsequence/reportbuilder/__init__.py +0 -0
  53. mainsequence/reportbuilder/__main__.py +0 -0
  54. mainsequence/reportbuilder/examples/ms_template_report.py +706 -0
  55. mainsequence/reportbuilder/model.py +713 -0
  56. mainsequence/reportbuilder/slide_templates.py +532 -0
  57. mainsequence/tdag/__init__.py +8 -0
  58. mainsequence/tdag/__main__.py +0 -0
  59. mainsequence/tdag/config.py +129 -0
  60. mainsequence/tdag/data_nodes/__init__.py +12 -0
  61. mainsequence/tdag/data_nodes/build_operations.py +751 -0
  62. mainsequence/tdag/data_nodes/data_nodes.py +1292 -0
  63. mainsequence/tdag/data_nodes/persist_managers.py +812 -0
  64. mainsequence/tdag/data_nodes/run_operations.py +543 -0
  65. mainsequence/tdag/data_nodes/utils.py +24 -0
  66. mainsequence/tdag/future_registry.py +25 -0
  67. mainsequence/tdag/utils.py +40 -0
  68. mainsequence/virtualfundbuilder/__init__.py +45 -0
  69. mainsequence/virtualfundbuilder/__main__.py +235 -0
  70. mainsequence/virtualfundbuilder/agent_interface.py +77 -0
  71. mainsequence/virtualfundbuilder/config_handling.py +86 -0
  72. mainsequence/virtualfundbuilder/contrib/__init__.py +0 -0
  73. mainsequence/virtualfundbuilder/contrib/apps/__init__.py +8 -0
  74. mainsequence/virtualfundbuilder/contrib/apps/etf_replicator_app.py +164 -0
  75. mainsequence/virtualfundbuilder/contrib/apps/generate_report.py +292 -0
  76. mainsequence/virtualfundbuilder/contrib/apps/load_external_portfolio.py +107 -0
  77. mainsequence/virtualfundbuilder/contrib/apps/news_app.py +437 -0
  78. mainsequence/virtualfundbuilder/contrib/apps/portfolio_report_app.py +91 -0
  79. mainsequence/virtualfundbuilder/contrib/apps/portfolio_table.py +95 -0
  80. mainsequence/virtualfundbuilder/contrib/apps/run_named_portfolio.py +45 -0
  81. mainsequence/virtualfundbuilder/contrib/apps/run_portfolio.py +40 -0
  82. mainsequence/virtualfundbuilder/contrib/apps/templates/base.html +147 -0
  83. mainsequence/virtualfundbuilder/contrib/apps/templates/report.html +77 -0
  84. mainsequence/virtualfundbuilder/contrib/data_nodes/__init__.py +5 -0
  85. mainsequence/virtualfundbuilder/contrib/data_nodes/external_weights.py +61 -0
  86. mainsequence/virtualfundbuilder/contrib/data_nodes/intraday_trend.py +149 -0
  87. mainsequence/virtualfundbuilder/contrib/data_nodes/market_cap.py +310 -0
  88. mainsequence/virtualfundbuilder/contrib/data_nodes/mock_signal.py +78 -0
  89. mainsequence/virtualfundbuilder/contrib/data_nodes/portfolio_replicator.py +269 -0
  90. mainsequence/virtualfundbuilder/contrib/prices/__init__.py +1 -0
  91. mainsequence/virtualfundbuilder/contrib/prices/data_nodes.py +810 -0
  92. mainsequence/virtualfundbuilder/contrib/prices/utils.py +11 -0
  93. mainsequence/virtualfundbuilder/contrib/rebalance_strategies/__init__.py +1 -0
  94. mainsequence/virtualfundbuilder/contrib/rebalance_strategies/rebalance_strategies.py +313 -0
  95. mainsequence/virtualfundbuilder/data_nodes.py +637 -0
  96. mainsequence/virtualfundbuilder/enums.py +23 -0
  97. mainsequence/virtualfundbuilder/models.py +282 -0
  98. mainsequence/virtualfundbuilder/notebook_handling.py +42 -0
  99. mainsequence/virtualfundbuilder/portfolio_interface.py +272 -0
  100. mainsequence/virtualfundbuilder/resource_factory/__init__.py +0 -0
  101. mainsequence/virtualfundbuilder/resource_factory/app_factory.py +170 -0
  102. mainsequence/virtualfundbuilder/resource_factory/base_factory.py +238 -0
  103. mainsequence/virtualfundbuilder/resource_factory/rebalance_factory.py +101 -0
  104. mainsequence/virtualfundbuilder/resource_factory/signal_factory.py +183 -0
  105. mainsequence/virtualfundbuilder/utils.py +381 -0
  106. mainsequence-2.0.0.dist-info/METADATA +105 -0
  107. mainsequence-2.0.0.dist-info/RECORD +110 -0
  108. mainsequence-2.0.0.dist-info/WHEEL +5 -0
  109. mainsequence-2.0.0.dist-info/licenses/LICENSE +40 -0
  110. mainsequence-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,381 @@
1
+ import copy
2
+ import enum
3
+ import inspect
4
+ import json
5
+ import logging
6
+ from typing import Optional, Union, get_origin, get_args
7
+
8
+ from pydantic.fields import PydanticUndefined, FieldInfo
9
+
10
+ import pandas as pd
11
+ from mainsequence.client import CONSTANTS, Asset
12
+ from mainsequence.tdag.data_nodes import DataNode
13
+ import numpy as np
14
+ from tqdm import tqdm
15
+ from numpy.linalg import LinAlgError
16
+ from numpy.typing import NDArray
17
+ from joblib import delayed, Parallel
18
+ from typing import Dict, Any, List, Tuple, Union, Optional
19
+ from datetime import datetime
20
+ import docstring_parser
21
+ from typing import Any, Dict, List, Union, get_type_hints
22
+ from enum import Enum
23
+ from pydantic import BaseModel
24
+ import yaml
25
+ from mainsequence.logconf import logger
26
+ import inspect
27
+ from typing import Any, Dict, List, Optional, Type, Union
28
+ from pydantic import BaseModel, Field, create_model
29
+
30
+ def get_vfb_logger():
31
+ global logger
32
+
33
+ # If the logger doesn't have any handlers, create it using the custom function
34
+ logger.bind(sub_application="virtualfundbuilder")
35
+ return logger
36
+
37
+ logger = get_vfb_logger()
38
+
39
+ # Symbol mapping for CoinGecko API
40
+ GECKO_SYMBOL_MAPPING = {
41
+ "ADA": "cardano",
42
+ "AVAX": "avalanche-2",
43
+ "BCH": "bitcoin-cash",
44
+ "DOT": "polkadot",
45
+ "LINK": "chainlink",
46
+ "LTC": "litecoin",
47
+ "MATIC": "matic-network",
48
+ "SOL": "solana",
49
+ "ATOM": "cosmos",
50
+ "BTC": "bitcoin",
51
+ "ETH": "ethereum"
52
+ }
53
+
54
+ # Small time delta for precision operations
55
+ TIMEDELTA = pd.Timedelta("5ms")
56
+
57
+ def runs_in_main_process() -> bool:
58
+ import multiprocessing
59
+ return multiprocessing.current_process().name == "MainProcess"
60
+
61
+ def reindex_df(df: pd.DataFrame, start_time: datetime, end_time: datetime, freq: str) -> pd.DataFrame:
62
+ """
63
+ Aligns two DataFrames on a new index based on a specified frequency, filling missing entries with the last known values.
64
+
65
+ Args:
66
+ df (pd.DataFrame): Reference DataFrame used to determine the new index range.
67
+ start_time (datetime): start of index
68
+ end_time (datetime): end of index
69
+ freq (str): Frequency string (e.g., '1T' for one minute) to define the interval of the new index.
70
+
71
+ Returns:
72
+ pd.DataFrame: The df_to_align DataFrame reindexed to match the new timeline and filled with forward filled values.
73
+ """
74
+ new_index = pd.date_range(start=start_time, end=end_time, freq=freq)
75
+ return df.reindex(new_index).ffill()
76
+
77
+ def convert_to_binance_frequency(freq: str) -> str:
78
+ """
79
+ Converts a generic frequency format to a format compatible with Binance API requirements.
80
+
81
+ Args:
82
+ freq (str): The generic frequency format (e.g., '1m', '1h').
83
+
84
+ Returns:
85
+ str: A frequency string adapted for Binance API (e.g., '1m', '1h').
86
+ """
87
+ frequency_mappings = {'min': 'm', 'h': 'h', 'd': 'd', 'w': 'w'} # TODO extend
88
+ for unit, binance_unit in frequency_mappings.items():
89
+ if freq.endswith(unit):
90
+ return freq[:-len(unit)] + binance_unit
91
+ raise NotImplementedError(f"Frequency of {freq} not supported")
92
+
93
+
94
+
95
+ def get_last_query_times_per_asset(
96
+ latest_value: datetime,
97
+ metadata: dict,
98
+ asset_list: List[Asset],
99
+ max_lookback_time: datetime,
100
+ current_time: datetime,
101
+ query_frequency: str
102
+ ) -> Dict[str, Optional[float]]:
103
+ """
104
+ Determines the last query times for each asset based on metadata, a specified lookback limit, and a query frequency.
105
+
106
+ Args:
107
+ latest_value (datetime|None): Timestamp of the last value in the database for each asset.
108
+ metadata (dict): Metadata containing previous query information for each coin.
109
+ asset_list (List[Asset]): List of asset objects to process.
110
+ max_lookback_time (datetime): Maximum historical lookback time allowed for the node.
111
+ current_time (datetime): Current time to consider for the calculations.
112
+ query_frequency (str): Query frequency as a pandas-parseable string to determine if new data needs fetching.
113
+
114
+ Returns:
115
+ Dict[str, Optional[float]]: A dictionary mapping asset IDs to their respective last query times expressed in UNIX timestamp.
116
+ """
117
+ if latest_value:
118
+ last_query_times_per_asset = metadata["sourcetableconfiguration"]["multi_index_stats"]["max_per_asset_symbol"]
119
+ else:
120
+ last_query_times_per_asset = {}
121
+
122
+ for asset in asset_list:
123
+ asset_id = asset.unique_identifier
124
+ if asset_id in last_query_times_per_asset:
125
+ asset_start_time = pd.to_datetime(last_query_times_per_asset[asset_id])
126
+ else:
127
+ asset_start_time = max_lookback_time
128
+
129
+ if asset_start_time >= (current_time - pd.Timedelta(query_frequency)):
130
+ logger.info(f"no new data for asset {asset.name} from {asset_start_time} to {current_time}")
131
+ last_query_times_per_asset[asset_id] = None
132
+ else:
133
+ last_query_times_per_asset[asset_id] = (asset_start_time + TIMEDELTA).timestamp()
134
+
135
+ return last_query_times_per_asset
136
+
137
+ def do_single_regression(xx: NDArray, XTX_inv_list: list, rolling_window: int, col_name: str, tmp_y: NDArray, XTX_inv_diag: list) -> pd.DataFrame:
138
+ """
139
+ Performs a single regression analysis on a sliding window of data points for a specific column.
140
+
141
+ Args:
142
+ xx (NDArray): An array of independent variable data with a sliding window applied.
143
+ XTX_inv_list (list): A list of precomputed inverse matrices of X.T @ X for each window.
144
+ rolling_window (int): The number of observations per window.
145
+ col_name (str): The name of the column being analyzed, used for labeling the output.
146
+ tmp_y (NDArray): The dependent variable data.
147
+ XTX_inv_diag (list): Diagonals of the precomputed inverse matrices, used for standard error calculation.
148
+
149
+ Returns:
150
+ pd.DataFrame: A DataFrame containing the regression results with coefficients, R-squared, and t-statistics.
151
+ """
152
+ mean_y = tmp_y.mean(axis=1).reshape(-1, 1)
153
+ SST = np.sum((tmp_y - mean_y) ** 2, axis=1)
154
+ precompute_y_ = {"SST": SST, "mean_y": mean_y}
155
+
156
+ results = []
157
+ for i in tqdm(range(xx.shape[0]), desc=f"building regression {col_name}"):
158
+ xxx = xx[i].reshape(rolling_window, xx[i].shape[-1])
159
+ tmpy_ = tmp_y[i]
160
+ x_mult = XTX_inv_list[i] @ (xxx.T)
161
+ coefs = (x_mult @ tmpy_.T)
162
+ y_estimates = (xxx @ coefs.reshape(-1, 1)).ravel()
163
+ residuals = tmpy_ - y_estimates
164
+ SSR = np.sum((y_estimates - precompute_y_["mean_y"][i]) ** 2)
165
+ rsquared = SSR / precompute_y_["SST"][i]
166
+ residuals_var = np.sum(residuals ** 2) / (rolling_window - coefs.shape[0] + 1)
167
+ standard_errors = np.sqrt(XTX_inv_diag[i] * residuals_var)
168
+ ts = coefs / standard_errors
169
+ results.append(dict(beta=coefs[0], intercept=coefs[1],
170
+ rsquared=rsquared, t_intercept=ts[1], t_beta=ts[0]
171
+ ))
172
+ results = pd.concat([pd.DataFrame(results)], keys=[col_name], axis=1)
173
+
174
+ return results
175
+
176
+ def build_rolling_regression_from_df(x: NDArray, y: NDArray, rolling_window: int, column_names: list, threads: int=5) -> pd.DataFrame:
177
+ """
178
+ Builds rolling regressions for multiple variables in parallel using a specified rolling window.
179
+
180
+ Args:
181
+ x (NDArray): An array of independent variables.
182
+ y (NDArray): An array of dependent variables.
183
+ rolling_window (int): The size of the rolling window for each regression.
184
+ column_names (list): Names of the dependent variables, used for labeling the output.
185
+ threads (int): Number of threads to use for parallel processing.
186
+
187
+ Returns:
188
+ pd.DataFrame: A DataFrame containing the regression results for all variables.
189
+ """
190
+ XX = np.concatenate([x.reshape(-1, 1), np.ones((x.shape[0], 1))], axis=1)
191
+ xx = np.lib.stride_tricks.sliding_window_view(XX, (rolling_window, XX.shape[1]))
192
+
193
+ XTX_inv_list, XTX_inv_diag = [], [] # pre multiplication of x before y and diagonal for standard errros
194
+
195
+ # precompute for x
196
+ for i in tqdm(range(xx.shape[0]), desc="building x precomputes"):
197
+ xxx = xx[i].reshape(rolling_window, xx[i].shape[-1])
198
+ try:
199
+ XTX_inv = np.linalg.inv(xxx.T @ xxx)
200
+ XTX_inv_list.append(XTX_inv)
201
+ XTX_inv_diag.append(np.diag(XTX_inv))
202
+ except LinAlgError as le:
203
+ XTX_inv_list.append(XTX_inv_list[-1] * np.nan)
204
+ XTX_inv_diag.append(XTX_inv_diag[-1] * np.nan)
205
+
206
+ y_views = {i: np.lib.stride_tricks.sliding_window_view(y[:, i], (rolling_window,)) for i in range(y.shape[1])}
207
+
208
+ work_details = dict(n_jobs=threads, prefer="threads")
209
+ reg_results = Parallel(**work_details)(
210
+ delayed(do_single_regression)(xx=xx, tmp_y=tmp_y, XTX_inv_list=XTX_inv_list,
211
+ rolling_window=rolling_window,
212
+ XTX_inv_diag=XTX_inv_diag, col_name=column_names[y_col]
213
+ ) for y_col, tmp_y in y_views.items())
214
+
215
+ reg_results = pd.concat(reg_results, axis=1)
216
+ reg_results.columns = reg_results.columns.swaplevel()
217
+ return reg_results
218
+
219
+
220
+ def parse_google_docstring(docstring):
221
+ parsed = docstring_parser.parse(docstring)
222
+ return {
223
+ "description": parsed.description,
224
+ "args_descriptions": {param.arg_name: param.description for param in parsed.params},
225
+ "returns": parsed.returns.description if parsed.returns else None,
226
+ "example": "\n".join([param.description for param in parsed.examples]),
227
+ "raises": {exc.type_name: exc.description for exc in parsed.raises}
228
+ }
229
+
230
+ def extract_code(output_string):
231
+ import re
232
+ # Use regex to find content between triple backticks
233
+ match = re.search(r'```[^\n]*\n(.*?)```', output_string, re.DOTALL)
234
+ if match:
235
+ code = match.group(1)
236
+ return code
237
+ else:
238
+ return ''
239
+
240
+
241
+ def _convert_unknown_to_string(obj):
242
+ """Converts unsupported/unknown types to strings."""
243
+ try:
244
+ return str(obj)
245
+ except Exception:
246
+ raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable")
247
+
248
+ def is_jupyter_environment():
249
+ try:
250
+ from IPython import get_ipython
251
+ return "ipykernel" in str(get_ipython())
252
+ except ImportError:
253
+ return False
254
+
255
+
256
+ def type_to_json_schema(py_type: Type, definitions: Dict[str, Any]) -> Dict[str, Any]:
257
+ """
258
+ Recursively converts a Python type annotation to a JSON schema dictionary.
259
+ Handles Pydantic models, Enums, Lists, Unions, and basic types.
260
+
261
+ Args:
262
+ py_type: The Python type to convert.
263
+ definitions: A dict to store schemas of nested models, used for $defs.
264
+
265
+ Returns:
266
+ A dictionary representing the JSON schema for the given type.
267
+ """
268
+ origin = get_origin(py_type)
269
+ args = get_args(py_type)
270
+
271
+ # Handle Optional[T] by making the inner type nullable
272
+ if origin is Union and len(args) == 2 and type(None) in args:
273
+ non_none_type = args[0] if args[1] is type(None) else args[1]
274
+ schema = type_to_json_schema(non_none_type, definitions)
275
+ # Add null type to anyOf or create a new anyOf
276
+ if "anyOf" in schema:
277
+ if not any(sub.get("type") == "null" for sub in schema["anyOf"]):
278
+ schema["anyOf"].append({"type": "null"})
279
+ else:
280
+ schema = {"anyOf": [schema, {"type": "null"}]}
281
+ return schema
282
+
283
+ if origin is Union:
284
+ return {"anyOf": [type_to_json_schema(arg, definitions) for arg in args]}
285
+ if origin in (list, List):
286
+ item_schema = type_to_json_schema(args[0], definitions) if args else {}
287
+ return {"type": "array", "items": item_schema}
288
+ if origin in (dict, Dict):
289
+ value_schema = type_to_json_schema(args[1], definitions) if len(args) > 1 else {}
290
+ return {"type": "object", "additionalProperties": value_schema}
291
+
292
+ # Handle Pydantic Models by creating a reference
293
+ if inspect.isclass(py_type) and issubclass(py_type, BaseModel):
294
+ model_name = py_type.__name__
295
+ if model_name not in definitions:
296
+ definitions[model_name] = {} # Placeholder to break recursion
297
+ model_schema = py_type.model_json_schema(ref_template="#/$defs/{model}")
298
+ if "$defs" in model_schema:
299
+ for def_name, def_schema in model_schema.pop("$defs").items():
300
+ if def_name not in definitions:
301
+ definitions[def_name] = def_schema
302
+ definitions[model_name] = model_schema
303
+ return {"$ref": f"#/$defs/{model_name}"}
304
+
305
+ # Handle Enums
306
+ if inspect.isclass(py_type) and issubclass(py_type, Enum):
307
+ return {"type": "string", "enum": [e.value for e in py_type]}
308
+
309
+ # Handle basic types
310
+ type_map = {str: "string", int: "integer", float: "number", bool: "boolean"}
311
+ if py_type in type_map:
312
+ return {"type": type_map[py_type]}
313
+ if py_type is Any:
314
+ return {} # Any type, no constraint
315
+
316
+ # Fallback for unknown types
317
+ return {"type": "string", "description": f"Unrecognized type: {getattr(py_type, '__name__', str(py_type))}"}
318
+
319
+
320
+ def create_schema_from_signature(func: callable) -> Dict[str, Any]:
321
+ """
322
+ Parses a function's signature (like __init__) and creates a JSON schema.
323
+
324
+ Args:
325
+ func: The function or method to parse.
326
+
327
+ Returns:
328
+ A dictionary representing the JSON schema of the function's signature.
329
+ """
330
+ try:
331
+ signature = inspect.signature(func)
332
+ type_hints = get_type_hints(func)
333
+ except (TypeError, NameError): # Handles cases where hints can't be resolved
334
+ return {}
335
+
336
+ parsed_doc = docstring_parser.parse(func.__doc__ or "")
337
+ arg_descriptions = {p.arg_name: p.description for p in parsed_doc.params}
338
+
339
+ properties = {}
340
+ required = []
341
+ definitions = {} # For nested models
342
+
343
+ for name, param in signature.parameters.items():
344
+ if name in ('self', 'cls', 'args', 'kwargs'):
345
+ continue
346
+
347
+ param_type = type_hints.get(name, Any)
348
+ prop_schema = type_to_json_schema(param_type, definitions)
349
+ prop_schema['title'] = name.replace('_', ' ').title()
350
+
351
+ if name in arg_descriptions:
352
+ prop_schema['description'] = arg_descriptions[name]
353
+
354
+ if param.default is inspect.Parameter.empty:
355
+ required.append(name)
356
+ else:
357
+ default_value = param.default
358
+ try:
359
+ # Ensure default is JSON serializable
360
+ json.dumps(default_value)
361
+ prop_schema['default'] = default_value
362
+ except TypeError:
363
+ if isinstance(default_value, Enum):
364
+ prop_schema['default'] = default_value.value
365
+ else:
366
+ # Fallback for non-serializable defaults
367
+ prop_schema['default'] = str(default_value)
368
+
369
+ properties[name] = prop_schema
370
+
371
+ schema = {
372
+ "title": getattr(func, '__name__', 'Schema'),
373
+ "type": "object",
374
+ "properties": properties,
375
+ }
376
+ if required:
377
+ schema["required"] = required
378
+ if definitions:
379
+ schema["$defs"] = definitions
380
+
381
+ return schema
@@ -0,0 +1,105 @@
1
+ Metadata-Version: 2.4
2
+ Name: mainsequence
3
+ Version: 2.0.0
4
+ Summary: Main Sequence SDK
5
+ Author-email: Main Sequence GmbH <dev@main-sequence.io>
6
+ License: MainSequence GmbH SDK License Agreement
7
+ This License Agreement (the "License") governs the use, modification, and distribution of the software provided by MainSequence GmbH (the "Licensor"). The software (the "Software") is provided to you under the terms of this License. By using the Software, you agree to the terms of this License.
8
+
9
+ TERMS AND CONDITIONS
10
+ 0. Definitions
11
+ "Personal Use": Use by an individual for personal purposes that are not connected to any business, organization, or commercial activity.
12
+ "Internal Use": Use within a business, organization, or other entity, provided it is not made accessible to third parties or used for commercial purposes.
13
+ "Commercial Use": Use of the Software in exchange for monetary or other compensation, including hosting, offering Software as a service, selling the Software, or using it in a product or service for sale.
14
+ "License Agreement": The legally binding agreement between the Licensor and the licensee (you), subject to the terms outlined in this License.
15
+ 1. Grant of License
16
+ 1.1 Personal and Internal Use
17
+ The Licensor grants you a limited, non-exclusive, non-transferable, revocable license to use and modify the Software for personal or internal use only, provided that such use is strictly subject to this License Agreement and continues only while the License Agreement remains in effect.
18
+ Upon termination of this License Agreement, all rights to use the Software for personal or internal purposes shall be immediately revoked, and you must cease all use of the Software.
19
+ 1.2 Modification
20
+ You are permitted to modify the Software solely for your own personal or internal use, subject to the restrictions outlined in this License Agreement.
21
+ You are not permitted to distribute, sublicense, or otherwise transfer modified or unmodified versions of the Software to any third party.
22
+ 1.3 Prohibited Redistribution
23
+ You may not redistribute, sublicense, sell, lease, rent, or otherwise transfer the Software, whether in its original form or as modified by you, to any third party.
24
+ Any attempt to distribute or transfer the Software in any way, without explicit permission from MainSequence GmbH, is strictly prohibited.
25
+ 2. Prohibition of Commercial Use
26
+ The Software may not be used for any commercial purposes without obtaining a separate commercial license from MainSequence GmbH.
27
+ Examples of prohibited commercial use include, but are not limited to:
28
+ Hosting or offering the Software as a service to others, either modified or unmodified.
29
+ Using the Software as part of a commercial product or service provided to customers for a fee.
30
+ Using the Software in any production environment that generates income, directly or indirectly, from its use.
31
+ 3. Termination
32
+ This License Agreement will automatically terminate if you fail to comply with any of its terms.
33
+ Upon termination of this License, you must immediately cease all use of the Software, destroy all copies (modified or unmodified), and remove the Software from any devices or systems on which it is installed.
34
+ MainSequence GmbH reserves the right to terminate this License at its discretion for any violation of its terms or for any other reason.
35
+ 4. Commercial License
36
+ If you wish to use the Software for commercial purposes, you must contact MainSequence GmbH to negotiate and obtain a separate commercial license. The terms of the commercial license, including any fees, will be negotiated separately from this License Agreement.
37
+ Without a valid commercial license, you are strictly prohibited from using the Software for any commercial activity.
38
+ 5. Disclaimer of Warranty
39
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL MAINSEQUENCE GMBH OR THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40
+
41
+ 6. Limitation of Liability
42
+ IN NO EVENT SHALL MAINSEQUENCE GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
43
+
44
+ 7. Governing Law
45
+ This License Agreement shall be governed by and construed in accordance with the laws of the jurisdiction where MainSequence GmbH is located, without regard to its conflict of law provisions.
46
+ Project-URL: Homepage, https://github.com/mainsequence-sdk/mainsequence-sdk
47
+ Project-URL: Issues, https://github.com/mainsequence-sdk/mainsequence-sdk/issues
48
+ Classifier: Programming Language :: Python :: 3
49
+ Classifier: Programming Language :: Python :: 3 :: Only
50
+ Classifier: License :: OSI Approved :: MIT License
51
+ Classifier: Operating System :: OS Independent
52
+ Requires-Python: >=3.10
53
+ Description-Content-Type: text/markdown
54
+ License-File: LICENSE
55
+ Requires-Dist: cloudpickle
56
+ Requires-Dist: cryptography
57
+ Requires-Dist: fire
58
+ Requires-Dist: google-auth
59
+ Requires-Dist: joblib
60
+ Requires-Dist: matplotlib
61
+ Requires-Dist: nbconvert
62
+ Requires-Dist: numexpr
63
+ Requires-Dist: opentelemetry-api
64
+ Requires-Dist: opentelemetry-exporter-otlp
65
+ Requires-Dist: opentelemetry-sdk
66
+ Requires-Dist: pandas
67
+ Requires-Dist: pandas-market-calendars
68
+ Requires-Dist: psutil
69
+ Requires-Dist: pyarrow
70
+ Requires-Dist: pydantic
71
+ Requires-Dist: python-binance
72
+ Requires-Dist: python-dotenv
73
+ Requires-Dist: python-logstash
74
+ Requires-Dist: pyyaml
75
+ Requires-Dist: s3fs
76
+ Requires-Dist: scikit-learn
77
+ Requires-Dist: scipy
78
+ Requires-Dist: structlog
79
+ Requires-Dist: tqdm
80
+ Requires-Dist: colorama
81
+ Requires-Dist: kaleido
82
+ Requires-Dist: newspaper3k
83
+ Requires-Dist: lxml-html-clean
84
+ Requires-Dist: docstring-parser
85
+ Requires-Dist: concurrent-log-handler
86
+ Requires-Dist: duckdb
87
+ Requires-Dist: plotly
88
+ Requires-Dist: typer
89
+ Requires-Dist: QuantLib
90
+ Provides-Extra: dev
91
+ Requires-Dist: mkdocs; extra == "dev"
92
+ Requires-Dist: mkdocs-material; extra == "dev"
93
+ Requires-Dist: mkdocs-gen-files; extra == "dev"
94
+ Requires-Dist: mkdocs-literate-nav; extra == "dev"
95
+ Requires-Dist: mkdocs-autorefs; extra == "dev"
96
+ Requires-Dist: mkdocstrings[python]; extra == "dev"
97
+ Requires-Dist: mkdocs-mermaid2-plugin; extra == "dev"
98
+ Requires-Dist: pymdown-extensions; extra == "dev"
99
+ Requires-Dist: pipdeptree; extra == "dev"
100
+ Requires-Dist: pytest; extra == "dev"
101
+ Requires-Dist: pytest-freezegun; extra == "dev"
102
+ Requires-Dist: twine; extra == "dev"
103
+ Dynamic: license-file
104
+
105
+ # Main Sequence Python SDK
@@ -0,0 +1,110 @@
1
+ mainsequence/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ mainsequence/__main__.py,sha256=1_gCQd-MlXQxAubgVdTDgmP2117UQmj5DvTI_PASZis,162
3
+ mainsequence/logconf.py,sha256=OLkhALon2uIDZSeGOwX3DneapkVqlwDjqJm96TRAhgA,10057
4
+ mainsequence/cli/__init__.py,sha256=TNxXsTPgb52OhakIda9wTRh91cqoBqgQRx5TxjzQQFU,21
5
+ mainsequence/cli/api.py,sha256=swUAVjJCr2xannssLcg6BrwbToPFNgqu1G0_kyVTLck,6155
6
+ mainsequence/cli/cli.py,sha256=fVc5k8g96LYDrah5334vDXeSGH8_lf6unMH0WSFtG34,16435
7
+ mainsequence/cli/config.py,sha256=HVTGfXaxlYE47VShvYuIo40Wdkxaf3xYM_y4FsI0mGg,2583
8
+ mainsequence/cli/ssh_utils.py,sha256=95CmZk2nIoJhNTCmifMEsE9QXJrXY3zvfxLQp3QpdiM,5088
9
+ mainsequence/client/__init__.py,sha256=CDlJtsh0L9Z29OVMBnZsQajKBa193Yy5TkqLoilkbZM,869
10
+ mainsequence/client/base.py,sha256=rQp4SPzR8y-sW7-EDBvVtd-jPxt78QQFo0LjekB8iD4,14972
11
+ mainsequence/client/models_helpers.py,sha256=QXu-EZK54ryszVbjREwb7qRrS2WPvn_voboptPTR6kM,4100
12
+ mainsequence/client/models_report_studio.py,sha256=mKu7k0STyUZMTzTK98w46t2b1jv8hVhDpmCzI4EeSnQ,13971
13
+ mainsequence/client/models_tdag.py,sha256=A9mjdpcXFWbxfb9B9gfqml3AK9Lxbc7ovFuofimHnwM,90328
14
+ mainsequence/client/models_vam.py,sha256=E78QsdDNszpgweVvGUY5QF3DDOtSjJNZeVXvast2BjU,72891
15
+ mainsequence/client/utils.py,sha256=4aLctRMmQdFtLzaI9b28ifP141pO-VAmiQ7wTdHpqGg,11665
16
+ mainsequence/client/data_sources_interfaces/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
+ mainsequence/client/data_sources_interfaces/duckdb.py,sha256=cOvq_241eU6jPUw3DqLQDBWOUt3cXkP9UaMWzLhSG0M,67207
18
+ mainsequence/client/data_sources_interfaces/timescale.py,sha256=y_-vnX2JPUnweuajmBSPQxirNAA7BeljuYfYiFrlKcU,20126
19
+ mainsequence/dashboards/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ mainsequence/dashboards/streamlit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ mainsequence/dashboards/streamlit/scaffold.py,sha256=oOhwHmzwgeDTDQgDwzPvTkWrkf_-KmI1ankOi7r5IUk,7532
22
+ mainsequence/dashboards/streamlit/assets/config.toml,sha256=GCsLTasaF9kJlRRY1SnXLY-X5PyzLkGG4LX48gefkcc,314
23
+ mainsequence/dashboards/streamlit/assets/favicon.png,sha256=-CHfKx6jfMlXb8TnFQh2BNIBiKeVFfxK7g9K9BaqX6I,347
24
+ mainsequence/dashboards/streamlit/assets/logo.png,sha256=20KBis07H579XnXi0vMNzcjFyaAfW0CmI_dOtj-UYc4,34970
25
+ mainsequence/dashboards/streamlit/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
+ mainsequence/dashboards/streamlit/core/theme.py,sha256=Gc2lIUDugogTSGgBLn6nL3PDJxhpsKgWGj6FP3f4huY,7977
27
+ mainsequence/dashboards/streamlit/pages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
+ mainsequence/instrumentation/__init__.py,sha256=qfHOseVGOW_WdoTgw7TWZYpF1REwf14eF9awxWcLtfI,154
29
+ mainsequence/instrumentation/utils.py,sha256=XgVg9FijubSy5qMNw0yCkl5TMD2n56TnT4Q58WfZXbw,3354
30
+ mainsequence/instruments/__init__.py,sha256=HBHAfuMwV0LOxhjk7z7CvvD5lT1x8gJSaujjoIBtlak,26
31
+ mainsequence/instruments/settings.py,sha256=kaQqp1USERxU-7zALEKysHinaNpmau06OWBdbcWNS9A,5670
32
+ mainsequence/instruments/utils.py,sha256=eiqaTfcq4iulSdEwgi1sMq8xAKK8ONl22a-FNItcbYk,698
33
+ mainsequence/instruments/data_interface/__init__.py,sha256=yfaifbYZmX0u7wmcf_27G0dUK3jEQrlFAEwSNLqrp24,370
34
+ mainsequence/instruments/data_interface/data_interface.py,sha256=iIU92GT9iLVacrMVeTvJMYvoY2f0GsMkWtpnyBsKsbk,14905
35
+ mainsequence/instruments/instruments/__init__.py,sha256=Xe1hCMsOGc3IyyfA90Xuv7pO9t8TctpM7fo-6hML9Cg,154
36
+ mainsequence/instruments/instruments/base_instrument.py,sha256=XQeZxDSGhZ_ZNut3867I_q3UvDvp9VZDW4VRzyyFe-A,3185
37
+ mainsequence/instruments/instruments/bond.py,sha256=tm1Xr-OX2kbAzEZin5qbFBPhWyrFNUjLf7aWVQ6FTzg,17432
38
+ mainsequence/instruments/instruments/european_option.py,sha256=amyl52DsgOSMDiMZn4CbmWA4QGfVn38ojVVMhdOLKXM,2760
39
+ mainsequence/instruments/instruments/interest_rate_swap.py,sha256=NQljSAk4DyxAiUsAU2053TnCrbwjTqGk56m16Tgeh3w,7815
40
+ mainsequence/instruments/instruments/json_codec.py,sha256=94sOEL2N7nPMUsleB3GD3FzwYy5sVYsgthvQ2g8u9gE,22070
41
+ mainsequence/instruments/instruments/knockout_fx_option.py,sha256=JuRdBOOjrlLazH_Q98jTfTv7tA1nvG4QZHDkTgGlAnw,6115
42
+ mainsequence/instruments/instruments/position.py,sha256=i8aYyPET1gipw7rgsJtZ4FZZ5EtFccu6DGI6yB_vKp8,19351
43
+ mainsequence/instruments/instruments/ql_fields.py,sha256=rMzq0FAaVRoYpgdRUW7tjGJq9SgtFr-4_P0hbIgdfTM,8952
44
+ mainsequence/instruments/instruments/vanilla_fx_option.py,sha256=CdSd2_4CaxUlB8tYSZEKTjdrKc0HeqZ8W-bY9sYI1lQ,4280
45
+ mainsequence/instruments/pricing_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
+ mainsequence/instruments/pricing_models/black_scholes.py,sha256=bs7fsgiDKRuBZo7fvemVdmUHN-NjC2v6XUjhPaLNC-4,1588
47
+ mainsequence/instruments/pricing_models/bond_pricer.py,sha256=JXBOsDonlLwYG3GyHGD7rV1cddCPot8ZgE1Th-tHiqY,6566
48
+ mainsequence/instruments/pricing_models/fx_option_pricer.py,sha256=cMRejaIo3ZEhKCS960C7lg8ejh3b9RqIfL3Hhj4LB0A,3292
49
+ mainsequence/instruments/pricing_models/indices.py,sha256=LYzjZWmZvwiv0Jlcr6f9v_Jy4HKvJd1BygQrtphWQH0,12437
50
+ mainsequence/instruments/pricing_models/knockout_fx_pricer.py,sha256=FrO1uRn63zktkm6LwfLKZf0vPn5x0NOCBIPfSPEIO9c,6772
51
+ mainsequence/instruments/pricing_models/swap_pricer.py,sha256=vQXL1pgWPS9EUu8xXDyrA6QZm-t7wH0Hx3GU3yl1HHw,17994
52
+ mainsequence/reportbuilder/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
+ mainsequence/reportbuilder/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
+ mainsequence/reportbuilder/model.py,sha256=GOdQnl4odk_eKu5BM5eV1FN6WmZcl_LGWd0E9DQfu1k,26741
55
+ mainsequence/reportbuilder/slide_templates.py,sha256=VCHtrWl0FJIGGyo3cdHUjMCQuuOzJ95kOFejh56beRk,17654
56
+ mainsequence/reportbuilder/examples/ms_template_report.py,sha256=pOfUcVqixmyWMArJvJ340L1SWaD3SAnXHTHcHFgVeok,39208
57
+ mainsequence/tdag/__init__.py,sha256=CFxObmFsuyq06hOSxpv0VceZgOuDC8ebm_u7evQW0Bs,210
58
+ mainsequence/tdag/__main__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
+ mainsequence/tdag/config.py,sha256=oscijihkIloNwOaqLubxQoB3H8JT5rBb2aU0yP_alYE,3824
60
+ mainsequence/tdag/future_registry.py,sha256=wWD_u9pFt2tP80ra22kkvQT3cNj-ELmocoeXE9UUTPM,732
61
+ mainsequence/tdag/utils.py,sha256=vxEBaz94ZC1lm-Nc1OZMvpPJLVDSI8lGYn-RozcuGbo,1025
62
+ mainsequence/tdag/data_nodes/__init__.py,sha256=nyNxBWGTE1aoNtZAMMTNnQP-mZ6aU0zcvnKcd0EeXrs,103
63
+ mainsequence/tdag/data_nodes/build_operations.py,sha256=23CruSozk1-FhAg6JLGVubiXKFyLe9qWv4dw1sltFxI,28348
64
+ mainsequence/tdag/data_nodes/data_nodes.py,sha256=4TTEs4Wpa_-mp0gq8zjps3sOv-bDxh4gu4cqhvazpdQ,51727
65
+ mainsequence/tdag/data_nodes/persist_managers.py,sha256=11NtBm-J0lhr6VHSD9R3eFadgrGEMTalFNRpNgrA_OA,33440
66
+ mainsequence/tdag/data_nodes/run_operations.py,sha256=Oy51i6kCJmKFiUmqHZBT3PwESfspi4SzUR-RNIk0_78,23428
67
+ mainsequence/tdag/data_nodes/utils.py,sha256=atFF14Gg_itQs1J8BrmVSJl8Us29qu7fdCooDqFvP78,613
68
+ mainsequence/virtualfundbuilder/__init__.py,sha256=sOqlMt1qteORAHc_PDjUI9gZY1Bh86nTAd_ZtxfuQcQ,1438
69
+ mainsequence/virtualfundbuilder/__main__.py,sha256=mdj8cQ1Zims8ZkX8TR4zVSCEzTtzPpaxInQmXY0WBYM,8873
70
+ mainsequence/virtualfundbuilder/agent_interface.py,sha256=1xUZCvP1XcHp9JZanIRAFBydAaP7uUoGH02B6kkTywo,2744
71
+ mainsequence/virtualfundbuilder/config_handling.py,sha256=pDQB7SIY2-Hqh1wRhcDa3bOAWAwCezbmRG6TwlzzRHQ,3982
72
+ mainsequence/virtualfundbuilder/data_nodes.py,sha256=NvazPj2UOsIlqz1yiuvgNORAO_FIUNxtRJH6nRU2vkk,27838
73
+ mainsequence/virtualfundbuilder/enums.py,sha256=aTNmhK9Syp0ZuhzfQ_-Hsdr_u53SQShUL84CD3kVgMA,544
74
+ mainsequence/virtualfundbuilder/models.py,sha256=eoRXICs2wcyCP2-64ki9VXyJicfFku9dG4xcAW1a7ko,11666
75
+ mainsequence/virtualfundbuilder/notebook_handling.py,sha256=R_iiqQvP8ReEEYxk6vCcgcUg6SjFBsU1oVpZk8jC3X0,1148
76
+ mainsequence/virtualfundbuilder/portfolio_interface.py,sha256=ejYXLDgxDQsIQWQjGcT7N9iXhArcmaSDg-Lnelw1o5U,12303
77
+ mainsequence/virtualfundbuilder/utils.py,sha256=XwWtout8EitwY-iD49zebgzSNHoACfxKXrh2-rjLs7M,15128
78
+ mainsequence/virtualfundbuilder/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
+ mainsequence/virtualfundbuilder/contrib/apps/__init__.py,sha256=oBt3cy1TxA87ZesCm9djRYEyGnRvAuNs3wVOYm1i4Kk,259
80
+ mainsequence/virtualfundbuilder/contrib/apps/etf_replicator_app.py,sha256=a9lR8un2av7rp-N-DT0eQjOvWglBUUKRgosfV7HO3dc,7960
81
+ mainsequence/virtualfundbuilder/contrib/apps/generate_report.py,sha256=Q5O63AUpQQEDJRSR3KvkpE6644l4FwQaVQKz8ZXpjwc,12891
82
+ mainsequence/virtualfundbuilder/contrib/apps/load_external_portfolio.py,sha256=flp0LQbCZHckZLPRi9RIWXjhP99gBaE0lNIROoitQ5Y,4544
83
+ mainsequence/virtualfundbuilder/contrib/apps/news_app.py,sha256=IaUMPQoCG5sMmPcwPbgdqMOh0mjyUeoANYjk1-L5W6o,20148
84
+ mainsequence/virtualfundbuilder/contrib/apps/portfolio_report_app.py,sha256=dFwx8Kea0K-Lo29O3cLdR-ldLX4pGviKtPmusARMEdQ,3672
85
+ mainsequence/virtualfundbuilder/contrib/apps/portfolio_table.py,sha256=oJxUnskf2bDJIGs09_r1TgDbU4xJYwYVh6r_eQNx8BM,4906
86
+ mainsequence/virtualfundbuilder/contrib/apps/run_named_portfolio.py,sha256=qu36aMC0VZhirfum-s0PJ8jASuY7VrA75kxI51AuXE4,1809
87
+ mainsequence/virtualfundbuilder/contrib/apps/run_portfolio.py,sha256=a6A23aiyRk0EBfRR3e_sKqhRARWHoQd7lGxjymdwUlk,1649
88
+ mainsequence/virtualfundbuilder/contrib/apps/templates/base.html,sha256=HvZKYEozva9xSn9R4rxevAAKJ0hzyGIB5aXhJu5Yzw8,3939
89
+ mainsequence/virtualfundbuilder/contrib/apps/templates/report.html,sha256=qt2GWAht9u0Ai9pvtYNXz0wz0Yp8l_8OM4KBRZx8bvU,2059
90
+ mainsequence/virtualfundbuilder/contrib/data_nodes/__init__.py,sha256=DJR8l7DaA7dzgajHr16LnvBSaee95vKsIC8fLI2Iza0,150
91
+ mainsequence/virtualfundbuilder/contrib/data_nodes/external_weights.py,sha256=-V8LPlm6SN37WeLiOnuwp7r5vRqPTA173Kwjc8obruE,2306
92
+ mainsequence/virtualfundbuilder/contrib/data_nodes/intraday_trend.py,sha256=q05M5Zuxnwdib5J1a4xE5v-xJoZ7NIRz-rOHsxb7y_U,6970
93
+ mainsequence/virtualfundbuilder/contrib/data_nodes/market_cap.py,sha256=LjfDMqW1-8di9Cn_Ic5q7hzzvHUbu1v60WyazLLBslk,16119
94
+ mainsequence/virtualfundbuilder/contrib/data_nodes/mock_signal.py,sha256=UtfrHo9bnHfO5aaXZXh8dVhP0CqjXe1WE-l9cdjLNKU,3447
95
+ mainsequence/virtualfundbuilder/contrib/data_nodes/portfolio_replicator.py,sha256=EitkOzOX_OpNZGInkfyybZNiyHxx9jGA1utu3GTIS4U,10321
96
+ mainsequence/virtualfundbuilder/contrib/prices/__init__.py,sha256=m27GuJPSzOYAhMuTo1xv3aBDigvSxufZ2HQANKbyaVA,58
97
+ mainsequence/virtualfundbuilder/contrib/prices/data_nodes.py,sha256=pFbrTxbrbnRB531-JJJn7CXqh7X8eu_c-3-Rek3b-nw,32228
98
+ mainsequence/virtualfundbuilder/contrib/prices/utils.py,sha256=Mg0Xjty4264N2wqwKX7DC_44_1vQi2xaOzp-EVJxIeg,358
99
+ mainsequence/virtualfundbuilder/contrib/rebalance_strategies/__init__.py,sha256=qeRNqy36lPrzzthnIbZ3X7q-1KPuAfr-amnA6Bo46RE,35
100
+ mainsequence/virtualfundbuilder/contrib/rebalance_strategies/rebalance_strategies.py,sha256=C0sleZsFVzl26iw_l07zkkdBTp5k9gokIWCZvxLMxl0,14493
101
+ mainsequence/virtualfundbuilder/resource_factory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
102
+ mainsequence/virtualfundbuilder/resource_factory/app_factory.py,sha256=XSZo9ImdTRmLy81BuBLKOlVwfmr2wI0CpZO-2dHuRUU,6342
103
+ mainsequence/virtualfundbuilder/resource_factory/base_factory.py,sha256=jPXdK2WCaNw3r6kP3sZGIL7M4ygfIMs8ek3Yq4QYQZg,9434
104
+ mainsequence/virtualfundbuilder/resource_factory/rebalance_factory.py,sha256=ysEeJrlbxrMPA7wFw7KDtuCTzXYkdfYZuxUFpPPY7vE,3732
105
+ mainsequence/virtualfundbuilder/resource_factory/signal_factory.py,sha256=ywa7vxxLlQopuRwwRKyj866ftgaj8uKVoiPQ9YJ2IIo,7198
106
+ mainsequence-2.0.0.dist-info/licenses/LICENSE,sha256=fXoCKgEuZXmP84_QDXpvO18QHze_6AAhd-zvZBUjJxQ,4524
107
+ mainsequence-2.0.0.dist-info/METADATA,sha256=O4KBwTZAqaMbCFQziJjeZmFBChDu8ODCTaqN0bitQcw,6979
108
+ mainsequence-2.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
109
+ mainsequence-2.0.0.dist-info/top_level.txt,sha256=uSLD9rXMDMN0cc1x0p808bwyQMoRmYY2pdQZEWLajX8,13
110
+ mainsequence-2.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,40 @@
1
+ MainSequence GmbH SDK License Agreement
2
+ This License Agreement (the "License") governs the use, modification, and distribution of the software provided by MainSequence GmbH (the "Licensor"). The software (the "Software") is provided to you under the terms of this License. By using the Software, you agree to the terms of this License.
3
+
4
+ TERMS AND CONDITIONS
5
+ 0. Definitions
6
+ "Personal Use": Use by an individual for personal purposes that are not connected to any business, organization, or commercial activity.
7
+ "Internal Use": Use within a business, organization, or other entity, provided it is not made accessible to third parties or used for commercial purposes.
8
+ "Commercial Use": Use of the Software in exchange for monetary or other compensation, including hosting, offering Software as a service, selling the Software, or using it in a product or service for sale.
9
+ "License Agreement": The legally binding agreement between the Licensor and the licensee (you), subject to the terms outlined in this License.
10
+ 1. Grant of License
11
+ 1.1 Personal and Internal Use
12
+ The Licensor grants you a limited, non-exclusive, non-transferable, revocable license to use and modify the Software for personal or internal use only, provided that such use is strictly subject to this License Agreement and continues only while the License Agreement remains in effect.
13
+ Upon termination of this License Agreement, all rights to use the Software for personal or internal purposes shall be immediately revoked, and you must cease all use of the Software.
14
+ 1.2 Modification
15
+ You are permitted to modify the Software solely for your own personal or internal use, subject to the restrictions outlined in this License Agreement.
16
+ You are not permitted to distribute, sublicense, or otherwise transfer modified or unmodified versions of the Software to any third party.
17
+ 1.3 Prohibited Redistribution
18
+ You may not redistribute, sublicense, sell, lease, rent, or otherwise transfer the Software, whether in its original form or as modified by you, to any third party.
19
+ Any attempt to distribute or transfer the Software in any way, without explicit permission from MainSequence GmbH, is strictly prohibited.
20
+ 2. Prohibition of Commercial Use
21
+ The Software may not be used for any commercial purposes without obtaining a separate commercial license from MainSequence GmbH.
22
+ Examples of prohibited commercial use include, but are not limited to:
23
+ Hosting or offering the Software as a service to others, either modified or unmodified.
24
+ Using the Software as part of a commercial product or service provided to customers for a fee.
25
+ Using the Software in any production environment that generates income, directly or indirectly, from its use.
26
+ 3. Termination
27
+ This License Agreement will automatically terminate if you fail to comply with any of its terms.
28
+ Upon termination of this License, you must immediately cease all use of the Software, destroy all copies (modified or unmodified), and remove the Software from any devices or systems on which it is installed.
29
+ MainSequence GmbH reserves the right to terminate this License at its discretion for any violation of its terms or for any other reason.
30
+ 4. Commercial License
31
+ If you wish to use the Software for commercial purposes, you must contact MainSequence GmbH to negotiate and obtain a separate commercial license. The terms of the commercial license, including any fees, will be negotiated separately from this License Agreement.
32
+ Without a valid commercial license, you are strictly prohibited from using the Software for any commercial activity.
33
+ 5. Disclaimer of Warranty
34
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL MAINSEQUENCE GMBH OR THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
+
36
+ 6. Limitation of Liability
37
+ IN NO EVENT SHALL MAINSEQUENCE GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
38
+
39
+ 7. Governing Law
40
+ This License Agreement shall be governed by and construed in accordance with the laws of the jurisdiction where MainSequence GmbH is located, without regard to its conflict of law provisions.
@@ -0,0 +1 @@
1
+ mainsequence