dtscore 2.7.2__tar.gz → 2.7.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. {dtscore-2.7.2/src/dtscore.egg-info → dtscore-2.7.4}/PKG-INFO +1 -1
  2. {dtscore-2.7.2 → dtscore-2.7.4}/pyproject.toml +1 -1
  3. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/hxloader/indicators.py +18 -31
  4. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/hxloader/loader.py +44 -24
  5. {dtscore-2.7.2 → dtscore-2.7.4/src/dtscore.egg-info}/PKG-INFO +1 -1
  6. {dtscore-2.7.2 → dtscore-2.7.4}/tests/test_hxl.py +3 -2
  7. {dtscore-2.7.2 → dtscore-2.7.4}/LICENSE +0 -0
  8. {dtscore-2.7.2 → dtscore-2.7.4}/README.md +0 -0
  9. {dtscore-2.7.2 → dtscore-2.7.4}/setup.cfg +0 -0
  10. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/__init__.py +0 -0
  11. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/consoleutils.py +0 -0
  12. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/csvnames.py +0 -0
  13. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/dataframenames.py +0 -0
  14. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/domain.py +0 -0
  15. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/events.py +0 -0
  16. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/fileutils.py +0 -0
  17. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/globals.py +0 -0
  18. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/hxloader/__init__.py +0 -0
  19. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/__init__.py +0 -0
  20. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/account_summary_tags.py +0 -0
  21. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/client.py +0 -0
  22. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/comm.py +0 -0
  23. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/commission_report.py +0 -0
  24. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/common.py +0 -0
  25. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/connection.py +0 -0
  26. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/const.py +0 -0
  27. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/contract.py +0 -0
  28. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/decoder.py +0 -0
  29. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/enum_implem.py +0 -0
  30. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/errors.py +0 -0
  31. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/execution.py +0 -0
  32. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/ineligibility_reason.py +0 -0
  33. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/message.py +0 -0
  34. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/news.py +0 -0
  35. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/object_implem.py +0 -0
  36. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/order.py +0 -0
  37. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/order_cancel.py +0 -0
  38. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/order_condition.py +0 -0
  39. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/order_state.py +0 -0
  40. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/orderdecoder.py +0 -0
  41. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/reader.py +0 -0
  42. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/scanner.py +0 -0
  43. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/server_versions.py +0 -0
  44. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/softdollartier.py +0 -0
  45. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/tag_value.py +0 -0
  46. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/ticktype.py +0 -0
  47. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/utils.py +0 -0
  48. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/ibapi/wrapper.py +0 -0
  49. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/logging.py +0 -0
  50. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/queuemanager.py +0 -0
  51. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/schema_enums.py +0 -0
  52. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/tiingo.py +0 -0
  53. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/tws.py +0 -0
  54. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore/utils.py +0 -0
  55. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore.egg-info/SOURCES.txt +0 -0
  56. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore.egg-info/dependency_links.txt +0 -0
  57. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore.egg-info/requires.txt +0 -0
  58. {dtscore-2.7.2 → dtscore-2.7.4}/src/dtscore.egg-info/top_level.txt +0 -0
  59. {dtscore-2.7.2 → dtscore-2.7.4}/tests/test.py +0 -0
  60. {dtscore-2.7.2 → dtscore-2.7.4}/tests/test2.py +0 -0
  61. {dtscore-2.7.2 → dtscore-2.7.4}/tests/test_ib.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dtscore
3
- Version: 2.7.2
3
+ Version: 2.7.4
4
4
  Summary: DTS Core Services
5
5
  Author-email: "D. Smith" <dgsmith.hpot@gmail.com>
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dtscore"
7
- version = "2.7.2"
7
+ version = "2.7.4"
8
8
  authors = [
9
9
  { name="D. Smith", email="dgsmith.hpot@gmail.com" },
10
10
  ]
@@ -10,55 +10,49 @@ import stock_indicators as si
10
10
  from dtscore import logging as _log
11
11
 
12
12
  DEFAULT_ROUNDTO = 5
13
- DEFAULT_DROP_NANS = True
14
13
 
15
14
  CandlePart = si.CandlePart
16
15
 
17
16
  _roundif_float = lambda v,rt: round(v, rt) if isinstance(v,float) else v
18
17
 
