artesian-sdk 4.2.3.dev43__tar.gz → 4.3.1.dev1__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 (129) hide show
  1. artesian_sdk-4.3.1.dev1/CODEOWNERS +5 -0
  2. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/PKG-INFO +127 -27
  3. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/README.md +126 -26
  4. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestActual.py +1 -1
  5. artesian_sdk-4.3.1.dev1/samples/TestDerivedCfgTransform.py +101 -0
  6. artesian_sdk-4.3.1.dev1/samples/TestDerivedTransformQueryValidation.py +37 -0
  7. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/MarketDataService.py +49 -0
  8. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Dto/DerivedCfg.py +2 -1
  9. artesian_sdk-4.3.1.dev1/src/Artesian/MarketData/_Dto/DerivedTransformQueryValidation.py +34 -0
  10. artesian_sdk-4.3.1.dev1/src/Artesian/MarketData/_Dto/DerivedTransformQueryValidationResponse.py +30 -0
  11. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Dto/MarketDataEntityInput.py +25 -1
  12. artesian_sdk-4.3.1.dev1/src/Artesian/MarketData/_Dto/TimeSerieData.py +22 -0
  13. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Dto/__init__.py +2 -0
  14. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Enum/DerivedAlgorithm.py +1 -0
  15. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/_ClientsExecutor/Client.py +2 -2
  16. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/_version.py +3 -3
  17. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/artesian_sdk.egg-info/PKG-INFO +127 -27
  18. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/artesian_sdk.egg-info/SOURCES.txt +5 -0
  19. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/artesian_sdk.egg-info/scm_file_list.json +5 -0
  20. artesian_sdk-4.3.1.dev1/src/artesian_sdk.egg-info/scm_version.json +8 -0
  21. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/tests/TestMarketDataService.py +109 -0
  22. artesian_sdk-4.2.3.dev43/CODEOWNERS +0 -1
  23. artesian_sdk-4.2.3.dev43/src/artesian_sdk.egg-info/scm_version.json +0 -8
  24. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/.flake8 +0 -0
  25. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/.github/dependabot.yml +0 -0
  26. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/.github/workflows/dependency-review.yaml +0 -0
  27. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/.github/workflows/python-tests.yml +0 -0
  28. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/.gitignore +0 -0
  29. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/.vscode/extensions.json +0 -0
  30. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/.vscode/launch.json +0 -0
  31. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/.vscode/settings.json +0 -0
  32. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/CONTRIBUTING.md +0 -0
  33. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/LICENSE +0 -0
  34. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/pyproject.toml +0 -0
  35. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/renovate.json +0 -0
  36. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestAuction.py +0 -0
  37. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestBidAsk.py +0 -0
  38. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestDerivedCfg.py +0 -0
  39. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestGMEOffers.py +0 -0
  40. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestMarketDataService.py +0 -0
  41. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestMas.py +0 -0
  42. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestSearchFacet.py +0 -0
  43. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestVersioned.py +0 -0
  44. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestWriteDataAndDeleteActual.py +0 -0
  45. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestWriteDataAndDeleteAuction.py +0 -0
  46. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestWriteDataAndDeleteBidAsk.py +0 -0
  47. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestWriteDataAndDeleteMas.py +0 -0
  48. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestWriteDataAndDeleteVersioned.py +0 -0
  49. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestWriteDataAndQueryActual.py +0 -0
  50. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestWriteDataAndQueryAuction.py +0 -0
  51. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestWriteDataAndQueryBidAsk.py +0 -0
  52. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/samples/TestWriteDataAndQueryMas.py +0 -0
  53. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/setup.cfg +0 -0
  54. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/.gitignore +0 -0
  55. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/ArtesianConfig.py +0 -0
  56. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/ArtesianPolicyConfig.py +0 -0
  57. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Exceptions.py +0 -0
  58. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/ExtractionRangeConfig.py +0 -0
  59. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/GMEPublicOfferQuery.py +0 -0
  60. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/GMEPublicOfferQueryParameters.py +0 -0
  61. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/GMEPublicOfferService.py +0 -0
  62. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/_Enum/BaType.py +0 -0
  63. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/_Enum/GenerationType.py +0 -0
  64. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/_Enum/Market.py +0 -0
  65. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/_Enum/Purpose.py +0 -0
  66. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/_Enum/Scope.py +0 -0
  67. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/_Enum/Status.py +0 -0
  68. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/_Enum/UnitType.py +0 -0
  69. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/_Enum/Zone.py +0 -0
  70. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/_Enum/__init__.py +0 -0
  71. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/GMEPublicOffers/__init__.py +0 -0
  72. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Granularity.py +0 -0
  73. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/CommonUnitOfMeasure.py +0 -0
  74. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Dto/ArtesianMetadataFacet.py +0 -0
  75. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Dto/ArtesianSearchResults.py +0 -0
  76. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Dto/CheckConversionResult.py +0 -0
  77. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Dto/CurveRangeEntity.py +0 -0
  78. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Dto/DeleteData.py +0 -0
  79. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Dto/MarketDataEntityOutput.py +0 -0
  80. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Dto/MarketDataIdentifier.py +0 -0
  81. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Dto/PagedResult.py +0 -0
  82. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Dto/UnitOfMeasure.py +0 -0
  83. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Dto/UpsertData.py +0 -0
  84. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Enum/AggregationRule.py +0 -0
  85. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Enum/ArtesianMetadataFacetType.py +0 -0
  86. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Enum/MarketDataType.py +0 -0
  87. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Enum/UpsertMode.py +0 -0
  88. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/_Enum/__init__.py +0 -0
  89. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/MarketData/__init__.py +0 -0
  90. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/ActualQuery.py +0 -0
  91. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/AuctionQuery.py +0 -0
  92. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/BidAskQuery.py +0 -0
  93. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/DefaultPartitionStrategy.py +0 -0
  94. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/MasQuery.py +0 -0
  95. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/QueryService.py +0 -0
  96. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/RelativeInterval.py +0 -0
  97. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/VersionedQuery.py +0 -0
  98. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_Query.py +0 -0
  99. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_QueryParameters/ActualQueryParameters.py +0 -0
  100. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_QueryParameters/AuctionQueryParameters.py +0 -0
  101. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_QueryParameters/BidAskQueryParameters.py +0 -0
  102. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_QueryParameters/ExtractionRangeConfig.py +0 -0
  103. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_QueryParameters/ExtractionRangeType.py +0 -0
  104. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_QueryParameters/MasQueryParameters.py +0 -0
  105. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_QueryParameters/MostRecentSelectionConfig.py +0 -0
  106. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_QueryParameters/QueryParameters.py +0 -0
  107. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_QueryParameters/VersionSelectionConfig.py +0 -0
  108. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_QueryParameters/VersionSelectionType.py +0 -0
  109. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_QueryParameters/VersionedQueryParameters.py +0 -0
  110. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_QueryParameters/VersionsRangeSelectionConfig.py +0 -0
  111. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/_QueryParameters/__init__.py +0 -0
  112. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/Query/__init__.py +0 -0
  113. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/_ClientsExecutor/ArtesianJsonSerializer.py +0 -0
  114. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/_ClientsExecutor/RequestExecutor.py +0 -0
  115. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/_ClientsExecutor/__init__.py +0 -0
  116. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/Artesian/__init__.py +0 -0
  117. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/artesian_sdk.egg-info/dependency_links.txt +0 -0
  118. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/artesian_sdk.egg-info/requires.txt +0 -0
  119. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/src/artesian_sdk.egg-info/top_level.txt +0 -0
  120. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/tests/TestActual.py +0 -0
  121. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/tests/TestBidAsk.py +0 -0
  122. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/tests/TestClientErrorHandling.py +0 -0
  123. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/tests/TestGMEPO.py +0 -0
  124. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/tests/TestMarketDataDeleteData.py +0 -0
  125. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/tests/TestMarketDataUpsertData.py +0 -0
  126. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/tests/TestMas.py +0 -0
  127. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/tests/TestVersioned.py +0 -0
  128. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/tests/__init__.py +0 -0
  129. {artesian_sdk-4.2.3.dev43 → artesian_sdk-4.3.1.dev1}/tests/helpers.py +0 -0
