@fuzzle/opencode-accountant 0.13.13-next.1 → 0.13.14-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +74 -75
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25652,36 +25652,6 @@ function processNonMergerAction(action, inventory, entries, logger) {
|
|
|
25652
25652
|
}
|
|
25653
25653
|
}
|
|
25654
25654
|
}
|
|
25655
|
-
function processCorporateActions(actions, inventory, lotInventoryPath, projectDir, logger) {
|
|
25656
|
-
const entries = [];
|
|
25657
|
-
actions.sort((a, b) => formatDate(a.date).localeCompare(formatDate(b.date)));
|
|
25658
|
-
const mergerActions = [];
|
|
25659
|
-
const otherActions = [];
|
|
25660
|
-
for (const action of actions) {
|
|
25661
|
-
if (MERGER_LIKE_TYPES.has(action.type)) {
|
|
25662
|
-
mergerActions.push(action);
|
|
25663
|
-
} else {
|
|
25664
|
-
otherActions.push(action);
|
|
25665
|
-
}
|
|
25666
|
-
}
|
|
25667
|
-
const mergerGroups = groupMergerActions(mergerActions);
|
|
25668
|
-
mergerGroups.sort((a, b) => formatDate(a.date).localeCompare(formatDate(b.date)));
|
|
25669
|
-
let mi = 0;
|
|
25670
|
-
let oi = 0;
|
|
25671
|
-
while (mi < mergerGroups.length || oi < otherActions.length) {
|
|
25672
|
-
const mergerDate = mi < mergerGroups.length ? formatDate(mergerGroups[mi].date) : "\uFFFF";
|
|
25673
|
-
const otherDate = oi < otherActions.length ? formatDate(otherActions[oi].date) : "\uFFFF";
|
|
25674
|
-
if (mergerDate <= otherDate) {
|
|
25675
|
-
const groupEntries = processMultiWayMerger(mergerGroups[mi], inventory, lotInventoryPath, projectDir, logger);
|
|
25676
|
-
entries.push(...groupEntries);
|
|
25677
|
-
mi++;
|
|
25678
|
-
} else {
|
|
25679
|
-
processNonMergerAction(otherActions[oi], inventory, entries, logger);
|
|
25680
|
-
oi++;
|
|
25681
|
-
}
|
|
25682
|
-
}
|
|
25683
|
-
return entries;
|
|
25684
|
-
}
|
|
25685
25655
|
function groupMergerActions(actions) {
|
|
25686
25656
|
const groupMap = new Map;
|
|
25687
25657
|
for (const action of actions) {
|
|
@@ -26013,57 +25983,86 @@ async function preprocessSwissquote(csvPath, projectDir, currency, year, lotInve
|
|
|
26013
25983
|
logger?.logStep("route", "success", `Simple: ${stats.simpleTransactions}, Trades: ${stats.trades}, Dividends: ${stats.dividends}, Corporate: ${stats.corporateActions}, Forex: ${stats.forexTransactions}, Skipped: ${stats.skipped}`);
|
|
26014
25984
|
logger?.endSection();
|
|
26015
25985
|
const journalEntries = [];
|
|
26016
|
-
|
|
26017
|
-
|
|
26018
|
-
|
|
26019
|
-
|
|
26020
|
-
|
|
26021
|
-
|
|
26022
|
-
|
|
26023
|
-
|
|
26024
|
-
|
|
26025
|
-
|
|
26026
|
-
|
|
26027
|
-
|
|
26028
|
-
|
|
26029
|
-
|
|
26030
|
-
|
|
26031
|
-
|
|
26032
|
-
|
|
26033
|
-
|
|
26034
|
-
|
|
26035
|
-
|
|
26036
|
-
|
|
26037
|
-
|
|
25986
|
+
const timeline = [];
|
|
25987
|
+
for (const trade of trades) {
|
|
25988
|
+
timeline.push({ kind: "trade", sortDate: formatDate(trade.date), trade });
|
|
25989
|
+
}
|
|
25990
|
+
for (const dividend of dividends) {
|
|
25991
|
+
timeline.push({ kind: "dividend", sortDate: formatDate(dividend.date), dividend });
|
|
25992
|
+
}
|
|
25993
|
+
const mergerActions = [];
|
|
25994
|
+
const otherCorpActions = [];
|
|
25995
|
+
for (const action of corporateActions) {
|
|
25996
|
+
if (MERGER_LIKE_TYPES.has(action.type)) {
|
|
25997
|
+
mergerActions.push(action);
|
|
25998
|
+
} else {
|
|
25999
|
+
otherCorpActions.push(action);
|
|
26000
|
+
}
|
|
26001
|
+
}
|
|
26002
|
+
const mergerGroups = groupMergerActions(mergerActions);
|
|
26003
|
+
for (const group of mergerGroups) {
|
|
26004
|
+
timeline.push({ kind: "mergerGroup", sortDate: formatDate(group.date), group });
|
|
26005
|
+
}
|
|
26006
|
+
for (const action of otherCorpActions) {
|
|
26007
|
+
timeline.push({ kind: "corpAction", sortDate: formatDate(action.date), action });
|
|
26008
|
+
}
|
|
26009
|
+
timeline.sort((a, b) => a.sortDate.localeCompare(b.sortDate));
|
|
26010
|
+
if (timeline.length > 0) {
|
|
26011
|
+
logger?.startSection("Chronological Event Processing", 2);
|
|
26012
|
+
for (const event of timeline) {
|
|
26013
|
+
switch (event.kind) {
|
|
26014
|
+
case "trade": {
|
|
26015
|
+
const trade = event.trade;
|
|
26016
|
+
try {
|
|
26017
|
+
if (trade.type === "Buy") {
|
|
26018
|
+
const tradeInfo = {
|
|
26019
|
+
date: formatDate(trade.date),
|
|
26020
|
+
orderNum: trade.orderNum,
|
|
26021
|
+
symbol: trade.symbol,
|
|
26022
|
+
isin: trade.isin,
|
|
26023
|
+
quantity: trade.quantity,
|
|
26024
|
+
unitPrice: trade.unitPrice,
|
|
26025
|
+
currency: trade.currency
|
|
26026
|
+
};
|
|
26027
|
+
addLot(inventory, tradeInfo, logger);
|
|
26028
|
+
const entry = generateBuyEntry(trade, logger);
|
|
26029
|
+
journalEntries.push(entry);
|
|
26030
|
+
logger?.logStep("trade-buy", "success", `Buy ${trade.quantity} ${trade.symbol} @ ${trade.unitPrice} ${trade.currency}`);
|
|
26031
|
+
} else if (trade.type === "Sell") {
|
|
26032
|
+
const consumed = consumeLotsFIFO(inventory, trade.symbol, trade.quantity, logger);
|
|
26033
|
+
const entry = generateSellEntry(trade, consumed, logger);
|
|
26034
|
+
journalEntries.push(entry);
|
|
26035
|
+
const totalCost = consumed.reduce((sum, c) => sum + c.totalCost, 0);
|
|
26036
|
+
const gain = trade.quantity * trade.unitPrice - totalCost;
|
|
26037
|
+
logger?.logStep("trade-sell", "success", `Sell ${trade.quantity} ${trade.symbol} @ ${trade.unitPrice} ${trade.currency}, gain: ${gain.toFixed(2)}`);
|
|
26038
|
+
}
|
|
26039
|
+
} catch (error45) {
|
|
26040
|
+
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
26041
|
+
logger?.logStep("trade", "error", `Failed to process trade: ${message}`);
|
|
26042
|
+
logger?.error(`Trade processing error for ${trade.symbol}`, error45 instanceof Error ? error45 : undefined);
|
|
26043
|
+
}
|
|
26044
|
+
break;
|
|
26045
|
+
}
|
|
26046
|
+
case "dividend": {
|
|
26047
|
+
const dividend = event.dividend;
|
|
26048
|
+
const entry = generateDividendEntry(dividend, logger);
|
|
26038
26049
|
journalEntries.push(entry);
|
|
26039
|
-
|
|
26040
|
-
|
|
26041
|
-
|
|
26050
|
+
logger?.logStep("dividend", "success", `Dividend ${dividend.symbol}: ${dividend.netAmount} ${dividend.currency} (tax: ${dividend.withholdingTax})`);
|
|
26051
|
+
break;
|
|
26052
|
+
}
|
|
26053
|
+
case "mergerGroup": {
|
|
26054
|
+
const groupEntries = processMultiWayMerger(event.group, inventory, lotInventoryPath, projectDir, logger);
|
|
26055
|
+
journalEntries.push(...groupEntries);
|
|
26056
|
+
break;
|
|
26057
|
+
}
|
|
26058
|
+
case "corpAction": {
|
|
26059
|
+
processNonMergerAction(event.action, inventory, journalEntries, logger);
|
|
26060
|
+
break;
|
|
26042
26061
|
}
|
|
26043
|
-
} catch (error45) {
|
|
26044
|
-
const message = error45 instanceof Error ? error45.message : String(error45);
|
|
26045
|
-
logger?.logStep("trade", "error", `Failed to process trade: ${message}`);
|
|
26046
|
-
logger?.error(`Trade processing error for ${trade.symbol}`, error45 instanceof Error ? error45 : undefined);
|
|
26047
26062
|
}
|
|
26048
26063
|
}
|
|
26049
26064
|
logger?.endSection();
|
|
26050
26065
|
}
|
|
26051
|
-
if (dividends.length > 0) {
|
|
26052
|
-
logger?.startSection("Dividend Processing", 2);
|
|
26053
|
-
for (const dividend of dividends) {
|
|
26054
|
-
const entry = generateDividendEntry(dividend, logger);
|
|
26055
|
-
journalEntries.push(entry);
|
|
26056
|
-
logger?.logStep("dividend", "success", `Dividend ${dividend.symbol}: ${dividend.netAmount} ${dividend.currency} (tax: ${dividend.withholdingTax})`);
|
|
26057
|
-
}
|
|
26058
|
-
logger?.endSection();
|
|
26059
|
-
}
|
|
26060
|
-
if (corporateActions.length > 0) {
|
|
26061
|
-
logger?.startSection("Corporate Actions Processing", 2);
|
|
26062
|
-
const corpEntries = processCorporateActions(corporateActions, inventory, lotInventoryPath, projectDir, logger);
|
|
26063
|
-
journalEntries.push(...corpEntries);
|
|
26064
|
-
logger?.logStep("corporate", "success", `Processed ${corporateActions.length} corporate actions`);
|
|
26065
|
-
logger?.endSection();
|
|
26066
|
-
}
|
|
26067
26066
|
logger?.logStep("save-inventory", "start", "Saving lot inventory");
|
|
26068
26067
|
saveLotInventory(projectDir, lotInventoryPath, inventory, logger);
|
|
26069
26068
|
logger?.logStep("save-inventory", "success", "Lot inventory saved");
|
package/package.json
CHANGED