/** * Get data for candle chart. * * @param Request $request */ public function getChart(Request $request) { $zoom = (int) $request->input('zoom'); $interval = $request->input('pointInterval') / 1000; list($market, $base) = explode('/', $request->input('pair')); $base_wallet = Wallet::where('short', $base)->first(); $market_wallet = Wallet::where('short', $market)->first(); $data = []; $old_data = Cache::tags('charts')->remember($base . $market . $zoom . $interval, 1, function () use($base_wallet, $market_wallet, $zoom, $interval) { $old_data = []; OrdersChart::selectRaw(' date*1000 as date, volume, open, high, low, close ')->where(function (\Illuminate\Database\Eloquent\Builder $query) use($base_wallet, $market_wallet) { $query->where('wallet_id', $base_wallet->id)->where('want_wallet_id', $market_wallet->id); })->where(DB::raw('from_unixtime(date)'), '>=', DB::raw('DATE_SUB(NOW(), INTERVAL ' . $zoom . ' HOUR)'))->where('interval', $interval)->orderBy('date', 'asc')->chunk(1000, function ($orders) use(&$old_data) { foreach ($orders as $key => $order) { $old_data[] = [(int) $order->date, (double) $order->open, (double) $order->high, (double) $order->low, (double) $order->close, (int) $order->volume]; } }); return $old_data; }); $data = array_merge($data, $old_data); usort($data, function ($a, $b) { return $a[0] - $b[0]; }); return response()->json($old_data)->setCallback($request->input('callback')); }
/** * Execute the console command. * * @return mixed */ public function handle() { $intervals = [300, 900, 1800, 7200, 14400, 86400]; $base = Wallet::where('base', true)->get(); $all = Wallet::all(); foreach ($base as $base_wallet) { foreach ($all as $market_wallet) { if ($market_wallet->id == $base_wallet->id) { continue; } foreach ($intervals as $interval) { OrdersTransaction::selectRaw(' FLOOR(MIN(unix_timestamp(`created_at`))/' . $interval . ')*' . $interval . ' AS date, SUM(amount) AS volume, SUBSTRING_INDEX(MIN(CONCAT(unix_timestamp(`created_at`), \'_\', price)), \'_\', -1) AS `open`, MAX(price) AS high, MIN(price) AS low, SUBSTRING_INDEX(MAX(CONCAT(unix_timestamp(`created_at`), \'_\', price)), \'_\', -1) AS `close` ')->where(function (\Illuminate\Database\Eloquent\Builder $query) use($base_wallet, $market_wallet) { $query->where('wallet_id', $base_wallet->id)->where('want_wallet_id', $market_wallet->id); })->where('created_at', '>=', DB::raw('DATE_SUB(NOW(), INTERVAL 24 HOUR)'))->groupBy(DB::raw('FLOOR(unix_timestamp(`created_at`)/' . $interval . ')'))->orderBy('created_at', 'asc')->chunk(100000, function ($orders) use($base_wallet, $market_wallet, $interval) { foreach ($orders as $key => $order) { try { $cache = OrdersChart::firstOrNew(['wallet_id' => $base_wallet->id, 'want_wallet_id' => $market_wallet->id, 'date' => $order->date, 'interval' => $interval]); $cache->date = $order->date; $cache->open = $order->open; $cache->high = $order->high; $cache->low = $order->low; $cache->close = $order->close; $cache->volume = $order->volume; $cache->wallet_id = $base_wallet->id; $cache->want_wallet_id = $market_wallet->id; $cache->interval = $interval; $cache->save(); } catch (\Exception $e) { } } }); } } } }
/** * Place new order. * * @param float $amount coins amount to sell/buy * @param float $price price per share * @param string $base_market base coin * @param string $market current coin * @param string $type order type */ public static function place($amount, $price, $base_market, $market, $type) { $total_price = round($amount * $price, 8); $base_wallet = Wallet::where('short', $base_market)->first(); $want_wallet = Wallet::where('short', $market)->first(); if ($base_wallet && $want_wallet) { if ($type == 's') { $user_wallet_id = $want_wallet->generateUserAddress(Auth::user()); } else { $user_wallet_id = $base_wallet->generateUserAddress(Auth::user()); } $user_wallet = WalletsAddress::where('id', $user_wallet_id)->first(); if ($user_wallet) { if ($type == 's') { $need_amount = $amount; } else { $need_amount = $total_price; } if ($user_wallet->balance >= $need_amount) { try { DB::beginTransaction(); $initial_amount = $amount; self::fullfillSuitable($initial_amount, $price, $base_wallet, $want_wallet, $user_wallet, $type); if ($initial_amount > 0) { $total_price = round($initial_amount * $price, 8); if ($type == 's') { $need_amount = $amount; } else { $need_amount = $total_price; } $order = new self(); $order->user_id = Auth::user()->id; $order->initial_amount = $initial_amount; $order->amount = $initial_amount; $order->price = $price; $order->wallet_id = $base_wallet->id; $order->want_wallet_id = $want_wallet->id; $order->user_id = Auth::user()->id; $order->type = $type == 's' ? 'sell' : 'buy'; if ($order->save()) { $user_wallet->withdrawal($need_amount); Cache::tags('user' . Auth::user()->id)->forget('wallets'); $response['success'] = true; $response['message'] = 'Order ' . $order->id . ' placed'; } else { $response['success'] = false; $response['error'] = 'Can\'t place order, please try again'; } } else { $response['success'] = true; $response['message'] = 'Order completed'; } DB::commit(); } catch (\Exception $e) { DB::rollback(); $response['error'] = $e->getMessage(); } } else { $response['success'] = false; $response['error'] = 'Not enough balance to place order'; } } else { $response['success'] = false; $response['error'] = 'user#' . Auth::user()->id . ' wallet#' . $base_wallet->id . ' not found'; } } else { $response['success'] = false; $response['error'] = 'market pair not found'; } return $response; }