const WebSocket = require('ws');
const fs = require('fs');
// Load config
const config = JSON.parse(fs.readFileSync('./config.json'));
const API_TOKEN = VOdSXwiY07JNMQ1;
const APP_ID = CR7914869;
const ws = new WebSocket(`wss://ws.derivws.com/websockets/v3?app_id=${APP_ID}`);
const minStake = 0.35
const maxStake = 10.00;
const targetProfit = 200.00;
const stopLoss = 50.00;
const maxConsecutiveLosses = 3;
const tradeIntervalMin = 30000;
const tradeIntervalMax = 60000;
const digitWindow = 20;
let currentStake = minStake;
let totalProfit = 0;
let totalLoss = 0;
let consecutiveLosses = 0;
let lastDigitHistory = [];
let isTrading = true;
let contractId = null;
ws.on('open', () => {
console.log('Connected to Deriv API.');
ws.send(JSON.stringify({ authorize: API_TOKEN }));
});
ws.on('message', async (data) => {
const msg = JSON.parse(data);
if (msg.error) {
console.log(`API error: ${msg.error.message}`);
return;
}
switch (msg.msg_type) {
case 'authorize':
console.log('Authorized. Subscribing to ticks.');
subscribeToTicks();
break;
case 'tick':
processTick(msg.tick);
break;
case 'proposal':
buyContract(msg.proposal.id, currentStake);
break;
case 'buy':
contractId = msg.buy.contract_id;
break;
case 'contract':
processContractResult(msg.contract);
break;
}
});
function getRandomDelay() {
return Math.floor(Math.random() * (tradeIntervalMax - tradeIntervalMin + 1)) +
tradeIntervalMin;
}
function getBestDigitToMatch() {
if (lastDigitHistory.length < digitWindow) return Math.floor(Math.random() *
10);
const digitCounts = Array(10).fill(0);
lastDigitHistory.forEach(d => digitCounts[d]++);
const maxCount = Math.max(...digitCounts);
return digitCounts.indexOf(maxCount);
}
function adjustStake(isWin) {
currentStake = isWin ? Math.min(currentStake * 1.5, maxStake) : minStake;
}
function subscribeToTicks() {
ws.send(JSON.stringify({ ticks: 'R_10', subscribe: 1 }));
}
function processTick(tick) {
if (!isTrading) return;
const lastDigit = Math.floor(tick.quote % 10);
lastDigitHistory.push(lastDigit);
if (lastDigitHistory.length > digitWindow) lastDigitHistory.shift();
executeTrade();
}
async function executeTrade() {
if (!isTrading) return;
if (totalLoss >= stopLoss || consecutiveLosses >= maxConsecutiveLosses) {
console.log('Hit stop-loss or too many losses. Pausing.');
isTrading = false;
setTimeout(() => {
isTrading = true;
consecutiveLosses = 0;
executeTrade();
}, 3600000);
return;
}
if (totalProfit >= targetProfit) {
console.log('Profit target reached. Stopping.');
isTrading = false;
return;
}
const digitToMatch = getBestDigitToMatch();
console.log(`Betting on digit ${digitToMatch} with stake $$
{currentStake.toFixed(2)}`);
ws.send(JSON.stringify({
proposal: 1,
amount: currentStake,
basis: 'stake',
contract_type: 'DIGITMATCH',
currency: 'USD',
duration: 5,
duration_unit: 't',
symbol: 'R_10',
barrier: digitToMatch
}));
}
function buyContract(proposalId, stake) {
ws.send(JSON.stringify({
buy: proposalId,
price: stake
}));
}
function processContractResult(contract) {
if (contract.status !== 'settled') return;
const isWin = contract.profit > 0;
const payout = isWin ? contract.payout : 0;
const loss = isWin ? 0 : currentStake;
if (isWin) {
totalProfit += payout - currentStake;
consecutiveLosses = 0;
console.log(`Win! Payout: $${payout.toFixed(2)} | Profit: $${(payout -
currentStake).toFixed(2)}`);
} else {
totalLoss += loss;
consecutiveLosses++;
console.log(`Loss: $${loss.toFixed(2)} | Consecutive losses: $
{consecutiveLosses}`);
}
adjustStake(isWin);
setTimeout(executeTrade, getRandomDelay());
}
ws.on('error', (err) => {
console.log(`WebSocket error: ${err.message}`);
});