<?php
//die();
date_default_timezone_set("Asia/Tehran");
error_reporting(E_ALL);
ini_set('display_errors', '1');
require_once 'functions.php';
//set_time_limit(59);


//====================================================================== start main
//$pathbest = 'data/BestCoinexStoch.json';
//$jsonData = file_get_contents($pathbest);
//$data9 = json_decode($jsonData, true);
$bestStoch = [];
$defaultValues = [
    "Stochlength" => 40,
    "StochK" => 1,
    "StochD" => 10,
    "StochLower" => 20,
    "StochUpper" => 80,
    "StochProfit" => 0,
    "RSIlength" => 14,
    "RSIupper" => 70,
    "RSIlower" => 30
];
//if (json_last_error() !== JSON_ERROR_NONE || empty($data9)) {
//    $data9 = [];
//}
//$time = $data9['time'] ?? date('Y-m-d H:i:s');
//unset($data9['time']);
//foreach ($data9 as $symbol => $StochValues)
//    $bestStoch[$symbol] = !empty($StochValues) ? $StochValues : $defaultValues;

//if (empty($bestStoch)) {
//    $bestStoch['BTCIRT'] = $defaultValues;
//    $bestStoch['ETHusdt'] = $defaultValues;
//}
//$bestStoch['ETHusdt'] = $defaultValues;

if (isset($_GET['te'])) {
    print_r($bestStoch['BTCIRT']);
    echo PHP_EOL;
    print_r($bestStoch['ETHusdt']);
    die();
}
//==================================================================
$Coinex = $binancePrice = $symbols = [];
$min = date('i');
//================================================================ read files
for ($i = 0; $i <= 3; $i++) {

    $path1 = 'data/CoinexOHLC';
    $Coinexfiles = scandir($path1);
    $StochResults = [];
    $StochResults['time'] = date('Y-m-d H:i:s');
    foreach ($Coinexfiles as $file) {
        if ($file == '.' || $file == '..')
            continue;
        $symbol = str_replace('.json', '', $file);
        $data = readJson($path1 . '/' . $file);


        if ($data) {
            if (!isset($bestStoch[$symbol]) || $bestStoch[$symbol]['StochProfit'] == 0)
                $bestStoch[$symbol] = [
                    "Stochlength" => 40,
                    "StochK" => 1,
                    "StochD" => 10,//10
                    "StochLower" => 20,
                    "StochUpper" => 80,
                    "StochProfit" => 0,
                    "RSIlength" => 14,
                    "RSIupper" => 70,
                    "RSIlower" => $bestStoch[$symbol]['RSIlower'] ?? 30
                ];
            list($StochD, $StochK) = calculateStochastic($data, $bestStoch[$symbol]['Stochlength'], $bestStoch[$symbol]['StochK'], $bestStoch[$symbol]['StochD']);

            $RSI = calculateRSI($data);
            $currntRSI = $RSI;
            if ($RSI && $RSI <= $bestStoch[$symbol]['RSIlower'])
                $RSI = 'buy';
            else
                $RSI = 'sell';

            $StochResults[$symbol] = [
                'StochK' => $StochD,
                'StochD' => $StochK,
                'StochLength' => $bestStoch[$symbol]['Stochlength'],
                'StochLower' => $bestStoch[$symbol]['StochLower'],
                'StochUpper' => $bestStoch[$symbol]['StochUpper'],
                'StochProfit' => $bestStoch[$symbol]['StochProfit'],
                'buy' => $StochD > -1 && $StochD <= $bestStoch[$symbol]['StochLower'] && $StochK > -1 && $StochK <= $bestStoch[$symbol]['StochLower'] ? 'yes' : 'no',///* && $bestStoch[$symbol]['StochProfit'] > 0*/
                'close' => isset($data->data) && isset(end($data->data)->close) ? end($data->data)->close : null,
                'RSIlength' => $bestStoch[$symbol]['RSIlength'],
                'RSIupper' => $bestStoch[$symbol]['RSIupper'],
                'RSIlower' => $bestStoch[$symbol]['RSIlower'],
                'RSIbuy' => $RSI,
                'currentRSI' => $currntRSI
            ];
        }
    }

// ذخیره نتایج ATR در فایل جیسون
    file_put_contents('data/CoinexIndicators.json', json_encode($StochResults, JSON_PRETTY_PRINT));
    if (date('s') + 15 > 58)
        break;
    else
        sleep(15);

}
//========================================================== functions


function readJson($path)
{
    if (!file_exists($path)) {
        usleep(300000);
        if (!file_exists($path)) {
            return [];
        }
    }
    $fileSize = filesize($path);
    if ($fileSize === 0) return [];

    $file = fopen($path, "r");
    if (!$file) return [];

    $response = fread($file, $fileSize);
    fclose($file);
    return json_decode($response) ?: [];
}

function calculateSMA($data, $period)
{
    $sma = [];
    for ($i = 0; $i <= count($data) - $period; $i++) {
        $sma[] = array_sum(array_slice($data, $i, $period)) / $period;
    }
    return $sma;
}

