execute_python can load any data source
This commit is contained in:
@@ -29,6 +29,22 @@ def _get_indicator_registry():
|
||||
return _indicator_registry
|
||||
|
||||
|
||||
def _get_order_store():
|
||||
"""Get the global OrderStore instance."""
|
||||
registry = _get_registry()
|
||||
if registry and "OrderStore" in registry.entries:
|
||||
return registry.entries["OrderStore"].model
|
||||
return None
|
||||
|
||||
|
||||
def _get_chart_store():
|
||||
"""Get the global ChartStore instance."""
|
||||
registry = _get_registry()
|
||||
if registry and "ChartStore" in registry.entries:
|
||||
return registry.entries["ChartStore"].model
|
||||
return None
|
||||
|
||||
|
||||
async def _get_chart_data_impl(countback: Optional[int] = None):
|
||||
"""Internal implementation for getting chart data.
|
||||
|
||||
@@ -60,8 +76,13 @@ async def _get_chart_data_impl(countback: Optional[int] = None):
|
||||
start_time = chart_data.get("start_time")
|
||||
end_time = chart_data.get("end_time")
|
||||
|
||||
if not symbol:
|
||||
raise ValueError("No symbol set in ChartStore - user may not have loaded a chart yet")
|
||||
if not symbol or symbol is None:
|
||||
raise ValueError(
|
||||
"No chart visible - ChartStore symbol is None. "
|
||||
"The user is likely on a narrow screen (mobile) where charts are hidden. "
|
||||
"Let them know they can view charts on a wider screen, or use get_historical_data() "
|
||||
"if they specify a symbol and timeframe."
|
||||
)
|
||||
|
||||
# Parse the symbol to extract exchange/source and symbol name
|
||||
# Format is "EXCHANGE:SYMBOL" (e.g., "BINANCE:BTC/USDT", "DEMO:BTC/USD")
|
||||
@@ -142,6 +163,11 @@ async def get_chart_data(countback: Optional[int] = None) -> Dict[str, Any]:
|
||||
This is the preferred way to access chart data when helping the user analyze
|
||||
what they're looking at, since it automatically uses their current chart context.
|
||||
|
||||
**IMPORTANT**: This tool will fail if ChartStore.symbol is None (no chart visible).
|
||||
This happens when the user is on a narrow screen (mobile) where charts are hidden.
|
||||
In that case, let the user know charts are only visible on wider screens, or use
|
||||
get_historical_data() if they specify a symbol and timeframe.
|
||||
|
||||
Args:
|
||||
countback: Optional limit on number of bars to return. If not specified,
|
||||
returns all bars in the visible time range.
|
||||
@@ -157,7 +183,7 @@ async def get_chart_data(countback: Optional[int] = None) -> Dict[str, Any]:
|
||||
|
||||
Raises:
|
||||
ValueError: If ChartStore or DataSourceRegistry is not initialized,
|
||||
or if the symbol format is invalid
|
||||
if no chart is visible (symbol is None), or if the symbol format is invalid
|
||||
|
||||
Example:
|
||||
# User is viewing BINANCE:BTC/USDT on 15min chart
|
||||
@@ -191,12 +217,26 @@ async def execute_python(code: str, countback: Optional[int] = None) -> Dict[str
|
||||
- `talib` : TA-Lib technical analysis library
|
||||
- `indicator_registry`: 150+ registered indicators
|
||||
- `plot_ohlc(df)` : Helper function for beautiful candlestick charts
|
||||
- `registry` : SyncRegistry instance - access to all registered stores
|
||||
- `datasource_registry`: DataSourceRegistry - access to data sources (binance, etc.)
|
||||
- `order_store` : OrderStore instance - current orders list
|
||||
- `chart_store` : ChartStore instance - current chart state
|
||||
|
||||
Auto-loaded when user has a chart open:
|
||||
Auto-loaded when user has a chart visible (ChartStore.symbol is not None):
|
||||
- `df` : pandas DataFrame with DatetimeIndex and columns:
|
||||
open, high, low, close, volume (OHLCV data ready to use)
|
||||
- `chart_context` : dict with symbol, interval, start_time, end_time
|
||||
|
||||
When NO chart is visible (narrow screen/mobile):
|
||||
- `df` : None
|
||||
- `chart_context` : None
|
||||
|
||||
If `df` is None, you can still load alternative data by:
|
||||
- Using chart_store to see what symbol/timeframe is configured
|
||||
- Using datasource_registry.get_source('binance') to access data sources
|
||||
- Calling datasource.get_history(symbol, interval, start, end) to load any data
|
||||
- This allows you to make plots of ANY chart even when not connected to chart view
|
||||
|
||||
The `plot_ohlc()` Helper:
|
||||
Create professional candlestick charts instantly:
|
||||
- `plot_ohlc(df)` - basic OHLC chart with volume
|
||||
@@ -250,6 +290,41 @@ async def execute_python(code: str, countback: Optional[int] = None) -> Dict[str
|
||||
print("Recent swing highs:")
|
||||
print(swing_highs)
|
||||
\"\"\")
|
||||
|
||||
# Load alternative data when df is None or for different symbol/timeframe
|
||||
execute_python(\"\"\"
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# Get data source
|
||||
binance = datasource_registry.get_source('binance')
|
||||
|
||||
# Load ETH data even if viewing BTC chart
|
||||
end_time = datetime.now()
|
||||
start_time = end_time - timedelta(days=7)
|
||||
|
||||
result = await binance.get_history(
|
||||
symbol='ETH/USDT',
|
||||
interval='1h',
|
||||
start=int(start_time.timestamp()),
|
||||
end=int(end_time.timestamp())
|
||||
)
|
||||
|
||||
# Convert to DataFrame
|
||||
rows = [{'time': pd.to_datetime(bar.time, unit='s'), **bar.data} for bar in result.bars]
|
||||
eth_df = pd.DataFrame(rows).set_index('time')
|
||||
|
||||
# Calculate RSI and plot
|
||||
eth_df['RSI'] = talib.RSI(eth_df['close'], 14)
|
||||
fig = plot_ohlc(eth_df, title='ETH/USDT 1h - RSI Analysis')
|
||||
print(f"ETH RSI: {eth_df['RSI'].iloc[-1]:.2f}")
|
||||
\"\"\")
|
||||
|
||||
# Access chart store to see current state
|
||||
execute_python(\"\"\"
|
||||
print(f"Current symbol: {chart_store.chart_state.symbol}")
|
||||
print(f"Current interval: {chart_store.chart_state.interval}")
|
||||
print(f"Orders: {len(order_store.orders)}")
|
||||
\"\"\")
|
||||
"""
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
@@ -292,6 +367,10 @@ async def execute_python(code: str, countback: Optional[int] = None) -> Dict[str
|
||||
# --- Get indicator registry ---
|
||||
indicator_registry = _get_indicator_registry()
|
||||
|
||||
# --- Get DataStores ---
|
||||
order_store = _get_order_store()
|
||||
chart_store = _get_chart_store()
|
||||
|
||||
# --- Build globals ---
|
||||
script_globals: Dict[str, Any] = {
|
||||
'pd': pd,
|
||||
@@ -299,6 +378,10 @@ async def execute_python(code: str, countback: Optional[int] = None) -> Dict[str
|
||||
'plt': plt,
|
||||
'talib': talib,
|
||||
'indicator_registry': indicator_registry,
|
||||
'registry': registry,
|
||||
'datasource_registry': datasource_registry,
|
||||
'order_store': order_store,
|
||||
'chart_store': chart_store,
|
||||
'df': df,
|
||||
'chart_context': chart_context,
|
||||
'plot_ohlc': plot_ohlc,
|
||||
|
||||
Reference in New Issue
Block a user