@@ -0,0 +1,5 @@
1
+ * @ARKlab/team-teapot418
2
+ /.github/ @ARKlab/maintainers
3
+ /LICENSE @ARKlab/maintainers
4
+ /CODEOWNERS @ARKlab/maintainers
5
+ /renovate.json @ARKlab/maintainers
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: artesian-sdk
3
- Version: 4.2.3.dev43
3
+ Version: 4.3.1.dev1
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>
@@ -469,8 +469,8 @@ Artesian support Query over GME Public Offers which comes in a custom and dedica
469
469
  Note (performance):
470
470
  GME Public Offer data is partitioned by date, offerType, status, and market. Requesting very narrow subsets (for example a single status or offerType in several separate requests) does not improve performance and can cause the same data to be fetched multiple times.
471
471
  For this reason, the examples below:
472
- Use a large page size so that all data for a given (date, market, filters) is typically returned in a single page.
473
- Loop over markets explicitly to cover all required markets without redundant fetches.
472
+ Use a large page size so that all data for a given (date, market, filters) is typically returned in a single page.
473
+ Loop over markets explicitly to cover all required markets without redundant fetches.
474
474
 
475
475
  ### Extract GME Public Offer
476
476
 
@@ -763,6 +763,76 @@ Extraction options for GME Public Offer queries.
763
763
  .withAggregationRule(AggregationRule.SumAndDivide)
764
764
  ```
765
765
 
766
+ ### DerivedTransform: Query Validation
767
+
768
+ Use the `DerivedTransformQueryValidation` to validate and execute a derived transform query against a sample TimeSerieData.
769
+
770
+ ```Python
771
+ from Artesian.MarketData import MarketDataService
772
+ from Artesian.MarketData._Dto.DerivedTransformQueryValidation import DerivedTransformQueryValidation
773
+ from Artesian.MarketData._Dto.TimeSerieData import TimeSerieData
774
+ from Artesian import MarketDataType
775
+ from datetime import datetime
776
+
777
+ mds = MarketDataService(cfg)
778
+
779
+ request = DerivedTransformQueryValidation(
780
+ data=TimeSerieData(
781
+ rows=[
782
+ (datetime(2018, 10, 1, 0, 0), 100),
783
+ (datetime(2018, 10, 1, 1, 0), 100)
784
+ ],
785
+ type=MarketDataType.ActualTimeSerie,
786
+ ),
787
+ transform="SELECT Time, (Value + 1) as Value FROM $table"
788
+ )
789
+
790
+ derivedTransformResponse = mds.derivedTransformQueryValidation(request)
791
+ ```
792
+
793
+ #### Available Columns
794
+
795
+ | Column | Type |
796
+ | ------ | -------- |
797
+ | Time | datetime |
798
+ | Value | double |
799
+
800
+ > `$table` is a virtual table exposed by the query engine.
801
+
802
+ **Returned Object: DerivedTransformQueryValidationResponse**
803
+
804
+ | Property | Description |
805
+ | -------- | ---------------------------------------------- |
806
+ | Data | Transformed time series generated by the query |
807
+ | Valid | Indicates whether the query is valid |
808
+ | Error | Validation error details when `Valid = false` |
809
+
810
+ #### Query examples
811
+
812
+ ```sql
813
+ SELECT Time + INTERVAL 1 DAY AS Time, Value FROM $table
814
+
815
+ SELECT Time, CASE WHEN EXTRACT(HOUR FROM (Time AT TIME ZONE 'UTC') AT TIME ZONE 'Europe/Rome') < 10 THEN Value + 1 ELSE Value END AS Value FROM $table WHERE Time IS NOT NULL
816
+
817
+ SELECT Time, Value FROM $table WHERE Version IS NOT NULL AND ((EXTRACT(hour FROM Version) < 10 AND Time >= date_trunc('day', Version + interval '1 day')) OR (EXTRACT(hour FROM Version) >= 10 AND Time >= date_trunc('day', Version + interval '2 day')))
818
+ ```
819
+
820
+ #### SQL Dialect & Execution Model
821
+
822
+ The query engine uses a DuckDB-compatible SQL dialect (PostgreSQL-like).
823
+
824
+ Queries are executed against a virtual table named `$table`, which represents the provided sample TimeSerieData.
825
+
826
+ The engine supports common SQL features including:
827
+
828
+ - SELECT expressions
829
+ - WHERE filtering
830
+ - CASE WHEN expressions
831
+ - Date/time arithmetic and functions
832
+ - Timezone conversion functions
833
+
834
+ Full DuckDB SQL reference: https://duckdb.org/docs/sql/introduction.html
835
+
766
836
  ## Write Data in Artesian
767
837
 
768
838
  Using the MarketDataService is possible to register MarketData and write curves into it using the UpsertData method.
@@ -816,9 +886,11 @@ mkservice.upsertData(data)
816
886
  ```
817
887
 
818
888
  Upsert has optional switches that can be applied
889
+
819
890
  ```
820
891
  mkservice.upsertData(data, deferCommandExecution, deferDataGeneration, keepNulls, upsertMode)
821
892
  ```
893
+
822
894
  The switch details are,
823
895
 
824
896
  deferCommandExecution (true/false) choose between syncronoys and asyncronous command execution, default is false.
@@ -826,12 +898,11 @@ deferDataGeneration (true/false) choose between syncronoys and asyncronous preco
826
898
  keepNulls (true/false) if true then nulls are written in the curve replacing any data present for the instant, default is false.
827
899
  upsertMode (Merge/Replace) for ActualTimeSeries the two modes are equivalent. Leaving Null/None/Empty is equivalent to Merge.
828
900
 
829
-
830
- DerivedCfg can be of algorithm type: Coalesce, Sum, Muv.
901
+ DerivedCfg can be of algorithm type: Coalesce, Sum, Muv, Transform.
831
902
 
832
903
  Updating the DerivedCfg can be performed with `updateDerivedConfiguration` on MarketDataService. A validation will be done on the existing DerivedCfg of the MarketData, that should be not null and with same type as the one used for the update.
833
904
 
834
- ```csharp
905
+ ```Python
835
906
  derivedCfgUpdate = DerivedCfg(
836
907
  version=1,
837
908
  derivedAlgorithm=DerivedAlgorithm.Coalesce,
@@ -844,6 +915,31 @@ marketDataUpdated = mkdservice.updateDerivedConfiguration(
844
915
  False)
845
916
  ```
846
917
 
918
+ For DerivedCfg Transform, `orderedReferencedMarketDataIds` contains a single source series (the series where the transform is applied), and `transform` contains the query to apply.
919
+
920
+ ```Python
921
+ derivedCfgUpdate = DerivedCfg(
922
+ version=1,
923
+ derivedAlgorithm=DerivedAlgorithm.Transform,
924
+ orderedReferencedMarketDataIds=[10001],
925
+ transform="SELECT Time, (Value + 1) as Value FROM $table"
926
+ )
927
+
928
+ marketDataUpdated = mkdservice.updateDerivedConfiguration(
929
+ registeredDerived.marketDataId,
930
+ derivedCfgUpdate,
931
+ False)
932
+ ```
933
+
934
+ #### Available Columns
935
+
936
+ | Column | Type |
937
+ | ------ | -------- |
938
+ | Time | datetime |
939
+ | Value | double |
940
+
941
+ > `$table` is a virtual table exposed by the query engine.
942
+
847
943
  In case we want to write an hourly (or lower) time series the timezone for the upsert data must be UTC:
848
944
 
849
945
  ```Python
@@ -926,9 +1022,11 @@ mkservice.upsertData(data)
926
1022
  ```
927
1023
 
928
1024
  Upsert has optional switches that can be applied
1025
+
929
1026
  ```
930
1027
  mkservice.upsertData(data, deferCommandExecution, deferDataGeneration, keepNulls, upsertMode)
931
1028
  ```
1029
+
932
1030
  The switch details are,
933
1031
 
934
1032
  deferCommandExecution (true/false) choose between syncronoys and asyncronous command execution, default is false.
@@ -936,25 +1034,24 @@ deferDataGeneration (true/false) choose between syncronoys and asyncronous preco
936
1034
  keepNulls (true/false) if true then nulls are written in the curve replacing any data present for the instant, default is false.
937
1035
  upsertMode (Merge/Replace) for VersionedTimeSeries the merge writes in to the curve replacing existing data for an existing instant, replace writes the payload removing any previous data for the version. Leaving Null/None/Empty is equivalent to Merge.
938
1036
 
939
- | DATETIME | EXISTING | PAYLOAD | MERGE | REPALACE |
940
- |---|---|---|---|---|
1037
+ | DATETIME | EXISTING | PAYLOAD | MERGE | REPLACE |
1038
+ | ------------ | ---------- | ---------- | ---------- | ---------- |
941
1039
  | VERSION NAME | 2025-01-01 | 2025-01-01 | 2025-01-01 | 2025-01-01 |
942
- | 2025-01-01 | | | | |
943
- | 2025-01-02 | 999.99 | 222.22 | 222.22 | 222.22 |
944
- | 2025-01-03 | 999.99 | 222.22 | 222.22 | 222.22 |
945
- | 2025-01-04 | 999.99 | 222.22 | 222.22 | 222.22 |
946
- | 2025-01-05 | 999.99 | 222.22 | 222.22 | 222.22 |
947
- | 2025-01-06 | 999.99 | 222.22 | 222.22 | 222.22 |
948
- | 2025-01-07 | 999.99 | 222.22 | 222.22 | 222.22 |
949
- | 2025-01-08 | | 222.22 | 222.22 | 222.22 |
950
- | 2025-01-09 | | | | |
951
- | 2025-01-10 | | | | |
952
- | 2025-01-11 | 999.99 | | 999.99 | |
953
- | 2025-01-12 | 999.99 | | 999.99 | |
954
- | 2025-01-13 | 999.99 | | 999.99 | |
955
- | 2025-01-14 | | | | |
956
- | 2025-01-15 | | | | |
957
-
1040
+ | 2025-01-01 | | | | |
1041
+ | 2025-01-02 | 999.99 | 222.22 | 222.22 | 222.22 |
1042
+ | 2025-01-03 | 999.99 | 222.22 | 222.22 | 222.22 |
1043
+ | 2025-01-04 | 999.99 | 222.22 | 222.22 | 222.22 |
1044
+ | 2025-01-05 | 999.99 | 222.22 | 222.22 | 222.22 |
1045
+ | 2025-01-06 | 999.99 | 222.22 | 222.22 | 222.22 |
1046
+ | 2025-01-07 | 999.99 | 222.22 | 222.22 | 222.22 |
1047
+ | 2025-01-08 | | 222.22 | 222.22 | 222.22 |
1048
+ | 2025-01-09 | | | | |
1049
+ | 2025-01-10 | | | | |
1050
+ | 2025-01-11 | 999.99 | | 999.99 | |
1051
+ | 2025-01-12 | 999.99 | | 999.99 | |
1052
+ | 2025-01-13 | 999.99 | | 999.99 | |
1053
+ | 2025-01-14 | | | | |
1054
+ | 2025-01-15 | | | | |
958
1055
 
959
1056
  ### Write Data in a Market Assessment Time Series
960
1057
 
@@ -1004,9 +1101,11 @@ mkservice.upsertData(marketAssessment)
1004
1101
  ```
1005
1102
 
1006
1103
  Upsert has optional switches that can be applied
1104
+
1007
1105
  ```
1008
1106
  mkservice.upsertData(data, deferCommandExecution, deferDataGeneration, keepNulls, upsertMode)
1009
1107
  ```
1108
+
1010
1109
  The switch details are,
1011
1110
 
1012
1111
  deferCommandExecution (true/false) choose between syncronoys and asyncronous command execution, default is false.
@@ -1014,7 +1113,6 @@ deferDataGeneration (true/false) choose between syncronoys and asyncronous preco
1014
1113
  keepNulls (true/false) if true then nulls are written in the curve replacing any data present for the instant, default is false.
1015
1114
  upsertMode (Merge/Replace) for MarketAssessment merge adds the new products to the existing and overwrites existing with the new ones while replace replaces all the existing products with the new ones. Leaving Null/None/Empty is equivalent to Merge.
1016
1115
 
1017
-
1018
1116
  ### Write Data in a Bid Ask Time Series
1019
1117
 
1020
1118
  ```Python
@@ -1062,9 +1160,11 @@ mkservice.upsertData(bidAsk)
1062
1160
  ```
1063
1161
 
1064
1162
  Upsert has optional switches that can be applied
1163
+
1065
1164
  ```
1066
1165
  mkservice.upsertData(data, deferCommandExecution, deferDataGeneration, keepNulls, upsertMode)
1067
1166
  ```
1167
+
1068
1168
  The switch details are,
1069
1169
 
1070
1170
  deferCommandExecution (true/false) choose between syncronoys and asyncronous command execution, default is false.
@@ -1072,7 +1172,6 @@ deferDataGeneration (true/false) choose between syncronoys and asyncronous preco
1072
1172
  keepNulls (true/false) if true then nulls are written in the curve replacing any data present for the instant, default is false.
1073
1173
  upsertMode (Merge/Replace) for BidAsk merge adds the new products to the existing and overwrites existing with the new ones while replace replaces all the existing products with the new ones. Leaving Null/None/Empty is equivalent to Merge.
1074
1174
 
1075
-
1076
1175
  ### Write Data in an Auction Time Series
1077
1176
 
1078
1177
  ```Python
@@ -1120,9 +1219,11 @@ auctionRows = MarketData.UpsertData(MarketData.MarketDataIdentifier('PROVIDER',
1120
1219
  ```
1121
1220
 
1122
1221
  Upsert has optional switches that can be applied
1222
+
1123
1223
  ```
1124
1224
  mkservice.upsertData(data, deferCommandExecution, deferDataGeneration, keepNulls, upsertMode)
1125
1225
  ```
1226
+
1126
1227
  The switch details are,
1127
1228
 
1128
1229
  deferCommandExecution (true/false) choose between syncronoys and asyncronous command execution, default is false.
@@ -1130,7 +1231,6 @@ deferDataGeneration (true/false) choose between syncronoys and asyncronous preco
1130
1231
  keepNulls (true/false) if true then nulls are written in the curve replacing any data present for the instant, default is false.
1131
1232
  upsertMode (Merge/Replace) for Auction merge and replace are equivalent. Leaving Null/None/Empty is equivalent to Merge.
1132
1233
 
1133
-
1134
1234
  ## Delete Data in Artesian
1135
1235
 
1136
1236
  Using the MarketDataService is possible to delete MarketData and its curves.
@@ -414,8 +414,8 @@ Artesian support Query over GME Public Offers which comes in a custom and dedica
414
414
  Note (performance):
415
415
  GME Public Offer data is partitioned by date, offerType, status, and market. Requesting very narrow subsets (for example a single status or offerType in several separate requests) does not improve performance and can cause the same data to be fetched multiple times.
416
416
  For this reason, the examples below:
417
- Use a large page size so that all data for a given (date, market, filters) is typically returned in a single page.
418
- Loop over markets explicitly to cover all required markets without redundant fetches.
417
+ Use a large page size so that all data for a given (date, market, filters) is typically returned in a single page.
418
+ Loop over markets explicitly to cover all required markets without redundant fetches.
419
419
 
420
420
  ### Extract GME Public Offer
421
421
 
@@ -708,6 +708,76 @@ Extraction options for GME Public Offer queries.
708
708
  .withAggregationRule(AggregationRule.SumAndDivide)
709
709
  ```
710
710
 
711
+ ### DerivedTransform: Query Validation
712
+
713
+ Use the `DerivedTransformQueryValidation` to validate and execute a derived transform query against a sample TimeSerieData.
714
+
715
+ ```Python
716
+ from Artesian.MarketData import MarketDataService
717
+ from Artesian.MarketData._Dto.DerivedTransformQueryValidation import DerivedTransformQueryValidation
718
+ from Artesian.MarketData._Dto.TimeSerieData import TimeSerieData
719
+ from Artesian import MarketDataType
720
+ from datetime import datetime
721
+
722
+ mds = MarketDataService(cfg)
723
+
724
+ request = DerivedTransformQueryValidation(
725
+ data=TimeSerieData(
726
+ rows=[
727
+ (datetime(2018, 10, 1, 0, 0), 100),
728
+ (datetime(2018, 10, 1, 1, 0), 100)
729
+ ],
730
+ type=MarketDataType.ActualTimeSerie,
731
+ ),
732
+ transform="SELECT Time, (Value + 1) as Value FROM $table"
733
+ )
734
+
735
+ derivedTransformResponse = mds.derivedTransformQueryValidation(request)
736
+ ```
737
+
738
+ #### Available Columns
739
+
740
+ | Column | Type |
741
+ | ------ | -------- |
742
+ | Time | datetime |
743
+ | Value | double |
744
+
745
+ > `$table` is a virtual table exposed by the query engine.
746
+
747
+ **Returned Object: DerivedTransformQueryValidationResponse**
748
+
749
+ | Property | Description |
750
+ | -------- | ---------------------------------------------- |
751
+ | Data | Transformed time series generated by the query |
752
+ | Valid | Indicates whether the query is valid |
753
+ | Error | Validation error details when `Valid = false` |
754
+
755
+ #### Query examples
756
+
757
+ ```sql
758
+ SELECT Time + INTERVAL 1 DAY AS Time, Value FROM $table
759
+
760
+ SELECT Time, CASE WHEN EXTRACT(HOUR FROM (Time AT TIME ZONE 'UTC') AT TIME ZONE 'Europe/Rome') < 10 THEN Value + 1 ELSE Value END AS Value FROM $table WHERE Time IS NOT NULL
761
+
762
+ SELECT Time, Value FROM $table WHERE Version IS NOT NULL AND ((EXTRACT(hour FROM Version) < 10 AND Time >= date_trunc('day', Version + interval '1 day')) OR (EXTRACT(hour FROM Version) >= 10 AND Time >= date_trunc('day', Version + interval '2 day')))
763
+ ```
764
+
765
+ #### SQL Dialect & Execution Model
766
+
767
+ The query engine uses a DuckDB-compatible SQL dialect (PostgreSQL-like).
768
+
769
+ Queries are executed against a virtual table named `$table`, which represents the provided sample TimeSerieData.
770
+
771
+ The engine supports common SQL features including:
772
+
773
+ - SELECT expressions
774
+ - WHERE filtering
775
+ - CASE WHEN expressions
776
+ - Date/time arithmetic and functions
777
+ - Timezone conversion functions
778
+
779
+ Full DuckDB SQL reference: https://duckdb.org/docs/sql/introduction.html
780
+
711
781
  ## Write Data in Artesian
712
782
 
713
783
  Using the MarketDataService is possible to register MarketData and write curves into it using the UpsertData method.
@@ -761,9 +831,11 @@ mkservice.upsertData(data)
761
831
  ```
762
832
 
763
833
  Upsert has optional switches that can be applied
834
+
764
835
  ```
765
836
  mkservice.upsertData(data, deferCommandExecution, deferDataGeneration, keepNulls, upsertMode)
766
837
  ```
838
+
767
839
  The switch details are,
768
840
 
769
841
  deferCommandExecution (true/false) choose between syncronoys and asyncronous command execution, default is false.
@@ -771,12 +843,11 @@ deferDataGeneration (true/false) choose between syncronoys and asyncronous preco
771
843
  keepNulls (true/false) if true then nulls are written in the curve replacing any data present for the instant, default is false.
772
844
  upsertMode (Merge/Replace) for ActualTimeSeries the two modes are equivalent. Leaving Null/None/Empty is equivalent to Merge.
773
845
 
774
-
775
- DerivedCfg can be of algorithm type: Coalesce, Sum, Muv.
846
+ DerivedCfg can be of algorithm type: Coalesce, Sum, Muv, Transform.
776
847
 
777
848
  Updating the DerivedCfg can be performed with `updateDerivedConfiguration` on MarketDataService. A validation will be done on the existing DerivedCfg of the MarketData, that should be not null and with same type as the one used for the update.
778
849
 
779
- ```csharp
850
+ ```Python
780
851
  derivedCfgUpdate = DerivedCfg(
781
852
  version=1,
782
853
  derivedAlgorithm=DerivedAlgorithm.Coalesce,
@@ -789,6 +860,31 @@ marketDataUpdated = mkdservice.updateDerivedConfiguration(
789
860
  False)
790
861
  ```
791
862
 
863
+ For DerivedCfg Transform, `orderedReferencedMarketDataIds` contains a single source series (the series where the transform is applied), and `transform` contains the query to apply.
864
+
865
+ ```Python
866
+ derivedCfgUpdate = DerivedCfg(
867
+ version=1,
868
+ derivedAlgorithm=DerivedAlgorithm.Transform,
869
+ orderedReferencedMarketDataIds=[10001],
870
+ transform="SELECT Time, (Value + 1) as Value FROM $table"
871
+ )
872
+
873
+ marketDataUpdated = mkdservice.updateDerivedConfiguration(
874
+ registeredDerived.marketDataId,
875
+ derivedCfgUpdate,
876
+ False)
877
+ ```
878
+
879
+ #### Available Columns
880
+
881
+ | Column | Type |
882
+ | ------ | -------- |
883
+ | Time | datetime |
884
+ | Value | double |
885
+
886
+ > `$table` is a virtual table exposed by the query engine.
887
+
792
888
  In case we want to write an hourly (or lower) time series the timezone for the upsert data must be UTC:
793
889
 
794
890
  ```Python
@@ -871,9 +967,11 @@ mkservice.upsertData(data)
871
967
  ```
872
968
 
873
969
  Upsert has optional switches that can be applied
970
+
874
971
  ```
875
972
  mkservice.upsertData(data, deferCommandExecution, deferDataGeneration, keepNulls, upsertMode)
876
973
  ```
974
+
877
975
  The switch details are,
878
976
 
879
977
  deferCommandExecution (true/false) choose between syncronoys and asyncronous command execution, default is false.
@@ -881,25 +979,24 @@ deferDataGeneration (true/false) choose between syncronoys and asyncronous preco
881
979
  keepNulls (true/false) if true then nulls are written in the curve replacing any data present for the instant, default is false.
882
980
  upsertMode (Merge/Replace) for VersionedTimeSeries the merge writes in to the curve replacing existing data for an existing instant, replace writes the payload removing any previous data for the version. Leaving Null/None/Empty is equivalent to Merge.
883
981
 
884
- | DATETIME | EXISTING | PAYLOAD | MERGE | REPALACE |
885
- |---|---|---|---|---|
982
+ | DATETIME | EXISTING | PAYLOAD | MERGE | REPLACE |
983
+ | ------------ | ---------- | ---------- | ---------- | ---------- |
886
984
  | VERSION NAME | 2025-01-01 | 2025-01-01 | 2025-01-01 | 2025-01-01 |
887
- | 2025-01-01 | | | | |
888
- | 2025-01-02 | 999.99 | 222.22 | 222.22 | 222.22 |
889
- | 2025-01-03 | 999.99 | 222.22 | 222.22 | 222.22 |
890
- | 2025-01-04 | 999.99 | 222.22 | 222.22 | 222.22 |
891
- | 2025-01-05 | 999.99 | 222.22 | 222.22 | 222.22 |
892
- | 2025-01-06 | 999.99 | 222.22 | 222.22 | 222.22 |
893
- | 2025-01-07 | 999.99 | 222.22 | 222.22 | 222.22 |
894
- | 2025-01-08 | | 222.22 | 222.22 | 222.22 |
895
- | 2025-01-09 | | | | |
896
- | 2025-01-10 | | | | |
897
- | 2025-01-11 | 999.99 | | 999.99 | |
898
- | 2025-01-12 | 999.99 | | 999.99 | |
899
- | 2025-01-13 | 999.99 | | 999.99 | |
900
- | 2025-01-14 | | | | |
901
- | 2025-01-15 | | | | |
902
-
985
+ | 2025-01-01 | | | | |
986
+ | 2025-01-02 | 999.99 | 222.22 | 222.22 | 222.22 |
987
+ | 2025-01-03 | 999.99 | 222.22 | 222.22 | 222.22 |
988
+ | 2025-01-04 | 999.99 | 222.22 | 222.22 | 222.22 |
989
+ | 2025-01-05 | 999.99 | 222.22 | 222.22 | 222.22 |
990
+ | 2025-01-06 | 999.99 | 222.22 | 222.22 | 222.22 |
991
+ | 2025-01-07 | 999.99 | 222.22 | 222.22 | 222.22 |
992
+ | 2025-01-08 | | 222.22 | 222.22 | 222.22 |
993
+ | 2025-01-09 | | | | |
994
+ | 2025-01-10 | | | | |
995
+ | 2025-01-11 | 999.99 | | 999.99 | |
996
+ | 2025-01-12 | 999.99 | | 999.99 | |
997
+ | 2025-01-13 | 999.99 | | 999.99 | |
998
+ | 2025-01-14 | | | | |
999
+ | 2025-01-15 | | | | |
903
1000
 
904
1001
  ### Write Data in a Market Assessment Time Series
905
1002
 
@@ -949,9 +1046,11 @@ mkservice.upsertData(marketAssessment)
949
1046
  ```
950
1047
 
951
1048
  Upsert has optional switches that can be applied
1049
+
952
1050
  ```
953
1051
  mkservice.upsertData(data, deferCommandExecution, deferDataGeneration, keepNulls, upsertMode)
954
1052
  ```
1053
+
955
1054
  The switch details are,
956
1055
 
957
1056
  deferCommandExecution (true/false) choose between syncronoys and asyncronous command execution, default is false.
@@ -959,7 +1058,6 @@ deferDataGeneration (true/false) choose between syncronoys and asyncronous preco
959
1058
  keepNulls (true/false) if true then nulls are written in the curve replacing any data present for the instant, default is false.
960
1059
  upsertMode (Merge/Replace) for MarketAssessment merge adds the new products to the existing and overwrites existing with the new ones while replace replaces all the existing products with the new ones. Leaving Null/None/Empty is equivalent to Merge.
961
1060
 
962
-
963
1061
  ### Write Data in a Bid Ask Time Series
964
1062
 
965
1063
  ```Python
@@ -1007,9 +1105,11 @@ mkservice.upsertData(bidAsk)
1007
1105
  ```
1008
1106
 
1009
1107
  Upsert has optional switches that can be applied
1108
+
1010
1109
  ```
1011
1110
  mkservice.upsertData(data, deferCommandExecution, deferDataGeneration, keepNulls, upsertMode)
1012
1111
  ```
1112
+
1013
1113
  The switch details are,
1014
1114
 
1015
1115
  deferCommandExecution (true/false) choose between syncronoys and asyncronous command execution, default is false.
@@ -1017,7 +1117,6 @@ deferDataGeneration (true/false) choose between syncronoys and asyncronous preco
1017
1117
  keepNulls (true/false) if true then nulls are written in the curve replacing any data present for the instant, default is false.
1018
1118
  upsertMode (Merge/Replace) for BidAsk merge adds the new products to the existing and overwrites existing with the new ones while replace replaces all the existing products with the new ones. Leaving Null/None/Empty is equivalent to Merge.
1019
1119
 
1020
-
1021
1120
  ### Write Data in an Auction Time Series
1022
1121
 
1023
1122
  ```Python
@@ -1065,9 +1164,11 @@ auctionRows = MarketData.UpsertData(MarketData.MarketDataIdentifier('PROVIDER',
1065
1164
  ```
1066
1165
 
1067
1166
  Upsert has optional switches that can be applied
1167
+
1068
1168
  ```
1069
1169
  mkservice.upsertData(data, deferCommandExecution, deferDataGeneration, keepNulls, upsertMode)
1070
1170
  ```
1171
+
1071
1172
  The switch details are,
1072
1173
 
1073
1174
  deferCommandExecution (true/false) choose between syncronoys and asyncronous command execution, default is false.
@@ -1075,7 +1176,6 @@ deferDataGeneration (true/false) choose between syncronoys and asyncronous preco
1075
1176
  keepNulls (true/false) if true then nulls are written in the curve replacing any data present for the instant, default is false.
1076
1177
  upsertMode (Merge/Replace) for Auction merge and replace are equivalent. Leaving Null/None/Empty is equivalent to Merge.
1077
1178
 
1078
-
1079
1179
  ## Delete Data in Artesian
1080
1180
 
1081
1181
  Using the MarketDataService is possible to delete MarketData and its curves.
@@ -5,7 +5,7 @@ cfg = ArtesianConfig("https://arkive.artesian.cloud/tenantName/", "APIKey")
5
5
 
6
6
  qs = QueryService(cfg)
7
7
 
8
- # AbsoluteRange - TimeZone - MultiIds
8
+ # AbsoluteRange - TimeZone - MultiIds
9
9
  test1 = (
10
10
  qs.createActual()
11
11
  .forMarketData(
@@ -0,0 +1,101 @@
1
+ from datetime import datetime
2
+ import Artesian
3
+ from Artesian.Granularity import Granularity
4
+ from Artesian.MarketData._Dto.DerivedCfg import DerivedCfg
5
+ from Artesian.MarketData._Enum.DerivedAlgorithm import DerivedAlgorithm
6
+ from Artesian.MarketData._Enum.MarketDataType import MarketDataType
7
+ import time
8
+
9
+ cfg = Artesian.ArtesianConfig("https://arkive.artesian.cloud/tenantName/", "APIKey")
10
+
11
+ mkdservice = Artesian.MarketData.MarketDataService(cfg)
12
+
13
+ # curveOne
14
+ actualCurveOne = Artesian.MarketData.MarketDataEntityInput(
15
+ "TestProviderNameDerivedTransform",
16
+ "CurveOne",
17
+ Granularity.Hour,
18
+ MarketDataType.ActualTimeSerie,
19
+ "UTC"
20
+ )
21
+
22
+ registeredCurveOne = mkdservice.readMarketDataRegistryByName(
23
+ actualCurveOne.providerName, actualCurveOne.marketDataName
24
+ )
25
+ if registeredCurveOne is None:
26
+ registeredCurveOne = mkdservice.registerMarketData(actualCurveOne)
27
+
28
+ marketIdentifierCurveOne = Artesian.MarketData.MarketDataIdentifier(
29
+ actualCurveOne.providerName, actualCurveOne.marketDataName
30
+ )
31
+
32
+ # mkdservice.deleteMarketData(registeredCurveOne.marketDataId)
33
+
34
+ data = Artesian.MarketData.UpsertData(
35
+ marketIdentifierCurveOne,
36
+ "UTC",
37
+ rows={datetime(2020, 1, 1, h): 10 for h in range(0, 8)},
38
+ )
39
+
40
+ mkdservice.upsertData(data)
41
+
42
+ curveIds = [registeredCurveOne.marketDataId]
43
+
44
+ # Create DerivedCfgTransform
45
+ derivedCfg = DerivedCfg(
46
+ version=1,
47
+ derivedAlgorithm=DerivedAlgorithm.Transform,
48
+ transform="SELECT Time, (Value + 1) as Value FROM $table",
49
+ orderedReferencedMarketDataIds=curveIds,
50
+ )
51
+
52
+ actualCurveDerived = Artesian.MarketData.MarketDataEntityInput(
53
+ "TestProviderNameDerivedTransform",
54
+ "CurveDerived",
55
+ Granularity.Hour,
56
+ MarketDataType.ActualTimeSerie,
57
+ "UTC",
58
+ derivedCfg=derivedCfg,
59
+ )
60
+
61
+ registeredDerived = mkdservice.readMarketDataRegistryByName(
62
+ actualCurveDerived.providerName, actualCurveDerived.marketDataName
63
+ )
64
+
65
+ # mkdservice.deleteMarketData(registeredDerived.marketDataId)
66
+
67
+ if registeredDerived is None:
68
+ registeredDerived = mkdservice.registerMarketData(actualCurveDerived)
69
+
70
+ # check that derivedCfg is as expected
71
+ assert (
72
+ registeredDerived.derivedCfg is not None
73
+ and registeredDerived.derivedCfg.derivedAlgorithm == DerivedAlgorithm.Transform
74
+ ), "Derived Algorithm is not the expected (Transform)"
75
+
76
+ marketIdentifierDerived = Artesian.MarketData.MarketDataIdentifier(
77
+ actualCurveDerived.providerName, actualCurveDerived.marketDataName
78
+ )
79
+
80
+ time.sleep(2)
81
+
82
+ # get the derived curve and check values are in according to the configuration
83
+ query = Artesian.Query.QueryService(cfg)
84
+
85
+ res = (
86
+ query.createActual()
87
+ .forMarketData([registeredDerived.marketDataId])
88
+ .inAbsoluteDateRange("2020-01-01", "2020-01-02")
89
+ .inTimeZone("UTC")
90
+ .inGranularity(Granularity.Hour)
91
+ .execute()
92
+ )
93
+
94
+ print(res)
95
+
96
+ for i in range(0, 8):
97
+ assert res[i]['D'] == 11
98
+
99
+ # Delete the curves completely
100
+ mkdservice.deleteMarketData(registeredCurveOne.marketDataId)
101
+ mkdservice.deleteMarketData(registeredDerived.marketDataId)
@@ -0,0 +1,37 @@
1
+ from datetime import datetime
2
+ import Artesian
3
+ from Artesian.MarketData._Dto.DerivedTransformQueryValidation import (
4
+ DerivedTransformQueryValidation,
5
+ )
6
+ from Artesian.MarketData._Dto.TimeSerieData import TimeSerieData
7
+ from Artesian.MarketData._Enum.MarketDataType import MarketDataType
8
+
9
+ cfg = Artesian.ArtesianConfig("https://arkive.artesian.cloud/tenantName/", "APIKey")
10
+
11
+ mkdservice = Artesian.MarketData.MarketDataService(cfg)
12
+
13
+ # Validate a transform query against in-memory sample time-series data.
14
+ derivedTransformQueryValidation = DerivedTransformQueryValidation(
15
+ data=TimeSerieData(
16
+ type=MarketDataType.ActualTimeSerie,
17
+ timezone="UTC",
18
+ rows={
19
+ datetime(2020, 1, 1, 0): 10.0,
20
+ datetime(2020, 1, 1, 1): 11.0,
21
+ },
22
+ ),
23
+ transform="SELECT Time, Value + 1 AS Value FROM $table"
24
+ )
25
+
26
+ result = mkdservice.derivedTransformQueryValidation(derivedTransformQueryValidation)
27
+
28
+ assert result.valid, (
29
+ f"Derived transform query is not valid: "
30
+ f"{result.error.message if result.error else 'unknown error'}"
31
+ )
32
+
33
+ assert result.data.rows is not None, "Expected transformed rows in response"
34
+ assert result.data.rows[datetime(2020, 1, 1, 0)] == 11.0
35
+ assert result.data.rows[datetime(2020, 1, 1, 1)] == 12.0
36
+
37
+ print(result)