FpML Integration Guide¶
Neutryx provides comprehensive support for FpML (Financial products Markup Language), the industry-standard XML format for representing derivatives trades and market data. For a high-level introduction to the platform, refer to the project README.
Overview¶
The FpML integration enables:
- Parsing FpML 5.x XML documents
- Mapping FpML trades to Neutryx pricing models
- Pricing FpML trades using JAX-accelerated Monte Carlo engines
- Serializing Neutryx results back to FpML format
- Validation of FpML document structure
Architecture¶
┌─────────────────────────────────────────────────────────────────┐
│ FpML Integration Layer │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Parser │──▶│ Mappings │──▶│ Neutryx │ │
│ │ (XML→Py) │ │ (FpML→Req) │ │ Engine │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Serializer │◀──│ Mappings │◀──│ Results │ │
│ │ (Py→XML) │ │ (Req→FpML) │ │ │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Module Structure¶
src/neutryx/bridge/fpml/
├── __init__.py # Public API exports
├── schemas.py # Pydantic models for FpML elements
├── parser.py # XML → Pydantic conversion
├── serializer.py # Pydantic → XML conversion
└── mappings.py # FpML ⇔ Neutryx conversion
src/neutryx/bridge/
└── fpml_adapter.py # High-level workflow API
Quick Start¶
1. Parse FpML Document¶
from neutryx.integrations import fpml
# Load FpML XML
with open("trade.xml") as f:
fpml_xml = f.read()
# Parse to structured format
fpml_doc = fpml.parse_fpml(fpml_xml)
# Access trade details
trade = fpml_doc.primary_trade
print(f"Trade date: {trade.tradeHeader.tradeDate}")
if trade.equityOption:
print(f"Strike: {trade.equityOption.strike.strikePrice}")
2. Price FpML Trade¶
from neutryx.integrations.fpml_adapter import quick_price_fpml
# Define market data
market_data = {
"spot": 155.0,
"volatility": 0.25,
"rate": 0.05,
"dividend": 0.01,
}
# Price the trade
price = quick_price_fpml(fpml_xml, market_data)
print(f"Price: ${price:.2f}")
3. Convert to FpML¶
from datetime import date
from neutryx.api.rest import VanillaOptionRequest
from neutryx.integrations import fpml
# Create pricing request
request = VanillaOptionRequest(
spot=100.0,
strike=105.0,
maturity=1.0,
volatility=0.25,
call=True,
)
# Convert to FpML
fpml_doc = fpml.neutryx_to_fpml(
request,
instrument_id="US0378331005",
trade_date=date.today()
)
# Serialize to XML
xml_output = fpml.serialize_fpml(fpml_doc)
Supported Products¶
Equity Options¶
Supported Features: - Put/Call specification - European and American exercise - Strike price - Underlyer identification (ISIN, RIC, etc.) - Expiration dates - Number of options - Settlement type
Example FpML:
<equityOption>
<buyerPartyReference href="party1"/>
<sellerPartyReference href="party2"/>
<optionType>Call</optionType>
<underlyer>
<instrumentId>US0378331005</instrumentId>
<description>Apple Inc.</description>
</underlyer>
<strike>
<strikePrice>150.00</strikePrice>
</strike>
<equityExercise>
<equityEuropeanExercise>
<expirationDate>
<adjustableDate>
<unadjustedDate>2025-01-15</unadjustedDate>
</adjustableDate>
</expirationDate>
</equityEuropeanExercise>
</equityExercise>
</equityOption>
FX Options¶
Supported Features: - Currency pair specification - Put/Call currency amounts - Strike rate - Spot rate - European and American exercise - Expiry date and time - Cut name (timezone)
Example FpML:
<fxOption>
<putCurrencyAmount>
<currency>USD</currency>
<amount>1100000.00</amount>
</putCurrencyAmount>
<callCurrencyAmount>
<currency>EUR</currency>
<amount>1000000.00</amount>
</callCurrencyAmount>
<strike>
<rate>1.10</rate>
</strike>
<europeanExercise>
<expiryDate>2025-01-15</expiryDate>
</europeanExercise>
</fxOption>
Interest Rate Swaps¶
Supported Features:
- ✅ Fixed and floating legs
- ✅ Notional schedules
- ✅ Payment frequencies (Monthly, Quarterly, Semiannual, Annual)
- ✅ Day count conventions (ACT/360, ACT/365, 30/360, ACT/ACT)
- ✅ Floating rate indices (LIBOR, SOFR, EURIBOR, ESTR)
- ✅ Calculation period dates with business day adjustments
- ✅ Present value calculation
- ✅ DV01 and risk metrics
- ✅ Cash flow schedule generation
Valuation: Full swap valuation is now implemented with JAX-accelerated pricing. The swap pricer supports: - Fixed vs. floating leg present value calculations - Discount factor curves - Payment schedule generation with business day conventions - Risk metrics including DV01 (dollar value of 1 basis point)
Example:
from neutryx.products.swap import price_vanilla_swap
# Price a 5-year interest rate swap
value = price_vanilla_swap(
notional=10_000_000, # $10M notional
fixed_rate=0.05, # 5% fixed rate
floating_rate=0.045, # 4.5% current floating rate
maturity=5.0, # 5 years
payment_frequency=2, # Semiannual payments
discount_rate=0.05, # 5% discount rate
pay_fixed=True # Pay fixed, receive floating
)
print(f"Swap Value: ${value:,.2f}")
API Reference¶
Core Functions¶
parse_fpml(xml_content: str) -> FpMLDocument¶
Parse FpML XML to structured Pydantic model.
Parameters:
- xml_content: FpML XML document as string
Returns:
- FpMLDocument: Parsed document with parties and trades
Raises:
- FpMLParseError: If XML is invalid or cannot be parsed
Example:
from neutryx.integrations import fpml
doc = fpml.parse_fpml(xml_string)
print(f"Parties: {len(doc.party)}")
print(f"Trades: {len(doc.trade)}")
fpml_to_neutryx(fpml_doc: FpMLDocument, market_data: dict) -> VanillaOptionRequest¶
Convert FpML document to Neutryx pricing request.
Parameters:
- fpml_doc: Parsed FpML document
- market_data: Dictionary with market data:
- For equity options: spot, volatility, rate, dividend
- For FX options: spot_rate, volatility, domestic_rate, foreign_rate
Returns:
- VanillaOptionRequest: Neutryx pricing request
Raises:
- FpMLMappingError: If required data missing or conversion fails
Example:
from neutryx.integrations import fpml
doc = fpml.parse_fpml(xml_string)
market_data = {"spot": 100.0, "volatility": 0.25, "rate": 0.05}
request = fpml.fpml_to_neutryx(doc, market_data)
neutryx_to_fpml(request: VanillaOptionRequest, instrument_id: str, trade_date: date) -> FpMLDocument¶
Convert Neutryx request to FpML document.
Parameters:
- request: Neutryx vanilla option request
- instrument_id: Underlying instrument identifier
- trade_date: Trade date
Returns:
- FpMLDocument: FpML document ready for serialization
Example:
from datetime import date
from neutryx.api.rest import VanillaOptionRequest
from neutryx.integrations import fpml
request = VanillaOptionRequest(
spot=100.0, strike=105.0, maturity=1.0, volatility=0.25, call=True
)
doc = fpml.neutryx_to_fpml(request, "US0378331005", date.today())
serialize_fpml(fpml_doc: FpMLDocument, pretty_print: bool = True) -> str¶
Serialize FpML document to XML string.
Parameters:
- fpml_doc: FpML document
- pretty_print: Whether to format with indentation
Returns: - XML string representation
Example:
from neutryx.integrations import fpml
xml_string = fpml.serialize_fpml(doc, pretty_print=True)
print(xml_string)
High-Level Adapter¶
FpMLPricingAdapter¶
Comprehensive adapter for end-to-end FpML workflows.
Methods:
- parse_xml(xml_content): Parse FpML XML
- price_from_xml(xml_content, market_data, mc_config): Price from XML
- price_from_document(fpml_doc, market_data, mc_config): Price from parsed doc
- export_to_fpml(...): Export parameters to FpML
Example:
from neutryx.integrations.fpml_adapter import FpMLPricingAdapter
from neutryx.core.engine import MCConfig
adapter = FpMLPricingAdapter(
default_mc_config=MCConfig(steps=252, paths=100_000),
seed=42
)
result = adapter.price_from_xml(fpml_xml, market_data)
print(f"Price: {result['price']}")
print(f"Trade info: {result['trade_info']}")
FpMLBatchPricer¶
Batch pricer for multiple trades.
Example:
from neutryx.integrations.fpml_adapter import FpMLBatchPricer
pricer = FpMLBatchPricer(seed=42)
results = pricer.price_multiple_xml(xml_list, market_data_list)
for i, result in enumerate(results):
print(f"Trade {i}: ${result['price']:.2f}")
REST API Endpoints¶
POST /fpml/price¶
Price an FpML trade document.
Request:
{
"fpml_xml": "<dataDocument>...</dataDocument>",
"market_data": {
"spot": 155.0,
"volatility": 0.25,
"rate": 0.05,
"dividend": 0.01
},
"steps": 252,
"paths": 100000,
"seed": 42
}
Response:
{
"price": 12.34,
"trade_date": "2024-01-15",
"trade_info": {
"product_type": "EquityOption",
"option_type": "Call",
"strike": 150.0,
"underlyer": "US0378331005"
}
}
POST /fpml/parse¶
Parse and inspect FpML document structure.
Request:
{
"fpml_xml": "<dataDocument>...</dataDocument>"
}
Response:
{
"trade_date": "2024-01-15",
"parties": [
{"id": "party1", "name": "Bank ABC"},
{"id": "party2", "name": "Client XYZ"}
],
"product": {
"type": "EquityOption",
"option_type": "Call",
"strike": 150.0,
"underlyer": "US0378331005",
"expiration": "2025-01-15"
}
}
POST /fpml/validate¶
Validate FpML document structure.
Request:
{
"fpml_xml": "<dataDocument>...</dataDocument>"
}
Response:
{
"valid": true,
"message": "FpML document is valid"
}
Error Handling¶
Parse Errors¶
from neutryx.integrations import fpml
try:
doc = fpml.parse_fpml(invalid_xml)
except fpml.FpMLParseError as e:
print(f"Parse error: {e}")
# Handle: invalid XML, missing elements, etc.
Mapping Errors¶
from neutryx.integrations import fpml
try:
request = fpml.fpml_to_neutryx(doc, market_data)
except fpml.FpMLMappingError as e:
print(f"Mapping error: {e}")
# Handle: missing market data, expired options, unsupported products
Advanced Usage¶
Custom Reference Date¶
By default, maturity is calculated from the trade date. You can specify a custom reference date:
from datetime import date
from neutryx.integrations.fpml import FpMLToNeutryxMapper
mapper = FpMLToNeutryxMapper(reference_date=date(2024, 6, 1))
request = mapper.map_trade(fpml_doc.primary_trade, market_data)
Custom Monte Carlo Configuration¶
from neutryx.integrations.fpml_adapter import FpMLPricingAdapter
from neutryx.core.engine import MCConfig
# High-accuracy configuration
mc_config = MCConfig(
steps=500,
paths=1_000_000,
antithetic=True
)
adapter = FpMLPricingAdapter(default_mc_config=mc_config)
result = adapter.price_from_xml(fpml_xml, market_data, mc_config)
Accessing Detailed Trade Information¶
from neutryx.integrations import fpml
doc = fpml.parse_fpml(fpml_xml)
trade = doc.primary_trade
if trade.equityOption:
opt = trade.equityOption
print(f"Buyer: {opt.buyerPartyReference.href}")
print(f"Seller: {opt.sellerPartyReference.href}")
print(f"Underlyer: {opt.underlyer.instrumentId}")
print(f"Description: {opt.underlyer.description}")
print(f"Strike: {opt.strike.strikePrice}")
print(f"Expiration: {opt.equityExercise.expirationDate.unadjustedDate}")
Performance Considerations¶
XML Parsing¶
The default implementation uses Python's built-in xml.etree.ElementTree which is sufficient for most use cases. For high-volume processing, consider:
- lxml: Faster XML parsing (install with
pip install lxml) - Batch processing: Use
FpMLBatchPricerfor multiple trades - Caching: Parse FpML documents once and reuse
Pricing Performance¶
Monte Carlo pricing is GPU-accelerated via JAX:
# Standard configuration (~10ms per option)
MCConfig(steps=252, paths=100_000)
# Fast configuration (~2ms per option, lower accuracy)
MCConfig(steps=64, paths=10_000)
# High-accuracy configuration (~100ms per option)
MCConfig(steps=500, paths=1_000_000)
Testing¶
Run FpML integration tests:
pytest src/neutryx/tests/test_fpml.py -v
Test coverage includes: - Parsing equity and FX options - Round-trip conversions - Error handling - API endpoints - Batch pricing
Examples¶
Complete examples are available in examples/advanced/fpml/:
equity_call_option.xml- Sample equity optionfx_call_option.xml- Sample FX optionfpml_pricing_example.py- Comprehensive Python examplesREADME.md- Quick start guide
Run examples:
cd examples/advanced/fpml
python fpml_pricing_example.py
Limitations and Future Work¶
Current Limitations¶
- Swaps: Basic structure parsing only; full valuation requires yield curve module
- Exotic Options: Barrier, Asian, Lookback require custom mapping
- Schema Validation: Optional (requires xmlschema package)
- Namespace Handling: Supports FpML 5.x default namespace
Roadmap¶
- [ ] Full interest rate swap valuation
- [ ] Barrier and exotic option support
- [ ] Multi-leg structures
- [ ] Credit derivatives (CDS)
- [ ] Real-time market data integration
- [ ] FpML 6.x support
Best Practices¶
- Always validate market data: Ensure all required fields are present
- Handle errors gracefully: Use try/except blocks for parsing and mapping
- Cache parsed documents: Avoid re-parsing the same XML
- Use batch pricing: More efficient for multiple trades
- Monitor performance: Adjust MC configuration based on accuracy needs
Support¶
For issues or questions:
- GitHub Issues: neutryx-lab/neutryx-core/issues
- Documentation: docs.neutryx.tech
- Examples: examples/advanced/fpml/