= 2) { $status = 'RUNNING'; } } ?>
GHOST DAEMON PLATFORM 플랫폼 유령 데몬
PID 파일 경로:
PID 파일 존재:
PID 값: []
DAEMON RUNNING 🔴 DAEMON STOPPED
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (Throwable $e) {} // API $api = require '/home/www/DB/upbit_api_url.php'; $API_MARKETS = $api['market_all'] . '?isDetails=false'; $API_TICKER = $api['ticker'] . '?markets='; function http_get_json($url){ $ctx = stream_context_create([ 'http'=>[ 'timeout'=>6, 'header'=>"User-Agent: upbit-daemon\r\n", ] ]); $raw = @file_get_contents($url,false,$ctx); if ($raw === false) return null; $j = json_decode($raw,true); return is_array($j) ? $j : null; } $krw = []; $last_market_refresh = 0; $load_markets = function() use (&$krw, &$last_market_refresh, $API_MARKETS) { $m = http_get_json($API_MARKETS); if (!$m) return false; $tmp = []; foreach ($m as $v) { if (isset($v['market']) && strpos($v['market'], 'KRW-') === 0) { $tmp[] = $v['market']; } } if (!$tmp) return false; $krw = $tmp; $last_market_refresh = time(); return true; }; $load_markets(); // =============================== // SQL // =============================== $stmt = $pdo->prepare(" INSERT INTO daemon_upbit_Ticker ( market, trade_date, trade_time, trade_date_kst, trade_time_kst, opening_price, high_price, low_price, trade_price, prev_closing_price, `change`, change_price, change_rate, signed_change_price, signed_change_rate, trade_volume, acc_trade_volume, acc_trade_volume_24h, acc_trade_price, acc_trade_price_24h, highest_52_week_price, highest_52_week_date, lowest_52_week_price, lowest_52_week_date, collected_at, collected_ms, tr_trade_timestamp, tr_trade_price, tr_trade_volume, tr_ask_bid, tr_trade_date_utc, tr_trade_time_utc, tr_trade_date_kst, tr_trade_time_kst, tr_collected_at, tr_collected_ms, ob_timestamp, ob_total_ask_size, ob_total_bid_size, ob_units, ob_collected_at, ob_collected_ms, day_of_week, daemon_id, daemon_pid, daemon_heartbeat ) VALUES ( :market, :trade_date, :trade_time, :trade_date_kst, :trade_time_kst, :opening_price, :high_price, :low_price, :trade_price, :prev_closing_price, :change, :change_price, :change_rate, :signed_change_price, :signed_change_rate, :trade_volume, :acc_trade_volume, :acc_trade_volume_24h, :acc_trade_price, :acc_trade_price_24h, :highest_52_week_price, :highest_52_week_date, :lowest_52_week_price, :lowest_52_week_date, :collected_at, :collected_ms, :tr_trade_timestamp, :tr_trade_price, :tr_trade_volume, :tr_ask_bid, :tr_trade_date_utc, :tr_trade_time_utc, :tr_trade_date_kst, :tr_trade_time_kst, :tr_collected_at, :tr_collected_ms, :ob_timestamp, :ob_total_ask_size, :ob_total_bid_size, :ob_units, :ob_collected_at, :ob_collected_ms, :day_of_week, :daemon_id, :daemon_pid, :daemon_heartbeat ) ON DUPLICATE KEY UPDATE trade_price=VALUES(trade_price), change_rate=VALUES(change_rate), tr_trade_timestamp=VALUES(tr_trade_timestamp), tr_trade_price=VALUES(tr_trade_price), tr_trade_volume=VALUES(tr_trade_volume), tr_ask_bid=VALUES(tr_ask_bid), tr_trade_date_utc=VALUES(tr_trade_date_utc), tr_trade_time_utc=VALUES(tr_trade_time_utc), tr_trade_date_kst=VALUES(tr_trade_date_kst), tr_trade_time_kst=VALUES(tr_trade_time_kst), tr_collected_at=VALUES(tr_collected_at), tr_collected_ms=VALUES(tr_collected_ms), ob_timestamp=VALUES(ob_timestamp), ob_total_ask_size=VALUES(ob_total_ask_size), ob_total_bid_size=VALUES(ob_total_bid_size), ob_units=VALUES(ob_units), ob_collected_at=VALUES(ob_collected_at), ob_collected_ms=VALUES(ob_collected_ms), day_of_week=VALUES(day_of_week), daemon_id=VALUES(daemon_id), daemon_pid=VALUES(daemon_pid), daemon_heartbeat=VALUES(daemon_heartbeat), collected_at=VALUES(collected_at), collected_ms=VALUES(collected_ms) "); // =============================== // LOOP // =============================== while (true) { if (time() - $last_market_refresh >= 600) { $load_markets(); } if (!$krw) { usleep(500000); continue; } $ms = (int)(microtime(true) * 1000); $at = date('Y-m-d H:i:s'); foreach (array_chunk($krw, 100) as $c) { $tks = http_get_json($API_TICKER . implode(',', $c)); if (!$tks) continue; foreach ($tks as $t) { // Trades $trs = http_get_json( 'https://api.upbit.com/v1/trades/ticks?market=' . $t['market'] . '&count=1' ); $tr = (is_array($trs) && isset($trs[0])) ? $trs[0] : null; // Orderbook $obs = http_get_json( 'https://api.upbit.com/v1/orderbook?markets=' . $t['market'] ); $ob = (is_array($obs) && isset($obs[0])) ? $obs[0] : null; // --- 수정 구간: 체결 시각(timestamp) 기준 데이터 산출 --- // timestamp는 밀리초 단위이므로 1000으로 나눔 $tr_time_ref = (isset($tr['timestamp'])) ? (int)($tr['timestamp'] / 1000) : time(); $target_date_kst = date('Ymd', $tr_time_ref); $target_time_kst = date('His', $tr_time_ref); $target_dow = (int)date('w', $tr_time_ref); // --------------------------------------------------- $stmt->execute([ ':market'=>$t['market']??'', ':trade_date'=>$t['trade_date']??'', ':trade_time'=>$t['trade_time']??'', ':trade_date_kst'=>$t['trade_date_kst']??'', ':trade_time_kst'=>$t['trade_time_kst']??'', ':opening_price'=>$t['opening_price']??0, ':high_price'=>$t['high_price']??0, ':low_price'=>$t['low_price']??0, ':trade_price'=>$t['trade_price']??0, ':prev_closing_price'=>$t['prev_closing_price']??0, ':change'=>$t['change']??'', ':change_price'=>$t['change_price']??0, ':change_rate'=>$t['change_rate']??0, ':signed_change_price'=>$t['signed_change_price']??0, ':signed_change_rate'=>$t['signed_change_rate']??0, ':trade_volume'=>$t['trade_volume']??0, ':acc_trade_volume'=>$t['acc_trade_volume']??0, ':acc_trade_volume_24h'=>$t['acc_trade_volume_24h']??0, ':acc_trade_price'=>$t['acc_trade_price']??0, ':acc_trade_price_24h'=>$t['acc_trade_price_24h']??0, ':highest_52_week_price'=>$t['highest_52_week_price']??0, ':highest_52_week_date'=>$t['highest_52_week_date']??'', ':lowest_52_week_price'=>$t['lowest_52_week_price']??0, ':lowest_52_week_date'=>$t['lowest_52_week_date']??'', ':collected_at'=>$at, ':collected_ms'=>$ms, // Trades ':tr_trade_timestamp'=>$tr['timestamp'] ?? 0, ':tr_trade_price'=>$tr['trade_price'] ?? 0, ':tr_trade_volume'=>$tr['trade_volume'] ?? 0, ':tr_ask_bid'=>$tr['ask_bid'] ?? '', ':tr_trade_date_utc'=>$tr['trade_date_utc'] ?? '', ':tr_trade_time_utc'=>$tr['trade_time_utc'] ?? '', ':tr_trade_date_kst'=>$target_date_kst, // 수정됨 (체결기준) ':tr_trade_time_kst'=>$target_time_kst, // 수정됨 (체결기준) ':tr_collected_at'=>$at, ':tr_collected_ms'=>$ms, // Orderbook ':ob_timestamp'=>$ob['timestamp'] ?? 0, ':ob_total_ask_size'=>$ob['total_ask_size'] ?? 0, ':ob_total_bid_size'=>$ob['total_bid_size'] ?? 0, ':ob_units'=>isset($ob['orderbook_units']) ? json_encode($ob['orderbook_units'], JSON_UNESCAPED_UNICODE) : null, ':ob_collected_at'=>$at, ':ob_collected_ms'=>$ms, // 관리 ':day_of_week'=>$target_dow, // 수정됨 (체결기준 요일) ':daemon_id'=>$DAEMON_ID, ':daemon_pid'=>getmypid(), ':daemon_heartbeat'=>$ms, ]); } } usleep(1000000); } } // =============================== // 웹 영역 // =============================== extract($_GET, EXTR_SKIP); // 실행 if (isset($start) && $start === 'yes') { $cmd = 'nohup php ' . escapeshellarg(__FILE__) . ' --daemon > /dev/null 2>&1 &'; @exec($cmd); ?>

데몬 실행 요청 완료

유령데몬 삭제 페이지 : 무당 부적 부착 -> 데몬 실행

데몬 삭제 완료"; } ?>

유령데몬 삭제 페이지 : 무당 휘발 -> 삭제 선택

유령데몬 관리 페이지 : 플렛폼 0S 테이블