@tradejs/app 1.0.9 → 1.0.11

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.
Files changed (125) hide show
  1. package/README.md +16 -3
  2. package/bin/tradejs-app.mjs +146 -2
  3. package/next.config.mjs +0 -14
  4. package/package.json +35 -19
  5. package/src/app/actions/backtest.ts +54 -0
  6. package/src/app/actions/kline.ts +10 -5
  7. package/src/app/actions/scanner.ts +8 -3
  8. package/src/app/actions/strategies.ts +39 -0
  9. package/src/app/api/ai/route.ts +5 -4
  10. package/src/app/api/auth/[...nextauth]/route.ts +1 -1
  11. package/src/app/api/backtest/configs/route.ts +25 -0
  12. package/src/app/api/backtest/files/route.ts +5 -2
  13. package/src/app/api/backtest/order-log/[strategy]/[name]/route.ts +26 -2
  14. package/src/app/api/backtest/result/[strategy]/[name]/route.ts +27 -2
  15. package/src/app/api/backtest/runs/[jobId]/route.ts +124 -0
  16. package/src/app/api/backtest/runs/route.ts +45 -0
  17. package/src/app/api/backtest/test/[strategy]/[name]/route.ts +19 -2
  18. package/src/app/api/derivatives/summary/route.ts +8 -1
  19. package/src/app/api/install/route.ts +51 -0
  20. package/src/app/api/kline/[provider]/[universe]/[symbol]/[interval]/route.ts +1 -0
  21. package/src/app/api/kline/{[provider]/[symbol]/[interval]/route.ts → handler.ts} +61 -39
  22. package/src/app/api/scanner/[provider]/[universe]/route.ts +1 -0
  23. package/src/app/api/scanner/[provider]/route.ts +30 -12
  24. package/src/app/api/scanner/route.ts +3 -3
  25. package/src/app/api/signal/[symbol]/[signalId]/route.ts +1 -1
  26. package/src/app/api/strategies/ai/[cardId]/route.ts +22 -0
  27. package/src/app/api/strategies/ai/route.ts +139 -0
  28. package/src/app/api/strategies/replay/[cardId]/route.ts +18 -0
  29. package/src/app/api/strategies/replay/route.ts +44 -0
  30. package/src/app/api/strategies/runtime/route.ts +831 -0
  31. package/src/app/api/user/runtime-deployments/[deploymentId]/route.ts +25 -0
  32. package/src/app/api/user/runtime-deployments/route.ts +94 -0
  33. package/src/app/api/user/runtime-strategy-configs/route.ts +241 -0
  34. package/src/app/api/user/settings/route.ts +18 -1
  35. package/src/app/api/user/trading-accounts/[accountId]/route.ts +35 -0
  36. package/src/app/api/user/trading-accounts/route.ts +134 -0
  37. package/src/app/auth.ts +1 -19
  38. package/src/app/components/Backtest/CompareList/index.tsx +1 -1
  39. package/src/app/components/Backtest/ResultsPageClient.tsx +376 -0
  40. package/src/app/components/Backtest/TestCard/ActionsMenu/index.tsx +123 -0
  41. package/src/app/components/Backtest/TestCard/Chart/index.tsx +1 -1
  42. package/src/app/components/Backtest/TestCard/CompareButton/index.tsx +1 -1
  43. package/src/app/components/Backtest/TestCard/ConfigDrawer/index.tsx +28 -12
  44. package/src/app/components/Backtest/TestCard/DeleteButton/index.tsx +33 -17
  45. package/src/app/components/Backtest/TestCard/FavoriteIndicator/index.tsx +2 -2
  46. package/src/app/components/Backtest/TestCard/OpenDashboardButton/index.tsx +10 -1
  47. package/src/app/components/Backtest/TestCard/OrdersDrawer/index.tsx +128 -0
  48. package/src/app/components/Backtest/TestCard/Root/index.tsx +18 -4
  49. package/src/app/components/Backtest/TestCard/Stat/index.tsx +2 -0
  50. package/src/app/components/Backtest/TestCard/StatDrawer/index.tsx +66 -0
  51. package/src/app/components/Backtest/TestCard/index.ts +6 -2
  52. package/src/app/components/Backtest/TestList/index.tsx +4 -9
  53. package/src/app/components/Dashboard/AiDrawer/index.tsx +1 -1
  54. package/src/app/components/Dashboard/KlineChart/hooks/useBacktest.ts +1 -1
  55. package/src/app/components/Dashboard/KlineChart/hooks/useBbIndicator.ts +10 -5
  56. package/src/app/components/Dashboard/KlineChart/hooks/useBtcCorrelation.ts +1 -1
  57. package/src/app/components/Dashboard/KlineChart/hooks/useBtcIndicator.ts +4 -1
  58. package/src/app/components/Dashboard/KlineChart/hooks/useEmaIndicator.ts +3 -1
  59. package/src/app/components/Dashboard/KlineChart/hooks/usePluginIndicators.ts +1 -1
  60. package/src/app/components/Dashboard/KlineChart/hooks/useSetup.ts +1 -1
  61. package/src/app/components/Dashboard/KlineChart/hooks/useSignal.ts +1 -1
  62. package/src/app/components/Dashboard/KlineChart/hooks/useSpreadIndicator.ts +1 -1
  63. package/src/app/components/Dashboard/KlineChart/hooks/useTrendLine.ts +1 -1
  64. package/src/app/components/Dashboard/KlineChart/hooks/useWmaIndicator.ts +3 -1
  65. package/src/app/components/Dashboard/KlineChart/index.tsx +21 -7
  66. package/src/app/components/Dashboard/MainChart/index.tsx +3 -22
  67. package/src/app/components/Shared/AppShell.tsx +2 -2
  68. package/src/app/components/Shared/BulkSelection/index.tsx +140 -0
  69. package/src/app/components/Shared/BulkSelection/useBulkSelection.ts +97 -0
  70. package/src/app/components/Shared/BulkSelection/utils.ts +126 -0
  71. package/src/app/components/Shared/Filters/Backtest/index.tsx +51 -51
  72. package/src/app/components/Shared/Filters/FavoriteIndicator/index.tsx +5 -3
  73. package/src/app/components/Shared/Filters/Indicators/index.tsx +2 -2
  74. package/src/app/components/Shared/Filters/Interval/index.tsx +1 -1
  75. package/src/app/components/Shared/Filters/Provider/index.tsx +8 -2
  76. package/src/app/components/Shared/Filters/Symbol/index.tsx +4 -3
  77. package/src/app/components/Shared/Filters/Universe/index.tsx +36 -0
  78. package/src/app/components/Shared/Filters/index.ts +2 -0
  79. package/src/app/components/Shared/OrdersDrawer.tsx +629 -0
  80. package/src/app/components/Shared/Sidebar/AccountSettingsDrawer.tsx +55 -28
  81. package/src/app/components/Shared/Sidebar/TradingAccountsPanel.tsx +445 -0
  82. package/src/app/components/Shared/Sidebar/index.tsx +17 -3
  83. package/src/app/components/Strategies/AdvancedMetricsPanel.tsx +727 -0
  84. package/src/app/components/Strategies/RuntimeStrategyCard.tsx +2204 -0
  85. package/src/app/components/Strategies/RuntimeStrategyCardSkeleton.tsx +40 -0
  86. package/src/app/components/Strategies/RuntimeStrategyChart.tsx +121 -0
  87. package/src/app/components/Strategies/RuntimeStrategyConfigDrawer.tsx +458 -0
  88. package/src/app/components/Strategies/StrategySnapshotCard.tsx +2890 -0
  89. package/src/app/components/Strategies/StrategySnapshotChart.tsx +94 -0
  90. package/src/app/components/Strategies/StrategySnapshotList.tsx +82 -0
  91. package/src/app/components/UI/Segment/index.tsx +8 -1
  92. package/src/app/components/UI/Select/index.tsx +24 -13
  93. package/src/app/components/UI/SelectWithSearch/index.tsx +46 -5
  94. package/src/app/layout.tsx +1 -1
  95. package/src/app/lib/backtestJobs.ts +925 -0
  96. package/src/app/lib/cardPageLayout.ts +1 -0
  97. package/src/app/lib/connectorCreator.ts +28 -0
  98. package/src/app/lib/currentUser.ts +1 -1
  99. package/src/app/lib/errorMessage.ts +34 -0
  100. package/src/app/lib/installation.ts +83 -0
  101. package/src/app/lib/marketDefaults.ts +12 -0
  102. package/src/app/lib/marketRoutes.ts +58 -0
  103. package/src/app/lib/runtimeStrategies.ts +1376 -0
  104. package/src/app/lib/runtimeStrategyConfigForm.ts +86 -0
  105. package/src/app/provider.tsx +1 -1
  106. package/src/app/routes/backtest/page.tsx +1100 -302
  107. package/src/app/routes/dashboard/{[provider]/[symbol]/[interval]/page.tsx → Dashboard.tsx} +76 -35
  108. package/src/app/routes/dashboard/[provider]/[universe]/[symbol]/[interval]/page.tsx +1 -0
  109. package/src/app/routes/dashboard/page.tsx +15 -3
  110. package/src/app/routes/derivatives/page.tsx +1222 -165
  111. package/src/app/routes/install/page.tsx +175 -0
  112. package/src/app/routes/signin/page.tsx +7 -0
  113. package/src/app/routes/strategies/StrategiesPageClient.tsx +593 -0
  114. package/src/app/routes/strategies/[mode]/page.tsx +20 -0
  115. package/src/app/routes/strategies/page.tsx +7 -0
  116. package/src/app/store/ai.ts +1 -1
  117. package/src/app/store/data.ts +73 -17
  118. package/src/app/store/filters.ts +1 -0
  119. package/src/app/store/marketKlineStream.ts +87 -0
  120. package/src/app/store/tests.ts +83 -45
  121. package/src/app/store/tickers.ts +59 -22
  122. package/src/proxy.ts +4 -0
  123. package/tsconfig.json +17 -12
  124. package/src/app/components/Backtest/TestCard/OpenReportButton/index.tsx +0 -24
  125. package/src/app/routes/backtest/[test]/page.tsx +0 -33
@@ -0,0 +1,175 @@
1
+ 'use client';
2
+
3
+ import { useEffect, useState } from 'react';
4
+ import { useRouter } from 'next/navigation';
5
+ import Image from 'next/image';
6
+ import { signIn } from 'next-auth/react';
7
+ import { Box, Button, Field, Flex, Input, Stack, Text } from '@chakra-ui/react';
8
+
9
+ const FIRST_DASHBOARD_PATH = '/routes/dashboard/coinbase/crypto/BTCUSDT/15';
10
+
11
+ const Install = () => {
12
+ const router = useRouter();
13
+ const [password, setPassword] = useState('');
14
+ const [confirmPassword, setConfirmPassword] = useState('');
15
+ const [error, setError] = useState('');
16
+ const [isLoading, setIsLoading] = useState(true);
17
+ const [isSubmitting, setIsSubmitting] = useState(false);
18
+
19
+ useEffect(() => {
20
+ void fetch('/api/install')
21
+ .then(async (response) => {
22
+ if (!response.ok) throw new Error('Unable to check installation');
23
+ return (await response.json()) as { required?: boolean };
24
+ })
25
+ .then(({ required }) => {
26
+ if (!required) {
27
+ router.replace('/routes/signin');
28
+ return;
29
+ }
30
+ setIsLoading(false);
31
+ })
32
+ .catch(() => {
33
+ setError('Unable to connect to the local TradeJS infrastructure');
34
+ setIsLoading(false);
35
+ });
36
+ }, [router]);
37
+
38
+ const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
39
+ event.preventDefault();
40
+ setError('');
41
+
42
+ if (password.length < 8) {
43
+ setError('Password must contain at least 8 characters');
44
+ return;
45
+ }
46
+ if (password !== confirmPassword) {
47
+ setError('Passwords do not match');
48
+ return;
49
+ }
50
+
51
+ setIsSubmitting(true);
52
+ const response = await fetch('/api/install', {
53
+ method: 'POST',
54
+ headers: { 'content-type': 'application/json' },
55
+ body: JSON.stringify({ password, confirmPassword }),
56
+ });
57
+ const payload = (await response.json().catch(() => null)) as {
58
+ error?: string;
59
+ } | null;
60
+
61
+ if (!response.ok) {
62
+ setError(payload?.error || 'Unable to install TradeJS');
63
+ setIsSubmitting(false);
64
+ return;
65
+ }
66
+
67
+ const result = await signIn('credentials', {
68
+ redirect: false,
69
+ username: 'root',
70
+ password,
71
+ callbackUrl: FIRST_DASHBOARD_PATH,
72
+ });
73
+
74
+ if (!result || result.error) {
75
+ router.replace('/routes/signin');
76
+ return;
77
+ }
78
+
79
+ router.replace(FIRST_DASHBOARD_PATH);
80
+ };
81
+
82
+ return (
83
+ <Flex minH="100vh" direction={{ base: 'column', lg: 'row' }} bg="gray.950">
84
+ <Flex
85
+ w={{ base: 'full', lg: '40%' }}
86
+ px={{ base: 6, md: 10, lg: 12 }}
87
+ py={{ base: 10, lg: 12 }}
88
+ align="center"
89
+ justify="center"
90
+ minH={{ base: '100vh', lg: 'auto' }}
91
+ >
92
+ <form onSubmit={handleSubmit} style={{ width: '100%' }}>
93
+ <Box w="full" maxW="420px" mx="auto">
94
+ <Stack gap="6">
95
+ <Stack gap="3">
96
+ <Text fontSize="sm" opacity={0.7} letterSpacing="0.2em">
97
+ INSTALL TRADEJS
98
+ </Text>
99
+ <Text as="h1" fontSize="3xl" fontWeight="700" color="white">
100
+ Create your local password
101
+ </Text>
102
+ <Text color="gray.400">
103
+ This password protects the local root account. It is stored
104
+ only in your TradeJS infrastructure.
105
+ </Text>
106
+ </Stack>
107
+
108
+ <Stack gap="4">
109
+ <Field.Root>
110
+ <Field.Label>Password</Field.Label>
111
+ <Input
112
+ aria-label="Password"
113
+ value={password}
114
+ onChange={(event) => setPassword(event.target.value)}
115
+ type="password"
116
+ autoComplete="new-password"
117
+ disabled={isLoading}
118
+ />
119
+ </Field.Root>
120
+ <Field.Root>
121
+ <Field.Label>Confirm password</Field.Label>
122
+ <Input
123
+ aria-label="Confirm password"
124
+ value={confirmPassword}
125
+ onChange={(event) => setConfirmPassword(event.target.value)}
126
+ type="password"
127
+ autoComplete="new-password"
128
+ disabled={isLoading}
129
+ />
130
+ </Field.Root>
131
+ </Stack>
132
+
133
+ {error ? (
134
+ <Text role="alert" fontSize="sm" color="red.300">
135
+ {error}
136
+ </Text>
137
+ ) : null}
138
+
139
+ <Button
140
+ type="submit"
141
+ loading={isSubmitting || isLoading}
142
+ disabled={isLoading || !password || !confirmPassword}
143
+ bg="#20c5bd"
144
+ color="gray.950"
145
+ _hover={{ bg: '#42d8d0' }}
146
+ >
147
+ Install and open dashboard
148
+ </Button>
149
+ </Stack>
150
+ </Box>
151
+ </form>
152
+ </Flex>
153
+
154
+ <Box
155
+ display={{ base: 'none', lg: 'block' }}
156
+ w={{ lg: '60%' }}
157
+ minH="100vh"
158
+ bg="gray.900"
159
+ position="relative"
160
+ overflow="hidden"
161
+ >
162
+ <Image
163
+ src="/auth-bg.jpg"
164
+ alt="Market chart background"
165
+ fill
166
+ priority
167
+ sizes="(min-width: 1024px) 60vw, 0vw"
168
+ style={{ objectFit: 'cover', objectPosition: 'center' }}
169
+ />
170
+ </Box>
171
+ </Flex>
172
+ );
173
+ };
174
+
175
+ export default Install;
@@ -26,6 +26,13 @@ const SigninContent = () => {
26
26
  }
27
27
  }, [status, router, callbackUrl]);
28
28
 
29
+ useEffect(() => {
30
+ const suggestedUsername = searchParams.get('username')?.trim();
31
+ if (suggestedUsername) {
32
+ setUsername((current) => current || suggestedUsername);
33
+ }
34
+ }, [searchParams]);
35
+
29
36
  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
30
37
  event.preventDefault();
31
38
  setError('');