diff --git a/docs/README.md b/docs/README.md index 1067206..7495554 100644 --- a/docs/README.md +++ b/docs/README.md @@ -511,7 +511,7 @@ Copied from [/developer/docs/stable#bulk](https://site.financialmodelingprep.com | ❌️ | - | `/price-target-summary-bulk` | | ❌️ | - | `/etf-holder-bulk` | | ❌️ | - | `/upgrades-downgrades-consensus-bulk` | -| ❌️ | - | `/key-metrics-ttm-bulk` | +| ✅️ | - | `/key-metrics-ttm-bulk` | | ❌️ | - | `/ratios-ttm-bulk` | | ❌️ | - | `/ratios-ttm-bulk` | | ❌️ | - | `/peers-bulk` | diff --git a/src/main/java/com/marketdataapi/fmp4j/clients/FmpBulkClient.java b/src/main/java/com/marketdataapi/fmp4j/clients/FmpBulkClient.java index 655f8e7..1528417 100644 --- a/src/main/java/com/marketdataapi/fmp4j/clients/FmpBulkClient.java +++ b/src/main/java/com/marketdataapi/fmp4j/clients/FmpBulkClient.java @@ -9,10 +9,12 @@ import com.marketdataapi.fmp4j.models.FmpCashFlowStatement; import com.marketdataapi.fmp4j.models.FmpCashFlowStatementGrowth; import com.marketdataapi.fmp4j.models.FmpCompanies; +import com.marketdataapi.fmp4j.models.FmpKeyMetricTtm; import com.marketdataapi.fmp4j.services.FmpBulkBalanceSheetStatementService; import com.marketdataapi.fmp4j.services.FmpBulkCashFlowStatementGrowthService; import com.marketdataapi.fmp4j.services.FmpBulkCashFlowStatementService; import com.marketdataapi.fmp4j.services.FmpBulkCompaniesService; +import com.marketdataapi.fmp4j.services.FmpBulkKeyMetricTtmService; import com.marketdataapi.fmp4j.services.FmpService; import com.marketdataapi.fmp4j.types.FmpPart; import com.marketdataapi.fmp4j.types.FmpPeriod; @@ -26,6 +28,7 @@ public class FmpBulkClient { protected final FmpService fmpBulkBalanceSheetService; protected final FmpService fmpBulkCashFlowService; protected final FmpService fmpBulkCashFlowStatementGrowthService; + protected final FmpService fmpBulkKeyMetricTtmService; public FmpBulkClient(FmpConfig fmpConfig, FmpHttpClient fmpHttpClient) { this.fmpBulkCompaniesService = new FmpBulkCompaniesService(fmpConfig, fmpHttpClient); @@ -33,6 +36,7 @@ public FmpBulkClient(FmpConfig fmpConfig, FmpHttpClient fmpHttpClient) { this.fmpBulkCashFlowService = new FmpBulkCashFlowStatementService(fmpConfig, fmpHttpClient); this.fmpBulkCashFlowStatementGrowthService = new FmpBulkCashFlowStatementGrowthService(fmpConfig, fmpHttpClient); + this.fmpBulkKeyMetricTtmService = new FmpBulkKeyMetricTtmService(fmpConfig, fmpHttpClient); } public synchronized List companies(FmpPart part) { @@ -57,4 +61,8 @@ public synchronized List cashFlowStatementGrowth(Fmp fmpBulkCashFlowStatementGrowthService.param(PARAM_PERIOD, period); return fmpBulkCashFlowStatementGrowthService.download(); } + + public synchronized List keyMetricsTtm() { + return fmpBulkKeyMetricTtmService.download(); + } } diff --git a/src/main/java/com/marketdataapi/fmp4j/services/FmpBulkKeyMetricTtmService.java b/src/main/java/com/marketdataapi/fmp4j/services/FmpBulkKeyMetricTtmService.java new file mode 100644 index 0000000..fdb6cf6 --- /dev/null +++ b/src/main/java/com/marketdataapi/fmp4j/services/FmpBulkKeyMetricTtmService.java @@ -0,0 +1,32 @@ +package com.marketdataapi.fmp4j.services; + +import com.marketdataapi.fmp4j.cfg.FmpConfig; +import com.marketdataapi.fmp4j.http.FmpHttpClient; +import com.marketdataapi.fmp4j.models.FmpKeyMetricTtm; +import java.util.Map; + +public class FmpBulkKeyMetricTtmService extends FmpService { + public FmpBulkKeyMetricTtmService(FmpConfig cfg, FmpHttpClient http) { + super(cfg, http, FmpKeyMetricTtm.class); + } + + @Override + protected String relativeUrl() { + return "/key-metrics-ttm-bulk"; + } + + @Override + protected Map> requiredParams() { + return Map.of(); + } + + @Override + protected Map> optionalParams() { + return Map.of(); + } + + @Override + protected Map headers() { + return Map.of("Content-Type", "text/csv"); + } +} diff --git a/src/test/java/com/marketdataapi/fmp4j/FmpClientTest.java b/src/test/java/com/marketdataapi/fmp4j/FmpClientTest.java index 89e771c..6142ca4 100644 --- a/src/test/java/com/marketdataapi/fmp4j/FmpClientTest.java +++ b/src/test/java/com/marketdataapi/fmp4j/FmpClientTest.java @@ -757,6 +757,20 @@ void keyMetrics(String p) { assertValidResult(result, limit.value(), FmpKeyMetric.class); } + @Test + void key_metrics_ttm_bulk() { + // given + var endpoint = "key-metrics-ttm-bulk"; + var file = format("stable/%s/excerpt.csv", endpoint); + + // when + mockHttpGetFromFile(file); + var result = fmpClient.bulk().keyMetricsTtm(); + + // then + assertValidResult(result, 2, FmpKeyMetricTtm.class); + } + @Test void key_metrics_ttm() { // given diff --git a/src/test/java/com/marketdataapi/fmp4j/services/FmpBulkKeyMetricTtmServiceTest.java b/src/test/java/com/marketdataapi/fmp4j/services/FmpBulkKeyMetricTtmServiceTest.java new file mode 100644 index 0000000..f61a5f7 --- /dev/null +++ b/src/test/java/com/marketdataapi/fmp4j/services/FmpBulkKeyMetricTtmServiceTest.java @@ -0,0 +1,63 @@ +package com.marketdataapi.fmp4j.services; + +import static com.marketdataapi.fmp4j.TestUtils.assertAllFieldsNonNull; +import static com.marketdataapi.fmp4j.TestUtils.testResource; +import static java.util.stream.IntStream.range; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.marketdataapi.fmp4j.models.FmpKeyMetricTtm; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class FmpBulkKeyMetricTtmServiceTest extends HttpTest { + private FmpService service; + + @BeforeEach + void setup() { + service = new FmpBulkKeyMetricTtmService(config, client); + } + + @Test + void relative_url() { + // given // when + var relativeUrl = service.relativeUrl(); + + // then + assertEquals("/key-metrics-ttm-bulk", relativeUrl); + } + + @Test + void required_params() { + // given // when + var params = service.requiredParams(); + + // then + assertEquals(Map.of(), params); + } + + @Test + void optional_params() { + // given // when + var params = service.optionalParams(); + + // then + assertEquals(Map.of(), params); + } + + @Test + void successful_download() { + // given + httpStub.configureResponse() + .body(testResource("stable/key-metrics-ttm-bulk/excerpt.csv")) + .statusCode(200) + .apply(); + + // when + var result = service.download(); + + // then + assertEquals(2, result.size()); + range(0, result.size()).forEach(i -> assertAllFieldsNonNull(result.get(i))); + } +} diff --git a/src/testFixtures/resources/stable/key-metrics-ttm-bulk/excerpt.csv b/src/testFixtures/resources/stable/key-metrics-ttm-bulk/excerpt.csv new file mode 100644 index 0000000..08b3971 --- /dev/null +++ b/src/testFixtures/resources/stable/key-metrics-ttm-bulk/excerpt.csv @@ -0,0 +1,3 @@ +"symbol","marketCap","enterpriseValueTTM","evToSalesTTM","evToOperatingCashFlowTTM","evToFreeCashFlowTTM","evToEBITDATTM","netDebtToEBITDATTM","currentRatioTTM","incomeQualityTTM","grahamNumberTTM","grahamNetNetTTM","taxBurdenTTM","interestBurdenTTM","workingCapitalTTM","investedCapitalTTM","returnOnAssetsTTM","operatingReturnOnAssetsTTM","returnOnTangibleAssetsTTM","returnOnEquityTTM","returnOnInvestedCapitalTTM","returnOnCapitalEmployedTTM","earningsYieldTTM","freeCashFlowYieldTTM","capexToOperatingCashFlowTTM","capexToDepreciationTTM","capexToRevenueTTM","salesGeneralAndAdministrativeToRevenueTTM","researchAndDevelopementToRevenueTTM","stockBasedCompensationToRevenueTTM","intangiblesToTotalAssetsTTM","averageReceivablesTTM","averagePayablesTTM","averageInventoryTTM","daysOfSalesOutstandingTTM","daysOfPayablesOutstandingTTM","daysOfInventoryOutstandingTTM","operatingCycleTTM","cashConversionCycleTTM","freeCashFlowToEquityTTM","freeCashFlowToFirmTTM","tangibleAssetValueTTM","netCurrentAssetValueTTM" +"AAPL",2800000000000,2700000000000,7.5,12.3,15.2,20.5,0.8,1.2,1.1,45.2,-5.3,0.85,0.95,50000000000,1500000000000,0.25,0.30,0.28,0.45,0.35,0.40,0.12,0.08,0.15,0.5,0.03,0.05,0.08,0.01,0.02,30000000000,25000000000,15000000000,12,15,20,32,17,80000000000,90000000000,200000000000,180000000000 +"GOOGL",2000000000000,1900000000000,6.8,15.1,18.5,22.3,0.6,1.3,1.2,38.7,-8.2,0.88,0.92,60000000000,1200000000000,0.22,0.28,0.25,0.38,0.30,0.35,0.10,0.07,0.12,0.4,0.02,0.04,0.07,0.01,0.01,25000000000,20000000000,10000000000,10,12,18,28,16,70000000000,80000000000,150000000000,140000000000