id; echo 'workid--' . $workid . "\r\n"; if ($workid == 0) { Timer::add(1, function () { $data = Events::getMarketList(); $group_id = 'swapMarketList'; $message3 = json_encode(['code' => 0, 'msg' => 'success', 'data' => $data, 'sub' => $group_id]); if (Gateway::getClientIdCountByGroup($group_id) > 0) Gateway::sendToGroup($group_id, $message3); }); // COIN_SYMBOL -- START $coins = config('coin.swap_symbols'); $seconds = 1; // var_dump($coins); foreach ($coins as $coin1 => $class) { if($coin1 == 'AAAAA'){ continue; } Timer::add($seconds, function ($coin1, $class) { $symbol = $coin1; $group_id = 'swapBuyList_' . $symbol; if (Gateway::getClientIdCountByGroup($group_id) > 0) { $data = Events::getCoinBuyList($symbol, $class); $message = json_encode(['code' => 0, 'msg' => 'success', 'data' => $data, 'sub' => $group_id]); Gateway::sendToGroup($group_id, $message); } }, [$coin1, $class]); if ($coin1 != strtolower(config('coin.coin_symbol'))) { Timer::add($seconds, function ($coin1, $class) { $symbol = $coin1; $group_id = 'swapSellList_' . $symbol; if (Gateway::getClientIdCountByGroup($group_id) > 0) { $data = Events::getCoinBuyList($symbol, $class); $message = json_encode(['code' => 0, 'msg' => 'success', 'data' => $data, 'sub' => $group_id]); Gateway::sendToGroup($group_id, $message); } }, [$coin1, $class]); } Timer::add($seconds, function ($coin1, $class) { $symbol = $coin1; $group_id = 'swapTradeList_' . $symbol; if (Gateway::getClientIdCountByGroup($group_id) > 0) { $data = Events::getCoinTradeItem($symbol, $class); $message = json_encode(['code' => 0, 'msg' => 'success', 'type' => 'dynamic', 'data' => $data, 'sub' => $group_id]); Gateway::sendToGroup($group_id, $message); } }, [$coin1, $class]); $periods = ['1min', '5min', '15min', '30min', '60min', '1day', '1week', '1mon']; // $periodMap = [ // '1min' => ['start' => [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,18,20,21,22,23,24,25,26,27,28.29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59], 'end' => [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,18,20,21,22,23,24,25,26,27,28.29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59]], // '5min' => ['start' => [0,5,10,15,20,25,30,35,40,45,50,55], 'end' => [4,9,14,19,24,29,34,39,44,49,54,59]], // '15min' => ['start' => [0,15,30,45], 'end' => [14,29,44,59]], // '30min' => ['start' => [0,30], 'end' => [29,59]], // '60min' => ['start' => [0], 'end' => [59]], // '1day' => ['start' => [0], 'end' => [59]], // '1week' => ['start' => [0], 'end' => [59]], // '1mon' => ['start' => [0], 'end' => [59]] // ]; Timer::add($seconds, function ($periods, $coin1, $class) { $periodMap = [ '1min' => ['start' => [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,18,20,21,22,23,24,25,26,27,28.29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59], 'end' => [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,18,20,21,22,23,24,25,26,27,28.29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59]], '5min' => ['start' => [0,5,10,15,20,25,30,35,40,45,50,55], 'end' => [4,9,14,19,24,29,34,39,44,49,54,59]], '15min' => ['start' => [0,15,30,45], 'end' => [14,29,44,59]], '30min' => ['start' => [0,30], 'end' => [29,59]], '60min' => ['start' => [0], 'end' => [59]], '1day' => ['start' => [0], 'end' => [59]], '1week' => ['start' => [0], 'end' => [59]], '1mon' => ['start' => [0], 'end' => [59]] ]; $symbol = $coin1; foreach ($periods as $period) { $data_old = $data = Events::getCoinKline($symbol, $period, $class); $now_price = Cache::store('redis')->get('swap:' . $symbol . '_detail'); $now_per = Cache::store('redis')->get('swap:' . $symbol . '_kline_' . $period); // if($period != '1min'){ // $data['high'] = $data['open'] ; // $data['low'] = $data['open'] ; // } if (in_array(date('i', time()), $periodMap[$period]['start']) && date('s', time()) < 3) { // $data['high'] = $data['open']; // $data['low'] = $data['open']; }elseif (in_array(date('i', time()), $periodMap[$period]['end']) && date('s', time()) > 58){ $data = $data_old; }else{ // $data['high'] = $data['open']; // $data['low'] = $data['open']; } if (date('s', time()) >= 3 && date('s', time()) <= 58) { if ($now_price['price'] > $now_per['high']) { $data['high'] = $now_price['price']; } else { $data['high'] = $now_per['high']; } if ($now_price['price'] < $now_per['low']) { $data['low'] = $now_price['price']; } else { $data['low'] = $now_per['low']; } } if ($period == "1day") { $data['high'] = $data['open']; $data['low'] = $data['open']; } // if ($period != "1min") { // $data['high'] = $data['open']; // $data['low'] = $data['open']; // } Cache::store('redis')->put('swap:' . $symbol . '_kline_' . $period, $data); $group_id = 'swapKline_' . $symbol . '_' . $period; if (Gateway::getClientIdCountByGroup($group_id) > 0) { $message = json_encode(['code' => 0, 'msg' => 'success', 'data' => $data, 'sub' => $group_id, 'type' => 'dynamic']); Gateway::sendToGroup($group_id, $message); } } }, [$periods, $coin1, $class]); Timer::add($seconds, function ($coin1, $class) { $coin1_symbol = $coin1; $kline = $class::query()->where('Date', '<', time())->where('is_1min', 1)->orderByDesc('Date')->first(); $day_kline = $class::query()->where('Date', Carbon::yesterday()->getTimestamp())->where('is_day', 1)->orderByDesc('Date')->first(); // echo 3333; if (blank($kline)) { // echo 555; $cache_data = []; } else { // echo 2222; $decimal = 100000; $ups_downs_high = 20; //高 $ups_downs_low = 1; //低 $up_or_down = mt_rand(1, 5); $flag2 = mt_rand(1, 2); $cache_data = [ "id" => $kline['Date'], "count" => $day_kline['Amount'], "open" => $kline['Open'], "low" => $kline['Low'], "high" => $kline['High'], "vol" => $day_kline['Volume'], "version" => $kline['Date'], 'ts' => \Carbon\Carbon::now()->getPreciseTimestamp(3), ]; $cache_data['amount'] = $flag2 == 1 ? round($day_kline['Amount'] + (mt_rand(10, 40) / 1000), 5) : round($day_kline['Amount'] - (mt_rand(10, 40) / 1000), 5); $decimal_price = $kline['Close'] * $decimal * (1 + round((mt_rand(1000, 3000) / 10000000), 4)); //$decimal_price = $kline['Close'] * $decimal ; $now_min = date('s', time()); // 最后5秒用k图数据 if ($now_min < 55) { if ($up_or_down <= 3) { $cache_data['close'] = mt_rand($decimal_price, $decimal_price + mt_rand($ups_downs_low, $ups_downs_high)) / $decimal; } else { $cache_data['close'] = mt_rand($decimal_price - mt_rand($ups_downs_low, $ups_downs_high), $decimal_price) / $decimal; } } else { $cache_data['close'] = $kline['Close']; } $cache_data['price'] = $cache_data['close']; echo "test---"; echo $cache_data['open']; echo "test---"; echo $day_kline; if (isset($cache_data['open']) && $cache_data['open'] != 0 && $day_kline['Symbol']!='AAAAA') { if (blank($day_kline)) { if (($cache_data['close'] - $cache_data['open']) == 0) { $increase = 0; } else { $increase = round(($cache_data['close'] - $cache_data['open']) / $cache_data['open'], 4); } } else { echo 2222; if (($cache_data['close'] - $day_kline['Close']) == 0) { $increase = 0; } else { echo 33333; $increase = round(($cache_data['close'] - $day_kline['Close']) / $day_kline['Close'], 4); } } } else { $increase = 0; } $cache_data['increase'] = $increase; $flag = $increase >= 0 ? '+' : ''; $cache_data['increaseStr'] = $increase == 0 ? '+0.00%' : $flag . $increase * 100 . '%'; } // echo $coin1_symbol; $cache_data2 = [ "id" => Str::uuid()->toString(), "ts" => $cache_data['ts'], "tradeId" => Str::uuid()->toString(), "amount" => $cache_data['amount'], "price" => $cache_data['price'], // "direction"=> "buy", 'direction' => mt_rand(0, 1) == 0 ? 'buy' : 'sell', "increase" => $cache_data['increase'], "increaseStr" => $cache_data['increaseStr'], ]; // 历史价格数据book // $new_price_book_key = 'swap:' . $coin1_symbol . '_newPriceBook'; $new_price_book_key = 'swap:tradeList_' . $coin1_symbol; $new_price_book = Cache::store('redis')->get($new_price_book_key); if (blank($new_price_book)) { $prices = []; } else { $size = count($new_price_book) >= 10 ? 10 : count($new_price_book); $prices = array_random($new_price_book, $size); $prices = array_values(Arr::sort($prices, function ($value) { return $value['ts']; })); $prices = Arr::pluck($prices, 'price'); } $cache_data['prices'] = $prices; //todo 更新24小时最高价格 // Log::info('更新24小时最高价格'); echo $coin1_symbol; $new_cache = $cache_data; //当天第一分钟 $day_time_one = strtotime(date('Y-m-d') . ' 00:00:00'); //当前时间的上一分钟 $high = $class::query()->where('Date', '<', time())->where('Date', '>', $day_time_one)->where('is_1min', 1)->orderByDesc('High')->first(); if ($new_cache['high'] < $high['High']) { $new_cache['high'] = $high['High']; } $low = $class::query()->where('Date', '<', time())->where('Date', '>', $day_time_one)->where('is_1min', 1)->orderBy('Low', 'asc')->first(); if ($new_cache['low'] > $low['Low']) { $new_cache['low'] = $low['Low']; } //var_dump($new_cache); Cache::store('redis')->put('swap:' . $coin1_symbol . '_detail', $new_cache); if (!blank($cache_data2)) { Cache::store('redis')->put('swap:trade_detail_' . $coin1_symbol, $cache_data); //缓存历史价格数据book if (blank($new_price_book)) { Cache::store('redis')->put($new_price_book_key, [$cache_data2]); } else { array_push($new_price_book, $cache_data2); if (count($new_price_book) > 200) { array_shift($new_price_book); } Cache::store('redis')->put($new_price_book_key, $new_price_book); } } }, [$coin1, $class]); } // COIN_SYMBOL -- END } } public static function getMarketList($type = 'marketList') { $marketList = []; $symbols = \App\Models\ContractPair::query()->where('status', 1)->orderBy('sort', 'DESC')->pluck('symbol'); $kk = 0; foreach ($symbols as $k => $symbol) { $coin = array_first(Coins::getCachedCoins(), function ($value, $key) { return $value['coin_name'] == 'USDT'; }); $marketList[$kk]['coin_name'] = $coin['coin_name']; $marketList[$kk]['full_name'] = $coin['full_name']; $marketList[$kk]['coin_icon'] = getFullPath($coin['coin_icon']); $marketList[$kk]['coin_content'] = $coin['coin_content']; $marketList[$kk]['qty_decimals'] = $coin['qty_decimals']; $marketList[$kk]['price_decimals'] = $coin['price_decimals']; $cd = Cache::store('redis')->get('swap:' . $symbol . '_detail'); $data = $cd; if($symbol == 'BTC'){ $cd['close'] = custom_number_format($cd['close'], 1); } $data['price'] = $cd['close']; $data['symbol'] = $symbol; $data['pair_name'] = $symbol . '/' . 'USDT'; $data['type'] = 'USDT'; $marketList[$kk]['marketInfoList'][$k] = $data; } return $marketList; } public static function getCoinBuyList($symbol, $class) { $kline = $class::query()->where('is_1min', 1)->where('Date', '<', time())->orderByDesc('Date')->first(); if (blank($kline)) return []; $kline_cache_data = Cache::store('redis')->get('swap:' . $symbol . '_detail'); $buyList = []; for ($i = 0; $i <= 19; $i++) { if ($i == 0) { $buyList[$i] = [ 'id' => Str::uuid(), "amount" => round((mt_rand(10000, 3000000) / 1000), 4), 'price' => $kline_cache_data['close'], ]; } else { $open = $kline['Open']; $close = $kline['Close']; $min = min($open, $close) * 100000; $max = max($open, $close) * 100000; $price = round(mt_rand($min, $max) / 100000, 5); $buyList[$i] = [ 'id' => Str::uuid()->toString(), "amount" => round((mt_rand(10000, 3000000) / 1000), 4), 'price' => $price, ]; } } return $buyList; } public static function getCoinTradeItem($symbol, $class = null) { $kline_cache_data = Cache::store('redis')->get('swap:' . $symbol . '_detail'); $tradeItem = [ 'id' => Str::uuid()->toString(), "amount" => round((mt_rand(10000, 3000000) / 1000), 4), 'price' => $kline_cache_data['close'], 'tradeId' => Str::uuid()->toString(), 'ts' => Carbon::now()->getPreciseTimestamp(3), 'increase' => 0, 'increaseStr' => "--", 'direction' => mt_rand(0, 1) == 0 ? 'buy' : 'sell', ]; return $tradeItem; } public static function getCoinKline($symbol, $period, $class) { $periods = [ '1min' => 60, '5min' => 300, '15min' => 900, '30min' => 1800, '60min' => 3600, '1day' => 86400, '1week' => 604800, '1mon' => 2592000, ]; $wheres = [ '1min' => 'is_1min', '5min' => 'is_5min', '15min' => 'is_15min', '30min' => 'is_30min', '60min' => 'is_1h', '1day' => 'is_day', '1week' => 'is_week', '1mon' => 'is_month', ]; $seconds = $periods[$period] ?? 60; $where = $wheres[$period] ?? 'is_1min'; $kline = $class::query()->where($where, 1)->where('Date', '>', (time() - $seconds))->where('Date', '<=', time())->first(); $kline_cache_data = Cache::store('redis')->get('swap:' . $symbol . '_detail'); if ($kline['Date'] == time()) { $cache_data = [ "id" => $kline['Date'], "amount" => $kline['Amount'], "count" => mt_rand(10, 55), "open" => $kline['Open'], "close" => $kline['Close'], "low" => $kline['Low'], "high" => $kline['High'], "vol" => $kline['Volume'], ]; $cache_data['price'] = $cache_data['close']; } else { $cache_data = [ "id" => $kline['Date'], "amount" => round($kline['Amount'] + (mt_rand(10, 99) / 1000), 5), "count" => mt_rand(10, 55), "open" => $kline['Open'], "close" => $kline_cache_data['close'], "low" => $kline['Low'], "high" => $kline['High'], "vol" => $kline['Volume'], ]; $cache_data['price'] = $cache_data['close']; } return $cache_data; } public static function onWorkerStop($businessWorker) { // 拿到当前进程的id编号. $workid = $businessWorker->id; if ($workid == 0) { Timer::delAll(); } } public static function onConnect($client_id) { } public static function getCoinTradeList($symbol, $class) { $kline = $class::query()->where('is_1min', 1)->where('Date', '<', time())->orderByDesc('Date')->first(); if (blank($kline)) return []; $kline_cache_data = Cache::store('redis')->get('swap:' . $symbol . '_detail'); $tradeList = []; for ($i = 0; $i <= 30; $i++) { if ($i == 0) { $tradeList[$i] = [ 'id' => Str::uuid(), "amount" => round((mt_rand(10000, 3000000) / 1000), 4), 'price' => $kline_cache_data['close'], 'tradeId' => Str::uuid()->toString(), 'ts' => Carbon::now()->getPreciseTimestamp(3), 'increase' => -0.1626, 'increaseStr' => "-16.26%", 'direction' => mt_rand(0, 1) == 0 ? 'buy' : 'sell', ]; } else { $open = $kline['Open']; $close = $kline['Close']; $min = min($open, $close) * 100000; $max = max($open, $close) * 100000; $price = round(mt_rand($min, $max) / 100000, 5); $tradeList[$i] = [ 'id' => Str::uuid()->toString(), "amount" => round((mt_rand(10000, 3000000) / 1000), 4), 'price' => $price, 'tradeId' => Str::uuid()->toString(), 'ts' => Carbon::now()->getPreciseTimestamp(3), 'increase' => -0.1626, 'increaseStr' => "-16.26%", 'direction' => mt_rand(0, 1) == 0 ? 'buy' : 'sell', ]; } } return $tradeList; } public static function getNewPrice($symbol) { $key = 'swap:' . $symbol . '_newPrice'; $data = Cache::store('redis')->get($key); $data['ts'] = Carbon::now()->getPreciseTimestamp(3); return $data; } public static function onWebSocketConnect($client_id, $data) { echo "onWebSocketConnect\r\n"; } public static function onMessage($client_id, $message) { // echo $message . ':' . $client_id . "--onMessage\r\n"; $message = json_decode($message); if (isset($message->cmd)) { switch ($message->cmd) { case 'pong' : Gateway::sendToClient($client_id, json_encode(['code' => 0, 'msg' => 'success'])); break; case 'sub' : $sub = $message->msg; $_SESSION['subs'][$sub] = $sub; Gateway::joinGroup($client_id, $sub); break; case 'unsub' : $sub = $message->msg; if (array_get($_SESSION['subs'], $sub)) { array_forget($_SESSION['subs'], $sub); Gateway::leaveGroup($client_id, $sub); } break; case 'req' : $ch = $message->msg; $type = str_before($ch, '_'); if ($type == 'swapTradeList') { $params = str_after($ch, '_'); $symbol = str_before($params, '_'); // 火币最新成交明细缓存 $new_price_book_key = 'swap:' . 'tradeList_' . $symbol; $new_price_book = Cache::store('redis')->get($new_price_book_key); if (blank($new_price_book)) $new_price_book = []; Gateway::sendToClient($client_id, json_encode(['code' => 0, 'msg' => 'success', 'data' => $new_price_book, 'sub' => $ch, 'type' => 'history', 'client_id' => $client_id])); } elseif ($type == 'swapKline') { $params = str_after($ch, '_'); $symbol = str_before($params, '_'); $period = str_after($params, '_'); if (blank($symbol) || blank($period)) { Gateway::sendToClient($client_id, json_encode(['code' => -1, 'msg' => 'params error', 'client_id' => $client_id])); break; } $kline_book_key = 'swap:' . $symbol . '_kline_book_' . $period; $kline_book = Cache::store('redis')->get($kline_book_key); if (blank($kline_book)) $kline_book = []; Gateway::sendToClient($client_id, json_encode(['code' => 0, 'msg' => 'success', 'data' => $kline_book, 'sub' => $ch, 'type' => 'history', 'client_id' => $client_id])); } break; } } return true; } public static function onClose($client_id) { if (isset($_SESSION['time_id'])) { Timer::del($_SESSION['time_id']); } } }