From fa0df46e0426890d67c5e19ff6a9e1e781dd267e Mon Sep 17 00:00:00 2001 From: TZGyn Date: Wed, 19 Feb 2025 21:54:44 +0800 Subject: [PATCH] add close position schema --- src/routes/api/bybit/test/+server.ts | 24 ++++++- src/routes/dashboard/bybit/+page.svelte | 80 ++++++++++++++++++++++- src/routes/dashboard/bybit/+page.ts | 18 ++++- src/routes/dashboard/bybit/schema.ts | 8 +++ src/routes/webhook/tradingview/+server.ts | 60 +++++++++-------- 5 files changed, 156 insertions(+), 34 deletions(-) diff --git a/src/routes/api/bybit/test/+server.ts b/src/routes/api/bybit/test/+server.ts index ab8190c..da96cd4 100644 --- a/src/routes/api/bybit/test/+server.ts +++ b/src/routes/api/bybit/test/+server.ts @@ -10,9 +10,29 @@ export const POST = async () => { const orders = await client.getActiveOrders({ category: 'linear', - baseCoin: 'USDT', + symbol: 'BTC', }) - console.log(orders) + + const orderbook = await client.getOrderbook({ + category: 'linear', + symbol: 'BTCUSDT', + }) + + // console.log(orderbook.result) + + const history = await client.getHistoricOrders({ + category: 'linear', + orderStatus: 'Filled', + }) + // console.log(history.result.list) + + const position = await client.getPositionInfo({ + category: 'linear', + symbol: 'BTCUSDT', + }) + console.log(position.result) + + // console.log(orders) return json({ orders, }) diff --git a/src/routes/dashboard/bybit/+page.svelte b/src/routes/dashboard/bybit/+page.svelte index 9c549eb..b310089 100644 --- a/src/routes/dashboard/bybit/+page.svelte +++ b/src/routes/dashboard/bybit/+page.svelte @@ -5,7 +5,11 @@ import { Input } from '$lib/components/ui/input' import { superForm } from 'sveltekit-superforms' import { zod } from 'sveltekit-superforms/adapters' - import { formSchema, percentSchema } from './schema' + import { + closePositionSchema, + formSchema, + percentSchema, + } from './schema' import { Slider } from '$lib/components/ui/slider/index.js' import { JsonView } from '@zerodevx/svelte-json-view' import copy from 'copy-to-clipboard' @@ -65,6 +69,31 @@ const { form: percentFormData, enhance: percentEnhance } = percentForm + + const closePositionForm = superForm(data.closePositionForm, { + resetForm: false, + SPA: true, + validators: zod(closePositionSchema), + onSubmit: ({}) => { + copy( + JSON.stringify( + { + type: 'Close Position', + ...$closePositionFormData, + entryPrice: '{trigger_entry_value}', + }, + null, + 2, + ), + ) + toast.success('Copied to Clipboard') + }, + }) + + const { + form: closePositionFormData, + enhance: closePositionEnhance, + } = closePositionForm
@@ -72,6 +101,7 @@ Flat Percent + Close
@@ -309,5 +339,53 @@ $percentFormData.stopLossPercent.toString(), }} /> + + + + + {#snippet children({ props })} + Key + + {/snippet} + + Key + + + + + {#snippet children({ props })} + Secret + + {/snippet} + + Secret + + + + + {#snippet children({ props })} + Symbol + + {/snippet} + + Symbol + + + Copy + + +
diff --git a/src/routes/dashboard/bybit/+page.ts b/src/routes/dashboard/bybit/+page.ts index 3f2e7ab..0a3f2d7 100644 --- a/src/routes/dashboard/bybit/+page.ts +++ b/src/routes/dashboard/bybit/+page.ts @@ -1,7 +1,11 @@ import { superValidate } from 'sveltekit-superforms' import { zod } from 'sveltekit-superforms/adapters' import type { PageLoad } from './$types' -import { formSchema, percentSchema } from './schema' +import { + closePositionSchema, + formSchema, + percentSchema, +} from './schema' export const load = (async () => { const form = await superValidate( @@ -23,5 +27,15 @@ export const load = (async () => { zod(percentSchema), { errors: false }, ) - return { form, percentForm } + + const closePositionForm = await superValidate( + { + key: '', + secret: '', + symbol: 'BTCUSDT', + }, + zod(closePositionSchema), + { errors: false }, + ) + return { form, percentForm, closePositionForm } }) satisfies PageLoad diff --git a/src/routes/dashboard/bybit/schema.ts b/src/routes/dashboard/bybit/schema.ts index e7ae896..995a180 100644 --- a/src/routes/dashboard/bybit/schema.ts +++ b/src/routes/dashboard/bybit/schema.ts @@ -24,6 +24,14 @@ export const percentSchema = z.object({ stopLossPercent: z.number(), }) +export const closePositionSchema = z.object({ + key: z.string(), + secret: z.string(), + symbol: z.string(), +}) + export type PercentSchema = typeof percentSchema export type FormSchema = typeof formSchema + +export type ClosePositionSchema = typeof closePositionSchema diff --git a/src/routes/webhook/tradingview/+server.ts b/src/routes/webhook/tradingview/+server.ts index b729c1e..eabdaeb 100644 --- a/src/routes/webhook/tradingview/+server.ts +++ b/src/routes/webhook/tradingview/+server.ts @@ -34,22 +34,28 @@ export const POST = async ({ locals, request }) => { takeProfitPercent: z.string().optional(), stopLossPercent: z.string().optional(), }) - const form = z.union([flatSchema, percentSchema]).safeParse(body) + 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 apiKey = 'wrc1w54Zp5JAfXLxY2' - // const apiSecret = 'tY7oYPhwSE1gabFS4PmxtmbDOhkYWvPh0khf' - - const { key, secret, side, symbol } = form.data + const { key, secret, symbol } = form.data try { let qty let takeProfit let stopLoss + let side const client = new RestClientV5({ key: key, @@ -57,34 +63,12 @@ export const POST = async ({ locals, request }) => { demoTrading: true, }) - const orders = await client.getActiveOrders({ - category: 'linear', - symbol, - }) - - const amount = orders.result.list.reduce( - (acc, curr) => acc + Number(curr.qty), - 0, - ) - - if (amount > 0) { - const order = await client.submitOrder({ - category: 'linear', - symbol, - side, - orderType: 'Market', - qty: amount.toString(), - takeProfit, - stopLoss, - }) - return new Response() - } - if (form.data.type === 'Flat') { qty = form.data.qty takeProfit = form.data.takeProfit stopLoss = form.data.stopLoss - } else { + side = form.data.side + } else if (form.data.type === 'Percent') { const wallet = await client.getWalletBalance({ accountType: 'UNIFIED', coin: 'USDT', @@ -109,6 +93,24 @@ export const POST = async ({ locals, request }) => { Number(form.data.entryPrice) * (1 - Number(form.data.stopLossPercent) / 100) ).toFixed(1) + side = form.data.side + } else { + const position = await client.getPositionInfo({ + category: 'linear', + symbol: symbol, + }) + + 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].positionValue } console.log({ qty, takeProfit, stopLoss })