"; echo "

⚠️ [치명적 오류] 발생

"; echo "메시지: " . htmlspecialchars((string)$error['message'], ENT_QUOTES, 'UTF-8') . "
"; echo "파일: " . htmlspecialchars((string)$error['file'], ENT_QUOTES, 'UTF-8') . "
"; echo "라인: " . (int)$error['line']; echo ""; } }); function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES|ENT_SUBSTITUTE, 'UTF-8'); } function badge($k,$v, $class=''){ echo "
".h($k)." ".h($v)."
"; } /* -------------------------- * (0) 보안 * -------------------------- */ $TOKEN = ''; $ALLOW_IPS = []; $k = $_GET['k'] ?? ''; $client_ip = $_SERVER['REMOTE_ADDR'] ?? ''; if ($TOKEN !== '' && $k !== $TOKEN) { http_response_code(403); echo "접근 거부\n"; exit; } if (!empty($ALLOW_IPS) && !in_array($client_ip, $ALLOW_IPS, true)) { http_response_code(403); echo "IP 거부\n"; exit; } /* -------------------------- * (1) trading 폴더 고정 * -------------------------- */ $ROOT = '/home/www'; $BASE = $ROOT . '/DATA/UPBIT/daemon/trading'; $ENV = $BASE . '/db_calculation_environment.php'; $SETTING = $BASE . '/setting_daemon_trading.php'; $BRAIN = $BASE . '/brain_daemon_trading.php'; $ENGINE1 = $BASE . '/brain_engine_1.php'; $ENGINE2 = $BASE . '/brain_engine_2.php'; $daemon_id = 'monitor_chain'; if (!defined('ENGINE2_NO_HTML')) define('ENGINE2_NO_HTML', true); /* -------------------------- * (2) 단계별 파일 점검 및 실행 (순서 및 로직 보강) * -------------------------- */ $chain_status = [ '환경(ENV)' => ['path' => $ENV, 'exists' => '없음', 'load' => '대기'], '설정(SETTING)' => ['path' => $SETTING, 'exists' => '없음', 'load' => '대기'], '브레인(BRAIN)' => ['path' => $BRAIN, 'exists' => '없음', 'load' => '대기'], '엔진1(ENGINE1)' => ['path' => $ENGINE1, 'exists' => '없음', 'load' => '대기'], '엔진2(ENGINE2)' => ['path' => $ENGINE2, 'exists' => '없음', 'load' => '대기'], ]; $ok = true; $err = ''; // 1. 환경 및 설정 로드 (DB 연결, 함수 정의) foreach (['환경(ENV)', '설정(SETTING)'] as $key) { $info = &$chain_status[$key]; if (is_file($info['path'])) { $info['exists'] = '확인'; try { require_once $info['path']; $info['load'] = '성공'; } catch (Throwable $e) { $info['load'] = '실패'; $ok = false; $err = "[$key] " . $e->getMessage(); } } else { $info['exists'] = '미발견'; $ok = false; } } // 2. 키 로드 (모니터링을 위해 명시적 호출) if ($ok && function_exists('upbit_key_load')) { upbit_key_load(); } // 3. 브레인 로드 ($rows 생성) if ($ok) { $info = &$chain_status['브레인(BRAIN)']; if (is_file($info['path'])) { $info['exists'] = '확인'; try { require $info['path']; // require_once 대신 require 사용 (재실행 고려) $info['load'] = '성공'; } catch (Throwable $e) { $info['load'] = '실패'; $ok = false; $err = "[브레인] " . $e->getMessage(); } } else { $info['exists'] = '미발견'; $ok = false; } } // 4. 엔진1 로드 ($ticker_map, $accounts_map 생성) if ($ok) { $info = &$chain_status['엔진1(ENGINE1)']; if (is_file($info['path'])) { $info['exists'] = '확인'; try { // 엔진1 실행 전 필수 변수 확인 if (!isset($rows) || !is_array($rows)) $rows = $GLOBALS['rows'] ?? []; require $info['path']; $info['load'] = '성공'; } catch (Throwable $e) { $info['load'] = '실패'; $ok = false; $err = "[엔진1] " . $e->getMessage(); } } else { $info['exists'] = '미발견'; $ok = false; } } // 5. 엔진2 로드 (신호 생성 시뮬레이션) if ($ok) { $info = &$chain_status['엔진2(ENGINE2)']; if (is_file($info['path'])) { $info['exists'] = '확인'; try { require $info['path']; $info['load'] = '성공'; } catch (Throwable $e) { $info['load'] = '실패'; $ok = false; $err = "[엔진2] " . $e->getMessage(); } } else { $info['exists'] = '미발견'; $ok = false; } } // 전역 변수 동기화 if (empty($UPBIT_ACCESS_KEY) && !empty($GLOBALS['UPBIT_ACCESS_KEY'])) $UPBIT_ACCESS_KEY = $GLOBALS['UPBIT_ACCESS_KEY']; if (empty($UPBIT_SECRET_KEY) && !empty($GLOBALS['UPBIT_SECRET_KEY'])) $UPBIT_SECRET_KEY = $GLOBALS['UPBIT_SECRET_KEY']; $rows = (isset($rows) && is_array($rows)) ? $rows : ($GLOBALS['rows'] ?? []); $signals = (isset($signals) && is_array($signals)) ? $signals : ($GLOBALS['signals'] ?? []); $price_map = (isset($PRICE_MAP) && is_array($PRICE_MAP)) ? $PRICE_MAP : ($GLOBALS['PRICE_MAP'] ?? []); $accounts_map = (isset($accounts_map) && is_array($accounts_map)) ? $accounts_map : ($GLOBALS['accounts_map'] ?? []); $ticker_map = (isset($ticker_map) && is_array($ticker_map)) ? $ticker_map : ($GLOBALS['ticker_map'] ?? []); // [PATCH] API PRICE 배지 로직 강화 (진단용) $price_ok = false; $price_src = 'NONE'; if (is_array($price_map) && !empty($price_map)) { $price_ok = true; $price_src = 'MAP'; } elseif (is_array($rows)) { foreach ($rows as $_r) { if (isset($_r['current_price']) && $_r['current_price'] > 0) { $price_ok = true; $price_src = 'ROW'; break; } } } if (!$price_ok && is_array($ticker_map) && !empty($ticker_map)) { foreach ($ticker_map as $_t) { $_tp = $_t['trade_price'] ?? $_t['closing_price'] ?? 0; if ($_tp > 0) { $price_ok = true; $price_src = 'TICKER'; break; } } } $price_label = $price_ok ? "CONNECTED ($price_src)" : "DISCONNECTED"; /* -------------------------- * (3) 헬퍼 함수 * -------------------------- */ function pick_row($r, $k) { return (is_array($r) && array_key_exists($k, $r)) ? $r[$k] : null; } function norm_mode_ko($mode) : string { $m = strtolower(trim((string)$mode)); if ($m === 'prev_close' || $m === 'start_price') return '전일종가'; if ($m === 'avg_buy' || $m === 'avg_price') return '평단가'; if ($m === 'fixed' || $m === 'fixed_price') return '고정값'; return ($m !== '' ? $m : ''); } function build_opts_text(array $r, string $side, int $max=10, $criteria_val=null, $cur_price=null) : string { $out = []; $cv = (is_numeric($criteria_val)) ? (float)$criteria_val : null; $cur = (is_numeric($cur_price)) ? (float)$cur_price : null; for ($i=1; $i<=$max; $i++) { $pk = "{$side}_percent_{$i}"; $ak = "{$side}_amount_{$i}"; if (!array_key_exists($pk, $r) && !array_key_exists($ak, $r)) continue; $pct_raw = trim((string)($r[$pk] ?? '')); $amt = trim((string)($r[$ak] ?? '')); if ($pct_raw === '' && $amt === '') continue; $pct = is_numeric($pct_raw) ? (float)$pct_raw : null; $is_filtered = ($pct !== null && (($side === 'buy' && $pct > 0) || ($side === 'sell' && $pct < 0))); $filter_txt = $is_filtered ? " (필터)" : ""; $hit_txt = "가=-"; $cond_txt = "[판정불가]"; if ($pct !== null && $cv !== null && $cv > 0) { $hit_val = $cv * (1 + $pct / 100); $hit_txt = "가=" . number_format($hit_val); if (!$is_filtered && $cur !== null && $cur > 0) { if ($side === 'buy') $cond_txt = ($cur <= $hit_val) ? "[조건충족]" : "[미충족]"; else $cond_txt = ($cur >= $hit_val) ? "[조건충족]" : "[미충족]"; } } $out[] = "{$i}: {$pct_raw}%{$filter_txt} / {$amt} / {$hit_txt} {$cond_txt}"; } return implode("\n", $out); } $now = date('Y-m-d H:i:s'); $rows_cnt = (is_array($rows) ? count($rows) : 0); require_once '/home/www/GNU/_PAGE/head.php'; ?> DAEMON MONITORING DASHBOARD

