artesian-sdk 4.0.3.dev14__tar.gz → 4.1.1.dev5__tar.gz

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 (119) hide show
  1. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/PKG-INFO +163 -2
  2. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/README.md +160 -0
  3. artesian_sdk-4.1.1.dev5/src/Artesian/MarketData/CommonUnitOfMeasure.py +17 -0
  4. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/MarketDataService.py +56 -0
  5. artesian_sdk-4.1.1.dev5/src/Artesian/MarketData/_Dto/CheckConversionResult.py +19 -0
  6. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Dto/MarketDataEntityInput.py +2 -0
  7. artesian_sdk-4.1.1.dev5/src/Artesian/MarketData/_Dto/UnitOfMeasure.py +15 -0
  8. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Dto/__init__.py +4 -0
  9. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/__init__.py +6 -0
  10. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/ActualQuery.py +33 -0
  11. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/VersionedQuery.py +33 -0
  12. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_QueryParameters/ActualQueryParameters.py +9 -0
  13. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_QueryParameters/AuctionQueryParameters.py +1 -1
  14. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_QueryParameters/BidAskQueryParameters.py +1 -1
  15. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_QueryParameters/MasQueryParameters.py +1 -1
  16. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_QueryParameters/VersionedQueryParameters.py +10 -1
  17. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/_version.py +2 -2
  18. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/artesian_sdk.egg-info/PKG-INFO +163 -2
  19. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/artesian_sdk.egg-info/SOURCES.txt +3 -0
  20. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/tests/TestActual.py +34 -0
  21. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/tests/TestMarketDataService.py +35 -2
  22. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/tests/TestVersioned.py +35 -0
  23. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/.flake8 +0 -0
  24. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/.github/dependabot.yml +0 -0
  25. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/.github/workflows/dependency-review.yaml +0 -0
  26. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/.github/workflows/python-tests.yml +0 -0
  27. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/.gitignore +0 -0
  28. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/.vscode/extensions.json +0 -0
  29. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/.vscode/launch.json +0 -0
  30. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/.vscode/settings.json +0 -0
  31. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/CODEOWNERS +0 -0
  32. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/CONTRIBUTING.md +0 -0
  33. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/LICENSE +0 -0
  34. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/pyproject.toml +0 -0
  35. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/renovate.json +0 -0
  36. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestActual.py +0 -0
  37. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestAuction.py +0 -0
  38. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestBidAsk.py +0 -0
  39. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestDerivedCfg.py +0 -0
  40. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestGMEOffers.py +0 -0
  41. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestMarketDataService.py +0 -0
  42. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestMas.py +0 -0
  43. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestSearchFacet.py +0 -0
  44. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestVersioned.py +0 -0
  45. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestWriteDataAndDeleteActual.py +0 -0
  46. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestWriteDataAndDeleteAuction.py +0 -0
  47. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestWriteDataAndDeleteBidAsk.py +0 -0
  48. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestWriteDataAndDeleteMas.py +0 -0
  49. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestWriteDataAndDeleteVersioned.py +0 -0
  50. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestWriteDataAndQueryActual.py +0 -0
  51. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestWriteDataAndQueryAuction.py +0 -0
  52. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestWriteDataAndQueryBidAsk.py +0 -0
  53. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/samples/TestWriteDataAndQueryMas.py +0 -0
  54. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/setup.cfg +0 -0
  55. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/.gitignore +0 -0
  56. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/ArtesianConfig.py +0 -0
  57. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/ArtesianPolicyConfig.py +0 -0
  58. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Exceptions.py +0 -0
  59. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/ExtractionRangeConfig.py +0 -0
  60. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/GMEPublicOfferQuery.py +0 -0
  61. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/GMEPublicOfferQueryParameters.py +0 -0
  62. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/GMEPublicOfferService.py +0 -0
  63. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/_Enum/BaType.py +0 -0
  64. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/_Enum/GenerationType.py +0 -0
  65. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/_Enum/Market.py +0 -0
  66. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/_Enum/Purpose.py +0 -0
  67. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/_Enum/Scope.py +0 -0
  68. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/_Enum/Status.py +0 -0
  69. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/_Enum/UnitType.py +0 -0
  70. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/_Enum/Zone.py +0 -0
  71. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/_Enum/__init__.py +0 -0
  72. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/GMEPublicOffers/__init__.py +0 -0
  73. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Granularity.py +0 -0
  74. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Dto/ArtesianMetadataFacet.py +0 -0
  75. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Dto/ArtesianSearchResults.py +0 -0
  76. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Dto/CurveRangeEntity.py +0 -0
  77. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Dto/DeleteData.py +0 -0
  78. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Dto/DerivedCfg.py +0 -0
  79. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Dto/MarketDataEntityOutput.py +0 -0
  80. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Dto/MarketDataIdentifier.py +0 -0
  81. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Dto/PagedResult.py +0 -0
  82. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Dto/UpsertData.py +0 -0
  83. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Enum/AggregationRule.py +0 -0
  84. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Enum/ArtesianMetadataFacetType.py +0 -0
  85. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Enum/DerivedAlgorithm.py +0 -0
  86. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Enum/MarketDataType.py +0 -0
  87. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/MarketData/_Enum/__init__.py +0 -0
  88. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/AuctionQuery.py +0 -0
  89. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/BidAskQuery.py +0 -0
  90. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/DefaultPartitionStrategy.py +0 -0
  91. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/MasQuery.py +0 -0
  92. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/QueryService.py +0 -0
  93. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/RelativeInterval.py +0 -0
  94. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_Query.py +0 -0
  95. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_QueryParameters/ExtractionRangeConfig.py +0 -0
  96. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_QueryParameters/ExtractionRangeType.py +0 -0
  97. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_QueryParameters/MostRecentSelectionConfig.py +0 -0
  98. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_QueryParameters/QueryParameters.py +0 -0
  99. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_QueryParameters/VersionSelectionConfig.py +0 -0
  100. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_QueryParameters/VersionSelectionType.py +0 -0
  101. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_QueryParameters/VersionsRangeSelectionConfig.py +0 -0
  102. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/_QueryParameters/__init__.py +0 -0
  103. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/Query/__init__.py +0 -0
  104. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/_ClientsExecutor/ArtesianJsonSerializer.py +0 -0
  105. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/_ClientsExecutor/Client.py +0 -0
  106. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/_ClientsExecutor/RequestExecutor.py +0 -0
  107. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/_ClientsExecutor/__init__.py +0 -0
  108. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/Artesian/__init__.py +0 -0
  109. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/artesian_sdk.egg-info/dependency_links.txt +0 -0
  110. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/artesian_sdk.egg-info/requires.txt +0 -0
  111. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/src/artesian_sdk.egg-info/top_level.txt +0 -0
  112. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/tests/TestBidAsk.py +0 -0
  113. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/tests/TestClientErrorHandling.py +0 -0
  114. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/tests/TestGMEPO.py +0 -0
  115. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/tests/TestMarketDataDeleteData.py +0 -0
  116. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/tests/TestMarketDataUpsertData.py +0 -0
  117. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/tests/TestMas.py +0 -0
  118. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/tests/__init__.py +0 -0
  119. {artesian_sdk-4.0.3.dev14 → artesian_sdk-4.1.1.dev5}/tests/helpers.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: artesian-sdk
