siglab-py 0.5.12__py3-none-any.whl → 0.5.15__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.

Potentially problematic release.


This version of siglab-py might be problematic. Click here for more details.

@@ -30,6 +30,7 @@ API
30
30
  stock basic info https://openapi.futunn.com/futu-api-doc/en/quote/get-static-info.html
31
31
  historical candles https://openapi.futunn.com/futu-api-doc/en/quote/request-history-kline.html
32
32
  realtime candles https://openapi.futunn.com/futu-api-doc/en/quote/get-kl.html
33
+ orderbook https://openapi.futunn.com/futu-api-doc/en/quote/get-order-book.html
33
34
  real time quote https://openapi.futunn.com/futu-api-doc/en/quote/get-stock-quote.html
34
35
  open orders https://openapi.futunn.com/futu-api-doc/en/trade/get-order-list.html
35
36
  historical orders https://openapi.futunn.com/futu-api-doc/en/trade/get-history-order-list.html
@@ -21,6 +21,9 @@ Usage:
21
21
 
22
22
  python futu_candles_ta_to_csv.py --symbol AAPL --end_date "2025-03-11 0:0:0" --start_date "2024-03-11 0:0:0" --market US --trdmarket US --security_firm FUTUSECURITIES --security_type STOCK --compute_ta Y --pypy_compatible N
23
23
 
24
+ Gold contracts? Note, symbol is case sensitive with Futu.
25
+ python futu_candles_ta_to_csv.py --symbol US.GCmain --end_date "2025-03-11 0:0:0" --start_date "2021-03-11 0:0:0" --market US --trdmarket FUTURES --security_firm FUTUSECURITIES --security_type FUTURE --compute_ta Y --pypy_compatible N
26
+
24
27
  (Remember: python -mpip install siglab_py)
25
28
 
26
29
  This script is pypy compatible. Set "pypy_compatible" to True, in which case "compute_candles_stats" will skip calculation for TAs which requires: scipy, statsmodels, scikit-learn, sklearn.preprocessing
@@ -50,7 +50,7 @@ class AnalyticUtilTests(unittest.TestCase):
50
50
  'is_green', 'pct_change_close',
51
51
  'sma_short_periods', 'sma_long_periods', 'ema_short_periods', 'ema_long_periods', 'ema_close',
52
52
  'std', 'std_percent',
53
- 'normalized_close_short', 'normalized_close_long',
53
+ 'vwap_short_periods', 'vwap_long_periods',
54
54
  'candle_height_percent', 'candle_height_percent_rounded',
55
55
  'log_return', 'interval_hist_vol', 'annualized_hist_vol',
56
56
  'chop_against_ema',
@@ -61,7 +61,9 @@ class AnalyticUtilTests(unittest.TestCase):
61
61
  'boillenger_upper', 'boillenger_lower', 'boillenger_channel_height', 'boillenger_upper_agg', 'boillenger_lower_agg', 'boillenger_channel_height_agg',
62
62
  'aggressive_up', 'aggressive_up_index', 'aggressive_up_candle_height', 'aggressive_up_candle_high', 'aggressive_up_candle_low', 'aggressive_down', 'aggressive_down_index', 'aggressive_down_candle_height', 'aggressive_down_candle_high', 'aggressive_down_candle_low',
63
63
  'fvg_low', 'fvg_high', 'fvg_gap', 'fvg_mitigated',
64
- 'close_delta', 'close_delta_percent', 'up', 'down', 'rsi', 'ema_rsi', 'typical_price',
64
+ 'close_delta', 'close_delta_percent', 'up', 'down',
65
+ 'rsi', 'ema_rsi', 'rsi_max', 'rsi_idmax', 'rsi_min', 'rsi_idmin', 'rsi_trend',
66
+ 'typical_price',
65
67
  'money_flow', 'money_flow_positive', 'money_flow_negative', 'positive_flow_sum', 'negative_flow_sum', 'money_flow_ratio', 'mfi',
