diff --git a/html/rechner/script.js b/html/rechner/script.js
index 9ff1a00..3627959 100644
--- a/html/rechner/script.js
+++ b/html/rechner/script.js
@@ -424,6 +424,86 @@
initialCapitalDiv.appendChild(initialCapitalInput);
contentDiv.appendChild(initialCapitalDiv);
+ // Create deposit tracking section
+ const depositSectionDiv = document.createElement("div");
+ depositSectionDiv.style.marginBottom = "10px";
+ depositSectionDiv.style.padding = "10px";
+ depositSectionDiv.style.border = "1px solid #444";
+ depositSectionDiv.style.borderRadius = "5px";
+ depositSectionDiv.style.backgroundColor = "#2a2a2a";
+
+ const depositSectionLabel = document.createElement("h4");
+ depositSectionLabel.textContent = "Deposit/Withdrawal History";
+ depositSectionLabel.style.marginTop = "0";
+ depositSectionLabel.style.marginBottom = "10px";
+ depositSectionDiv.appendChild(depositSectionLabel);
+
+ // Deposit list container
+ const depositListDiv = document.createElement("div");
+ depositListDiv.className = "deposit-list";
+ depositSectionDiv.appendChild(depositListDiv);
+
+ // Add deposit controls
+ const addDepositDiv = document.createElement("div");
+ addDepositDiv.style.marginTop = "10px";
+
+ const depositDateInput = document.createElement("input");
+ depositDateInput.type = "date";
+ depositDateInput.value = getToday();
+ depositDateInput.style.marginRight = "5px";
+
+ const depositAmountInput = document.createElement("input");
+ depositAmountInput.type = "number";
+ depositAmountInput.step = "0.01";
+ depositAmountInput.placeholder = "Amount (+/-)";
+ depositAmountInput.style.marginRight = "5px";
+ depositAmountInput.style.width = "120px";
+
+ const depositNotesInput = document.createElement("input");
+ depositNotesInput.type = "text";
+ depositNotesInput.placeholder = "Notes (optional)";
+ depositNotesInput.style.marginRight = "5px";
+ depositNotesInput.style.width = "150px";
+
+ const addDepositBtn = document.createElement("button");
+ addDepositBtn.textContent = "Add Deposit/Withdrawal";
+ addDepositBtn.style.fontSize = "12px";
+ addDepositBtn.addEventListener("click", () => {
+ if (depositAmountInput.value && depositDateInput.value) {
+ addDepositEntry(depositListDiv, {
+ date: depositDateInput.value,
+ amount: parseFloat(depositAmountInput.value),
+ notes: depositNotesInput.value || ""
+ }, trackerId);
+ depositAmountInput.value = "";
+ depositNotesInput.value = "";
+ saveCoinTrackers();
+ updateInvestedChart();
+ }
+ });
+
+ addDepositDiv.appendChild(depositDateInput);
+ addDepositDiv.appendChild(depositAmountInput);
+ addDepositDiv.appendChild(depositNotesInput);
+ addDepositDiv.appendChild(addDepositBtn);
+ depositSectionDiv.appendChild(addDepositDiv);
+
+ contentDiv.appendChild(depositSectionDiv);
+
+ // Load existing deposits if available
+ if (data && data.deposits && data.deposits.length > 0) {
+ data.deposits.forEach(deposit => {
+ addDepositEntry(depositListDiv, deposit, trackerId);
+ });
+ } else if (data && data.initialCapital && parseFloat(data.initialCapital) > 0) {
+ // Migrate existing initial capital as first deposit
+ addDepositEntry(depositListDiv, {
+ date: "2025-01-01", // Default date for migrated data
+ amount: parseFloat(data.initialCapital),
+ notes: "Migrated from Initial Capital"
+ }, trackerId);
+ }
+
// Create a container with positioning context for the table
const tableWrapper = document.createElement("div");
tableWrapper.className = "table-wrapper";
@@ -621,6 +701,76 @@
updateRowYieldProjections(tr);
};
+ // Function to add deposit/withdrawal entries to the deposit history
+ const addDepositEntry = (depositListDiv, depositData, trackerId) => {
+ const depositDiv = document.createElement("div");
+ depositDiv.style.display = "flex";
+ depositDiv.style.alignItems = "center";
+ depositDiv.style.marginBottom = "5px";
+ depositDiv.style.padding = "5px";
+ depositDiv.style.backgroundColor = "#3a3a3a";
+ depositDiv.style.borderRadius = "3px";
+
+ const dateSpan = document.createElement("span");
+ dateSpan.textContent = depositData.date;
+ dateSpan.style.minWidth = "100px";
+ dateSpan.style.marginRight = "10px";
+
+ const amountSpan = document.createElement("span");
+ const amount = parseFloat(depositData.amount);
+ amountSpan.textContent = amount >= 0 ? `+$${amount.toFixed(2)}` : `-$${Math.abs(amount).toFixed(2)}`;
+ amountSpan.style.minWidth = "80px";
+ amountSpan.style.marginRight = "10px";
+ amountSpan.style.color = amount >= 0 ? "#4CAF50" : "#f44336";
+ amountSpan.style.fontWeight = "bold";
+
+ const notesSpan = document.createElement("span");
+ notesSpan.textContent = depositData.notes || "";
+ notesSpan.style.flex = "1";
+ notesSpan.style.marginRight = "10px";
+ notesSpan.style.fontStyle = "italic";
+ notesSpan.style.color = "#ccc";
+
+ const deleteBtn = document.createElement("button");
+ deleteBtn.textContent = "×";
+ deleteBtn.style.background = "#f44336";
+ deleteBtn.style.color = "white";
+ deleteBtn.style.border = "none";
+ deleteBtn.style.borderRadius = "50%";
+ deleteBtn.style.width = "20px";
+ deleteBtn.style.height = "20px";
+ deleteBtn.style.fontSize = "12px";
+ deleteBtn.style.cursor = "pointer";
+ deleteBtn.title = "Delete deposit";
+ deleteBtn.addEventListener("click", () => {
+ if (confirm("Are you sure you want to delete this deposit record?")) {
+ depositDiv.remove();
+ saveCoinTrackers();
+ updateInvestedChart();
+ }
+ });
+
+ depositDiv.appendChild(dateSpan);
+ depositDiv.appendChild(amountSpan);
+ depositDiv.appendChild(notesSpan);
+ depositDiv.appendChild(deleteBtn);
+
+ // Insert deposits in chronological order
+ let inserted = false;
+ const existingDeposits = depositListDiv.children;
+ for (let i = 0; i < existingDeposits.length; i++) {
+ const existingDate = existingDeposits[i].querySelector('span').textContent;
+ if (depositData.date < existingDate) {
+ depositListDiv.insertBefore(depositDiv, existingDeposits[i]);
+ inserted = true;
+ break;
+ }
+ }
+ if (!inserted) {
+ depositListDiv.appendChild(depositDiv);
+ }
+ };
+
// Enhanced version of addDynamicEntry that supports transaction types
const addDynamicEntryWithData = (tbody, rowData, trackerId) => {
const tr = document.createElement("tr");
@@ -790,19 +940,32 @@
let totalDeposited = {};
let dailyYieldTotals = {}; // Add this to track daily yields
- // Calculate total initial capital across all trackers
- let totalInitialCapital = 0;
- Array.from(trackerDivs).forEach(div => {
- if (div.dataset.showInChart === "false") return;
- // Get initialCapital value
- const initialCapitalInput = div.querySelector(".content input[type='number']");
- if (initialCapitalInput) {
- totalInitialCapital += parseFloat(initialCapitalInput.value || "0") || 0;
- }
- });
+ // Collect all deposit data from all trackers
+ let allDeposits = {};
Array.from(trackerDivs).forEach(div => {
if (div.dataset.showInChart === "false") return;
+
+ // Collect deposits for this tracker
+ const depositListDiv = div.querySelector(".deposit-list");
+ if (depositListDiv) {
+ Array.from(depositListDiv.children).forEach(depositDiv => {
+ const dateSpan = depositDiv.querySelector('span:nth-child(1)');
+ const amountSpan = depositDiv.querySelector('span:nth-child(2)');
+
+ if (dateSpan && amountSpan) {
+ const date = dateSpan.textContent;
+ const amountText = amountSpan.textContent;
+ const amount = parseFloat(amountText.replace(/[+\-$]/g, '')) * (amountText.startsWith('-') ? -1 : 1);
+
+ if (!allDeposits[date]) {
+ allDeposits[date] = 0;
+ }
+ allDeposits[date] += amount;
+ }
+ });
+ }
+
const table = div.querySelector("table.coin-table");
if (table) {
const tbody = table.querySelector("tbody");
@@ -829,9 +992,6 @@
// Calculate daily yield in dollars and accumulate for each date
const yieldInDollars = currentVal * (dailyYieldPercent / 100);
dailyYieldTotals[date] = (dailyYieldTotals[date] || 0) + yieldInDollars;
-
- // Set totalDeposited to the initial capital for all dates
- totalDeposited[date] = totalInitialCapital;
}
});
for (const date in trackerDaily) {
@@ -840,6 +1000,20 @@
}
});
+ // Calculate cumulative deposits over time
+ const sortedDepositDates = Object.keys(allDeposits).sort();
+ let cumulativeDeposits = 0;
+ const allDates = new Set([...Object.keys(portfolioValues), ...sortedDepositDates]);
+
+ Array.from(allDates).sort().forEach(date => {
+ // Add any deposits that occurred on this date
+ if (allDeposits[date]) {
+ cumulativeDeposits += allDeposits[date];
+ }
+ // Set total deposited for this date to the cumulative amount
+ totalDeposited[date] = cumulativeDeposits;
+ });
+
// Update daily yield history with new calculations
for (const date in dailyYieldTotals) {
dailyYieldHistory[date] = dailyYieldTotals[date];
@@ -861,7 +1035,7 @@
let labels = dates.map(date => new Date(date).toLocaleDateString());
let dailyFeesData = dates.map(date => dailyYieldHistory[date] || 0);
let portfolioData = dates.map(date => portfolioValues[date] || persistedHistory[date]);
- let depositedData = dates.map(date => totalDeposited[date] || persistedHistory[date] * 0.9);
+ let depositedData = dates.map(date => totalDeposited[date] || 0);
// Update or create the chart
if (investedChart) {
@@ -1155,6 +1329,26 @@
const initialCapitalInput = div.querySelector(".content input[type='number']");
const initialCapital = initialCapitalInput ? initialCapitalInput.value : "0.00";
+ // Get deposit history
+ const depositListDiv = div.querySelector(".deposit-list");
+ const deposits = [];
+ if (depositListDiv) {
+ Array.from(depositListDiv.children).forEach(depositDiv => {
+ const dateSpan = depositDiv.querySelector('span:nth-child(1)');
+ const amountSpan = depositDiv.querySelector('span:nth-child(2)');
+ const notesSpan = depositDiv.querySelector('span:nth-child(3)');
+
+ if (dateSpan && amountSpan) {
+ const date = dateSpan.textContent;
+ const amountText = amountSpan.textContent;
+ // Parse amount from "+$123.45" or "-$123.45" format
+ const amount = parseFloat(amountText.replace(/[+\-$]/g, '')) * (amountText.startsWith('-') ? -1 : 1);
+ const notes = notesSpan ? notesSpan.textContent : "";
+ deposits.push({ date, amount, notes });
+ }
+ });
+ }
+
const table = div.querySelector("table.coin-table");
const tbody = table.querySelector("tbody");
const rows = [];
@@ -1171,8 +1365,8 @@
rows.push({ date, time, currentValue, income, compound, dailyYield, notes, created });
});
const hasData = rows.some(row => row.currentValue !== 0 || row.income !== 0 || row.dailyYield !== 0);
- if (hasData) {
- trackers.push({ id: trackerId, coinName, platform, initialCapital, rows, showInChart, active });
+ if (hasData || deposits.length > 0) {
+ trackers.push({ id: trackerId, coinName, platform, initialCapital, deposits, rows, showInChart, active });
}
});
updateCoinTrackersToBackend(trackers);