Skip to content

Cursor#8

Merged
chpeu merged 20 commits into
claude2from
cursor
Nov 10, 2025
Merged

Cursor#8
chpeu merged 20 commits into
claude2from
cursor

Conversation

@chpeu

@chpeu chpeu commented Nov 10, 2025

Copy link
Copy Markdown
Owner

PR Type

Enhancement, Bug fix, Documentation


Description

  • Backend refactoring: Removed server-side HTML rendering (Jinja2Templates, StaticFiles) as frontend is now handled by Svelte, and replaced deprecated _calculate_pnl() with pnl_calculator for accurate PnL calculations

  • New API endpoint: Added /api/config/complete endpoint to expose all configuration variables to the frontend

  • Real-time stats synchronization: Integrated stats_update WebSocket event emission after position closure for frontend synchronization

  • WebSocket improvements: Enhanced connection initialization with better error handling, state synchronization, and retry logic with exponential backoff

  • Configuration viewer: Implemented new "Variables en cours" tab in frontend to display all current configuration variables with categorization and formatting

  • Telegram status migration: Migrated Telegram status check from REST API to WebSocket-based state requests

  • WebSocket URL configuration: Added development/production environment detection for proper WebSocket URL routing (localhost:5000 for dev, proxy for prod)

  • Bug fix: Fixed SvelteKit parameter export warning by adding explicit export let params = {} declaration

  • Comprehensive documentation: Added WebSocket synchronization audit report (90.5% of fields using WebSocket), configuration verification guide with multiple methods, Streamlit migration analysis, and backend cleanup summary


Diagram Walkthrough

flowchart LR
  A["Backend<br/>main.py"] -->|"New endpoint"| B["/api/config/complete"]
  A -->|"WebSocket events"| C["stats_update<br/>event"]
  D["Frontend<br/>+page.svelte"] -->|"Enhanced<br/>connection"| C
  E["VariablesPanel.svelte"] -->|"Fetch config"| B
  F["NotificationSettings.svelte"] -->|"Migrate to WS"| C
  G["websocket-impl.ts"] -->|"Dev/Prod<br/>routing"| H["ws://localhost:5000<br/>or proxy"]
  I["position_check_loop.py"] -->|"Emit stats"| C
Loading

File Walkthrough

Relevant files
Enhancement
5 files
main.py
Backend cleanup and PnL calculation refactoring                   

main.py

  • Removed server-side HTML rendering (Jinja2Templates, StaticFiles,
    HTMLResponse) as frontend is now handled by Svelte
  • Replaced deprecated _calculate_pnl() method with pnl_calculator for
    accurate PnL calculations
  • Added new /api/config/complete endpoint to expose all configuration
    variables
  • Refactored WebSocket connection initialization with improved error
    handling and state synchronization
  • Added stats_update event emission after position closure for real-time
    stats synchronization
  • Exposed telegram_enabled status in API responses and WebSocket state
+139/-131
position_check_loop.py
Real-time stats emission for position updates                       

core/callbacks/position_check_loop.py

  • Added _emit_stats_update() function to calculate and emit real-time
    stats via WebSocket
  • Integrated stats emission after position closure for frontend
    synchronization
  • Stats calculation supports both analytics_db and app_state fallback
    sources
+97/-0   
VariablesPanel.svelte
New configuration variables viewer tab                                     

frontend/src/lib/components/VariablesPanel.svelte

  • Added new "Variables en cours" tab to display all current
    configuration variables
  • Implemented loadCompleteConfig() function to fetch
    /api/config/complete endpoint
  • Added organizeTradingConfig() to categorize trading config by sections
    (General, Validation, Patterns, etc.)
  • Implemented value formatting functions for different data types
    (boolean, object, number)
  • Added comprehensive styling for config display with collapsible
    details for complex objects
+516/-0 
+page.svelte
Enhanced WebSocket connection and state synchronization   