3
- Version: 4.0.3.dev14
3
+ Version: 4.1.1.dev5
4
4
  Summary: Library provides read access to the Artesian API
5
5
  Author-email: ARK Lab <arklab@ark-energy.eu>
6
6
  Maintainer-email: ARK Lab <arklab@ark-energy.eu>
@@ -51,6 +51,7 @@ Requires-Dist: pytest-cov; extra == "dev"
51
51
  Requires-Dist: twine; extra == "dev"
52
52
  Requires-Dist: build; extra == "dev"
53
53
  Requires-Dist: black; extra == "dev"
54
+ Dynamic: license-file
54
55
 
55
56
  # Artesian.SDK
56
57
 
@@ -496,6 +497,154 @@ To construct a GME Public Offer Extraction the following must be provided.
496
497
 
497
498
  </table>
498
499
 
500
+ ### Unit of Measure Conversion Functionality
501
+
502
+ ### Overview
503
+
504
+ The unit of measure conversion functionality allows users to request a conversion of units for Market Data that was registered using a different unit. This feature is supported only for Actual and Versioned Time Series.
505
+ Supported units are defined in the CommonUnitOfMeasure object and conform to ISO/IEC 80000 (i.e., `kW`, `MW`, `kWh`, `MWh`, `m`, `km`, `day`, `min`, `h`, `s`, `mo`, `yr`).
506
+
507
+ Note: Duration-based units are interpreted with the following fixed assumptions:
508
+ `1 day = 24 hours`
509
+ `1 mo = 30 days`
510
+ `1 yr = 365 days`
511
+
512
+ Additional supported units include **currency codes** in 3-letter format as per ISO 4217:2015 (e.g., `EUR`, `USD`, `JPY`). These are not part of CommonUnitOfMeasure and must be specified as regular strings.
513
+ Units of measure can also be **composite**, using the {a}/{b} syntax, where both {a} and {b} are either units from CommonUnitOfMeasure or ISO 4217 currency codes.
514
+
515
+ ### Conversion Logic
516
+
517
+ Unit conversion is based on the assumption that each unit of measure can be decomposed into a **"BaseDimension"**, which represents a polynomial of base SI units (`m`, `s`, `kg`, etc.) and currencies (`EUR`, `USD`, etc.).
518
+ A unit of measure is represented as a value in BaseDimension UnitOdMeasure.
519
+ Example:
520
+ 10 `Wh` = 10 `kg·m²·s⁻³`
521
+ Conversion is allowed when the BaseDimensions **match exactly**, i.e., the same set of base units raised to the same exponents.
522
+ In Artesian, units that differ **only** in the **time dimension** are also potentially convertible, as the time dimension can be inferred from the data’s time interval.
523
+
524
+ ### Example: Power to Energy Conversion
525
+
526
+ Converting `W` to `Wh`:
527
+ • `W` → BaseDimension: `k·m²·s⁻³`
528
+ • `Wh` → BaseDimension: `kg·m²·s⁻²`
529
+ • `1 h = 3600 s`
530
+ **Conversion Steps:**
531
+ 10 W = 10 kg·m²/s³
532
+ 1 h = 3600 s
533
+ 10 kg·m²/s³ × 3600 s = 36000 kg·m²/s² = 10 Wh
534
+
535
+ ### MarketData Registration with UnitOfMeasure
536
+
537
+ The UnitOfMeasure is defined during registration:
538
+
539
+ ```Python
540
+ mkd = MarketData.MarketDataEntityInput(
541
+ providerName = "TestProviderName",
542
+ marketDataName = "TestMarketDataName",
543
+ originalGranularity=Granularity.Day,
544
+ type=MarketData.MarketDataType.ActualTimeSerie,
545
+ originalTimezone="CET",
546
+ aggregationRule=AggregationRule.SumAndDivide,
547
+ UnitOfMeasure = CommonUnitOfMeasure.kW
548
+ )
549
+
550
+ registered = mkservice.readMarketDataRegistryByName(mkdid.provider, mkdid.name)
551
+ if (registered is None):
552
+ registered = mkservice.registerMarketData(mkd)
553
+ ```
554
+
555
+ ### UnitOfMeasure Conversion and Aggregation Rule Override
556
+
557
+ In the QueryService, there are two supported methods related to unit of measure handling during extraction:
558
+
559
+ 1. UnitOfMeasure Conversion
560
+ 2. Aggregation Rule Override
561
+
562
+ ### UnitOfMeasure Conversion
563
+
564
+ To convert a UnitOfMeasure during data extraction, use the `.inUnitOfMeasure()` method. This function converts the data from the unit defined at MarketData registration to the target unit you specify in the query.
565
+
566
+ ```Python
567
+ qs = QueryService(cfg)
568
+ data = qs.createActual() \
569
+ .forMarketData([100011484]) \
570
+ .inAbsoluteDateRange("2024-01-01","2024-01-02") \
571
+ .inTimeZone("UTC") \
572
+ .inGranularity(Granularity.Day) \
573
+ .inUnitOfMeasure(CommonUnitOfMeasure.MW) \
574
+ .execute()
575
+ ```
576
+
577
+ By default, the aggregation rule used during extraction is the one defined at registration. However, you can override it if needed. The conversion is always applied before aggregation.
578
+
579
+ ### Aggregation Rule Override
580
+
581
+ AggregationRule can be overrided using the `.withAggregationRule()` method in QueryService.
582
+
583
+ ```Python
584
+ qs = QueryService(cfg)
585
+ data = qs.createActual() \
586
+ .forMarketData([100011484]) \
587
+ .inAbsoluteDateRange("2024-01-01","2024-01-02") \
588
+ .inTimeZone("UTC") \
589
+ .inGranularity(Granularity.Day) \
590
+ .withAggregationRule(AggregationRule.AverageAndReplicate) \
591
+ .execute()
592
+ ```
593
+
594
+ Sometimes, especially when converting from a **consumption unit** (e.g., `MWh`) to a **power unit** (e.g., `MW`), the registered aggregation rule (e.g., `SumAndDivide`) may not make sense for the new unit.
595
+
596
+ If you **don’t override the aggregation rule**, the conversion may produce **invalid or misleading results**.
597
+
598
+ ### Example: Convert power (`MW`) to energy (`MWh`):
599
+
600
+ ```Python
601
+ data = qs.createActual() \
602
+ .forMarketData([100011484]) \
603
+ .inAbsoluteDateRange("2024-01-01","2024-01-02") \
604
+ .inTimeZone("UTC") \
605
+ .inGranularity(Granularity.Day) \
606
+ .inUnitOfMeasure(CommonUnitOfMeasure.MWh) \
607
+ .withAggregationRule(AggregationRule.AverageAndReplicate) \
608
+ .execute()
609
+ ```
610
+
611
+ ### Composite Unit Example: `MWh/day`
612
+
613
+ ```Python
614
+ data = qs.createActual() \
615
+ .forMarketData([100011484]) \
616
+ .inAbsoluteDateRange("2024-01-01","2024-01-02") \
617
+ .inTimeZone("UTC") \
618
+ .inGranularity(Granularity.Day) \
619
+ .inUnitOfMeasure(CommonUnitOfMeasure.MWh / CommonUnitOfMeasure.day) \
620
+ .withAggregationRule(AggregationRule.AverageAndReplicate) \
621
+ .execute()
622
+ ```
623
+
624
+ ### CheckConversion: Validate Unit Compatibility
625
+
626
+ Use the `CheckConversion` method to verify whether a list of input units can be converted into a specifified target unit:
627
+
628
+ ```Python
629
+ from Artesian import ArtesianConfig, MarketData
630
+ from Artesian.MarketData import CommonUnitOfMeasure
631
+
632
+ cfg = ArtesianConfg()
633
+
634
+ mkservice = MarketData.MarketDataService(cfg)
635
+
636
+ inputUnitsOfMeasure = [CommonUnitOfMeasure.kW, CommonUnitOfMeasure.kWh, "EUR/MWh"]
637
+ targetUnitOfMeasure = CommonUnitOfMeasure.MW
638
+
639
+ checkConversionResult = mkservice.checkConversion(inputUnitsOfMeasure , targetUnitOfMeasure)
640
+ ```
641
+
642
+ **Returned Object: CheckConversionResult**
643
+
644
+ 1. TargetUnitOfMeasure: "`kW`"
645
+ 2. ConvertibleInputUnitsOfMeasure: [ "`MW`", "`kW/s`" ]
646
+ 3. NotConvertibleInputUnitsOfMeasure: [ "`s`" ]
647
+
499
648
  ### Extraction Options
