From 8354aa5acdc6f0ce19848ef7cb43a0f19ce60a1c Mon Sep 17 00:00:00 2001 From: kienvt Date: Thu, 17 Jul 2025 17:06:54 +0700 Subject: [PATCH 1/3] update --- src/services/indicatorService.ts | 47 +++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/src/services/indicatorService.ts b/src/services/indicatorService.ts index d4d2715..e72b456 100644 --- a/src/services/indicatorService.ts +++ b/src/services/indicatorService.ts @@ -11,12 +11,23 @@ import { Order } from "../dao/order"; import { supabase } from "./supabaseService"; import { Wave } from "../dao/wave"; -export type EventType = "HighVolatility" | "PinBar" | "EmaCross" | "MacdCross" | "MacdCrossUp" | "MacdCrossDown" | "Touch200" | "Reverse200"; +export type EventType = + | "HighVolatility" + | "PinBar" + | "EmaCross" + | "MacdCross" + | "MacdCrossUp" + | "MacdCrossDown" + | "Touch200" + | "Reverse200"; export interface EventHandler { onBuy: (candle: Order, reason: string) => void; onSell: (candle: Order, reason: string) => void; - onEvent: (eventType: EventType, {candle, analysis}: {candle: Candle, analysis: Analysis}) => void; + onEvent: ( + eventType: EventType, + { candle, analysis }: { candle: Candle; analysis: Analysis } + ) => void; } export class IndicatorService { @@ -233,7 +244,7 @@ export class IndicatorService { candles: Candle[], side: "buy" | "sell" ): Order { - const last10Candles = candles.slice(0, 12); + const last10Candles = candles.slice(0, 5); const lowestPrice = last10Candles.reduce( (min, c) => Math.min(min, c.low), Number.MAX_SAFE_INTEGER @@ -244,19 +255,29 @@ export class IndicatorService { ); let entry = candles[0].close; if (side === "buy") { - if (analysis.currentBB.upper < Math.max(candles[0].close, candles[0].open)) { + if ( + analysis.currentBB.upper < Math.max(candles[0].close, candles[0].open) + ) { entry = analysis.currentBB.upper; } - if (analysis.currentBB.lower < candles[0].open && analysis.currentBB.lower > candles[0].close) { + if ( + analysis.currentBB.lower < candles[0].open && + analysis.currentBB.lower > candles[0].close + ) { entry = analysis.currentBB.lower; } } if (side === "sell") { - if (analysis.currentBB.lower > Math.min(candles[0].close, candles[0].open)) { + if ( + analysis.currentBB.lower > Math.min(candles[0].close, candles[0].open) + ) { entry = analysis.currentBB.lower; } - if (analysis.currentBB.upper > candles[0].open && analysis.currentBB.upper < candles[0].close) { + if ( + analysis.currentBB.upper > candles[0].open && + analysis.currentBB.upper < candles[0].close + ) { entry = analysis.currentBB.upper; } } @@ -277,12 +298,18 @@ export class IndicatorService { candles: Candle[], eventHandler: EventHandler ) { - if ((analysis.isTouch200 || analysis.isReverse200) && analysis.emaDirection === "Bullish") { + if ( + (analysis.isTouch200 || analysis.isReverse200) && + analysis.emaDirection === "Bullish" + ) { const order = this.makeOrder(analysis, candles, "buy"); eventHandler.onBuy(order, "Follow trend EMA Touch 200"); return; } - if ((analysis.isTouch200 || analysis.isReverse200) && analysis.emaDirection === "Bearish") { + if ( + (analysis.isTouch200 || analysis.isReverse200) && + analysis.emaDirection === "Bearish" + ) { const order = this.makeOrder(analysis, candles, "sell"); eventHandler.onSell(order, "Follow trend EMA Touch 200"); return; @@ -316,7 +343,7 @@ export class IndicatorService { } if (analysis.isHighVolatility) { - eventHandler.onEvent("HighVolatility", {candle: candles[0], analysis}); + eventHandler.onEvent("HighVolatility", { candle: candles[0], analysis }); } } From 3d0079dd068f439e8be3b43bbe24808686919e4a Mon Sep 17 00:00:00 2001 From: kienvt Date: Thu, 17 Jul 2025 17:25:07 +0700 Subject: [PATCH 2/3] update --- src/services/indicatorService.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/services/indicatorService.ts b/src/services/indicatorService.ts index e72b456..e412fdf 100644 --- a/src/services/indicatorService.ts +++ b/src/services/indicatorService.ts @@ -47,7 +47,7 @@ export class IndicatorService { } let close = candles.map((c) => c.close); const ema34 = EMA.calculate({ - period: 20, + period: 34, values: close, reversedInput: true, }); @@ -244,7 +244,7 @@ export class IndicatorService { candles: Candle[], side: "buy" | "sell" ): Order { - const last10Candles = candles.slice(0, 5); + const last10Candles = candles.slice(0, 12); const lowestPrice = last10Candles.reduce( (min, c) => Math.min(min, c.low), Number.MAX_SAFE_INTEGER From 66d33e7cb3f4a9bc630a0013e31a603d5e8f83f7 Mon Sep 17 00:00:00 2001 From: kienvt Date: Thu, 17 Jul 2025 17:38:51 +0700 Subject: [PATCH 3/3] update --- src/dao/position.ts | 7 +++--- src/schedule/index.ts | 51 ++++++++++++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/dao/position.ts b/src/dao/position.ts index 7fcadc2..d915b3a 100644 --- a/src/dao/position.ts +++ b/src/dao/position.ts @@ -4,6 +4,7 @@ export interface Position { entry: number; leverage: number; volume: number; - profit: number; - profitPercentage: number; -} \ No newline at end of file + sl: number; + tp: number; + status: string; +} diff --git a/src/schedule/index.ts b/src/schedule/index.ts index 5957d57..0b3a2fd 100644 --- a/src/schedule/index.ts +++ b/src/schedule/index.ts @@ -16,8 +16,6 @@ const bybitService = new BybitService( false ); - - export const eventHandlerFuture: EventHandler = { onBuy: (order: Order, reason: string) => { sendMessage(`Future Buy ${order.symbol} ${order.interval}M @@ -35,9 +33,10 @@ export const eventHandlerFuture: EventHandler = { side: "Buy", orderType: "Limit", price: Number(order.entry).toFixed(2), - qty: '1', + stopLoss: Number(order.stopLoss).toFixed(2), + qty: "1", }); - + console.log( `Buy ${order.symbol} ${order.interval}M ${reason} ${order.entry}` ); @@ -57,13 +56,17 @@ export const eventHandlerFuture: EventHandler = { side: "Sell", orderType: "Limit", price: Number(order.entry).toFixed(2), - qty: '1', + stopLoss: Number(order.stopLoss).toFixed(2), + qty: "1", }); console.log( `Sell ${order.symbol} ${order.interval}M ${reason} ${order.entry}` ); }, - onEvent: async (eventType: EventType, {candle, analysis}: {candle: Candle, analysis: Analysis}) => { + onEvent: async ( + eventType: EventType, + { candle, analysis }: { candle: Candle; analysis: Analysis } + ) => { if (eventType === "HighVolatility") { const positions = await bybitService.listPositions({ category: "linear", @@ -78,10 +81,15 @@ export const eventHandlerFuture: EventHandler = { symbol: analysis.symbol, side: "Sell", orderType: "Limit", - price: candle.close > analysis.currentBB.upper ? Number(candle.close).toFixed(2) : Number(analysis.currentBB.upper).toFixed(2), + price: + candle.close > analysis.currentBB.upper + ? Number(candle.close).toFixed(2) + : Number(analysis.currentBB.upper).toFixed(2), qty: halfSize, }); - sendMessage(`Future Căt nửa ${analysis.symbol} ${analysis.interval}M ${analysis.currentBB.upper} ${halfSize}`); + sendMessage( + `Future Căt nửa ${analysis.symbol} ${analysis.interval}M ${analysis.currentBB.upper} ${halfSize}` + ); } if (position.side === "Sell" && analysis.isUnderBbLower) { const halfSize = (Number(position.size) / 2).toFixed(2); @@ -90,10 +98,15 @@ export const eventHandlerFuture: EventHandler = { symbol: analysis.symbol, side: "Buy", orderType: "Limit", - price: candle.close < analysis.currentBB.lower ? Number(candle.close).toFixed(2) : Number(analysis.currentBB.lower).toFixed(2), + price: + candle.close < analysis.currentBB.lower + ? Number(candle.close).toFixed(2) + : Number(analysis.currentBB.lower).toFixed(2), qty: halfSize, }); - sendMessage(`Future Căt nửa ${analysis.symbol} ${analysis.interval}M ${analysis.currentBB.lower} ${halfSize}`); + sendMessage( + `Future Căt nửa ${analysis.symbol} ${analysis.interval}M ${analysis.currentBB.lower} ${halfSize}` + ); } } } @@ -117,9 +130,9 @@ const eventHandlerSpot: EventHandler = { side: "Buy", orderType: "Limit", price: Number(order.entry).toFixed(2), - qty: '1', + qty: "1", }); - + console.log( `Buy ${order.symbol} ${order.interval}M ${reason} ${order.entry}` ); @@ -134,8 +147,10 @@ const eventHandlerSpot: EventHandler = { reason: ${reason} `); }, - onEvent: async (eventType: EventType, {candle, analysis}: {candle: Candle, analysis: Analysis}) => { - }, + onEvent: async ( + eventType: EventType, + { candle, analysis }: { candle: Candle; analysis: Analysis } + ) => {}, }; const eventHandlerNotification: EventHandler = { @@ -148,7 +163,7 @@ const eventHandlerNotification: EventHandler = { volume: ${order.volume} reason: ${reason} `); - + console.log( `Buy ${order.symbol} ${order.interval}M ${reason} ${order.entry}` ); @@ -163,8 +178,10 @@ const eventHandlerNotification: EventHandler = { reason: ${reason} `); }, - onEvent: async (eventType: EventType, {candle, analysis}: {candle: Candle, analysis: Analysis}) => { - }, + onEvent: async ( + eventType: EventType, + { candle, analysis }: { candle: Candle; analysis: Analysis } + ) => {}, }; createCandleAnalysisSchedule("ETHUSDT", "15", eventHandlerFuture);