Crypto Arbitrage Profitability Tool

Crypto Arbitrage Profitability Tool

Buy Side

Sell Side

Transfer (Optional)

Buy Fee (${resultsData.buyFeeValue}${resultsData.buyFeeType === 'percentage' ? '%' : '$'}): $${resultsData.buyFeeAmount.toFixed(2)}


Sell Side (${resultsData.sellExchangeName})

Total Sell Value (Quantity * Price): $${resultsData.totalSellValue.toFixed(2)}

Sell Fee (${resultsData.sellFeeValue}${resultsData.sellFeeType === 'percentage' ? '%' : '$'}): $${resultsData.sellFeeAmount.toFixed(2)}


Fees & Summary

Transfer Fee: $${resultsData.transferFee.toFixed(2)}

Total Fees (Buy + Sell + Transfer): $${resultsData.totalFees.toFixed(2)}

Total Cost (Buy Value + All Fees): $${resultsData.totalCostIncludingFees.toFixed(2)}

Total Revenue (Sell Value - Sell Fee): $${resultsData.totalRevenueAfterFees.toFixed(2)}


Gross Profit (Before Fees): $${resultsData.grossProfitBeforeFees.toFixed(2)}

Net Profit / Loss: $${resultsData.netProfit.toFixed(2)} (${resultsData.netProfitPercentage.toFixed(2)}%)

