Skip to content

Integrating error codes and better input validation #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ third_party/
*.msix
*.msm
*.msp
*.txt

# Linux specific
*.deb
Expand Down
186 changes: 186 additions & 0 deletions Error_Code_To_Do_LIst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
1.1 Error Code Infrastructure

- Create include/libtradier2/error_codes.hpp
- Define TradierErrorCode enum with all 72+ error codes
- Add ErrorCodeInfo struct with description, category, retry behavior
- Implement error code to string mapping functions
- Enhance Exception Hierarchy in include/libtradier2/exceptions.hpp
- Extend TradierApiException with error code support
- Add structured error information (code, message, suggestions)
- Create category-specific exception types (AccountError, OrderError, etc.)
- Update Response Parsing in src/response_parser.cpp
- Parse error codes from API response "errors" property
- Map string error codes to enum values
- Extract additional error context from responses

1.2 Error Code Mapping Table

- Create src/error_code_mappings.cpp
- Static map of error codes to ErrorCodeInfo structs
- Include recovery suggestions and retry policies for each code
- Categorize errors by type (account, trading, validation, system)

Phase 2: Response Validation Framework (Week 2-3)

2.1 Field Reference System

- Create include/libtradier2/field_reference.hpp
- Define FieldInfo struct with validation metadata
- Create static maps for all API response types (Orders, Balances, etc.)
- Include data types, constraints, and descriptions from reference
- Implement Validation Engine in src/response_validator.cpp
- Template-based validator for different response types
- Check required fields, data types, and value constraints
- Generate detailed validation reports with field-level errors

2.2 Response Structure Validation

- Enhance existing response classes
- Add validation methods to Order, Balance, Position classes
- Implement self-validation during deserialization
- Create validation result objects with warnings/errors

Phase 3: Enhanced Order Validation (Week 3-4)

3.1 Pre-submission Validation

- Extend src/order_validator.cpp
- Add Tradier-specific validation rules from error code mappings
- Implement market hours validation using Clock API
- Add account permission checking against balance types
- Create Account-Aware Validation
- Validate orders against account type restrictions
- Check buying power and margin requirements
- Implement position-aware validation (long/short conflicts)

3.2 Order Type Specific Rules

- Market Order Validation
- Enforce day-only restriction for market orders
- Validate pre/post market restrictions
- Stop Order Validation
- Check stop price vs current bid/ask requirements
- Validate stop price positioning rules

Phase 4: Intelligent Error Recovery (Week 4-5)

4.1 Retry Policy Framework

- Create include/libtradier2/retry_policy.hpp
- Define retry configuration with backoff strategies
- Implement error-specific retry logic
- Add circuit breaker pattern for failing endpoints
- Enhance TradierClient with Retry Logic
- Automatic retry for retryable errors
- Rate limit aware retry delays
- Configurable retry policies per endpoint

4.2 Resilience Patterns

- Circuit Breaker Implementation
- Track failure rates per endpoint
- Implement half-open/open/closed states
- Add health check mechanisms

Phase 5: Reference Data Integration (Week 5-6)

5.1 Market Reference Data

- Create src/market_reference.cpp
- Embed exchange codes and descriptions
- Add market hours and trading session information
- Implement symbol format validation

5.2 Helper Utilities

- Symbol Validation and Formatting
- OCC option symbol parsing and validation
- Exchange code lookup and validation
- Symbol type detection (stock, option, ETF, etc.)

Phase 6: Developer Experience & Documentation (Week 6-7)

6.1 Error Debugging Tools

- Create diagnostic utilities
- Error code lookup tools
- Validation report formatters
- Recovery suggestion generators

6.2 Examples and Documentation

- Update examples with error handling patterns
- Create error handling best practices guide
- Add API reference documentation for new features

Phase 7: Testing & Integration (Week 7-8)

7.1 Comprehensive Test Suite

- Error code mapping tests
- Response validation tests
- Retry policy tests
- Integration tests with mock error responses