500
649
 
501
650
  Extraction options for GME Public Offer queries.
@@ -572,6 +721,18 @@ Extraction options for GME Public Offer queries.
572
721
  .withPagination(1,10)
573
722
  ```
574
723
 
724
+ #### UnitOfMeasure (for Actual and Versioned Time Series)
725
+
726
+ ```Python
727
+ .inUnitOfMeasure(CommonUnitOfMeasure.kWh)
728
+ ```
729
+
730
+ #### AggregationRule (for Actual and Versioned Time Series)
731
+
732
+ ```Python
733
+ .withAggregationRule(AggregationRule.SumAndDivide)
734
+ ```
735
+
575
736
  ## Write Data in Artesian
576
737
 
577
738
  Using the MarketDataService is possible to register MarketData and write curves into it using the UpsertData method.
@@ -442,6 +442,154 @@ To construct a GME Public Offer Extraction the following must be provided.
442
442
 
443
443
  </table>
444
444
 
445
+ ### Unit of Measure Conversion Functionality
446
+
447
+ ### Overview
448
+
449
+ The unit of measure conversion functionality allows users to request a conversion of units for Market Data that was registered using a different unit. This feature is supported only for Actual and Versioned Time Series.
450
+ Supported units are defined in the CommonUnitOfMeasure object and conform to ISO/IEC 80000 (i.e., `kW`, `MW`, `kWh`, `MWh`, `m`, `km`, `day`, `min`, `h`, `s`, `mo`, `yr`).
451
+
452
+ Note: Duration-based units are interpreted with the following fixed assumptions:
453
+ `1 day = 24 hours`
454
+ `1 mo = 30 days`
455
+ `1 yr = 365 days`
456
+
457
+ Additional supported units include **currency codes** in 3-letter format as per ISO 4217:2015 (e.g., `EUR`, `USD`, `JPY`). These are not part of CommonUnitOfMeasure and must be specified as regular strings.
458
+ Units of measure can also be **composite**, using the {a}/{b} syntax, where both {a} and {b} are either units from CommonUnitOfMeasure or ISO 4217 currency codes.
459
+
460
+ ### Conversion Logic
461
+
462
+ Unit conversion is based on the assumption that each unit of measure can be decomposed into a **"BaseDimension"**, which represents a polynomial of base SI units (`m`, `s`, `kg`, etc.) and currencies (`EUR`, `USD`, etc.).
463
+ A unit of measure is represented as a value in BaseDimension UnitOdMeasure.
464
+ Example:
465
+ 10 `Wh` = 10 `kg·m²·s⁻³`
466
+ Conversion is allowed when the BaseDimensions **match exactly**, i.e., the same set of base units raised to the same exponents.
467
+ In Artesian, units that differ **only** in the **time dimension** are also potentially convertible, as the time dimension can be inferred from the data’s time interval.
468
+
469
+ ### Example: Power to Energy Conversion
470
+
471
+ Converting `W` to `Wh`:
472
+ • `W` → BaseDimension: `k·m²·s⁻³`
473
+ • `Wh` → BaseDimension: `kg·m²·s⁻²`
474
+ • `1 h = 3600 s`
475
+ **Conversion Steps:**
476
+ 10 W = 10 kg·m²/s³
477
+ 1 h = 3600 s
478
+ 10 kg·m²/s³ × 3600 s = 36000 kg·m²/s² = 10 Wh
479
+
480
+ ### MarketData Registration with UnitOfMeasure
481
+
482
+ The UnitOfMeasure is defined during registration:
483
+
484
+ ```Python
485
+ mkd = MarketData.MarketDataEntityInput(
486
+ providerName = "TestProviderName",
487
+ marketDataName = "TestMarketDataName",
488
+ originalGranularity=Granularity.Day,
489
+ type=MarketData.MarketDataType.ActualTimeSerie,
490
+ originalTimezone="CET",
491
+ aggregationRule=AggregationRule.SumAndDivide,
492
+ UnitOfMeasure = CommonUnitOfMeasure.kW
493
+ )
494
+
495
+ registered = mkservice.readMarketDataRegistryByName(mkdid.provider, mkdid.name)
496
+ if (registered is None):
497
+ registered = mkservice.registerMarketData(mkd)
498
+ ```
499
+
500
+ ### UnitOfMeasure Conversion and Aggregation Rule Override
501
+
502
+ In the QueryService, there are two supported methods related to unit of measure handling during extraction:
503
+
504
+ 1. UnitOfMeasure Conversion
505
+ 2. Aggregation Rule Override
506
+
507
+ ### UnitOfMeasure Conversion
508
+
509
+ To convert a UnitOfMeasure during data extraction, use the `.inUnitOfMeasure()` method. This function converts the data from the unit defined at MarketData registration to the target unit you specify in the query.
510
+
511
+ ```Python
512
+ qs = QueryService(cfg)
513
+ data = qs.createActual() \
514
+ .forMarketData([100011484]) \
515
+ .inAbsoluteDateRange("2024-01-01","2024-01-02") \
516
+ .inTimeZone("UTC") \
517
+ .inGranularity(Granularity.Day) \
518
+ .inUnitOfMeasure(CommonUnitOfMeasure.MW) \
519
+ .execute()
520
+ ```
521
+
522
+ By default, the aggregation rule used during extraction is the one defined at registration. However, you can override it if needed. The conversion is always applied before aggregation.
523
+
524
+ ### Aggregation Rule Override
525
+
526
+ AggregationRule can be overrided using the `.withAggregationRule()` method in QueryService.
527
+
528
+ ```Python
529
+ qs = QueryService(cfg)
530
+ data = qs.createActual() \
531
+ .forMarketData([100011484]) \
532
+ .inAbsoluteDateRange("2024-01-01","2024-01-02") \
533
+ .inTimeZone("UTC") \
534
+ .inGranularity(Granularity.Day) \
535
+ .withAggregationRule(AggregationRule.AverageAndReplicate) \
536
+ .execute()
537
+ ```
538
+
539
+ Sometimes, especially when converting from a **consumption unit** (e.g., `MWh`) to a **power unit** (e.g., `MW`), the registered aggregation rule (e.g., `SumAndDivide`) may not make sense for the new unit.
540
+
541
+ If you **don’t override the aggregation rule**, the conversion may produce **invalid or misleading results**.
542
+
543
+ ### Example: Convert power (`MW`) to energy (`MWh`):
544
+
545
+ ```Python
546
+ data = qs.createActual() \
547
+ .forMarketData([100011484]) \
548
+ .inAbsoluteDateRange("2024-01-01","2024-01-02") \
549
+ .inTimeZone("UTC") \
550
+ .inGranularity(Granularity.Day) \
551
+ .inUnitOfMeasure(CommonUnitOfMeasure.MWh) \
552
+ .withAggregationRule(AggregationRule.AverageAndReplicate) \
553
+ .execute()
554
+ ```
555
+
556
+ ### Composite Unit Example: `MWh/day`
557
+
558
+ ```Python
559
+ data = qs.createActual() \
560
+ .forMarketData([100011484]) \
561
+ .inAbsoluteDateRange("2024-01-01","2024-01-02") \
562
+ .inTimeZone("UTC") \
563
+ .inGranularity(Granularity.Day) \
564
+ .inUnitOfMeasure(CommonUnitOfMeasure.MWh / CommonUnitOfMeasure.day) \
565
+ .withAggregationRule(AggregationRule.AverageAndReplicate) \
566
+ .execute()
567
+ ```
568
+
569
+ ### CheckConversion: Validate Unit Compatibility
570
+
571
+ Use the `CheckConversion` method to verify whether a list of input units can be converted into a specifified target unit:
572
+
573
+ ```Python
574
+ from Artesian import ArtesianConfig, MarketData
575
+ from Artesian.MarketData import CommonUnitOfMeasure
576
+
577
+ cfg = ArtesianConfg()
578
+
579
+ mkservice = MarketData.MarketDataService(cfg)
580
+
581
+ inputUnitsOfMeasure = [CommonUnitOfMeasure.kW, CommonUnitOfMeasure.kWh, "EUR/MWh"]
582
+ targetUnitOfMeasure = CommonUnitOfMeasure.MW
583
+
584
+ checkConversionResult = mkservice.checkConversion(inputUnitsOfMeasure , targetUnitOfMeasure)
585
+ ```
586
+
587
+ **Returned Object: CheckConversionResult**
588
+
589
+ 1. TargetUnitOfMeasure: "`kW`"
590
+ 2. ConvertibleInputUnitsOfMeasure: [ "`MW`", "`kW/s`" ]
591
+ 3. NotConvertibleInputUnitsOfMeasure: [ "`s`" ]
592
+
445
593
  ### Extraction Options
446
594
 
447
595
  Extraction options for GME Public Offer queries.
@@ -518,6 +666,18 @@ Extraction options for GME Public Offer queries.
518
666
  .withPagination(1,10)
519
667
  ```
520
668
 
669
+ #### UnitOfMeasure (for Actual and Versioned Time Series)
670
+
671
+ ```Python
672
+ .inUnitOfMeasure(CommonUnitOfMeasure.kWh)
673
+ ```
674
+
675
+ #### AggregationRule (for Actual and Versioned Time Series)
676
+
677
+ ```Python
678
+ .withAggregationRule(AggregationRule.SumAndDivide)
679
+ ```
680
+
521
681
  ## Write Data in Artesian
522
682
 
523
683
  Using the MarketDataService is possible to register MarketData and write curves into it using the UpsertData method.
@@ -0,0 +1,17 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass(frozen=True)
5
+ class CommonUnitOfMeasure:
6
+ kW = "kW"
7
+ MW = "MW"
8
+ kWh = "kWh"
9
+ MWh = "MWh"
10
+ m = "m"
11
+ km = "km"
12
+ day = "day"
13
+ min = "min"
14
+ h = "h"
15
+ s = "s"
16
+ mo = "mo"
17
+ yr = "yr"
@@ -11,6 +11,7 @@ from ._Dto.PagedResult import PagedResultCurveRangeEntity
11
11
  from ._Dto.ArtesianSearchResults import ArtesianSearchResults
12
12
  from ._Dto.MarketDataEntityInput import MarketDataEntityInput
