<?php
die();
date_default_timezone_set("Asia/Tehran");
error_reporting(E_ALL);
ini_set('display_errors', '1');


$symbols = ['BONKUSDT', 'FLOKIUSDT', 'SATSUSDT', 'MEWUSDT', 'CKBUSDT'];

//===================================================================================== PLACE ORDER
$MaxVol = 1;
$leverage = 20;
$apiSecret = '2B730CF8D25475B25BA430F6563B634B3F5B84DB50079385';
$apiKey = '164EB52B11B44AE3A1BDEEB4211C0A03';

//======================================================================================= ORDER Conditions
$min = date('i');

while ($min == date('i')) {

    $data = readJson('data/ichi_bb_sar.json');
//    $data = json_decode($jsonData, true);

    if (!isset($data)) continue;
    foreach ($data as $symbol => $values) {
        if ($symbol == 'time') continue; // Skip the time field
//-------------------------------------------
//    $symbol = 'ADAUSDT';
//-------------------------------------------


        $depth = getMarketDepth($symbol);
        if (!isset($depth['depth']) || !isset($values['close'])) continue;
        $firstAsk = $depth['depth']['asks'][0][0] ?? null;
        $firstBid = $depth['depth']['bids'][0][0] ?? null;
        $LastPrice = $depth['depth']['last'] ?? null;


        // Extract values from JSON data
        $close = $values['close'];
        $high = $values['high'];
        $low = $values['low'];
        $high1 = $values['high1'];
        $low1 = $values['low1'];
        $conversionLine = $values['conversionLine'];
        $baseLine = $values['baseLine'];
        $conversionLine1 = $values['conversionLine1'];
        $baseLine1 = $values['baseLine1'];
        $leadingSpanA = $values['leadingSpanA'];
        $leadingSpanB = $values['leadingSpanB'];
        $leadingSpanA1 = $values['leadingSpanA1'];
        $leadingSpanB1 = $values['leadingSpanB1'];
        $upperBollinger = $values['bbupper'];
        $middleBollinger = $values['bbbasis'];
        $middleBollinger1 = $values['bbbasis1'];
        $lowerBollinger = $values['bblower'];
        $sar_signal = $values['sar'];
        $sar_signal1 = $values['sar1'];

        if (isset($_GET['test'])) {
            $orders = GetUnfilledOrders($apiKey, $apiSecret, 'FUTURES', 'buy');
            $findOrder = null;
            $price = '0.3200';
            if (isset($orders['data']))
                foreach ($orders['data'] as $order) {
                    if (isset($order['market']) && $order['market'] == 'ADAUSDT') {
                        echo $order['market'];
                        $findOrder = $order;
                        break;
                    }
                }
            if ($findOrder != null) {
                $unfilledPercentage = $findOrder['unfilled_amount'] / $findOrder['amount'];
                $tuu=($findOrder['created_at']/1000);
                echo '<br>' . $unfilledPercentage . '<br>'.$tuu.'<br>'.time();
//                die();
                if ($unfilledPercentage < 0.1 || $findOrder['created_at']/1000 > time() - 120) { // اگر مقدار باقیمانده کمتر از ۱۰ درصد است
                    $res3 = CancelOrder($apiKey, $apiSecret, 'ADAUSDT', 'FUTURES', $findOrder['order_id']);
                    print_r($res3);
                } else
                    if ($findOrder['last_filled_price'] != $price) {
                        $res4 = ModifyOrder($apiKey, $apiSecret, 'ADAUSDT', 'FUTURES', $findOrder['order_id'], $findOrder['unfilled_amount'], $price);
                        print_r($res4);
                    }

            }
            die();
        }


        $longCondition = ($sar_signal == 'long' && $conversionLine >= $baseLine && ($low > max($leadingSpanB, $leadingSpanA)) &&
            ($upperBollinger > $leadingSpanA) && ($low > $middleBollinger));

        $shortCondition = ($sar_signal == 'short' && $conversionLine <= $baseLine && $high < min($leadingSpanB, $leadingSpanA) &&
            ($lowerBollinger < $leadingSpanB) && ($high < $middleBollinger));

        if ($longCondition)
            if ($sar_signal1 == 'short' ||
                CrossUp($conversionLine, $conversionLine1, $baseLine, $baseLine1) ||
                ($low1 <= max($leadingSpanB, $leadingSpanA))) {
                manageOrder($apiKey, $apiSecret, $symbol, 'FUTURES', 'long', ($MaxVol / $LastPrice * $leverage), $LastPrice, $leverage);
            }

        if ($shortCondition)
            if ($sar_signal1 == 'long' ||
                CrossDown($conversionLine, $conversionLine1, $baseLine, $baseLine1) ||
                $high1 >= min($leadingSpanB, $leadingSpanA)) {
                manageOrder($apiKey, $apiSecret, $symbol, 'FUTURES', 'short', ($MaxVol / $LastPrice * $leverage), $LastPrice, $leverage);
            }


// Exit condition for long
        if ($sar_signal == 'short' || ($conversionLine < $baseLine)) {
            $positions = GetCurrentPositions($apiKey, $apiSecret, 'FUTURES');
            $hasLongOpenPosition = false;
            foreach ($positions['data'] as $position) {
                if ($position['market'] == $symbol && $position['side'] == "long") {
                    $hasLongOpenPosition = true;
                    break;
                }
            }
            if ($hasLongOpenPosition)
                $orderResponse = ClosePosition(
                    $apiKey,
                    $apiSecret,
                    $symbol,
                    'FUTURES',
                    'limit',
                    $firstAsk - (($firstAsk - $firstBid)) / 4
                );
        }


// Exit condition for short
        if ($sar_signal == 'long' || ($conversionLine > $baseLine)) {
            $positions = GetCurrentPositions($apiKey, $apiSecret, 'FUTURES');
            $hasShortOpenPosition = false;
            foreach ($positions['data'] as $position) {
                if ($position['market'] == $symbol && $position['side'] == "short") {
                    $hasShortOpenPosition = true;
                    break;
                }
            }
            if ($hasShortOpenPosition)
                $orderResponse = ClosePosition(
                    $apiKey,
                    $apiSecret,
                    $symbol,
                    'FUTURES',
                    'limit',
                    $firstAsk - (($firstAsk - $firstBid)) / 4
                );
        }
    }
    sleep(2);
}
//========================================================== End of Main
//========================================================== End of Main

