DATA/STOCK/daemon/korea/0100/stock_total_env.php
<?php
// ============================================================
// 환경기 : stock_total_env.php
// DB 연결, 종목 로드, 바구니 세팅까지만. 끝.
// ============================================================

function get_db_connection() {
    try {
        $db_upbit = null;
        @include '/home/www/DB/db_upbit.php';
        if (!($db_upbit instanceof PDO)) return null;
        $pdo = $db_upbit;
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        return $pdo;
    } catch (Throwable $e) {
        return null;
    }
}

function get_gnu_connection() {
    try {
        $db_gnu  = null;
        $pdo_gnu = null;
        $pdo     = null;
        @include '/home/www/DB/db_gnu.php';
        if ($db_gnu instanceof PDO) {
            $db_gnu->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            return $db_gnu;
        }
        if ($pdo_gnu instanceof PDO) {
            $pdo_gnu->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            return $pdo_gnu;
        }
        if ($pdo instanceof PDO) {
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            return $pdo;
        }
        return null;
    } catch (Throwable $e) {
        return null;
    }
}

// DB 연결
$pdo     = get_db_connection();
$pdo_gnu = get_gnu_connection();

// 종목 로드 (x2_run 있는 행만)
if ($pdo_gnu) {
    $stmt = $pdo_gnu->query("
        SELECT wr_subject, wr_subject_kr
        FROM g5_write_daemon_kind_stock
        WHERE x2_run IS NOT NULL AND x2_run != ''
    ");
    $rows = $stmt->fetchAll();
} else {
    $rows = [];
}

// 종목코드 배열로 추출
$symbols = array_column($rows, 'wr_subject');

// 40개씩 5바구니로 쪼개기 (최대 200종목)
$symbols    = array_slice($symbols, 0, 200);
$unit_packs = array_chunk($symbols, 40);

// 한투 API 키 로드
include_once '/home/www/DB/key_stock_api.php';

// 웹소켓 Approval Key 발급
$WS_APPROVAL_KEY = get_ws_approval_key($STOCK_ACCESS_KEY, $STOCK_SECRET_KEY);

// 웹소켓 URL
$WS_URL = "tcp://ops.koreainvestment.com:21000";

// ============================================================
// 웹소켓 Approval Key 발급 함수
// ============================================================
function get_ws_approval_key($appkey, $appsecret) {
    $token_file = '/tmp/kis_ws_approval.json';

    if (file_exists($token_file)) {
        $saved = json_decode(file_get_contents($token_file), true);
        if ($saved && $saved['expires'] > time() + 60) {
            return $saved['key'];
        }
    }

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://openapi.koreainvestment.com:9443/oauth2/Approval");
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
        "grant_type" => "client_credentials",
        "appkey"     => $appkey,
        "secretkey"  => $appsecret
    ]));
    curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $res = json_decode(curl_exec($ch), true);
    curl_close($ch);

    if (empty($res['approval_key'])) {
        error_log("[환경기] WS Approval Key 발급 실패");
        return '';
    }

    file_put_contents($token_file, json_encode([
        'key'     => $res['approval_key'],
        'expires' => time() + 86400 - 300
    ]));

    return $res['approval_key'];
}