quantmod 0.0.8__tar.gz → 0.0.9__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 (44) hide show
  1. {quantmod-0.0.8 → quantmod-0.0.9}/PKG-INFO +1 -1
  2. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/charts/plotting.py +95 -12
  3. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/models/__init__.py +2 -1
  4. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/risk/var.py +8 -6
  5. quantmod-0.0.9/quantmod/version.py +1 -0
  6. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod.egg-info/PKG-INFO +1 -1
  7. quantmod-0.0.8/quantmod/version.py +0 -1
  8. {quantmod-0.0.8 → quantmod-0.0.9}/LICENSE.txt +0 -0
  9. {quantmod-0.0.8 → quantmod-0.0.9}/README.md +0 -0
  10. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/__init__.py +0 -0
  11. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/_version.py +0 -0
  12. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/charts/__init__.py +0 -0
  13. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/charts/themes.py +0 -0
  14. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/datasets/__init__.py +0 -0
  15. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/datasets/data/nifty50.csv +0 -0
  16. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/datasets/data/spx.csv +0 -0
  17. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/datasets/dataloader.py +0 -0
  18. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/derivatives/__init__.py +0 -0
  19. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/derivatives/nse.py +0 -0
  20. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/indicators/__init__.py +0 -0
  21. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/indicators/indicators.py +0 -0
  22. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/main.py +0 -0
  23. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/markets/__init__.py +0 -0
  24. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/markets/bb.py +0 -0
  25. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/markets/yahoo.py +0 -0
  26. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/models/binomial.py +0 -0
  27. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/models/blackscholes.py +0 -0
  28. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/models/montecarlo.py +0 -0
  29. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/models/optioninputs.py +0 -0
  30. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/risk/__init__.py +0 -0
  31. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/risk/varbacktest.py +0 -0
  32. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/risk/varinputs.py +0 -0
  33. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/timeseries/__init__.py +0 -0
  34. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/timeseries/performance.py +0 -0
  35. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/timeseries/timeseries.py +0 -0
  36. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod/utils.py +0 -0
  37. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod.egg-info/SOURCES.txt +0 -0
  38. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod.egg-info/dependency_links.txt +0 -0
  39. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod.egg-info/entry_points.txt +0 -0
  40. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod.egg-info/not-zip-safe +0 -0
  41. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod.egg-info/requires.txt +0 -0
  42. {quantmod-0.0.8 → quantmod-0.0.9}/quantmod.egg-info/top_level.txt +0 -0
  43. {quantmod-0.0.8 → quantmod-0.0.9}/setup.cfg +0 -0
  44. {quantmod-0.0.8 → quantmod-0.0.9}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: quantmod
3
- Version: 0.0.8
3
+ Version: 0.0.9
4
4
  Summary: Quantmod Python Package
5
5
  Home-page: https://kannansingaravelu.com/
6
6
  Author: Kannan Singaravelu
@@ -29,6 +29,7 @@ Available Chart Types:
29
29
  - "treemap": Treemap chart
30
30
  - "overlay": Overlay multiple series with secondary y-axis
31
31
  - "normalized": Normalized line chart (base=100)
32
+ - "surface": Surface Plot
32
33
 
