diff --git a/src/lib/db/schema.ts b/src/lib/db/schema.ts index 833c177..a7ec32a 100644 --- a/src/lib/db/schema.ts +++ b/src/lib/db/schema.ts @@ -2,6 +2,11 @@ import { pgTable } from 'drizzle-orm/pg-core' export const bybit_logs = pgTable('bybit_logs', (t) => ({ status: t.varchar('status').$type<'success' | 'failed'>().notNull(), + type: t + .varchar('type') + .$type<'order' | 'trading stop'>() + .notNull() + .default('order'), request: t.json('request').notNull(), payload: t.json('payload').notNull(), response: t.json('response').notNull(), diff --git a/src/routes/dashboard/trading-stop/+page.svelte b/src/routes/dashboard/trading-stop/+page.svelte index a080e73..0a3ee71 100644 --- a/src/routes/dashboard/trading-stop/+page.svelte +++ b/src/routes/dashboard/trading-stop/+page.svelte @@ -160,6 +160,44 @@ max={100} step={0.1} /> + + + {#snippet children({ props })} + Active Price (%) + + {/snippet} + + Active Price + + + + + + {#snippet children({ props })} + Trailing Distance Percent (%) + + {/snippet} + + Trailing Distance Percent + + + {#snippet children({ props })} @@ -183,6 +221,9 @@ leverage: $formData.leverage.toString(), takeProfitPercent: $formData.takeProfitPercent.toString(), stopLossPercent: $formData.stopLossPercent.toString(), + activePricePercent: $formData.activePricePercent.toString(), + trailingDistancePercent: + $formData.trailingDistancePercent.toString(), demo: $formData.demo.toString(), }} /> diff --git a/src/routes/dashboard/trading-stop/schema.ts b/src/routes/dashboard/trading-stop/schema.ts index f2d5c79..26d9d0e 100644 --- a/src/routes/dashboard/trading-stop/schema.ts +++ b/src/routes/dashboard/trading-stop/schema.ts @@ -9,6 +9,8 @@ export const formSchema = z.object({ leverage: z.number().default(1), takeProfitPercent: z.number(), stopLossPercent: z.number(), + activePricePercent: z.number(), + trailingDistancePercent: z.number(), demo: z.boolean().default(true), }) diff --git a/src/routes/webhook/tradingview/tradingstop/+server.ts b/src/routes/webhook/tradingview/tradingstop/+server.ts index 1acc880..0b65616 100644 --- a/src/routes/webhook/tradingview/tradingstop/+server.ts +++ b/src/routes/webhook/tradingview/tradingstop/+server.ts @@ -25,6 +25,8 @@ export const POST = async ({ locals, request }) => { leverage: z.string().default('1'), takeProfitPercent: z.string(), stopLossPercent: z.string(), + activePricePercent: z.string(), + trailingDistancePercent: z.string(), demo: z.enum(['true', 'false']), }) @@ -131,43 +133,108 @@ export const POST = async ({ locals, request }) => { console.log('Orders:', orders) - const buyOrder = orders[0] - await db.insert(bybit_logs).values({ - status: buyOrder.retCode === 0 ? 'success' : 'failed', - request: form.data, - payload: { + const activePriceBuy = ( + Number(form.data.entryPrice) * + (1 + Number(form.data.activePricePercent) / 100) + ).toFixed(decimalLength) + + const activePriceSell = ( + Number(form.data.entryPrice) * + (1 - Number(form.data.activePricePercent) / 100) + ).toFixed(decimalLength) + + const trailingDistance = ( + Number(form.data.entryPrice) * + (Number(form.data.activePricePercent) / 100) + ).toFixed(decimalLength) + + const tradingStops = await Promise.all([ + await client.setTradingStop({ category: 'linear', - symbol, - side: 'Buy', - orderType: 'Market', - qty, - takeProfit: takeProfitBuy, - stopLoss: stopLossBuy, - isLeverage: form.data.leverage ? 1 : 0, + activePrice: activePriceBuy, + trailingStop: trailingDistance, + symbol: symbol, positionIdx: 1, - }, - response: buyOrder, - createdAt: Date.now(), - }) + }), + await client.setTradingStop({ + category: 'linear', + activePrice: activePriceSell, + trailingStop: trailingDistance, + symbol: symbol, + positionIdx: 2, + }), + ]) + console.log('Trading Stops:', tradingStops) + + const buyOrder = orders[0] const sellOrder = orders[1] - await db.insert(bybit_logs).values({ - status: sellOrder.retCode === 0 ? 'success' : 'failed', - request: form.data, - payload: { - category: 'linear', - symbol, - side: 'Sell', - orderType: 'Market', - qty, - takeProfit: takeProfitSell, - stopLoss: stopLossSell, - isLeverage: form.data.leverage ? 1 : 0, - positionIdx: 1, - }, - response: sellOrder, - createdAt: Date.now(), - }) + const buyTradingStop = tradingStops[0] + const sellTradingStop = tradingStops[1] + const logs = await Promise.all([ + await db.insert(bybit_logs).values({ + status: buyOrder.retCode === 0 ? 'success' : 'failed', + request: form.data, + payload: { + category: 'linear', + symbol, + side: 'Buy', + orderType: 'Market', + qty, + takeProfit: takeProfitBuy, + stopLoss: stopLossBuy, + isLeverage: form.data.leverage ? 1 : 0, + positionIdx: 1, + }, + response: buyOrder, + createdAt: Date.now(), + }), + await db.insert(bybit_logs).values({ + status: sellOrder.retCode === 0 ? 'success' : 'failed', + request: form.data, + payload: { + category: 'linear', + symbol, + side: 'Sell', + orderType: 'Market', + qty, + takeProfit: takeProfitSell, + stopLoss: stopLossSell, + isLeverage: form.data.leverage ? 1 : 0, + positionIdx: 1, + }, + response: sellOrder, + createdAt: Date.now(), + }), + await db.insert(bybit_logs).values({ + status: buyTradingStop.retCode === 0 ? 'success' : 'failed', + type: 'trading stop', + request: form.data, + payload: { + category: 'linear', + activePrice: activePriceBuy, + trailingStop: trailingDistance, + symbol: symbol, + positionIdx: 1, + }, + response: buyTradingStop, + createdAt: Date.now(), + }), + await db.insert(bybit_logs).values({ + status: sellTradingStop.retCode === 0 ? 'success' : 'failed', + type: 'trading stop', + request: form.data, + payload: { + category: 'linear', + activePrice: activePriceSell, + trailingStop: trailingDistance, + symbol: symbol, + positionIdx: 2, + }, + response: sellTradingStop, + createdAt: Date.now(), + }), + ]) return new Response() } catch (error) {