diff --git a/src/components/layout/Modals.svelte b/src/components/layout/Modals.svelte
index 03b829d..db387eb 100644
--- a/src/components/layout/Modals.svelte
+++ b/src/components/layout/Modals.svelte
@@ -14,6 +14,7 @@
import UnstakeCAP from '../modals/UnstakeCAP.svelte'
import HistoryOrderStatus from '../modals/HistoryOrderStatus.svelte'
import Settings from '../modals/Settings.svelte'
+ import ExportHistory from '../modals/ExportHistory.svelte'
@@ -67,4 +68,8 @@
{#if $activeModal && $activeModal.name == 'MarketInfo'}
+{/if}
+
+{#if $activeModal && $activeModal.name == 'ExportHistory'}
+
{/if}
\ No newline at end of file
diff --git a/src/components/modals/ExportHistory.svelte b/src/components/modals/ExportHistory.svelte
new file mode 100644
index 0000000..70fd521
--- /dev/null
+++ b/src/components/modals/ExportHistory.svelte
@@ -0,0 +1,227 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Default: last 30 days. Large exports are processed in a background thread.
+
+
+
+
+
+
+
+
+
diff --git a/src/components/trade/account/History.svelte b/src/components/trade/account/History.svelte
index 68ee72e..273c143 100644
--- a/src/components/trade/account/History.svelte
+++ b/src/components/trade/account/History.svelte
@@ -120,6 +120,24 @@
+{#if !$isLoading && $historySorted.length > 0}
+
+
+
+{/if}
+
c.label);
+ let csv = headers.join(',') + '\n';
+
+ // Build data rows
+ for (const item of items) {
+ const row = columns.map(col => {
+ let value = item[col.key];
+
+ // Apply formatter if provided
+ if (col.format && formatters[col.format]) {
+ value = formatters[col.format](value);
+ }
+
+ // Handle undefined/null
+ if (value === undefined || value === null) {
+ return '';
+ }
+
+ // Escape CSV: wrap in quotes if contains comma, quote, or newline
+ const str = String(value);
+ if (str.includes(',') || str.includes('"') || str.includes('\n')) {
+ return '"' + str.replace(/"/g, '""') + '"';
+ }
+ return str;
+ });
+ csv += row.join(',') + '\n';
+ }
+
+ self.postMessage({ csv });
+};