66
68
  'macd', 'signal', 'macd_minus_signal',
67
69
  'fib_618_short_periods', 'fib_618_long_periods',
@@ -13,7 +13,7 @@ Have a look at this for a visual explaination how "Gradually tightened stops" wo
13
13
 
14
14
  # @unittest.skip("Skip all integration tests.")
15
15
  class TradingUtilTests(unittest.TestCase):
16
- def test_timestamp_to_active_trading_regions_case1(self):
16
+ def test_calc_eff_trailing_sl_case1(self):
17
17
  tp_min_percent : float = 1.5
18
18
  tp_max_percent : float = 2.5
19
19
  sl_percent_trailing : float = 50 # Trailing stop loss in percent
@@ -30,7 +30,7 @@ class TradingUtilTests(unittest.TestCase):
30
30
  )
31
31
  assert(effective_tp_trailing_percent==50) # Generous trailing SL when trading starting out and pnl small.
32
32
 
33
- def test_timestamp_to_active_trading_regions_case2(self):
33
+ def test_calc_eff_trailing_sl_case2(self):
34
34
  tp_min_percent : float = 1.5
35
35
  tp_max_percent : float = 2.5
36
36
  sl_percent_trailing : float = 50 # Trailing stop loss in percent
@@ -47,7 +47,7 @@ class TradingUtilTests(unittest.TestCase):
47
47
  )
48
48
  assert(effective_tp_trailing_percent==25) # Intermediate trailing SL
49
49
 
50
- def test_timestamp_to_active_trading_regions_case3(self):
50
+ def test_calc_eff_trailing_sl_case3(self):
51
51
  tp_min_percent : float = 1.5
52
52
  tp_max_percent : float = 2.5
53
53
  sl_percent_trailing : float = 50 # Trailing stop loss in percent