function readJson($path)
{
    if (!filesize($path))
        return [];

    $response = file_get_contents($path);
    return json_decode($response, true);
}

function GetUnfilledOrders($apiKey, $apiSecret, $marketType, $side) //, $market=null
{
    $method = 'GET';
    $request_path = '/v2/futures/pending-order';
    $params = [
//        'market' => $market,
        'market_type' => $marketType,
        'side' => $side,
        'limit' => 25
    ];
    $query_string = http_build_query($params);
    $url = 'https://api.coinex.com' . $request_path . '?' . $query_string;
    $timestamp = round(microtime(true) * 1000);
    $prepared_str = $method . $request_path . '?' . $query_string . $timestamp;
    $signed_str = hash_hmac('sha256', $prepared_str, $apiSecret);
    $headers = [
        'Accept: application/json',
        'X-COINEX-KEY: ' . $apiKey,
        'X-COINEX-SIGN: ' . $signed_str,
        'X-COINEX-TIMESTAMP: ' . $timestamp
    ];
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($ch);
    if ($response === false) {
        $response = curl_error($ch);
    }
    curl_close($ch);
    return json_decode($response, true);
}


function GetCurrentPositions($apiKey, $apiSecret, $marketType) //, $market=null
{
    $method = 'GET';
    $request_path = '/v2/futures/pending-position';
    $params = [
//        'market' => $market,
        'market_type' => $marketType
    ];
    $query_string = http_build_query($params);
    $url = 'https://api.coinex.com' . $request_path . '?' . $query_string;
    $timestamp = round(microtime(true) * 1000);
    $prepared_str = $method . $request_path . '?' . $query_string . $timestamp;
    $signed_str = hash_hmac('sha256', $prepared_str, $apiSecret);
    $headers = [
        'Accept: application/json',
        'X-COINEX-KEY: ' . $apiKey,
        'X-COINEX-SIGN: ' . $signed_str,
        'X-COINEX-TIMESTAMP: ' . $timestamp
    ];
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($ch);
    if ($response === false) {
        $response = curl_error($ch);
    }
    curl_close($ch);
    return json_decode($response, true);
}