19
- def _finalize_result(df:pd.DataFrame, result:pd.DataFrame, drop_nans:bool) -> pd.DataFrame:
20
- final = _concat_result(df, result)
21
- return final.dropna() if drop_nans else final
22
-
23
18
  def macd(
24
19
  df:pd.DataFrame, fast_periods:int=12, slow_periods:int=26, signal_periods:int=9,
25
- candle_part:si.CandlePart=si.CandlePart.CLOSE, roundto:int=DEFAULT_ROUNDTO, drop_nans:bool=DEFAULT_DROP_NANS,) -> pd.DataFrame:
20
+ candle_part:si.CandlePart=si.CandlePart.CLOSE, roundto:int=DEFAULT_ROUNDTO) -> pd.DataFrame:
26
21
  macds = si.indicators.macd.get_macd(_to_quotes(df), fast_periods, slow_periods, signal_periods, candle_part)
27
22
  for m in macds: m.macd = _roundif_float(m.macd,roundto)
28
23
  df_result = pd.DataFrame([[m.date.date(), m.macd] for m in macds], columns=['Date','MACD'])
29
- return _finalize_result(df, df_result, drop_nans)
24
+ return _concat_result(df, df_result)
30
25
 
31
- def obv(df:pd.DataFrame, sma_periods:int|None=None, roundto:int=DEFAULT_ROUNDTO, drop_nans:bool=DEFAULT_DROP_NANS) -> pd.DataFrame:
26
+ def obv(df:pd.DataFrame, sma_periods:int|None=None, roundto:int=DEFAULT_ROUNDTO) -> pd.DataFrame:
32
27
  obvs = si.indicators.obv.get_obv(_to_quotes(df), sma_periods=sma_periods)
33
28
  for o in obvs: o.obv = _roundif_float(o.obv, roundto)
34
29
  df_result = pd.DataFrame([[o.date.date(), o.obv] for o in obvs], columns=['Date','OBV'])
35
- return _finalize_result(df, df_result, drop_nans)
30
+ return _concat_result(df, df_result)
36
31
 
37
- def adline(df:pd.DataFrame, sma_periods:int|None=None, roundto:int=DEFAULT_ROUNDTO, drop_nans:bool=DEFAULT_DROP_NANS) -> pd.DataFrame:
32
+ def adline(df:pd.DataFrame, sma_periods:int|None=None, roundto:int=DEFAULT_ROUNDTO) -> pd.DataFrame:
38
33
  adlines = si.indicators.adl.get_adl(_to_quotes(df), sma_periods=sma_periods)
39
34
  for a in adlines: a.adl = _roundif_float(a.adl, roundto)
40
35
  df_result = pd.DataFrame([[adl.date.date(), adl.adl] for adl in adlines], columns=['Date','ADL'])
41
- return _finalize_result(df, df_result, drop_nans)
36
+ return _concat_result(df, df_result)
42
37
 
43
- def adx(df:pd.DataFrame, lookback_periods:int=14, roundto:int=DEFAULT_ROUNDTO, drop_nans:bool=DEFAULT_DROP_NANS) -> pd.DataFrame:
38
+ def adx(df:pd.DataFrame, lookback_periods:int=14, roundto:int=DEFAULT_ROUNDTO) -> pd.DataFrame:
44
39
  adxs = si.indicators.adx.get_adx(_to_quotes(df), lookback_periods=lookback_periods)
45
40
  for a in adxs: a.adx = _roundif_float(a.adx, roundto)
46
41
  df_result = pd.DataFrame([[adx.date.date(), adx.adx] for adx in adxs], columns=['Date','ADX'])
47
- return _finalize_result(df, df_result, drop_nans)
42
+ return _concat_result(df, df_result)
48
43
 
49
- def rsi(df:pd.DataFrame, lookback_periods:int=14, roundto:int=DEFAULT_ROUNDTO, drop_nans:bool=DEFAULT_DROP_NANS) -> pd.DataFrame:
44
+ def rsi(df:pd.DataFrame, lookback_periods:int=14, roundto:int=DEFAULT_ROUNDTO) -> pd.DataFrame:
50
45
  rsis = si.indicators.rsi.get_rsi(_to_quotes(df), lookback_periods=lookback_periods)
51
46
  for r in rsis: r.rsi = _roundif_float(r.rsi, roundto)
52
47
  df_result = pd.DataFrame([[rsi.date.date(), rsi.rsi] for rsi in rsis], columns=['Date','RSI'])
53
- return _finalize_result(df, df_result, drop_nans)
48
+ return _concat_result(df, df_result)
54
49
 
55
50
  def sma(df:pd.DataFrame, lookback_periods:list[int]|None=None, candle_part:si.CandlePart=si.CandlePart.CLOSE,
56
- roundto:int=DEFAULT_ROUNDTO, drop_nans:bool=DEFAULT_DROP_NANS) -> pd.DataFrame:
51
+ roundto:int=DEFAULT_ROUNDTO) -> pd.DataFrame:
57
52
  def _gen_sma(quotes, period:int, candle_part:si.CandlePart, roundto:int) -> pd.DataFrame:
58
53
  smas = si.indicators.sma.get_sma(quotes, lookback_periods=period, candle_part=candle_part)
59
54
  for m in smas: m.sma = _roundif_float(m.sma, roundto)
60
- df_result = pd.DataFrame([[ma.date.date(), ma.sma] for ma in smas], columns=['Date',f'SMA_{period}'])
61
- return df_result
55
+ return pd.DataFrame([[ma.date.date(), ma.sma] for ma in smas], columns=['Date',f'SMA_{period}'])
62
56
 
63
57
  if lookback_periods is None: lookback_periods = [50, 200]
64
58
  quotes = _to_quotes(df)
@@ -68,16 +62,15 @@ def sma(df:pd.DataFrame, lookback_periods:list[int]|None=None, candle_part:si.Ca
68
62
  for period in lookback_periods
69
63
  ]
70
64
  df_result = pd.concat(smas, axis=1).reset_index()
71
- return _finalize_result(df, df_result, drop_nans)
65
+ return _concat_result(df, df_result)
72
66
 
73
67
  def ema(df:pd.DataFrame, lookback_periods:list[int]|None=None, candle_part:si.CandlePart=si.CandlePart.CLOSE,
74
- roundto:int=DEFAULT_ROUNDTO, drop_nans:bool=DEFAULT_DROP_NANS) -> pd.DataFrame:
68
+ roundto:int=DEFAULT_ROUNDTO) -> pd.DataFrame:
75
69
  # generate ema for a single symbol
76
70
  def _gen_ema(quotes:list[si.Quote], period:int, candle_part:si.CandlePart, roundto:int) -> pd.DataFrame:
77
71
  emas = si.indicators.ema.get_ema(quotes, lookback_periods=period, candle_part=candle_part)
78
72
  for e in emas: e.ema = _roundif_float(e.ema, roundto)
79
- df_result = pd.DataFrame([[ea.date.date(), ea.ema] for ea in emas], columns=['Date', f'EMA_{period}'])
80
- return df_result
73
+ return pd.DataFrame([[ea.date.date(), ea.ema] for ea in emas], columns=['Date', f'EMA_{period}'])
81
74
 
82
75
  if lookback_periods is None: lookback_periods =[50, 200]
83
76
  quotes = _to_quotes(df)
@@ -86,10 +79,9 @@ def ema(df:pd.DataFrame, lookback_periods:list[int]|None=None, candle_part:si.Ca
86
79
  for period in lookback_periods
87
80
  ]
88
81
  df_result = pd.concat(emas, axis=1).reset_index()
89
- return _finalize_result(df, df_result, drop_nans)
82
+ return _concat_result(df, df_result)
90
83
 
91
- def bollbands(df:pd.DataFrame, lookback_periods:int=20, standard_deviations:float=2.0,
92
- roundto:int=DEFAULT_ROUNDTO, drop_nans:bool=DEFAULT_DROP_NANS) -> pd.DataFrame:
84
+ def bollbands(df:pd.DataFrame, lookback_periods:int=20, standard_deviations:float=2.0, roundto:int=DEFAULT_ROUNDTO) -> pd.DataFrame:
93
85
  bbs = si.indicators.get_bollinger_bands(_to_quotes(df), lookback_periods=lookback_periods, standard_deviations=standard_deviations)
94
86
  values = [[bb.date, bb.sma, bb.upper_band, bb.lower_band, bb.percent_b, bb.z_score, bb.width] for bb in bbs ]
95
87
  values = [ [_roundif_float(v,roundto) for v in item] for item in values ]
@@ -97,7 +89,7 @@ def bollbands(df:pd.DataFrame, lookback_periods:int=20, standard_deviations:floa
97
89
  data=values,
98
90
  columns=['Date', f'BB_SMA_{lookback_periods}','UPPER_BAND','LOWER_BAND','PERCENT_B','Z_SCORE','WIDTH']
99
91
  )
100
- return _finalize_result(df, df_result, drop_nans)
92
+ return _concat_result(df, df_result)
101
93
 
102
94
  def _to_quotes(df:pd.DataFrame) -> list[si.Quote]:
103
95
  return [
@@ -105,11 +97,6 @@ def _to_quotes(df:pd.DataFrame) -> list[si.Quote]:
105
97
  for d,o,h,l,c,v
106
98
  in zip(df['Date'], df['Open'], df['High'], df['Low'], df['Close'], df['Volume'])
107
99
  ]