@@ -118,9 +118,11 @@ def compute_candles_stats(
118
118
  pd_candles['ema_long_periods'] = close_long_periods_ewm.mean()
119
119
  pd_candles['ema_close'] = pd_candles['ema_long_periods'] # Alias, shorter name
120
120
  pd_candles['std'] = close_long_periods_rolling.std()
121
-
122
121
  pd_candles['std_percent'] = pd_candles['std'] / pd_candles['ema_close'] * 100
123
122
 
123
+ pd_candles['vwap_short_periods'] = (pd_candles['close'] * pd_candles['volume']).rolling(window=int(sliding_window_how_many_candles/slow_fast_interval_ratio)).sum() / pd_candles['volume'].rolling(window=int(sliding_window_how_many_candles/slow_fast_interval_ratio)).sum()
124
+ pd_candles['vwap_long_periods'] = (pd_candles['close'] * pd_candles['volume']).rolling(window=sliding_window_how_many_candles).sum() / pd_candles['volume'].rolling(window=sliding_window_how_many_candles).sum()
125
+
124
126
  pd_candles['candle_height_percent'] = pd_candles['candle_height'] / pd_candles['ema_close'] * 100
125
127
  pd_candles['candle_height_percent_rounded'] = pd_candles['candle_height_percent'].round().astype('Int64')
126
128
 
@@ -360,6 +362,23 @@ def compute_candles_stats(
360
362
  span=rsi_sliding_window_how_many_candles if rsi_sliding_window_how_many_candles else sliding_window_how_many_candles,
361
363
  adjust=False).mean()
362
364
 
365
+ rsi_rolling = pd_candles['rsi'].rolling(window=int(rsi_sliding_window_how_many_candles if rsi_sliding_window_how_many_candles else sliding_window_how_many_candles))
366
+ pd_candles['rsi_max'] = rsi_rolling.max()
367
+ pd_candles['rsi_idmax'] = rsi_rolling.apply(lambda x : x.idxmax())
368
+ pd_candles['rsi_min'] = rsi_rolling.min()
369
+ pd_candles['rsi_idmin'] = rsi_rolling.apply(lambda x : x.idxmin())
370
+
371
+ def rsi_trend(
372
+ row,
373
+ rsi_upper_threshold : float = 70,
374
+ rsi_lower_threshold : float = 30):
375
+ if row['rsi_idmax'] > row['rsi_idmin']:
376
+ return 'DOWN' if row.name > row['rsi_idmax'] and row['rsi'] <= rsi_upper_threshold else 'up'
377
+ else:
378
+ return 'UP' if row.name > row['rsi_idmin'] and row['rsi'] >= rsi_lower_threshold else 'down'
379
+
380
+ pd_candles['rsi_trend'] = pd_candles.apply(lambda row: rsi_trend(row), axis=1)
381
+
363
382
 
364
383
  # MFI (Money Flow Index) https://randerson112358.medium.com/algorithmic-trading-strategy-using-money-flow-index-mfi-python-aa46461a5ea5
365
384
  pd_candles['typical_price'] = (pd_candles['high'] + pd_candles['low'] + pd_candles['close']) / 3
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: siglab-py
3
- Version: 0.5.12
3
+ Version: 0.5.15
4
4
  Summary: Market data fetches, TA calculations and generic order gateway.
5
5
  Author: r0bbarh00d
6
6
  Author-email: r0bbarh00d <r0bbarh00d@gmail.com>
@@ -2,14 +2,14 @@ siglab_py/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  siglab_py/constants.py,sha256=5isS_9WNoqpq9nC3ME5I5j7hJI9HAImij2bcgVVyWeY,275
3
3
  siglab_py/exchanges/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  siglab_py/exchanges/any_exchange.py,sha256=Y-zue75ZSmu9Ga1fONbjBGLNH5pDHQI01hCSjuLBkAk,889
5
- siglab_py/exchanges/futubull.py,sha256=6M99G8ZYsIyDyoTvvleMT_WPyNYbb6q-t2KXp0Qyi6g,20422
5
+ siglab_py/exchanges/futubull.py,sha256=f-_trzvuH5NaiG-PzyiNqZ12w7J-ARi_-xcr78rFU4E,20510
6
6
  siglab_py/market_data_providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  siglab_py/market_data_providers/aggregated_orderbook_provider.py,sha256=FZRobEBNRzcNGlOG3u38OVhmOZYlkNm8dVvR-S7Ii2g,23342
8
8
  siglab_py/market_data_providers/candles_provider.py,sha256=fqHJjlECsBiBlpgyywrc4gTgxiROPNzZM8KxQBB5cOg,14139
9
9
  siglab_py/market_data_providers/candles_ta_provider.py,sha256=uiAhbEZZdTF-YulBHpSLwabos5LHCKU91NTiTmpUc0w,12001
10
10
  siglab_py/market_data_providers/ccxt_candles_ta_to_csv.py,sha256=DHj51QTbkCmEd9RFNVhWWpsSPz1aLd6zTLqkUUbEkK0,11158
11
11
  siglab_py/market_data_providers/deribit_options_expiry_provider.py,sha256=e9Ee8TmC8pXaid8-jouSLKIpuW6_JBBgwRTieI665yQ,8684
12
- siglab_py/market_data_providers/futu_candles_ta_to_csv.py,sha256=S4GXaJ7AveEh-Cm9-VhENBdlj_1CfyBTrQO7acTqfUE,10226
12
+ siglab_py/market_data_providers/futu_candles_ta_to_csv.py,sha256=PZRpVL80CG6518uUg38Wb9aoWzidunyBAFFFGvrDnaI,10531
13
13
  siglab_py/market_data_providers/orderbooks_provider.py,sha256=olt-3LIkoyzQWfNNQRhJtKibLbkTutt_q_rCCTM7i1g,16216
14
14
  siglab_py/market_data_providers/test_provider.py,sha256=wBLCgcWjs7FGZJXWsNyn30lkOLa_cgpuvqRakMC0wbA,2221
15
15
  siglab_py/market_data_providers/tg_monitor.py,sha256=lRqONP0JAP223gyX37R-wCkhyGFKTvKkgmeDNoO3ay4,21813
@@ -22,18 +22,18 @@ siglab_py/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  siglab_py/tests/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
23
  siglab_py/tests/integration/market_data_util_tests.py,sha256=p-RWIJZLyj0lAdfi4QTIeAttCm_e8mEVWFKh4OWuogU,7189
24
24
  siglab_py/tests/unit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- siglab_py/tests/unit/analytic_util_tests.py,sha256=eeusM5zkQR2QyVhT7nqF0mwHVg7vlxwtgv2JnLqwQgY,3852
25
+ siglab_py/tests/unit/analytic_util_tests.py,sha256=4PPPgwvTCqgfgYV48j3vcJQM4w2ITUDBA0NE3doC_t8,3932
26
26
  siglab_py/tests/unit/market_data_util_tests.py,sha256=A1y83itISmMJdn6wLpfwcr4tGola8wTf1D1xbelMvgw,2026
27
- siglab_py/tests/unit/trading_util_tests.py,sha256=0dhqyzK4swCu7Q5DSXlUb4DrFJhS8iXvfr8Vwpa367s,3915
27
+ siglab_py/tests/unit/trading_util_tests.py,sha256=9DZmTZlW55lPtNfTCukgDdiyBiMYv9R4mEFWJIJiTNg,3870
28
28
  siglab_py/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
- siglab_py/util/analytic_util.py,sha256=blFJ1kY_aSJeuzzk28vdB4nhLgmosz0L8IJaJCZy9OM,47272
29
+ siglab_py/util/analytic_util.py,sha256=UGIpvnBuwy6z7l_YnGMSFFHSxTcH__MfljizvpK7Pbk,48674
30
30
  siglab_py/util/aws_util.py,sha256=KGmjHrr1rpnnxr33nXHNzTul4tvyyxl9p6gpwNv0Ygc,2557
31
31
  siglab_py/util/market_data_util.py,sha256=mUXg4uaiX3b6_klgJWIEgnUQU4IUd6CwTOqKLiQWRlU,31307
32
32
  siglab_py/util/notification_util.py,sha256=vySgHjpHgwFDLW0tHSi_AGh9JBbPc25IUgvWxmjAeT8,2658
33
33
  siglab_py/util/retry_util.py,sha256=g-UU6pkPouWZZRZEqP99R2Z0lX5xzckYkzjwqqSDpVQ,922
34
34
  siglab_py/util/slack_notification_util.py,sha256=G27n-adbT3Q6oaHSMvu_Nom794rrda5PprSF-zvmzkM,1912
35
35
  siglab_py/util/trading_util.py,sha256=-TGNgJdy4HMDPgq31KQn_lRawFxuXnFU5NnLRb1XM5o,5757
36
- siglab_py-0.5.12.dist-info/METADATA,sha256=QS0mtJr12ZWB60_OMOV6S5Q6GgFh7T4V38bREAUuZoc,980
37
- siglab_py-0.5.12.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
38
- siglab_py-0.5.12.dist-info/top_level.txt,sha256=AbD4VR9OqmMOGlMJLkAVPGQMtUPIQv0t1BF5xmcLJSk,10
39
- siglab_py-0.5.12.dist-info/RECORD,,
36
+ siglab_py-0.5.15.dist-info/METADATA,sha256=a36d3u762HvS-yyiGyq2BU92RXECAIE9ytLGw1yOy4Y,980
37
+ siglab_py-0.5.15.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
38
+ siglab_py-0.5.15.dist-info/top_level.txt,sha256=AbD4VR9OqmMOGlMJLkAVPGQMtUPIQv0t1BF5xmcLJSk,10
39
+ siglab_py-0.5.15.dist-info/RECORD,,