laplace-api 4.0.0 → 4.2.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.
@@ -1,5 +1,5 @@
1
1
  import { Client } from './client';
2
- import { Stock } from './stocks';
2
+ import { HistoricalPricePeriod, PriceDataPoint, Stock } from './stocks';
3
3
 
4
4
  export enum CollectionType {
5
5
  Sector = 'sector',
@@ -42,52 +42,81 @@ export interface CollectionDetail extends Collection {
42
42
  stocks: Stock[];
43
43
  }
44
44
 
45
+ export interface CollectionPriceGraph {
46
+ previous_close: number;
47
+ graph: PriceDataPoint[];
48
+ }
49
+
45
50
  export class CollectionClient extends Client {
46
- private async getAllCollectionsPrivate(collectionType: CollectionType, region: Region, locale: Locale): Promise<Collection[]> {
51
+ async getAllSectors(region: Region, locale: Locale): Promise<Collection[]> {
47
52
  return this.sendRequest<Collection[]>({
48
53
  method: 'GET',
49
- url: `/api/v1/${collectionType}`,
54
+ url: `/api/v1/sector`,
50
55
  params: { region, locale },
51
56
  });
52
57
  }
53
-
54
- private async getCollectionDetailPrivate(id: string, collectionType: CollectionType, region: Region, locale: Locale): Promise<CollectionDetail> {
55
- return this.sendRequest<CollectionDetail>({
58
+
59
+ async getAllIndustries(region: Region, locale: Locale): Promise<Collection[]> {
60
+ return this.sendRequest<Collection[]>({
56
61
  method: 'GET',
57
- url: `/api/v1/${collectionType}/${id}`,
62
+ url: `/api/v1/industry`,
58
63
  params: { region, locale },
59
64
  });
60
65
  }
61
-
62
- async getAllSectors(region: Region, locale: Locale): Promise<Collection[]> {
63
- return this.getAllCollectionsPrivate(CollectionType.Sector, region, locale);
64
- }
65
-
66
- async getAllIndustries(region: Region, locale: Locale): Promise<Collection[]> {
67
- return this.getAllCollectionsPrivate(CollectionType.Industry, region, locale);
68
- }
69
-
66
+
70
67
  async getAllThemes(region: Region, locale: Locale): Promise<Collection[]> {
71
- return this.getAllCollectionsPrivate(CollectionType.Theme, region, locale);
68
+ return this.sendRequest<Collection[]>({
69
+ method: 'GET',
70
+ url: `/api/v1/theme`,
71
+ params: { region, locale },
72
+ });
72
73
  }
73
-
74
+
74
75
  async getAllCollections(region: Region, locale: Locale): Promise<Collection[]> {
75
- return this.getAllCollectionsPrivate(CollectionType.Collection, region, locale);
76
+ return this.sendRequest<Collection[]>({
77
+ method: 'GET',
78
+ url: `/api/v1/collection`,
79
+ params: { region, locale },
80
+ });
76
81
  }
77
-
82
+
78
83
  async getSectorDetail(id: string, region: Region, locale: Locale): Promise<CollectionDetail> {
79
- return this.getCollectionDetailPrivate(id, CollectionType.Sector, region, locale);
84
+ return this.sendRequest<CollectionDetail>({
85
+ method: 'GET',
86
+ url: `/api/v1/sector/${id}`,
87
+ params: { region, locale },
88
+ });
80
89
  }
81
-
90
+
82
91
  async getIndustryDetail(id: string, region: Region, locale: Locale): Promise<CollectionDetail> {
83
- return this.getCollectionDetailPrivate(id, CollectionType.Industry, region, locale);
92
+ return this.sendRequest<CollectionDetail>({
93
+ method: 'GET',
94
+ url: `/api/v1/industry/${id}`,
95
+ params: { region, locale },
96
+ });
84
97
  }
85
-
98
+
86
99
  async getThemeDetail(id: string, region: Region, locale: Locale): Promise<CollectionDetail> {
87
- return this.getCollectionDetailPrivate(id, CollectionType.Theme, region, locale);
100
+ return this.sendRequest<CollectionDetail>({
101
+ method: 'GET',
102
+ url: `/api/v1/theme/${id}`,
103
+ params: { region, locale },
104
+ });
88
105
  }
89
-
106
+
90
107
  async getCollectionDetail(id: string, region: Region, locale: Locale): Promise<CollectionDetail> {
91
- return this.getCollectionDetailPrivate(id, CollectionType.Collection, region, locale);
108
+ return this.sendRequest<CollectionDetail>({
109
+ method: 'GET',
110
+ url: `/api/v1/collection/${id}`,
111
+ params: { region, locale },
112
+ });
113
+ }
114
+
115
+ async getAggregateGraph(period: HistoricalPricePeriod, sectorId: string, industryId: string, collectionId: string, region: Region): Promise<CollectionPriceGraph> {
116
+ return this.sendRequest<CollectionPriceGraph>({
117
+ method: 'GET',
118
+ url: `/api/v1/aggregate/graph`,
119
+ params: { period, sectorId, industryId, collectionId, region },
120
+ });
92
121
  }
93
- }
122
+ }
@@ -75,13 +75,10 @@ export class FinancialFundamentalsClient extends Client {
75
75
  symbol: string,
76
76
  region: Region
77
77
  ): Promise<StockDividend[]> {
78
- const url = new URL(`${this["baseUrl"]}/api/v2/stock/dividends`);
79
- url.searchParams.append("symbol", symbol);
80
- url.searchParams.append("region", region);
81
-
82
78
  return this.sendRequest<StockDividend[]>({
83
79
  method: 'GET',
84
- url: url.toString(),
80
+ url: "/api/v2/stock/dividends",
81
+ params: { symbol, region }
85
82
  });
86
83
  }
87
84
 
@@ -3,7 +3,7 @@ import { Region, Locale } from "./collections";
3
3
 
4
4
  export enum RatioComparisonPeerType {
5
5
  Industry = "industry",
6
- Sector = "sector"
6
+ Sector = "sector",
7
7
  }
8
8
 
9
9
  export interface StockPeerFinancialRatioComparison {
@@ -43,79 +43,79 @@ export enum HistoricalRatiosFormat {
43
43
  }
44
44
 
45
45
  export enum HistoricalRatiosKey {
46
- Revenue = 'satislar',
47
- EBITDA = 'ebitda',
48
- NetProfit = 'net_kar',
49
- GrossMargin = 'gross-margin',
50
- NetMargin = 'net-margin',
51
- ReturnOnAssets = 'roa',
52
- ReturnOnEquity = 'roe',
53
- ReturnOnCapitalEmployed = 'roce',
54
- ReturnOnInvestedCapital = 'roic',
55
- PriceToEarningsRatio = 'pe-ratio',
56
- PriceToEarnings = 'poe',
57
- PriceToBookRatio = 'pb-ratio',
58
- EnterpriseValueToEBITDA = 'ev-to-ebitda',
59
- EnterpriseValueToInvestedCapital = 'evic',
60
- InterestCoverage = 'interestCoverage',
61
- QuickRatio = 'quick-ratio',
62
- LeverageRatio = 'leverage-ratio',
63
- DebtToEquity = 'debt-to-equity',
64
- RevenueGrowth = 'satis_buyumesi',
65
- EBITDAGrowth = 'favok_buyumesi',
66
- NetProfitGrowth = 'net_kar_buyumesi',
67
- FreeCashFlowGrowth = 'serbest_nakit_akisi_buyumesi',
68
- CashConversionCycle = 'cash-conversion-cycle',
69
- DaysSalesOutstanding = 'days-sales-outstanding',
70
- DaysPayable = 'days-payable',
71
- DaysInventory = 'days-inventory',
72
-
73
- EBITDAMargin = 'favok_marji',
74
- InventoryTurnover = 'inventory-turnover',
75
- DepositGrowth = 'mevduat_buyumesi',
76
- NetInterestMargin = 'net_faiz_marji',
77
- CompensationGrowth = 'gerceklesen_tazminatlar_buyumesi',
78
- PremiumPerCompensation = 'prim_basina_tazminat_orani',
79
- EnterpriseValueToOperatingCashFlow = 'evOcf',
80
- EarningsBeforeTax = 'ebt',
81
- CapitalExpenditure = 'capex',
82
- FinancialInvestments = 'financial_investments',
83
- RealtimeEarningsPerShare = 'realtime_eps-basic',
84
- RealtimeMarketValue = 'realtime_piyasa_degeri',
85
- RealtimePriceToBookRatio = 'realtime_pb-ratio',
86
- RealtimePriceToEarningsRatio = 'realtime_pe-ratio',
87
- CurrentRatio = 'current-ratio',
88
- AssetTurnover = 'asset-turnover',
89
- TotalOperationalExpense = 'total_operational_expense',
90
- TotalOperationalExpenseToGrossProfit = 'total_operational_expense_gross_profit_ratio',
91
- CashAndCashEquivalents = 'cash_and_cash_equivalents',
92
- CashToAssets = 'cash_to_assets',
93
- CapexToNetProfit = 'capex_to_net_profit',
94
- RealtimeEnterpriseValueToEBITDA = 'realtime_ev-to-ebitda',
95
- ReceivablesTurnover = 'alacak_devir_hizi',
96
- EarningsPerShare = 'eps-basic',
97
- CreditToAssetRatio = 'kredi_aktif_orani',
98
- CreditToDepositRatio = 'kredi_mevduat_orani',
99
- TechnicalProfitGrowth = 'teknik_kar_buyumesi',
100
- NetEarnedPremiumGrowth = 'net_kazanilan_prim_buyumesi',
101
- EBITGrowth = 'ebitGrowth',
102
- CashReturnOnInvestedCapital = 'croic',
103
- MarketCapitalization = 'piyasa_degeri',
104
- ShortTermToLongTermObligations = 'short_term_obligations_long_term_obligations',
105
- RetainedEarnings = 'retained_earnings',
106
- ThreeYearCAGRFreeCashFlow = 'three_year_cagr_free_cash_flow',
107
- LongTermLoansToPeriodicProfitRatio = 'long_term_loans_period_profit_ratio',
108
- LongTermLoans = 'long_term_loans',
109
- CommercialReceivablesToTotalCurrentAssets = 'commercial_receivables_total_current_assets',
110
- StockGrowth = 'stock_growth',
111
- FiveYearRetainedEarningsChange = 'five_year_retained_earnings_change',
112
- ThreeYearCAGRRetainedEarnings = 'three_year_cagr_retained_earnings',
113
- PotentialOperatingCashFlow = 'pocf',
114
- FreeCashFlowToEnterpriseValue = 'fcfEv',
115
- DebtToDeposit = 'dd',
116
- NetDebt = 'net_borc',
117
- PaidCapital = 'odenmis_sermaye',
118
- FinancialExpensesToEBIT = 'financial_expenses_ebit_ratio'
46
+ Revenue = "satislar",
47
+ EBITDA = "ebitda",
48
+ NetProfit = "net_kar",
49
+ GrossMargin = "gross-margin",
50
+ NetMargin = "net-margin",
51
+ ReturnOnAssets = "roa",
52
+ ReturnOnEquity = "roe",
53
+ ReturnOnCapitalEmployed = "roce",
54
+ ReturnOnInvestedCapital = "roic",
55
+ PriceToEarningsRatio = "pe-ratio",
56
+ PriceToEarnings = "poe",
57
+ PriceToBookRatio = "pb-ratio",
58
+ EnterpriseValueToEBITDA = "ev-to-ebitda",
59
+ EnterpriseValueToInvestedCapital = "evic",
60
+ InterestCoverage = "interestCoverage",
61
+ QuickRatio = "quick-ratio",
62
+ LeverageRatio = "leverage-ratio",
63
+ DebtToEquity = "debt-to-equity",
64
+ RevenueGrowth = "satis_buyumesi",
65
+ EBITDAGrowth = "favok_buyumesi",
66
+ NetProfitGrowth = "net_kar_buyumesi",
67
+ FreeCashFlowGrowth = "serbest_nakit_akisi_buyumesi",
68
+ CashConversionCycle = "cash-conversion-cycle",
69
+ DaysSalesOutstanding = "days-sales-outstanding",
70
+ DaysPayable = "days-payable",
71
+ DaysInventory = "days-inventory",
72
+
73
+ EBITDAMargin = "favok_marji",
74
+ InventoryTurnover = "inventory-turnover",
75
+ DepositGrowth = "mevduat_buyumesi",
76
+ NetInterestMargin = "net_faiz_marji",
77
+ CompensationGrowth = "gerceklesen_tazminatlar_buyumesi",
78
+ PremiumPerCompensation = "prim_basina_tazminat_orani",
79
+ EnterpriseValueToOperatingCashFlow = "evOcf",
80
+ EarningsBeforeTax = "ebt",
81
+ CapitalExpenditure = "capex",
82
+ FinancialInvestments = "financial_investments",
83
+ RealtimeEarningsPerShare = "realtime_eps-basic",
84
+ RealtimeMarketValue = "realtime_piyasa_degeri",
85
+ RealtimePriceToBookRatio = "realtime_pb-ratio",
86
+ RealtimePriceToEarningsRatio = "realtime_pe-ratio",
87
+ CurrentRatio = "current-ratio",
88
+ AssetTurnover = "asset-turnover",
89
+ TotalOperationalExpense = "total_operational_expense",
90
+ TotalOperationalExpenseToGrossProfit = "total_operational_expense_gross_profit_ratio",
91
+ CashAndCashEquivalents = "cash_and_cash_equivalents",
92
+ CashToAssets = "cash_to_assets",
93
+ CapexToNetProfit = "capex_to_net_profit",
94
+ RealtimeEnterpriseValueToEBITDA = "realtime_ev-to-ebitda",
95
+ ReceivablesTurnover = "alacak_devir_hizi",
96
+ EarningsPerShare = "eps-basic",
97
+ CreditToAssetRatio = "kredi_aktif_orani",
98
+ CreditToDepositRatio = "kredi_mevduat_orani",
99
+ TechnicalProfitGrowth = "teknik_kar_buyumesi",
100
+ NetEarnedPremiumGrowth = "net_kazanilan_prim_buyumesi",
101
+ EBITGrowth = "ebitGrowth",
102
+ CashReturnOnInvestedCapital = "croic",
103
+ MarketCapitalization = "piyasa_degeri",
104
+ ShortTermToLongTermObligations = "short_term_obligations_long_term_obligations",
105
+ RetainedEarnings = "retained_earnings",
106
+ ThreeYearCAGRFreeCashFlow = "three_year_cagr_free_cash_flow",
107
+ LongTermLoansToPeriodicProfitRatio = "long_term_loans_period_profit_ratio",
108
+ LongTermLoans = "long_term_loans",
109
+ CommercialReceivablesToTotalCurrentAssets = "commercial_receivables_total_current_assets",
110
+ StockGrowth = "stock_growth",
111
+ FiveYearRetainedEarningsChange = "five_year_retained_earnings_change",
112
+ ThreeYearCAGRRetainedEarnings = "three_year_cagr_retained_earnings",
113
+ PotentialOperatingCashFlow = "pocf",
114
+ FreeCashFlowToEnterpriseValue = "fcfEv",
115
+ DebtToDeposit = "dd",
116
+ NetDebt = "net_borc",
117
+ PaidCapital = "odenmis_sermaye",
118
+ FinancialExpensesToEBIT = "financial_expenses_ebit_ratio",
119
119
  }
120
120
 
121
121
  export interface StockHistoricalRatiosDescription {
@@ -148,21 +148,21 @@ export interface HistoricalFinancialSheetRow {
148
148
  }
149
149
 
150
150
  export enum FinancialSheetType {
151
- IncomeStatement = 'incomeStatement',
152
- BalanceSheet = 'balanceSheet',
153
- CashFlow = 'cashFlowStatement',
151
+ IncomeStatement = "incomeStatement",
152
+ BalanceSheet = "balanceSheet",
153
+ CashFlow = "cashFlowStatement",
154
154
  }
155
155
 
156
156
  export enum FinancialSheetPeriod {
157
- Annual = 'annual',
158
- Quarterly = 'quarterly',
159
- Cumulative = 'cumulative',
157
+ Annual = "annual",
158
+ Quarterly = "quarterly",
159
+ Cumulative = "cumulative",
160
160
  }
161
161
 
162
162
  export enum Currency {
163
- USD = 'USD',
164
- TRY = 'TRY',
165
- EUR = 'EUR',
163
+ USD = "USD",
164
+ TRY = "TRY",
165
+ EUR = "EUR",
166
166
  }
167
167
 
168
168
  export interface FinancialSheetDate {
@@ -203,7 +203,7 @@ export class FinancialClient extends Client {
203
203
  url.searchParams.append("slugs", keys.join(","));
204
204
 
205
205
  return this.sendRequest<StockHistoricalRatios[]>({
206
- method: 'GET',
206
+ method: "GET",
207
207
  url: url.toString(),
208
208
  });
209
209
  }
@@ -219,7 +219,7 @@ export class FinancialClient extends Client {
219
219
  url.searchParams.append("region", region);
220
220
 
221
221
  return this.sendRequest<StockHistoricalRatiosDescription[]>({
222
- method: 'GET',
222
+ method: "GET",
223
223
  url: url.toString(),
224
224
  });
225
225
  }
@@ -233,18 +233,37 @@ export class FinancialClient extends Client {
233
233
  currency: Currency,
234
234
  region: Region
235
235
  ): Promise<HistoricalFinancialSheets> {
236
- const url = new URL(`${this['baseUrl']}/api/v2/stock/historical-financial-sheets`);
237
- url.searchParams.append('symbol', symbol);
238
- url.searchParams.append('from', `${from.year.toString().padStart(4, '0')}-${from.month.toString().padStart(2, '0')}-${from.day.toString().padStart(2, '0')}`);
239
- url.searchParams.append('to', `${to.year.toString().padStart(4, '0')}-${to.month.toString().padStart(2, '0')}-${to.day.toString().padStart(2, '0')}`);
240
- url.searchParams.append('sheetType', sheetType);
241
- url.searchParams.append('periodType', period);
242
- url.searchParams.append('currency', currency);
243
- url.searchParams.append('region', region);
236
+ const url = new URL(
237
+ `${this["baseUrl"]}/api/v3/stock/historical-financial-sheets`
238
+ );
239
+ url.searchParams.append("symbol", symbol);
240
+ url.searchParams.append(
241
+ "from",
242
+ `${from.year.toString().padStart(4, "0")}-${from.month
243
+ .toString()
244
+ .padStart(2, "0")}-${from.day.toString().padStart(2, "0")}`
245
+ );
246
+ url.searchParams.append(
247
+ "to",
248
+ `${to.year.toString().padStart(4, "0")}-${to.month
249
+ .toString()
250
+ .padStart(2, "0")}-${to.day.toString().padStart(2, "0")}`
251
+ );
252
+ url.searchParams.append("sheetType", sheetType);
253
+ url.searchParams.append("periodType", period);
254
+ url.searchParams.append("currency", currency);
255
+ url.searchParams.append("region", region);
256
+
257
+ if (
258
+ sheetType === FinancialSheetType.BalanceSheet &&
259
+ period !== FinancialSheetPeriod.Cumulative
260
+ ) {
261
+ throw new Error("balance sheet is only available for cumulative period");
262
+ }
244
263
 
245
264
  return this.sendRequest<HistoricalFinancialSheets>({
246
- method: 'GET',
265
+ method: "GET",
247
266
  url: url.toString(),
248
267
  });
249
268
  }
250
- }
269
+ }
@@ -1,4 +1,3 @@
1
-
2
1
  interface RawBISTStockLiveData {
3
2
  _id: number;
4
3
  symbol: string;
@@ -99,7 +98,10 @@ export class LivePriceWebSocketClient {
99
98
  feed: LivePriceFeed;
100
99
  }
101
100
  >();
102
- private symbolLastData = new Map<string, BISTStockLiveData | USStockLiveData>();
101
+ private symbolLastData = new Map<
102
+ string,
103
+ BISTStockLiveData | USStockLiveData
104
+ >();
103
105
  private reconnectAttempts = 0;
104
106
  private reconnectTimeout: NodeJS.Timeout | null = null;
105
107
  private isClosed: boolean = false;
@@ -110,8 +112,16 @@ export class LivePriceWebSocketClient {
110
112
  private lastMessageTimestamp: number = 0;
111
113
  private inactivityCheckInterval: NodeJS.Timeout | null = null;
112
114
  private readonly INACTIVITY_TIMEOUT = 15000;
115
+ private externalUserId: string | null = null;
116
+ private feeds: LivePriceFeed[] | null = null;
113
117
 
114
- constructor(options: WebSocketOptions = {}) {
118
+ constructor(
119
+ feeds: LivePriceFeed[],
120
+ externalUserId: string,
121
+ options: WebSocketOptions = {}
122
+ ) {
123
+ this.feeds = feeds;
124
+ this.externalUserId = externalUserId;
115
125
  this.options = {
116
126
  enableLogging: true,
117
127
  logLevel: LogLevel.Error,
@@ -128,17 +138,17 @@ export class LivePriceWebSocketClient {
128
138
  clearInterval(this.inactivityCheckInterval);
129
139
  this.inactivityCheckInterval = null;
130
140
  }
131
-
132
- this.inactivityCheckInterval = setInterval(async ()=> {
141
+
142
+ this.inactivityCheckInterval = setInterval(async () => {
133
143
  if (Date.now() - this.lastMessageTimestamp >= this.INACTIVITY_TIMEOUT) {
134
144
  this.stopInactivityInterval();
135
145
  try {
136
146
  this.attemptReconnect();
137
- } catch(error) {
147
+ } catch (error) {
138
148
  this.log(`Failed to reconnect: ${error}`, "error");
139
149
  }
140
150
  }
141
- }, this.INACTIVITY_TIMEOUT)
151
+ }, this.INACTIVITY_TIMEOUT);
142
152
  }
143
153
 
144
154
  private stopInactivityInterval() {
@@ -177,10 +187,14 @@ export class LivePriceWebSocketClient {
177
187
 
178
188
  async connect(url: string): Promise<WebSocket> {
179
189
  this.log("Connecting to WebSocket...");
190
+ if (!this.externalUserId || !this.feeds) {
191
+ throw new Error("External user ID and feeds are required");
192
+ }
193
+
180
194
  this.wsUrl = url;
181
195
 
182
196
  if (!this.ws || this.ws.readyState === WebSocket.CLOSED) {
183
- this.ws = new WebSocket(url);
197
+ this.ws = new WebSocket(this.wsUrl);
184
198
  this.connectPromise = this.setupWebSocket();
185
199
 
186
200
  await this.connectPromise;
@@ -419,7 +433,8 @@ export class LivePriceWebSocketClient {
419
433
  if (symbolHandlers.length === 1) {
420
434
  symbolsToAdd.push(symbol);
421
435
  } else if (symbolHandlers.length > 1) {
422
- const lastData: BISTStockLiveData | USStockLiveData | undefined = this.symbolLastData.get(symbol);
436
+ const lastData: BISTStockLiveData | USStockLiveData | undefined =
437
+ this.symbolLastData.get(symbol);
423
438
  if (lastData) {
424
439
  typedHandler(lastData);
425
440
  }