Daemon Monitor READONLY

Next update in 1.0s
System Overview
1. Integrity Check
$info): ?>
PHASEFILE PATHPRESENCELOAD STATUS
2. Analysis & Signals
💡 Rule Notice: BUY only valid when pct ≤ 0 / SELL only valid when pct ≥ 0. Otherwise, items are automatically filtered.
0) { $diag_p = $r['current_price']; $diag_src = 'ROW'; } elseif (isset($ticker_map[$coin])) { $diag_p = $ticker_map[$coin]['trade_price'] ?? $ticker_map[$coin]['closing_price'] ?? '-'; $diag_src = ($diag_p !== '-') ? 'TICKER' : 'NONE'; } // 계좌 정보 매칭 (KRW-BTC -> BTC) $curr_code = ''; if (function_exists('market_to_currency')) { $curr_code = market_to_currency($coin); } else { $curr_code = (strpos((string)$coin, '-') !== false) ? explode('-', (string)$coin)[1] : ''; } $acc = (is_array($accounts_map) && $curr_code !== '' && array_key_exists($curr_code, $accounts_map)) ? $accounts_map[$curr_code] : null; $mode_raw = pick_row($r, '_mode') ?? pick_row($r, 'coin_criteria'); // 기준값 결정 (평단가 모드인 경우 평단가 사용) $c_val = pick_row($r, '_criteria_val'); $bal_f = (is_array($acc) && is_numeric($acc['balance'] ?? null)) ? (float)$acc['balance'] : 0.0; $avg_f = (is_array($acc) && is_numeric($acc['avg_buy_price'] ?? null)) ? (float)$acc['avg_buy_price'] : 0.0; // 평단가 모드라면 기준값을 평단가로 덮어씌움 (화면 표시용) if ($mode_raw === 'avg_price' || $mode_raw === 'avg_buy') { if ($avg_f > 0) $c_val = $avg_f; } $cv_f = is_numeric($c_val) ? (float)$c_val : 0.0; $is_avg_criteria = false; if ($bal_f > 0 && $avg_f > 0 && $cv_f > 0) { if (abs($cv_f - $avg_f) / max($avg_f, 1.0) < 1e-9) $is_avg_criteria = true; } $mode_ko = ($mode_raw === 'avg_price' || $mode_raw === 'avg_buy') ? '평단가' : norm_mode_ko($mode_raw); $buy_txt_esc = build_opts_text($r, 'buy', 10, $c_val, $diag_p); $sell_txt_esc = build_opts_text($r, 'sell', 10, $c_val, $diag_p); ?> = 150) break; endforeach; else: ?>
#IDTICKERCURRENT PRICE (SRC)HOLDINGAVG BUYCRITERIA / MODEVALUEBUY OPTIONSSELL OPTIONS
()
0 ? number_format($c_val) : 'EMPTY')?>
No active rows found.
3. Recent Signals
TICKERSIDEAMOUNT/VOL
No signals detected.
4. Price Map (Top 200)
 $p) {
                            echo h($m . " → " . $p . "\n");
                            if (++$shown >= 200) break;
                        }
                    } else { echo "EMPTY"; }
                ?>
Raw Data Preview (rows[0])
[KEY CHECK] $ktc: " . ($has ? "YES" : "NO") . ""; } } else { echo "rows[0] is not available."; } ?>