Page 2 of 2

Re: Custom volume and direction indicator for MT4

Posted: Wed Sep 02, 2026 3:08 pm
by PTScalper
Plus i prepared something special to improve webhooks for high frequency scalpers.

To handle high-volume executions without timing out TradingView's webhook limits (TradingView expects a 200 OK response within 3 seconds) or hitting broker rate limits, the Flask application must decouple the incoming request from the execution logic.

The most robust way to achieve this in a standalone Python application is by implementing a Producer-Consumer pattern using a thread-safe in-memory queue. The Flask route acts as the producer, mathematically slicing the massive position and instantly pushing the chunks to a queue. A background daemon thread acts as the consumer, popping chunks off the queue and executing them with a built-in rate-limiting delay.

The Python Flask Receiver

Code: Select all

from flask import Flask, request, jsonify
import threading
import queue
import time
import math
import logging

# Configure logging for server monitoring
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')

app = Flask(__name__)

# Thread-safe queue to hold order chunks
order_queue = queue.Queue()

# --- Configuration ---
MAX_CHUNK_LOTS = 50.0
RATE_LIMIT_DELAY = 0.5  # Seconds to wait between broker API calls
MIN_LOT_STEP = 0.01     # Broker minimum volume step

#+------------------------------------------------------------------+
#| Background Worker: Processes chunks sequentially                 |
#+------------------------------------------------------------------+
def broker_execution_worker():
    logging.info("Background broker execution worker started.")
    while True:
        # Block until a chunk is available in the queue
        chunk = order_queue.get()
        
        symbol = chunk.get('symbol')
        qty = chunk.get('qty')
        action = chunk.get('action')
        
        try:
            # ---------------------------------------------------------
            # TODO: Insert your specific Broker API execution call here
            # Example: requests.post('http://broker-api...', json=chunk)
            # ---------------------------------------------------------
            logging.info(f"EXECUTING BROKER API: {action} {qty} lots of {symbol}")
            
        except Exception as e:
            logging.error(f"Broker API Error for {symbol}: {e}")
            # Optional: Implement retry logic and push back to queue on failure
            
        finally:
            # Enforce rate limit delay before processing the next chunk
            time.sleep(RATE_LIMIT_DELAY)
            order_queue.task_done()

# Start the background worker thread (daemon=True ensures it dies when Flask stops)
threading.Thread(target=broker_execution_worker, daemon=True).start()

#+------------------------------------------------------------------+
#| Webhook Route: Catches TV payload and chunks it instantly        |
#+------------------------------------------------------------------+
@app.route('/tv-webhook', methods=['POST'])
def tradingview_webhook():
    if not request.is_json:
        return jsonify({"error": "Payload must be JSON"}), 400
        
    data = request.json
    symbol = data.get('symbol')
    total_qty = data.get('qty')
    action = data.get('action', 'close')
    
    if not symbol or not total_qty:
        return jsonify({"error": "Missing symbol or qty"}), 400
        
    try:
        total_qty = float(total_qty)
        remaining_qty = abs(total_qty)
        chunks_queued = 0
        
        # Slice the massive position into broker-safe chunks
        while remaining_qty >= MIN_LOT_STEP:
            close_qty = min(remaining_qty, MAX_CHUNK_LOTS)
            
            # Normalize to avoid Invalid Volume errors
            close_qty = math.floor(close_qty / MIN_LOT_STEP) * MIN_LOT_STEP
            
            if close_qty < MIN_LOT_STEP:
                break
                
            # Create the chunk payload
            chunk_payload = {
                "action": action,
                "symbol": symbol,
                "qty": round(close_qty, 2)
            }
            
            # Push to the background queue instantly
            order_queue.put(chunk_payload)
            
            remaining_qty -= close_qty
            chunks_queued += 1
            
        logging.info(f"Received webhook for {symbol}. Sliced into {chunks_queued} chunks.")
        
        # Return 202 Accepted immediately so TradingView does not timeout
        return jsonify({
            "status": "queued",
            "symbol": symbol,
            "chunks_generated": chunks_queued
        }), 202

    except ValueError:
        return jsonify({"error": "Invalid quantity format"}), 400

if __name__ == '__main__':
    # Run the server on port 5000
    app.run(host='0.0.0.0', port=5000)

Re: Custom volume and direction indicator for MT4

Posted: Wed Sep 02, 2026 3:09 pm
by PTScalper
Production Deployment Security

When deploying this web stack to your Google Cloud Platform or Alibaba Cloud instances, the Flask development server (app.run()) is not designed to handle raw internet traffic safely.

1.Deploy a WSGI Server:Wrap the Flask application using a production-grade WSGI server like Gunicorn or uWSGI to handle concurrent network connections efficiently.

2.Configure Nginx Reverse Proxy:Set up Nginx to proxy incoming requests on port 80/443 to the Gunicorn socket. This layer absorbs slow-loris attacks and manages SSL termination.

3.Lock Down Firewall Rules:Critical for execution safety.Configure your cloud network security groups to drop all traffic to the webhook route except for TradingView's specific, publicly published IP addresses (e.g., 52.89.214.238, 34.212.75.30, etc.).

4.Implement Secret Tokens:Add an authentication token parameter to your TradingView alert JSON (e.g., {"secret": "YOUR_HASH"}) and validate it at the top of the /tv-webhook route before processing the payload.