fix: v11 worker missing use_quality_filters + RSI bounds + wrong import path
THREE critical bugs in cluster/v11_test_worker.py: 1. Missing use_quality_filters parameter when creating MoneyLineV11Inputs - Parameter defaults to True but wasn't being passed explicitly - Fix: Added use_quality_filters=True to inputs creation 2. Missing fixed RSI parameters (rsi_long_max, rsi_short_min) - Worker only passed rsi_long_min and rsi_short_max (sweep params) - Missing rsi_long_max=70 and rsi_short_min=30 (fixed params) - Fix: Added both fixed parameters to inputs creation 3. Import path mismatch - worker imported OLD version - Worker added cluster/ to sys.path, imported from parent directory - Old v11_moneyline_all_filters.py (21:40) missing use_quality_filters - Fixed v11_moneyline_all_filters.py was in backtester/ subdirectory - Fix: Deployed corrected file to /home/comprehensive_sweep/ Result: 0 signals → 1,096-1,186 signals per config ✓ Verified: Local test (314 signals), EPYC dataset test (1,186 signals), Worker log now shows signal variety across 27 concurrent configs. Progressive sweep now running successfully on EPYC cluster.
This commit is contained in:
78
app/api/drift/markets/route.ts
Normal file
78
app/api/drift/markets/route.ts
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
import { NextRequest, NextResponse } from 'next/server'
|
||||||
|
import { initializeDriftService, getDriftService } from '@/lib/drift/client'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/drift/markets
|
||||||
|
*
|
||||||
|
* Query Drift Protocol perpetual markets
|
||||||
|
* Optional query param: ?search=FARTCOIN to filter by symbol
|
||||||
|
*/
|
||||||
|
export async function GET(request: NextRequest) {
|
||||||
|
try {
|
||||||
|
const searchParams = request.nextUrl.searchParams
|
||||||
|
const searchSymbol = searchParams.get('search')?.toUpperCase()
|
||||||
|
|
||||||
|
await initializeDriftService()
|
||||||
|
const driftService = getDriftService()
|
||||||
|
const driftClient = driftService.getClient()
|
||||||
|
|
||||||
|
const perpMarketAccounts = driftClient.getPerpMarketAccounts()
|
||||||
|
|
||||||
|
if (!perpMarketAccounts || perpMarketAccounts.length === 0) {
|
||||||
|
return NextResponse.json({ markets: [] })
|
||||||
|
}
|
||||||
|
|
||||||
|
const markets = perpMarketAccounts.map((market, index) => {
|
||||||
|
if (!market) return null
|
||||||
|
|
||||||
|
// Decode market name from bytes
|
||||||
|
const nameBytes = market.name as unknown as number[]
|
||||||
|
const symbol = nameBytes
|
||||||
|
? String.fromCharCode(...Array.from(nameBytes).filter((b: number) => b !== 0)).trim()
|
||||||
|
: `Market-${index}`
|
||||||
|
|
||||||
|
const minOrderSize = market.amm?.minOrderSize
|
||||||
|
? Number(market.amm.minOrderSize) / 1e9
|
||||||
|
: 0
|
||||||
|
|
||||||
|
const tickSize = market.amm?.orderTickSize
|
||||||
|
? Number(market.amm.orderTickSize) / 1e6
|
||||||
|
: 0.0001
|
||||||
|
|
||||||
|
const oracleAddress = market.amm?.oracle?.toString() || 'N/A'
|
||||||
|
|
||||||
|
return {
|
||||||
|
index,
|
||||||
|
symbol,
|
||||||
|
oracleAddress,
|
||||||
|
minOrderSize,
|
||||||
|
tickSize,
|
||||||
|
marginRatioInitial: market.marginRatioInitial
|
||||||
|
? Number(market.marginRatioInitial) / 10000
|
||||||
|
: 0,
|
||||||
|
marginRatioMaintenance: market.marginRatioMaintenance
|
||||||
|
? Number(market.marginRatioMaintenance) / 10000
|
||||||
|
: 0,
|
||||||
|
}
|
||||||
|
}).filter(Boolean)
|
||||||
|
|
||||||
|
// Filter by search if provided
|
||||||
|
const filtered = searchSymbol
|
||||||
|
? markets.filter(m => m && m.symbol.toUpperCase().includes(searchSymbol))
|
||||||
|
: markets
|
||||||
|
|
||||||
|
await driftService.disconnect()
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
total: markets.length,
|
||||||
|
filtered: filtered.length,
|
||||||
|
markets: filtered,
|
||||||
|
})
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('❌ Error fetching markets:', error)
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: 'Failed to fetch markets', message: error.message },
|
||||||
|
{ status: 500 }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -215,7 +215,7 @@ def deploy_worker(worker_name: str, chunk_id: str, start_combo: int):
|
|||||||
'scp',
|
'scp',
|
||||||
'-o', 'StrictHostKeyChecking=no',
|
'-o', 'StrictHostKeyChecking=no',
|
||||||
'-o', f'ProxyJump={worker["ssh_hop"]}',
|
'-o', f'ProxyJump={worker["ssh_hop"]}',
|
||||||
'cluster/v11_test_worker.py',
|
'v11_test_worker.py',
|
||||||
f'{worker["host"]}:{workspace}/'
|
f'{worker["host"]}:{workspace}/'
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
@@ -223,7 +223,7 @@ def deploy_worker(worker_name: str, chunk_id: str, start_combo: int):
|
|||||||
scp_cmd = [
|
scp_cmd = [
|
||||||
'scp',
|
'scp',
|
||||||
'-o', 'StrictHostKeyChecking=no',
|
'-o', 'StrictHostKeyChecking=no',
|
||||||
'cluster/v11_test_worker.py',
|
'v11_test_worker.py',
|
||||||
f'{worker["host"]}:{workspace}/'
|
f'{worker["host"]}:{workspace}/'
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -263,7 +263,7 @@ def deploy_worker(worker_name: str, chunk_id: str, start_combo: int):
|
|||||||
# Start worker
|
# Start worker
|
||||||
print(f"🚀 Starting worker process...")
|
print(f"🚀 Starting worker process...")
|
||||||
|
|
||||||
worker_cmd = f"cd {workspace} && nohup python3 v11_test_worker.py {DATA_FILE} {chunk_id} {start_combo} > {chunk_id}_worker.log 2>&1 &"
|
worker_cmd = f"cd {workspace} && nohup .venv/bin/python3 v11_test_worker.py {DATA_FILE} {chunk_id} {start_combo} > {chunk_id}_worker.log 2>&1 &"
|
||||||
|
|
||||||
if 'ssh_hop' in worker:
|
if 'ssh_hop' in worker:
|
||||||
ssh_cmd = [
|
ssh_cmd = [
|
||||||
|
|||||||
@@ -113,6 +113,7 @@ def backtest_config(config: Dict[str, Any]) -> Dict[str, Any]:
|
|||||||
try:
|
try:
|
||||||
# Create v11 inputs
|
# Create v11 inputs
|
||||||
inputs = MoneyLineV11Inputs(
|
inputs = MoneyLineV11Inputs(
|
||||||
|
use_quality_filters=True, # 🔧 FIX: Enable filters for progressive sweep
|
||||||
flip_threshold=config['flip_threshold'],
|
flip_threshold=config['flip_threshold'],
|
||||||
adx_min=config['adx_min'],
|
adx_min=config['adx_min'],
|
||||||
long_pos_max=config['long_pos_max'],
|
long_pos_max=config['long_pos_max'],
|
||||||
@@ -120,6 +121,8 @@ def backtest_config(config: Dict[str, Any]) -> Dict[str, Any]:
|
|||||||
vol_min=config['vol_min'],
|
vol_min=config['vol_min'],
|
||||||
entry_buffer_atr=config['entry_buffer_atr'],
|
entry_buffer_atr=config['entry_buffer_atr'],
|
||||||
rsi_long_min=config['rsi_long_min'],
|
rsi_long_min=config['rsi_long_min'],
|
||||||
|
rsi_long_max=70, # 🔧 FIX: Add missing fixed parameter
|
||||||
|
rsi_short_min=30, # 🔧 FIX: Add missing fixed parameter
|
||||||
rsi_short_max=config['rsi_short_max'],
|
rsi_short_max=config['rsi_short_max'],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
71
test_worker_params.py
Normal file
71
test_worker_params.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Test exact parameters worker is using"""
|
||||||
|
|
||||||
|
import pandas as pd
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, 'backtester')
|
||||||
|
|
||||||
|
from v11_moneyline_all_filters import money_line_v11_signals, MoneyLineV11Inputs
|
||||||
|
|
||||||
|
# Load dataset
|
||||||
|
print("Loading data...")
|
||||||
|
df = pd.read_csv('data/solusdt_5m.csv')
|
||||||
|
df['timestamp'] = pd.to_datetime(df['timestamp'])
|
||||||
|
df = df.set_index('timestamp')
|
||||||
|
print(f"✓ Loaded {len(df)} bars")
|
||||||
|
|
||||||
|
# Test EXACT worker configuration (most permissive combination)
|
||||||
|
config = {
|
||||||
|
'flip_threshold': 0.4, # Most permissive
|
||||||
|
'adx_min': 0, # Filter DISABLED
|
||||||
|
'long_pos_max': 100, # Most permissive
|
||||||
|
'short_pos_min': 0, # Filter DISABLED
|
||||||
|
'vol_min': 0.0, # Filter DISABLED
|
||||||
|
'entry_buffer_atr': 0.0, # Filter DISABLED
|
||||||
|
'rsi_long_min': 25, # Permissive
|
||||||
|
'rsi_short_max': 80, # Permissive
|
||||||
|
}
|
||||||
|
|
||||||
|
print("\nTest 1: Worker parameters WITH use_quality_filters=True")
|
||||||
|
print(f"Config: {config}")
|
||||||
|
inputs = MoneyLineV11Inputs(
|
||||||
|
use_quality_filters=True,
|
||||||
|
flip_threshold=config['flip_threshold'],
|
||||||
|
adx_min=config['adx_min'],
|
||||||
|
long_pos_max=config['long_pos_max'],
|
||||||
|
short_pos_min=config['short_pos_min'],
|
||||||
|
vol_min=config['vol_min'],
|
||||||
|
entry_buffer_atr=config['entry_buffer_atr'],
|
||||||
|
rsi_long_min=config['rsi_long_min'],
|
||||||
|
rsi_long_max=70,
|
||||||
|
rsi_short_min=30,
|
||||||
|
rsi_short_max=config['rsi_short_max'],
|
||||||
|
)
|
||||||
|
print(f"use_quality_filters: {inputs.use_quality_filters}")
|
||||||
|
print(f"RSI bounds: long [{inputs.rsi_long_min}, {inputs.rsi_long_max}], short [{inputs.rsi_short_min}, {inputs.rsi_short_max}]")
|
||||||
|
|
||||||
|
signals = money_line_v11_signals(df, inputs)
|
||||||
|
print(f"RESULT: {len(signals)} signals")
|
||||||
|
|
||||||
|
if len(signals) == 0:
|
||||||
|
print("\n🔴 ZERO SIGNALS - Same as worker!")
|
||||||
|
print("\nTest 2: Try WITHOUT quality filters")
|
||||||
|
inputs2 = MoneyLineV11Inputs(
|
||||||
|
use_quality_filters=False, # Bypass all filters
|
||||||
|
flip_threshold=0.4,
|
||||||
|
)
|
||||||
|
signals2 = money_line_v11_signals(df, inputs2)
|
||||||
|
print(f"RESULT: {len(signals2)} signals")
|
||||||
|
|
||||||
|
if len(signals2) > 0:
|
||||||
|
print("\n✓ Filter bypass works - problem is WITH filters")
|
||||||
|
print("Debugging which filter is blocking...")
|
||||||
|
|
||||||
|
# Check each filter component
|
||||||
|
print("\n First 10 rows of data:")
|
||||||
|
print(df[['open', 'high', 'low', 'close', 'volume']].head(10))
|
||||||
|
else:
|
||||||
|
print(f"\n✅ SUCCESS: {len(signals)} signals generated!")
|
||||||
|
print(f" First 3 signals:")
|
||||||
|
for s in signals[:3]:
|
||||||
|
print(f" {s.timestamp} {s.direction} @ ${s.entry_price:.2f}")
|
||||||
Reference in New Issue
Block a user