Merge branch 'main' of http://192.168.1.16:3210/administrator/ai-trading-sys
This commit is contained in:
commit
272ba19977
3 changed files with 75 additions and 30 deletions
|
|
@ -4,6 +4,7 @@ export interface Position {
|
||||||
entry: number;
|
entry: number;
|
||||||
leverage: number;
|
leverage: number;
|
||||||
volume: number;
|
volume: number;
|
||||||
profit: number;
|
sl: number;
|
||||||
profitPercentage: number;
|
tp: number;
|
||||||
|
status: string;
|
||||||
}
|
}
|
||||||
|
|
@ -16,8 +16,6 @@ const bybitService = new BybitService(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const eventHandlerFuture: EventHandler = {
|
export const eventHandlerFuture: EventHandler = {
|
||||||
onBuy: (order: Order, reason: string) => {
|
onBuy: (order: Order, reason: string) => {
|
||||||
sendMessage(`Future Buy ${order.symbol} ${order.interval}M
|
sendMessage(`Future Buy ${order.symbol} ${order.interval}M
|
||||||
|
|
@ -35,7 +33,8 @@ export const eventHandlerFuture: EventHandler = {
|
||||||
side: "Buy",
|
side: "Buy",
|
||||||
orderType: "Limit",
|
orderType: "Limit",
|
||||||
price: Number(order.entry).toFixed(2),
|
price: Number(order.entry).toFixed(2),
|
||||||
qty: '1',
|
stopLoss: Number(order.stopLoss).toFixed(2),
|
||||||
|
qty: "1",
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
|
|
@ -57,13 +56,17 @@ export const eventHandlerFuture: EventHandler = {
|
||||||
side: "Sell",
|
side: "Sell",
|
||||||
orderType: "Limit",
|
orderType: "Limit",
|
||||||
price: Number(order.entry).toFixed(2),
|
price: Number(order.entry).toFixed(2),
|
||||||
qty: '1',
|
stopLoss: Number(order.stopLoss).toFixed(2),
|
||||||
|
qty: "1",
|
||||||
});
|
});
|
||||||
console.log(
|
console.log(
|
||||||
`Sell ${order.symbol} ${order.interval}M ${reason} ${order.entry}`
|
`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") {
|
if (eventType === "HighVolatility") {
|
||||||
const positions = await bybitService.listPositions({
|
const positions = await bybitService.listPositions({
|
||||||
category: "linear",
|
category: "linear",
|
||||||
|
|
@ -78,10 +81,15 @@ export const eventHandlerFuture: EventHandler = {
|
||||||
symbol: analysis.symbol,
|
symbol: analysis.symbol,
|
||||||
side: "Sell",
|
side: "Sell",
|
||||||
orderType: "Limit",
|
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,
|
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 && candle.close < candle.open) {
|
if (position.side === "Sell" && analysis.isUnderBbLower && candle.close < candle.open) {
|
||||||
const halfSize = (Number(position.size) / 2).toFixed(2);
|
const halfSize = (Number(position.size) / 2).toFixed(2);
|
||||||
|
|
@ -90,10 +98,15 @@ export const eventHandlerFuture: EventHandler = {
|
||||||
symbol: analysis.symbol,
|
symbol: analysis.symbol,
|
||||||
side: "Buy",
|
side: "Buy",
|
||||||
orderType: "Limit",
|
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,
|
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,7 +130,7 @@ const eventHandlerSpot: EventHandler = {
|
||||||
side: "Buy",
|
side: "Buy",
|
||||||
orderType: "Limit",
|
orderType: "Limit",
|
||||||
price: Number(order.entry).toFixed(2),
|
price: Number(order.entry).toFixed(2),
|
||||||
qty: '1',
|
qty: "1",
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
|
|
@ -134,8 +147,10 @@ const eventHandlerSpot: EventHandler = {
|
||||||
reason: ${reason}
|
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 = {
|
const eventHandlerNotification: EventHandler = {
|
||||||
|
|
@ -163,8 +178,10 @@ const eventHandlerNotification: EventHandler = {
|
||||||
reason: ${reason}
|
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);
|
createCandleAnalysisSchedule("ETHUSDT", "15", eventHandlerFuture);
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,23 @@ import { Order } from "../dao/order";
|
||||||
import { supabase } from "./supabaseService";
|
import { supabase } from "./supabaseService";
|
||||||
import { Wave } from "../dao/wave";
|
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 {
|
export interface EventHandler {
|
||||||
onBuy: (candle: Order, reason: string) => void;
|
onBuy: (candle: Order, reason: string) => void;
|
||||||
onSell: (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 {
|
export class IndicatorService {
|
||||||
|
|
@ -36,7 +47,7 @@ export class IndicatorService {
|
||||||
}
|
}
|
||||||
let close = candles.map((c) => c.close);
|
let close = candles.map((c) => c.close);
|
||||||
const ema34 = EMA.calculate({
|
const ema34 = EMA.calculate({
|
||||||
period: 20,
|
period: 34,
|
||||||
values: close,
|
values: close,
|
||||||
reversedInput: true,
|
reversedInput: true,
|
||||||
});
|
});
|
||||||
|
|
@ -244,19 +255,29 @@ export class IndicatorService {
|
||||||
);
|
);
|
||||||
let entry = candles[0].close;
|
let entry = candles[0].close;
|
||||||
if (side === "buy") {
|
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;
|
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;
|
entry = analysis.currentBB.lower;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (side === "sell") {
|
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;
|
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;
|
entry = analysis.currentBB.upper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -277,12 +298,18 @@ export class IndicatorService {
|
||||||
candles: Candle[],
|
candles: Candle[],
|
||||||
eventHandler: EventHandler
|
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");
|
const order = this.makeOrder(analysis, candles, "buy");
|
||||||
eventHandler.onBuy(order, "Follow trend EMA Touch 200");
|
eventHandler.onBuy(order, "Follow trend EMA Touch 200");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((analysis.isTouch200 || analysis.isReverse200) && analysis.emaDirection === "Bearish") {
|
if (
|
||||||
|
(analysis.isTouch200 || analysis.isReverse200) &&
|
||||||
|
analysis.emaDirection === "Bearish"
|
||||||
|
) {
|
||||||
const order = this.makeOrder(analysis, candles, "sell");
|
const order = this.makeOrder(analysis, candles, "sell");
|
||||||
eventHandler.onSell(order, "Follow trend EMA Touch 200");
|
eventHandler.onSell(order, "Follow trend EMA Touch 200");
|
||||||
return;
|
return;
|
||||||
|
|
@ -316,7 +343,7 @@ export class IndicatorService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (analysis.isHighVolatility) {
|
if (analysis.isHighVolatility) {
|
||||||
eventHandler.onEvent("HighVolatility", {candle: candles[0], analysis});
|
eventHandler.onEvent("HighVolatility", { candle: candles[0], analysis });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue