chore: Add project configuration and documentation
Some checks failed
Build and Test / build (push) Has been cancelled
Some checks failed
Build and Test / build (push) Has been cancelled
- Kilocode AI agent rules and guidelines - Setup and implementation guides - Architecture documentation - Build and verification references
This commit is contained in:
727
docs/architecture/interface_stability_contract.md
Normal file
727
docs/architecture/interface_stability_contract.md
Normal file
@@ -0,0 +1,727 @@
|
||||
# Interface Stability Contract - SDK ↔ Adapter Boundary
|
||||
|
||||
**Version**: 1.0
|
||||
**Date**: February 14, 2026
|
||||
**Status**: DRAFT - Needs Review & Approval
|
||||
|
||||
---
|
||||
|
||||
## Purpose
|
||||
|
||||
This document defines the **stable API contract** between:
|
||||
- **NT8.Core.dll** (SDK - platform-agnostic)
|
||||
- **NT8.Adapters.dll** (Adapters - platform-specific)
|
||||
|
||||
**Goal**: Ensure SDK updates don't break adapters, and vice versa.
|
||||
|
||||
---
|
||||
|
||||
## Design Principles
|
||||
|
||||
### 1. **Stable Interfaces, Evolving Implementations**
|
||||
- Interfaces are contracts (change rarely)
|
||||
- Implementations can evolve freely (change often)
|
||||
- Adapters depend on interfaces, NOT implementations
|
||||
|
||||
### 2. **Semantic Versioning**
|
||||
- **MAJOR**: Breaking changes to interfaces
|
||||
- **MINOR**: New features (backward compatible)
|
||||
- **PATCH**: Bug fixes (no API changes)
|
||||
|
||||
### 3. **Explicit Deprecation Cycle**
|
||||
- Deprecated methods stay for 2+ minor versions
|
||||
- Mark with `[Obsolete]` attribute
|
||||
- Provide migration path in docs
|
||||
|
||||
---
|
||||
|
||||
## Current Interface Contract (v1.0)
|
||||
|
||||
### Core SDK Interfaces (STABLE)
|
||||
|
||||
These interfaces define the boundary. **Changes require MAJOR version bump.**
|
||||
|
||||
#### 1. Strategy Interface
|
||||
|
||||
```csharp
|
||||
// src/NT8.Core/Common/Interfaces/IStrategy.cs
|
||||
// VERSION: 1.0.0
|
||||
// STABILITY: STABLE
|
||||
|
||||
public interface IStrategy
|
||||
{
|
||||
// Properties
|
||||
StrategyMetadata Metadata { get; }
|
||||
|
||||
// Methods
|
||||
void Initialize(StrategyConfig config, IMarketDataProvider dataProvider, ILogger logger);
|
||||
StrategyIntent OnBar(BarData bar, StrategyContext context);
|
||||
StrategyIntent OnTick(TickData tick, StrategyContext context);
|
||||
Dictionary<string, object> GetParameters();
|
||||
void SetParameters(Dictionary<string, object> parameters);
|
||||
}
|
||||
```
|
||||
|
||||
**Stability Guarantee:**
|
||||
- ✅ Method signatures won't change
|
||||
- ✅ Method names won't change
|
||||
- ✅ Return types won't change (may add properties to returned objects)
|
||||
- ✅ Parameter types won't change (may add optional parameters)
|
||||
|
||||
**Allowed Changes:**
|
||||
- ➕ Add new optional methods with default implementations
|
||||
- ➕ Add properties to `StrategyMetadata`
|
||||
- ➕ Add properties to `StrategyConfig`
|
||||
- ❌ Cannot remove existing methods
|
||||
- ❌ Cannot change existing method signatures
|
||||
|
||||
---
|
||||
|
||||
#### 2. Data Models (STABLE)
|
||||
|
||||
```csharp
|
||||
// src/NT8.Core/Common/Models/BarData.cs
|
||||
// VERSION: 1.0.0
|
||||
// STABILITY: STABLE
|
||||
|
||||
public class BarData
|
||||
{
|
||||
// Core properties (IMMUTABLE)
|
||||
public string Symbol { get; set; }
|
||||
public DateTime Time { get; set; }
|
||||
public double Open { get; set; }
|
||||
public double High { get; set; }
|
||||
public double Low { get; set; }
|
||||
public double Close { get; set; }
|
||||
public long Volume { get; set; }
|
||||
public TimeSpan BarSize { get; set; }
|
||||
|
||||
// Constructor (IMMUTABLE signature)
|
||||
public BarData(
|
||||
string symbol,
|
||||
DateTime time,
|
||||
double open,
|
||||
double high,
|
||||
double low,
|
||||
double close,
|
||||
long volume,
|
||||
TimeSpan barSize)
|
||||
{ ... }
|
||||
}
|
||||
```
|
||||
|
||||
**Stability Guarantee:**
|
||||
- ✅ Existing properties keep same names
|
||||
- ✅ Existing properties keep same types
|
||||
- ✅ Constructor signature won't change (may add overloads)
|
||||
- ✅ Property getters/setters won't change behavior
|
||||
|
||||
**Allowed Changes:**
|
||||
- ➕ Add new properties (with sensible defaults)
|
||||
- ➕ Add new constructor overloads
|
||||
- ➕ Add helper methods
|
||||
- ❌ Cannot rename existing properties
|
||||
- ❌ Cannot change property types
|
||||
- ❌ Cannot remove properties
|
||||
|
||||
---
|
||||
|
||||
#### 3. Strategy Intent (STABLE)
|
||||
|
||||
```csharp
|
||||
// src/NT8.Core/Common/Models/StrategyIntent.cs
|
||||
// VERSION: 1.0.0
|
||||
// STABILITY: STABLE
|
||||
|
||||
public class StrategyIntent
|
||||
{
|
||||
// Core properties (IMMUTABLE)
|
||||
public string IntentId { get; private set; }
|
||||
public DateTime Timestamp { get; private set; }
|
||||
public string Symbol { get; set; }
|
||||
public OrderSide Side { get; set; }
|
||||
public OrderType EntryType { get; set; }
|
||||
public double? LimitPrice { get; set; }
|
||||
public int StopTicks { get; set; }
|
||||
public int? TargetTicks { get; set; }
|
||||
public double Confidence { get; set; }
|
||||
public string Reason { get; set; }
|
||||
public Dictionary<string, object> Metadata { get; set; }
|
||||
|
||||
// Constructor (IMMUTABLE signature)
|
||||
public StrategyIntent(
|
||||
string symbol,
|
||||
OrderSide side,
|
||||
OrderType entryType,
|
||||
double? limitPrice,
|
||||
int stopTicks,
|
||||
int? targetTicks,
|
||||
double confidence,
|
||||
string reason,
|
||||
Dictionary<string, object> metadata)
|
||||
{ ... }
|
||||
|
||||
// Validation (IMMUTABLE signature)
|
||||
public bool IsValid() { ... }
|
||||
}
|
||||
```
|
||||
|
||||
**Stability Guarantee:**
|
||||
- ✅ All property names fixed
|
||||
- ✅ All property types fixed
|
||||
- ✅ `IsValid()` signature fixed
|
||||
- ✅ Enums can add new values (but not remove)
|
||||
|
||||
**Allowed Changes:**
|
||||
- ➕ Add new optional properties
|
||||
- ➕ Add new validation methods
|
||||
- ➕ Add enum values to `OrderSide`, `OrderType`
|
||||
- ❌ Cannot remove properties
|
||||
- ❌ Cannot change property types
|
||||
- ❌ Cannot remove enum values
|
||||
|
||||
---
|
||||
|
||||
#### 4. Strategy Context (STABLE)
|
||||
|
||||
```csharp
|
||||
// src/NT8.Core/Common/Models/StrategyContext.cs
|
||||
// VERSION: 1.0.0
|
||||
// STABILITY: STABLE
|
||||
|
||||
public class StrategyContext
|
||||
{
|
||||
// Core properties (IMMUTABLE)
|
||||
public string Symbol { get; set; }
|
||||
public DateTime CurrentTime { get; set; }
|
||||
public Position CurrentPosition { get; set; }
|
||||
public AccountInfo Account { get; set; }
|
||||
public MarketSession Session { get; set; }
|
||||
public Dictionary<string, object> CustomData { get; set; }
|
||||
|
||||
// Constructor (IMMUTABLE signature)
|
||||
public StrategyContext(
|
||||
string symbol,
|
||||
DateTime currentTime,
|
||||
Position currentPosition,
|
||||
AccountInfo account,
|
||||
MarketSession session,
|
||||
Dictionary<string, object> customData)
|
||||
{ ... }
|
||||
}
|
||||
```
|
||||
|
||||
**Stability Guarantee:**
|
||||
- ✅ Context structure is stable
|
||||
- ✅ Nested objects (`Position`, `AccountInfo`, `MarketSession`) can add properties
|
||||
- ✅ `CustomData` dictionary for extensibility
|
||||
|
||||
**Allowed Changes:**
|
||||
- ➕ Add properties to `Position`, `AccountInfo`, `MarketSession`
|
||||
- ➕ Add new top-level properties to `StrategyContext`
|
||||
- ❌ Cannot remove existing properties
|
||||
- ❌ Cannot change property types
|
||||
|
||||
---
|
||||
|
||||
### Adapter Interface (SEMI-STABLE)
|
||||
|
||||
This is platform-specific. Can evolve more freely.
|
||||
|
||||
```csharp
|
||||
// src/NT8.Adapters/NinjaTrader/INT8Adapter.cs
|
||||
// VERSION: 1.0.0
|
||||
// STABILITY: SEMI-STABLE (can evolve between minor versions)
|
||||
|
||||
public interface INT8Adapter
|
||||
{
|
||||
// Initialization
|
||||
void Initialize(IRiskManager riskManager, IPositionSizer positionSizer);
|
||||
|
||||
// Data conversion (SDK models as return types = STABLE)
|
||||
BarData ConvertToSdkBar(string symbol, DateTime time, double open, double high, double low, double close, long volume, int barSize);
|
||||
AccountInfo ConvertToSdkAccount(double equity, double buyingPower, double dailyPnL, double maxDrawdown, DateTime lastUpdate);
|
||||
Position ConvertToSdkPosition(string symbol, int quantity, double averagePrice, double unrealizedPnL, double realizedPnL, DateTime lastUpdate);
|
||||
|
||||
// Intent execution (SDK models as parameters = STABLE)
|
||||
void ExecuteIntent(StrategyIntent intent, SizingResult sizing);
|
||||
|
||||
// NT8 callbacks (NT8-specific parameters = CAN CHANGE)
|
||||
void OnOrderUpdate(string orderId, double limitPrice, double stopPrice, int quantity, int filled, double averageFillPrice, string orderState, DateTime time, string errorCode, string nativeError);
|
||||
void OnExecutionUpdate(string executionId, string orderId, double price, int quantity, string marketPosition, DateTime time);
|
||||
}
|
||||
```
|
||||
|
||||
**Stability Guarantee:**
|
||||
- ✅ Methods that return SDK models are stable
|
||||
- ✅ Methods that accept SDK models are stable
|
||||
- 🟡 NT8-specific signatures can evolve (minor versions)
|
||||
|
||||
**Allowed Changes:**
|
||||
- ➕ Add new conversion methods
|
||||
- ➕ Add optional parameters to NT8-specific methods
|
||||
- ➕ Add new callback methods
|
||||
- ❌ Cannot change SDK model signatures
|
||||
- 🟡 Can change NT8-specific signatures (with deprecation)
|
||||
|
||||
---
|
||||
|
||||
## Versioning Strategy
|
||||
|
||||
### SDK Core (NT8.Core.dll)
|
||||
|
||||
```
|
||||
Version Format: MAJOR.MINOR.PATCH
|
||||
|
||||
1.0.0 → Initial release (Phase 1)
|
||||
1.1.0 → Add new optional features (Phase 2)
|
||||
1.2.0 → More new features (Phase 3)
|
||||
2.0.0 → Breaking interface changes (major refactor)
|
||||
```
|
||||
|
||||
**Breaking Changes (MAJOR bump):**
|
||||
- Remove methods from `IStrategy`
|
||||
- Change method signatures in core interfaces
|
||||
- Remove properties from data models
|
||||
- Change property types in data models
|
||||
|
||||
**Compatible Changes (MINOR bump):**
|
||||
- Add new optional interface methods (with defaults)
|
||||
- Add new properties to data models
|
||||
- Add new data models
|
||||
- Add new interfaces
|
||||
|
||||
**Bug Fixes (PATCH bump):**
|
||||
- Fix bugs in implementations
|
||||
- Performance improvements
|
||||
- Internal refactoring
|
||||
- Documentation updates
|
||||
|
||||
---
|
||||
|
||||
### Adapters (NT8.Adapters.dll)
|
||||
|
||||
```
|
||||
Version Format: Matches SDK version for compatibility
|
||||
|
||||
NT8.Core 1.0.0 → NT8.Adapters 1.0.x (compatible)
|
||||
NT8.Core 1.1.0 → NT8.Adapters 1.1.x (compatible)
|
||||
NT8.Core 2.0.0 → NT8.Adapters 2.0.x (requires rewrite)
|
||||
```
|
||||
|
||||
**Adapter versions MUST match SDK MAJOR.MINOR**
|
||||
|
||||
---
|
||||
|
||||
## Interface Evolution Examples
|
||||
|
||||
### Example 1: Adding Optional Feature (MINOR version)
|
||||
|
||||
**Scenario**: Add support for multiple targets
|
||||
|
||||
```csharp
|
||||
// v1.0.0 - Original
|
||||
public class StrategyIntent
|
||||
{
|
||||
public int? TargetTicks { get; set; }
|
||||
// ...
|
||||
}
|
||||
|
||||
// v1.1.0 - Enhanced (BACKWARD COMPATIBLE)
|
||||
public class StrategyIntent
|
||||
{
|
||||
public int? TargetTicks { get; set; } // Keep for compatibility
|
||||
|
||||
// NEW: Optional multiple targets
|
||||
public List<int> TargetTicksList { get; set; } // Defaults to null
|
||||
|
||||
// Helper to maintain compatibility
|
||||
public int? GetPrimaryTarget()
|
||||
{
|
||||
if (TargetTicksList != null && TargetTicksList.Count > 0)
|
||||
return TargetTicksList[0];
|
||||
return TargetTicks;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Adapter Impact**: ✅ None - old code still works
|
||||
**Strategy Impact**: ✅ None - can optionally use new feature
|
||||
|
||||
---
|
||||
|
||||
### Example 2: Deprecating Old Method (MINOR version with warning)
|
||||
|
||||
**Scenario**: Rename method for clarity
|
||||
|
||||
```csharp
|
||||
// v1.0.0 - Original
|
||||
public interface IStrategy
|
||||
{
|
||||
StrategyIntent OnBar(BarData bar, StrategyContext context);
|
||||
}
|
||||
|
||||
// v1.1.0 - Add new, deprecate old
|
||||
public interface IStrategy
|
||||
{
|
||||
[Obsolete("Use OnBarClose instead. Will be removed in v2.0.0")]
|
||||
StrategyIntent OnBar(BarData bar, StrategyContext context);
|
||||
|
||||
// NEW preferred method
|
||||
StrategyIntent OnBarClose(BarData bar, StrategyContext context);
|
||||
}
|
||||
|
||||
// v1.2.0 - Still support both
|
||||
// ... same as v1.1.0 ...
|
||||
|
||||
// v2.0.0 - Remove old (BREAKING CHANGE)
|
||||
public interface IStrategy
|
||||
{
|
||||
StrategyIntent OnBarClose(BarData bar, StrategyContext context);
|
||||
}
|
||||
```
|
||||
|
||||
**Migration Timeline**:
|
||||
- v1.1.0: Add new method, deprecate old (warning)
|
||||
- v1.2.0: Keep both (warning)
|
||||
- v2.0.0: Remove old (breaking change, requires adapter update)
|
||||
|
||||
---
|
||||
|
||||
### Example 3: Breaking Change (MAJOR version)
|
||||
|
||||
**Scenario**: Change position model to support multi-symbol
|
||||
|
||||
```csharp
|
||||
// v1.x.x - Original
|
||||
public class StrategyContext
|
||||
{
|
||||
public Position CurrentPosition { get; set; } // Single position
|
||||
}
|
||||
|
||||
// v2.0.0 - Breaking change
|
||||
public class StrategyContext
|
||||
{
|
||||
public Dictionary<string, Position> Positions { get; set; } // Multi-symbol
|
||||
|
||||
// Helper for single-symbol strategies
|
||||
public Position GetPosition(string symbol)
|
||||
{
|
||||
return Positions.ContainsKey(symbol) ? Positions[symbol] : null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Adapter Impact**: ❌ Must update - breaking change
|
||||
**Migration Required**: Yes, all adapters need rewrite
|
||||
**Version Bump**: 1.x.x → 2.0.0
|
||||
|
||||
---
|
||||
|
||||
## Compatibility Matrix
|
||||
|
||||
### SDK ↔ Adapter Compatibility
|
||||
|
||||
| SDK Version | Adapter Version | Compatible? | Notes |
|
||||
|-------------|-----------------|-------------|-------|
|
||||
| 1.0.0 | 1.0.x | ✅ Yes | Perfect match |
|
||||
| 1.1.0 | 1.0.x | ✅ Yes | Forward compatible |
|
||||
| 1.1.0 | 1.1.x | ✅ Yes | Perfect match |
|
||||
| 1.2.0 | 1.1.x | ✅ Yes | Forward compatible |
|
||||
| 2.0.0 | 1.x.x | ❌ No | Breaking change |
|
||||
| 2.0.0 | 2.0.x | ✅ Yes | Perfect match |
|
||||
|
||||
**Rule**: Adapter MINOR can be less than SDK MINOR (forward compatible)
|
||||
**Rule**: Adapter MAJOR must equal SDK MAJOR
|
||||
|
||||
---
|
||||
|
||||
## Contract Testing
|
||||
|
||||
### Automated Contract Tests
|
||||
|
||||
Create tests that verify interface stability:
|
||||
|
||||
```csharp
|
||||
// tests/NT8.Core.Tests/Contracts/InterfaceStabilityTests.cs
|
||||
|
||||
[Fact]
|
||||
public void IStrategy_Interface_Should_Be_Stable()
|
||||
{
|
||||
var type = typeof(IStrategy);
|
||||
|
||||
// Verify method count hasn't decreased
|
||||
var methods = type.GetMethods();
|
||||
Assert.True(methods.Length >= 5, "IStrategy methods removed!");
|
||||
|
||||
// Verify specific methods exist
|
||||
Assert.NotNull(type.GetMethod("OnBar"));
|
||||
Assert.NotNull(type.GetMethod("OnTick"));
|
||||
Assert.NotNull(type.GetMethod("Initialize"));
|
||||
|
||||
// Verify method signatures
|
||||
var onBarMethod = type.GetMethod("OnBar");
|
||||
Assert.Equal(typeof(StrategyIntent), onBarMethod.ReturnType);
|
||||
|
||||
var parameters = onBarMethod.GetParameters();
|
||||
Assert.Equal(2, parameters.Length);
|
||||
Assert.Equal(typeof(BarData), parameters[0].ParameterType);
|
||||
Assert.Equal(typeof(StrategyContext), parameters[1].ParameterType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void BarData_Properties_Should_Be_Stable()
|
||||
{
|
||||
var type = typeof(BarData);
|
||||
|
||||
// Verify required properties exist
|
||||
Assert.NotNull(type.GetProperty("Symbol"));
|
||||
Assert.NotNull(type.GetProperty("Time"));
|
||||
Assert.NotNull(type.GetProperty("Open"));
|
||||
Assert.NotNull(type.GetProperty("High"));
|
||||
Assert.NotNull(type.GetProperty("Low"));
|
||||
Assert.NotNull(type.GetProperty("Close"));
|
||||
Assert.NotNull(type.GetProperty("Volume"));
|
||||
|
||||
// Verify property types haven't changed
|
||||
Assert.Equal(typeof(string), type.GetProperty("Symbol").PropertyType);
|
||||
Assert.Equal(typeof(DateTime), type.GetProperty("Time").PropertyType);
|
||||
Assert.Equal(typeof(double), type.GetProperty("Open").PropertyType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void StrategyIntent_Constructor_Should_Be_Stable()
|
||||
{
|
||||
var type = typeof(StrategyIntent);
|
||||
|
||||
// Verify constructor exists with expected parameters
|
||||
var constructor = type.GetConstructor(new[]
|
||||
{
|
||||
typeof(string), // symbol
|
||||
typeof(OrderSide), // side
|
||||
typeof(OrderType), // entryType
|
||||
typeof(double?), // limitPrice
|
||||
typeof(int), // stopTicks
|
||||
typeof(int?), // targetTicks
|
||||
typeof(double), // confidence
|
||||
typeof(string), // reason
|
||||
typeof(Dictionary<string, object>) // metadata
|
||||
});
|
||||
|
||||
Assert.NotNull(constructor);
|
||||
}
|
||||
```
|
||||
|
||||
**Run these tests** in CI/CD to catch accidental breaking changes!
|
||||
|
||||
---
|
||||
|
||||
## Adapter-Safe Practices
|
||||
|
||||
### For SDK Developers
|
||||
|
||||
**DO:**
|
||||
- ✅ Add optional parameters with defaults
|
||||
- ✅ Add new properties with sensible defaults
|
||||
- ✅ Add new interfaces for new features
|
||||
- ✅ Add helper methods to existing classes
|
||||
- ✅ Mark deprecated methods with `[Obsolete]`
|
||||
- ✅ Run contract tests before release
|
||||
|
||||
**DON'T:**
|
||||
- ❌ Remove existing methods
|
||||
- ❌ Change method signatures
|
||||
- ❌ Rename properties
|
||||
- ❌ Change property types
|
||||
- ❌ Remove enum values
|
||||
- ❌ Break existing constructors
|
||||
|
||||
### For Adapter Developers
|
||||
|
||||
**DO:**
|
||||
- ✅ Depend only on interfaces, not implementations
|
||||
- ✅ Use factory patterns for object creation
|
||||
- ✅ Handle new optional properties gracefully
|
||||
- ✅ Catch and log unknown enum values
|
||||
- ✅ Version-check SDK at runtime if needed
|
||||
|
||||
**DON'T:**
|
||||
- ❌ Depend on internal implementation details
|
||||
- ❌ Assume fixed property counts
|
||||
- ❌ Hard-code enum values
|
||||
- ❌ Access private members via reflection
|
||||
|
||||
---
|
||||
|
||||
## Naming Conventions (IMMUTABLE)
|
||||
|
||||
These naming patterns are **contracts** and won't change:
|
||||
|
||||
### Interface Names
|
||||
```
|
||||
Pattern: I{Concept}
|
||||
Examples: IStrategy, IRiskManager, IPositionSizer, ILogger
|
||||
```
|
||||
|
||||
### Model Classes
|
||||
```
|
||||
Pattern: {Concept}{Type}
|
||||
Examples: BarData, TickData, StrategyIntent, StrategyContext
|
||||
```
|
||||
|
||||
### Enums
|
||||
```
|
||||
Pattern: {Concept}{Optional Suffix}
|
||||
Examples: OrderSide, OrderType, TickType, RiskLevel
|
||||
```
|
||||
|
||||
### Methods
|
||||
```
|
||||
Pattern: {Verb}{Noun}
|
||||
Examples: OnBar, OnTick, Initialize, ValidateOrder, CalculateSize
|
||||
```
|
||||
|
||||
### Properties
|
||||
```
|
||||
Pattern: {Noun} or {Adjective}{Noun}
|
||||
Examples: Symbol, Timestamp, CurrentPosition, DailyPnL
|
||||
```
|
||||
|
||||
**These patterns are STABLE and won't change.**
|
||||
|
||||
---
|
||||
|
||||
## Extension Points (For Future Growth)
|
||||
|
||||
### 1. Metadata Dictionaries
|
||||
```csharp
|
||||
public Dictionary<string, object> Metadata { get; set; }
|
||||
```
|
||||
**Use for**: Adding data without breaking compatibility
|
||||
|
||||
### 2. Optional Parameters
|
||||
```csharp
|
||||
public void Initialize(
|
||||
StrategyConfig config,
|
||||
IMarketDataProvider dataProvider,
|
||||
ILogger logger,
|
||||
Dictionary<string, object> options = null) // Extension point
|
||||
```
|
||||
|
||||
### 3. Interface Composition
|
||||
```csharp
|
||||
// Instead of changing IStrategy, create new interface
|
||||
public interface IAdvancedStrategy : IStrategy
|
||||
{
|
||||
void OnMarketDepth(MarketDepthData depth);
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Feature Flags
|
||||
```csharp
|
||||
public class StrategyMetadata
|
||||
{
|
||||
public Dictionary<string, bool> SupportedFeatures { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
**Adapters can check**: `if (metadata.SupportedFeatures["MultiTarget"]) { ... }`
|
||||
|
||||
---
|
||||
|
||||
## Documentation Requirements
|
||||
|
||||
### For Every Interface Change
|
||||
|
||||
**Must Document:**
|
||||
1. **What changed** (method/property added/removed/changed)
|
||||
2. **Why it changed** (business reason)
|
||||
3. **Version** it changed in
|
||||
4. **Migration path** for adapters
|
||||
5. **Deprecation timeline** (if applicable)
|
||||
|
||||
**Example**:
|
||||
```markdown
|
||||
## v1.1.0 - January 2026
|
||||
|
||||
### Added
|
||||
- `StrategyIntent.TargetTicksList` - Support for multiple profit targets
|
||||
- **Migration**: Not required. Old code using `TargetTicks` still works.
|
||||
- **New feature**: Strategies can now specify multiple targets.
|
||||
|
||||
### Deprecated
|
||||
- `IStrategy.OnBar()` - Deprecated in favor of `OnBarClose()`
|
||||
- **Reason**: Clearer naming for bar-close strategies
|
||||
- **Timeline**: Will be removed in v2.0.0 (12+ months)
|
||||
- **Migration**: Replace `OnBar` with `OnBarClose` (same signature)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Approval Process
|
||||
|
||||
### Before Releasing Interface Changes
|
||||
|
||||
**Required Reviews:**
|
||||
1. ✅ Technical review (breaking vs. non-breaking)
|
||||
2. ✅ Contract tests pass
|
||||
3. ✅ Documentation updated
|
||||
4. ✅ Migration guide written (if needed)
|
||||
5. ✅ Version number updated correctly
|
||||
|
||||
**For Breaking Changes:**
|
||||
1. ✅ All of the above, plus:
|
||||
2. ✅ Deprecation period completed (2+ minor versions)
|
||||
3. ✅ Adapter developers notified 30+ days in advance
|
||||
4. ✅ Migration tooling provided (if possible)
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
### The Contract
|
||||
|
||||
**SDK Core provides:**
|
||||
- Stable interfaces (`IStrategy`, `IRiskManager`, `IPositionSizer`)
|
||||
- Stable data models (`BarData`, `StrategyIntent`, `StrategyContext`)
|
||||
- Versioned API (semantic versioning)
|
||||
- Backward compatibility within MAJOR versions
|
||||
|
||||
**Adapters rely on:**
|
||||
- Interface contracts (not implementations)
|
||||
- Data model structures
|
||||
- Method signatures
|
||||
- Enum values
|
||||
|
||||
**The promise:**
|
||||
- SDK can evolve WITHOUT breaking adapters (within MAJOR version)
|
||||
- Adapters can evolve WITHOUT rewriting SDK
|
||||
- Clear versioning communicates compatibility
|
||||
- Deprecation gives time to migrate
|
||||
|
||||
---
|
||||
|
||||
## Action Items
|
||||
|
||||
### Immediate (Before Phase 1 Release)
|
||||
|
||||
- [ ] Review all public interfaces for stability
|
||||
- [ ] Add contract tests to CI/CD
|
||||
- [ ] Document current interface versions
|
||||
- [ ] Establish version numbering (start at 1.0.0)
|
||||
- [ ] Get team approval on this contract
|
||||
|
||||
### Ongoing
|
||||
|
||||
- [ ] Run contract tests on every build
|
||||
- [ ] Review all PR's for interface stability
|
||||
- [ ] Document changes in CHANGELOG.md
|
||||
- [ ] Notify adapter developers of deprecations
|
||||
- [ ] Maintain compatibility matrix
|
||||
|
||||
---
|
||||
|
||||
**Version History:**
|
||||
- v1.0 (2026-02-14): Initial draft
|
||||
- [Future versions will be listed here]
|
||||
|
||||
Reference in New Issue
Block a user