oilpriceapi 0.5.3 → 0.7.0

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 (49) hide show
  1. package/README.md +395 -110
  2. package/dist/client.d.ts +83 -3
  3. package/dist/client.js +118 -38
  4. package/dist/index.d.ts +31 -6
  5. package/dist/index.js +17 -3
  6. package/dist/resources/alerts.d.ts +52 -15
  7. package/dist/resources/alerts.js +143 -85
  8. package/dist/resources/analytics.d.ts +325 -0
  9. package/dist/resources/analytics.js +221 -0
  10. package/dist/resources/bunker-fuels.d.ts +270 -0
  11. package/dist/resources/bunker-fuels.js +191 -0
  12. package/dist/resources/commodities.d.ts +148 -0
  13. package/dist/resources/commodities.js +110 -0
  14. package/dist/resources/data-quality.d.ts +229 -0
  15. package/dist/resources/data-quality.js +139 -0
  16. package/dist/resources/data-sources.d.ts +365 -0
  17. package/dist/resources/data-sources.js +349 -0
  18. package/dist/resources/drilling.d.ts +403 -0
  19. package/dist/resources/drilling.js +264 -0
  20. package/dist/resources/ei/drilling-productivity.d.ts +173 -0
  21. package/dist/resources/ei/drilling-productivity.js +103 -0
  22. package/dist/resources/ei/forecasts.d.ts +177 -0
  23. package/dist/resources/ei/forecasts.js +101 -0
  24. package/dist/resources/ei/frac-focus.d.ts +212 -0
  25. package/dist/resources/ei/frac-focus.js +150 -0
  26. package/dist/resources/ei/index.d.ts +140 -0
  27. package/dist/resources/ei/index.js +87 -0
  28. package/dist/resources/ei/oil-inventories.d.ts +155 -0
  29. package/dist/resources/ei/oil-inventories.js +92 -0
  30. package/dist/resources/ei/opec-production.d.ts +146 -0
  31. package/dist/resources/ei/opec-production.js +92 -0
  32. package/dist/resources/ei/rig-counts.d.ts +131 -0
  33. package/dist/resources/ei/rig-counts.js +88 -0
  34. package/dist/resources/ei/well-permits.d.ts +178 -0
  35. package/dist/resources/ei/well-permits.js +119 -0
  36. package/dist/resources/forecasts.d.ts +200 -0
  37. package/dist/resources/forecasts.js +157 -0
  38. package/dist/resources/futures.d.ts +322 -0
  39. package/dist/resources/futures.js +228 -0
  40. package/dist/resources/rig-counts.d.ts +221 -0
  41. package/dist/resources/rig-counts.js +157 -0
  42. package/dist/resources/storage.d.ts +182 -0
  43. package/dist/resources/storage.js +161 -0
  44. package/dist/resources/webhooks.d.ts +290 -0
  45. package/dist/resources/webhooks.js +297 -0
  46. package/dist/types.d.ts +106 -6
  47. package/dist/version.d.ts +1 -1
  48. package/dist/version.js +1 -1
  49. package/package.json +3 -3
@@ -76,9 +76,9 @@ export class AlertsResource {
76
76
  * ```
77
77
  */
78
78
  async list() {
79
- const response = await this.client['request']('/v1/alerts', {});
79
+ const response = await this.client["request"]("/v1/alerts", {});
80
80
  // API returns array directly, but handle both formats for compatibility
81
- return Array.isArray(response) ? response : (response.alerts || []);
81
+ return Array.isArray(response) ? response : response.alerts || [];
82
82
  }
83
83
  /**
84
84
  * Get a specific price alert by ID
@@ -99,12 +99,12 @@ export class AlertsResource {
99
99
  * ```
100
100
  */
101
101
  async get(id) {
102
- if (!id || typeof id !== 'string') {
103
- throw new Error('Alert ID must be a non-empty string');
102
+ if (!id || typeof id !== "string") {
103
+ throw new Error("Alert ID must be a non-empty string");
104
104
  }
105
- const response = await this.client['request'](`/v1/alerts/${id}`, {});
105
+ const response = await this.client["request"](`/v1/alerts/${id}`, {});
106
106
  // API returns object directly, but handle both formats for compatibility
107
- return 'alert' in response ? response.alert : response;
107
+ return "alert" in response ? response.alert : response;
108
108
  }
109
109
  /**
110
110
  * Create a new price alert
@@ -145,57 +145,57 @@ export class AlertsResource {
145
145
  */
146
146
  async create(params) {
147
147
  // Validate required fields
148
- if (!params.name || typeof params.name !== 'string') {
149
- throw new Error('Alert name is required and must be a string');
148
+ if (!params.name || typeof params.name !== "string") {
149
+ throw new Error("Alert name is required and must be a string");
150
150
  }
151
151
  if (params.name.length < 1 || params.name.length > 100) {
152
- throw new Error('Alert name must be 1-100 characters');
152
+ throw new Error("Alert name must be 1-100 characters");
153
153
  }
154
- if (!params.commodity_code || typeof params.commodity_code !== 'string') {
155
- throw new Error('Commodity code is required and must be a string');
154
+ if (!params.commodity_code || typeof params.commodity_code !== "string") {
155
+ throw new Error("Commodity code is required and must be a string");
156
156
  }
157
157
  if (!params.condition_operator) {
158
- throw new Error('Condition operator is required');
158
+ throw new Error("Condition operator is required");
159
159
  }
160
160
  const validOperators = [
161
- 'greater_than',
162
- 'less_than',
163
- 'equals',
164
- 'greater_than_or_equal',
165
- 'less_than_or_equal'
161
+ "greater_than",
162
+ "less_than",
163
+ "equals",
164
+ "greater_than_or_equal",
165
+ "less_than_or_equal",
166
166
  ];
167
167
  if (!validOperators.includes(params.condition_operator)) {
168
- throw new Error(`Invalid operator. Must be one of: ${validOperators.join(', ')}`);
168
+ throw new Error(`Invalid operator. Must be one of: ${validOperators.join(", ")}`);
169
169
  }
170
- if (typeof params.condition_value !== 'number') {
171
- throw new Error('Condition value must be a number');
170
+ if (typeof params.condition_value !== "number") {
171
+ throw new Error("Condition value must be a number");
172
172
  }
173
173
  if (params.condition_value <= 0 || params.condition_value > 1000000) {
174
- throw new Error('Condition value must be greater than 0 and less than or equal to 1,000,000');
174
+ throw new Error("Condition value must be greater than 0 and less than or equal to 1,000,000");
175
175
  }
176
176
  // Validate optional fields
177
177
  if (params.webhook_url !== undefined) {
178
- if (typeof params.webhook_url !== 'string') {
179
- throw new Error('Webhook URL must be a string');
178
+ if (typeof params.webhook_url !== "string") {
179
+ throw new Error("Webhook URL must be a string");
180
180
  }
181
- if (params.webhook_url && !params.webhook_url.startsWith('https://')) {
182
- throw new Error('Webhook URL must use HTTPS protocol');
181
+ if (params.webhook_url && !params.webhook_url.startsWith("https://")) {
182
+ throw new Error("Webhook URL must use HTTPS protocol");
183
183
  }
184
184
  }
185
185
  if (params.cooldown_minutes !== undefined) {
186
- if (typeof params.cooldown_minutes !== 'number') {
187
- throw new Error('Cooldown minutes must be a number');
186
+ if (typeof params.cooldown_minutes !== "number") {
187
+ throw new Error("Cooldown minutes must be a number");
188
188
  }
189
189
  if (params.cooldown_minutes < 0 || params.cooldown_minutes > 1440) {
190
- throw new Error('Cooldown minutes must be between 0 and 1440 (24 hours)');
190
+ throw new Error("Cooldown minutes must be between 0 and 1440 (24 hours)");
191
191
  }
192
192
  }
193
- const url = `${this.client['baseUrl']}/v1/alerts`;
193
+ const url = `${this.client["baseUrl"]}/v1/alerts`;
194
194
  const response = await fetch(url, {
195
- method: 'POST',
195
+ method: "POST",
196
196
  headers: {
197
- 'Authorization': `Bearer ${this.client['apiKey']}`,
198
- 'Content-Type': 'application/json',
197
+ Authorization: `Bearer ${this.client["apiKey"]}`,
198
+ "Content-Type": "application/json",
199
199
  },
200
200
  body: JSON.stringify({
201
201
  price_alert: {
@@ -206,17 +206,17 @@ export class AlertsResource {
206
206
  webhook_url: params.webhook_url,
207
207
  enabled: params.enabled ?? true,
208
208
  cooldown_minutes: params.cooldown_minutes ?? 60,
209
- metadata: params.metadata
210
- }
211
- })
209
+ metadata: params.metadata,
210
+ },
211
+ }),
212
212
  });
213
213
  if (!response.ok) {
214
214
  const errorText = await response.text();
215
215
  throw new Error(`Failed to create alert: ${response.status} ${errorText}`);
216
216
  }
217
- const data = await response.json();
217
+ const data = (await response.json());
218
218
  // API returns object directly, but handle both formats for compatibility
219
- return 'alert' in data ? data.alert : data;
219
+ return "alert" in data ? data.alert : data;
220
220
  }
221
221
  /**
222
222
  * Update an existing price alert
@@ -250,65 +250,68 @@ export class AlertsResource {
250
250
  * ```
251
251
  */
252
252
  async update(id, params) {
253
- if (!id || typeof id !== 'string') {
254
- throw new Error('Alert ID must be a non-empty string');
253
+ if (!id || typeof id !== "string") {
254
+ throw new Error("Alert ID must be a non-empty string");
255
255
  }
256
256
  // Validate fields if provided
257
257
  if (params.name !== undefined) {
258
- if (typeof params.name !== 'string' || params.name.length < 1 || params.name.length > 100) {
259
- throw new Error('Alert name must be 1-100 characters');
258
+ if (typeof params.name !== "string" ||
259
+ params.name.length < 1 ||
260
+ params.name.length > 100) {
261
+ throw new Error("Alert name must be 1-100 characters");
260
262
  }
261
263
  }
262
264
  if (params.condition_operator !== undefined) {
263
265
  const validOperators = [
264
- 'greater_than',
265
- 'less_than',
266
- 'equals',
267
- 'greater_than_or_equal',
268
- 'less_than_or_equal'
266
+ "greater_than",
267
+ "less_than",
268
+ "equals",
269
+ "greater_than_or_equal",
270
+ "less_than_or_equal",
269
271
  ];
270
272
  if (!validOperators.includes(params.condition_operator)) {
271
- throw new Error(`Invalid operator. Must be one of: ${validOperators.join(', ')}`);
273
+ throw new Error(`Invalid operator. Must be one of: ${validOperators.join(", ")}`);
272
274
  }
273
275
  }
274
276
  if (params.condition_value !== undefined) {
275
- if (typeof params.condition_value !== 'number') {
276
- throw new Error('Condition value must be a number');
277
+ if (typeof params.condition_value !== "number") {
278
+ throw new Error("Condition value must be a number");
277
279
  }
278
280
  if (params.condition_value <= 0 || params.condition_value > 1000000) {
279
- throw new Error('Condition value must be greater than 0 and less than or equal to 1,000,000');
281
+ throw new Error("Condition value must be greater than 0 and less than or equal to 1,000,000");
280
282
  }
281
283
  }
282
284
  if (params.webhook_url !== undefined && params.webhook_url !== null) {
283
- if (typeof params.webhook_url !== 'string' || !params.webhook_url.startsWith('https://')) {
284
- throw new Error('Webhook URL must be a valid HTTPS URL');
285
+ if (typeof params.webhook_url !== "string" ||
286
+ !params.webhook_url.startsWith("https://")) {
287
+ throw new Error("Webhook URL must be a valid HTTPS URL");
285
288
  }
286
289
  }
287
290
  if (params.cooldown_minutes !== undefined) {
288
- if (typeof params.cooldown_minutes !== 'number' ||
291
+ if (typeof params.cooldown_minutes !== "number" ||
289
292
  params.cooldown_minutes < 0 ||
290
293
  params.cooldown_minutes > 1440) {
291
- throw new Error('Cooldown minutes must be between 0 and 1440 (24 hours)');
294
+ throw new Error("Cooldown minutes must be between 0 and 1440 (24 hours)");
292
295
  }
293
296
  }
294
- const url = `${this.client['baseUrl']}/v1/alerts/${id}`;
297
+ const url = `${this.client["baseUrl"]}/v1/alerts/${id}`;
295
298
  const response = await fetch(url, {
296
- method: 'PATCH',
299
+ method: "PATCH",
297
300
  headers: {
298
- 'Authorization': `Bearer ${this.client['apiKey']}`,
299
- 'Content-Type': 'application/json',
301
+ Authorization: `Bearer ${this.client["apiKey"]}`,
302
+ "Content-Type": "application/json",
300
303
  },
301
304
  body: JSON.stringify({
302
- price_alert: params
303
- })
305
+ price_alert: params,
306
+ }),
304
307
  });
305
308
  if (!response.ok) {
306
309
  const errorText = await response.text();
307
310
  throw new Error(`Failed to update alert: ${response.status} ${errorText}`);
308
311
  }
309
- const data = await response.json();
312
+ const data = (await response.json());
310
313
  // API returns object directly, but handle both formats for compatibility
311
- return 'alert' in data ? data.alert : data;
314
+ return "alert" in data ? data.alert : data;
312
315
  }
313
316
  /**
314
317
  * Delete a price alert
@@ -327,16 +330,16 @@ export class AlertsResource {
327
330
  * ```
328
331
  */
329
332
  async delete(id) {
330
- if (!id || typeof id !== 'string') {
331
- throw new Error('Alert ID must be a non-empty string');
333
+ if (!id || typeof id !== "string") {
334
+ throw new Error("Alert ID must be a non-empty string");
332
335
  }
333
- const url = `${this.client['baseUrl']}/v1/alerts/${id}`;
336
+ const url = `${this.client["baseUrl"]}/v1/alerts/${id}`;
334
337
  const response = await fetch(url, {
335
- method: 'DELETE',
338
+ method: "DELETE",
336
339
  headers: {
337
- 'Authorization': `Bearer ${this.client['apiKey']}`,
338
- 'Content-Type': 'application/json',
339
- }
340
+ Authorization: `Bearer ${this.client["apiKey"]}`,
341
+ "Content-Type": "application/json",
342
+ },
340
343
  });
341
344
  if (!response.ok) {
342
345
  const errorText = await response.text();
@@ -344,28 +347,83 @@ export class AlertsResource {
344
347
  }
345
348
  }
346
349
  /**
347
- * Test a webhook endpoint
350
+ * Test an alert
351
+ *
352
+ * Triggers a test run of the alert to verify it's working correctly.
353
+ * Does not affect the alert's cooldown or trigger count.
348
354
  *
349
- * **NOTE:** This feature is not yet available in the API. The `/v1/alerts/test_webhook`
350
- * endpoint has not been implemented yet. This method will throw an error until the
351
- * backend endpoint is added.
355
+ * @param alertId - The alert ID to test
356
+ * @returns Test results
357
+ *
358
+ * @throws {NotFoundError} If alert not found
359
+ * @throws {OilPriceAPIError} If API request fails
352
360
  *
353
- * To test if an alert would trigger, use the backend's `/v1/alerts/test` endpoint instead:
354
- * ```bash
355
- * curl -X POST "https://api.oilpriceapi.com/v1/alerts/:id/test" \
356
- * -H "Authorization: Bearer YOUR_API_KEY"
361
+ * @example
362
+ * ```typescript
363
+ * const result = await client.alerts.test(alertId);
364
+ * console.log(`Test ${result.success ? 'passed' : 'failed'}`);
365
+ * if (result.response_time_ms) {
366
+ * console.log(`Webhook response time: ${result.response_time_ms}ms`);
367
+ * }
357
368
  * ```
369
+ */
370
+ async test(alertId) {
371
+ if (!alertId || typeof alertId !== "string") {
372
+ throw new Error("Alert ID must be a non-empty string");
373
+ }
374
+ const url = `${this.client["baseUrl"]}/v1/alerts/${alertId}/test`;
375
+ const response = await fetch(url, {
376
+ method: "POST",
377
+ headers: {
378
+ Authorization: `Bearer ${this.client["apiKey"]}`,
379
+ "Content-Type": "application/json",
380
+ },
381
+ });
382
+ if (!response.ok) {
383
+ const errorText = await response.text();
384
+ throw new Error(`Failed to test alert: ${response.status} ${errorText}`);
385
+ }
386
+ return response.json();
387
+ }
388
+ /**
389
+ * Get available alert triggers
358
390
  *
359
- * @param webhookUrl - The HTTPS webhook URL to test
360
- * @returns Test results including response time and status
391
+ * Returns list of supported trigger conditions and event types.
361
392
  *
362
- * @throws {Error} Feature not yet available
393
+ * @returns Array of available triggers
363
394
  *
364
- * @deprecated This feature is not yet available in the API
395
+ * @throws {OilPriceAPIError} If API request fails
396
+ *
397
+ * @example
398
+ * ```typescript
399
+ * const triggers = await client.alerts.triggers();
400
+ * triggers.forEach(trigger => {
401
+ * console.log(`${trigger.name}: ${trigger.description}`);
402
+ * });
403
+ * ```
404
+ */
405
+ async triggers() {
406
+ const response = await this.client["request"]("/v1/alerts/triggers", {});
407
+ return Array.isArray(response) ? response : response.triggers;
408
+ }
409
+ /**
410
+ * Get alert analytics history
411
+ *
412
+ * Returns historical analytics data for alerts including trigger frequency,
413
+ * success rates, and response times.
414
+ *
415
+ * @returns Analytics history data
416
+ *
417
+ * @throws {OilPriceAPIError} If API request fails
418
+ *
419
+ * @example
420
+ * ```typescript
421
+ * const analytics = await client.alerts.analyticsHistory();
422
+ * console.log(`Total triggers: ${analytics.total_triggers}`);
423
+ * console.log(`Success rate: ${analytics.success_rate}%`);
424
+ * ```
365
425
  */
366
- async testWebhook(webhookUrl) {
367
- throw new Error('Webhook testing is not yet available. The /v1/alerts/test_webhook endpoint ' +
368
- 'has not been implemented in the API. To test if an alert would trigger, ' +
369
- 'use the /v1/alerts/:id/test endpoint instead.');
426
+ async analyticsHistory() {
427
+ return this.client["request"]("/v1/alerts/analytics_history", {});
370
428
  }
371
429
  }
@@ -0,0 +1,325 @@
1
+ /**
2
+ * Analytics Resource
3
+ *
4
+ * Access advanced analytics including performance metrics, statistical analysis,
5
+ * correlations, trend detection, spreads, and forecasts.
6
+ */
7
+ import type { OilPriceAPI } from "../client.js";
8
+ /**
9
+ * Performance metrics for commodities
10
+ */
11
+ export interface PerformanceMetrics {
12
+ /** Commodity code */
13
+ commodity?: string;
14
+ /** Time period analyzed (in days) */
15
+ period_days: number;
16
+ /** Average price over period */
17
+ average_price: number;
18
+ /** Price volatility (standard deviation) */
19
+ volatility: number;
20
+ /** Percentage return over period */
21
+ return_percent: number;
22
+ /** Highest price in period */
23
+ high: number;
24
+ /** Lowest price in period */
25
+ low: number;
26
+ /** ISO timestamp */
27
+ timestamp: string;
28
+ }
29
+ /**
30
+ * Options for performance query
31
+ */
32
+ export interface PerformanceOptions {
33
+ /** Commodity code to analyze */
34
+ commodity?: string;
35
+ /** Number of days to analyze (default: 30) */
36
+ days?: number;
37
+ }
38
+ /**
39
+ * Statistical analysis results
40
+ */
41
+ export interface StatisticalAnalysis {
42
+ /** Commodity code */
43
+ commodity: string;
44
+ /** Time period analyzed (in days) */
45
+ period_days: number;
46
+ /** Mean price */
47
+ mean: number;
48
+ /** Median price */
49
+ median: number;
50
+ /** Standard deviation */
51
+ std_dev: number;
52
+ /** Variance */
53
+ variance: number;
54
+ /** Minimum price */
55
+ min: number;
56
+ /** Maximum price */
57
+ max: number;
58
+ /** 25th percentile */
59
+ percentile_25?: number;
60
+ /** 75th percentile */
61
+ percentile_75?: number;
62
+ /** Skewness */
63
+ skewness?: number;
64
+ /** Kurtosis */
65
+ kurtosis?: number;
66
+ /** ISO timestamp */
67
+ timestamp: string;
68
+ }
69
+ /**
70
+ * Correlation analysis between two commodities
71
+ */
72
+ export interface CorrelationAnalysis {
73
+ /** First commodity code */
74
+ commodity1: string;
75
+ /** Second commodity code */
76
+ commodity2: string;
77
+ /** Time period analyzed (in days) */
78
+ period_days: number;
79
+ /** Pearson correlation coefficient (-1 to 1) */
80
+ correlation: number;
81
+ /** Correlation strength description */
82
+ strength?: "strong" | "moderate" | "weak" | "none";
83
+ /** R-squared value */
84
+ r_squared?: number;
85
+ /** ISO timestamp */
86
+ timestamp: string;
87
+ }
88
+ /**
89
+ * Trend analysis results
90
+ */
91
+ export interface TrendAnalysis {
92
+ /** Commodity code */
93
+ commodity: string;
94
+ /** Time period analyzed (in days) */
95
+ period_days: number;
96
+ /** Overall trend direction */
97
+ trend: "upward" | "downward" | "sideways";
98
+ /** Trend strength (0-100) */
99
+ strength: number;
100
+ /** Slope of trend line */
101
+ slope?: number;
102
+ /** Price momentum */
103
+ momentum?: number;
104
+ /** Support level */
105
+ support?: number;
106
+ /** Resistance level */
107
+ resistance?: number;
108
+ /** ISO timestamp */
109
+ timestamp: string;
110
+ }
111
+ /**
112
+ * Spread analysis between commodities
113
+ */
114
+ export interface SpreadAnalysis {
115
+ /** First commodity code */
116
+ commodity1: string;
117
+ /** Second commodity code */
118
+ commodity2: string;
119
+ /** Current spread (commodity1 - commodity2) */
120
+ spread: number;
121
+ /** Historical average spread */
122
+ average_spread?: number;
123
+ /** Spread standard deviation */
124
+ spread_volatility?: number;
125
+ /** Z-score of current spread */
126
+ z_score?: number;
127
+ /** ISO timestamp */
128
+ timestamp: string;
129
+ }
130
+ /**
131
+ * Forecast data point
132
+ */
133
+ export interface ForecastPoint {
134
+ /** Forecast date */
135
+ date: string;
136
+ /** Forecasted price */
137
+ price: number;
138
+ /** Lower bound of confidence interval */
139
+ lower_bound?: number;
140
+ /** Upper bound of confidence interval */
141
+ upper_bound?: number;
142
+ /** Confidence level (e.g., 0.95 for 95%) */
143
+ confidence?: number;
144
+ }
145
+ /**
146
+ * Price forecast
147
+ */
148
+ export interface PriceForecast {
149
+ /** Commodity code */
150
+ commodity: string;
151
+ /** Forecast model used */
152
+ model?: string;
153
+ /** Forecast horizon (days ahead) */
154
+ horizon_days: number;
155
+ /** Array of forecast points */
156
+ forecast: ForecastPoint[];
157
+ /** Model accuracy metrics */
158
+ accuracy?: {
159
+ /** Mean Absolute Percentage Error */
160
+ mape?: number;
161
+ /** Root Mean Squared Error */
162
+ rmse?: number;
163
+ };
164
+ /** ISO timestamp when forecast was generated */
165
+ timestamp: string;
166
+ }
167
+ /**
168
+ * Analytics Resource
169
+ *
170
+ * Access advanced analytics including performance metrics, statistical analysis,
171
+ * correlations, trends, spreads, and forecasts.
172
+ *
173
+ * @example
174
+ * ```typescript
175
+ * import { OilPriceAPI } from 'oilpriceapi';
176
+ *
177
+ * const client = new OilPriceAPI({ apiKey: 'your_key' });
178
+ *
179
+ * // Get performance metrics
180
+ * const perf = await client.analytics.performance({ commodity: 'WTI_USD', days: 30 });
181
+ * console.log(`30-day return: ${perf.return_percent}%`);
182
+ * console.log(`Volatility: ${perf.volatility}`);
183
+ *
184
+ * // Analyze correlation
185
+ * const corr = await client.analytics.correlation('WTI_USD', 'BRENT_CRUDE_USD', 90);
186
+ * console.log(`Correlation: ${corr.correlation}`);
187
+ * ```
188
+ */
189
+ export declare class AnalyticsResource {
190
+ private client;
191
+ constructor(client: OilPriceAPI);
192
+ /**
193
+ * Get performance metrics for a commodity
194
+ *
195
+ * Returns key performance indicators including returns, volatility,
196
+ * and price range over a specified period.
197
+ *
198
+ * @param options - Analysis parameters
199
+ * @returns Performance metrics
200
+ *
201
+ * @throws {OilPriceAPIError} If API request fails
202
+ *
203
+ * @example
204
+ * ```typescript
205
+ * const metrics = await client.analytics.performance({
206
+ * commodity: 'WTI_USD',
207
+ * days: 30
208
+ * });
209
+ * console.log(`Return: ${metrics.return_percent}%`);
210
+ * console.log(`Volatility: ${metrics.volatility}`);
211
+ * console.log(`High: $${metrics.high}, Low: $${metrics.low}`);
212
+ * ```
213
+ */
214
+ performance(options?: PerformanceOptions): Promise<PerformanceMetrics>;
215
+ /**
216
+ * Get statistical analysis for a commodity
217
+ *
218
+ * Returns comprehensive statistical metrics including mean, median,
219
+ * standard deviation, and distribution characteristics.
220
+ *
221
+ * @param commodity - Commodity code to analyze
222
+ * @param days - Number of days to analyze (default: 30)
223
+ * @returns Statistical analysis
224
+ *
225
+ * @throws {NotFoundError} If commodity not found
226
+ * @throws {OilPriceAPIError} If API request fails
227
+ *
228
+ * @example
229
+ * ```typescript
230
+ * const stats = await client.analytics.statistics('BRENT_CRUDE_USD', 90);
231
+ * console.log(`Mean: $${stats.mean}`);
232
+ * console.log(`Std Dev: ${stats.std_dev}`);
233
+ * console.log(`Range: $${stats.min} - $${stats.max}`);
234
+ * ```
235
+ */
236
+ statistics(commodity: string, days?: number): Promise<StatisticalAnalysis>;
237
+ /**
238
+ * Analyze correlation between two commodities
239
+ *
240
+ * Calculates the Pearson correlation coefficient to measure how closely
241
+ * two commodities move together.
242
+ *
243
+ * @param commodity1 - First commodity code
244
+ * @param commodity2 - Second commodity code
245
+ * @param days - Number of days to analyze (default: 30)
246
+ * @returns Correlation analysis
247
+ *
248
+ * @throws {NotFoundError} If either commodity not found
249
+ * @throws {OilPriceAPIError} If API request fails
250
+ *
251
+ * @example
252
+ * ```typescript
253
+ * const corr = await client.analytics.correlation('WTI_USD', 'BRENT_CRUDE_USD', 90);
254
+ * console.log(`Correlation: ${corr.correlation}`);
255
+ * console.log(`Strength: ${corr.strength}`);
256
+ * console.log(`R-squared: ${corr.r_squared}`);
257
+ * ```
258
+ */
259
+ correlation(commodity1: string, commodity2: string, days?: number): Promise<CorrelationAnalysis>;
260
+ /**
261
+ * Analyze price trend for a commodity
262
+ *
263
+ * Detects trend direction, strength, and key levels (support/resistance).
264
+ *
265
+ * @param commodity - Commodity code to analyze
266
+ * @param days - Number of days to analyze (default: 30)
267
+ * @returns Trend analysis
268
+ *
269
+ * @throws {NotFoundError} If commodity not found
270
+ * @throws {OilPriceAPIError} If API request fails
271
+ *
272
+ * @example
273
+ * ```typescript
274
+ * const trend = await client.analytics.trend('WTI_USD', 60);
275
+ * console.log(`Trend: ${trend.trend} (strength: ${trend.strength})`);
276
+ * console.log(`Support: $${trend.support}`);
277
+ * console.log(`Resistance: $${trend.resistance}`);
278
+ * ```
279
+ */
280
+ trend(commodity: string, days?: number): Promise<TrendAnalysis>;
281
+ /**
282
+ * Analyze spread between two commodities
283
+ *
284
+ * Calculates current spread and compares to historical patterns.
285
+ *
286
+ * @param commodity1 - First commodity code
287
+ * @param commodity2 - Second commodity code
288
+ * @returns Spread analysis
289
+ *
290
+ * @throws {NotFoundError} If either commodity not found
291
+ * @throws {OilPriceAPIError} If API request fails
292
+ *
293
+ * @example
294
+ * ```typescript
295
+ * const spread = await client.analytics.spread('BRENT_CRUDE_USD', 'WTI_USD');
296
+ * console.log(`Current spread: $${spread.spread}`);
297
+ * console.log(`Average spread: $${spread.average_spread}`);
298
+ * console.log(`Z-score: ${spread.z_score}`);
299
+ * ```
300
+ */
301
+ spread(commodity1: string, commodity2: string): Promise<SpreadAnalysis>;
302
+ /**
303
+ * Get price forecast for a commodity
304
+ *
305
+ * Returns forecasted prices with confidence intervals.
306
+ *
307
+ * @param commodity - Commodity code to forecast
308
+ * @returns Price forecast
309
+ *
310
+ * @throws {NotFoundError} If commodity not found
311
+ * @throws {OilPriceAPIError} If API request fails
312
+ *
313
+ * @example
314
+ * ```typescript
315
+ * const forecast = await client.analytics.forecast('WTI_USD');
316
+ * console.log(`Forecast model: ${forecast.model}`);
317
+ * console.log(`Horizon: ${forecast.horizon_days} days`);
318
+ *
319
+ * forecast.forecast.forEach(point => {
320
+ * console.log(`${point.date}: $${point.price} (${point.lower_bound}-${point.upper_bound})`);
321
+ * });
322
+ * ```
323
+ */
324
+ forecast(commodity: string): Promise<PriceForecast>;
325
+ }