13
13
  from ._Dto.MarketDataEntityOutput import MarketDataEntityOutput
14
+ from ._Dto.CheckConversionResult import CheckConversionResult
14
15
  from ._Dto.UpsertData import UpsertData
15
16
  import asyncio
16
17
 
@@ -396,6 +397,61 @@ class MarketDataService:
396
397
  self.registerMarketDataAsync(entity)
397
398
  )
398
399
 
400
+ async def checkConversionAsync(
401
+ self: MarketDataService,
402
+ inputUnitsOfMeasure: List[str],
403
+ targetUnitOfMeasure: str
404
+ ) -> CheckConversionResult:
405
+ """
406
+ Check UnitOfMeasure conversion.
407
+
408
+ Args:
409
+ inputUnitsOfMeasure: the list of the input UnitOfMeasure to be check for
410
+ conversion
411
+ targetUnitOfMeasure: The target UnitOfMeasure
412
+
413
+ Returns:
414
+ CheckConversionResult Entity (Async).
415
+ """
416
+ url = "/uom/checkconversion"
417
+ params = {"inputUnitsOfMeasure": inputUnitsOfMeasure,
418
+ "targetUnitOfMeasure": targetUnitOfMeasure}
419
+ with self.__client as c:
420
+ res = await asyncio.gather(
421
+ *[
422
+ self.__executor.exec(
423
+ c.exec,
424
+ "GET",
425
+ url,
426
+ None,
427
+ retcls=CheckConversionResult,
428
+ params=params,
429
+ )
430
+ ]
431
+ )
432
+ return cast(CheckConversionResult, res[0])
433
+
434
+ def checkConversion(
435
+ self: MarketDataService,
436
+ inputUnitsOfMeasure: List[str],
437
+ targetUnitOfMeasure: str
438
+ ) -> CheckConversionResult:
439
+ """
440
+ Check UnitOfMeasure conversion.
441
+
442
+ Args:
443
+ inputUnitsOfMeasure: the list of the input UnitOfMeasure to be check for
444
+ conversion
445
+ targetUnitOfMeasure: The target UnitOfMeasure
446
+
447
+ Returns:
448
+ CheckConversionResult Entity.
449
+ """
450
+
451
+ return _get_event_loop().run_until_complete(
452
+ self.checkConversionAsync(inputUnitsOfMeasure, targetUnitOfMeasure)
453
+ )
454
+
399
455
  async def updateDerivedConfigurationAsync(
400
456
  self: MarketDataService,
401
457
  marketDataId: int,
@@ -0,0 +1,19 @@
1
+ from dataclasses import dataclass
2
+ from typing import List
3
+
4
+
5
+ @dataclass
6
+ class CheckConversionResult:
7
+ """
8
+ Class for the CheckConversionResult.
9
+
10
+ Attributes:
11
+ targetUnitOfMeasure: the target UnitOfMeasure
12
+ convertibleInputUnitsOfMeasure: the list of convertible input UnitOfMeasure
13
+ notConvertibleInputUnitsOfMeasure: the list of not convertible input
14
+ UnitOfMeasure
15
+ """
16
+
17
+ targetUnitOfMeasure: str
18
+ convertibleInputUnitsOfMeasure: List[str]
19
+ notConvertibleInputUnitsOfMeasure: List[str]
@@ -2,6 +2,7 @@ from dataclasses import dataclass
2
2
  from typing import Dict, List, Optional
3
3
 
4
4
  from .DerivedCfg import DerivedCfg
5
+ from .UnitOfMeasure import UnitOfMeasure
5
6
  from .._Enum.DerivedAlgorithm import DerivedAlgorithm
6
7
  from .._Enum import MarketDataType
7
8
  from .._Enum import AggregationRule
@@ -34,6 +35,7 @@ class MarketDataEntityInput:
34
35
  originalGranularity: Granularity
35
36
  type: MarketDataType
36
37
  originalTimezone: str
38
+ unitOfMeasure: Optional[UnitOfMeasure] = None
37
39
  derivedCfg: Optional[DerivedCfg] = None
38
40
  aggregationRule: AggregationRule = AggregationRule.Undefined
39
41
  tags: Optional[Dict[str, List[str]]] = None
@@ -0,0 +1,15 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class UnitOfMeasure:
6
+ """
7
+ Class for the UnitOfMeasure.
8
+
9
+ Attributes:
10
+ value: the value of the unit of measure for the values of timeseries
11
+ (actual and versioned)
12
+
13
+ """
14
+
15
+ value: str
@@ -1,5 +1,7 @@
1
1
  from .MarketDataEntityInput import MarketDataEntityInput
2
2
  from .MarketDataEntityOutput import MarketDataEntityOutput
3
+ from .CheckConversionResult import CheckConversionResult
4
+ from .UnitOfMeasure import UnitOfMeasure
3
5
  from .CurveRangeEntity import CurveRangeEntity
4
6
  from .PagedResult import PagedResultCurveRangeEntity
5
7
  from .ArtesianSearchResults import ArtesianSearchResults
@@ -31,4 +33,6 @@ __all__ = [
31
33
  ArtesianMetadataFacet.__name__,
32
34
  ArtesianMetadataFacetCount.__name__,
33
35
  DerivedCfg.__name__,
36
+ CheckConversionResult.__name__,
37
+ UnitOfMeasure.__name__,
34
38
  ] # type: ignore
@@ -4,6 +4,7 @@ from ._Enum.AggregationRule import AggregationRule
4
4
  from ..Granularity import Granularity
5
5
  from ._Enum.MarketDataType import MarketDataType
6
6
  from ._Enum.ArtesianMetadataFacetType import ArtesianMetadataFacetType
7
+ from .CommonUnitOfMeasure import CommonUnitOfMeasure
7
8
 
8
9
  from ._Dto import (
9
10
  AuctionBids,
@@ -21,6 +22,8 @@ from ._Dto import (
21
22
  ArtesianMetadataFacet,
22
23
  ArtesianMetadataFacetCount,
23
24
  DerivedCfg,
25
+ CheckConversionResult,
26
+ UnitOfMeasure,
24
27
  )
25
28
 
26
29
  __all__ = [
@@ -44,5 +47,8 @@ __all__ = [
44
47
  ArtesianMetadataFacetCount.__name__,
45
48
  ArtesianMetadataFacetType.__name__,
46
49
  DerivedCfg.__name__,
50
+ CheckConversionResult.__name__,
47
51
  DerivedAlgorithm.__name__,
52
+ CommonUnitOfMeasure.__name__,
53
+ UnitOfMeasure.__name__,
48
54
  ] # type: ignore
@@ -13,6 +13,7 @@ from ._Query import _Query
13
13
  from .RelativeInterval import RelativeInterval
14
14
  from ._QueryParameters.ActualQueryParameters import ActualQueryParameters
15
15
  from Artesian.MarketData import Granularity
16
+ from Artesian.MarketData import AggregationRule
16
17
  from urllib import parse
17
18
  from typing import List, Optional
18
19
 
@@ -221,6 +222,34 @@ class ActualQuery(_Query):
221
222
  self._queryParameters.fill = _FillCustomTimeserieStrategy(value)
222
223
  return self
223
224
 
225
+ def inUnitOfMeasure(self: ActualQuery, unitOfMeasure: str) -> ActualQuery:
226
+ """
227
+ Gets the Actual Query in a specific unit of measure to be queried.
228
+
229
+ Args:
230
+ unitOfMeasure: str ex.: "MW", "MWh", "kW/day", "km"
231
+
232
+ Returns:
233
+ ActualQuery.
234
+ """
235
+ self._queryParameters.unitOfMeasure = unitOfMeasure
236
+ return self
237
+
238
+ def withAggregationRule(self: ActualQuery,
239
+ aggregationRule: AggregationRule) -> ActualQuery:
240
+ """
241
+ Optional AggregationRule for the extraction.
242
+
243
+ Args:
244
+ aggregationRule: enum AggregationRule ex.: "SumAndDivide",
245
+ "AverageAndReplicate"
246
+
247
+ Returns:
248
+ ActualQuery.
249
+ """
250
+ self._queryParameters.aggregationRule = aggregationRule
251
+ return self
252
+
224
253
  def execute(self: ActualQuery) -> list:
225
254
  """
226
255
  Execute the Query.
@@ -260,6 +289,10 @@ class ActualQuery(_Query):
260
289
  url = url + "&tz=" + qp.timezone
261
290
  if not (qp.transformId is None):
262
291
  url = url + "&tr=" + str(qp.transformId)
292
+ if not (qp.unitOfMeasure is None):
293
+ url = url + "&unitOfMeasure=" + qp.unitOfMeasure
294
+ if not (qp.aggregationRule is None):
295
+ url = url + "&aggregationRule=" + str(qp.aggregationRule)
263
296
  if not (qp.fill is None):
264
297
  url = url + "&" + qp.fill.getUrlParams()
265
298
  urls.append(url)
@@ -16,6 +16,7 @@ from ._QueryParameters.VersionedQueryParameters import VersionedQueryParameters
16
16
  from ._QueryParameters.VersionSelectionType import VersionSelectionType
17
17
  from .RelativeInterval import RelativeInterval
18
18
  from Artesian.MarketData import Granularity
19
+ from Artesian.MarketData import AggregationRule
19
20
 
20
21
 
21
22
  class VersionedQuery(_Query):
@@ -341,6 +342,34 @@ class VersionedQuery(_Query):
341
342
  self._queryParameters.fill = _FillCustomTimeserieStrategy(val)
342
343
  return self
343
344
 
345
+ def inUnitOfMeasure(self: VersionedQuery, unitOfMeasure: str) -> VersionedQuery:
346
+ """
347
+ Gets the Actual Query in a specific unit of measure to be queried.
348
+
349
+ Args:
350
+ unitOfMeasure: str ex.: "MW", "MWh", "kW/day", "km"
351
+
352
+ Returns:
353
+ VersionedQuery.
354
+ """
355
+ self._queryParameters.unitOfMeasure = unitOfMeasure
356
+ return self
357
+
358
+ def withAggregationRule(self: VersionedQuery,
359
+ aggregationRule: AggregationRule) -> VersionedQuery:
360
+ """
361
+ Optional AggregationRule for the extraction.
362
+
363
+ Args:
364
+ aggregationRule: enum AggregationRule ex.: "SumAndDivide",
365
+ "AverageAndReplicate"
366
+
367
+ Returns:
368
+ VersionedQuery.
369
+ """
370
+ self._queryParameters.aggregationRule = aggregationRule
371
+ return self
372
+
344
373
  def execute(self: VersionedQuery) -> list:
345
374
  """
346
375
  Execute the Query.
@@ -385,6 +414,10 @@ class VersionedQuery(_Query):
385
414
  url = url + "&" + qp.fill.getUrlParams()
386
415
  if not (qp.versionLimit is None):
387
416
  url = url + "&versionLimit=" + qp.versionLimit
417
+ if not (qp.unitOfMeasure is None):
418
+ url = url + "&unitOfMeasure=" + qp.unitOfMeasure
419
+ if not (qp.aggregationRule is None):
420
+ url = url + "&aggregationRule=" + str(qp.aggregationRule)
388
421
  urls.append(url)
389
422
  return urls
390
423
 
@@ -4,6 +4,7 @@ from .QueryParameters import _QueryParameters
4
4
  from .ExtractionRangeType import ExtractionRangeType
5
5
  from .ExtractionRangeConfig import ExtractionRangeConfig
6
6
  from Artesian.MarketData import Granularity
7
+ from Artesian.MarketData import AggregationRule
7
8
 
8
9
 
9
10
  class ActualQueryParameters(_QueryParameters):
@@ -18,6 +19,8 @@ class ActualQueryParameters(_QueryParameters):
18
19
  filterId: filters marketdata ID to be queries.
19
20
  granularity: sets the granularity to be queried.
20
21
  transformId: sets time range.
22
+ unitOfMeasure: The UnitOfMeasure to use for extraction.
23
+ aggregationRule: The AggregationRule to use for extraction.
21
24
  """
22
25
 
23
26
  def __init__(
@@ -29,6 +32,8 @@ class ActualQueryParameters(_QueryParameters):
29
32
  filterId: Optional[int] = None,
30
33
  granularity: Optional[Granularity] = None,
31
34
  transformId: Optional[str] = None,
35
+ unitOfMeasure: Optional[str] = None,
36
+ aggregationRule: Optional[AggregationRule] = None
32
37
  ) -> None:
33
38
  """
34
39
  Inits ActualQueryParameters
@@ -42,9 +47,13 @@ class ActualQueryParameters(_QueryParameters):
42
47
  filterId: An int that filters marketdata ID to be queries.
43
48
  granularity: An enum that sets the granularity to be queried.
44
49
  transformId: The name of the Time Transform to use for extraction.
50
+ unitOfMeasure: The UnitOfMeasure to use for extraction.
51
+ aggregationRule: The AggregationRule to use for extraction.
45
52
  """
46
53
  _QueryParameters.__init__(
47
54
  self, ids, extractionRangeConfig, extractionRangeType, timezone, filterId
48
55
  )
49
56
  self.granularity = granularity
50
57
  self.transformId = transformId
58
+ self.unitOfMeasure = unitOfMeasure
59
+ self.aggregationRule = aggregationRule