108
- # records = df.to_dict('records')
109
- # return [
110
- # si.Quote(date=q['Date'], open=q['Open'], high=q['High'], low=q['Low'],
111
- # close=q['Close'], volume=q['Volume']) for q in records
112
- # ]
113
100
 
114
101
  def _concat_result(df:pd.DataFrame, indicators:pd.DataFrame) -> pd.DataFrame:
115
102
  df = df.set_index('Date')
@@ -50,10 +50,10 @@ class HxDataset:
50
50
  data = pd.DataFrame(q_list, columns=all_cols)
51
51
  return HxDataset(symbol, dates, data)
52
52
 
53
- def __len__(self):
53
+ def __len__(self) -> int:
54
54
  return len(self.data)
55
55
 
56
- def __getitem__(self, index:list[str]):
56
+ def __getitem__(self, index:list[str]) -> type[Self]:
57
57
  return HxDataset(self.symbol, self.dates, self.data[index])
58
58
 
59
59
  def to_csvfile(self, folder:str) -> type[Self]:
@@ -84,45 +84,65 @@ class HxDataset:
84
84
  return HxDataset(self.symbol, self.dates, df)
85
85
 
86
86
  def add_macd(self,fast_periods:int=12, slow_periods:int=26, signal_periods:int=9,
87
- candle_part:ind.CandlePart=ind.CandlePart.CLOSE, roundto:int=ind.DEFAULT_ROUNDTO,
88
- drop_nans:bool=ind.DEFAULT_DROP_NANS,) -> type[Self]:
87
+ candle_part:ind.CandlePart=ind.CandlePart.CLOSE, roundto:int=ind.DEFAULT_ROUNDTO) -> type[Self]:
88
+ """Generate the macd indicator
89
+
90
+ Args:
91
+ fast_periods (int): fast period
92
+ slow_periods (int): slow period
93
+ signal_perids (int): signal periods
94
+ candle_part (ind.CandlePart): candle part
95
+ roundto (float): precision of float point results
96
+ """
89
97
  df = ind.macd(self.data, fast_periods=fast_periods, slow_periods=slow_periods,
90
- signal_periods=signal_periods, candle_part=candle_part, roundto=roundto, drop_nans=drop_nans)
98
+ signal_periods=signal_periods, candle_part=candle_part, roundto=roundto)
91
99
  return HxDataset(symbol=self.symbol, dates=self.dates, data=df)
92
100
 
93
- def add_obv(self, sma_periods:int|None=None, roundto:int=ind.DEFAULT_ROUNDTO,
94
- drop_nans:bool=ind.DEFAULT_DROP_NANS,) -> type[Self]:
95
- df = ind.obv(self.data, sma_periods=sma_periods, roundto=roundto, drop_nans=drop_nans)
101
+ def add_obv(self, sma_periods:int|None=None, roundto:int=ind.DEFAULT_ROUNDTO) -> type[Self]:
102
+ """Generate the on balance volume indicator.
103
+
104
+ Args:
105
+ sma_periods (int|None): sma_periods
106
+ roundto (int):
107
+ """
108
+ df = ind.obv(self.data, sma_periods=sma_periods, roundto=roundto)
96
109
  return HxDataset(symbol=self.symbol, dates=self.dates, data=df)
97
110
 
98
- def add_adline(self, sma_periods:int|None=None, roundto:int=ind.DEFAULT_ROUNDTO,
99
- drop_nans:bool=ind.DEFAULT_DROP_NANS,) -> type[Self]:
100
- df = ind.adline(self.df, sma_periods=sma_periods, roundto=roundto, drop_nans=drop_nans)
111
+ def add_adline(self, sma_periods:int|None=None, roundto:int=ind.DEFAULT_ROUNDTO) -> type[Self]:
112
+ """Generate the adline indicator."""
113
+ df = ind.adline(self.data, sma_periods=sma_periods, roundto=roundto)
101
114
  return HxDataset(symbol=self.symbol, dates=self.dates, data=df)
102
115
 
103
- def add_adx(self, lookback_periods:int=14, roundto:int=ind.DEFAULT_ROUNDTO,
104
- drop_nans:bool=ind.DEFAULT_DROP_NANS,) -> type[Self]:
105
- df = ind.adx(self.data, lookback_periods=lookback_periods, roundto=roundto, drop_nans=drop_nans)
116
+ def add_adx(self, lookback_periods:int=14, roundto:int=ind.DEFAULT_ROUNDTO) -> type[Self]:
117
+ """Generate the adx indicator."""
118
+ df = ind.adx(self.data, lookback_periods=lookback_periods, roundto=roundto)
106
119
  return HxDataset(symbol=self.symbol, dates=self.dates, data=df)