`; resultsArbitrageEl.style.display = 'block'; } /** * Handles the arbitrage calculation process. */ function handleArbitrageCalculate() { const inputs = getArbitrageInputs(); if (!inputs) return; if (!validateArbitrageInputs(inputs)) { if(resultsArbitrageEl) resultsArbitrageEl.style.display = 'none'; return; } const calculationResults = calculateArbitrage(inputs); displayArbitrageResults(calculationResults); } /** * Generates and downloads a PDF of the arbitrage results. */ function generateArbitragePdf() { const inputs = getArbitrageInputs(); if (!inputs) { alert('Could not retrieve input data for PDF generation. Please calculate first.'); return; } if (!validateArbitrageInputs(inputs)) { alert('Invalid inputs. Please correct them before generating PDF.'); return; } const resultsData = calculateArbitrage(inputs); if (!resultsData) { alert('Could not calculate results for PDF generation. Please try again.'); return; } const doc = new jsPDF(); const today = new Date(); const formattedDate = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}`; const title = `Crypto Arbitrage Report: ${resultsData.cryptoName}`; doc.setFontSize(18); doc.text(title, 14, 22); doc.setFontSize(11); doc.setTextColor(100); doc.text(`Report Generated: ${formattedDate}`, 14, 30); const headStyle = { fillColor: [79, 70, 229] }; // Indigo for header const bodyStyle = { minCellHeight: 9, fontSize: 10 }; const inputSummaryBody = [ ['Cryptocurrency', resultsData.cryptoName], ['Quantity', resultsData.quantity.toLocaleString()], ['Transfer Fee', `$${resultsData.transferFee.toFixed(2)}`], ]; doc.autoTable({ startY: 40, head: [['Trade Overview', '']], body: inputSummaryBody, theme: 'striped', headStyles: headStyle, styles: bodyStyle, columnStyles: { 0: { fontStyle: 'bold' } } }); const buySideBody = [ ['Buy Exchange', resultsData.buyExchangeName], ['Buy Price per Unit', `$${resultsData.buyPrice.toFixed(2)}`], ['Total Buy Value (Qty * Price)', `$${resultsData.totalBuyValue.toFixed(2)}`], ['Buy Fee', `${resultsData.buyFeeValue}${resultsData.buyFeeType === 'percentage' ? '%' : '$ (Fixed)'}`], ['Buy Fee Amount', `$${resultsData.buyFeeAmount.toFixed(2)}`], ]; doc.autoTable({ startY: doc.lastAutoTable.finalY + 10, head: [['Buy Side Details', '']], body: buySideBody, theme: 'striped', headStyles: headStyle, styles: bodyStyle, columnStyles: { 0: { fontStyle: 'bold' } } }); const sellSideBody = [ ['Sell Exchange', resultsData.sellExchangeName], ['Sell Price per Unit', `$${resultsData.sellPrice.toFixed(2)}`], ['Total Sell Value (Qty * Price)', `$${resultsData.totalSellValue.toFixed(2)}`], ['Sell Fee', `${resultsData.sellFeeValue}${resultsData.sellFeeType === 'percentage' ? '%' : '$ (Fixed)'}`], ['Sell Fee Amount', `$${resultsData.sellFeeAmount.toFixed(2)}`], ]; doc.autoTable({ startY: doc.lastAutoTable.finalY + 10, head: [['Sell Side Details', '']], body: sellSideBody, theme: 'striped', headStyles: headStyle, styles: bodyStyle, columnStyles: { 0: { fontStyle: 'bold' } } }); const resultsSummaryBody = [ ['Total Cost (Buy Value + All Fees)', `$${resultsData.totalCostIncludingFees.toFixed(2)}`], ['Total Revenue (Sell Value - Sell Fee)', `$${resultsData.totalRevenueAfterFees.toFixed(2)}`], ['Gross Profit (Before Fees)', `$${resultsData.grossProfitBeforeFees.toFixed(2)}`], ['Total Fees Paid', `$${resultsData.totalFees.toFixed(2)}`], ['Net Profit / Loss', `$${resultsData.netProfit.toFixed(2)}`], ['Net Profit / Loss (%)', `${resultsData.netProfitPercentage.toFixed(2)}%`], ]; doc.autoTable({ startY: doc.lastAutoTable.finalY + 10, head: [['Profitability Summary', '']], body: resultsSummaryBody, theme: 'striped', headStyles: headStyle, styles: bodyStyle, columnStyles: { 0: { fontStyle: 'bold', cellWidth: 80 }, 1: { cellWidth: 'auto'} }, didParseCell: function (data) { // Color coding for Net Profit/Loss if (data.row.index === 4 || data.row.index === 5) { // Net Profit/Loss rows if (resultsData.netProfit < 0) { data.cell.styles.textColor = [239, 68, 68]; // Red for loss } else { data.cell.styles.textColor = [16, 185, 129]; // Green for profit } } } }); doc.save(`arbitrage_report_${resultsData.cryptoName.replace(/[^a-zA-Z0-9]/g, '_')}_${formattedDate}.pdf`); } // Event listener for DOMContentLoaded document.addEventListener('DOMContentLoaded', function() { // Assign DOM elements cryptoNameEl = document.getElementById('cryptoName'); quantityEl = document.getElementById('quantity'); buyExchangeNameEl = document.getElementById('buyExchangeName'); buyPriceEl = document.getElementById('buyPrice'); buyFeeValueEl = document.getElementById('buyFeeValue'); buyFeeTypeEl = document.getElementById('buyFeeType'); sellExchangeNameEl = document.getElementById('sellExchangeName'); sellPriceEl = document.getElementById('sellPrice'); sellFeeValueEl = document.getElementById('sellFeeValue'); sellFeeTypeEl = document.getElementById('sellFeeType'); transferFeeEl = document.getElementById('transferFee'); errorArbitrageEl = document.getElementById('errorArbitrage'); resultsArbitrageEl = document.getElementById('resultsArbitrage'); // Null checks for critical elements const criticalElements = [ cryptoNameEl, quantityEl, buyExchangeNameEl, buyPriceEl, buyFeeValueEl, buyFeeTypeEl, sellExchangeNameEl, sellPriceEl, sellFeeValueEl, sellFeeTypeEl, transferFeeEl, errorArbitrageEl, resultsArbitrageEl ]; if (criticalElements.some(el => !el)) { console.error("One or more critical elements are missing from the DOM for the Arbitrage Calculator."); const body = document.querySelector('body'); if (body && errorArbitrageEl && errorArbitrageEl.style.display === 'none') { // only show if no other error shown errorArbitrageEl.textContent = "Error: Calculator UI could not be fully initialized. Some fields may be missing. Please refresh."; errorArbitrageEl.style.display = 'block'; } else if (body && !errorArbitrageEl) { // If errorArbitrageEl itself is missing const errorDiv = document.createElement('div'); errorDiv.className = 'error-message'; // Use existing styles errorDiv.textContent = "Critical Error: Calculator UI initialization failed. Please refresh."; errorDiv.style.display = 'block'; const container = document.querySelector('.calculator-container'); if (container) container.prepend(errorDiv); else body.prepend(errorDiv); } } });
Scroll to Top