38239-vm/api.php
Flatlogic Bot f1fc7be962 BIT
2026-02-07 06:05:18 +00:00

258 lines
9.8 KiB
PHP

<?php
include_once 'config.php';
$action = $_GET['action'] ?? '';
// Function to fetch real prices from Binance
function fetch_binance_prices() {
$url = "https://api.binance.com/api/v3/ticker/24hr";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
$response = curl_exec($ch);
curl_close($ch);
if (!$response) return [];
$data = json_decode($response, true);
$prices = [];
if (is_array($data)) {
foreach ($data as $item) {
$prices[$item['symbol']] = [
'price' => $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;
}
?>