function placeOrder($apiKey, $apiSecret, $market, $marketType, $side, $type, $amount, $price, $leverage, $clientId = null, $isHide = false)
{
    $SL = 0.1;  //10%
    $orderResponse1 = SetMarginLeverage(
        $apiKey,
        $apiSecret,
        $market,
        'FUTURES',
        'isolated',
        $leverage
    );

    $method = 'POST';
    $request_path = '/v2/futures/order';//'/v2/futures/stop-order';
    $url = 'https://api.coinex.com' . $request_path;
    $params = json_encode([
        'market' => $market,
        'market_type' => $marketType,
        'side' => $side,
        'type' => $type,
        'amount' => $amount,
        'price' => $price,
//        'trigger_price_type' => 'latest_price',
//        'trigger_price' => $side == 'buy' ? $price - ($price * $SL) : $price + ($price * $SL),
        'is_hide' => (bool)$isHide,
        'stp_mode' => 'both'
    ]);
    $timestamp = round(microtime(true) * 1000);
    $prepared_str = $method . $request_path . $params . $timestamp;
    $signed_str = hash_hmac('sha256', $prepared_str, $apiSecret);
    $headers = [
        'X-COINEX-KEY: ' . $apiKey,
        'X-COINEX-SIGN: ' . $signed_str,
        'X-COINEX-TIMESTAMP: ' . $timestamp,
        'Content-Type: application/json'
    ];
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($ch);
    if ($response === false) {
        $response = curl_error($ch);
    }
    curl_close($ch);
    return json_decode($response, true);
}

function SetMarginLeverage($apiKey, $apiSecret, $market, $marketType, $margin_mode, $leverage)
{
    $method = 'POST';
    $request_path = '/v2/futures/adjust-position-leverage';
    $url = 'https://api.coinex.com' . $request_path;
    $params = json_encode([
        'market' => $market,
        'market_type' => $marketType,
        'margin_mode' => $margin_mode,
        'leverage' => $leverage
    ]);
    $timestamp = round(microtime(true) * 1000);
    $prepared_str = $method . $request_path . $params . $timestamp;
    $signed_str = hash_hmac('sha256', $prepared_str, $apiSecret);
    $headers = [
        'X-COINEX-KEY: ' . $apiKey,
        'X-COINEX-SIGN: ' . $signed_str,
        'X-COINEX-TIMESTAMP: ' . $timestamp,
        'Content-Type: application/json'
    ];
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($ch);
    if ($response === false) {
        $response = curl_error($ch);
    }
    curl_close($ch);
    return json_decode($response, true);
}

function ModifyOrder($apiKey, $apiSecret, $market, $marketType, $order_id, $amount, $price)
{
    $method = 'POST';
    $request_path = '/v2/futures/modify-order';
    $url = 'https://api.coinex.com' . $request_path;
    $params = json_encode([
        'market' => $market,
        'market_type' => $marketType,
        'order_id' => $order_id,
        'amount' => $amount,
        'price' => $price
    ]);
    $timestamp = round(microtime(true) * 1000);
    $prepared_str = $method . $request_path . $params . $timestamp;
    $signed_str = hash_hmac('sha256', $prepared_str, $apiSecret);
    $headers = [
        'X-COINEX-KEY: ' . $apiKey,
        'X-COINEX-SIGN: ' . $signed_str,
        'X-COINEX-TIMESTAMP: ' . $timestamp,
        'Content-Type: application/json'
    ];
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($ch);
    if ($response === false) {
        $response = curl_error($ch);
    }
    curl_close($ch);
    return json_decode($response, true);
}

function CancelOrder($apiKey, $apiSecret, $market, $marketType, $order_id)
{
    $method = 'POST';
    $request_path = '/v2/futures/cancel-order';
    $url = 'https://api.coinex.com' . $request_path;
    $params = json_encode([
        'market' => $market,
        'market_type' => $marketType,
        'order_id' => $order_id
    ]);
    $timestamp = round(microtime(true) * 1000);
    $prepared_str = $method . $request_path . $params . $timestamp;
    $signed_str = hash_hmac('sha256', $prepared_str, $apiSecret);
    $headers = [
        'X-COINEX-KEY: ' . $apiKey,
        'X-COINEX-SIGN: ' . $signed_str,
        'X-COINEX-TIMESTAMP: ' . $timestamp,
        'Content-Type: application/json'
    ];
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $response = curl_exec($ch);
    if ($response === false) {
        $response = curl_error($ch);
    }
    curl_close($ch);
    return json_decode($response, true);
}

function ClosePosition($apiKey, $apiSecret, $market, $marketType, $type, $price, $clientId = null, $isHide = false)
{
    $method = 'POST';
    $request_path = '/v2/futures/close-position';
    $url = 'https://api.coinex.com' . $request_path;

    $params = json_encode([
        'market' => $market,
        'market_type' => $marketType,
        'type' => $type,
        'price' => $price,
        'is_hide' => (bool)$isHide,
        'stp_mode' => 'both'
    ]);

    $timestamp = round(microtime(true) * 1000);
    $prepared_str = $method . $request_path . $params . $timestamp;
    $signed_str = hash_hmac('sha256', $prepared_str, $apiSecret);

    $headers = [
        'X-COINEX-KEY: ' . $apiKey,
        'X-COINEX-SIGN: ' . $signed_str,
        'X-COINEX-TIMESTAMP: ' . $timestamp,
        'Content-Type: application/json'
    ];

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
//    curl_setopt($ch, CURLOPT_PROXY, 'localhost');
//    curl_setopt($ch, CURLOPT_PROXYPORT, '10809');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    $response = curl_exec($ch);
    if ($response === false) {
        $response = curl_error($ch);
    }
    curl_close($ch);

    return json_decode($response, true);
}

function getMarketDepth($market, $limit = 5, $interval = "0")
{
    $url = 'https://api.coinex.com/v2/futures/depth';
    $query = http_build_query([
        'market' => $market,
        'limit' => $limit,
        'interval' => $interval
    ]);
    $finalUrl = $url . '?' . $query;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $finalUrl);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//    curl_setopt($ch, CURLOPT_PROXY, 'localhost');
//    curl_setopt($ch, CURLOPT_PROXYPORT, '10809');
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json'
    ]);
    $response = curl_exec($ch);
    curl_close($ch);
    $responseData = json_decode($response, true);
    return $responseData['data'];
}

function CrossUp($a, $a1, $b, $b1): bool
{
    if ($a1 < $b1 && $a >= $b)
        return true;
    else return false;
}

function CrossDown($a, $a1, $b, $b1): bool
{
    if ($a1 > $b1 && $a <= $b)
        return true;
    else return false;
}


function manageOrder($apiKey, $apiSecret, $market, $marketType, $side, $amount, $price, $leverage)
{
    file_put_contents('logsami_up.txt', json_encode([$market, $marketType, $side, $amount, $price, $leverage]) . PHP_EOL, FILE_APPEND);

    $positions = GetCurrentPositions($apiKey, $apiSecret, $marketType);
    $hasOpenPosition = false;
    if (isset($positions['data']))
        foreach ($positions['data'] as $position) {
            if (isset($positions['market']) && $position['market'] == $market) {
                $hasOpenPosition = true;
                break;
            }
        }


    if (!$hasOpenPosition) {
        $orders = GetUnfilledOrders($apiKey, $apiSecret, $marketType, $side == "short" ? 'sell' : 'buy');
        $findOrder = null;
        if (isset($orders['data']))
            foreach ($orders['data'] as $order) {
                if (isset($order['market']) && $order['market'] == $market) {
                    $findOrder = $order;
                    break;
                }
            }

        if ($findOrder != null) {
            $unfilledPercentage = $findOrder['unfilled_amount'] / $findOrder['amount'];

            if ($unfilledPercentage < 0.1 || $findOrder['created_at']/1000 > time() - 120) { // اگر مقدار باقیمانده کمتر از ۱۰ درصد است
                CancelOrder($apiKey, $apiSecret, $market, $marketType, $findOrder['order_id']);
            } else {
                if ($findOrder['last_filled_price'] != $price)
                    ModifyOrder($apiKey, $apiSecret, $market, $marketType, $findOrder['order_id'], $findOrder['unfilled_amount'], $price);
            }
        } else {
            file_put_contents('logsami.txt', json_encode([$market, $marketType, $side == "short" ? 'sell' : 'buy', 'limit', $amount, $price, $leverage]) . PHP_EOL, FILE_APPEND);

            $res = placeOrder($apiKey, $apiSecret, $market, $marketType, $side == "short" ? 'sell' : 'buy', 'limit', $amount, $price, $leverage);

        }
    }
    sleep(5);
}