7.2 Performance Testing

- Validation overhead measurement
- Error handling performance impact
- Memory usage analysis

Implementation Details

File Structure Plan

include/libtradier2/
├── error_codes.hpp # Error code enums and info
├── field_reference.hpp # API field metadata
├── retry_policy.hpp # Retry and recovery logic
├── response_validator.hpp # Validation framework
└── market_reference.hpp # Exchange/symbol reference

src/
├── error_code_mappings.cpp # Error code to info mapping
├── response_validator.cpp # Validation implementation
├── retry_policy.cpp # Retry logic implementation
├── market_reference.cpp # Reference data implementation
└── enhanced_exceptions.cpp # Extended exception handling

Integration Strategy

Backward Compatibility

- All new features are additive
- Existing API remains unchanged
- Optional validation can be enabled/disabled
- Gradual migration path for users

Configuration Options

- Enable/disable response validation
- Configure retry policies per application
- Customize error handling behavior
- Debug mode with detailed error information

Performance Considerations

- Lazy loading of reference data
- Efficient error code lookups
- Minimal overhead for validation
- Optional compile-time optimizations

Risk Mitigation

Testing Strategy

- Unit tests for each component
- Integration tests with Tradier sandbox
- Mock error scenario testing
- Performance regression testing

Rollback Plan

- Feature flags for new functionality
- Comprehensive logging for debugging
- Gradual rollout with monitoring
- Quick disable mechanisms
78 changes: 78 additions & 0 deletions debug_validation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include <iostream>
#include <simdjson.h>
#include "include/oqdTradierpp/trading/order.hpp"
#include "include/oqdTradierpp/account/position.hpp"

using namespace oqd;

int main() {
simdjson::dom::parser parser;

// Test Order validation
std::string order_json = R"({
"id": "12345",
"class": "equity",
"symbol": "AAPL",
"side": "buy",
"quantity": "100",
"type": "limit",
"duration": "day",
"price": "150.50",
"avg_fill_price": "0.00",
"exec_quantity": "0",
"last_fill_price": "0.00",
"last_fill_quantity": "0",
"remaining_quantity": "100",
"status": "pending",
"tag": "user_order",
"create_date": "2023-01-01T09:30:00.000Z",
"transaction_date": "2023-01-01T09:30:00.000Z"
})";

auto order_doc = parser.parse(order_json);
auto order = Order::from_json(order_doc.value());

std::cout << "Order validation:\n";
std::cout << "ID: " << order.id << "\n";
std::cout << "Price: " << order.price << "\n";
std::cout << "Symbol: " << order.symbol << "\n";

auto result = order.validate(ValidationLevel::Basic);
std::cout << "Basic validation: " << (result.is_valid ? "PASS" : "FAIL") << "\n";

if (!result.is_valid) {
std::cout << "Issues:\n";
for (const auto& issue : result.issues) {
std::cout << " - " << issue.field_name << ": " << issue.message << "\n";
}
}

// Test Position validation
std::string position_json = R"({
"cost_basis": "15000.00",
"date_acquired": "2023-01-01T00:00:00.000Z",
"id": "pos123",
"quantity": "100.0",
"symbol": "AAPL"
})";

auto pos_doc = parser.parse(position_json);
auto position = Position::from_json(pos_doc.value());

std::cout << "\nPosition validation:\n";
std::cout << "Cost basis: " << position.cost_basis << "\n";
std::cout << "Quantity: " << position.quantity << "\n";
std::cout << "Average cost: " << position.get_average_cost() << "\n";

auto pos_result = position.validate(ValidationLevel::Basic);
std::cout << "Basic validation: " << (pos_result.is_valid ? "PASS" : "FAIL") << "\n";

if (!pos_result.is_valid) {
std::cout << "Issues:\n";
for (const auto& issue : pos_result.issues) {
std::cout << " - " << issue.field_name << ": " << issue.message << "\n";
}
}

return 0;
}
Loading