eetc-utils 1.2.0__tar.gz → 1.3.0__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.
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/PKG-INFO +1 -1
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/pyproject.toml +1 -1
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/clients/eetc_data.py +101 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/finance.py +1 -1
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/LICENSE +0 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/README.md +0 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/__init__.py +0 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/clients/__init__.py +0 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/clients/eetc_notifications.py +0 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/options.py +0 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/strategy/__init__.py +0 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/strategy/backtesting/__init__.py +0 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/strategy/backtesting/broker_sim.py +0 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/strategy/backtesting/engine.py +0 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/strategy/backtesting/metrics.py +0 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/strategy/backtesting/strategy.py +0 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/strategy/engine.py +0 -0
- {eetc_utils-1.2.0 → eetc_utils-1.3.0}/src/eetc_utils/strategy/strategy.py +0 -0
|
@@ -374,3 +374,104 @@ class EETCDataClient:
|
|
|
374
374
|
|
|
375
375
|
if response.status_code not in [200, 201]:
|
|
376
376
|
response.raise_for_status()
|
|
377
|
+
|
|
378
|
+
def get_roguetrader_signals(
|
|
379
|
+
self,
|
|
380
|
+
date: Optional[str] = None,
|
|
381
|
+
symbol: Optional[str] = None,
|
|
382
|
+
as_json: bool = False,
|
|
383
|
+
) -> Union[pd.DataFrame, List[Dict]]:
|
|
384
|
+
"""
|
|
385
|
+
Retrieve RogueTrader signals from the EETC Data Hub via the
|
|
386
|
+
`/roguetrader-signals` API.
|
|
387
|
+
|
|
388
|
+
This endpoint returns eetc-roguetrader generated signals data
|
|
389
|
+
with optional filtering. Filters can be combined to narrow
|
|
390
|
+
down results (e.g., by date and symbol).
|
|
391
|
+
|
|
392
|
+
:param date: Signal generation date in format "yyyy-mm-dd".
|
|
393
|
+
:param symbol: Ticker symbol of the instrument (e.g., "AAPL").
|
|
394
|
+
:param as_json: If True, returns raw JSON list; if False
|
|
395
|
+
(default), returns pandas DataFrame.
|
|
396
|
+
:return: RogueTrader signals data as pandas DataFrame (default)
|
|
397
|
+
or list of dicts (if as_json=True).
|
|
398
|
+
:raises requests.HTTPError: If the API request fails.
|
|
399
|
+
"""
|
|
400
|
+
|
|
401
|
+
url = f"{self.base_url}/roguetrader-signals/"
|
|
402
|
+
params = {
|
|
403
|
+
"date": date,
|
|
404
|
+
"symbol": symbol,
|
|
405
|
+
}
|
|
406
|
+
params = {k: v for k, v in params.items() if v is not None}
|
|
407
|
+
|
|
408
|
+
response = self._send_http_request(url, params)
|
|
409
|
+
data = response.json()
|
|
410
|
+
|
|
411
|
+
return data if as_json else pd.json_normalize(data)
|
|
412
|
+
|
|
413
|
+
def save_roguetrader_signals(self, signals: List[Dict[str, Any]]) -> None:
|
|
414
|
+
"""
|
|
415
|
+
Save one or multiple eetc-roguetrader signals to the EETC Data
|
|
416
|
+
Hub.
|
|
417
|
+
|
|
418
|
+
:param signals: List of signal dictionaries. Each signal should
|
|
419
|
+
contain:
|
|
420
|
+
- date (str): Signal generation date (e.g., "2024-01-15")
|
|
421
|
+
- symbol (str): Ticker symbol (e.g., "SPY")
|
|
422
|
+
- previous_close (float): Previous day's closing price
|
|
423
|
+
- open_price (float): Opening price
|
|
424
|
+
- open_gap (float): Gap percentage
|
|
425
|
+
- atm_strike (int): At-the-money strike price
|
|
426
|
+
- atm_iv (float): At-the-money implied volatility
|
|
427
|
+
- implied_daily_move_pct (float): Expected daily move %
|
|
428
|
+
- atm_greeks (dict): ATM option Greeks
|
|
429
|
+
- vix_previous_close (float): Previous VIX close
|
|
430
|
+
- vix_at_calculation (float): VIX at calculation time
|
|
431
|
+
- vix_change_pct (float): VIX change percentage
|
|
432
|
+
- signals (list): List of signal values
|
|
433
|
+
- aggregate_gex (float): Aggregate gamma exposure
|
|
434
|
+
- zero_gamma_level (float): Zero gamma price level
|
|
435
|
+
- gex_regime (str): GEX regime ("positive" or "negative")
|
|
436
|
+
- trading_allowed (bool): Whether trading is allowed
|
|
437
|
+
- halt_reason (str, optional): Reason for trading halt
|
|
438
|
+
|
|
439
|
+
Example:
|
|
440
|
+
>>> client.save_roguetrader_signals([{
|
|
441
|
+
... "date": "2024-01-15",
|
|
442
|
+
... "symbol": "SPY",
|
|
443
|
+
... "previous_close": 450.25,
|
|
444
|
+
... "open_price": 451.00,
|
|
445
|
+
... "open_gap": 0.17,
|
|
446
|
+
... "atm_strike": 450,
|
|
447
|
+
... "atm_iv": 0.15,
|
|
448
|
+
... "implied_daily_move_pct": 1.2,
|
|
449
|
+
... "atm_greeks": {"delta": 0.5, "gamma": 0.02},
|
|
450
|
+
... "vix_previous_close": 14.5,
|
|
451
|
+
... "vix_at_calculation": 15.2,
|
|
452
|
+
... "vix_change_pct": 4.83,
|
|
453
|
+
... "signals": [{"signal": 13.12}],
|
|
454
|
+
... "aggregate_gex": 1250000.0,
|
|
455
|
+
... "zero_gamma_level": 448.5,
|
|
456
|
+
... "gex_regime": "positive",
|
|
457
|
+
... "trading_allowed": True,
|
|
458
|
+
... "halt_reason": None
|
|
459
|
+
... }])
|
|
460
|
+
|
|
461
|
+
:raises requests.HTTPError: If the API request fails
|
|
462
|
+
(non-200/201 status).
|
|
463
|
+
"""
|
|
464
|
+
|
|
465
|
+
url = f"{self.base_url}/roguetrader-signals/"
|
|
466
|
+
|
|
467
|
+
response = requests.post(
|
|
468
|
+
url,
|
|
469
|
+
json=signals,
|
|
470
|
+
headers={
|
|
471
|
+
"Content-Type": "application/json",
|
|
472
|
+
"EETC-API-Key": self.api_key,
|
|
473
|
+
},
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
if response.status_code not in [200, 201]:
|
|
477
|
+
response.raise_for_status()
|
|
@@ -114,7 +114,7 @@ def calculate_optimal_leverage_kelly(
|
|
|
114
114
|
if use_garch:
|
|
115
115
|
# use GARCH function to get annualized volatility
|
|
116
116
|
annualized_volatility = garch_annualized_volatility(df)
|
|
117
|
-
annualized_variance = annualized_volatility
|
|
117
|
+
annualized_variance = annualized_volatility**2
|
|
118
118
|
else:
|
|
119
119
|
# simple historical variance
|
|
120
120
|
daily_variance = df["log_return"].var()
|
|
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
|