use common williams market structure calcs
This commit is contained in:
@@ -19,16 +19,19 @@ import logging
|
||||
from datetime import datetime
|
||||
import json
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
# Import core components from main system
|
||||
try:
|
||||
from core.data_provider import DataProvider
|
||||
from core.orchestrator import TradingOrchestrator
|
||||
from core.config import get_config
|
||||
from core.williams_market_structure import WilliamsMarketStructure
|
||||
except ImportError as e:
|
||||
print(f"Warning: Could not import main system components: {e}")
|
||||
print("Running in standalone mode with limited functionality")
|
||||
DataProvider = None
|
||||
WilliamsMarketStructure = None
|
||||
TradingOrchestrator = None
|
||||
get_config = lambda: {}
|
||||
|
||||
@@ -200,66 +203,90 @@ class AnnotationDashboard:
|
||||
|
||||
def _get_pivot_markers_for_timeframe(self, symbol: str, timeframe: str, df: pd.DataFrame) -> dict:
|
||||
"""
|
||||
Get pivot markers for a specific timeframe
|
||||
Returns dict with indices mapping to pivot info for that candle
|
||||
Get pivot markers for a specific timeframe using WilliamsMarketStructure directly
|
||||
Returns dict with all pivot points and identifies which are the last high/low per level
|
||||
"""
|
||||
try:
|
||||
if not self.data_provider:
|
||||
if WilliamsMarketStructure is None:
|
||||
logger.warning("WilliamsMarketStructure not available")
|
||||
return {}
|
||||
|
||||
# Get Williams pivot levels for this timeframe
|
||||
pivot_levels = self.data_provider.get_williams_pivot_levels(
|
||||
symbol=symbol,
|
||||
base_timeframe=timeframe,
|
||||
limit=len(df)
|
||||
if df is None or len(df) < 10:
|
||||
logger.warning(f"Insufficient data for pivot calculation: {len(df) if df is not None else 0} bars")
|
||||
return {}
|
||||
|
||||
# Convert DataFrame to numpy array format expected by Williams Market Structure
|
||||
ohlcv_array = df[['open', 'high', 'low', 'close', 'volume']].copy()
|
||||
|
||||
# Add timestamp as first column (convert to milliseconds)
|
||||
timestamps = df.index.astype(np.int64) // 10**6 # pandas index is ns -> convert to ms
|
||||
ohlcv_array.insert(0, 'timestamp', timestamps)
|
||||
ohlcv_array = ohlcv_array.to_numpy()
|
||||
|
||||
# Initialize Williams Market Structure with default distance
|
||||
# We'll override it in the calculation call
|
||||
williams = WilliamsMarketStructure(min_pivot_distance=1)
|
||||
|
||||
# Calculate recursive pivot points with min_pivot_distance=2
|
||||
# This ensures 5 candles per pivot (tip + 2 prev + 2 next)
|
||||
pivot_levels = williams.calculate_recursive_pivot_points(
|
||||
ohlcv_array,
|
||||
min_pivot_distance=2
|
||||
)
|
||||
|
||||
if not pivot_levels:
|
||||
logger.debug(f"No pivot levels found for {symbol} {timeframe}")
|
||||
return {}
|
||||
|
||||
# Build a map of timestamp -> pivot info
|
||||
# Also track last high/low per level for drawing horizontal lines
|
||||
pivot_map = {}
|
||||
last_pivots = {} # {level: {'high': (ts_str, idx), 'low': (ts_str, idx)}}
|
||||
|
||||
# For each level (1-5), find the last high and last low pivot
|
||||
# For each level (1-5), collect ALL pivot points
|
||||
for level_num, trend_level in pivot_levels.items():
|
||||
if not hasattr(trend_level, 'pivot_points') or not trend_level.pivot_points:
|
||||
continue
|
||||
|
||||
# Find last high and last low for this level
|
||||
last_high = None
|
||||
last_low = None
|
||||
last_pivots[level_num] = {'high': None, 'low': None}
|
||||
|
||||
# Add ALL pivot points to the map
|
||||
for pivot in trend_level.pivot_points:
|
||||
ts_str = pivot.timestamp.strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
if ts_str not in pivot_map:
|
||||
pivot_map[ts_str] = {'highs': [], 'lows': []}
|
||||
|
||||
pivot_info = {
|
||||
'level': level_num,
|
||||
'price': pivot.price,
|
||||
'strength': pivot.strength,
|
||||
'is_last': False # Will be updated below
|
||||
}
|
||||
|
||||
if pivot.pivot_type == 'high':
|
||||
last_high = pivot
|
||||
pivot_map[ts_str]['highs'].append(pivot_info)
|
||||
last_pivots[level_num]['high'] = (ts_str, len(pivot_map[ts_str]['highs']) - 1)
|
||||
elif pivot.pivot_type == 'low':
|
||||
last_low = pivot
|
||||
|
||||
# Add to pivot map
|
||||
if last_high:
|
||||
ts_str = last_high.timestamp.strftime('%Y-%m-%d %H:%M:%S')
|
||||
if ts_str not in pivot_map:
|
||||
pivot_map[ts_str] = {'highs': [], 'lows': []}
|
||||
pivot_map[ts_str]['highs'].append({
|
||||
'level': level_num,
|
||||
'price': last_high.price,
|
||||
'strength': last_high.strength
|
||||
})
|
||||
|
||||
if last_low:
|
||||
ts_str = last_low.timestamp.strftime('%Y-%m-%d %H:%M:%S')
|
||||
if ts_str not in pivot_map:
|
||||
pivot_map[ts_str] = {'highs': [], 'lows': []}
|
||||
pivot_map[ts_str]['lows'].append({
|
||||
'level': level_num,
|
||||
'price': last_low.price,
|
||||
'strength': last_low.strength
|
||||
})
|
||||
pivot_map[ts_str]['lows'].append(pivot_info)
|
||||
last_pivots[level_num]['low'] = (ts_str, len(pivot_map[ts_str]['lows']) - 1)
|
||||
|
||||
# Mark the last high and last low for each level
|
||||
for level_num, last_info in last_pivots.items():
|
||||
if last_info['high']:
|
||||
ts_str, idx = last_info['high']
|
||||
pivot_map[ts_str]['highs'][idx]['is_last'] = True
|
||||
if last_info['low']:
|
||||
ts_str, idx = last_info['low']
|
||||
pivot_map[ts_str]['lows'][idx]['is_last'] = True
|
||||
|
||||
logger.info(f"Found {len(pivot_map)} pivot candles for {symbol} {timeframe} (from {len(df)} candles)")
|
||||
return pivot_map
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting pivot markers for {timeframe}: {e}")
|
||||
import traceback
|
||||
logger.error(traceback.format_exc())
|
||||
return {}
|
||||
|
||||
def _setup_routes(self):
|
||||
|
||||
Reference in New Issue
Block a user