You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
4.0 KiB
TypeScript

import { json } from '@sveltejs/kit'
import { RestClientV5 } from 'bybit-api'
import { z } from 'zod'
export const POST = async ({ locals, request }) => {
const type = request.headers.get('Content-Type')
if (type !== 'application/json; charset=utf-8') {
return new Response()
}
const body = await request.json()
console.log('Body:', body)
const flatSchema = z.object({
type: z.literal('Flat'),
key: z.string(),
secret: z.string(),
symbol: z.string(),
side: z.enum(['Buy', 'Sell']),
qty: z.string(),
leverage: z.string().optional(),
takeProfit: z.string().optional(),
stopLoss: z.string().optional(),
})
const percentSchema = z.object({
type: z.literal('Percent'),
key: z.string(),
secret: z.string(),
symbol: z.string(),
side: z.enum(['Buy', 'Sell']),
entryPrice: z.string(),
qtyPercent: z.string(),
qtyDecimalPoint: z.string(),
leverage: z.string().default('1'),
takeProfitPercent: z.string().optional(),
stopLossPercent: z.string().optional(),
// tpslDecimalPoint: z.string().default('1'),
})
const closePositionSchema = z.object({
type: z.literal('Close Position'),
key: z.string(),
secret: z.string(),
symbol: z.string(),
})
const form = z
.union([flatSchema, percentSchema, closePositionSchema])
.safeParse(body)
if (!form.success) {
console.log(form.error)
return json({}, { status: 400 })
}
const { key, secret, symbol } = form.data
try {
let qty
let takeProfit
let stopLoss
let side
let isLeverage
if (form.data.type === 'Close Position') {
isLeverage = false
} else if (form.data.leverage) {
isLeverage = true
} else {
isLeverage = false
}
const client = new RestClientV5({
key: key,
secret: secret,
demoTrading: true,
})
if (form.data.type === 'Flat') {
qty = (
Number(form.data.qty) * Number(form.data.leverage || '1')
).toString()
takeProfit = form.data.takeProfit
stopLoss = form.data.stopLoss
side = form.data.side
} else if (form.data.type === 'Percent') {
const wallet = await client.getWalletBalance({
accountType: 'UNIFIED',
coin: 'USDT',
})
console.log(
'Available Balance:',
wallet.result.list[0].totalAvailableBalance,
)
console.log('calculate:')
console.log('Entry Price:', form.data.entryPrice)
console.log('Qty Percent:', form.data.qtyPercent)
console.log(
'Wallet Balance:',
wallet.result.list[0].totalAvailableBalance,
)
const [price, decimals] = form.data.entryPrice.split('.')
console.log('Decimals', decimals)
console.log('Decimals Length', decimals?.length || 0)
const decimalLength = decimals?.length || 0
qty = (
(Number(wallet.result.list[0].totalAvailableBalance) *
((Number(form.data.qtyPercent) / 100) *
Number(form.data.leverage || '1'))) /
Number(form.data.entryPrice)
).toFixed(Number(form.data.qtyDecimalPoint))
takeProfit = (
Number(form.data.entryPrice) *
(1 + Number(form.data.takeProfitPercent) / 100)
).toFixed(decimalLength)
stopLoss = (
Number(form.data.entryPrice) *
(1 - Number(form.data.stopLossPercent) / 100)
).toFixed(decimalLength)
side = form.data.side
} else {
const position = await client.getPositionInfo({
category: 'linear',
symbol: symbol,
})
console.log('closing')
console.log(position.result.list)
if (position.result.list.length <= 0) {
return new Response()
}
if (position.result.list[0].side === 'None')
return new Response()
side =
position.result.list[0].side === 'Buy'
? ('Sell' as const)
: ('Buy' as const)
qty = position.result.list[0].size
}
console.log({ qty, takeProfit, stopLoss })
const order = await client.submitOrder({
category: 'linear',
symbol,
side,
orderType: 'Market',
qty,
takeProfit: side === 'Buy' ? takeProfit : stopLoss,
stopLoss: side === 'Buy' ? stopLoss : takeProfit,
isLeverage: isLeverage ? 1 : 0,
})
return new Response()
} catch (error) {
console.log('Error', error)
} finally {
return new Response()
}
}