$item['lastPrice'], 'change' => $item['priceChangePercent'] ]; } } return $prices; } if ($action === 'market_data') { $binance_prices = fetch_binance_prices(); $stmt = db()->query("SELECT * FROM cryptocurrencies WHERE is_active = 1"); $coins = $stmt->fetchAll(); foreach ($coins as &$coin) { $symbol = $coin['symbol']; if (isset($binance_prices[$symbol])) { $coin['price'] = (float)$binance_prices[$symbol]['price']; $coin['change'] = (float)$binance_prices[$symbol]['change']; // Apply manual price if set if ($coin['manual_price'] > 0) { $coin['price'] = (float)$coin['manual_price']; } // Update DB with latest price $upd = db()->prepare("UPDATE cryptocurrencies SET current_price = ?, change_24h = ? WHERE id = ?"); $upd->execute([$coin['price'], $coin['change'], $coin['id']]); } else { $coin['price'] = (float)$coin['current_price']; $coin['change'] = (float)$coin['change_24h']; } } header('Content-Type: application/json'); echo json_encode($coins); exit; } if ($action === 'submit_order') { check_auth(); $data = json_decode(file_get_contents('php://input'), true); if (!$data) { echo json_encode(['status' => 'error', 'message' => '无效请求数据']); exit; } $user_id = $_SESSION['user_id']; $account = get_account($user_id); $symbol = $data['symbol'] ?? 'BTCUSDT'; $side = $data['side'] ?? 'BUY'; $trade_type = strtoupper($data['trade_type'] ?? 'SPOT'); $amount = (float)($data['amount'] ?? 0); $leverage = (int)($data['leverage'] ?? 1); if ($amount <= 0) { echo json_encode(['status' => 'error', 'message' => '请输入有效数量']); exit; } // Get current price $stmt = db()->prepare("SELECT * FROM cryptocurrencies WHERE symbol = ?"); $stmt->execute([$symbol]); $coin = $stmt->fetch(); $current_price = $coin ? (float)$coin['current_price'] : 0; if ($current_price <= 0) { echo json_encode(['status' => 'error', 'message' => '价格获取失败,请重试']); exit; } try { $db = db(); $db->beginTransaction(); if ($trade_type === 'SPOT') { if ($side === 'BUY') { $total_cost = $amount * $current_price; if ($account['balance'] < $total_cost) { throw new Exception('余额不足 (需要 ' . $total_cost . ' USDT)'); } // Deduct USDT $stmt = $db->prepare("UPDATE accounts SET balance = balance - ? WHERE id = ?"); $stmt->execute([$total_cost, $account['id']]); // Add Asset $stmt = $db->prepare("INSERT INTO assets (account_id, currency, balance) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE balance = balance + ?"); $stmt->execute([$account['id'], str_replace('USDT', '', $symbol), $amount, $amount]); } else { // SELL $currency = str_replace('USDT', '', $symbol); $stmt = $db->prepare("SELECT balance FROM assets WHERE account_id = ? AND currency = ?"); $stmt->execute([$account['id'], $currency]); $asset = $stmt->fetch(); if (!$asset || $asset['balance'] < $amount) { throw new Exception('资产余额不足'); } // Deduct Asset $stmt = $db->prepare("UPDATE assets SET balance = balance - ? WHERE account_id = ? AND currency = ?"); $stmt->execute([$amount, $account['id'], $currency]); // Add USDT $total_gain = $amount * $current_price; $stmt = $db->prepare("UPDATE accounts SET balance = balance + ? WHERE id = ?"); $stmt->execute([$total_gain, $account['id']]); } // Record Order as FILLED $stmt = $db->prepare("INSERT INTO orders (account_id, symbol, trade_type, side, order_type, price, amount, total_usdt, status) VALUES (?, ?, 'SPOT', ?, 'MARKET', ?, ?, ?, 'FILLED')"); $stmt->execute([$account['id'], $symbol, $side, $current_price, $amount, $amount * $current_price]); } else if ($trade_type === 'CONTRACT') { // Simple Contract Logic: Deduct Margin $margin = ($amount * $current_price) / $leverage; if ($account['balance'] < $margin) { throw new Exception('保证金不足 (需要 ' . $margin . ' USDT)'); } // Deduct Margin $stmt = $db->prepare("UPDATE accounts SET balance = balance - ? WHERE id = ?"); $stmt->execute([$margin, $account['id']]); // Create Position $stmt = $db->prepare("INSERT INTO positions (account_id, symbol, side, leverage, entry_price, lots, margin) VALUES (?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([$account['id'], $symbol, ($side === 'BUY' ? 'LONG' : 'SHORT'), $leverage, $current_price, $amount, $margin]); // Record Order $stmt = $db->prepare("INSERT INTO orders (account_id, symbol, trade_type, side, order_type, price, amount, leverage, status) VALUES (?, ?, 'CONTRACT', ?, 'MARKET', ?, ?, ?, 'FILLED')"); $stmt->execute([$account['id'], $symbol, $side, $current_price, $amount, $leverage]); } $db->commit(); echo json_encode(['status' => 'success', 'message' => '交易成功']); } catch (Exception $e) { $db->rollBack(); echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); } exit; } if ($action === 'positions') { check_auth(); $user_id = $_SESSION['user_id']; $account = get_account($user_id); $stmt = db()->prepare("SELECT * FROM positions WHERE account_id = ? AND is_active = 1"); $stmt->execute([$account['id']]); $positions = $stmt->fetchAll(); // Calculate PnL for each position foreach ($positions as &$pos) { $stmt = db()->prepare("SELECT current_price FROM cryptocurrencies WHERE symbol = ?"); $stmt->execute([$pos['symbol']]); $coin = $stmt->fetch(); $current_price = $coin ? (float)$coin['current_price'] : $pos['entry_price']; if ($pos['side'] === 'LONG') { $pos['pnl'] = ($current_price - $pos['entry_price']) * $pos['lots']; } else { $pos['pnl'] = ($pos['entry_price'] - $current_price) * $pos['lots']; } // Apply Win/Loss Control (Display purpose) if ($account['win_loss_control'] == 1 && $pos['pnl'] < 0) { $pos['pnl'] = abs($pos['pnl']) * 0.2; // Show small profit } else if ($account['win_loss_control'] == -1 && $pos['pnl'] > 0) { $pos['pnl'] = -abs($pos['pnl']) * 1.5; // Show big loss } $pos['current_price'] = $current_price; } echo json_encode($positions); exit; } if ($action === 'close_position') { check_auth(); $data = json_decode(file_get_contents('php://input'), true); $pos_id = $data['id'] ?? 0; $user_id = $_SESSION['user_id']; $account = get_account($user_id); try { $db = db(); $db->beginTransaction(); $stmt = $db->prepare("SELECT * FROM positions WHERE id = ? AND account_id = ? AND is_active = 1"); $stmt->execute([$pos_id, $account['id']]); $pos = $stmt->fetch(); if (!$pos) throw new Exception('仓位不存在'); $stmt = db()->prepare("SELECT current_price FROM cryptocurrencies WHERE symbol = ?"); $stmt->execute([$pos['symbol']]); $coin = $stmt->fetch(); $current_price = $coin ? (float)$coin['current_price'] : $pos['entry_price']; if ($pos['side'] === 'LONG') { $pnl = ($current_price - $pos['entry_price']) * $pos['lots']; } else { $pnl = ($pos['entry_price'] - $current_price) * $pos['lots']; } // Win/Loss Control Logic if ($account['win_loss_control'] == 1) { // Always Win if ($pnl < 0) $pnl = abs($pnl) * 0.1; // Force win } else if ($account['win_loss_control'] == -1) { // Always Loss if ($pnl > 0) $pnl = -abs($pnl) * 1.2; // Force loss } // Return Margin + PnL $payout = $pos['margin'] + $pnl; if ($payout < 0) $payout = 0; $stmt = $db->prepare("UPDATE accounts SET balance = balance + ? WHERE id = ?"); $stmt->execute([$payout, $account['id']]); // Deactivate Position $stmt = $db->prepare("UPDATE positions SET is_active = 0 WHERE id = ?"); $stmt->execute([$pos_id]); $db->commit(); echo json_encode(['status' => 'success', 'message' => '平仓成功']); } catch (Exception $e) { $db->rollBack(); echo json_encode(['status' => 'error', 'message' => $e->getMessage()]); } exit; } ?>