├── .gitignore ├── exchange.js ├── config.js ├── package.json ├── index.js ├── __tests__ ├── exchange.test.js ├── bot.test.js └── binanceExchange.test.js ├── binanceExchange.js ├── bot.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /node_modules/ 3 | /coverage/ 4 | /coverage/* -------------------------------------------------------------------------------- /exchange.js: -------------------------------------------------------------------------------- 1 | class Exchange { 2 | constructor(apiKey, apiSecret, config) { 3 | this.apiKey = apiKey 4 | this.apiSecret = apiSecret 5 | this.config = config 6 | } 7 | 8 | async fetchOHLCV(symbol, timeframe) { 9 | throw new Error('Not implemented') 10 | } 11 | 12 | async executeOrder(symbol, side, quantity) { 13 | throw new Error('Not implemented') 14 | } 15 | } 16 | 17 | module.exports = Exchange -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | apiKey: 'your_api_key', 3 | apiSecret: 'your_api_secret', 4 | symbol: 'BTC/USDT', 5 | timeframe: '1h', 6 | scalping: { 7 | buyDropPercent: 0.01, // 1% drop for buy signal 8 | sellRisePercent: 0.01 // 1% rise for sell signal 9 | }, 10 | swingTrading: { 11 | fibonacciLevels: [0.236, 0.382, 0.5, 0.618, 0.786] // Fibonacci retracement levels 12 | }, 13 | redis: { 14 | host: 'localhost', 15 | port: 6379 16 | }, 17 | exchange: 'binance' 18 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bot-deepseek-trading", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "jest --coverage", 8 | "test:watch": "jest --watchAll --coverage" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "ccxt": "^4.2.82", 15 | "redis": "^4.6.13", 16 | "technicalindicators": "^3.1.0" 17 | }, 18 | "devDependencies": { 19 | "cheerio": "^1.0.0-rc.12", 20 | "jest": "^29.7.0", 21 | "nock": "^13.5.4" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const config = require('./config') 2 | const BinanceExchange = require('./binanceExchange') 3 | const TradingBot = require('./bot') 4 | 5 | const binance = new BinanceExchange(config.apiKey, config.apiSecret, config) 6 | const bot = new TradingBot(binance, config) 7 | 8 | bot.run().catch(console.error) 9 | 10 | process.on('unhandledRejection', (reason, promise) => { 11 | console.error('Unhandled Rejection at:', promise, 'reason:', reason) 12 | process.exit(1) 13 | }) 14 | 15 | process.on('uncaughtException', (err) => { 16 | console.error('Uncaught Exception thrown:', err) 17 | process.exit(1) 18 | }) -------------------------------------------------------------------------------- /__tests__/exchange.test.js: -------------------------------------------------------------------------------- 1 | const Exchange = require('../exchange') 2 | 3 | describe('Exchange', () => { 4 | let exchange; 5 | 6 | beforeEach(() => { 7 | exchange = new Exchange('apiKey', 'apiSecret', {}); 8 | }); 9 | 10 | test('should throw an error when fetchOHLCV is called', async () => { 11 | await expect(exchange.fetchOHLCV('BTC/USDT', '1h')).rejects.toThrow('Not implemented'); 12 | }); 13 | 14 | test('should throw an error when executeOrder is called', async () => { 15 | await expect(exchange.executeOrder('BTC/USDT', 'buy', 1)).rejects.toThrow('Not implemented'); 16 | }); 17 | }) -------------------------------------------------------------------------------- /binanceExchange.js: -------------------------------------------------------------------------------- 1 | const Exchange = require('./exchange') 2 | const ccxt = require('ccxt') 3 | 4 | class BinanceExchange extends Exchange { 5 | constructor(apiKey, apiSecret, config) { 6 | super(apiKey, apiSecret, config) 7 | this.exchange = new ccxt.binance({ 8 | apiKey: apiKey, 9 | secret: apiSecret 10 | }) 11 | } 12 | 13 | async fetchOHLCV(symbol, timeframe) { 14 | try { 15 | const ohlcv = await this.exchange.fetchOHLCV(symbol, timeframe) 16 | return ohlcv 17 | } catch (error) { 18 | console.error('Error fetching OHLCV data:', error) 19 | throw error 20 | } 21 | } 22 | 23 | async getBalance(symbol) { 24 | try { 25 | const balance = await this.exchange.fetchBalance() 26 | return balance[symbol] 27 | } catch (error) { 28 | console.error('Error fetching balance:', error) 29 | throw error 30 | } 31 | } 32 | 33 | async getOpenOrders(symbol) { 34 | try { 35 | const openOrders = await this.exchange.fetchOpenOrders(symbol) 36 | return openOrders 37 | } catch (error) { 38 | console.error('Error fetching open orders:', error) 39 | throw error 40 | } 41 | } 42 | 43 | async executeOrder(symbol, side, quantity) { 44 | try { 45 | const order = await this.exchange.createMarketOrder(symbol, side, this.exchange.amountToPrecision(symbol, quantity)) 46 | console.log(`Order executed: ${order.id}`) 47 | return order 48 | } catch (error) { 49 | console.error('Error executing order:', error) 50 | throw error 51 | } 52 | } 53 | 54 | async cancelOrder(orderId, symbol) { 55 | try { 56 | const response = await this.exchange.cancelOrder(orderId, symbol) 57 | console.log(`Order canceled: ${orderId}`) 58 | return response 59 | } catch (error) { 60 | console.error('Error canceling order:', error) 61 | throw error 62 | } 63 | } 64 | 65 | calculateFibonacciLevels(high, low) { 66 | const levels = this.config.swingTrading.fibonacciLevels 67 | return levels.map(level => { 68 | const diff = high - low 69 | const levelPrice = high - diff * level 70 | return levelPrice 71 | }) 72 | } 73 | } 74 | 75 | module.exports = BinanceExchange -------------------------------------------------------------------------------- /__tests__/bot.test.js: -------------------------------------------------------------------------------- 1 | const TradingBot = require('../bot'); 2 | const BinanceExchange = require('../binanceExchange'); 3 | const { apiKey, apiSecret, config } = require('../config'); 4 | 5 | jest.mock('../binanceExchange'); 6 | 7 | describe('TradingBot', () => { 8 | let bot; 9 | let exchange; 10 | 11 | beforeEach(() => { 12 | exchange = new BinanceExchange(apiKey, apiSecret, config); 13 | bot = new TradingBot(exchange, config); 14 | }); 15 | 16 | afterEach(() => { 17 | jest.clearAllMocks(); 18 | }); 19 | 20 | test('should check if a trade is open', async () => { 21 | bot.getAsync = jest.fn().mockResolvedValue('open'); 22 | const isOpen = await bot.isTradeOpen(); 23 | expect(isOpen).toBe(true); 24 | expect(bot.getAsync).toHaveBeenCalledWith(bot.config.tradeStateKey); 25 | }); 26 | 27 | test('should set the trade state', async () => { 28 | bot.setAsync = jest.fn().mockResolvedValue(null); 29 | await bot.setTradeState('closed'); 30 | expect(bot.setAsync).toHaveBeenCalledWith(bot.config.tradeStateKey, 'closed'); 31 | }); 32 | 33 | test('should run the swing trading strategy', async () => { 34 | // Mock the exchange's fetchOHLCV method to return sample data 35 | exchange.fetchOHLCV = jest.fn().mockResolvedValue([ 36 | [1504541580000, '0.0027', '0.0027', '0.0027', '0.0027', '10'], // Sample candle 37 | // ... more candles as needed 38 | ]); 39 | 40 | // Mock the bot's calculateFibonacciLevels method 41 | bot.calculateFibonacciLevels = jest.fn().mockReturnValue([0.0020, 0.0023, 0.0027]); 42 | 43 | // Mock the bot's setTradeState method 44 | bot.setTradeState = jest.fn().mockResolvedValue(null); 45 | 46 | // Run the swing trading strategy 47 | await bot.runSwingTradingStrategy(); 48 | 49 | // Assertions will depend on the logic within the strategy 50 | // For example, you might check if the buy or sell signals were triggered 51 | // and if the appropriate methods were called on the exchange 52 | }); 53 | 54 | test('should run the scalping strategy', async () => { 55 | // Mock the exchange's fetchOHLCV method to return sample data 56 | exchange.fetchOHLCV = jest.fn().mockResolvedValue([ 57 | [1504541580000, '0.0027', '0.0027', '0.0027', '0.0027', '10'], // Sample candle 58 | // ... more candles as needed 59 | ]); 60 | 61 | // Mock the bot's setTradeState method 62 | bot.setTradeState = jest.fn().mockResolvedValue(null); 63 | 64 | // Run the scalping strategy 65 | await bot.runScalpingStrategy(); 66 | 67 | // Assertions will depend on the logic within the strategy 68 | // For example, you might check if the buy or sell signals were triggered 69 | // and if the appropriate methods were called on the exchange 70 | }); 71 | }); -------------------------------------------------------------------------------- /__tests__/binanceExchange.test.js: -------------------------------------------------------------------------------- 1 | const nock = require('nock') 2 | const BinanceExchange = require('../binanceExchange') 3 | const { apiKey, apiSecret, config } = require('../config') 4 | 5 | describe('BinanceExchange', () => { 6 | let binanceExchange 7 | 8 | beforeEach(() => { 9 | binanceExchange = new BinanceExchange(apiKey, apiSecret, config) 10 | }); 11 | 12 | afterEach(() => { 13 | nock.cleanAll() 14 | }) 15 | 16 | // ... other tests ... 17 | 18 | test('should get balance', async () => { 19 | const balanceResponse = { 20 | BTC: { 21 | free: '0.1', 22 | used: '0.0', 23 | total: '0.1' 24 | } 25 | } 26 | 27 | nock('https://api.binance.com') 28 | .get('/api/v3/account') 29 | .query({ timestamp: /\d+/ }) // Match any timestamp 30 | .reply(200, balanceResponse) 31 | 32 | const balance = await binanceExchange.getBalance('BTC') 33 | expect(balance).toEqual(balanceResponse.BTC) 34 | }) 35 | 36 | test('should get open orders', async () => { 37 | const openOrdersResponse = [ 38 | { 39 | symbol: 'BTCUSDT', 40 | orderId: 123456789, 41 | // ... other order details 42 | } 43 | ] 44 | 45 | nock('https://api.binance.com') 46 | .get('/api/v3/openOrders') 47 | .query({ symbol: 'BTCUSDT', timestamp: /\d+/ }) // Match any timestamp 48 | .reply(200, openOrdersResponse) 49 | 50 | const openOrders = await binanceExchange.getOpenOrders('BTC/USDT') 51 | expect(openOrders).toEqual(openOrdersResponse) 52 | }) 53 | 54 | test('should execute a market order', async () => { 55 | const orderResponse = { 56 | symbol: 'BTCUSDT', 57 | orderId: 987654321, 58 | // ... other order details 59 | } 60 | 61 | nock('https://api.binance.com') 62 | .post('/api/v3/order', { 63 | symbol: 'BTCUSDT', 64 | side: 'BUY', 65 | type: 'MARKET', 66 | quantity: '0.1', 67 | timestamp: /\d+/, // Match any timestamp 68 | signature: /.+/ // Match any signature 69 | }) 70 | .reply(200, orderResponse) 71 | 72 | const order = await binanceExchange.executeOrder('BTC/USDT', 'buy', 0.1) 73 | expect(order).toEqual(orderResponse) 74 | }); 75 | 76 | test('should cancel an order', async () => { 77 | const cancelResponse = { 78 | symbol: 'BTCUSDT', 79 | orderId: 987654321, 80 | // ... other cancellation details 81 | } 82 | 83 | nock('https://api.binance.com') 84 | .delete('/api/v3/order', { 85 | symbol: 'BTCUSDT', 86 | orderId: '987654321', 87 | timestamp: /\d+/, // Match any timestamp 88 | signature: /.+/ // Match any signature 89 | }) 90 | .reply(200, cancelResponse) 91 | 92 | const cancel = await binanceExchange.cancelOrder(987654321, 'BTC/USDT') 93 | expect(cancel).toEqual(cancelResponse) 94 | }) 95 | }) -------------------------------------------------------------------------------- /bot.js: -------------------------------------------------------------------------------- 1 | const redis = require('redis') 2 | const { promisify } = require('util') 3 | const Exchange = require('./exchange') 4 | 5 | class TradingBot { 6 | constructor(exchange, config) { 7 | if (!(exchange instanceof Exchange)) throw new Error('Invalid exchange instance') 8 | this.exchange = exchange 9 | this.config = config 10 | this.redisClient = redis.createClient(config.redis) 11 | this.getAsync = promisify(this.redisClient.get).bind(this.redisClient) 12 | this.setAsync = promisify(this.redisClient.set).bind(this.redisClient) 13 | } 14 | 15 | async isTradeOpen() { 16 | const tradeState = await this.getAsync(this.config.tradeStateKey) 17 | return tradeState === 'open' 18 | } 19 | 20 | async setTradeState(state) { 21 | await this.setAsync(this.config.tradeStateKey, state) 22 | } 23 | 24 | async runSwingTradingStrategy() { 25 | // Fetch OHLCV data 26 | const ohlcv = await this.exchange.fetchOHLCV(this.config.symbol, this.config.timeframe) 27 | if (!ohlcv || ohlcv.length === 0) { 28 | console.log('No OHLCV data available.') 29 | return 30 | } 31 | 32 | // Calculate Fibonacci levels 33 | const high = Math.max(...ohlcv.map(candle => candle[2])) 34 | const low = Math.min(...ohlcv.map(candle => candle[3])) 35 | const closingPrices = ohlcv.map(candle => candle[4]) 36 | const currentPrice = closingPrices[closingPrices.length - 1] 37 | const fibonacciLevels = this.calculateFibonacciLevels(high, low) 38 | 39 | // Check for buy or sell signals 40 | if (currentPrice > fibonacciLevels[fibonacciLevels.length - 1]) { 41 | console.log('Buy signal triggered at Fibonacci level') 42 | // Execute buy order logic here 43 | } else if (currentPrice < fibonacciLevels[0]) { 44 | console.log('Sell signal triggered at Fibonacci level') 45 | // Execute sell order logic here 46 | } 47 | } 48 | 49 | async runScalpingStrategy() { 50 | // Fetch OHLCV data 51 | const ohlcv = await this.exchange.fetchOHLCV(this.config.symbol, this.config.timeframe) 52 | if (!ohlcv || ohlcv.length === 0) { 53 | console.log('No OHLCV data available.') 54 | return 55 | } 56 | 57 | // Calculate scalping thresholds 58 | const closingPrices = ohlcv.map(candle => candle[4]) 59 | const currentPrice = closingPrices[closingPrices.length - 1] 60 | const buyDrop = currentPrice * (1 - this.config.scalping.buyDropPercent) 61 | const sellRise = currentPrice * (1 + this.config.scalping.sellRisePercent) 62 | 63 | // Check for buy or sell signals 64 | if (currentPrice < buyDrop) { 65 | console.log('Buy signal triggered at scalping strategy') 66 | // Execute buy order logic here 67 | } else if (currentPrice > sellRise) { 68 | console.log('Sell signal triggered at scalping strategy') 69 | // Execute sell order logic here 70 | } 71 | } 72 | 73 | async run() { 74 | if (await this.isTradeOpen()) { 75 | console.log('A trade is currently open, waiting for it to close before starting a new one.') 76 | return 77 | } 78 | 79 | try { 80 | await this.runSwingTradingStrategy() 81 | await this.runScalpingStrategy() 82 | } finally { 83 | await this.setTradeState('closed') 84 | } 85 | } 86 | 87 | calculateFibonacciLevels(high, low) { 88 | const levels = this.config.swingTrading.fibonacciLevels 89 | return levels.map(level => { 90 | const diff = high - low 91 | const levelPrice = high - diff * level 92 | return levelPrice 93 | }) 94 | } 95 | } 96 | 97 | module.exports = TradingBot -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # DeepSeek-Trading Bot Design 3 | 4 | (This is version 1 and you want more efficent and perfect bot for your trading, please contact to me!) 5 | 6 | ## 1. Core Features 7 | - **Data Collection**: Fetch real-time and historical data from DexScreener or other sources. 8 | - **Data Parsing**: Extract relevant information (e.g., price, volume, liquidity, market cap, etc.). 9 | - **Data Storage**: Save data to a database for historical analysis. 10 | - **Pattern Analysis**: Use machine learning or statistical methods to identify patterns. 11 | - **Alert System**: Notify users when specific patterns (e.g., pump, rug pull) are detected. 12 | 13 | ## 2. Tech Stack 14 | - **Programming Language**: JavaScript (Node.js) 15 | 16 | ### Libraries: 17 | - `axios` or `node-fetch` for API calls 18 | - `cheerio` for HTML parsing (if needed) 19 | - `redis` or `PostgreSQL` for database storage 20 | - `technicalindicators` for pattern analysis 21 | - `telegram-bot-api` for Telegram notifications 22 | 23 | ### APIs: 24 | - DexScreener API (if available) or web scraping. 25 | 26 | ## 3. Workflow 27 | - **Fetch Data**: Use DexScreener's API or scrape the website to collect data. 28 | - **Parse Data**: Extract key metrics (e.g., price, volume, liquidity). 29 | - **Store Data**: Save parsed data into a database like Redis or PostgreSQL. 30 | - **Analyze Data**: Identify patterns using statistical or machine learning models. 31 | - **Generate Alerts**: Notify users when specific conditions are met. 32 | 33 | ### Integrated Features: 34 | 1. **Telegram Integration**: 35 | - Real-time buy/sell notifications 36 | - Manual trading commands (`/buy`, `/sell`) 37 | - Status updates and alerts 38 | 39 | 2. **BonkBot Trading**: 40 | - Automated trade execution based on signals 41 | - Configurable trade size and slippage 42 | - Trade confirmation with TX hashes 43 | 44 | 3. **Enhanced Security**: 45 | - Integrated Rugcheck.xyz verification 46 | - Supply distribution checks 47 | - Dynamic blacklisting system 48 | 49 | 4. **Continuous Monitoring**: 50 | - 24/7 market scanning 51 | - 5-minute interval checks 52 | - Automated anomaly detection 53 | 54 | --- 55 | 56 | ### **Setup Instructions** 57 | 58 | 1. **Replace placeholder values in `CONFIG`**: 59 | - Telegram bot token 60 | - Chat ID 61 | - BonkBot API key 62 | - Pair addresses to monitor 63 | 64 | 2. **Install required packages**: 65 | ```bash 66 | npm install axios cheerio redis technicalindicators node-fetch telegram-bot-api 67 | ``` 68 | 69 | 3. **Run the bot**: 70 | ```bash 71 | node bot.js 72 | ``` 73 | 74 | --- 75 | 76 | ### **Commands Available** 77 | - `/start` - Show help menu 78 | - `/buy ` - Execute manual buy order 79 | - `/sell ` - Execute manual sell order 80 | - Automatic alerts for detected opportunities 81 | 82 | --- 83 | 84 | ### **Recommended Improvements** 85 | 1. Add stop-loss/take-profit functionality 86 | 2. Implement portfolio balancing 87 | 3. Add multi-exchange support 88 | 4. Integrate backtesting framework 89 | 5. Add detailed risk management controls 90 | 91 | --- 92 | 93 | ### **Additional Notes** 94 | - This bot uses a custom configuration file (`CONFIG`) to store important keys, like Telegram bot token and BonkBot API key. Be sure to replace the placeholders with your own credentials. 95 | - The bot fetches data from DexScreener or other similar APIs, parses it, and uses the `technicalindicators` library to analyze the data for trading opportunities. 96 | - Alerts are sent via Telegram, and trades can be executed automatically or manually based on user commands. 97 | 98 | --- 99 | 100 | ### **Package Dependencies**: 101 | 102 | The `package.json` includes the following dependencies: 103 | - `ccxt`: For integrating exchange data (optional for additional exchange support). 104 | - `redis`: For storing data in a Redis database (optional, can be replaced with PostgreSQL or other database solutions). 105 | - `technicalindicators`: For pattern analysis and identifying trading signals. 106 | - `cheerio`: For HTML parsing (if you need to scrape web data). 107 | - `jest` & `nock`: For testing and mocking API calls. 108 | 109 | ### **Testing**: 110 | You can run the tests with Jest using: 111 | ```bash 112 | npm test 113 | ``` 114 | 115 | For continuous testing with Jest in watch mode, run: 116 | ```bash 117 | npm run test:watch 118 | ``` 119 | 120 | ### ✉ Connect With Me: 121 | 122 | [![Twitter Badge](https://img.shields.io/badge/Twitter-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white)](https://twitter.com/MichalStefanow) 123 | [![Mail Badge](https://img.shields.io/badge/Gmail-D14836?style=for-the-badge&logo=gmail&logoColor=white)](mailto:nikolic.miloje0507@gmail.com) 124 | [![Telegram Badge](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/mylord1_1) 125 | [![Skype Badge](https://img.shields.io/badge/Skype-00AFF0?style=for-the-badge&logo=skype&logoColor=white)](https://join.skype.com/ubWuVGchDEnU) 126 | [![Discord Badge](https://img.shields.io/badge/Discord-5865F2?style=for-the-badge&logo=discord&logoColor=white)](https://discord.com/users/509337382810550280) 127 | --------------------------------------------------------------------------------