Deriv Rise/Fall Trading Bot

Automated trading bot for Rise and Fall on Deriv with Martingale strategy and intelligent analysis

Size

31.6 KB

Version

1.2.8

Created

Dec 20, 2025

Updated

about 2 months ago

1// ==UserScript==
2// @name		Deriv Rise/Fall Trading Bot
3// @description		Automated trading bot for Rise and Fall on Deriv with Martingale strategy and intelligent analysis
4// @version		1.2.8
5// @match		https://*.app.deriv.com/*
6// @icon		https://app.deriv.com/favicon.ico
7// ==/UserScript==
8(function() {
9    'use strict';
10
11    // Bot configuration and state
12    const botState = {
13        isRunning: false,
14        strategy: 'martingale',
15        baseStake: 1,
16        currentStake: 1,
17        tradeType: 'rise', // 'rise' or 'fall'
18        stats: {
19            totalTrades: 0,
20            wins: 0,
21            losses: 0,
22            profit: 0,
23            winStreak: 0,
24            lossStreak: 0
25        },
26        lastTradeResult: null,
27        martingaleMultiplier: 2,
28        maxStake: 1000,
29        delayBetweenTrades: 5000,
30        balanceBeforeTrade: 0,
31        useAnalysis: true,
32        useTrendAnalysis: true,
33        trendHistory: [] // Store last 10 results
34    };
35
36    const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
37
38    // Create bot UI
39    function createBotUI() {
40        console.log('Creating Even/Odd bot UI...');
41        
42        const existingUI = document.getElementById('deriv-bot-panel');
43        if (existingUI) existingUI.remove();
44
45        const botPanel = document.createElement('div');
46        botPanel.id = 'deriv-bot-panel';
47        botPanel.innerHTML = `
48            <div class="bot-header">
49                <h3>Rise/Fall Bot</h3>
50                <button id="bot-minimize" class="bot-btn-icon"></button>
51            </div>
52            <div class="bot-content">
53                <div class="bot-section">
54                    <label>Strategy:</label>
55                    <select id="bot-strategy" class="bot-select">
56                        <option value="martingale">Martingale</option>
57                        <option value="anti-martingale">Anti-Martingale</option>
58                        <option value="fixed">Fixed Stake</option>
59                    </select>
60                </div>
61                
62                <div class="bot-section">
63                    <label>Trade Type:</label>
64                    <select id="bot-trade-type" class="bot-select">
65                        <option value="rise">Rise</option>
66                        <option value="fall">Fall</option>
67                        <option value="alternate">Alternate</option>
68                    </select>
69                </div>
70                
71                <div class="bot-section">
72                    <label>Base Stake (USD):</label>
73                    <input type="number" id="bot-stake" class="bot-input" value="1" min="1" step="1">
74                </div>
75                
76                <div class="bot-section">
77                    <label>Max Stake (USD):</label>
78                    <input type="number" id="bot-max-stake" class="bot-input" value="1000" min="1" step="10">
79                </div>
80                
81                <div class="bot-section">
82                    <label>Delay (ms):</label>
83                    <input type="number" id="bot-delay" class="bot-input" value="5000" min="1000" step="500">
84                </div>
85                
86                <div class="bot-controls">
87                    <button id="bot-start" class="bot-btn bot-btn-start">Start Bot</button>
88                    <button id="bot-stop" class="bot-btn bot-btn-stop" disabled>Stop Bot</button>
89                    <button id="bot-reset" class="bot-btn bot-btn-reset">Reset Stats</button>
90                </div>
91                
92                <div class="bot-stats">
93                    <h4>Statistics</h4>
94                    <div class="stats-grid">
95                        <div class="stat-item">
96                            <span class="stat-label">Total Trades:</span>
97                            <span id="stat-total" class="stat-value">0</span>
98                        </div>
99                        <div class="stat-item">
100                            <span class="stat-label">Wins:</span>
101                            <span id="stat-wins" class="stat-value stat-win">0</span>
102                        </div>
103                        <div class="stat-item">
104                            <span class="stat-label">Losses:</span>
105                            <span id="stat-losses" class="stat-value stat-loss">0</span>
106                        </div>
107                        <div class="stat-item">
108                            <span class="stat-label">Win Rate:</span>
109                            <span id="stat-winrate" class="stat-value">0%</span>
110                        </div>
111                        <div class="stat-item">
112                            <span class="stat-label">Profit/Loss:</span>
113                            <span id="stat-profit" class="stat-value">$0.00</span>
114                        </div>
115                        <div class="stat-item">
116                            <span class="stat-label">Current Stake:</span>
117                            <span id="stat-current-stake" class="stat-value">$1.00</span>
118                        </div>
119                    </div>
120                </div>
121                
122                <div class="bot-status">
123                    <span id="bot-status-text">Bot is idle</span>
124                </div>
125                
126                <div id="bot-notifications" class="bot-notifications"></div>
127            </div>
128        `;
129
130        const styles = `
131            #deriv-bot-panel {
132                position: fixed;
133                top: 80px;
134                right: 20px;
135                width: 340px;
136                background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
137                border: 2px solid #0f3460;
138                border-radius: 12px;
139                box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
140                z-index: 999999;
141                font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
142                color: #ffffff;
143            }
144            
145            .bot-header {
146                background: linear-gradient(135deg, #0f3460 0%, #16213e 100%);
147                padding: 14px 18px;
148                border-radius: 10px 10px 0 0;
149                display: flex;
150                justify-content: space-between;
151                align-items: center;
152                cursor: move;
153                border-bottom: 2px solid #e94560;
154            }
155            
156            .bot-header h3 {
157                margin: 0;
158                font-size: 17px;
159                font-weight: 600;
160                color: #ffffff;
161            }
162            
163            .bot-btn-icon {
164                background: transparent;
165                border: none;
166                color: #ffffff;
167                font-size: 24px;
168                cursor: pointer;
169                padding: 0;
170                width: 24px;
171                height: 24px;
172            }
173            
174            .bot-btn-icon:hover {
175                color: #e94560;
176            }
177            
178            .bot-content {
179                padding: 18px;
180                max-height: 650px;
181                overflow-y: auto;
182            }
183            
184            .bot-content::-webkit-scrollbar {
185                width: 6px;
186            }
187            
188            .bot-content::-webkit-scrollbar-track {
189                background: #1a1a2e;
190            }
191            
192            .bot-content::-webkit-scrollbar-thumb {
193                background: #0f3460;
194                border-radius: 3px;
195            }
196            
197            .bot-section {
198                margin-bottom: 16px;
199            }
200            
201            .bot-section label {
202                display: block;
203                margin-bottom: 8px;
204                font-size: 13px;
205                font-weight: 600;
206                color: #b8c1ec;
207            }
208            
209            .bot-select, .bot-input {
210                width: 100%;
211                padding: 10px 14px;
212                background: #0f3460;
213                border: 1px solid #16213e;
214                border-radius: 8px;
215                color: #ffffff;
216                font-size: 14px;
217                transition: all 0.3s ease;
218            }
219            
220            .bot-select:focus, .bot-input:focus {
221                outline: none;
222                border-color: #e94560;
223                box-shadow: 0 0 0 3px rgba(233, 69, 96, 0.2);
224            }
225            
226            .bot-controls {
227                display: flex;
228                gap: 10px;
229                margin: 18px 0;
230                flex-wrap: wrap;
231            }
232            
233            .bot-btn {
234                flex: 1;
235                min-width: 95px;
236                padding: 12px 18px;
237                border: none;
238                border-radius: 8px;
239                font-size: 13px;
240                font-weight: 700;
241                cursor: pointer;
242                transition: all 0.3s ease;
243                text-transform: uppercase;
244                letter-spacing: 0.5px;
245            }
246            
247            .bot-btn-start {
248                background: linear-gradient(135deg, #00d4ff 0%, #0099cc 100%);
249                color: #ffffff;
250            }
251            
252            .bot-btn-start:hover:not(:disabled) {
253                background: linear-gradient(135deg, #00bbff 0%, #0088bb 100%);
254                transform: translateY(-2px);
255                box-shadow: 0 6px 16px rgba(0, 212, 255, 0.5);
256            }
257            
258            .bot-btn-stop {
259                background: linear-gradient(135deg, #e94560 0%, #cc3850 100%);
260                color: #ffffff;
261            }
262            
263            .bot-btn-stop:hover:not(:disabled) {
264                background: linear-gradient(135deg, #d63850 0%, #bb2840 100%);
265                transform: translateY(-2px);
266                box-shadow: 0 6px 16px rgba(233, 69, 96, 0.5);
267            }
268            
269            .bot-btn-reset {
270                background: linear-gradient(135deg, #533483 0%, #3d2563 100%);
271                color: #ffffff;
272            }
273            
274            .bot-btn-reset:hover:not(:disabled) {
275                background: linear-gradient(135deg, #432873 0%, #2d1553 100%);
276                transform: translateY(-2px);
277                box-shadow: 0 6px 16px rgba(83, 52, 131, 0.5);
278            }
279            
280            .bot-btn:disabled {
281                opacity: 0.5;
282                cursor: not-allowed;
283            }
284            
285            .bot-stats {
286                background: rgba(15, 52, 96, 0.5);
287                padding: 16px;
288                border-radius: 10px;
289                margin-top: 18px;
290            }
291            
292            .bot-stats h4 {
293                margin: 0 0 14px 0;
294                font-size: 14px;
295                color: #b8c1ec;
296                text-transform: uppercase;
297                letter-spacing: 1px;
298            }
299            
300            .stats-grid {
301                display: grid;
302                grid-template-columns: 1fr 1fr;
303                gap: 12px;
304            }
305            
306            .stat-item {
307                display: flex;
308                flex-direction: column;
309                gap: 6px;
310            }
311            
312            .stat-label {
313                font-size: 11px;
314                color: #b8c1ec;
315                text-transform: uppercase;
316                letter-spacing: 0.5px;
317            }
318            
319            .stat-value {
320                font-size: 18px;
321                font-weight: 700;
322                color: #ffffff;
323            }
324            
325            .stat-win {
326                color: #00ff88;
327            }
328            
329            .stat-loss {
330                color: #ff4444;
331            }
332            
333            .bot-status {
334                margin-top: 14px;
335                padding: 12px;
336                background: rgba(15, 52, 96, 0.3);
337                border-radius: 8px;
338                text-align: center;
339                font-size: 13px;
340                font-weight: 500;
341                color: #b8c1ec;
342                border-left: 4px solid #e94560;
343            }
344            
345            .bot-status.active {
346                border-left-color: #00ff88;
347                animation: pulse 2s infinite;
348            }
349            
350            .bot-notifications {
351                margin-top: 14px;
352                max-height: 200px;
353                overflow-y: auto;
354            }
355            
356            .bot-notification {
357                padding: 10px 12px;
358                margin-bottom: 8px;
359                border-radius: 8px;
360                font-size: 12px;
361                font-weight: 500;
362                animation: slideIn 0.3s ease;
363            }
364            
365            .bot-notification.win {
366                background: rgba(0, 255, 136, 0.15);
367                border-left: 4px solid #00ff88;
368                color: #00ff88;
369            }
370            
371            .bot-notification.loss {
372                background: rgba(255, 68, 68, 0.15);
373                border-left: 4px solid #ff4444;
374                color: #ff4444;
375            }
376            
377            .bot-notification.info {
378                background: rgba(0, 212, 255, 0.15);
379                border-left: 4px solid #00d4ff;
380                color: #00d4ff;
381            }
382            
383            @keyframes slideIn {
384                from {
385                    opacity: 0;
386                    transform: translateX(20px);
387                }
388                to {
389                    opacity: 1;
390                    transform: translateX(0);
391                }
392            }
393            
394            @keyframes pulse {
395                0%, 100% { opacity: 1; }
396                50% { opacity: 0.7; }
397            }
398        `;
399
400        const styleSheet = document.createElement('style');
401        styleSheet.textContent = styles;
402        document.head.appendChild(styleSheet);
403
404        document.body.appendChild(botPanel);
405        console.log('Bot UI created');
406
407        makeDraggable(botPanel);
408        attachEventListeners();
409    }
410
411    function makeDraggable(element) {
412        const header = element.querySelector('.bot-header');
413        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
414
415        header.onmousedown = (e) => {
416            e.preventDefault();
417            pos3 = e.clientX;
418            pos4 = e.clientY;
419            document.onmouseup = () => {
420                document.onmouseup = null;
421                document.onmousemove = null;
422            };
423            document.onmousemove = (e) => {
424                e.preventDefault();
425                pos1 = pos3 - e.clientX;
426                pos2 = pos4 - e.clientY;
427                pos3 = e.clientX;
428                pos4 = e.clientY;
429                element.style.top = (element.offsetTop - pos2) + 'px';
430                element.style.left = (element.offsetLeft - pos1) + 'px';
431                element.style.right = 'auto';
432            };
433        };
434    }
435
436    function attachEventListeners() {
437        document.getElementById('bot-start').addEventListener('click', startBot);
438        document.getElementById('bot-stop').addEventListener('click', stopBot);
439        document.getElementById('bot-reset').addEventListener('click', resetStats);
440        document.getElementById('bot-minimize').addEventListener('click', toggleMinimize);
441
442        document.getElementById('bot-strategy').addEventListener('change', (e) => {
443            botState.strategy = e.target.value;
444        });
445
446        document.getElementById('bot-trade-type').addEventListener('change', (e) => {
447            botState.tradeType = e.target.value;
448        });
449
450        document.getElementById('bot-stake').addEventListener('change', (e) => {
451            botState.baseStake = parseFloat(e.target.value) || 1;
452            botState.currentStake = botState.baseStake;
453            updateStats();
454        });
455
456        document.getElementById('bot-max-stake').addEventListener('change', (e) => {
457            botState.maxStake = parseFloat(e.target.value) || 1000;
458        });
459
460        document.getElementById('bot-delay').addEventListener('change', (e) => {
461            botState.delayBetweenTrades = parseInt(e.target.value) || 5000;
462        });
463    }
464
465    function toggleMinimize() {
466        const content = document.querySelector('.bot-content');
467        const btn = document.getElementById('bot-minimize');
468        
469        if (content.style.display === 'none') {
470            content.style.display = 'block';
471            btn.textContent = '−';
472        } else {
473            content.style.display = 'none';
474            btn.textContent = '+';
475        }
476    }
477
478    function addNotification(message, type) {
479        const container = document.getElementById('bot-notifications');
480        const notification = document.createElement('div');
481        notification.className = `bot-notification ${type}`;
482        notification.textContent = message;
483        container.insertBefore(notification, container.firstChild);
484        
485        // Keep only last 5 notifications
486        while (container.children.length > 5) {
487            container.removeChild(container.lastChild);
488        }
489    }
490
491    async function startBot() {
492        console.log('Starting bot...');
493        botState.isRunning = true;
494        
495        document.getElementById('bot-start').disabled = true;
496        document.getElementById('bot-stop').disabled = false;
497        document.getElementById('bot-strategy').disabled = true;
498        document.getElementById('bot-trade-type').disabled = true;
499        document.getElementById('bot-stake').disabled = true;
500        document.getElementById('bot-max-stake').disabled = true;
501        
502        updateStatusText('Bot is running...', true);
503        addNotification('Bot started successfully', 'info');
504        
505        runTradingLoop();
506    }
507
508    function stopBot() {
509        console.log('Stopping bot...');
510        botState.isRunning = false;
511        
512        document.getElementById('bot-start').disabled = false;
513        document.getElementById('bot-stop').disabled = true;
514        document.getElementById('bot-strategy').disabled = false;
515        document.getElementById('bot-trade-type').disabled = false;
516        document.getElementById('bot-stake').disabled = false;
517        document.getElementById('bot-max-stake').disabled = false;
518        
519        updateStatusText('Bot stopped', false);
520        addNotification('Bot stopped', 'info');
521    }
522
523    function resetStats() {
524        botState.stats = {
525            totalTrades: 0,
526            wins: 0,
527            losses: 0,
528            profit: 0,
529            winStreak: 0,
530            lossStreak: 0
531        };
532        botState.currentStake = botState.baseStake;
533        updateStats();
534        addNotification('Statistics reset', 'info');
535    }
536
537    function updateStatusText(text, isActive = false) {
538        const statusElement = document.getElementById('bot-status-text');
539        if (statusElement) {
540            statusElement.textContent = text;
541            const statusContainer = statusElement.parentElement;
542            if (isActive) {
543                statusContainer.classList.add('active');
544            } else {
545                statusContainer.classList.remove('active');
546            }
547        }
548    }
549
550    function updateStats() {
551        const stats = botState.stats;
552        const winRate = stats.totalTrades > 0 ? ((stats.wins / stats.totalTrades) * 100).toFixed(2) : 0;
553        
554        document.getElementById('stat-total').textContent = stats.totalTrades;
555        document.getElementById('stat-wins').textContent = stats.wins;
556        document.getElementById('stat-losses').textContent = stats.losses;
557        document.getElementById('stat-winrate').textContent = winRate + '%';
558        
559        const profitElement = document.getElementById('stat-profit');
560        profitElement.textContent = '$' + stats.profit.toFixed(2);
561        profitElement.style.color = stats.profit >= 0 ? '#00ff88' : '#ff4444';
562        
563        document.getElementById('stat-current-stake').textContent = '$' + botState.currentStake.toFixed(2);
564    }
565
566    function getCurrentBalance() {
567        const balanceElement = document.querySelector('[data-testid="dt_balance"]');
568        if (balanceElement) {
569            const balanceText = balanceElement.textContent.trim();
570            const balanceMatch = balanceText.match(/[\d,]+\.?\d*/);
571            if (balanceMatch) {
572                return parseFloat(balanceMatch[0].replace(/,/g, ''));
573            }
574        }
575        return null;
576    }
577
578    function setStakeAmount(amount) {
579        const stakeInput = document.querySelector('input[name="amount"]#dt_amount_input');
580        if (stakeInput) {
581            stakeInput.value = amount;
582            stakeInput.dispatchEvent(new Event('input', { bubbles: true }));
583            stakeInput.dispatchEvent(new Event('change', { bubbles: true }));
584            return true;
585        }
586        return false;
587    }
588
589    function getPayoutInfo() {
590        const riseButton = document.getElementById('dt_purchase_call_button');
591        const fallButton = document.getElementById('dt_purchase_put_button');
592        
593        if (!riseButton || !fallButton) return null;
594        
595        const risePercentText = riseButton.querySelector('.btn-purchase__info--right .dc-text');
596        const fallPercentText = fallButton.querySelector('.btn-purchase__info--right .dc-text');
597        
598        if (!risePercentText || !fallPercentText) return null;
599        
600        return {
601            rise: parseFloat(risePercentText.textContent.replace('%', '')),
602            fall: parseFloat(fallPercentText.textContent.replace('%', ''))
603        };
604    }
605
606    function analyzeBestTrade() {
607        const payouts = getPayoutInfo();
608        if (!payouts) return botState.tradeType;
609        
610        if (payouts.rise > payouts.fall) {
611            console.log('Analysis: Rise better (' + payouts.rise + '% vs ' + payouts.fall + '%)');
612            return 'rise';
613        } else {
614            console.log('Analysis: Fall better (' + payouts.fall + '% vs ' + payouts.rise + '%)');
615            return 'fall';
616        }
617    }
618
619    function analyzeTrend() {
620        // If not enough history, use the selected trade type
621        if (botState.trendHistory.length < 1) {
622            console.log('Trend: No data yet, using selected type:', botState.tradeType);
623            return botState.tradeType;
624        }
625        
626        // Get the last tick result
627        const lastTick = botState.trendHistory[botState.trendHistory.length - 1];
628        
629        console.log('Trend History:', botState.trendHistory.join(', '));
630        console.log('Last Tick:', lastTick);
631        
632        // Bet OPPOSITE of the last tick (reversal strategy)
633        if (lastTick === 'rise') {
634            console.log('Trend: Last tick was RISE → Betting FALL (reversal)');
635            return 'fall';
636        } else {
637            console.log('Trend: Last tick was FALL → Betting RISE (reversal)');
638            return 'rise';
639        }
640    }
641
642    function getNextTradeType() {
643        if (botState.tradeType === 'alternate') {
644            return botState.lastTradeResult === 'rise' ? 'fall' : 'rise';
645        }
646        
647        // ALWAYS use trend analysis if we have any history
648        if (botState.trendHistory.length > 0) {
649            return analyzeTrend();
650        }
651        
652        // If no history yet, use the selected trade type to start building history
653        return botState.tradeType;
654    }
655
656    function calculateNextStake(won) {
657        let nextStake = botState.currentStake;
658
659        if (botState.strategy === 'martingale') {
660            nextStake = won ? botState.baseStake : botState.currentStake * 2;
661            console.log(won ? 'WIN - Reset to base: ' + nextStake : 'LOSS - Double to: ' + nextStake);
662        } else if (botState.strategy === 'anti-martingale') {
663            nextStake = won ? botState.currentStake * 2 : botState.baseStake;
664        } else {
665            nextStake = botState.baseStake;
666        }
667
668        if (nextStake > botState.maxStake) nextStake = botState.maxStake;
669        if (nextStake < 1) nextStake = 1;
670
671        return Math.round(nextStake * 100) / 100;
672    }
673
674    async function executeTrade(tradeType) {
675        botState.balanceBeforeTrade = getCurrentBalance();
676        if (!botState.balanceBeforeTrade) return false;
677        
678        if (!setStakeAmount(botState.currentStake)) return false;
679        await wait(500);
680
681        const buttonId = tradeType === 'rise' ? 'dt_purchase_call_button' : 'dt_purchase_put_button';
682        const tradeButton = document.getElementById(buttonId);
683        
684        if (tradeButton && !tradeButton.disabled) {
685            tradeButton.click();
686            console.log('Trade placed:', tradeType, '$' + botState.currentStake);
687            updateStatusText(`Placed ${tradeType} trade: $${botState.currentStake.toFixed(2)}`, true);
688            return true;
689        }
690        return false;
691    }
692
693    async function waitForTradeCompletion() {
694        // Wait for buttons to be disabled (trade starts)
695        for (let i = 0; i < 20; i++) {
696            const riseBtn = document.getElementById('dt_purchase_call_button');
697            const fallBtn = document.getElementById('dt_purchase_put_button');
698            if (riseBtn?.disabled && fallBtn?.disabled) {
699                console.log('Trade started');
700                break;
701            }
702            await wait(500);
703        }
704
705        // Wait for buttons to be enabled (trade completes)
706        for (let i = 0; i < 120; i++) {
707            const riseBtn = document.getElementById('dt_purchase_call_button');
708            const fallBtn = document.getElementById('dt_purchase_put_button');
709            if (riseBtn && !riseBtn.disabled && fallBtn && !fallBtn.disabled) {
710                console.log('Trade completed');
711                return true;
712            }
713            await wait(500);
714        }
715        
716        return false;
717    }
718
719    async function getTradeResult() {
720        try {
721            console.log('getTradeResult() START - waiting 3 seconds...');
722            await wait(3000);
723            console.log('getTradeResult() - 3 second wait completed');
724            
725            let newBalance = null;
726            console.log('getTradeResult() - starting balance check loop...');
727            for (let i = 0; i < 5; i++) {
728                console.log('Balance check attempt', i + 1, 'of 5');
729                newBalance = getCurrentBalance();
730                console.log('Got balance:', newBalance, 'Previous:', botState.balanceBeforeTrade);
731                if (newBalance) {
732                    console.log('Balance retrieved successfully');
733                    break;
734                }
735                console.log('Balance is null, waiting 1 second...');
736                await wait(1000);
737            }
738            
739            console.log('Balance check loop completed. New:', newBalance, 'Old:', botState.balanceBeforeTrade);
740            
741            if (!newBalance || !botState.balanceBeforeTrade) {
742                console.error('Could not get balance. New:', newBalance, 'Old:', botState.balanceBeforeTrade);
743                return null;
744            }
745            
746            const profit = newBalance - botState.balanceBeforeTrade;
747            const won = profit > 0;
748            
749            console.log('=== RESULT ===');
750            console.log('Before: $' + botState.balanceBeforeTrade.toFixed(2));
751            console.log('After: $' + newBalance.toFixed(2));
752            console.log('Change: $' + profit.toFixed(2));
753            console.log('Result:', won ? 'WIN ✓' : 'LOSS ✗');
754            console.log('==============');
755            
756            console.log('getTradeResult() - returning result object');
757            return { won, profit };
758        } catch (error) {
759            console.error('ERROR in getTradeResult():', error);
760            console.error('Error stack:', error.stack);
761            return null;
762        }
763    }
764
765    async function runTradingLoop() {
766        while (botState.isRunning) {
767            try {
768                console.log('--- Trade Cycle | Stake: $' + botState.currentStake + ' ---');
769                
770                // Wait for buttons to be ready
771                const riseBtn = document.getElementById('dt_purchase_call_button');
772                const fallBtn = document.getElementById('dt_purchase_put_button');
773                
774                if (!riseBtn || !fallBtn || riseBtn.disabled || fallBtn.disabled) {
775                    console.log('Buttons not ready, waiting...');
776                    await wait(3000);
777                    continue;
778                }
779                
780                await wait(2000);
781                
782                const tradeType = getNextTradeType();
783                const executed = await executeTrade(tradeType);
784                
785                if (!executed) {
786                    console.log('Trade failed, waiting...');
787                    await wait(5000);
788                    continue;
789                }
790
791                botState.lastTradeResult = tradeType;
792
793                // Wait for trade to complete
794                console.log('Calling waitForTradeCompletion()...');
795                const completed = await waitForTradeCompletion();
796                console.log('waitForTradeCompletion() returned:', completed);
797                
798                if (!completed) {
799                    console.error('Trade timeout');
800                    stopBot();
801                    break;
802                }
803
804                // Get result
805                console.log('Calling getTradeResult()...');
806                const result = await getTradeResult();
807                console.log('getTradeResult() returned:', result);
808                
809                if (!result) {
810                    console.error('Could not get result');
811                    stopBot();
812                    break;
813                }
814
815                // Record the actual market result for trend analysis
816                // If we bet rise and won, market went rise. If we bet rise and lost, market went fall.
817                const actualMarketResult = (tradeType === 'rise' && result.won) || (tradeType === 'fall' && !result.won) ? 'rise' : 'fall';
818                botState.trendHistory.push(actualMarketResult);
819                
820                // Keep only last 10 results
821                if (botState.trendHistory.length > 10) {
822                    botState.trendHistory.shift();
823                }
824                
825                console.log('Market result:', actualMarketResult, '| Trend history:', botState.trendHistory.join(', '));
826
827                // Update stats
828                botState.stats.totalTrades++;
829                
830                if (result.won) {
831                    botState.stats.wins++;
832                    botState.stats.winStreak++;
833                    botState.stats.lossStreak = 0;
834                    botState.stats.profit += result.profit;
835                    updateStatusText(`WIN! +$${result.profit.toFixed(2)}`, true);
836                    addNotification(`WIN! +$${result.profit.toFixed(2)} | Stake: $${botState.currentStake}`, 'win');
837                } else {
838                    botState.stats.losses++;
839                    botState.stats.lossStreak++;
840                    botState.stats.winStreak = 0;
841                    botState.stats.profit += result.profit;
842                    updateStatusText(`LOSS! ${result.profit.toFixed(2)}`, true);
843                    addNotification(`LOSS! ${result.profit.toFixed(2)} | Stake: $${botState.currentStake}`, 'loss');
844                }
845
846                // Calculate next stake
847                botState.currentStake = calculateNextStake(result.won);
848                console.log('Next stake:', botState.currentStake);
849                
850                updateStats();
851
852                // Wait before next trade
853                await wait(botState.delayBetweenTrades);
854
855            } catch (error) {
856                console.error('Error:', error);
857                await wait(5000);
858            }
859        }
860    }
861
862    function init() {
863        console.log('Deriv Even/Odd Bot initializing...');
864        
865        if (document.readyState === 'loading') {
866            document.addEventListener('DOMContentLoaded', () => {
867                setTimeout(createBotUI, 2000);
868            });
869        } else {
870            setTimeout(createBotUI, 2000);
871        }
872    }
873
874    init();
875
876})();
Deriv Rise/Fall Trading Bot | Robomonkey