function calculateStochastic($klines, $period = 40, $kSmoothing = 1, $dSmoothing = 10)
{
    $klines = $klines->data;
//print_r($klines);
//die();
    if ($klines) {
        $highPrices = $lowPrices = $closePrices = [];
        foreach ($klines as $kline) {
            // Check if the required properties exist in the current object
            if (isset($kline->high) && isset($kline->low) && isset($kline->close)) {
                // Add the values to their respective arrays
                $highPrices[] = $kline->high;
                $lowPrices[] = $kline->low;
                $closePrices[] = $kline->close;
            }
        }

        $stochasticValues = [];

        // محاسبه مقادیر استوکاستیک K
        for ($i = 0; $i <= count($closePrices) - $period; $i++) {
            $currentClose = $closePrices[$i + $period - 1];
            $currentLow = min(array_slice($lowPrices, $i, $period));
            $currentHigh = max(array_slice($highPrices, $i, $period));

            $stochastic = ($currentHigh - $currentLow == 0) ? 50 : 100 * (($currentClose - $currentLow) / ($currentHigh - $currentLow));

            $stochasticValues[] = $stochastic;
        }

        // محاسبه مقادیر SMA برای K و D
        $kValues = calculateSMA($stochasticValues, $kSmoothing);
        $dValues = calculateSMA($kValues, $dSmoothing);

        if (!empty($dValues) && !empty($kValues)) {
            return [
                $dValues[count($dValues) - 1],
                $kValues[count($kValues) - 1]
            ];
        }
    }

    return [null, null];
}


//function calculateRSI($data, $length = 14)
//{
//    $data = $data->data;
//    /*  if (isset($data->close) && is_array($data->close))
//          $data = $data->close;
//      else
//          return null;*/
//
//    if ($data) {
//        foreach ($data as $datas)
//            if (isset($datas->close))
//                $closePrices[] = $datas->close;
//    } else
//        return null;
//
//    if (count($closePrices) < $length + 1) {
//        return null;
//    }
//
//    $gains = $losses = [];
//    for ($i = $length + 2; $i < count($closePrices); $i++) {
//        $change = $closePrices[$i] - $closePrices[$i - 1];
//        $gains[] = $change > 0 ? $change : 0;
//        $losses[] = $change < 0 ? abs($change) : 0;
//    }
//
//    $avgGain = array_sum(array_slice($gains, 0, $length)) / $length;
//    $avgLoss = array_sum(array_slice($losses, 0, $length)) / $length;
//
//    $rsi = [];
//    for ($i = $length; $i < count($gains); $i++) {
//        $avgGain = (($avgGain * ($length - 1)) + $gains[$i]) / $length;
//        $avgLoss = (($avgLoss * ($length - 1)) + $losses[$i]) / $length;
//        $avgGain = max($avgGain, 0.0001); // جلوگیری از صفر شدن avgGain
//        $avgLoss = max($avgLoss, 0.0001); // جلوگیری از صفر شدن avgLoss
//        $rs = $avgLoss == 0 ? 100 : $avgGain / $avgLoss;
//        $rsi[] = round((100 - (100 / (1 + $rs))), 2);
//    }
//
//    return  $rsi[count($rsi) - 1];
//}

function calculateRSI($data, $length = 14)
{
    if (!isset($data->data) || !is_array($data->data)) {
        return null;
    }

    $closePrices = [];
    foreach ($data->data as $candle) {
        if (isset($candle->close)) {
            $closePrices[] = $candle->close;
        }
    }

    if (count($closePrices) < $length + 1) {
        return null;
    }

    $gains = [];
    $losses = [];

    // محاسبه‌ی اولیه برای avgGain و avgLoss
    for ($i = 1; $i <= $length; $i++) {
        $change = $closePrices[$i] - $closePrices[$i - 1];
        if ($change > 0) {
            $gains[] = $change;
            $losses[] = 0;
        } else {
            $gains[] = 0;
            $losses[] = abs($change);
        }
    }

    $avgGain = array_sum($gains) / $length;
    $avgLoss = array_sum($losses) / $length;

    // حالا ادامه‌ی محاسبه RSI برای کندل‌های بعدی
    for ($i = $length + 1; $i < count($closePrices); $i++) {
        $change = $closePrices[$i] - $closePrices[$i - 1];
        $gain = $change > 0 ? $change : 0;
        $loss = $change < 0 ? abs($change) : 0;

        // محاسبه‌ی میانگین‌ها به روش EMA
        $avgGain = (($avgGain * ($length - 1)) + $gain) / $length;
        $avgLoss = (($avgLoss * ($length - 1)) + $loss) / $length;
    }

    // جلوگیری از تقسیم بر صفر
    if ($avgLoss == 0) {
        return 100.0;
    }

    $rs = $avgGain / $avgLoss;
    $rsi = 100 - (100 / (1 + $rs));

    return round($rsi, 2);
}
