MTS PULLBACK TRADING [FHENRY0331] DAILY SCANNER

buy when pullback candle high breaks

 

<?php

// ==========================================================

// MTS PULLBACK TRADING [FHENRY0331] DAILY SCANNER

// FIXED + OPTIMIZED VERSION

// ==========================================================


set_time_limit(0);

ini_set('memory_limit', '1024M');


if (php_sapi_name() !== 'cli') {

    header("Content-Type: text/plain");

}


while (ob_get_level() > 0) {

    ob_end_flush();

}


ob_implicit_flush(true);


function out($msg){

    echo $msg . PHP_EOL;

    flush();

}


// ==========================================================

// DATABASE

// ==========================================================

try {


    $pdo = new PDO(

        "mysql:host=localhost;dbname=mts_db;charset=utf8mb4",

        "root",

        "",

        [

            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,

            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC

        ]

    );


} catch(Exception $e){


    die("DB CONNECTION FAILED: " . $e->getMessage());

}


// ==========================================================

// EMA

// ==========================================================

function ema_series(array $data, int $period): array {


    $count = count($data);


    if($count == 0){

        return [];

    }


    $k = 2 / ($period + 1);


    $ema = [];

    $ema[0] = (float)$data[0];


    for($i = 1; $i < $count; $i++){


        $price = (float)$data[$i];


        $ema[$i] =

            ($price * $k)

            + ($ema[$i - 1] * (1 - $k));

    }


    return $ema;

}


// ==========================================================

// SMA

// ==========================================================

function sma(array $data, int $period): array {


    $count = count($data);


    $out = array_fill(0, $count, null);


    if($count < $period){

        return $out;

    }


    for($i = $period - 1; $i < $count; $i++){


        $sum = 0;

        $valid = true;


        for($j = $i - $period + 1; $j <= $i; $j++){


            if($data[$j] === null){

                $valid = false;

                break;

            }


            $sum += $data[$j];

        }


        if($valid){

            $out[$i] = $sum / $period;

        }

    }


    return $out;

}


// ==========================================================

// SETTINGS

// ==========================================================

$limit = 500;


out("======================================================");

out("   PULLBACK TRADING [FHENRY0331] DAILY SCANNER");

out("======================================================");


// ==========================================================

// SYMBOLS

// ==========================================================

$symbols = $pdo->query("

    SELECT symbol

    FROM mts_watchlist

    ORDER BY symbol

")->fetchAll(PDO::FETCH_COLUMN);


// ==========================================================

// PREPARED INSERT

// ==========================================================

$scannerName = basename(__FILE__);


$save = $pdo->prepare("

    INSERT IGNORE INTO mts_php_signals

    (

        symbol,

        signal_date,

        signal_type,

        reason,

        close_price,

        scanner,

        timeframe,

        scanner_name

    )

    VALUES

    (

        ?,

        ?,

        ?,

        ?,

        ?,

        ?,

        'daily',

        ?

    )

");


$totalSignals = 0;


// ==========================================================

// MAIN LOOP

// ==========================================================

foreach($symbols as $symbol){


    try {


        $stmt = $pdo->prepare("

            SELECT

                `date`,

                open,

                high,

                low,

                close,

                volume

            FROM price_cache

            WHERE symbol = ?

            ORDER BY `date` ASC

            LIMIT {$limit}

        ");


        $stmt->execute([$symbol]);


        $rows = $stmt->fetchAll();


        $count = count($rows);


        if($count < 60){

            continue;

        }


        // ==================================================

        // ARRAYS

        // ==================================================

        $close  = array_map('floatval', array_column($rows, 'close'));

        $high   = array_map('floatval', array_column($rows, 'high'));

        $low    = array_map('floatval', array_column($rows, 'low'));

        $volume = array_map('floatval', array_column($rows, 'volume'));


        $n = $count - 1;


        // ==================================================

        // EMA

        // ==================================================

        $ema13 = ema_series($close, 13);

        $ema26 = ema_series($close, 26);


        // ==================================================

        // FORCE INDEX

        // EFI = (Close - PrevClose) * Volume

        // ==================================================

        $efi = array_fill(0, $count, null);


        for($i = 1; $i < $count; $i++){


            $efi[$i] =

                ($close[$i] - $close[$i - 1]) *

                $volume[$i];

        }


        // ==================================================

        // EFI SMOOTH

        // ==================================================

        $efiSmooth = sma($efi, 2);


        $efiNow  = $efiSmooth[$n];

        $efiPrev = $efiSmooth[$n - 1] ?? null;


        if($efiNow === null || $efiPrev === null){

            continue;

        }


        // ==================================================

        // TREND FILTER

        // ==================================================

        $uptrend =

            $ema13[$n] > $ema26[$n] &&

            $ema13[$n] > $ema13[$n - 1] &&

            $close[$n] > $ema26[$n];


        $downtrend =

            $ema13[$n] < $ema26[$n] &&

            $ema13[$n] < $ema13[$n - 1] &&

            $close[$n] < $ema26[$n];


        // ==================================================

        // PULLBACK CONDITIONS

        // ==================================================

        $bull =

            $uptrend &&

            $efiNow < 0 &&

            $efiPrev >= 0 &&

            $low[$n] <= $ema13[$n] &&

            $close[$n] > $ema13[$n];


        $bear =

            $downtrend &&

            $efiNow > 0 &&

            $efiPrev <= 0 &&

            $high[$n] >= $ema13[$n] &&

            $close[$n] < $ema13[$n];


        if(!$bull && !$bear){

            continue;

        }


        $signal = $bull ? 'BUY' : 'SELL';


        // ==================================================

        // METRICS

        // ==================================================

        $distance =

            abs($close[$n] - $ema13[$n]) /

            max($ema13[$n], 0.0001) * 100;


        $efiStrength =

            abs($efiNow) /

            max(abs($efiPrev), 1);


        $reason =

            "pullback_fhenry_daily_" . strtolower($signal) .

            " | efi:" . round($efiNow) .

            " ema13:" . round($ema13[$n], 2) .

            " ema26:" . round($ema26[$n], 2) .

            " dist:" . round($distance, 2) . "%" .

            " strength:" . round($efiStrength, 2);


        // ==================================================

        // SAVE

        // ==================================================

        $save->execute([

            $symbol,

            $rows[$n]['date'],

            $signal,

            $reason,

            $close[$n],

            $scannerName,

            $scannerName

        ]);


        $totalSignals++;


        out(sprintf(

            "%-12s | %-4s | Close: %-10.2f | EFI: %-12s | EMA13: %-10.2f | STR: %.2f 🔥",

            $symbol,

            $signal,

            $close[$n],

            round($efiNow),

            $ema13[$n],

            $efiStrength

        ));


    } catch(Exception $e){


        out("ERROR {$symbol} : " . $e->getMessage());

    }

}


out("======================================================");

out("TOTAL SIGNALS : {$totalSignals}");

out("PULLBACK TRADING DAILY SCAN COMPLETE");

out("======================================================");

?>

Comments

Popular posts from this blog

OVERSOLD BY LINEAR REGRESSION

Top No-Code Algo Trading Platforms in India (2025) – Full Comparison & Ranking

OVERSOLD BY LINEAR REGRESSION