33
34
  """
34
35
 
@@ -62,6 +63,8 @@ def _iplot(self, kind="line", **kwargs):
62
63
  return _plot_normalized(self, **kwargs)
63
64
  if kind == "overlay":
64
65
  return _plot_overlay(self, **kwargs)
66
+ if kind == "surface":
67
+ return _plot_surface(self, **kwargs)
65
68
  if isinstance(self, pd.Series):
66
69
  df = self.to_frame()
67
70
  else:
@@ -92,6 +95,8 @@ def _iplot(self, kind="line", **kwargs):
92
95
  fig = _plot_pie(df, **kwargs)
93
96
  elif kind == "treemap":
94
97
  fig = _plot_treemap(df, **kwargs)
98
+ elif kind == "surface":
99
+ fig = _plot_surface(df, **kwargs)
95
100
  else:
96
101
  raise ValueError(f"Plot type '{kind}' not supported.")
97
102
 
@@ -126,10 +131,8 @@ def _plot_line(df, x=None, y=None, **kwargs):
126
131
  x_data = df.index if x is None else df[x]
127
132
  y_data = df[y] if isinstance(y, str) else df.iloc[:, 0]
128
133
 
129
- fig = go.Figure(
130
- go.Scatter(x=x_data, y=y_data, mode="lines", name="", **trace_kwargs)
131
- )
132
- _update_layout(fig, kwargs, default_title="Stock Prices", yaxis_title="")
134
+ fig = go.Figure(go.Scatter(x=x_data, y=y_data, mode="lines", **trace_kwargs))
135
+ _update_layout(fig, kwargs, default_title="Line Charts", yaxis_title="")
133
136
  return fig
134
137
 
135
138
 
@@ -153,9 +156,7 @@ def _plot_scatter(df, x=None, y=None, **kwargs):
153
156
  x_data = df.index if x is None else df[x]
154
157
  y_data = df[y] if isinstance(y, str) else df.iloc[:, 0]
155
158
 
156
- fig = go.Figure(
157
- go.Scatter(x=x_data, y=y_data, mode="markers", name="", **trace_kwargs)
158
- )
159
+ fig = go.Figure(go.Scatter(x=x_data, y=y_data, mode="markers", **trace_kwargs))
159
160
  _update_layout(fig, kwargs, default_title="Scatter Plot", yaxis_title="")
160
161
  return fig
161
162
 
@@ -344,18 +345,58 @@ def _plot_box(df, columns=None, **kwargs):
344
345
 
345
346
 
346
347
  def _plot_pie(df, names=None, values=None, **kwargs):
348
+ """
349
+ Plot a pie chart with options to filter only positive values, show only top N slices, and aggregate small values as 'Others'.
350
+
351
+ Parameters:
352
+ - top_n: int or None. If set, only the top N values are shown, the rest are aggregated as 'Others'.
353
+ - threshold: float or None. If set, all values below this fraction (e.g., 0.01 for 1%) of the total are aggregated as 'Others'.
354
+ """
347
355
  theme_name = kwargs.get("theme", DEFAULT_THEME)
348
356
  colors = _get_colors(theme_name)
349
357
 
350
- names_data = df.index if names is None else df[names]
351
- values_data = df.iloc[:, 0] if values is None else df[values]
358
+ # Extract top_n and threshold from kwargs
359
+ top_n = kwargs.pop("top_n", None)
360
+ threshold = kwargs.pop("threshold", None)
361
+
362
+ # For single-column DataFrame, use index and first column
363
+ names_data = df.index.to_list()
364
+ values_data = df.iloc[:, 0].to_list()
365
+
366
+ # Filter out non-positive values (negative and zero)
367
+ filtered = [(n, v) for n, v in zip(names_data, values_data) if v > 0]
368
+ if not filtered:
369
+ raise ValueError("No positive values to plot in pie chart.")
370
+ names_data, values_data = zip(*filtered)
371
+
372
+ # Convert to Series for easier manipulation
373
+ pie_series = pd.Series(values_data, index=names_data)
374
+ pie_series = pie_series.sort_values(ascending=False)
375
+
376
+ # Apply threshold: aggregate values below threshold as 'Others'
377
+ if threshold is not None:
378
+ total = pie_series.sum()
379
+ mask = pie_series / total < threshold
380
+ if mask.any():
381
+ others = pie_series[mask].sum()
382
+ pie_series = pie_series[~mask]
383
+ pie_series["Others"] = others
384
+
385
+ # Apply top_n: keep only top N, aggregate the rest as 'Others'
386
+ if top_n is not None and len(pie_series) > top_n:
387
+ top = pie_series.iloc[:top_n]
388
+ others = pie_series.iloc[top_n:].sum()
389
+ top["Others"] = others
390
+ pie_series = top
352
391
 
353
392
  fig = go.Figure(
354
393
  data=[
355
394
  go.Pie(
356
- labels=names_data,
357
- values=values_data,
358
- marker_colors=colors[: len(names_data)],
395
+ labels=pie_series.index,
396
+ values=pie_series.values,
397
+ marker_colors=colors[: len(pie_series)],
398
+ hole=0.4,
399
+ textinfo="label+percent",
359
400
  )
360
401
  ]
361
402
  )
@@ -441,6 +482,48 @@ def _plot_treemap(df, path=None, values=None, labels=None, parents=None, **kwarg
441
482
  return fig
442
483
 
443
484
 
485
+ def _plot_surface(df, x=None, y=None, z=None, **kwargs):
486
+ """
487
+ Plot a 3D surface plot using Plotly.
488
+ - x: Optional, column name or array for x-axis. If None, use df.columns.
489
+ - y: Optional, column name or array for y-axis. If None, use df.index.
490
+ - z: Optional, 2D array or DataFrame for z values. If None, use df.values.
491
+ - xaxis_title: Optional, string for x-axis title. Defaults to 'X'.
492
+ - yaxis_title: Optional, string for y-axis title. Defaults to 'Y'.
493
+ - zaxis_title: Optional, string for z-axis title. Defaults to 'Z'.
494
+ - title: Optional, string for plot title. Defaults to 'Surface Plot'.
495
+ """
496
+ theme_name = kwargs.get("theme", DEFAULT_THEME)
497
+ colorscale = kwargs.pop("colorscale", "Viridis")
498
+ xaxis_title = kwargs.pop("xaxis_title", "X")
499
+ yaxis_title = kwargs.pop("yaxis_title", "Y")
500
+ zaxis_title = kwargs.pop("zaxis_title", "Z")
501
+ # Don't pop title, just let it flow to _update_layout
502
+
503
+ # Prepare data
504
+ x_data = x if x is not None else df.columns
505
+ y_data = y if y is not None else df.index
506
+ z_data = z if z is not None else df.values
507
+
508
+ fig = go.Figure(
509
+ data=[
510
+ go.Surface(z=z_data, x=x_data, y=y_data, colorscale=colorscale)
511
+ ]
512
+ )
513
+ # For 3D plots, axis titles must be set via update_scenes
514
+ fig.update_scenes(
515
+ xaxis_title_text=xaxis_title,
516
+ yaxis_title_text=yaxis_title,
517
+ zaxis_title_text=zaxis_title
518
+ )
519
+ _update_layout(
520
+ fig,
521
+ kwargs, # Now kwargs no longer contains axis titles
522
+ default_title="Surface Plot"
523
+ )
524
+ return fig
525
+
526
+
444
527
  def _update_layout(fig, user_kwargs, default_title="", xaxis_title="", yaxis_title=""):
445
528
  theme_name = user_kwargs.pop("theme", DEFAULT_THEME)
446
529
  theme_layout = THEMES.get(theme_name, {}).get("layout", {})
@@ -18,7 +18,7 @@
18
18
 
19
19
  from .optioninputs import OptionInputs
20
20
  from .blackscholes import BlackScholesOptionPricing
21
- from .montecarlo import MonteCarloOptionPricing
21
+ from .montecarlo import BarrierType, MonteCarloOptionPricing
22
22
  from .binomial import OptionType, ExerciseStyle, BinomialOptionPricing
23
23
 
24
24
 
@@ -26,6 +26,7 @@ __all__ = [
26
26
  "OptionInputs",
27
27
  "OptionType",
28
28
  "ExerciseStyle",
29
+ "BarrierType",
29
30
  "BlackScholesOptionPricing",
30
31
  "MonteCarloOptionPricing",
31
32
  "BinomialOptionPricing",
@@ -45,12 +45,7 @@ class VaRMetrics:
45
45
  self.returns = inputs.portfolio_returns
46
46
  self.is_single_stock = inputs.is_single_stock
47
47
 
48
- # attributes
49
- self.parametric_var = self._parametric_var()
50
- self.historical_var = self._historical_var()
51
- self.monte_carlo_var = self._monte_carlo_var()
52
- self.expected_shortfall = self._expected_shortfall()
53
-
48
+ # Set weights before risk metric calculations
54
49
  if self.is_single_stock:
55
50
  self.weights = np.array([1.0]) # Single stock, full weight
56
51
  else:
@@ -59,9 +54,16 @@ class VaRMetrics:
59
54
  "Portfolio weights must be provided for portfolio VaR calculation"
60
55
  )
61
56
  self.weights = np.array(inputs.portfolio_weights)
57
+ # Only check shape for portfolio (2D returns)
62
58
  if len(self.weights) != self.returns.shape[1]:
63
59
  raise ValueError("Portfolio weights must match the number of assets")
64
60
 
61
+ # attributes
62
+ self.parametric_var = self._parametric_var()
63
+ self.historical_var = self._historical_var()
64
+ self.monte_carlo_var = self._monte_carlo_var()
65
+ self.expected_shortfall = self._expected_shortfall()
66
+
65
67
  def _parametric_var(self) -> float:
66
68
  mean_returns = np.mean(self.returns, axis=0)
67
69
  std = np.std(self.returns, axis=0)
@@ -0,0 +1 @@
1
+ version = "0.0.9"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: quantmod
3
- Version: 0.0.8
3
+ Version: 0.0.9
4
4
  Summary: Quantmod Python Package
5
5
  Home-page: https://kannansingaravelu.com/
6
6
  Author: Kannan Singaravelu
@@ -1 +0,0 @@
1
- version = "0.0.8"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes