@finatic/client 0.0.139 → 0.0.141
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/README.md +335 -446
- package/dist/index.d.ts +272 -515
- package/dist/index.js +531 -449
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +532 -449
- package/dist/index.mjs.map +1 -1
- package/dist/types/core/client/ApiClient.d.ts +81 -27
- package/dist/types/core/client/FinaticConnect.d.ts +53 -103
- package/dist/types/index.d.ts +1 -2
- package/dist/types/mocks/MockApiClient.d.ts +2 -4
- package/dist/types/mocks/utils.d.ts +0 -5
- package/dist/types/types/api/auth.d.ts +12 -30
- package/dist/types/types/api/broker.d.ts +117 -1
- package/package.json +7 -3
- package/src/core/client/ApiClient.ts +1978 -0
- package/src/core/client/FinaticConnect.ts +1557 -0
- package/src/core/portal/PortalUI.ts +300 -0
- package/src/index.d.ts +23 -0
- package/src/index.ts +99 -0
- package/src/mocks/MockApiClient.ts +1032 -0
- package/src/mocks/MockDataProvider.ts +986 -0
- package/src/mocks/MockFactory.ts +97 -0
- package/src/mocks/utils.ts +133 -0
- package/src/themes/portalPresets.ts +1307 -0
- package/src/types/api/auth.ts +112 -0
- package/src/types/api/broker.ts +461 -0
- package/src/types/api/core.ts +53 -0
- package/src/types/api/errors.ts +35 -0
- package/src/types/api/orders.ts +45 -0
- package/src/types/api/portfolio.ts +59 -0
- package/src/types/common/pagination.ts +138 -0
- package/src/types/connect.ts +56 -0
- package/src/types/index.ts +25 -0
- package/src/types/portal.ts +214 -0
- package/src/types/ui/theme.ts +105 -0
- package/src/utils/brokerUtils.ts +85 -0
- package/src/utils/errors.ts +104 -0
- package/src/utils/events.ts +54 -0
- package/src/utils/themeUtils.ts +146 -0
package/README.md
CHANGED
|
@@ -37,540 +37,429 @@ const finatic = await FinaticConnect.init('your-one-time-token', 'user-123', {
|
|
|
37
37
|
});
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
await finatic.openPortal({
|
|
42
|
-
onSuccess: (userId) => {
|
|
43
|
-
console.log('Authentication successful:', userId);
|
|
44
|
-
},
|
|
45
|
-
onError: (error) => {
|
|
46
|
-
console.error('Authentication failed:', error);
|
|
47
|
-
},
|
|
48
|
-
onClose: () => {
|
|
49
|
-
console.log('Portal closed');
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// After successful authentication, you can use these methods:
|
|
54
|
-
|
|
55
|
-
// Get list of supported brokers
|
|
56
|
-
const brokers = await finatic.getBrokerList();
|
|
57
|
-
|
|
58
|
-
// Get broker accounts with pagination
|
|
59
|
-
const accountsPage = await finatic.getAccounts({
|
|
60
|
-
page: 1,
|
|
61
|
-
perPage: 100
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// Navigate through pages
|
|
65
|
-
const nextPage = await accountsPage.nextPage();
|
|
66
|
-
const prevPage = await accountsPage.previousPage();
|
|
67
|
-
|
|
68
|
-
// Get all accounts (convenience method)
|
|
69
|
-
const allAccounts = await finatic.getAllAccounts();
|
|
70
|
-
|
|
71
|
-
// Get orders with filtering
|
|
72
|
-
const ordersPage = await finatic.getOrders({
|
|
73
|
-
page: 1,
|
|
74
|
-
perPage: 50,
|
|
75
|
-
filter: { status: 'filled', symbol: 'AAPL' }
|
|
76
|
-
});
|
|
40
|
+
## Portal Management
|
|
77
41
|
|
|
78
|
-
|
|
79
|
-
const positionsPage = await finatic.getPositions({
|
|
80
|
-
page: 1,
|
|
81
|
-
perPage: 100
|
|
82
|
-
});
|
|
42
|
+
### Opening the Portal
|
|
83
43
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
44
|
+
```typescript
|
|
45
|
+
// Open the portal with basic configuration
|
|
46
|
+
await finatic.openPortal({
|
|
47
|
+
onSuccess: userId => {
|
|
48
|
+
console.log('Authentication successful:', userId);
|
|
49
|
+
},
|
|
50
|
+
onError: error => {
|
|
51
|
+
console.error('Authentication failed:', error);
|
|
52
|
+
},
|
|
53
|
+
onClose: () => {
|
|
54
|
+
console.log('Portal closed');
|
|
55
|
+
},
|
|
91
56
|
});
|
|
92
57
|
|
|
93
58
|
// Open portal with broker filtering
|
|
94
59
|
await finatic.openPortal({
|
|
95
|
-
brokers: ['alpaca', 'robinhood'] // Only show these brokers
|
|
60
|
+
brokers: ['alpaca', 'robinhood'], // Only show these brokers
|
|
61
|
+
onSuccess: userId => {
|
|
62
|
+
console.log('Authentication successful:', userId);
|
|
63
|
+
},
|
|
96
64
|
});
|
|
97
65
|
|
|
98
|
-
//
|
|
99
|
-
const disconnectResponse = await finatic.disconnectCompany('connection-uuid-here');
|
|
100
|
-
console.log('Disconnect action:', disconnectResponse.response_data.action);
|
|
101
|
-
|
|
102
|
-
// Close the portal when done
|
|
103
|
-
finatic.closePortal();
|
|
104
|
-
|
|
105
|
-
````
|
|
106
|
-
|
|
107
|
-
## API Reference
|
|
108
|
-
|
|
109
|
-
### Initialization
|
|
110
|
-
|
|
111
|
-
#### `FinaticConnect.init(token, userId?, options?)`
|
|
112
|
-
|
|
113
|
-
Initialize the Finatic Client SDK.
|
|
114
|
-
|
|
115
|
-
- `token` (string): One-time token from your backend
|
|
116
|
-
- `userId` (string, optional): Pre-authenticated user ID from previous session
|
|
117
|
-
- `options` (object, optional): Configuration options
|
|
118
|
-
- `baseUrl` (string, optional): Custom API base URL
|
|
119
|
-
|
|
120
|
-
Returns: Promise<FinaticConnect>
|
|
121
|
-
|
|
122
|
-
### Portal Management
|
|
123
|
-
|
|
124
|
-
#### `openPortal(options?)`
|
|
125
|
-
|
|
126
|
-
Opens the authentication portal in an iframe.
|
|
127
|
-
|
|
128
|
-
- `options` (object, optional): Portal options
|
|
129
|
-
- `onSuccess` (function): Called when authentication succeeds
|
|
130
|
-
- `onError` (function): Called when authentication fails
|
|
131
|
-
- `onClose` (function): Called when portal is closed
|
|
132
|
-
- `onEvent` (function): Called when portal events occur
|
|
133
|
-
- `theme` (object, optional): Theme configuration
|
|
134
|
-
- `preset` (string, optional): Preset theme name ('dark', 'light', 'corporateBlue', 'purple', 'green', 'orange')
|
|
135
|
-
- `custom` (object, optional): Custom theme configuration object
|
|
136
|
-
- `brokers` (string[], optional): List of broker names to filter by (only these brokers will be shown)
|
|
137
|
-
|
|
138
|
-
#### `closePortal()`
|
|
139
|
-
|
|
140
|
-
Closes the authentication portal.
|
|
141
|
-
|
|
142
|
-
### Portal Theming
|
|
143
|
-
|
|
144
|
-
The Finatic Portal supports dynamic theme switching via URL parameters. You can customize the portal's appearance to match your application's branding.
|
|
145
|
-
|
|
146
|
-
#### Using Preset Themes
|
|
147
|
-
|
|
148
|
-
```javascript
|
|
149
|
-
// Use a preset theme
|
|
66
|
+
// Open portal with theming
|
|
150
67
|
await finatic.openPortal({
|
|
151
|
-
theme: {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
// Available presets: 'dark', 'light', 'corporateBlue', 'purple', 'green', 'orange'
|
|
155
|
-
````
|
|
156
|
-
|
|
157
|
-
#### Using Custom Themes
|
|
158
|
-
|
|
159
|
-
```javascript
|
|
160
|
-
// Use a custom theme
|
|
161
|
-
const customTheme = {
|
|
162
|
-
mode: 'dark',
|
|
163
|
-
colors: {
|
|
164
|
-
background: {
|
|
165
|
-
primary: '#1a1a1a',
|
|
166
|
-
secondary: '#2a2a2a',
|
|
167
|
-
tertiary: '#3a3a3a',
|
|
168
|
-
accent: 'rgba(59, 130, 246, 0.1)',
|
|
169
|
-
glass: 'rgba(255, 255, 255, 0.05)',
|
|
170
|
-
},
|
|
171
|
-
status: {
|
|
172
|
-
connected: '#10B981',
|
|
173
|
-
disconnected: '#EF4444',
|
|
174
|
-
warning: '#F59E0B',
|
|
175
|
-
pending: '#8B5CF6',
|
|
176
|
-
error: '#EF4444',
|
|
177
|
-
success: '#10B981',
|
|
178
|
-
},
|
|
179
|
-
text: {
|
|
180
|
-
primary: '#F8FAFC',
|
|
181
|
-
secondary: '#CBD5E1',
|
|
182
|
-
muted: '#94A3B8',
|
|
183
|
-
inverse: '#1a1a1a',
|
|
184
|
-
},
|
|
185
|
-
border: {
|
|
186
|
-
primary: 'rgba(59, 130, 246, 0.2)',
|
|
187
|
-
secondary: 'rgba(255, 255, 255, 0.1)',
|
|
188
|
-
hover: 'rgba(59, 130, 246, 0.4)',
|
|
189
|
-
focus: 'rgba(59, 130, 246, 0.6)',
|
|
190
|
-
accent: '#3B82F6',
|
|
191
|
-
},
|
|
192
|
-
input: {
|
|
193
|
-
background: '#334155',
|
|
194
|
-
border: 'rgba(59, 130, 246, 0.2)',
|
|
195
|
-
borderFocus: '#3B82F6',
|
|
196
|
-
text: '#F8FAFC',
|
|
197
|
-
placeholder: '#94A3B8',
|
|
198
|
-
},
|
|
199
|
-
button: {
|
|
200
|
-
primary: {
|
|
201
|
-
background: '#3B82F6',
|
|
202
|
-
text: '#FFFFFF',
|
|
203
|
-
hover: '#2563EB',
|
|
204
|
-
active: '#1D4ED8',
|
|
205
|
-
},
|
|
206
|
-
secondary: {
|
|
207
|
-
background: 'transparent',
|
|
208
|
-
text: '#3B82F6',
|
|
209
|
-
border: '#3B82F6',
|
|
210
|
-
hover: 'rgba(59, 130, 246, 0.1)',
|
|
211
|
-
active: 'rgba(59, 130, 246, 0.2)',
|
|
212
|
-
},
|
|
213
|
-
},
|
|
214
|
-
},
|
|
215
|
-
branding: {
|
|
216
|
-
primaryColor: '#3B82F6',
|
|
68
|
+
theme: {
|
|
69
|
+
primaryColor: '#007bff',
|
|
70
|
+
logoUrl: 'https://example.com/logo.png',
|
|
217
71
|
},
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
await finatic.openPortal({
|
|
221
|
-
theme: { custom: customTheme },
|
|
222
72
|
});
|
|
223
73
|
```
|
|
224
74
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
```javascript
|
|
228
|
-
import {
|
|
229
|
-
generatePortalThemeURL,
|
|
230
|
-
appendThemeToURL,
|
|
231
|
-
getThemePreset,
|
|
232
|
-
validateCustomTheme,
|
|
233
|
-
createCustomThemeFromPreset,
|
|
234
|
-
portalThemePresets,
|
|
235
|
-
} from 'finatic-sdk';
|
|
236
|
-
|
|
237
|
-
// Generate a themed portal URL
|
|
238
|
-
const themedUrl = generatePortalThemeURL('http://localhost:5173/companies', {
|
|
239
|
-
preset: 'corporateBlue',
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
// Get a theme preset
|
|
243
|
-
const darkTheme = getThemePreset('dark');
|
|
244
|
-
|
|
245
|
-
// Validate a custom theme
|
|
246
|
-
const isValid = validateCustomTheme(customTheme);
|
|
75
|
+
### Closing the Portal
|
|
247
76
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
background: {
|
|
252
|
-
primary: '#000000',
|
|
253
|
-
},
|
|
254
|
-
},
|
|
255
|
-
});
|
|
77
|
+
```typescript
|
|
78
|
+
// Close the portal
|
|
79
|
+
await finatic.closePortal();
|
|
256
80
|
```
|
|
257
81
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
The Finatic Portal supports broker filtering via URL parameters. You can restrict which brokers are displayed in the portal by specifying a list of allowed broker names.
|
|
261
|
-
|
|
262
|
-
#### Supported Brokers
|
|
263
|
-
|
|
264
|
-
The following broker names are supported:
|
|
265
|
-
|
|
266
|
-
- `alpaca` - Alpaca Markets
|
|
267
|
-
- `robinhood` - Robinhood
|
|
268
|
-
- `tasty_trade` - TastyTrade
|
|
269
|
-
- `ninja_trader` - NinjaTrader
|
|
82
|
+
## Data Access
|
|
270
83
|
|
|
271
|
-
|
|
84
|
+
### Paginated Data Access
|
|
272
85
|
|
|
273
|
-
|
|
274
|
-
// Show only specific brokers
|
|
275
|
-
await finatic.openPortal({
|
|
276
|
-
brokers: ['alpaca', 'robinhood'],
|
|
277
|
-
});
|
|
86
|
+
The SDK provides a consistent pagination pattern using `get*()` methods with navigation:
|
|
278
87
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
88
|
+
```typescript
|
|
89
|
+
// Get orders with pagination
|
|
90
|
+
const ordersPage = await finatic.getOrders({
|
|
91
|
+
page: 1,
|
|
92
|
+
perPage: 50,
|
|
93
|
+
filter: { status: 'filled', symbol: 'AAPL' },
|
|
282
94
|
});
|
|
283
95
|
|
|
284
|
-
//
|
|
285
|
-
await
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
96
|
+
// Navigate through pages
|
|
97
|
+
const nextPage = await ordersPage.nextPage();
|
|
98
|
+
const prevPage = await ordersPage.previousPage();
|
|
99
|
+
|
|
100
|
+
// Check pagination status
|
|
101
|
+
console.log('Has next page:', ordersPage.hasNext);
|
|
102
|
+
console.log('Has previous page:', ordersPage.hasPrevious);
|
|
103
|
+
console.log('Current page:', ordersPage.page);
|
|
104
|
+
console.log('Total pages:', ordersPage.totalPages);
|
|
289
105
|
```
|
|
290
106
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
If you pass an unsupported broker name, it will be logged as a warning to the console, but the portal will still open with the supported brokers:
|
|
107
|
+
### Get All Data (Convenience Methods)
|
|
294
108
|
|
|
295
|
-
```
|
|
296
|
-
//
|
|
297
|
-
await finatic.
|
|
298
|
-
|
|
299
|
-
|
|
109
|
+
```typescript
|
|
110
|
+
// Get all data across all pages
|
|
111
|
+
const allOrders = await finatic.getAllOrders();
|
|
112
|
+
const allPositions = await finatic.getAllPositions();
|
|
113
|
+
const allAccounts = await finatic.getAllAccounts();
|
|
114
|
+
const allBalances = await finatic.getAllBalances();
|
|
300
115
|
```
|
|
301
116
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
```javascript
|
|
305
|
-
import {
|
|
306
|
-
convertBrokerNamesToIds,
|
|
307
|
-
appendBrokerFilterToURL,
|
|
308
|
-
getSupportedBrokerNames,
|
|
309
|
-
isBrokerSupported,
|
|
310
|
-
} from 'finatic-sdk';
|
|
311
|
-
|
|
312
|
-
// Convert broker names to IDs
|
|
313
|
-
const { brokerIds, warnings } = convertBrokerNamesToIds(['alpaca', 'robinhood']);
|
|
117
|
+
### Convenience Filter Methods
|
|
314
118
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
const
|
|
119
|
+
```typescript
|
|
120
|
+
// Get filtered data
|
|
121
|
+
const openPositions = await finatic.getOpenPositions();
|
|
122
|
+
const filledOrders = await finatic.getFilledOrders();
|
|
123
|
+
const pendingOrders = await finatic.getPendingOrders();
|
|
124
|
+
const activeAccounts = await finatic.getActiveAccounts();
|
|
125
|
+
|
|
126
|
+
// Get data by symbol
|
|
127
|
+
const aaplOrders = await finatic.getOrdersBySymbol('AAPL');
|
|
128
|
+
const aaplPositions = await finatic.getPositionsBySymbol('AAPL');
|
|
129
|
+
|
|
130
|
+
// Get data by broker
|
|
131
|
+
const robinhoodOrders = await finatic.getOrdersByBroker('robinhood');
|
|
132
|
+
const robinhoodPositions = await finatic.getPositionsByBroker('robinhood');
|
|
320
133
|
```
|
|
321
134
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
#### `getAccounts(params?)`
|
|
325
|
-
|
|
326
|
-
Returns paginated broker accounts.
|
|
327
|
-
|
|
328
|
-
- `params` (object, optional): Query parameters
|
|
329
|
-
- `page` (number, optional): Page number (default: 1)
|
|
330
|
-
- `perPage` (number, optional): Items per page (default: 100)
|
|
331
|
-
- `filter` (object, optional): Filter parameters
|
|
332
|
-
|
|
333
|
-
Returns: Promise<PaginatedResult<BrokerDataAccount[]>>
|
|
334
|
-
|
|
335
|
-
#### `getOrders(params?)`
|
|
336
|
-
|
|
337
|
-
Returns paginated order history.
|
|
338
|
-
|
|
339
|
-
- `params` (object, optional): Query parameters
|
|
340
|
-
- `page` (number, optional): Page number (default: 1)
|
|
341
|
-
- `perPage` (number, optional): Items per page (default: 100)
|
|
342
|
-
- `filter` (object, optional): Filter parameters
|
|
343
|
-
|
|
344
|
-
Returns: Promise<PaginatedResult<BrokerDataOrder[]>>
|
|
345
|
-
|
|
346
|
-
#### `getPositions(params?)`
|
|
347
|
-
|
|
348
|
-
Returns paginated positions.
|
|
349
|
-
|
|
350
|
-
- `params` (object, optional): Query parameters
|
|
351
|
-
- `page` (number, optional): Page number (default: 1)
|
|
352
|
-
- `perPage` (number, optional): Items per page (default: 100)
|
|
353
|
-
- `filter` (object, optional): Filter parameters
|
|
354
|
-
|
|
355
|
-
Returns: Promise<PaginatedResult<BrokerDataPosition[]>>
|
|
356
|
-
|
|
357
|
-
### Data Access (Get All - Convenience Methods)
|
|
358
|
-
|
|
359
|
-
#### `getAllAccounts(filter?)`
|
|
360
|
-
|
|
361
|
-
Returns all broker accounts across all pages.
|
|
362
|
-
|
|
363
|
-
- `filter` (object, optional): Filter parameters
|
|
364
|
-
|
|
365
|
-
Returns: Promise<BrokerDataAccount[]>
|
|
366
|
-
|
|
367
|
-
#### `getAllOrders(filter?)`
|
|
135
|
+
## Trading Operations
|
|
368
136
|
|
|
369
|
-
|
|
137
|
+
### General Order Placement
|
|
370
138
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
Returns: Promise<BrokerDataPosition[]>
|
|
382
|
-
|
|
383
|
-
### Convenience Methods
|
|
384
|
-
|
|
385
|
-
#### `getOpenPositions()`
|
|
386
|
-
|
|
387
|
-
Returns only open positions.
|
|
388
|
-
|
|
389
|
-
Returns: Promise<BrokerDataPosition[]>
|
|
390
|
-
|
|
391
|
-
#### `getFilledOrders()`
|
|
392
|
-
|
|
393
|
-
Returns only filled orders.
|
|
394
|
-
|
|
395
|
-
Returns: Promise<BrokerDataOrder[]>
|
|
396
|
-
|
|
397
|
-
#### `getPendingOrders()`
|
|
398
|
-
|
|
399
|
-
Returns only pending orders.
|
|
400
|
-
|
|
401
|
-
Returns: Promise<BrokerDataOrder[]>
|
|
402
|
-
|
|
403
|
-
#### `getActiveAccounts()`
|
|
404
|
-
|
|
405
|
-
Returns only active accounts.
|
|
406
|
-
|
|
407
|
-
Returns: Promise<BrokerDataAccount[]>
|
|
408
|
-
|
|
409
|
-
#### `getOrdersBySymbol(symbol)`
|
|
410
|
-
|
|
411
|
-
Returns orders for a specific symbol.
|
|
412
|
-
|
|
413
|
-
- `symbol` (string): Stock symbol
|
|
414
|
-
|
|
415
|
-
Returns: Promise<BrokerDataOrder[]>
|
|
416
|
-
|
|
417
|
-
#### `getPositionsBySymbol(symbol)`
|
|
418
|
-
|
|
419
|
-
Returns positions for a specific symbol.
|
|
420
|
-
|
|
421
|
-
- `symbol` (string): Stock symbol
|
|
422
|
-
|
|
423
|
-
Returns: Promise<BrokerDataPosition[]>
|
|
424
|
-
|
|
425
|
-
#### `getOrdersByBroker(brokerId)`
|
|
426
|
-
|
|
427
|
-
Returns orders for a specific broker.
|
|
139
|
+
```typescript
|
|
140
|
+
// Place a market order
|
|
141
|
+
const orderResponse = await finatic.placeOrder({
|
|
142
|
+
symbol: 'AAPL',
|
|
143
|
+
side: 'buy',
|
|
144
|
+
quantity: 10,
|
|
145
|
+
orderType: 'market',
|
|
146
|
+
timeInForce: 'day',
|
|
147
|
+
});
|
|
428
148
|
|
|
429
|
-
|
|
149
|
+
// Place a limit order
|
|
150
|
+
const limitOrderResponse = await finatic.placeOrder({
|
|
151
|
+
symbol: 'AAPL',
|
|
152
|
+
side: 'buy',
|
|
153
|
+
quantity: 10,
|
|
154
|
+
orderType: 'limit',
|
|
155
|
+
price: 150.0,
|
|
156
|
+
timeInForce: 'gtc',
|
|
157
|
+
});
|
|
158
|
+
```
|
|
430
159
|
|
|
431
|
-
|
|
160
|
+
### Asset-Specific Order Methods
|
|
432
161
|
|
|
433
|
-
####
|
|
162
|
+
#### Stock Orders
|
|
434
163
|
|
|
435
|
-
|
|
164
|
+
```typescript
|
|
165
|
+
// Stock market order
|
|
166
|
+
const response = await finatic.placeStockMarketOrder('AAPL', 10, 'buy', 'robinhood', '123456789');
|
|
167
|
+
|
|
168
|
+
// Stock limit order
|
|
169
|
+
const response = await finatic.placeStockLimitOrder(
|
|
170
|
+
'AAPL',
|
|
171
|
+
10,
|
|
172
|
+
'buy',
|
|
173
|
+
150.0,
|
|
174
|
+
'gtc',
|
|
175
|
+
'robinhood',
|
|
176
|
+
'123456789'
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
// Stock stop order
|
|
180
|
+
const response = await finatic.placeStockStopOrder(
|
|
181
|
+
'AAPL',
|
|
182
|
+
10,
|
|
183
|
+
'sell',
|
|
184
|
+
140.0,
|
|
185
|
+
'gtc',
|
|
186
|
+
'robinhood',
|
|
187
|
+
'123456789'
|
|
188
|
+
);
|
|
189
|
+
```
|
|
436
190
|
|
|
437
|
-
|
|
191
|
+
#### Crypto Orders
|
|
438
192
|
|
|
439
|
-
|
|
193
|
+
```typescript
|
|
194
|
+
// Crypto market order
|
|
195
|
+
const response = await finatic.placeCryptoMarketOrder(
|
|
196
|
+
'BTC-USD',
|
|
197
|
+
0.1,
|
|
198
|
+
'buy',
|
|
199
|
+
'coinbase',
|
|
200
|
+
'123456789'
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
// Crypto limit order
|
|
204
|
+
const response = await finatic.placeCryptoLimitOrder(
|
|
205
|
+
'BTC-USD',
|
|
206
|
+
0.1,
|
|
207
|
+
'buy',
|
|
208
|
+
50000.0,
|
|
209
|
+
'gtc',
|
|
210
|
+
'coinbase',
|
|
211
|
+
'123456789'
|
|
212
|
+
);
|
|
213
|
+
```
|
|
440
214
|
|
|
441
|
-
|
|
215
|
+
#### Options Orders
|
|
442
216
|
|
|
443
|
-
|
|
217
|
+
```typescript
|
|
218
|
+
// Options market order
|
|
219
|
+
const response = await finatic.placeOptionsMarketOrder(
|
|
220
|
+
'AAPL240315C00150000',
|
|
221
|
+
1,
|
|
222
|
+
'buy',
|
|
223
|
+
'tasty_trade',
|
|
224
|
+
'123456789'
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
// Options limit order
|
|
228
|
+
const response = await finatic.placeOptionsLimitOrder(
|
|
229
|
+
'AAPL240315C00150000',
|
|
230
|
+
1,
|
|
231
|
+
'buy',
|
|
232
|
+
5.0,
|
|
233
|
+
'gtc',
|
|
234
|
+
'tasty_trade',
|
|
235
|
+
'123456789'
|
|
236
|
+
);
|
|
237
|
+
```
|
|
444
238
|
|
|
445
|
-
|
|
239
|
+
#### Futures Orders
|
|
446
240
|
|
|
447
|
-
|
|
241
|
+
```typescript
|
|
242
|
+
// Futures market order
|
|
243
|
+
const response = await finatic.placeFuturesMarketOrder('ES', 1, 'buy', 'ninja_trader', '123456789');
|
|
244
|
+
|
|
245
|
+
// Futures limit order
|
|
246
|
+
const response = await finatic.placeFuturesLimitOrder(
|
|
247
|
+
'ES',
|
|
248
|
+
1,
|
|
249
|
+
'buy',
|
|
250
|
+
4500.0,
|
|
251
|
+
'gtc',
|
|
252
|
+
'ninja_trader',
|
|
253
|
+
'123456789'
|
|
254
|
+
);
|
|
255
|
+
```
|
|
448
256
|
|
|
449
|
-
|
|
257
|
+
### Order Management
|
|
450
258
|
|
|
451
|
-
|
|
259
|
+
```typescript
|
|
260
|
+
// Cancel an order
|
|
261
|
+
const response = await finatic.cancelOrder('order-123', 'robinhood', 'connection-456');
|
|
262
|
+
|
|
263
|
+
// Modify an order
|
|
264
|
+
const response = await finatic.modifyOrder(
|
|
265
|
+
'order-123',
|
|
266
|
+
{ price: 155.0, quantity: 5 },
|
|
267
|
+
'robinhood',
|
|
268
|
+
'connection-456'
|
|
269
|
+
);
|
|
270
|
+
```
|
|
452
271
|
|
|
453
|
-
|
|
272
|
+
## Broker Information
|
|
454
273
|
|
|
455
|
-
|
|
274
|
+
```typescript
|
|
275
|
+
// Get list of supported brokers
|
|
276
|
+
const brokers = await finatic.getBrokerList();
|
|
456
277
|
|
|
457
|
-
|
|
278
|
+
// Get broker connections
|
|
279
|
+
const connections = await finatic.getBrokerConnections();
|
|
458
280
|
|
|
459
|
-
|
|
281
|
+
// Disconnect a company from a broker connection
|
|
282
|
+
const disconnectResponse = await finatic.disconnectCompany('connection-uuid-here');
|
|
283
|
+
console.log('Disconnect action:', disconnectResponse.response_data.action);
|
|
284
|
+
```
|
|
460
285
|
|
|
461
|
-
|
|
286
|
+
## Authentication
|
|
462
287
|
|
|
463
|
-
|
|
288
|
+
```typescript
|
|
289
|
+
// Check authentication status
|
|
290
|
+
const isAuthenticated = finatic.isAuthed();
|
|
291
|
+
const isAuthenticatedAlt = finatic.is_authenticated();
|
|
464
292
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
- `response_data.remaining_companies` (number, optional): Number of remaining companies if connection still exists
|
|
468
|
-
- `response_data.message` (string): Human-readable message about the action taken
|
|
293
|
+
// Get user ID
|
|
294
|
+
const userId = finatic.getUserId();
|
|
469
295
|
|
|
470
|
-
|
|
296
|
+
// Set user ID (for returning users)
|
|
297
|
+
finatic.setUserId('user-123');
|
|
298
|
+
```
|
|
471
299
|
|
|
472
|
-
|
|
300
|
+
## Error Handling
|
|
473
301
|
|
|
474
|
-
|
|
302
|
+
```typescript
|
|
303
|
+
import { AuthenticationError, ApiError, ValidationError } from '@finatic/client';
|
|
475
304
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
305
|
+
try {
|
|
306
|
+
const orders = await finatic.getOrders();
|
|
307
|
+
} catch (error) {
|
|
308
|
+
if (error instanceof AuthenticationError) {
|
|
309
|
+
console.error('Authentication failed:', error.message);
|
|
310
|
+
} else if (error instanceof ValidationError) {
|
|
311
|
+
console.error('Invalid request:', error.message);
|
|
312
|
+
} else if (error instanceof ApiError) {
|
|
313
|
+
console.error('API error:', error.message);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
```
|
|
484
317
|
|
|
485
|
-
|
|
318
|
+
## Advanced Usage
|
|
486
319
|
|
|
487
|
-
|
|
320
|
+
### Custom Filters
|
|
488
321
|
|
|
489
|
-
|
|
490
|
-
|
|
322
|
+
```typescript
|
|
323
|
+
// Get orders with custom filters
|
|
324
|
+
const orders = await finatic.getOrders({
|
|
325
|
+
page: 1,
|
|
326
|
+
perPage: 50,
|
|
327
|
+
filter: {
|
|
328
|
+
status: 'filled',
|
|
329
|
+
symbol: 'AAPL',
|
|
330
|
+
broker: 'robinhood',
|
|
331
|
+
},
|
|
332
|
+
});
|
|
333
|
+
```
|
|
491
334
|
|
|
492
|
-
|
|
335
|
+
### Pagination Navigation
|
|
493
336
|
|
|
494
|
-
|
|
337
|
+
```typescript
|
|
338
|
+
// Get paginated results with navigation
|
|
339
|
+
const ordersPage = await finatic.getOrders({ page: 1, perPage: 100 });
|
|
495
340
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
341
|
+
// Navigate through pages
|
|
342
|
+
if (ordersPage.hasNext) {
|
|
343
|
+
const nextPage = await ordersPage.nextPage();
|
|
344
|
+
}
|
|
499
345
|
|
|
500
|
-
|
|
346
|
+
if (ordersPage.hasPrevious) {
|
|
347
|
+
const prevPage = await ordersPage.previousPage();
|
|
348
|
+
}
|
|
349
|
+
```
|
|
501
350
|
|
|
502
|
-
|
|
351
|
+
### Session Management
|
|
503
352
|
|
|
504
|
-
|
|
353
|
+
```typescript
|
|
354
|
+
// The SDK automatically manages sessions
|
|
355
|
+
// Sessions are kept alive for 24 hours by default
|
|
356
|
+
// No manual session management required
|
|
357
|
+
```
|
|
505
358
|
|
|
506
|
-
|
|
359
|
+
## Order and Position Detail Data
|
|
507
360
|
|
|
508
|
-
|
|
361
|
+
### Getting Order Fills
|
|
509
362
|
|
|
510
|
-
|
|
363
|
+
Order fills represent individual execution fills for an order:
|
|
511
364
|
|
|
512
|
-
|
|
365
|
+
```typescript
|
|
366
|
+
// Get fills for a specific order
|
|
367
|
+
const fills = await finatic.getOrderFills('order-123', {
|
|
368
|
+
connection_id: 'connection-456',
|
|
369
|
+
limit: 50,
|
|
370
|
+
offset: 0,
|
|
371
|
+
});
|
|
372
|
+
```
|
|
513
373
|
|
|
514
|
-
|
|
374
|
+
### Getting Order Events
|
|
515
375
|
|
|
516
|
-
|
|
376
|
+
Order events represent lifecycle events for an order:
|
|
517
377
|
|
|
518
|
-
|
|
378
|
+
```typescript
|
|
379
|
+
// Get events for a specific order
|
|
380
|
+
const events = await finatic.getOrderEvents('order-123', {
|
|
381
|
+
connection_id: 'connection-456',
|
|
382
|
+
limit: 100,
|
|
383
|
+
});
|
|
384
|
+
```
|
|
519
385
|
|
|
520
|
-
|
|
386
|
+
### Getting Order Groups
|
|
521
387
|
|
|
522
|
-
|
|
388
|
+
Order groups contain multiple related orders:
|
|
523
389
|
|
|
524
|
-
|
|
390
|
+
```typescript
|
|
391
|
+
// Get order groups with filters
|
|
392
|
+
const groups = await finatic.getOrderGroups({
|
|
393
|
+
broker_id: 'robinhood',
|
|
394
|
+
connection_id: 'connection-456',
|
|
395
|
+
created_after: '2024-01-01T00:00:00Z',
|
|
396
|
+
limit: 50,
|
|
397
|
+
});
|
|
398
|
+
```
|
|
525
399
|
|
|
526
|
-
|
|
400
|
+
### Getting Position Lots (Tax Lots)
|
|
527
401
|
|
|
528
|
-
|
|
402
|
+
Position lots are used for tax reporting and track when positions were opened/closed:
|
|
529
403
|
|
|
530
|
-
|
|
404
|
+
```typescript
|
|
405
|
+
// Get position lots for tax reporting
|
|
406
|
+
const lots = await finatic.getPositionLots({
|
|
407
|
+
broker_id: 'robinhood',
|
|
408
|
+
account_id: '123456789',
|
|
409
|
+
symbol: 'AAPL',
|
|
410
|
+
limit: 100,
|
|
411
|
+
});
|
|
412
|
+
```
|
|
531
413
|
|
|
532
|
-
|
|
414
|
+
### Getting Position Lot Fills
|
|
533
415
|
|
|
534
|
-
|
|
416
|
+
Position lot fills show the execution details for each lot:
|
|
535
417
|
|
|
536
|
-
|
|
418
|
+
```typescript
|
|
419
|
+
// Get fills for a specific position lot
|
|
420
|
+
const lotFills = await finatic.getPositionLotFills('lot-123', {
|
|
421
|
+
connection_id: 'connection-456',
|
|
422
|
+
limit: 50,
|
|
423
|
+
});
|
|
424
|
+
```
|
|
537
425
|
|
|
538
|
-
|
|
426
|
+
## Type Definitions
|
|
539
427
|
|
|
540
|
-
|
|
428
|
+
The SDK includes comprehensive TypeScript definitions for all data structures:
|
|
541
429
|
|
|
542
|
-
|
|
430
|
+
- `BrokerDataOrder`: Order information
|
|
431
|
+
- `BrokerDataPosition`: Position information
|
|
432
|
+
- `BrokerDataAccount`: Account information
|
|
433
|
+
- `BrokerBalance`: Balance information
|
|
434
|
+
- `BrokerInfo`: Broker information
|
|
435
|
+
- `BrokerConnection`: Connection information
|
|
436
|
+
- `OrderResponse`: Order operation responses
|
|
437
|
+
- `PaginatedResult`: Paginated data responses
|
|
438
|
+
- `OrderFill`: Order fill information
|
|
439
|
+
- `OrderEvent`: Order event information
|
|
440
|
+
- `OrderGroup`: Order group information
|
|
441
|
+
- `PositionLot`: Position lot (tax lot) information
|
|
442
|
+
- `PositionLotFill`: Position lot fill information
|
|
543
443
|
|
|
544
|
-
|
|
545
|
-
import {
|
|
546
|
-
ApiError,
|
|
547
|
-
SessionError,
|
|
548
|
-
AuthenticationError,
|
|
549
|
-
AuthorizationError,
|
|
550
|
-
RateLimitError,
|
|
551
|
-
CompanyAccessError,
|
|
552
|
-
} from '@finatic/client';
|
|
444
|
+
## Error Types
|
|
553
445
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
console.log('No broker connections found for this company');
|
|
559
|
-
} else if (error instanceof AuthenticationError) {
|
|
560
|
-
console.log('Authentication failed');
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
```
|
|
446
|
+
- `AuthenticationError`: Authentication failures
|
|
447
|
+
- `ApiError`: API request failures
|
|
448
|
+
- `ValidationError`: Invalid request parameters
|
|
449
|
+
- `ConnectionError`: Network connectivity issues
|
|
564
450
|
|
|
565
451
|
## Browser Support
|
|
566
452
|
|
|
567
|
-
|
|
453
|
+
- Chrome 80+
|
|
454
|
+
- Firefox 75+
|
|
455
|
+
- Safari 13+
|
|
456
|
+
- Edge 80+
|
|
457
|
+
|
|
458
|
+
## Requirements
|
|
568
459
|
|
|
569
|
-
-
|
|
570
|
-
-
|
|
571
|
-
- Promise support
|
|
572
|
-
- LocalStorage (for token caching)
|
|
460
|
+
- Modern browser with ES2018+ support
|
|
461
|
+
- No external dependencies
|
|
573
462
|
|
|
574
463
|
## License
|
|
575
464
|
|
|
576
|
-
MIT
|
|
465
|
+
MIT License
|