frontend/src/routes/+page.svelte

  • Improved WebSocket initialization with better error handling and
    connection state checking
  • Added connect event listener to trigger initial state loading when
    WebSocket connects
  • Implemented retry logic with exponential backoff for failed state
    loads
  • Added stats_update event listener with logging for debugging
  • Removed excessive debug logging for WebSocket type checking
+46/-32 
NotificationSettings.svelte
Migrate Telegram status to WebSocket                                         

frontend/src/lib/components/NotificationSettings.svelte

  • Migrated Telegram status check from REST API to WebSocket-based state
    request
  • Updated to use sendRequestViaWS('state') instead of
    fetch('/api/config')
  • Added error handling for WebSocket connection failures
+14/-7   
Bug fix
1 files
+layout.svelte
Fix SvelteKit parameter export warning                                     

frontend/src/routes/+layout.svelte

  • Added explicit export let params = {} declaration to prevent SvelteKit
    warnings
  • Improved code clarity with explanatory comment about SvelteKit
    parameter handling
+3/-2     
Configuration changes
1 files
websocket-impl.ts
WebSocket URL configuration for dev/prod environments       

frontend/src/lib/utils/websocket-impl.ts

  • Added development environment detection for WebSocket URL
    configuration
  • In development (localhost:3000), connect directly to backend
    (ws://localhost:5000)
  • In production, use proxy or production URL (window.location.host)
  • Improved URL conversion logic with better comments
+13/-4   
Documentation
4 files
RAPPORT_SYNCHRONISATION_WEBSOCKET.md
Complete WebSocket synchronization audit report                   

RAPPORT_SYNCHRONISATION_WEBSOCKET.md

  • Comprehensive audit of all frontend fields and their synchronization
    status
  • Documented 74 fields across 8 tabs with synchronization type
    (WebSocket, REST, or Local)
  • Identified 67 fields (90.5%) using WebSocket native synchronization
  • Listed 7 fields (9.5%) still using REST that should be migrated
  • Provided action items for Sessions and Telegram status migration
+362/-0 
GUIDE_VERIFICATION_VARIABLES.md
Configuration verification methods guide                                 

docs/GUIDE_VERIFICATION_VARIABLES.md

  • Created comprehensive guide for verifying backend configuration
    variables
  • Documented 7 different verification methods (REST endpoints,
    WebSocket, config.py, logs, Python script)
  • Provided detailed examples for /api/config, /api/config/complete, and
    /api/state endpoints
  • Included code examples in cURL, Python, and JavaScript
  • Added troubleshooting section for common configuration issues
+598/-0 
STREAMLIT_ANALYSIS.md
Streamlit migration analysis and implementation guide       

docs/STREAMLIT_ANALYSIS.md

  • Analyzed migration feasibility from FastAPI+Svelte to Streamlit
    framework
  • Compared three architecture options (Streamlit Pure,
    Streamlit+FastAPI, Streamlit+WebSocket)
  • Provided detailed pros/cons analysis and performance comparisons
  • Included complete code example for Streamlit implementation
  • Outlined 4-phase migration plan with effort estimates
+541/-0 
BACKEND_CLEANUP_SUMMARY.md
Backend cleanup summary and architecture documentation     

docs/BACKEND_CLEANUP_SUMMARY.md

  • Added comprehensive documentation of backend cleanup efforts including
    removal of unnecessary HTML routes and imports
  • Documented WebSocket event improvements with new events like
    scan_started, scan_complete, and stats_update
  • Provided final architecture diagram showing API REST endpoints and
    WebSocket communication structure
  • Listed verification tests performed and notes about deprecated REST
    routes maintained for compatibility
+117/-0 

chpeu added 17 commits November 10, 2025 17:40
…ationSettings vers WebSocket + Marquage endpoints sessions deprecated
…Le backend émet maintenant stats_update après chaque fermeture de position et le frontend reçoit les mises à jour en temps réel
@qodo-code-review

qodo-code-review Bot commented Nov 10, 2025

Copy link
Copy Markdown

PR Compliance Guide 🔍

(Compliance updated until commit cfbc0ed)

Below is a summary of compliance checks for this PR:

Security Compliance
Missing auth on WebSocket

Description: The WebSocket endpoint echoes backend state and logs to any connected client without
authentication or authorization checks, enabling potential data exposure to
unauthenticated users.
main.py [1956-2211]

Referred Code
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    """Endpoint WebSocket bidirectionnel natif"""
    try:
        await ws_manager.connect(websocket)

        # 🔥 FIX: Envoyer état initial au client avec gestion d'erreur
        try:
            status_data = app_state.copy()
            if status_data.get('active_position') and hasattr(status_data['active_position'], 'to_dict'):
                try:
                    status_data['active_position'] = status_data['active_position'].to_dict()
                except Exception as e:
                    logger.warning(f"⚠️ Erreur conversion position en dict: {e}")
                    status_data['active_position'] = None

            await ws_manager.send_personal_message({
                'type': 'event',
                'event': 'status',
                'data': status_data
            }, websocket)


 ... (clipped 235 lines)
Sensitive information exposure

Description: The /api/config/complete endpoint exposes full runtime configuration objects which may
include sensitive operational parameters and environment-derived flags, risking
information disclosure if not access-controlled.
main.py [2598-2615]

Referred Code
async def api_get_complete_config():
    """
    🔥 NOUVEAU: Récupérer TOUTES les variables de configuration (TRADING_CONFIG complet)
    Utile pour vérifier toutes les variables prises en compte par le bot
    """
    from config import TRADING_CONFIG, RISK_CONFIG, CONDITION_WEIGHTS, TREND_BONUS_CONFIG
    from config import RETRY_CONFIG, CIRCUIT_BREAKER_CONFIG, WEBSOCKET_CONFIG

    return JSONResponse({
        'trading_config': TRADING_CONFIG,
        'risk_config': RISK_CONFIG,
        'condition_weights': CONDITION_WEIGHTS,
        'trend_bonus_config': TREND_BONUS_CONFIG,
        'retry_config': RETRY_CONFIG,
        'circuit_breaker_config': CIRCUIT_BREAKER_CONFIG,
        'websocket_config': WEBSOCKET_CONFIG,
        'timestamp': time.time()
    })
Insecure transport configuration

Description: The client auto-connects to ws://localhost:5000 in dev and to window host in prod without
TLS enforcement or auth tokens, which may allow MITM or unauthorized access if deployed
over insecure channels.
websocket-impl.ts [45-65]

Referred Code
constructor(url: string = '') {
    // Détecter l'URL depuis window.location si non fournie
    if (!url) {
        // 🔥 FIX: En développement, utiliser directement le backend (port 5000)
        // En production, utiliser le proxy Vite (window.location.host)
        const isDev = window.location.hostname === 'localhost' && window.location.port === '3000';
        if (isDev) {
            // Développement: connexion directe au backend
            url = 'ws://localhost:5000';
        } else {
            // Production: utiliser le proxy ou l'URL de production
            const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
            const host = window.location.host;
            url = `${protocol}//${host}`;
        }
    }

    // Convertir http:// en ws:// ou https:// en wss:// si nécessaire
    this.baseUrl = url.replace(/^http/, 'ws');
    this.url = this.baseUrl + '/ws';
}
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status:
Sensitive error exposure: WebSocket 'command_error' and request error responses send str(e) back to
clients which may leak internal details.

Referred Code
            'timestamp': time.time()
        }, websocket)
    except Exception as e:
        logger.error(f"Erreur commande {command}: {e}")
        await ws_manager.send_personal_message({
            'type': 'command_error',
            'id': command_id,
            'command': command,
            'error': str(e),
            'timestamp': time.time()
        }, websocket)

