@prefix shape: <https://semanticdataservices.com/ontology/shapes/financial#> .
@prefix party: <https://semanticdataservices.com/ontology/domain/party-organization#> .
@prefix inst: <https://semanticdataservices.com/ontology/domain/financial-instrument#> .
@prefix market: <https://semanticdataservices.com/ontology/domain/market-data#> .
@prefix port: <https://semanticdataservices.com/ontology/domain/portfolio#> .
@prefix trade: <https://semanticdataservices.com/ontology/domain/trading#> .
@prefix signal: <https://semanticdataservices.com/ontology/domain/prediction-signal#> .
@prefix cyber: <https://semanticdataservices.com/ontology/domain/cybersecurity#> .
@prefix risk: <https://semanticdataservices.com/ontology/domain/risk#> .
@prefix sdsu: <https://semanticdataservices.com/ontology/core/upper#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix dct: <http://purl.org/dc/terms/> .

<https://semanticdataservices.com/ontology/shapes/financial> a owl:Ontology ;
  owl:versionIRI <https://semanticdataservices.com/ontology/2026.08/shapes/financial> ; owl:versionInfo "2026.08" ;
  owl:imports <https://semanticdataservices.com/ontology/core/enterprise> ;
  dct:title "SDS Financial SHACL Shapes"@en ; dct:creator "Semantic Data Services" .

shape:LegalEntityIdentifierShape a sh:NodeShape ;
  sh:targetClass party:LegalEntityIdentifier ;
  sh:property [ sh:path party:leiCode ; sh:name "LEI code" ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:string ; sh:pattern "^[A-Z0-9]{18}[0-9]{2}$" ; sh:message "LEI must contain 20 uppercase alphanumeric characters."@en ] .

shape:MarketObservationShape a sh:NodeShape ;
  sh:targetClass market:MarketObservation ;
  sh:property [ sh:path market:observedInstrument ; sh:minCount 1 ; sh:maxCount 1 ; sh:class inst:FinancialInstrument ; sh:message "Every market observation must identify exactly one financial instrument."@en ] ;
  sh:property [ sh:path sdsu:eventTime ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:dateTime ] ;
  sh:property [ sh:path sdsu:ingestionTime ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:dateTime ] ;
  sh:property [ sh:path market:priceCurrency ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:string ; sh:pattern "^[A-Z]{3}$" ] ;
  sh:property [ sh:path sdsu:sourceRecordId ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:string ] .

shape:TradePrintShape a sh:NodeShape ;
  sh:targetClass market:TradePrint ;
  sh:property [ sh:path market:lastPrice ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:decimal ; sh:minExclusive 0 ] ;
  sh:property [ sh:path market:tradeVolume ; sh:minCount 1 ; sh:datatype xsd:decimal ; sh:minExclusive 0 ] .

shape:OrderShape a sh:NodeShape ;
  sh:targetClass trade:Order ;
  sh:property [ sh:path trade:clientOrderId ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:string ] ;
  sh:property [ sh:path trade:ordersInstrument ; sh:minCount 1 ; sh:maxCount 1 ; sh:class inst:FinancialInstrument ] ;
  sh:property [ sh:path trade:orderSide ; sh:minCount 1 ; sh:maxCount 1 ; sh:in ( "BUY" "SELL" "SELL_SHORT" ) ] ;
  sh:property [ sh:path trade:orderQuantity ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:decimal ; sh:minExclusive 0 ] .

shape:PositionShape a sh:NodeShape ;
  sh:targetClass port:Position ;
  sh:property [ sh:path port:positionInstrument ; sh:minCount 1 ; sh:maxCount 1 ; sh:class inst:FinancialInstrument ] ;
  sh:property [ sh:path port:quantity ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:decimal ] .

shape:PriceMovementPredictionShape a sh:NodeShape ;
  sh:targetClass signal:PriceMovementPrediction ;
  sh:property [ sh:path signal:aboutInstrument ; sh:minCount 1 ; sh:maxCount 1 ; sh:class inst:FinancialInstrument ] ;
  sh:property [ sh:path signal:producedByModel ; sh:minCount 1 ; sh:maxCount 1 ; sh:class signal:ModelVersion ] ;
  sh:property [ sh:path signal:confidence ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:decimal ; sh:minInclusive 0 ; sh:maxInclusive 1 ] ;
  sh:property [ sh:path signal:direction ; sh:minCount 1 ; sh:maxCount 1 ; sh:in ( "UP" "DOWN" "NEUTRAL" ) ] ;
  sh:property [ sh:path signal:explainedBy ; sh:minCount 1 ; sh:class signal:Explanation ; sh:message "A prediction must expose at least one explanation/evidence resource."@en ] .

shape:SecurityIncidentShape a sh:NodeShape ;
  sh:targetClass cyber:SecurityIncident ;
  sh:property [ sh:path cyber:targetsAsset ; sh:minCount 1 ; sh:class cyber:CyberAsset ] ;
  sh:property [ sh:path cyber:createsRisk ; sh:minCount 1 ; sh:class risk:CyberRisk ] ;
  sh:property [ sh:path cyber:severity ; sh:minCount 1 ; sh:maxCount 1 ; sh:in ( "LOW" "MEDIUM" "HIGH" "CRITICAL" ) ] ;
  sh:property [ sh:path sdsu:eventTime ; sh:minCount 1 ; sh:maxCount 1 ; sh:datatype xsd:dateTime ] .