107
120
 
108
- def add_rsi(self, lookback_periods:int=14, roundto:int=ind.DEFAULT_ROUNDTO,
109
- drop_nans:bool=ind.DEFAULT_DROP_NANS,) -> type[Self]:
110
- df = ind.rsi(self.data, lookback_periods=lookback_periods, roundto=roundto, drop_nans=drop_nans)
121
+ def add_rsi(self, lookback_periods:int=14, roundto:int=ind.DEFAULT_ROUNDTO) -> type[Self]:
122
+ """Generate the rsi indicator."""
123
+ df = ind.rsi(self.data, lookback_periods=lookback_periods, roundto=roundto)
111
124
  return HxDataset(symbol=self.symbol, dates=self.dates, data=df)
112
125
 
113
126
  def add_sma(self, lookback_periods:list[int], candle_part:ind.CandlePart=ind.CandlePart.CLOSE,
114
- roundto:int=ind.DEFAULT_ROUNDTO, drop_nans:bool=ind.DEFAULT_DROP_NANS) -> type[Self]:
115
- df = ind.sma(self.data, lookback_periods=lookback_periods, candle_part=candle_part, roundto=roundto, drop_nans=drop_nans)
127
+ roundto:int=ind.DEFAULT_ROUNDTO) -> type[Self]:
128
+ """Generate one or more simple moving averages."""
129
+ df = ind.sma(self.data, lookback_periods=lookback_periods, candle_part=candle_part, roundto=roundto)
116
130
  return HxDataset(symbol=self.symbol, dates=self.dates, data=df)
117
131
 
118
132
  def add_ema(self, lookback_periods:list[int], candle_part:ind.CandlePart=ind.CandlePart.CLOSE,
119
- roundto:int=ind.DEFAULT_ROUNDTO, drop_nans:bool=ind.DEFAULT_DROP_NANS,) -> type[Self]:
120
- df = ind.ema(self.data, lookback_periods=lookback_periods, candle_part=candle_part, roundto=roundto, drop_nans=drop_nans)
133
+ roundto:int=ind.DEFAULT_ROUNDTO) -> type[Self]:
134
+ """Generate one or more exponential moving averages."""
135
+ df = ind.ema(self.data, lookback_periods=lookback_periods, candle_part=candle_part, roundto=roundto)
121
136
  return HxDataset(symbol=self.symbol, dates=self.dates, data=df)
122
137
 
123
- def add_boll(self, lookback_periods:int=20, standard_deviations:float=2.0) -> type[Self]:
124
- df = ind.bollbands(self.data, lookback_periods=lookback_periods, standard_deviations=standard_deviations)
125
- return HxDataset(symbol=self.symbol, dates=self.dates, data=df)
138
+ def add_boll(self, lookback_periods:int=20, standard_deviations:float=2.0, roundto:int=ind.DEFAULT_ROUNDTO) -> type[Self]:
139
+ """Generate Bollinger bands."""
140
+ df = ind.bollbands(self.data, lookback_periods=lookback_periods, standard_deviations=standard_deviations, roundto=roundto)
141
+ return HxDataset(symbol=self.symbol, dates=self.dates, data=df)
142
+
143
+ def dropna(self,) -> type[Self]:
144
+ """Drop missing or non-numeric values."""
145
+ return HxDataset(symbol=self.symbol, dates=self.dates, data=self.data.copy().dropna())
126
146
 
127
147
 
128
148
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dtscore
3
- Version: 2.7.2
3
+ Version: 2.7.4
4
4
  Summary: DTS Core Services
5
5
  Author-email: "D. Smith" <dgsmith.hpot@gmail.com>
6
6
  Classifier: Development Status :: 5 - Production/Stable
@@ -17,9 +17,10 @@ def main():
17
17
  data = [
18
18
  ldr.HxDataset.download(symbol,dates) \
19
19
  .keep_and_rename_cols(keep_cols) \
20
- .add_sma(lookback_periods=[5,15,50,200], drop_nans=False) \
21
- .add_ema(lookback_periods=[5,15],drop_nans=False) \
20
+ .add_sma(lookback_periods=[5,15,50,200]) \
21
+ .add_ema(lookback_periods=[5,15]) \
22
22
  .add_boll(lookback_periods=5, standard_deviations=2.0) \
23
+ .dropna() \
23
24
  for symbol in symbols
24
25
  ]
25
26
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes