<?php
//die();
date_default_timezone_set("Asia/Tehran");
error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('memory_limit', '512M');
ini_set('max_execution_time', '120');

$symbols = [];
$min = date('i');

while ($min == date('i')) {
    $syms = readJson('data/symbols.json');
    if (!$syms) {
        sleep(1);
        continue;
    }
    $symbols = $syms;// [];
//    foreach ($syms as $val) {
//        $symbolFormatted = str_replace(['1K_', '100K_', '1M_', '1B_'], ['', '', '', '1M'], $val);
//        $symbols[] = $symbolFormatted;
//    }
    break;
}

$urls = [];
foreach ($symbols as $market) {
    $urls[$market] = "https://api.binance.com/api/v1/klines?symbol=" . $market . "&interval=1m&limit=300";//uae
}

$jsonDataSar2 = ['time' => date('Y-m-d H:i:s')];
$candles = [];

if (count($urls) > 10) {
    $chunks = sliceArrayIntoFiveParts($urls);
    foreach ($chunks as $chunk) {
        $candles += multiple_threads_request($chunk);
    }
} else {
    $candles = multiple_threads_request($urls);
}

foreach ($symbols as $market) {
    if (!isset($candles[$market])) continue;
    $binancedata = json_decode($candles[$market], true);
    if (!$binancedata || !isset($binancedata[0][2])) continue;
    $result = calculateBest($binancedata);


    $jsonDataSar2[$market] = $result;
   /* if (str_ends_with($market, 'FLOKIUSDT')) {
        $jsonDataSar2['100K_FLOKIUSDT'] = $result;
    }
    if (str_ends_with($market, 'PEPEUSDT')) {
        $jsonDataSar2['1M_PEPEUSDT'] = $result;
    }
    if (str_ends_with($market, 'BABYDOGEUSDT')) {
        $jsonDataSar2['1B_BABYDOGEUSDT'] = $result;
    }
    if (str_ends_with($market, 'BONKUSDT')) {
        $jsonDataSar2['1K_BONKUSDT'] = $result;
    }*/

}

file_put_contents('data/BestSAR.json', json_encode($jsonDataSar2, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));

//===================================================================functions
function calculateBest($data)
{
//
//    $candleData = [];
//    foreach ($data as $candle) {
//        $candleData[] = [
//            $candle[0] / 1000,
//            (float)$candle[1],
//            (float)$candle[2],
//            (float)$candle[3],
//            (float)$candle[4]
//        ];
//    }

    $sarStartRange = [0.01, 0.09];
    $sarIncRange = [0.01, 0.09];
    $maxRange = [0.1, 0.6];
    $bestProfit = -INF;
    $bestSarParams = null;
    $feeRate = 0.0005;

    for ($start = $sarStartRange[0]; $start <= $sarStartRange[1]; $start += 0.01) {
        for ($inc = $sarIncRange[0]; $inc <= $sarIncRange[1]; $inc += 0.01) {
            for ($max = $maxRange[0]; $max <= $maxRange[1]; $max += 0.1) {
                $sarData = calculateSAR($data, $start, $inc, $max);
                $profit = calculateProfit($data, $sarData, $feeRate);
                if ($profit > $bestProfit) {
                    $bestProfit = $profit;
                    $bestSarParams = ['start' => $start, 'inc' => $inc, 'max' => $max];
                }
            }
        }
    }
    return [
        round($bestSarParams['start'], 2),
        round($bestSarParams['inc'], 2),
        round($bestSarParams['max'], 2)
    ];
}

function sliceArrayIntoFiveParts($array)
{
    $totalElements = count($array);
    $baseSize = intdiv($totalElements, 10);
    $remainder = $totalElements % 10;

    $chunks = [];
    $start = 0;

    for ($i = 0; $i < 10; $i++) {
        $additionalElement = ($i < $remainder) ? 1 : 0;
        $chunkSize = $baseSize + $additionalElement;
        $chunks[] = array_slice($array, $start, $chunkSize);
        $start += $chunkSize;
    }

    return $chunks;
}

function calculateSAR($klines, $start, $inc, $max)
{
    $sar = [];
    $ep = $klines[0][2];
    $af = $start;
    $isUptrend = $klines[0][4] > $klines[0][1];
    $sar[0] = $isUptrend ? $klines[0][3] : $klines[0][2];

    for ($i = 1; $i < count($klines); $i++) {
        $sar[$i] = $sar[$i - 1] + $af * ($ep - $sar[$i - 1]);

        if ($isUptrend) {
            if ($klines[$i][3] < $sar[$i]) {
                $isUptrend = false;
                $sar[$i] = $ep;
                $ep = $klines[$i][3];
                $af = $start;
            } else {
                if ($klines[$i][2] > $ep) {
                    $ep = $klines[$i][2];
                    $af = min($af + $inc, $max);
                }
                $sar[$i] = min($sar[$i], $klines[$i - 1][3]);
                if ($i > 1) $sar[$i] = min($sar[$i], $klines[$i - 2][3]);
            }
        } else {
            if ($klines[$i][2] > $sar[$i]) {
                $isUptrend = true;
                $sar[$i] = $ep;
                $ep = $klines[$i][2];
                $af = $start;
            } else {
                if ($klines[$i][3] < $ep) {
                    $ep = $klines[$i][3];
                    $af = min($af + $inc, $max);
                }
                $sar[$i] = max($sar[$i], $klines[$i - 1][2]);
                if ($i > 1) $sar[$i] = max($sar[$i], $klines[$i - 2][2]);
            }
        }
    }

    return $sar;
}

function calculateProfit($data, $sarData, $feeRate)
{
    $profit = 0;
    $position = null;

    for ($i = 1; $i < count($sarData); $i++) {
        $sar = $sarData[$i];
        $closePrice = $data[$i][4];

        if ($closePrice > $sar && $position === null) {
            $position = $closePrice;
        } elseif ($closePrice < $sar && $position !== null) {
            $profit += ($closePrice - $position) * (1 - $feeRate);
            $position = null;
        }
    }

    return $profit;
}

function multiple_threads_request($nodes, $timeout = 15)
{
    $mh = curl_multi_init();
    $curl_array = [];

    foreach ($nodes as $i => $url) {
        $curl_array[$i] = curl_init($url);
        curl_setopt_array($curl_array[$i], [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => $timeout,           // زمان ماکزیمم برای هر درخواست
            CURLOPT_CONNECTTIMEOUT => 5,           // زمان اتصال اولیه
            CURLOPT_SSL_VERIFYPEER => false,       // اختیاری برای تست
            CURLOPT_SSL_VERIFYHOST => false        // اختیاری برای تست
        ]);
        curl_multi_add_handle($mh, $curl_array[$i]);
    }

    $startTime = microtime(true);
    $running = null;

    do {
        $status = curl_multi_exec($mh, $running);
        if ($running) {
            curl_multi_select($mh, 1); // حداکثر 1 ثانیه صبر کن
        }

        // اگر از کل تایم‌اوت بیشتر طول کشید، عملیات را متوقف کن
       /* if ((microtime(true) - $startTime) > ($timeout + 2)) {
            break;
        }*/

    } while ($running && $status == CURLM_OK);

    $res = [];
    foreach ($curl_array as $i => $ch) {
        if (curl_errno($ch)) {
            $res[$i] = null; // خطا در اتصال یا تایم‌اوت
        } else {
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $res[$i] = ($http_code == 200) ? curl_multi_getcontent($ch) : null;
        }
    }

    foreach ($curl_array as $ch) {
        curl_multi_remove_handle($mh, $ch);
        curl_close($ch);
    }
    curl_multi_close($mh);

    return $res;
}



function curl($url)
{
    $curl = curl_init();

    curl_setopt_array($curl, array(
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => '',
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 0,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => 'GET',
    ));

    $response = curl_exec($curl);

    curl_close($curl);

    return $response;
}

function readJson($path)
{
    if (!filesize($path))
        usleep(300000);

    if (!filesize($path))
        return [];

    $file = fopen($path, "r");
    $response = fread($file, filesize($path));
    fclose($file);

    return json_decode($response);
}