# Heartbeat (Frontend ↔ Backend)
elif msg_type == 'ping':
    await ws_manager.send_personal_message({
        'type': 'pong',
        'timestamp': time.time()
    }, websocket)

# Subscription (Frontend → Backend)
elif msg_type == 'subscribe':


 ... (clipped 176 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Missing audit context: New actions (e.g., emitting 'position_closed', 'stats_update',
WebSocket command handling) are logged minimally without user identity or structured audit
context, making it unclear who initiated actions.

Referred Code
        await add_log('INFO', 'Position fermée', f"{close_reason} - PnL: {result.get('pnl_usdt', 0):.2f} USDT")
        await ws_manager.emit('position_closed', result)

        # 🔥 FIX: Émettre stats_update après fermeture de position pour synchronisation temps réel
        try:
            from core.callbacks.position_check_loop import _emit_stats_update
            await _emit_stats_update()
        except Exception as e:
            logger.error(f"❌ Erreur émission stats_update: {e}")

        # 🔥 JOUR 5: Métriques
        if get_metrics_collector:
            metrics = get_metrics_collector()
            if metrics:
                metrics.positions_closed += 1
                if result.get('pnl_usdt', 0) > 0:
                    metrics.trades_wins += 1
                else:
                    metrics.trades_losses += 1

except Exception as e:


 ... (clipped 28 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Partial error handling: New WebSocket flow adds try/except and logs errors but returns raw str(e) in protocol
messages and lacks validation of incoming message schema and types.

Referred Code
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    """Endpoint WebSocket bidirectionnel natif"""
    try:
        await ws_manager.connect(websocket)

        # 🔥 FIX: Envoyer état initial au client avec gestion d'erreur
        try:
            status_data = app_state.copy()
            if status_data.get('active_position') and hasattr(status_data['active_position'], 'to_dict'):
                try:
                    status_data['active_position'] = status_data['active_position'].to_dict()
                except Exception as e:
                    logger.warning(f"⚠️ Erreur conversion position en dict: {e}")
                    status_data['active_position'] = None

            await ws_manager.send_personal_message({
                'type': 'event',
                'event': 'status',
                'data': status_data
            }, websocket)


 ... (clipped 251 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Log data sensitivity: Stats emission and logging include full trade objects (best/worst trade) without masking
which could include sensitive fields depending on upstream schema.

Referred Code
# Récupérer stats depuis analytics_db si disponible
if _analytics_db:
    try:
        trades = _analytics_db.get_trades(limit=10000)
        if trades:
            total = len(trades)
            wins = sum(1 for t in trades if t.get('pnl_usdt', 0) > 0)
            losses = total - wins

            # Calculer PnL total
            total_pnl_usdt = sum(t.get('pnl_usdt', 0) for t in trades)
            total_pnl_pct = sum(t.get('pnl_pct', 0) for t in trades)

            # Trouver best/worst trade
            best_trade = max(trades, key=lambda t: t.get('pnl_usdt', 0), default=None)
            worst_trade = min(trades, key=lambda t: t.get('pnl_usdt', 0), default=None)

            # Calculer durée moyenne
            durations = [t.get('duration_seconds', 0) for t in trades if t.get('duration_seconds')]
            avg_duration = sum(durations) / len(durations) if durations else 0.0



 ... (clipped 10 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Unvalidated WS input: The WebSocket message handler trusts 'message' fields (type, command, params)
without explicit schema validation or authorization checks before executing commands.

Referred Code
try:
    while True:
        data = await websocket.receive_text()
        message = json.loads(data)

        msg_type = message.get('type')

        # Traiter commandes (Frontend → Backend)
        if msg_type == 'command':
            command = message.get('command')
            params = message.get('params', {})
            command_id = message.get('id')

            logger.info(f"📨 Commande reçue: {command} (ID: {command_id})")

            try:
                result = await handle_client_command(command, params)
                await ws_manager.send_personal_message({
                    'type': 'command_response',
                    'id': command_id,
                    'command': command,


 ... (clipped 15 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

Previous compliance checks

Compliance check up to commit c35f862
Security Compliance
Insecure WebSocket URL

Description: Hardcodes ws://localhost:5000 for development which may leak environment assumptions and
fail under HTTPS, risking mixed-content or connection exposure if not gated by environment
checks.
websocket-impl.ts [49-59]

Referred Code
// En production, utiliser le proxy Vite (window.location.host)
const isDev = window.location.hostname === 'localhost' && window.location.port === '3000';
if (isDev) {
    // Développement: connexion directe au backend
    url = 'ws://localhost:5000';
} else {
    // Production: utiliser le proxy ou l'URL de production
    const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
    const host = window.location.host;
    url = `${protocol}//${host}`;
}
Sensitive information exposure

Description: WebSocket initial status and logs are sent using copies of app_state that may include
sensitive runtime data; without explicit filtering this could expose internal details to
any connected client.
main.py [1956-1993]

Referred Code
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    """Endpoint WebSocket bidirectionnel natif"""
    try:
        await ws_manager.connect(websocket)

        # 🔥 FIX: Envoyer état initial au client avec gestion d'erreur
        try:
            status_data = app_state.copy()
            if status_data.get('active_position') and hasattr(status_data['active_position'], 'to_dict'):
                try:
                    status_data['active_position'] = status_data['active_position'].to_dict()
                except Exception as e:
                    logger.warning(f"⚠️ Erreur conversion position en dict: {e}")
                    status_data['active_position'] = None

            await ws_manager.send_personal_message({
                'type': 'event',
                'event': 'status',
                'data': status_data
            }, websocket)


 ... (clipped 17 lines)
Configuration disclosure

Description: The new /api/config/complete endpoint exposes full configuration dictionaries which may
include sensitive keys if not sanitized, enabling config disclosure to unauthenticated
callers.
main.py [2591-2609]

Referred Code
@app.get("/api/config/complete")
async def api_get_complete_config():
    """
    🔥 NOUVEAU: Récupérer TOUTES les variables de configuration (TRADING_CONFIG complet)
    Utile pour vérifier toutes les variables prises en compte par le bot
    """
    from config import TRADING_CONFIG, RISK_CONFIG, CONDITION_WEIGHTS, TREND_BONUS_CONFIG
    from config import RETRY_CONFIG, CIRCUIT_BREAKER_CONFIG, WEBSOCKET_CONFIG

    return JSONResponse({
        'trading_config': TRADING_CONFIG,
        'risk_config': RISK_CONFIG,
        'condition_weights': CONDITION_WEIGHTS,
        'trend_bonus_config': TREND_BONUS_CONFIG,
        'retry_config': RETRY_CONFIG,
        'circuit_breaker_config': CIRCUIT_BREAKER_CONFIG,
        'websocket_config': WEBSOCKET_CONFIG,
        'timestamp': time.time()
    })
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status:
Missing audit context: New critical actions (position close emits, stats_update emissions, websocket
connection/init state send) add logs with generic messages but do not consistently include
user identity or full action context, making audit trails potentially incomplete.

Referred Code
        await add_log('INFO', 'Position fermée', f"{close_reason} - PnL: {result.get('pnl_usdt', 0):.2f} USDT")
        await ws_manager.emit('position_closed', result)

        # 🔥 FIX: Émettre stats_update après fermeture de position pour synchronisation temps réel
        try:
            from core.callbacks.position_check_loop import _emit_stats_update
            await _emit_stats_update()
        except Exception as e:
            logger.error(f"❌ Erreur émission stats_update: {e}")

        # 🔥 JOUR 5: Métriques
        if get_metrics_collector:
            metrics = get_metrics_collector()
            if metrics:
                metrics.positions_closed += 1
                if result.get('pnl_usdt', 0) > 0:
                    metrics.trades_wins += 1
                else:
                    metrics.trades_losses += 1

except Exception as e:


 ... (clipped 1115 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Partial try/except: New try/except blocks around websocket initialization and event emissions catch exceptions
but sometimes only log an error without fallback or client notification, which may lead to
silent degraded behavior.

Referred Code
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    """Endpoint WebSocket bidirectionnel natif"""
    try:
        await ws_manager.connect(websocket)

        # 🔥 FIX: Envoyer état initial au client avec gestion d'erreur
        try:
            status_data = app_state.copy()
            if status_data.get('active_position') and hasattr(status_data['active_position'], 'to_dict'):
                try:
                    status_data['active_position'] = status_data['active_position'].to_dict()
                except Exception as e:
                    logger.warning(f"⚠️ Erreur conversion position en dict: {e}")
                    status_data['active_position'] = None

            await ws_manager.send_personal_message({
                'type': 'event',
                'event': 'status',
                'data': status_data
            }, websocket)


 ... (clipped 18 lines)

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Log content risk: New logs forward recent entries over WebSocket and add detailed stats/trade emissions, but
no explicit redaction is shown; depending on log contents, this could expose sensitive
data to clients.

Referred Code
try:
    for log_entry in app_state.get('logs', [])[-50:]:
        try:
            await ws_manager.send_personal_message({
                'type': 'event',
                'event': 'log',
                'data': log_entry
            }, websocket)
        except Exception as e:
            logger.debug(f"⚠️ Erreur envoi log: {e}")
            break  # Arrêter si erreur
except Exception as e:
    logger.error(f"❌ Erreur envoi logs: {e}")

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Insecure dev URL: The client auto-selects ws://localhost:5000 in development without TLS or auth, and other
new endpoints expose full configuration via /api/config/complete, which may require access
control and validation not evident in the diff.

Referred Code
    // En production, utiliser le proxy Vite (window.location.host)
    const isDev = window.location.hostname === 'localhost' && window.location.port === '3000';
    if (isDev) {
        // Développement: connexion directe au backend
        url = 'ws://localhost:5000';
    } else {
        // Production: utiliser le proxy ou l'URL de production
        const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
        const host = window.location.host;
        url = `${protocol}//${host}`;
    }
}

Learn more about managing compliance generic rules or creating your own custom rules

@qodo-code-review

qodo-code-review Bot commented Nov 10, 2025

Copy link
Copy Markdown

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Security
Secure endpoint exposing all configurations

Restrict access to the /api/config/complete endpoint to localhost only to
prevent exposing sensitive configuration data.

main.py [2591-2609]

 @app.get("/api/config/complete")
-async def api_get_complete_config():
+async def api_get_complete_config(request: Request):
     """
     🔥 NOUVEAU: Récupérer TOUTES les variables de configuration (TRADING_CONFIG complet)
     Utile pour vérifier toutes les variables prises en compte par le bot
     """
+    # 🔒 SECURITY: Restrict access to localhost for this sensitive endpoint
+    if request.client.host != "127.0.0.1" and request.client.host != "localhost":
+        from fastapi import HTTPException
+        raise HTTPException(status_code=403, detail="Access forbidden")
+
     from config import TRADING_CONFIG, RISK_CONFIG, CONDITION_WEIGHTS, TREND_BONUS_CONFIG
     from config import RETRY_CONFIG, CIRCUIT_BREAKER_CONFIG, WEBSOCKET_CONFIG
     
     return JSONResponse({
         'trading_config': TRADING_CONFIG,
         'risk_config': RISK_CONFIG,
         'condition_weights': CONDITION_WEIGHTS,
         'trend_bonus_config': TREND_BONUS_CONFIG,
         'retry_config': RETRY_CONFIG,
         'circuit_breaker_config': CIRCUIT_BREAKER_CONFIG,
         'websocket_config': WEBSOCKET_CONFIG,
         'timestamp': time.time()
     })
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a security risk in a newly added endpoint and proposes a simple, effective mitigation to prevent potential information leakage.

Medium
High-level
Consider Streamlit for a simpler architecture

To simplify the architecture, consider migrating from the current FastAPI+Svelte
stack to Streamlit. This would unify the project into a single Python
application, simplifying development and maintenance.

Examples:

docs/STREAMLIT_ANALYSIS.md [1-541]
# 🔍 Analyse : Migration vers Streamlit

## 📊 Vue d'ensemble

**Streamlit** est un framework Python qui permet de créer des interfaces web rapidement, **sans frontend séparé** (pas de Svelte/React/Vue).

---

## 🏗️ Architecture Actuelle vs Streamlit


 ... (clipped 531 lines)

Solution Walkthrough:

Before:

# Current Architecture (FastAPI + Svelte)

# main.py (FastAPI Backend)
app = FastAPI()
app.include_router(api_router)

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    # ... WebSocket logic ...

# frontend/ (Svelte Frontend)
# Separate project with its own build process,
# communicating with FastAPI via WebSocket and REST API.
# Requires Node.js, npm, etc.

After:

# Proposed Architecture (Streamlit)

# streamlit_app.py (Single Python App)
import streamlit as st
from core.scanner import ScalabilityScanner # Direct import
from core.position_manager import PositionManager # Direct import

st.title("Trade Cursor")

if st.button("Start Scanner"):
    # Directly call backend logic
    scanner.start()

# Display data from backend objects
st.metric("Winrate", position_manager.get_stats()['winrate'])

# UI updates automatically on state change
Suggestion importance[1-10]: 7

__

Why: The suggestion is highly relevant as the PR itself introduces STREAMLIT_ANALYSIS.md, making this a valid strategic discussion, although it doesn't propose a change to the current PR's code.

Medium
General
Use environment variables for WebSocket URL

Use Vite environment variables (e.g., VITE_WS_URL) to configure the WebSocket
URL instead of hardcoding it for development.

frontend/src/lib/utils/websocket-impl.ts [45-65]

 constructor(url: string = '') {
     // Détecter l'URL depuis window.location si non fournie
     if (!url) {
-        // 🔥 FIX: En développement, utiliser directement le backend (port 5000)
-        // En production, utiliser le proxy Vite (window.location.host)
-        const isDev = window.location.hostname === 'localhost' && window.location.port === '3000';
-        if (isDev) {
-            // Développement: connexion directe au backend
-            url = 'ws://localhost:5000';
+        // 🔥 FIX: Utiliser les variables d'environnement Vite pour une configuration flexible
+        // VITE_WS_URL est défini dans .env.development (e.g., ws://localhost:5000)
+        // En production, il n'est pas défini, on utilise donc l'hôte actuel.
+        if (import.meta.env.VITE_WS_URL) {
+            url = import.meta.env.VITE_WS_URL;
         } else {
             // Production: utiliser le proxy ou l'URL de production
             const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
             const host = window.location.host;
             url = `${protocol}//${host}`;
         }
     }
     
     // Convertir http:// en ws:// ou https:// en wss:// si nécessaire
     this.baseUrl = url.replace(/^http/, 'ws');
     this.url = this.baseUrl + '/ws';
 }
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion improves maintainability by replacing a hardcoded development port with a more flexible environment variable-based approach, which is a good practice.

Low
Optimize fetching of Telegram status

Optimize fetching the Telegram status by creating a dedicated, lightweight
WebSocket request instead of fetching the entire application state.

frontend/src/lib/components/NotificationSettings.svelte [32-54]

 // 🔥 MIGRATION COMPLÈTE: Vérifier le statut Telegram via WebSocket
 async function checkTelegramStatus() {
 	try {
 		const { getWebSocket, sendRequestViaWS } = await import('$lib/utils/websocket');
 		const ws = getWebSocket();
 		if (ws && ws.connected) {
-			const response = await sendRequestViaWS('state', {});
-			const stateData = response?.data || response;
-			// Vérifier si Telegram est configuré (via backend)
-			// Le backend devrait exposer cette info dans state.config
-			if (stateData && stateData.config) {
-				telegramStatus = stateData.config.telegram_enabled ? '✅ Activé' : '❌ Désactivé (variables d\'environnement manquantes)';
+			// 🔥 FIX: Utiliser une requête dédiée et légère au lieu de 'state'
+			const response = await sendRequestViaWS('get_telegram_status', {});
+			const statusData = response?.data || response;
+			
+			if (statusData && typeof statusData.telegram_enabled === 'boolean') {
+				telegramStatus = statusData.telegram_enabled ? '✅ Activé' : '❌ Désactivé (variables d\'environnement manquantes)';
 			} else {
-				telegramStatus = '❌ Désactivé (variables d\'environnement manquantes)';
+				telegramStatus = '❔ Statut inconnu';
 			}
 		} else {
 			telegramStatus = '❌ WebSocket non connecté';
 		}
 	} catch (err) {
 		console.error('Erreur vérification Telegram:', err);
 		telegramStatus = '❌ Erreur de connexion';
 	}
 }
  • Apply / Chat
Suggestion importance[1-10]: 5

__

Why: The suggestion proposes a valid optimization to reduce unnecessary data transfer by creating a dedicated WebSocket request, improving network efficiency.

Low
  • Update

@chpeu chpeu merged commit c3d276c into claude2 Nov 10, 2025
chpeu pushed a commit that referenced this pull request Nov 28, 2025
…exit

Implémentation de 3 optimisations critiques pour améliorer winrate/PnL:

## OPT #2: Prix Réel Post-Ordre (+2-3% précision PnL)
**Problème**: Prix théorique utilisé au lieu du prix réel rempli
- Slippage market ignoré (0.01-0.05%)
- PnL calculé sur prix inexact

**Solution**:
- Récupération `dealAvgPrice` de MEXC après création ordre
- Calcul slippage réel: `(filled_price - theoretical_price) / theoretical_price * 100`
- PnL basé sur prix RÉEL (entry et exit)
- Logs détaillés: prix théorique vs réel

**Fichiers**: `trading/live_order_manager_futures.py:779-840, 1236-1293`

## OPT #3: Early Invalidation avec Prix Réel (+10-15% winrate)
**Problème**: Early invalidation basée sur prix théorique
- Avec slippage 0.05%, position déjà à -0.05% immédiatement
- Threshold -0.12% après 15s trop agressif (proche du slippage)
- Beaucoup de positions invalidées prématurément

**Solution**:
- Utiliser `entry_fill_price` (prix réel) au lieu de `entry` (théorique)
- PnL calculé depuis prix réel: `pnl = (current - filled_price) / filled_price`
- Threshold effectif devient -0.07% au lieu de -0.12% (plus réaliste)

**Fichiers**: `core/position_manager.py:1190-1208`

## OPT #13: Time-Based Exit 20min (+2-3% efficacité capital)
**Problème**: Positions "flat" monopolisent capital inutilement
- Position ouverte >20min avec PnL entre -0.1% et +0.1%
- Capital bloqué sans opportunité de profit

**Solution**:
- Détection position flat après 20min (1200s)
- Fermeture automatique si `-0.1% <= PnL <= +0.1%`
- Libère capital pour autres setups
- Reason: `TIME_BASED_EXIT`

**Fichiers**: `core/position_manager.py:1231-1239`

## Gains Estimés
- **OPT #2**: +2-3% précision PnL (prix réels)
- **OPT #3**: +10-15% winrate (moins d'invalidations prématurées)
- **OPT #13**: +2-3% efficacité capital (rotation plus rapide)
- **Total**: +14-21% amélioration cumulée

## Notes Importantes
- ✅ 0% fees sur paires scannées MEXC (confirmé par user)
- ✅ Slippage typique: 0.01-0.05% (maintenant tracké)
- ✅ Position check déjà à 0.1s (optimal, pas de modif)
- 🔜 Optimisations #8, #10, #11, #14 nécessitent refactoring majeur (report)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant