Compare commits
12 Commits
v0.5.0
...
cleanup/ru
| Author | SHA1 | Date | |
|---|---|---|---|
| 2ad2ddf38b | |||
| f8587125c0 | |||
| de6e150655 | |||
| 4453ff552a | |||
| 1cd8df759f | |||
| 2be9c843e5 | |||
| a6ececaf73 | |||
| ce74f68e54 | |||
| 3ccd3a8bfd | |||
| e2ea45b58f | |||
| 9a28a49292 | |||
| d856f3949d |
BIN
.gitattributes
vendored
Normal file
BIN
.gitattributes
vendored
Normal file
Binary file not shown.
@@ -1,204 +1,35 @@
|
||||
ALWAYS verify with the live Ninjascript reference available on the web at https://developer.ninjatrader.com/docs/desktop before making final edits.
|
||||
|
||||
This third file confirms a recurrence of CS0246 compiler errors in VWAP_Pro.cs, specifically related to undefined types like ModeType and AnchorModeType.
|
||||
|
||||
🔍 CS0246 - "The type or namespace name 'X' could not be found"
|
||||
Line Column Missing Type
|
||||
371 28 ModeType
|
||||
371 43 AnchorModeType
|
||||
391 39 ModeType
|
||||
391 54 AnchorModeType
|
||||
376 51 ModeType
|
||||
✅ How to Fix It
|
||||
🔧 1. Define Missing Enums (Recommended Fix)
|
||||
|
||||
It seems that ModeType and AnchorModeType are custom enums that were expected to exist in the code but were never declared.
|
||||
|
||||
Create a separate file or include this in the same VWAP_Pro.cs file near the top:
|
||||
|
||||
public enum ModeType
|
||||
{
|
||||
Standard,
|
||||
Aggressive,
|
||||
Conservative
|
||||
}
|
||||
|
||||
public enum AnchorModeType
|
||||
{
|
||||
SessionStart,
|
||||
FixedTime,
|
||||
Custom
|
||||
}
|
||||
|
||||
|
||||
You’ll need to customize the enum values (Standard, Aggressive, etc.) to match your strategy logic. These names are placeholders based on typical VWAP settings.
|
||||
|
||||
🔧 2. OR Add Missing using Directives
|
||||
|
||||
If these types exist in another NinjaTrader script or add-on you've imported before, ensure you include the right namespace:
|
||||
|
||||
using NinjaTrader.NinjaScript.AddOns.MyVWAPEnums; // Example
|
||||
|
||||
|
||||
But since these errors suggest the types are completely undefined, it's much more likely they are simply not declared anywhere.
|
||||
|
||||
🔧 3. Verify File Inclusion in NinjaTrader
|
||||
|
||||
If these enums are defined in another file (e.g., VWAPTypes.cs), make sure:
|
||||
|
||||
It's saved in the same directory as VWAP_Pro.cs
|
||||
|
||||
It's added to the NinjaScript Editor, not just sitting in the file system
|
||||
|
||||
You can add it using:
|
||||
|
||||
Tools > NinjaScript Editor > Right-click > Add > Existing Item...
|
||||
|
||||
🧼 Suggested Organization
|
||||
|
||||
If these enums are used across multiple indicators/strategies, you should centralize them:
|
||||
|
||||
VWAP_Enums.cs
|
||||
|
||||
namespace NinjaTrader.NinjaScript.VWAP
|
||||
{
|
||||
public enum ModeType
|
||||
{
|
||||
Standard,
|
||||
Aggressive,
|
||||
Conservative
|
||||
}
|
||||
|
||||
public enum AnchorModeType
|
||||
{
|
||||
SessionStart,
|
||||
FixedTime,
|
||||
Custom
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Then use:
|
||||
|
||||
using NinjaTrader.NinjaScript.VWAP;
|
||||
|
||||
|
||||
|
||||
These are occurring in VWAP_Pro.cs, mainly on lines 132–134:
|
||||
|
||||
Line Error Message (Truncated)
|
||||
132 Argument 2: cannot convert from 'int' to 'NinjaTrader.Gui.Tools.SimpleFont'
|
||||
132 Argument 3: cannot convert from 'NinjaTrader.Gui.Tools.SimpleFont' to 'System.Windows.Media.Brush'
|
||||
133 Same as above
|
||||
134 Same as above
|
||||
🔧 Interpretation:
|
||||
|
||||
It looks like a method (likely a drawing method like Draw.Text() or Draw.TextFixed()) is being called with the wrong argument types — specifically:
|
||||
|
||||
An int is being passed where a SimpleFont is expected.
|
||||
|
||||
A SimpleFont is being passed where a Brush is expected.
|
||||
|
||||
This suggests that arguments are out of order or misassigned.
|
||||
|
||||
✅ Proper Fix
|
||||
|
||||
Let’s consider the proper usage of Draw.Text() in NinjaTrader 8:
|
||||
|
||||
Draw.Text(NinjaScriptBase owner, string tag, bool isAutoScale, string text, int barsAgo, double y, Brush textBrush, SimpleFont font, TextAlignment alignment, Brush outlineBrush, int outlineWidth);
|
||||
|
||||
|
||||
Or for simpler usage:
|
||||
|
||||
Draw.Text(this, "tag1", "Hello", 0, Close[0], Brushes.White);
|
||||
|
||||
|
||||
Your issue likely looks like this:
|
||||
|
||||
Draw.Text(this, "tag1", true, "Label", 0, 100, 12, someFont, ...);
|
||||
|
||||
|
||||
Where 12 (int) is mistakenly passed as a font or brush, causing the error.
|
||||
|
||||
🔧 Corrected Example:
|
||||
|
||||
Assuming you want to draw text with a specific font and color:
|
||||
|
||||
SimpleFont font = new SimpleFont("Arial", 12);
|
||||
Draw.Text(this, "tag1", true, "VWAP Label", 0, Close[0], Brushes.White, font, TextAlignment.Center, Brushes.Black, 1);
|
||||
|
||||
|
||||
Brushes.White → text color
|
||||
|
||||
font → SimpleFont object
|
||||
|
||||
TextAlignment.Center → alignment
|
||||
|
||||
Brushes.Black → outline brush
|
||||
|
||||
1 → outline width
|
||||
|
||||
✅ Steps to Fix:
|
||||
|
||||
Replace the integer (e.g., 12) with a SimpleFont:
|
||||
|
||||
new SimpleFont("Arial", 12)
|
||||
|
||||
|
||||
Ensure arguments are in the correct order:
|
||||
Double-check the method signature from the NinjaTrader 8 Help Guide
|
||||
.
|
||||
|
||||
Use Brushes for colors, not fonts.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Summary of Errors:
|
||||
Line Column Missing Type
|
||||
403 39 ModeType
|
||||
403 54 AnchorModeType
|
||||
408 63 ModeType
|
||||
408 78 AnchorModeType
|
||||
367 28 ModeType
|
||||
✅ Fixes:
|
||||
|
||||
These types — ModeType and AnchorModeType — are not recognized. Here are the likely causes and solutions:
|
||||
|
||||
🔍 1. Missing using Directive
|
||||
|
||||
These types might be defined in a different namespace. If they are from a custom or NinjaTrader add-on:
|
||||
|
||||
Fix: Add the appropriate using statement at the top of your file.
|
||||
|
||||
Example:
|
||||
|
||||
using NinjaTrader.NinjaScript.AddOns.VWAP;
|
||||
|
||||
|
||||
Adjust according to where ModeType and AnchorModeType are defined.
|
||||
|
||||
🔍 2. Missing Class Definitions
|
||||
|
||||
If they are not in any existing libraries, they might be custom enum types that should be defined in your project but are missing.
|
||||
|
||||
Fix: Add enum declarations like these (if applicable):
|
||||
|
||||
public enum ModeType
|
||||
{
|
||||
Standard,
|
||||
Aggressive,
|
||||
Conservative
|
||||
}
|
||||
|
||||
public enum AnchorModeType
|
||||
{
|
||||
SessionStart,
|
||||
FixedTime,
|
||||
Custom
|
||||
}
|
||||
|
||||
|
||||
Only do this if you know what the enum values should be. These names are placeholders — you should match them with how your indicator/strategy is designed.
|
||||
# Compile Error Guidance - Reusable Protocol
|
||||
**Last Updated:** 2026-04-05
|
||||
|
||||
Apply this protocol for all compile issues.
|
||||
|
||||
## 1) Verify First
|
||||
- [ ] Verify exact NinjaScript/API signature against official NT8 docs before editing: `https://developer.ninjatrader.com/docs/desktop`.
|
||||
- [ ] Confirm file is in scope before making any change.
|
||||
|
||||
## 2) Classify the Error
|
||||
- [ ] Missing type/namespace (e.g., `CS0246`).
|
||||
- [ ] Invalid override/signature/access modifier (e.g., `CS0115`, `CS0507`).
|
||||
- [ ] Argument mismatch or wrong overload (e.g., `CS1503`).
|
||||
- [ ] C# language version incompatibility (C# 6+ syntax in C# 5 project).
|
||||
|
||||
## 3) Apply Smallest Safe Fix
|
||||
- [ ] Prefer minimal edits in scoped files only.
|
||||
- [ ] Fix root cause, not symptom chaining.
|
||||
- [ ] Preserve existing architecture/contracts unless task explicitly requires change.
|
||||
|
||||
## 4) Re-Run Verification
|
||||
- [ ] Run `.\verify-build.bat`.
|
||||
- [ ] Run required tests for changed area.
|
||||
- [ ] If NinjaScript touched, run NT8 compile check in NinjaScript Editor.
|
||||
|
||||
## 5) Capture Durable Learning
|
||||
For non-trivial compile failures, add concise entries to:
|
||||
- [ ] `docs/00-governance/common_failures.md` (error fingerprint + fix).
|
||||
- [ ] `docs/00-governance/compile_guardrails.md` (prevention rule).
|
||||
- [ ] `docs/00-governance/patterns_and_antipatterns.md` (good vs bad pattern).
|
||||
|
||||
## Do Not
|
||||
- [ ] Do not guess signatures, overloads, enums, or attributes.
|
||||
- [ ] Do not invent placeholder enums/types unless confirmed by domain/task requirements.
|
||||
- [ ] Do not keep one-off incident dumps in this rule file; store incidents in `common_failures.md`.
|
||||
|
||||
@@ -1,195 +1,33 @@
|
||||
# Coding Patterns — NT8 SDK Required Patterns
|
||||
# Coding Patterns - NT8 SDK Required Patterns
|
||||
**Last Updated:** 2026-04-05
|
||||
|
||||
All code in the NT8 SDK MUST follow these patterns without exception.
|
||||
All production code must use these implementation patterns.
|
||||
|
||||
---
|
||||
## Scope Discipline and Minimum Diff
|
||||
- [ ] Edit only files in task scope.
|
||||
- [ ] Make the smallest safe change that resolves the issue.
|
||||
- [ ] Do not change interfaces/contracts unless explicitly required.
|
||||
- [ ] Do not mix functional changes with style-only cleanup.
|
||||
|
||||
## 1. Thread Safety — Lock Everything Shared
|
||||
## C# 5.0 and .NET 4.8 Compatibility
|
||||
- [ ] Use C# 5.0 syntax only.
|
||||
- [ ] Avoid C# 6+ features (`$""`, `?.`, `nameof`, expression-bodied members, `out var`, etc.).
|
||||
- [ ] Keep compatibility with .NET Framework 4.8.
|
||||
- [ ] Use `string.Format` style logging/messages.
|
||||
|
||||
Every class with shared state must have a lock object:
|
||||
```csharp
|
||||
private readonly object _lock = new object();
|
||||
```
|
||||
## Core Implementation Patterns
|
||||
- [ ] Validate inputs at method entry.
|
||||
- [ ] Wrap public method logic in `try/catch` with meaningful logging.
|
||||
- [ ] Protect shared mutable collections/state with `lock (_lock)`.
|
||||
- [ ] Do not raise events while holding locks.
|
||||
- [ ] Keep public members documented with XML comments where required by project standards.
|
||||
|
||||
Every access to shared `Dictionary`, `List`, `Queue`, or any field touched by multiple threads:
|
||||
```csharp
|
||||
// ❌ NEVER
|
||||
_activeOrders[orderId] = status;
|
||||
## NinjaScript Coding Patterns (When Applicable)
|
||||
- [ ] Keep `OnStateChange` responsibilities separated by state.
|
||||
- [ ] Guard `OnBarUpdate` by `BarsInProgress` and bar readiness.
|
||||
- [ ] In managed order flow, set stop/target before entry on the same bar.
|
||||
|
||||
// ✅ ALWAYS
|
||||
lock (_lock)
|
||||
{
|
||||
_activeOrders[orderId] = status;
|
||||
}
|
||||
```
|
||||
|
||||
### Read-then-write must be atomic
|
||||
```csharp
|
||||
// ❌ WRONG — race condition between check and write
|
||||
if (!_orders.ContainsKey(id))
|
||||
_orders[id] = newOrder;
|
||||
|
||||
// ✅ CORRECT
|
||||
lock (_lock)
|
||||
{
|
||||
if (!_orders.ContainsKey(id))
|
||||
_orders[id] = newOrder;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Error Handling — Try-Catch on All Public Methods
|
||||
|
||||
```csharp
|
||||
public ReturnType MethodName(Type parameter)
|
||||
{
|
||||
// 1. Validate parameters first
|
||||
if (parameter == null)
|
||||
throw new ArgumentNullException("parameter");
|
||||
|
||||
// 2. Wrap the main logic
|
||||
try
|
||||
{
|
||||
// Implementation
|
||||
return result;
|
||||
}
|
||||
catch (SpecificException ex)
|
||||
{
|
||||
_logger.LogError("Specific failure in MethodName: {0}", ex.Message);
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("Unexpected failure in MethodName: {0}", ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Logging — Always string.Format, Never $""
|
||||
|
||||
```csharp
|
||||
// ❌ NEVER — C# 6 syntax, breaks NT8 compile
|
||||
_logger.LogInformation($"Order {orderId} filled");
|
||||
|
||||
// ✅ ALWAYS
|
||||
_logger.LogInformation("Order {0} filled", orderId);
|
||||
_logger.LogWarning("Risk check failed for {0}: {1}", symbol, reason);
|
||||
_logger.LogError("Exception in {0}: {1}", "MethodName", ex.Message);
|
||||
_logger.LogCritical("Emergency flatten triggered: {0}", reason);
|
||||
```
|
||||
|
||||
### Log level guide
|
||||
| Level | When to use |
|
||||
|---|---|
|
||||
| `LogTrace` | Entering/exiting methods, fine-grained flow |
|
||||
| `LogDebug` | State reads, normal data flow |
|
||||
| `LogInformation` | Important events: order submitted, filled, cancelled |
|
||||
| `LogWarning` | Recoverable issues: validation failed, limit approaching |
|
||||
| `LogError` | Failures: exceptions, unexpected states |
|
||||
| `LogCritical` | System integrity issues: emergency flatten, data corruption |
|
||||
|
||||
---
|
||||
|
||||
## 4. Events — Never Raise Inside Locks
|
||||
|
||||
Raising events inside a lock causes deadlocks when event handlers acquire other locks.
|
||||
|
||||
```csharp
|
||||
// ❌ DEADLOCK RISK
|
||||
lock (_lock)
|
||||
{
|
||||
_state = newState;
|
||||
OrderStateChanged?.Invoke(this, args); // handler may try to acquire _lock
|
||||
}
|
||||
|
||||
// ✅ CORRECT
|
||||
OrderState newState;
|
||||
lock (_lock)
|
||||
{
|
||||
newState = CalculateNewState();
|
||||
_state = newState;
|
||||
}
|
||||
// Raise AFTER releasing lock
|
||||
RaiseOrderStateChanged(orderId, previousState, newState);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Constructor — Validate All Dependencies
|
||||
|
||||
```csharp
|
||||
public MyClass(ILogger<MyClass> logger, ISomeDependency dep)
|
||||
{
|
||||
if (logger == null)
|
||||
throw new ArgumentNullException("logger");
|
||||
if (dep == null)
|
||||
throw new ArgumentNullException("dep");
|
||||
|
||||
_logger = logger;
|
||||
_dep = dep;
|
||||
|
||||
// Initialize collections
|
||||
_activeOrders = new Dictionary<string, OrderStatus>();
|
||||
|
||||
_logger.LogInformation("MyClass initialized");
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. XML Documentation — Required on All Public Members
|
||||
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// Brief one-line description of what this does.
|
||||
/// </summary>
|
||||
/// <param name="intent">The trading intent to validate.</param>
|
||||
/// <param name="context">Current strategy context with account state.</param>
|
||||
/// <returns>Risk decision indicating allow or reject.</returns>
|
||||
/// <exception cref="ArgumentNullException">Thrown when intent or context is null.</exception>
|
||||
public RiskDecision ValidateOrder(StrategyIntent intent, StrategyContext context)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. NT8-Specific Patterns (NinjaScript)
|
||||
|
||||
When writing code that runs inside NinjaTrader (in `NT8.Adapters/`):
|
||||
|
||||
```csharp
|
||||
// Always guard OnBarUpdate
|
||||
protected override void OnBarUpdate()
|
||||
{
|
||||
if (BarsInProgress != 0) return;
|
||||
if (CurrentBar < BarsRequiredToTrade) return;
|
||||
// ...
|
||||
}
|
||||
|
||||
// Managed order pattern — set stops BEFORE entry
|
||||
SetStopLoss("SignalName", CalculationMode.Ticks, stopTicks, false);
|
||||
SetProfitTarget("SignalName", CalculationMode.Ticks, targetTicks);
|
||||
EnterLong(contracts, "SignalName");
|
||||
|
||||
// Use string.Format for Print() too
|
||||
Print(string.Format("Order submitted: {0} contracts at {1}", qty, price));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Checklist Before Marking Any Method Complete
|
||||
|
||||
- [ ] Parameter null checks at the top
|
||||
- [ ] `try-catch` wrapping the body
|
||||
- [ ] All `Dictionary`/collection access inside `lock (_lock)`
|
||||
- [ ] All logging uses `string.Format()` (no `$""`)
|
||||
- [ ] XML `/// <summary>` on every public method, property, class
|
||||
- [ ] No C# 6+ syntax
|
||||
- [ ] Events raised outside lock blocks
|
||||
- [ ] `verify-build.bat` passes
|
||||
## Authoritative Rule References (Do Not Duplicate)
|
||||
- Syntax constraints: `.kilocode/rules/csharp_50_syntax.md`
|
||||
- NT8 compile and API constraints: `.kilocode/rules/nt8compilespec.md`
|
||||
- Verification commands and gates: `.kilocode/rules/verification_requirements.md`
|
||||
|
||||
@@ -1,243 +1,46 @@
|
||||
# NT8 Institutional SDK - Development Workflow
|
||||
# NT8-SDK Development Workflow
|
||||
**Last Updated:** 2026-04-05
|
||||
|
||||
## Overview
|
||||
This document outlines the development workflow for the NT8 Institutional SDK, following the Archon workflow principles even in the absence of the Archon MCP server.
|
||||
Operational workflow for Kilo/Codex-assisted development.
|
||||
|
||||
## Archon Workflow Principles
|
||||
## Per-Task Workflow (Required)
|
||||
1. **Confirm scope**
|
||||
- [ ] Confirm exact files allowed by task spec.
|
||||
- [ ] Cross-check `.kilocode/rules/file_boundaries.md`.
|
||||
2. **Set task state**
|
||||
- [ ] Move task status from `todo` -> `doing` before edits.
|
||||
3. **Implement**
|
||||
- [ ] Make minimum-diff changes only in scoped files.
|
||||
4. **Verify**
|
||||
- [ ] Run `.\verify-build.bat` per `.kilocode/rules/verification_requirements.md`.
|
||||
- [ ] Run focused tests required by changed area.
|
||||
5. **NT8 compile/deploy checks** (when NinjaScript files are touched)
|
||||
- [ ] Validate signatures against official NT8 docs.
|
||||
- [ ] Run repo build/deploy sequence required for NT8.
|
||||
- [ ] Compile in NinjaScript Editor (authoritative NT8 check).
|
||||
6. **Documentation updates**
|
||||
- [ ] Update `docs/00-governance/active_work.md` when task status or blockers changed.
|
||||
- [ ] Update `docs/00-governance/roadmap.md` when sequencing/scope changed.
|
||||
- [ ] Update `docs/00-governance/decisions.md` when durable architecture decisions were made.
|
||||
- [ ] Update `CLEANUP_LOG.md` when cleanup debt status changed.
|
||||
7. **Compile-learning capture** (if any compile issue occurred)
|
||||
- [ ] Add prevention rule to `docs/00-governance/compile_guardrails.md`.
|
||||
- [ ] Add error fingerprint + fix to `docs/00-governance/common_failures.md`.
|
||||
- [ ] Add pattern/anti-pattern to `docs/00-governance/patterns_and_antipatterns.md`.
|
||||
8. **Set task state and report**
|
||||
- [ ] Move task status from `doing` -> `review`.
|
||||
- [ ] Report changed files and verification evidence.
|
||||
|
||||
The development process follows these core principles adapted from the Archon workflow:
|
||||
## Definition of Done (Required)
|
||||
- [ ] Only scoped files changed.
|
||||
- [ ] Verification gates passed.
|
||||
- [ ] NT8 compile checks completed when relevant.
|
||||
- [ ] Relevant governance docs updated.
|
||||
- [ ] Compile learnings captured when applicable.
|
||||
- [ ] Task moved to `review` with evidence.
|
||||
|
||||
### 1. Check Current Task
|
||||
Before beginning any work, clearly define what needs to be accomplished:
|
||||
- Review requirements and specifications
|
||||
- Understand success criteria
|
||||
- Identify dependencies and blockers
|
||||
|
||||
### 2. Research for Task
|
||||
Conduct thorough research before implementation:
|
||||
- Review existing code and documentation
|
||||
- Understand best practices and patterns
|
||||
- Identify potential challenges and solutions
|
||||
|
||||
### 3. Implement the Task
|
||||
Execute the implementation with focus and precision:
|
||||
- Follow established patterns and conventions
|
||||
- Write clean, maintainable code
|
||||
- Include comprehensive error handling
|
||||
- Add structured logging for observability
|
||||
|
||||
### 4. Update Task Status
|
||||
Track progress and document completion:
|
||||
- Mark tasks as completed in the todo list
|
||||
- Document any issues or deviations
|
||||
- Note lessons learned for future reference
|
||||
|
||||
### 5. Get Next Task
|
||||
Move systematically through the implementation:
|
||||
- Prioritize tasks based on dependencies
|
||||
- Focus on one task at a time
|
||||
- Ensure quality before moving forward
|
||||
|
||||
## Development Process
|
||||
|
||||
### Phase 1: Planning and Design
|
||||
1. Review specifications and requirements
|
||||
2. Create architecture diagrams and documentation
|
||||
3. Identify core components and their interactions
|
||||
4. Plan implementation approach and timeline
|
||||
|
||||
### Phase 2: Environment Setup
|
||||
1. Create project structure and configuration files
|
||||
2. Set up build and test infrastructure
|
||||
3. Configure CI/CD pipeline
|
||||
4. Verify development environment
|
||||
|
||||
### Phase 3: Core Implementation
|
||||
1. Implement core interfaces and models
|
||||
2. Develop risk management components
|
||||
3. Create position sizing algorithms
|
||||
4. Build supporting utilities and helpers
|
||||
|
||||
### Phase 4: Testing and Validation
|
||||
1. Create comprehensive unit tests
|
||||
2. Implement integration tests
|
||||
3. Run validation scripts
|
||||
4. Verify all success criteria
|
||||
|
||||
### Phase 5: Documentation and Delivery
|
||||
1. Create developer documentation
|
||||
2. Write user guides and examples
|
||||
3. Prepare release notes
|
||||
4. Conduct final validation
|
||||
|
||||
## Code Quality Standards
|
||||
|
||||
### 1. Code Structure
|
||||
- Follow established naming conventions
|
||||
- Use consistent formatting and style
|
||||
- Organize code into logical modules
|
||||
- Maintain clear separation of concerns
|
||||
|
||||
### 2. Error Handling
|
||||
- Validate all inputs and parameters
|
||||
- Provide meaningful error messages
|
||||
- Handle exceptions gracefully
|
||||
- Log errors for debugging
|
||||
|
||||
### 3. Testing
|
||||
- Write unit tests for all public methods
|
||||
- Include edge case testing
|
||||
- Validate error conditions
|
||||
- Maintain >90% code coverage
|
||||
|
||||
### 4. Documentation
|
||||
- Include XML documentation for all public APIs
|
||||
- Add inline comments for complex logic
|
||||
- Document configuration options
|
||||
- Provide usage examples
|
||||
|
||||
## Git Workflow
|
||||
|
||||
### Branching Strategy
|
||||
- Use feature branches for all development
|
||||
- Create branches from main for new features
|
||||
- Keep feature branches short-lived
|
||||
- Merge to main after review and testing
|
||||
|
||||
### Commit Guidelines
|
||||
- Write clear, descriptive commit messages
|
||||
- Make small, focused commits
|
||||
- Reference issues or tasks in commit messages
|
||||
- Squash related commits before merging
|
||||
|
||||
### Pull Request Process
|
||||
- Create PRs for all feature work
|
||||
- Include description of changes and testing
|
||||
- Request review from team members
|
||||
- Address feedback before merging
|
||||
|
||||
## Development Environment
|
||||
|
||||
### Required Tools
|
||||
- .NET 6.0 SDK
|
||||
- Visual Studio Code or Visual Studio
|
||||
- Git for version control
|
||||
- Docker Desktop (recommended)
|
||||
|
||||
### Recommended Extensions
|
||||
- C# for Visual Studio Code
|
||||
- EditorConfig for VS Code
|
||||
- GitLens for enhanced Git experience
|
||||
- Docker extension for container management
|
||||
|
||||
## Build and Test Process
|
||||
|
||||
### Local Development
|
||||
1. Restore NuGet packages: `dotnet restore`
|
||||
2. Build solution: `dotnet build`
|
||||
3. Run tests: `dotnet test`
|
||||
4. Run specific test categories if needed
|
||||
|
||||
### Continuous Integration
|
||||
- Automated builds on every commit
|
||||
- Run full test suite on each build
|
||||
- Generate code coverage reports
|
||||
- Deploy to test environments
|
||||
|
||||
## Debugging and Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
1. **Build Failures**
|
||||
- Check for missing NuGet packages
|
||||
- Verify .NET SDK version
|
||||
- Ensure all projects reference correct frameworks
|
||||
|
||||
2. **Test Failures**
|
||||
- Review test output for specific errors
|
||||
- Check test data and setup
|
||||
- Verify mock configurations
|
||||
|
||||
3. **Runtime Errors**
|
||||
- Check logs for error details
|
||||
- Validate configuration settings
|
||||
- Review dependency injection setup
|
||||
|
||||
### Debugging Tools
|
||||
- Visual Studio debugger
|
||||
- Console logging
|
||||
- Structured logging with correlation IDs
|
||||
- Performance profiling tools
|
||||
|
||||
## Release Process
|
||||
|
||||
### Versioning
|
||||
- Follow semantic versioning (MAJOR.MINOR.PATCH)
|
||||
- Increment version in Directory.Build.props
|
||||
- Update release notes with changes
|
||||
- Tag releases in Git
|
||||
|
||||
### Deployment
|
||||
- Create NuGet packages for SDK components
|
||||
- Publish to internal package repository
|
||||
- Update documentation with release notes
|
||||
- Notify stakeholders of new releases
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Code Reviews
|
||||
- Review all code before merging
|
||||
- Focus on correctness, maintainability, and performance
|
||||
- Provide constructive feedback
|
||||
- Ensure adherence to coding standards
|
||||
|
||||
### 2. Performance Considerations
|
||||
- Minimize allocations in hot paths
|
||||
- Use efficient data structures
|
||||
- Cache expensive operations
|
||||
- Profile performance regularly
|
||||
|
||||
### 3. Security
|
||||
- Validate all inputs
|
||||
- Sanitize user data
|
||||
- Protect sensitive configuration
|
||||
- Follow secure coding practices
|
||||
|
||||
### 4. Maintainability
|
||||
- Write self-documenting code
|
||||
- Use meaningful variable and method names
|
||||
- Keep methods small and focused
|
||||
- Refactor regularly to improve design
|
||||
|
||||
## Task Management Without Archon
|
||||
|
||||
Since we're not using the Archon MCP server, we'll manage tasks using:
|
||||
1. **Todo Lists**: Track progress using markdown checklists
|
||||
2. **Documentation**: Maintain detailed records of implementation decisions
|
||||
3. **Git**: Use commits and branches to track work progress
|
||||
4. **Issue Tracking**: Use GitHub Issues or similar for task management
|
||||
|
||||
### Task Status Tracking
|
||||
- **Todo**: Task identified but not started
|
||||
- **In Progress**: Actively working on task
|
||||
- **Review**: Task completed, awaiting validation
|
||||
- **Done**: Task validated and completed
|
||||
|
||||
## Communication and Collaboration
|
||||
|
||||
### Team Coordination
|
||||
- Hold regular standups to discuss progress
|
||||
- Use collaborative tools for communication
|
||||
- Document architectural decisions
|
||||
- Share knowledge and best practices
|
||||
|
||||
### Knowledge Sharing
|
||||
- Conduct code walkthroughs for complex features
|
||||
- Create technical documentation
|
||||
- Share lessons learned from issues
|
||||
- Mentor new team members
|
||||
|
||||
## Conclusion
|
||||
|
||||
This development workflow ensures consistent, high-quality implementation of the NT8 Institutional SDK. By following these principles and practices, we can deliver a robust, maintainable, and scalable trading platform that meets institutional requirements for risk management and performance.
|
||||
|
||||
The workflow emphasizes systematic progress, quality assurance, and continuous improvement. Each task should be approached with thorough research, careful implementation, and comprehensive validation to ensure the highest quality outcome.
|
||||
## Out-of-Scope Safety
|
||||
- [ ] Do not modify files outside task scope.
|
||||
- [ ] Do not apply opportunistic refactors.
|
||||
- [ ] Do not modify historical/contextual docs unless explicitly requested.
|
||||
- [ ] If a real fix needs out-of-scope changes, stop and report a scope blocker.
|
||||
|
||||
31
.kilocode/rules/docs_maintenance.md
Normal file
31
.kilocode/rules/docs_maintenance.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Governance Docs Maintenance Policy
|
||||
**Last Updated:** 2026-04-05
|
||||
|
||||
## Canonical Source Rule
|
||||
- [ ] `docs/00-governance/*` is the canonical planning and execution source.
|
||||
- [ ] Prefer updating canonical governance docs over duplicating guidance elsewhere.
|
||||
|
||||
## Historical/Contextual Docs (Read-Only by Default)
|
||||
Treat these as non-canonical unless explicitly requested by task scope:
|
||||
- `README.md`
|
||||
- `docs/README.md`
|
||||
- `PROJECT_HANDOVER.md`
|
||||
- `DESIGNED_VS_IMPLEMENTED_GAP_ANALYSIS.md`
|
||||
- `docs/INDEX.md`
|
||||
|
||||
## Update Triggers
|
||||
- [ ] Update `docs/00-governance/active_work.md` when priorities, status, blockers, or ownership change.
|
||||
- [ ] Update `docs/00-governance/roadmap.md` when milestone sequence, scope, or timing changes.
|
||||
- [ ] Update `docs/00-governance/decisions.md` when durable architecture tradeoffs/decisions are made.
|
||||
- [ ] Update `CLEANUP_LOG.md` when cleanup debt is created, resolved, or deferred.
|
||||
|
||||
## Compile Knowledge Capture (Concise and Durable)
|
||||
When a compile issue occurs, record:
|
||||
- [ ] Prevention rule in `docs/00-governance/compile_guardrails.md`.
|
||||
- [ ] Error fingerprint + fix in `docs/00-governance/common_failures.md`.
|
||||
- [ ] Reusable pattern and anti-pattern in `docs/00-governance/patterns_and_antipatterns.md`.
|
||||
|
||||
## Documentation Hygiene
|
||||
- [ ] Keep entries concise, actionable, and dated.
|
||||
- [ ] Link to authoritative rules instead of duplicating long guidance.
|
||||
- [ ] Do not update unrelated docs in the same task.
|
||||
35
.kilocode/rules/ninjascript_guardrails.md
Normal file
35
.kilocode/rules/ninjascript_guardrails.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# NinjaScript Guardrails - Operational Checklist
|
||||
**Last Updated:** 2026-04-05
|
||||
|
||||
Use this checklist whenever touching NinjaScript-facing files.
|
||||
|
||||
## Pre-Edit Checks (Required)
|
||||
- [ ] Confirm file is in task scope and allowed by `.kilocode/rules/file_boundaries.md`.
|
||||
- [ ] Verify exact API signatures against official NT8 docs: `https://developer.ninjatrader.com/docs/desktop`.
|
||||
- [ ] Confirm C# 5.0 compatibility using `.kilocode/rules/csharp_50_syntax.md`.
|
||||
|
||||
## Lifecycle and Safety Rules (Required)
|
||||
- [ ] Use `OnStateChange` correctly: `State.SetDefaults`, `State.Configure`, `State.DataLoaded`.
|
||||
- [ ] Keep runtime logic out of `SetDefaults` and `Configure`.
|
||||
- [ ] Guard `OnBarUpdate` for series and readiness (`BarsInProgress`, `CurrentBar`/`CurrentBars`).
|
||||
- [ ] In managed order flow, set stop/target before entry on the same bar.
|
||||
- [ ] Do not mix managed and unmanaged order models unless explicitly required.
|
||||
|
||||
## API Integrity Rules (Required)
|
||||
- [ ] Do not guess method signatures, enum members, attributes, or overloads.
|
||||
- [ ] Do not use unsupported attributes (example: `[Optimizable]`).
|
||||
- [ ] Do not invent placeholder types/enums unless explicitly confirmed by task/domain requirements.
|
||||
|
||||
## Compile Validation Sequence
|
||||
- [ ] Run `.\verify-build.bat`.
|
||||
- [ ] Run required deploy step when NinjaScript source must be synced to NT8.
|
||||
- [ ] Compile in NT8 NinjaScript Editor (authoritative NinjaScript compile gate).
|
||||
|
||||
## Compile Failure Learning Loop
|
||||
If any compile issue occurs:
|
||||
- [ ] Capture error fingerprint (`code`, file, line, root cause).
|
||||
- [ ] Apply the smallest safe fix and re-run validation sequence.
|
||||
- [ ] Record durable learning in:
|
||||
- `docs/00-governance/common_failures.md` (symptom + fix)
|
||||
- `docs/00-governance/compile_guardrails.md` (preventive rule)
|
||||
- `docs/00-governance/patterns_and_antipatterns.md` (good vs bad pattern)
|
||||
@@ -1,96 +1,45 @@
|
||||
# Project Context — NT8 SDK (Production Hardening Phase)
|
||||
# Project Context - NT8 SDK
|
||||
**Last Updated:** 2026-04-05
|
||||
|
||||
You are working on the **NT8 SDK** — an institutional-grade algorithmic trading framework for NinjaTrader 8.
|
||||
This is production trading software. Bugs cause real financial losses.
|
||||
Mission: ship safe, compile-stable NT8 trading software with strict scope control and durable governance documentation.
|
||||
|
||||
---
|
||||
## Session Start (Mandatory)
|
||||
- [ ] Read these files first, in order:
|
||||
1. `docs/00-governance/executive_summary.md`
|
||||
2. `docs/00-governance/current_status.md`
|
||||
3. `docs/00-governance/active_work.md`
|
||||
4. `docs/00-governance/architecture.md`
|
||||
5. `docs/00-governance/roadmap.md`
|
||||
- [ ] Treat `docs/00-governance/*` as canonical for current direction.
|
||||
|
||||
## What Is Already Built (Do Not Touch)
|
||||
## Historical/Contextual Sources (Non-Canonical)
|
||||
Use only for background unless explicitly requested in task scope:
|
||||
- `README.md`
|
||||
- `docs/README.md`
|
||||
- `PROJECT_HANDOVER.md`
|
||||
- `DESIGNED_VS_IMPLEMENTED_GAP_ANALYSIS.md`
|
||||
- `docs/INDEX.md`
|
||||
|
||||
All core trading logic is complete and has 240+ passing tests:
|
||||
## File Touch Scope (Hard Rules)
|
||||
- [ ] Modify only files explicitly listed in the task spec.
|
||||
- [ ] Do not edit adjacent files for cleanup or style-only changes.
|
||||
- [ ] If a required fix is outside scope, stop and record a scope blocker.
|
||||
- [ ] Respect `.kilocode/rules/file_boundaries.md` at all times.
|
||||
|
||||
| Layer | Status | Key Files |
|
||||
|---|---|---|
|
||||
| Risk (Tier 1-3) | ✅ Complete | `src/NT8.Core/Risk/` |
|
||||
| Position Sizing | ✅ Complete | `src/NT8.Core/Sizing/` |
|
||||
| OMS / Order Lifecycle | ✅ Complete | `src/NT8.Core/OMS/` |
|
||||
| Intelligence | ✅ Complete | `src/NT8.Core/Intelligence/` |
|
||||
| Analytics | ✅ Complete | `src/NT8.Core/Analytics/` |
|
||||
| Execution Utilities | ✅ Complete | `src/NT8.Core/Execution/` |
|
||||
| Market Data | ✅ Complete | `src/NT8.Core/MarketData/` |
|
||||
## Conversation Separation (Hard Rules)
|
||||
- [ ] Strategy conversations: entry/exit logic and behavior.
|
||||
- [ ] Architecture conversations: cross-component design and interfaces.
|
||||
- [ ] Coding conversations: implementation details and diffs.
|
||||
- [ ] Do not mix decisions across tracks; record architecture decisions in `docs/00-governance/decisions.md`.
|
||||
|
||||
**NT8 Order Execution is ALREADY WIRED.**
|
||||
`NT8StrategyBase.SubmitOrderToNT8()` calls `EnterLong`, `EnterShort`, `SetStopLoss`, and
|
||||
`SetProfitTarget` directly. The execution path works end-to-end. Do not re-implement it.
|
||||
## Documentation Sync Triggers
|
||||
Update governance docs as part of normal task completion:
|
||||
- [ ] Update `docs/00-governance/active_work.md` when current priorities, status, blockers, or ownership change.
|
||||
- [ ] Update `docs/00-governance/roadmap.md` when milestone sequence, scope, or timing changes.
|
||||
- [ ] Update `docs/00-governance/decisions.md` when a durable tradeoff or architecture decision is made.
|
||||
- [ ] Update `CLEANUP_LOG.md` when cleanup debt is created, resolved, or deferred.
|
||||
|
||||
---
|
||||
|
||||
## What You Are Fixing (The Active Task List)
|
||||
|
||||
### CRITICAL — `NT8StrategyBase.cs`
|
||||
|
||||
**Gap 1 — No kill switch**
|
||||
`NT8StrategyBase` has no `EnableKillSwitch` NinjaScript parameter and no early-exit in `OnBarUpdate()`.
|
||||
A runaway strategy cannot be stopped without killing NinjaTrader.
|
||||
**Fix:** Add `EnableKillSwitch` (bool NinjaScript property) and `EnableVerboseLogging` property.
|
||||
Add kill switch check as the FIRST thing in `OnBarUpdate()`.
|
||||
→ See `TASK-01-kill-switch.md`
|
||||
|
||||
**Gap 2 — `ExecutionCircuitBreaker` not wired**
|
||||
`src/NT8.Core/Execution/ExecutionCircuitBreaker.cs` is complete and tested.
|
||||
It is never instantiated. Orders submit regardless of latency or rejection conditions.
|
||||
**Fix:** Instantiate in `InitializeSdkComponents()`, gate orders in `SubmitOrderToNT8()`, wire rejections in `OnOrderUpdate()`.
|
||||
→ See `TASK-02-circuit-breaker.md`
|
||||
|
||||
### HIGH — `TrailingStopManager.cs`
|
||||
|
||||
**Gap 3 — Placeholder stop math returns zero**
|
||||
`CalculateNewStopPrice()` FixedTrailing branch: `marketPrice - (x - x)` = always zero movement.
|
||||
ATRTrailing and Chandelier also have meaningless placeholder formulas.
|
||||
**Fix:** Replace with real calculations using `TrailingStopConfig.TrailingAmountTicks` and `AtrMultiplier`.
|
||||
→ See `TASK-03-trailing-stop.md`
|
||||
|
||||
### HIGH — `BasicLogger.cs`
|
||||
|
||||
**Gap 4 — No log-level filter**
|
||||
Every log statement writes to console unconditionally. Cannot suppress debug noise in production.
|
||||
**Fix:** Add `MinimumLevel` property (defaults to `Information`). Suppress messages below threshold.
|
||||
→ See `TASK-04-log-level.md`
|
||||
|
||||
### MEDIUM — `SessionManager.cs`
|
||||
|
||||
**Gap 5 — No holiday awareness**
|
||||
`IsRegularTradingHours()` checks session times only. Will attempt to trade on Christmas, Thanksgiving, etc.
|
||||
**Fix:** Add static CME holiday set for 2025/2026. Return `false` on those dates.
|
||||
→ See `TASK-05-session-holidays.md`
|
||||
|
||||
---
|
||||
|
||||
## Architecture (Read Before Touching Anything)
|
||||
|
||||
```
|
||||
SimpleORBStrategy.OnBar()
|
||||
↓ returns StrategyIntent
|
||||
NT8StrategyBase.OnBarUpdate()
|
||||
↓ [TASK-01: kill switch check here, first]
|
||||
↓ calls ProcessStrategyIntent()
|
||||
↓ calls _riskManager.ValidateOrder()
|
||||
↓ calls _positionSizer.CalculateSize()
|
||||
↓ calls SubmitOrderToNT8()
|
||||
↓ [TASK-02: circuit breaker gate here]
|
||||
↓ calls EnterLong/EnterShort/SetStopLoss/SetProfitTarget (already works)
|
||||
NT8 callbacks → OnOrderUpdate / OnExecutionUpdate
|
||||
↓ [TASK-02: record rejections in circuit breaker here]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Technology Constraints
|
||||
|
||||
- **C# 5.0 only** — no `$""`, no `?.`, no `=>` on methods/properties, no `nameof()`, no `out var`
|
||||
- **.NET Framework 4.8** — not .NET Core/5+/6+
|
||||
- **NinjaScript managed orders** — `EnterLong`, `EnterShort`, `SetStopLoss`, `SetProfitTarget`
|
||||
- `string.Format()` everywhere, never string interpolation
|
||||
- All `Dictionary`, `HashSet` access inside `lock (_lock)` blocks
|
||||
- XML doc comments on all public members
|
||||
- `try/catch` on all public methods with `LogError` in the catch
|
||||
## Compatibility and Safety Baselines
|
||||
- [ ] C# 5.0 only (`.kilocode/rules/csharp_50_syntax.md`).
|
||||
- [ ] NT8 compile safety (`.kilocode/rules/ninjascript_guardrails.md`, `.kilocode/rules/nt8compilespec.md`).
|
||||
- [ ] Verification gates (`.kilocode/rules/verification_requirements.md`).
|
||||
|
||||
@@ -1,4 +1,75 @@
|
||||
# Designed vs. Implemented Features - Gap Analysis
|
||||
> ⚠️ HISTORICAL — see docs/00-governance/ for current state
|
||||
|
||||
This file may contain outdated or mixed historical information.
|
||||
Canonical current-state documentation lives in docs/00-governance/.
|
||||
This file is retained for history/reference only.
|
||||
|
||||
# NT8-SDK — Gap Analysis & Roadmap
|
||||
**Version:** 3.0 | **Date:** 2026-03-27 | Supersedes all previous gap analysis documents.
|
||||
|
||||
---
|
||||
|
||||
## Open Gaps
|
||||
|
||||
| ID | Description | Priority | Sprint |
|
||||
|---|---|---|---|
|
||||
| GAP-001 | Runner leg backtest validation (Qty=2 check). EntriesPerDirection=2 restored but not backtested. | CRITICAL | S2-05 |
|
||||
| GAP-002 | orbRangeTicks not wired in DailyBarContext (hardcoded 0.0 in SimpleORBNT8.OnBarUpdate) | LOW | Sprint 3 |
|
||||
| GAP-003 | Risk parameter consistency: RiskPerTrade can exceed MaxTradeRisk silently. No assertion. | HIGH | S2-06 |
|
||||
| GAP-004 | GetRiskStatus() returns hardcoded limit rather than registered strategy config value | LOW | Sprint 3 |
|
||||
| GAP-005 | No Gitea CI pipeline. Build and test are manual. | MEDIUM | Sprint 3 |
|
||||
| GAP-006 | No n8n webhook alerts for fills, risk events, connection loss | MEDIUM | Sprint 3 |
|
||||
| GAP-007 | No walk-forward / out-of-sample validation. All backtests are in-sample. | HIGH | S2-08 |
|
||||
| GAP-008 | Short-side profitable only in crash regimes. No regime filter. | MEDIUM | Sprint 3 |
|
||||
| GAP-009 | No tick replay backtest. OnBarClose simulation compresses trade duration. | LOW | Sprint 3 |
|
||||
|
||||
---
|
||||
|
||||
## Sprint Roadmap
|
||||
|
||||
### Sprint 2 (ACTIVE) — SIM Validation
|
||||
Goal: 2+ weeks unattended SIM with dual-leg execution confirmed.
|
||||
Key pending: GAP-001 (runner validation), GAP-003 (risk consistency), GAP-007 (walk-forward).
|
||||
|
||||
### Sprint 3 — Production Hardening
|
||||
Goal: 30-day SIM clean. CI and alerts wired.
|
||||
Key work: GAP-004 through GAP-009, VWAPMeanReversion skeleton.
|
||||
|
||||
### Sprint 4 — Live Capital
|
||||
Gate: 30-day SIM PF > 2.0, max DD < $500.
|
||||
Key work: Go live 1 NQ contract, OvernightGap strategies, ops runbook.
|
||||
|
||||
### Sprint 5 — ML Inference
|
||||
Prerequisite: 60 days live data.
|
||||
Key work: FastAPI /predict, MLSignalFactorCalculator as 11th factor.
|
||||
|
||||
---
|
||||
|
||||
## Strategy Backlog
|
||||
|
||||
| ID | Strategy | Priority | Notes |
|
||||
|---|---|---|---|
|
||||
| STRAT_079 | Liquidity Sweep Reversal | Medium | Potential short-trade improvement |
|
||||
| STRAT_154 | Overnight Gap Continuation | High | Leverages existing SessionManager |
|
||||
| STRAT_214 | Overnight Gap Reversion | High | Counter to STRAT_154 |
|
||||
| LondonORB | London ORB (3:00 AM ET) | Medium | Separate LondonORBNT8 strategy file |
|
||||
| VWAP-MR | VWAP Mean Reversion | High | Sprint 3 build target |
|
||||
|
||||
---
|
||||
|
||||
## Backtest Performance Reference
|
||||
|
||||
| Date | Period | Trades | Win% | PF | Net | Config |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 2026-03-27 | Jan–Mar 2026 | 20 | 75% | **7.00** | $1,200 | trail=20 ✅ Production config |
|
||||
| 2026-03-27 | Jan–Mar 2026 | 40 | 75% | 3.69 | $1,075 | trail=12 |
|
||||
| 2026-03-27 | Mar 2025–Mar 2026 | 148 | 51% | 3.15 | $71,303 | 9 cts experimental |
|
||||
|
||||
Note: 148-trade run used RiskPerTrade=$500 + EntriesPerDirection=1 (runner blocked). Not a production reference.
|
||||
|
||||
---
|
||||
|
||||
# ARCHIVED BELOW — Original Gap Analysis (2026-02-17, superseded)
|
||||
|
||||
**Date:** February 17, 2026
|
||||
**Status:** Post Phase A-B-C NT8 Integration
|
||||
|
||||
@@ -1,9 +1,140 @@
|
||||
# NT8 SDK Project - Comprehensive Recap & Handover
|
||||
> ⚠️ HISTORICAL — see docs/00-governance/ for current state
|
||||
|
||||
**Document Version:** 2.0
|
||||
**Date:** February 16, 2026
|
||||
**Current Phase:** Phase 5 Complete
|
||||
**Project Completion:** ~85%
|
||||
This file may contain outdated or mixed historical information.
|
||||
Canonical current-state documentation lives in docs/00-governance/.
|
||||
This file is retained for history/reference only.
|
||||
|
||||
# NT8-SDK — Project Context & Current State
|
||||
**Version:** 3.0 | **Date:** 2026-03-27 | **Status:** Sprint 2 Active — SIM Validation
|
||||
|
||||
> This file supersedes the previous PROJECT_HANDOVER.md and is the live source of truth.
|
||||
> See also: `SPRINT_BOARD.md`, `GAP_ANALYSIS_AND_ROADMAP.md`, `CODING_PATTERNS.md`, `KILOCODE_WORKFLOW.md`
|
||||
> Full formatted handover: `NT8_SDK_Handover_Package.docx`
|
||||
|
||||
---
|
||||
|
||||
## 1. What This Is
|
||||
|
||||
NT8-SDK is an institutional-grade algorithmic futures trading system built on NinjaTrader 8. It is not a research prototype — it is production trading software where bugs equal real financial losses.
|
||||
|
||||
The system trades NQ (Nasdaq 100 E-mini futures) using a 30-minute Opening Range Breakout strategy (SimpleORB) with a 10-factor confluence scoring engine that grades each signal A+ through F before allowing execution. A scaler/runner dual-leg architecture captures quick targets on the scaler while the runner trails for extended moves.
|
||||
|
||||
**Division of labor:** Claude handles architecture, diagnosis, and Kilocode prompt design. Kilocode executes ALL code changes. Mo owns strategy direction and go/no-go decisions.
|
||||
|
||||
---
|
||||
|
||||
## 2. Technology Stack
|
||||
|
||||
| Layer | Technology | Constraint |
|
||||
|---|---|---|
|
||||
| Language | C# 5.0 | Hard — NinjaScript compiler limit |
|
||||
| Framework | .NET Framework 4.8 | Hard — NT8 requirement |
|
||||
| Platform | NinjaTrader 8 | Hard — execution environment |
|
||||
| Local repo | `C:\dev\nt8-sdk` | Windows path |
|
||||
| NT8 deploy | `C:\Users\billy\Documents\NinjaTrader 8\bin\Custom\Strategies\` | Must match source |
|
||||
| Deploy script | `deployment\deploy-to-nt8.bat` | Creates timestamped backups |
|
||||
| VCS | Gitea (self-hosted) | `https://git.thehussains.org/mo/nt8-sdk` |
|
||||
| AI coding | Kilocode | Executes ALL code changes |
|
||||
| Automation | n8n (self-hosted) | Deferred to Sprint 4 |
|
||||
| ML inference | Ollama (local) | Deferred to Sprint 5 |
|
||||
|
||||
**Critical C# constraint:** No `$""`, no `?.`, no `=>`, no async/await. Use `string.Format()`, explicit null checks, full method bodies.
|
||||
|
||||
---
|
||||
|
||||
## 3. Architecture (Top to Bottom)
|
||||
|
||||
```
|
||||
SimpleORBNT8.cs NT8 entry point — sets defaults, adds daily bar series, builds DailyBarContext
|
||||
↓
|
||||
NT8StrategyBase.cs Abstract base — bar routing, session management, kill switch, breakeven, runner
|
||||
↓
|
||||
SimpleORBStrategy.cs Core signal — ORB detection, 10-factor confluence, _tradeTaken session lock
|
||||
↓
|
||||
NT8OrderAdapter.cs INT8ExecutionBridge — calls EnterLong/EnterShort/SetStopLoss
|
||||
↓
|
||||
PortfolioRiskManager.cs Singleton — cross-strategy daily loss + contract cap
|
||||
↓
|
||||
NinjaTrader 8 Execution, fills, order management
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Current Production Parameters (SIM: SimSimple ORB)
|
||||
|
||||
| Parameter | Value | Notes |
|
||||
|---|---|---|
|
||||
| Instrument | NQ JUN26 | Primary instrument |
|
||||
| Bar type | 13-Range bars | |
|
||||
| BarsRequiredToTrade | 50 | Warm-up guard |
|
||||
| DailyLossLimit | $1,000 | |
|
||||
| MaxTradeRisk | $200 | |
|
||||
| RiskPerTrade | $100 | 2 contracts at current NQ prices |
|
||||
| MinContracts | 1 | |
|
||||
| MaxContracts | 3 | |
|
||||
| MaxOpenPositions | 2 | Scaler + runner |
|
||||
| EntriesPerDirection | 2 | Scaler slot 1, runner slot 2 |
|
||||
| MinTradeGrade | 5 (A) | 4 (B) for broad SIM testing |
|
||||
| EnableShortTrades | False | Long-only until short backtest done |
|
||||
| BreakevenTriggerTicks | 20 | Tuned from 12 |
|
||||
| RunnerTrailTicks | 20 | Tuned from 12 |
|
||||
| OpeningRangeMinutes | 30 | 9:30–10:00 ET |
|
||||
| StopTicks | 8 | $40 per contract NQ |
|
||||
| TargetTicks | 16 (dynamic) | Scales with ORB/ATR ratio |
|
||||
|
||||
---
|
||||
|
||||
## 5. Two-Path Deployment Rule
|
||||
|
||||
Every code change MUST be applied to both:
|
||||
1. `C:\dev\nt8-sdk\src\NT8.Adapters\Strategies\` (repo source)
|
||||
2. `C:\Users\billy\Documents\NinjaTrader 8\bin\Custom\Strategies\` (NT8 runtime)
|
||||
|
||||
After deployment, NT8 must recompile: Tools → Edit NinjaScript → open `NT8StrategyBase.cs` → save.
|
||||
|
||||
---
|
||||
|
||||
## 6. Key Learnings (Hard-Won)
|
||||
|
||||
1. **`State.Historical` guard** — `if (State == State.Realtime && !_realtimeBarSeen) return;` in `ProcessStrategyIntent` allows backtest (Historical), blocks replay burst in live.
|
||||
|
||||
2. **`_realtimeBarSeen` flag** — reset to `false` in `State.Realtime`, set `true` on first bar. Skips catch-up bar on live load to prevent replay burst.
|
||||
|
||||
3. **`EntriesPerDirection = 2`** — required for scaler + runner. Setting to 1 silently blocks the runner with no error.
|
||||
|
||||
4. **`SetStopLoss`/`SetProfitTarget` before `EnterLong`/`EnterShort`** — calling after entry is silently ignored in backtest.
|
||||
|
||||
5. **`Calculate.OnBarClose` backtest** — trades appear to close in under 1 second in logs. NT8 simulation artifact, not a bug. Live trades hold 2–20 minutes.
|
||||
|
||||
6. **NR7 warm-up** — requires 7 daily bars. Warm-up messages (0/7 bars) are correct behavior.
|
||||
|
||||
7. **NT8 never auto-recompiles** — always force recompile after file changes via NinjaScript Editor.
|
||||
|
||||
8. **Dual-path deployment mandatory** — stale deployed files cause phantom bugs where code looks right but behaves wrong.
|
||||
|
||||
9. **`PortfolioRiskManager` is a singleton** — fully implemented, no changes required. Kill switch, daily loss, contract cap all working.
|
||||
|
||||
10. **Sizing formula** — `floor(RiskPerTrade / (StopTicks × $5.00))`. NQ: `$100 / (8 × $5) = 2 contracts`. Always verify `RiskPerTrade <= MaxTradeRisk`.
|
||||
|
||||
---
|
||||
|
||||
## 7. Validated Backtest Results
|
||||
|
||||
| Date | Period | Trades | Win% | PF | Net | Config |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 2026-03-27 | Jan–Mar 2026 | 20 | 75% | **7.00** | $1,200 | 1 ct, trail=20 ✅ Best |
|
||||
| 2026-03-27 | Jan–Mar 2026 | 40 | 75% | 3.69 | $1,075 | 1 ct, trail=12 |
|
||||
| 2026-03-27 | Mar 2025–Mar 2026 | 148 | 51% | 3.15 | $71,303 | 9 cts (experimental) |
|
||||
|
||||
The 9-contract run used `RiskPerTrade=$500` — not a production configuration. Runner leg was also blocked (`EntriesPerDirection=1`) for that run. Re-run required after Sprint 2 fixes.
|
||||
|
||||
---
|
||||
|
||||
## 8. Immediate Next Actions Before Market Open
|
||||
|
||||
1. Run Strategy Analyzer (NQ JUN26, Jan 1 2026 → Mar 27 2026) and confirm `PNL_UPDATE Position=Short Qty=2` in session log — validates runner leg
|
||||
2. Verify SIM account settings: `RiskPerTrade=$100`, `BreakevenTriggerTicks=20`, `RunnerTrailTicks=20`
|
||||
3. Only re-enable BX68915-15 after runner validation passes — long-only, `MaxContracts=2`, `DailyLossLimit=$500`
|
||||
|
||||
---
|
||||
|
||||
|
||||
15
README.md
15
README.md
@@ -1,3 +1,18 @@
|
||||
> 📋 NOTE — This README is under revision. See docs/00-governance/ for current architecture and status.
|
||||
|
||||
# NT8-SDK — Institutional Algorithmic Futures Trading System
|
||||
|
||||
**See `NT8_SDK_Handover_Package.docx` for the complete milestone handover document.**
|
||||
|
||||
Quick reference docs in repo root:
|
||||
- `PROJECT_CONTEXT.md` — current state, parameters, key learnings
|
||||
- `SPRINT_BOARD.md` — active sprint tasks
|
||||
- `GAP_ANALYSIS_AND_ROADMAP.md` — open gaps and sprint plan
|
||||
- `CODING_PATTERNS.md` — C# 5.0 rules, NT8 quirks
|
||||
- `KILOCODE_WORKFLOW.md` — Kilocode prompt template and guardrails
|
||||
|
||||
---
|
||||
|
||||
# NT8 Institutional Trading SDK
|
||||
|
||||
**Version:** 0.2.0
|
||||
|
||||
@@ -173,7 +173,7 @@ else {
|
||||
}
|
||||
|
||||
if (-not $SkipVerification) {
|
||||
Write-Step "6/6" "Verifying deployment"
|
||||
Write-Step "6/7" "Verifying deployment"
|
||||
$ok = $true
|
||||
|
||||
if (-not (Test-Path "$nt8Custom\NT8.Core.dll")) {
|
||||
@@ -195,13 +195,43 @@ if (-not $SkipVerification) {
|
||||
Write-Success "Deployment verification passed"
|
||||
}
|
||||
else {
|
||||
Write-Step "6/6" "Skipping verification"
|
||||
Write-Step "6/7" "Skipping verification"
|
||||
}
|
||||
|
||||
# Step 7: Delete the compiled NinjaScript assembly so NT8 is forced to do a
|
||||
# full recompile from source on next startup. Without this, NT8 may load a
|
||||
# stale cached assembly and silently ignore updated .cs files.
|
||||
Write-Step "7/7" "Invalidating NinjaScript compiled assembly"
|
||||
$compiledDll = Join-Path $nt8Custom "NinjaTrader.Custom.dll"
|
||||
$compiledPdb = Join-Path $nt8Custom "NinjaTrader.Custom.pdb"
|
||||
$compiledXml = Join-Path $nt8Custom "NinjaTrader.Custom.xml"
|
||||
|
||||
$invalidated = 0
|
||||
foreach ($artifact in @($compiledDll, $compiledPdb)) {
|
||||
if (Test-Path $artifact) {
|
||||
Remove-Item $artifact -Force
|
||||
Write-Success ("Deleted {0}" -f (Split-Path $artifact -Leaf))
|
||||
$invalidated++
|
||||
}
|
||||
}
|
||||
|
||||
if ($invalidated -gt 0) {
|
||||
Write-Host " NT8 will perform a full recompile on next startup." -ForegroundColor Green
|
||||
Write-Host " The .xml file is documentation only and was left in place." -ForegroundColor Gray
|
||||
} else {
|
||||
Write-Warn "No compiled assembly found to delete (NT8 may not have been run yet)"
|
||||
}
|
||||
|
||||
$duration = (Get-Date) - $startTime
|
||||
Write-Header "Deployment Complete"
|
||||
Write-Host ("Duration: {0:F1} seconds" -f $duration.TotalSeconds)
|
||||
Write-Host "Next: Open NinjaTrader 8 -> NinjaScript Editor -> Compile All"
|
||||
Write-Host ""
|
||||
Write-Host "NEXT STEPS:" -ForegroundColor Cyan
|
||||
Write-Host " 1. Start NinjaTrader 8 (full recompile will happen automatically)" -ForegroundColor White
|
||||
Write-Host " 2. Wait for compilation to complete in the Output window" -ForegroundColor White
|
||||
Write-Host " 3. Remove and re-add the strategy to the chart" -ForegroundColor White
|
||||
Write-Host " 4. Verify defaults: BreakevenTriggerTicks=20 RunnerTrailTicks=20 MaxContracts=3" -ForegroundColor White
|
||||
Write-Host " 5. Confirm NT8 Output shows: StartBehavior=AdoptAccountPosition EntriesPerDirection=2" -ForegroundColor White
|
||||
|
||||
exit 0
|
||||
|
||||
|
||||
@@ -147,10 +147,32 @@ echo.
|
||||
echo Deployment complete.
|
||||
echo Backup location: %BACKUP_DIR%
|
||||
echo Manifest file : %MANIFEST_FILE%
|
||||
|
||||
echo.
|
||||
echo Next steps:
|
||||
echo 1. Open NinjaTrader 8.
|
||||
echo 2. Open NinjaScript Editor and press F5 (Compile).
|
||||
echo 3. Verify strategies appear in the Strategies list.
|
||||
echo Invalidating NinjaScript compiled assembly...
|
||||
set "COMPILED_DLL=%NT8_CUSTOM%\NinjaTrader.Custom.dll"
|
||||
set "COMPILED_PDB=%NT8_CUSTOM%\NinjaTrader.Custom.pdb"
|
||||
|
||||
if exist "%COMPILED_DLL%" (
|
||||
del /F /Q "%COMPILED_DLL%"
|
||||
echo [OK] Deleted NinjaTrader.Custom.dll
|
||||
) else (
|
||||
echo [WARN] NinjaTrader.Custom.dll not found - NT8 may not have been run yet
|
||||
)
|
||||
|
||||
if exist "%COMPILED_PDB%" (
|
||||
del /F /Q "%COMPILED_PDB%"
|
||||
echo [OK] Deleted NinjaTrader.Custom.pdb
|
||||
)
|
||||
|
||||
echo.
|
||||
echo ============================================================
|
||||
echo NEXT STEPS:
|
||||
echo 1. Start NinjaTrader 8 (full recompile happens automatically)
|
||||
echo 2. Wait for compilation to finish in the Output window
|
||||
echo 3. Remove and re-add the strategy to the chart
|
||||
echo 4. Verify defaults: BreakevenTriggerTicks=20 RunnerTrailTicks=20 MaxContracts=3
|
||||
echo 5. NT8 Output must show: StartBehavior=AdoptAccountPosition EntriesPerDirection=2
|
||||
echo ============================================================
|
||||
|
||||
exit /b 0
|
||||
|
||||
23
docs/00-governance/CLEANUP_LOG.md
Normal file
23
docs/00-governance/CLEANUP_LOG.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Governance Cleanup Log
|
||||
|
||||
## 2026-04-05
|
||||
- Established `docs/00-governance/` as canonical governance entry point.
|
||||
- Added concise governance baseline documents:
|
||||
- `executive_summary.md`
|
||||
- `architecture.md`
|
||||
- `current_status.md`
|
||||
- `roadmap.md`
|
||||
- `active_work.md`
|
||||
- Updated onboarding guidance in `.kilocode/rules/project_context.md` to point new sessions to governance docs first.
|
||||
- Reclassified `PROJECT_HANDOVER.md` and `DESIGNED_VS_IMPLEMENTED_GAP_ANALYSIS.md` as historical/contextual references, not primary truth.
|
||||
- No code files modified and no file moves performed.
|
||||
- Moved `docs/PHASE2_COMPLETION_REPORT.md` to `docs/archive/phase-history/PHASE2_COMPLETION_REPORT.md`.
|
||||
- Added historical header + archival note block to:
|
||||
- `docs/README.md`
|
||||
- `PROJECT_HANDOVER.md`
|
||||
- `DESIGNED_VS_IMPLEMENTED_GAP_ANALYSIS.md`
|
||||
- `docs/INDEX.md`
|
||||
- `docs/archive/phase-history/PHASE2_COMPLETION_REPORT.md`
|
||||
- Added a softer revision note to `README.md` instead of a historical warning.
|
||||
- Marked `docs/INDEX.md` historical in place because it currently misdirects navigation.
|
||||
- Added follow-up debt: shared metrics vocabulary currently duplicated in `docs/02-runbooks/backtest_review_workflow.md` and `docs/02-runbooks/live_test_review_workflow.md`; later extract to shared governance doc `docs/00-governance/metrics_vocabulary.md`.
|
||||
17
docs/00-governance/active_work.md
Normal file
17
docs/00-governance/active_work.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Active Work
|
||||
|
||||
## Current Execution Focus
|
||||
- Validate runner-leg dual-fill behavior in Strategy Analyzer/session logs.
|
||||
- Close remaining Sprint 2 hardening items already identified in task specs.
|
||||
- Preserve strict compile and deployment verification sequence for every change.
|
||||
|
||||
## In-Scope Hardening Themes
|
||||
- Strategy safety controls and execution circuit-breaker wiring.
|
||||
- Trailing stop calculation correctness.
|
||||
- Logging verbosity controls for production noise reduction.
|
||||
- Session/holiday awareness to avoid invalid trading windows.
|
||||
|
||||
## Working Rules
|
||||
- Apply changes only to explicitly scoped files per task.
|
||||
- Keep NT8 API signatures and managed-order sequencing exact.
|
||||
- Maintain C# 5.0 compatibility and existing interface boundaries.
|
||||
28
docs/00-governance/architecture.md
Normal file
28
docs/00-governance/architecture.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Architecture Governance
|
||||
|
||||
## Runtime Flow (Authoritative)
|
||||
```
|
||||
SimpleORBNT8.cs
|
||||
-> NT8StrategyBase.cs
|
||||
-> SimpleORBStrategy.cs
|
||||
-> NT8OrderAdapter.cs
|
||||
-> PortfolioRiskManager.cs
|
||||
-> NinjaTrader 8
|
||||
```
|
||||
|
||||
## Responsibilities
|
||||
- `SimpleORBNT8.cs`: NT8 entry point and platform lifecycle bridge.
|
||||
- `NT8StrategyBase.cs`: orchestration, risk gate sequencing, execution handoff, platform callbacks.
|
||||
- `SimpleORBStrategy.cs`: signal generation and confluence grading only.
|
||||
- `NT8OrderAdapter.cs`: execution bridge to NT8 managed order APIs.
|
||||
- `PortfolioRiskManager.cs`: cross-strategy risk controls and account-level enforcement.
|
||||
|
||||
## Architectural Constraints
|
||||
- Risk-first flow is mandatory; no strategy-level bypass of risk validation.
|
||||
- Managed-order sequence remains required (`SetStopLoss` / `SetProfitTarget` before entry).
|
||||
- C# 5.0 syntax only, .NET Framework 4.8 only.
|
||||
- NT8 signatures must be verified against official NinjaTrader docs before API-touching edits.
|
||||
|
||||
## Governance Notes
|
||||
- Core Risk/Sizing/OMS/Intelligence/Analytics layers are treated as complete and stable unless explicitly re-opened by approved work.
|
||||
- Hardening changes are concentrated in targeted adapter/utility components per active-work scope.
|
||||
33
docs/00-governance/common_failures.md
Normal file
33
docs/00-governance/common_failures.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Common Compile Failures
|
||||
**Last Updated:** 2026-04-05
|
||||
|
||||
Record concise error fingerprints and verified fixes.
|
||||
|
||||
## Entry Template
|
||||
- **Date:** YYYY-MM-DD
|
||||
- **Error:** `CSXXXX`
|
||||
- **Fingerprint:** file + line + short symptom
|
||||
- **Root cause:** one sentence
|
||||
- **Fix:** one to three concrete steps
|
||||
- **Prevention link:** guardrail/pattern doc entry added
|
||||
|
||||
## Starter Examples
|
||||
1. **`CS0115` no suitable method found to override**
|
||||
- Root cause: incorrect NT8 override signature.
|
||||
- Fix: replace with exact official signature; recompile.
|
||||
|
||||
2. **`CS0507` cannot change access modifiers when overriding**
|
||||
- Root cause: used `public override`/`private override` instead of `protected override`.
|
||||
- Fix: change to `protected override`; recompile.
|
||||
|
||||
3. **`CS0246` type or namespace not found**
|
||||
- Root cause: missing using/namespace or undefined domain type.
|
||||
- Fix: add correct namespace reference or confirmed type definition.
|
||||
|
||||
4. **`CS1503` argument type mismatch**
|
||||
- Root cause: wrong overload or argument ordering.
|
||||
- Fix: align call with exact method signature and parameter types.
|
||||
|
||||
5. **C# 6+ syntax in C# 5 project**
|
||||
- Root cause: use of `$""`, `?.`, `nameof`, expression-bodied members, etc.
|
||||
- Fix: rewrite using C# 5 compatible constructs.
|
||||
20
docs/00-governance/compile_guardrails.md
Normal file
20
docs/00-governance/compile_guardrails.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Compile Guardrails
|
||||
**Last Updated:** 2026-04-05
|
||||
|
||||
Preventive rules to reduce repeat compile failures.
|
||||
|
||||
## Core Prevention Rules
|
||||
- [ ] Verify NT8 signatures in official docs before adding/changing any `protected override`.
|
||||
- [ ] Keep NinjaScript edits within task scope and allowed file boundaries.
|
||||
- [ ] Enforce C# 5.0 syntax only; reject C# 6+ constructs.
|
||||
- [ ] Keep managed order sequence correct (stop/target before entry on same bar).
|
||||
- [ ] Guard `OnBarUpdate` by `BarsInProgress` and bar readiness.
|
||||
- [ ] Do not use unsupported attributes/types/enums without confirmation.
|
||||
|
||||
## Verification Gates
|
||||
- [ ] Run `.\verify-build.bat` after changes.
|
||||
- [ ] Run focused tests for changed area.
|
||||
- [ ] If NinjaScript touched, compile in NT8 NinjaScript Editor.
|
||||
|
||||
## Update Rule
|
||||
- [ ] Add a new guardrail entry whenever a compile issue reveals a missing prevention rule.
|
||||
20
docs/00-governance/current_status.md
Normal file
20
docs/00-governance/current_status.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Current Status
|
||||
|
||||
## Snapshot (2026-04-05)
|
||||
- Program phase: Sprint 2 SIM validation with production-hardening follow-through.
|
||||
- Core implementation: complete across major layers with 240+ passing tests.
|
||||
- Live focus: execution safety, validation depth, and operational reliability.
|
||||
|
||||
## Confirmed Working Areas
|
||||
- End-to-end strategy pipeline from signal -> risk -> sizing -> NT8 managed execution.
|
||||
- Session handling, portfolio risk controls, and base strategy orchestration.
|
||||
- Existing analytics/risk/sizing/OMS foundations remain stable.
|
||||
|
||||
## Open Findings Driving Work
|
||||
- Runner leg behavior requires explicit validation evidence (`Qty=2` path confirmation).
|
||||
- Risk/config consistency checks need tightening in runtime safeguards.
|
||||
- Operational controls (CI automation, alerting, and out-of-sample validation) remain pending.
|
||||
|
||||
## Operational Reality
|
||||
- `dotnet build` success is necessary but not sufficient; NT8 NinjaScript compile remains a separate required validation step.
|
||||
- Deployment integrity requires keeping repo and NT8 runtime strategy copies synchronized.
|
||||
15
docs/00-governance/decisions.md
Normal file
15
docs/00-governance/decisions.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Architecture Decisions
|
||||
|
||||
Use this file to record durable project decisions that affect implementation patterns, interfaces, or workflow.
|
||||
|
||||
## Decision Template
|
||||
- ID: DEC-YYYYMMDD-XX
|
||||
- Date:
|
||||
- Status: proposed | accepted | superseded
|
||||
- Context:
|
||||
- Decision:
|
||||
- Consequences:
|
||||
- Related Files:
|
||||
|
||||
## Decision Log
|
||||
- No decisions recorded yet.
|
||||
20
docs/00-governance/executive_summary.md
Normal file
20
docs/00-governance/executive_summary.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# Executive Summary
|
||||
|
||||
## Scope
|
||||
- This folder (`docs/00-governance/`) is the canonical governance source for project state, priorities, architecture intent, and active execution guidance.
|
||||
- Governance is aligned to Sprint 2 (SIM validation) with production hardening gaps tracked and prioritized.
|
||||
|
||||
## Current Position (2026-04-05)
|
||||
- Core engine is implemented with 240+ passing tests across core components.
|
||||
- NT8 execution path is wired and validated in SIM for baseline operation.
|
||||
- Remaining work is focused on closing operational hardening gaps and validating runner behavior under production-like conditions.
|
||||
|
||||
## Approved Direction
|
||||
- Keep execution in managed-order NT8 patterns and C# 5.0 / .NET Framework 4.8 constraints.
|
||||
- Complete critical and high-priority hardening tasks before expanding strategy scope.
|
||||
- Treat historical handover artifacts as context only; governance decisions flow from this folder.
|
||||
|
||||
## Immediate Priorities
|
||||
- Confirm runner-leg dual-fill behavior in analyzer/session logs.
|
||||
- Close safety and observability items already identified in Sprint 2/3 gap tracking.
|
||||
- Maintain strict file-boundary and compile-guardrail discipline for all changes.
|
||||
36
docs/00-governance/patterns_and_antipatterns.md
Normal file
36
docs/00-governance/patterns_and_antipatterns.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Patterns and Anti-Patterns
|
||||
**Last Updated:** 2026-04-05
|
||||
|
||||
Capture recurring implementation patterns that impact compile stability.
|
||||
|
||||
## Pattern Entry Template
|
||||
- **Context:** where this applies
|
||||
- **Good pattern:** concise example/description
|
||||
- **Anti-pattern:** concise example/description
|
||||
- **Why it matters:** one sentence
|
||||
|
||||
## Starter Patterns
|
||||
1. **NT8 override signatures**
|
||||
- Good pattern: copy exact signature from official NT8 docs before coding.
|
||||
- Anti-pattern: infer or copy from outdated examples.
|
||||
- Why it matters: prevents `CS0115` and runtime integration drift.
|
||||
|
||||
2. **Access modifier on overrides**
|
||||
- Good pattern: use `protected override` for NT8 lifecycle/event methods.
|
||||
- Anti-pattern: `public override` or `private override`.
|
||||
- Why it matters: prevents `CS0507`.
|
||||
|
||||
3. **C# 5 compatibility discipline**
|
||||
- Good pattern: `string.Format`, explicit null checks, block-bodied members.
|
||||
- Anti-pattern: string interpolation, null-conditional, expression-bodied members.
|
||||
- Why it matters: prevents avoidable language-version compile failures.
|
||||
|
||||
4. **Managed order sequencing**
|
||||
- Good pattern: set stop/target before entry on the same bar.
|
||||
- Anti-pattern: entry first, then stop/target.
|
||||
- Why it matters: avoids silent behavior defects and rejected assumptions.
|
||||
|
||||
5. **Scope-first fixes**
|
||||
- Good pattern: smallest safe change in scoped files only.
|
||||
- Anti-pattern: broad cleanup or adjacent-file edits during bugfix.
|
||||
- Why it matters: reduces regression risk and review churn.
|
||||
21
docs/00-governance/roadmap.md
Normal file
21
docs/00-governance/roadmap.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Roadmap
|
||||
|
||||
## Sprint 2 (Active): SIM Validation
|
||||
- Validate dual-leg execution behavior with log evidence.
|
||||
- Complete remaining safety/consistency fixes tied to active gap list.
|
||||
- Exit criteria: stable SIM behavior with no unresolved critical gaps.
|
||||
|
||||
## Sprint 3: Production Hardening
|
||||
- Implement CI build/test automation and operational alerting.
|
||||
- Complete lower-priority runtime consistency and observability improvements.
|
||||
- Add walk-forward and broader validation coverage beyond in-sample checks.
|
||||
|
||||
## Sprint 4: Live Capital Readiness
|
||||
- Gate on sustained SIM metrics and drawdown controls.
|
||||
- Introduce go-live runbook and operational controls for controlled capital exposure.
|
||||
|
||||
## Sprint 5: ML Extension (Deferred)
|
||||
- Add inference integration only after sufficient live/sim data and stable production operations.
|
||||
|
||||
## Sequencing Rule
|
||||
- No feature expansion ahead of unresolved safety and validation gates.
|
||||
36
docs/02-runbooks/backtest_review_workflow.md
Normal file
36
docs/02-runbooks/backtest_review_workflow.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Backtest Review Workflow
|
||||
|
||||
## Purpose
|
||||
Provide a consistent pass/fail review process for strategy backtest output.
|
||||
|
||||
## Inputs
|
||||
- Backtest report (date range, instrument, timeframe, settings).
|
||||
- Strategy version/commit reference.
|
||||
- Risk and execution assumptions used for the run.
|
||||
|
||||
## Review Steps
|
||||
1. Confirm run metadata is complete and reproducible.
|
||||
2. Validate data window and session settings match test intent.
|
||||
3. Review shared metrics vocabulary:
|
||||
- Net Profit
|
||||
- Profit Factor
|
||||
- Max Drawdown
|
||||
- Win Rate
|
||||
- Average Trade
|
||||
- Expectancy
|
||||
- Trade Count
|
||||
4. Check risk behavior consistency (drawdown shape, loss clustering, streak behavior).
|
||||
5. Compare against prior baseline and flag material regressions.
|
||||
6. Record decision: `pass`, `pass_with_conditions`, or `fail`.
|
||||
|
||||
## Required Output
|
||||
- Backtest Review Note with:
|
||||
- metadata,
|
||||
- metrics snapshot,
|
||||
- baseline delta,
|
||||
- decision,
|
||||
- required follow-ups.
|
||||
|
||||
## Exit Criteria
|
||||
- Review note is stored with clear decision and rationale.
|
||||
- Any follow-up actions are captured as tasks.
|
||||
30
docs/02-runbooks/compile_error_triage_workflow.md
Normal file
30
docs/02-runbooks/compile_error_triage_workflow.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# Compile Error Triage Workflow
|
||||
|
||||
## Purpose
|
||||
Resolve compile errors quickly using smallest-safe changes and durable prevention notes.
|
||||
|
||||
## Inputs
|
||||
- Failing command output (`./verify-build.bat` or `dotnet test`).
|
||||
- File scope constraints for current task.
|
||||
|
||||
## Steps
|
||||
1. Reproduce with the same command to confirm current error set.
|
||||
2. Classify each error:
|
||||
- missing type/namespace,
|
||||
- bad override/signature,
|
||||
- wrong overload/argument,
|
||||
- C# 5.0 compatibility violation.
|
||||
3. Verify any NinjaScript/API signatures against NT8 docs before editing.
|
||||
4. Apply minimum-diff fix in scoped files only.
|
||||
5. Re-run `./verify-build.bat`.
|
||||
6. Run focused tests for the impacted area.
|
||||
7. If issue is non-trivial, add concise prevention notes to governance docs.
|
||||
|
||||
## Required Output
|
||||
- Error-to-fix mapping (error code, root cause, fix).
|
||||
- Verification evidence (build/test commands and results).
|
||||
|
||||
## Exit Criteria
|
||||
- Build passes.
|
||||
- Relevant tests pass.
|
||||
- Non-trivial learnings are captured.
|
||||
36
docs/02-runbooks/live_test_review_workflow.md
Normal file
36
docs/02-runbooks/live_test_review_workflow.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Live Test Review Workflow
|
||||
|
||||
## Purpose
|
||||
Review paper/live-forward test behavior using the same decision discipline as backtest review.
|
||||
|
||||
## Inputs
|
||||
- Live test window and environment details (paper/live, broker feed, session template).
|
||||
- Strategy version/commit reference.
|
||||
- Execution logs and order/rejection events.
|
||||
|
||||
## Review Steps
|
||||
1. Confirm environment and deployment metadata.
|
||||
2. Validate runtime stability (disconnects, errors, unexpected restarts).
|
||||
3. Review shared metrics vocabulary:
|
||||
- Net Profit
|
||||
- Profit Factor
|
||||
- Max Drawdown
|
||||
- Win Rate
|
||||
- Average Trade
|
||||
- Expectancy
|
||||
- Trade Count
|
||||
4. Inspect execution quality (slippage, missed fills, rejection frequency, latency anomalies).
|
||||
5. Compare live metrics to backtest expectations and tolerance bands.
|
||||
6. Record decision: `promote`, `extend_test`, or `hold`.
|
||||
|
||||
## Required Output
|
||||
- Live Test Review Note with:
|
||||
- environment details,
|
||||
- key metrics,
|
||||
- execution anomalies,
|
||||
- decision,
|
||||
- next actions.
|
||||
|
||||
## Exit Criteria
|
||||
- Review note is complete and decision is explicit.
|
||||
- Any blockers or promotion prerequisites are tracked as tasks.
|
||||
25
docs/02-runbooks/repo_cleanup_workflow.md
Normal file
25
docs/02-runbooks/repo_cleanup_workflow.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Repo Cleanup Workflow
|
||||
|
||||
## Purpose
|
||||
Keep repository documentation and task metadata clean without changing functional behavior.
|
||||
|
||||
## Inputs
|
||||
- Cleanup trigger (stale docs, duplicate guidance, archival need, naming drift).
|
||||
- Current governance priorities from `docs/00-governance/active_work.md`.
|
||||
|
||||
## Steps
|
||||
1. Confirm cleanup scope and impacted files.
|
||||
2. Ensure no production code changes are included.
|
||||
3. Remove stale or duplicate sections that are no longer authoritative.
|
||||
4. Consolidate references so canonical docs remain in `docs/00-governance/`.
|
||||
5. Log cleanup action and any remaining debt in `docs/00-governance/CLEANUP_LOG.md`.
|
||||
6. Verify links/paths and runbook references after edits.
|
||||
|
||||
## Required Output
|
||||
- List of files cleaned and reason for each.
|
||||
- Cleanup debt notes for deferred follow-ups.
|
||||
|
||||
## Exit Criteria
|
||||
- Cleanup scope is complete.
|
||||
- `CLEANUP_LOG.md` is updated.
|
||||
- No code files were modified.
|
||||
26
docs/02-runbooks/session_start_workflow.md
Normal file
26
docs/02-runbooks/session_start_workflow.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Session Start Workflow
|
||||
|
||||
## Purpose
|
||||
Start each implementation session with correct scope, context, and task state before editing files.
|
||||
|
||||
## Inputs
|
||||
- Current priority task from Archon.
|
||||
- Governance docs in `docs/00-governance/`.
|
||||
|
||||
## Steps
|
||||
1. Open and read in order:
|
||||
- `docs/00-governance/executive_summary.md`
|
||||
- `docs/00-governance/current_status.md`
|
||||
- `docs/00-governance/active_work.md`
|
||||
- `docs/00-governance/architecture.md`
|
||||
- `docs/00-governance/roadmap.md`
|
||||
2. Pull current task details from Archon and confirm acceptance criteria.
|
||||
3. Confirm allowed file scope from task spec and `.kilocode/rules/file_boundaries.md`.
|
||||
4. Move task status in Archon from `todo` to `doing`.
|
||||
5. Capture a short execution plan (3-6 bullets) tied to acceptance criteria.
|
||||
6. Begin implementation with minimum-diff edits only in scoped files.
|
||||
|
||||
## Exit Criteria
|
||||
- Task is set to `doing`.
|
||||
- Scope boundaries are explicitly confirmed.
|
||||
- Work plan exists and maps to task acceptance criteria.
|
||||
49
docs/02-runbooks/spec_to_build_workflow.md
Normal file
49
docs/02-runbooks/spec_to_build_workflow.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Spec-to-Build Workflow
|
||||
|
||||
## Purpose
|
||||
Convert an approved spec into implementation-ready work with explicit tool handoffs and verifiable artifacts.
|
||||
|
||||
## Roles
|
||||
- Planner: decomposes spec into implementable tasks.
|
||||
- Implementer: edits code within scope.
|
||||
- Verifier: runs required build and tests.
|
||||
|
||||
## Tool Handoffs and Artifact Passing
|
||||
1. **Spec Intake (Planner)**
|
||||
- Tool: Archon task/project view.
|
||||
- Input artifact: approved spec text.
|
||||
- Output artifact: `Task Brief` containing objective, scope, constraints, acceptance criteria.
|
||||
2. **Task Breakdown (Planner)**
|
||||
- Tool: Archon task board.
|
||||
- Input artifact: `Task Brief`.
|
||||
- Output artifact: ordered subtasks with file scope and done criteria.
|
||||
3. **Implementation (Implementer)**
|
||||
- Tool: repository editor + scoped files.
|
||||
- Input artifact: ordered subtasks.
|
||||
- Output artifact: minimal code/doc diffs limited to allowed files.
|
||||
4. **Build Verification (Verifier)**
|
||||
- Tool: `./verify-build.bat`.
|
||||
- Input artifact: working tree changes.
|
||||
- Output artifact: pass/fail result with error details if failed.
|
||||
5. **Focused Tests (Verifier)**
|
||||
- Tool: `dotnet test` with area filter.
|
||||
- Input artifact: verified build output.
|
||||
- Output artifact: test evidence (command + pass/fail + failing test IDs).
|
||||
6. **Task State Update (Planner/Implementer)**
|
||||
- Tool: Archon task board.
|
||||
- Input artifact: verification evidence.
|
||||
- Output artifact: task moved `doing` -> `review` with implementation notes and evidence links.
|
||||
|
||||
## Required Artifact Bundle for Review
|
||||
- `Task Brief` (objective/scope/constraints/acceptance criteria).
|
||||
- Subtask list with scoped files.
|
||||
- Diff summary (files changed + why).
|
||||
- Verification evidence:
|
||||
- `./verify-build.bat` result.
|
||||
- Relevant `dotnet test` result.
|
||||
- Known limitations or follow-up items.
|
||||
|
||||
## Exit Criteria
|
||||
- Acceptance criteria are satisfied.
|
||||
- Evidence bundle is complete.
|
||||
- Task status is `review`.
|
||||
@@ -1,3 +1,10 @@
|
||||
> ⚠️ HISTORICAL — see docs/00-governance/ for current state
|
||||
|
||||
This file may contain outdated or mixed historical information.
|
||||
Canonical current-state documentation lives in docs/00-governance/.
|
||||
This file is retained for history/reference only.
|
||||
Navigation links in this file may be stale or broken.
|
||||
|
||||
# NT8 SDK - Documentation Index
|
||||
|
||||
**Complete documentation for the NT8 Institutional Trading SDK**
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
> ⚠️ HISTORICAL — see docs/00-governance/ for current state
|
||||
|
||||
This file may contain outdated or mixed historical information.
|
||||
Canonical current-state documentation lives in docs/00-governance/.
|
||||
This file is retained for history/reference only.
|
||||
|
||||
# NT8 Institutional Trading SDK
|
||||
|
||||
**Version:** 0.2.0
|
||||
|
||||
@@ -1,7 +1,99 @@
|
||||
# NT8 Institutional SDK - Phase 1 Sprint Plan
|
||||
# NT8-SDK — Sprint Board
|
||||
**Last Updated:** 2026-03-27 | **Active Sprint:** Sprint 2
|
||||
|
||||
## Overview
|
||||
This document outlines the sprint plan for Phase 1 development of the NT8 Institutional SDK. Phase 1 builds upon the completed Phase 0 foundation to deliver a more complete trading system with Order Management System (OMS), NinjaTrader 8 integration, enhanced risk controls, and market data handling.
|
||||
---
|
||||
|
||||
## Sprint 2 — SIM Validation (ACTIVE)
|
||||
**Goal:** Strategy runs unattended 2+ weeks in SIM with correct dual-leg execution.
|
||||
**Gate:** Zero unhandled exceptions, both scaler and runner filling (Qty=2 in log), daily loss limit never accidentally triggered.
|
||||
|
||||
| # | Task | Status | Notes |
|
||||
|---|---|---|---|
|
||||
| S2-01 | Restore `EntriesPerDirection=2` | ✅ Done | Deployed 2026-03-27 |
|
||||
| S2-02 | `MaxOpenPositions=2` in SimpleORBNT8 | ✅ Done | Deployed 2026-03-27 |
|
||||
| S2-03 | `_realtimeBarSeen` replay guard | ✅ Done | Blocks live replay burst, allows backtest |
|
||||
| S2-04 | `State.Historical` guard in ProcessStrategyIntent | ✅ Done | Restores backtest execution |
|
||||
| S2-05 | Validate runner leg — Qty=2 in session log | ⬜ Pending | Run backtest after S2-01 |
|
||||
| S2-06 | Risk parameter consistency validation | ⬜ Pending | Assert RiskPerTrade ≤ MaxTradeRisk |
|
||||
| S2-07 | SIM unattended run 2+ weeks | ▶ In progress | Started 2026-03-27 |
|
||||
| S2-08 | Walk-forward backtest split | ⬜ Pending | Mar–Sep 2025 train / Oct–Mar 2026 test |
|
||||
| S2-09 | BX68915-15 prop firm re-enable | 🔴 Blocked | Gate: S2-05 + S2-07 pass |
|
||||
|
||||
---
|
||||
|
||||
## Sprint 3 — Production Hardening
|
||||
**Goal:** 30-day SIM run clean. CI and alerts live.
|
||||
|
||||
| # | Task | Status | Notes |
|
||||
|---|---|---|---|
|
||||
| S3-01 | Gitea CI — build + test on push | ⬜ Pending | `.gitea/workflows/build.yml` |
|
||||
| S3-02 | n8n webhook — fills + risk events | ⬜ Pending | HTTP POST from NT8StrategyBase |
|
||||
| S3-03 | Fix `GetRiskStatus()` hardcoded limit | ⬜ Pending | Read from registered strategy config |
|
||||
| S3-04 | `orbRangeTicks` wiring in DailyBarContext | ⬜ Pending | Low priority |
|
||||
| S3-05 | Short-side regime filter | ⬜ Pending | 20-day MA or VIX-based gate |
|
||||
| S3-06 | Tick replay validation | ⬜ Pending | 30-day window |
|
||||
| S3-07 | VWAPMeanReversion strategy skeleton | ⬜ Pending | New IStrategy implementation |
|
||||
|
||||
---
|
||||
|
||||
## Sprint 4 — Live Capital
|
||||
**Gate:** 30-day SIM pass rate > 70%, PF > 2.0, max drawdown < $500
|
||||
|
||||
| # | Task | Status |
|
||||
|---|---|---|
|
||||
| S4-01 | Go live 1 NQ contract | ⬜ Pending gate |
|
||||
| S4-02 | OvernightGapContinuation strategy | ⬜ Pending |
|
||||
| S4-03 | OvernightGapReversion strategy | ⬜ Pending |
|
||||
| S4-04 | Ops runbook and emergency procedures | ⬜ Pending |
|
||||
| S4-05 | Connection loss recovery testing | ⬜ Pending |
|
||||
| S4-06 | CME holiday filter | ⬜ Pending |
|
||||
|
||||
---
|
||||
|
||||
## Sprint 5 — ML Inference
|
||||
**Prerequisite:** 60 days of live trading data.
|
||||
|
||||
| # | Task |
|
||||
|---|---|
|
||||
| S5-01 | FastAPI /predict endpoint on Ollama workstation |
|
||||
| S5-02 | HTTP client in SimpleORBStrategy |
|
||||
| S5-03 | MLSignalFactorCalculator as IFactorCalculator |
|
||||
| S5-04 | Feature engineering from live trade history |
|
||||
| S5-05 | A/B test: with vs without ML factor |
|
||||
|
||||
---
|
||||
|
||||
## Completed (Historical)
|
||||
|
||||
| Task | Sprint | Completed |
|
||||
|---|---|---|
|
||||
| Execute trades in NT8 SIM (execution bridge wired) | Sprint 1 | 2026-03-27 |
|
||||
| Historical replay burst fix | Sprint 1 | 2026-03-27 |
|
||||
| NR7 warm-up guard | Phase 4 | 2026-02 |
|
||||
| 10-factor confluence scoring engine | Phase 4 | 2026-02 |
|
||||
| PortfolioRiskManager singleton | Phase 4 | 2026-02 |
|
||||
| Analytics layer (240+ tests) | Phase 5 | 2026-02-16 |
|
||||
| Breakeven + runner trail logic | Sprint 1 | 2026-03 |
|
||||
| Connection loss detection | Sprint 1 | 2026-03 |
|
||||
| File logging + settings export | Sprint 1 | 2026-03 |
|
||||
|
||||
---
|
||||
|
||||
## Backtest Results History
|
||||
|
||||
| Date | Period | Trades | Win% | PF | Net | Config |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 2026-03-27 | Jan–Mar 2026 | 20 | 75% | 7.00 | $1,200 | trail=20, grade=B ✅ Use this |
|
||||
| 2026-03-27 | Jan–Mar 2026 | 40 | 75% | 3.69 | $1,075 | trail=12, grade=B |
|
||||
| 2026-03-27 | Mar 2025–Mar 2026 | 148 | 51% | 3.15 | $71,303 | 9 cts experimental |
|
||||
|
||||
**Note:** The 148-trade run used `RiskPerTrade=$500` producing 9 contracts AND had `EntriesPerDirection=1` blocking the runner. Not a production reference. Re-run required post Sprint 2.
|
||||
|
||||
---
|
||||
# ARCHIVED BELOW — Phase 1 Sprint Plan (2025-09-15, superseded)
|
||||
|
||||
## Overview (ARCHIVED)
|
||||
This document originally outlined Phase 1 sprint planning from September 2025.
|
||||
|
||||
## Sprint Goals
|
||||
1. Implement Order Management System (OMS) with smart order routing
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
> ⚠️ HISTORICAL — see docs/00-governance/ for current state
|
||||
|
||||
This file may contain outdated or mixed historical information.
|
||||
Canonical current-state documentation lives in docs/00-governance/.
|
||||
This file is retained for history/reference only.
|
||||
|
||||
# Phase 2 Completion Report
|
||||
|
||||
**Project:** NT8 Institutional Trading SDK
|
||||
@@ -54,6 +54,11 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
private DateTime _lastBarTime;
|
||||
private bool _killSwitchTriggered;
|
||||
private bool _connectionLost;
|
||||
private bool _realtimeBarSeen;
|
||||
private bool _breakevenMoved;
|
||||
private string _scalerSignalName;
|
||||
private string _runnerSignalName;
|
||||
private bool _runnerActive;
|
||||
private ExecutionCircuitBreaker _circuitBreaker;
|
||||
private System.IO.StreamWriter _fileLog;
|
||||
private readonly object _fileLock = new object();
|
||||
@@ -117,6 +122,29 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
[Display(Name = "Enable Short Trades", GroupName = "Trade Direction", Order = 2)]
|
||||
public bool EnableShortTrades { get; set; }
|
||||
|
||||
[NinjaScriptProperty]
|
||||
[Display(Name = "Enable Auto Breakeven", GroupName = "Exit Management", Order = 1)]
|
||||
public bool EnableAutoBreakeven { get; set; }
|
||||
|
||||
[NinjaScriptProperty]
|
||||
[Display(Name = "Breakeven Trigger Ticks", GroupName = "Exit Management", Order = 2)]
|
||||
[Range(1, 100)]
|
||||
public int BreakevenTriggerTicks { get; set; }
|
||||
|
||||
[NinjaScriptProperty]
|
||||
[Display(Name = "Breakeven Offset Ticks", GroupName = "Exit Management", Order = 3)]
|
||||
[Range(0, 20)]
|
||||
public int BreakevenOffsetTicks { get; set; }
|
||||
|
||||
[NinjaScriptProperty]
|
||||
[Display(Name = "Enable Runner", GroupName = "Exit Management", Order = 4)]
|
||||
public bool EnableRunner { get; set; }
|
||||
|
||||
[NinjaScriptProperty]
|
||||
[Display(Name = "Runner Trail Ticks", GroupName = "Exit Management", Order = 5)]
|
||||
[Range(4, 100)]
|
||||
public int RunnerTrailTicks { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
// INT8ExecutionBridge implementation
|
||||
@@ -154,6 +182,16 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
ExitShort("EmergencyFlatten");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the concrete strategy has ForceSessionReset enabled.
|
||||
/// Override in subclass to expose the NinjaScript parameter value.
|
||||
/// Default returns false so base class never forces a reset unless overridden.
|
||||
/// </summary>
|
||||
protected virtual bool GetForceSessionReset()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the SDK strategy instance.
|
||||
/// </summary>
|
||||
@@ -171,7 +209,7 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
Description = "SDK-integrated strategy base";
|
||||
// Name intentionally not set - this is an abstract base class
|
||||
Calculate = Calculate.OnBarClose;
|
||||
EntriesPerDirection = 1;
|
||||
EntriesPerDirection = 2;
|
||||
EntryHandling = EntryHandling.AllEntries;
|
||||
IsExitOnSessionCloseStrategy = true;
|
||||
ExitOnSessionCloseSeconds = 30;
|
||||
@@ -179,12 +217,12 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix;
|
||||
OrderFillResolution = OrderFillResolution.Standard;
|
||||
Slippage = 0;
|
||||
StartBehavior = StartBehavior.WaitUntilFlat;
|
||||
StartBehavior = StartBehavior.AdoptAccountPosition;
|
||||
TimeInForce = TimeInForce.Gtc;
|
||||
TraceOrders = false;
|
||||
RealtimeErrorHandling = RealtimeErrorHandling.StopCancelClose;
|
||||
StopTargetHandling = StopTargetHandling.PerEntryExecution;
|
||||
BarsRequiredToTrade = 50;
|
||||
BarsRequiredToTrade = 1;
|
||||
|
||||
EnableSDK = true;
|
||||
DailyLossLimit = 1000.0;
|
||||
@@ -192,7 +230,7 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
MaxOpenPositions = 3;
|
||||
RiskPerTrade = 100.0;
|
||||
MinContracts = 1;
|
||||
MaxContracts = 10;
|
||||
MaxContracts = 3;
|
||||
EnableKillSwitch = false;
|
||||
EnableVerboseLogging = false;
|
||||
MinTradeGrade = 4;
|
||||
@@ -200,6 +238,11 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
LogDirectory = string.Empty;
|
||||
EnableLongTrades = true;
|
||||
EnableShortTrades = true;
|
||||
EnableAutoBreakeven = true;
|
||||
BreakevenTriggerTicks = 20;
|
||||
BreakevenOffsetTicks = 1;
|
||||
EnableRunner = true;
|
||||
RunnerTrailTicks = 20;
|
||||
_killSwitchTriggered = false;
|
||||
_connectionLost = false;
|
||||
}
|
||||
@@ -209,6 +252,14 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
{
|
||||
try
|
||||
{
|
||||
// DIAGNOSTIC: Print actual runtime property values to confirm
|
||||
// what NT8 loaded vs what SetDefaults specified.
|
||||
Print(string.Format("[SDK-DIAG] SetDefaults check: BE={0} Trail={1} MaxC={2} SB={3} EPD={4}",
|
||||
BreakevenTriggerTicks,
|
||||
RunnerTrailTicks,
|
||||
MaxContracts,
|
||||
StartBehavior,
|
||||
EntriesPerDirection));
|
||||
InitFileLog();
|
||||
InitializeSdkComponents();
|
||||
_sdkInitialized = true;
|
||||
@@ -226,6 +277,19 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
}
|
||||
else if (State == State.Realtime)
|
||||
{
|
||||
_realtimeBarSeen = false;
|
||||
|
||||
// If ForceSessionReset is enabled, push a reset signal into the SDK strategy
|
||||
// so _tradeTaken is cleared before any live bar is processed.
|
||||
// This recovers from replay-burst scenarios where historical bars set _tradeTaken.
|
||||
if (_sdkStrategy != null && GetForceSessionReset())
|
||||
{
|
||||
var resetParams = new Dictionary<string, object>();
|
||||
resetParams.Add("force_session_reset", true);
|
||||
_sdkStrategy.SetParameters(resetParams);
|
||||
Print(string.Format("[SDK] ForceSessionReset: _tradeTaken cleared on live start at {0}", DateTime.Now.ToString("HH:mm:ss")));
|
||||
}
|
||||
|
||||
WriteSettingsFile();
|
||||
}
|
||||
else if (State == State.Terminated)
|
||||
@@ -243,6 +307,22 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
if (BarsInProgress != 0)
|
||||
return;
|
||||
|
||||
// Require 7 completed daily bars before allowing any signal.
|
||||
// NarrowRangeFactorCalculator needs 7 daily bars for NR7 scoring.
|
||||
// Without this guard, NR7 silently returns its floor score (0.3)
|
||||
// which may suppress trades via the MinTradeGrade confluence gate.
|
||||
if (BarsArray != null && BarsArray.Length > 1
|
||||
&& CurrentBars != null && CurrentBars.Length > 1
|
||||
&& CurrentBars[1] < 7)
|
||||
{
|
||||
// Always print warm-up status — visible in Strategy Analyzer output
|
||||
// to confirm how many daily bars are available on a given backtest range.
|
||||
if (CurrentBar % 20 == 0)
|
||||
Print(String.Format("[SDK] Daily warm-up: {0}/7 bars — waiting for NR7 history. Extend backtest start date or add pre-load days.",
|
||||
CurrentBars[1] + 1));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_sdkInitialized || _sdkStrategy == null)
|
||||
{
|
||||
return;
|
||||
@@ -256,8 +336,25 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
if (Time[0] == _lastBarTime)
|
||||
return;
|
||||
|
||||
if (Time[0].Date != _lastBarTime.Date && _lastBarTime != DateTime.MinValue)
|
||||
{
|
||||
_runnerActive = false;
|
||||
_breakevenMoved = false;
|
||||
_scalerSignalName = null;
|
||||
_runnerSignalName = null;
|
||||
}
|
||||
|
||||
_lastBarTime = Time[0];
|
||||
|
||||
// Mark first bar seen after going realtime. Until this fires, we're
|
||||
// processing catch-up replay bars and must not submit orders.
|
||||
if (State == State.Realtime && !_realtimeBarSeen)
|
||||
{
|
||||
_realtimeBarSeen = true;
|
||||
Print(string.Format("[SDK] First realtime bar seen: {0}", Time[0]));
|
||||
return;
|
||||
}
|
||||
|
||||
// Sync actual open position to portfolio manager on every bar
|
||||
PortfolioRiskManager.Instance.UpdateOpenContracts(Name, Math.Abs(Position.Quantity));
|
||||
|
||||
@@ -329,6 +426,50 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
Close[0]));
|
||||
}
|
||||
|
||||
// --- Breakeven and runner trailing monitor ---
|
||||
if (_runnerActive && !string.IsNullOrEmpty(_runnerSignalName) && Position.Quantity != 0)
|
||||
{
|
||||
double entryPrice = Position.AveragePrice;
|
||||
double currentClose = Close[0];
|
||||
bool isLong = Position.MarketPosition == MarketPosition.Long;
|
||||
|
||||
double profitTicks = isLong
|
||||
? (currentClose - entryPrice) / TickSize
|
||||
: (entryPrice - currentClose) / TickSize;
|
||||
|
||||
// Move runner stop to breakeven + offset once trigger is reached
|
||||
if (EnableAutoBreakeven && !_breakevenMoved && profitTicks >= BreakevenTriggerTicks)
|
||||
{
|
||||
double bePrice = isLong
|
||||
? entryPrice + (BreakevenOffsetTicks * TickSize)
|
||||
: entryPrice - (BreakevenOffsetTicks * TickSize);
|
||||
|
||||
SetStopLoss(_runnerSignalName, CalculationMode.Price, bePrice, false);
|
||||
_breakevenMoved = true;
|
||||
|
||||
Print(String.Format("[SDK] Runner breakeven set at {0:F2} (profit={1:F0} ticks)",
|
||||
bePrice, profitTicks));
|
||||
if (EnableFileLogging)
|
||||
FileLog(String.Format("BREAKEVEN runner stop -> {0:F2} profit={1:F0}ticks",
|
||||
bePrice, profitTicks));
|
||||
}
|
||||
|
||||
// Activate trailing stop on runner once breakeven is secured
|
||||
if (_breakevenMoved && RunnerTrailTicks > 0)
|
||||
{
|
||||
SetTrailStop(_runnerSignalName, CalculationMode.Ticks, RunnerTrailTicks, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear runner state when flat
|
||||
if (Position.Quantity == 0 && _runnerActive)
|
||||
{
|
||||
_runnerActive = false;
|
||||
_breakevenMoved = false;
|
||||
if (EnableFileLogging && !string.IsNullOrEmpty(_runnerSignalName))
|
||||
FileLog("RUNNER closed — position flat");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var barData = ConvertCurrentBar();
|
||||
@@ -427,7 +568,7 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
}
|
||||
|
||||
protected override void OnPositionUpdate(
|
||||
Position position,
|
||||
NinjaTrader.Cbi.Position position,
|
||||
double averagePrice,
|
||||
int quantity,
|
||||
MarketPosition marketPosition)
|
||||
@@ -442,7 +583,7 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
{
|
||||
try
|
||||
{
|
||||
dayPnL = Account.Get(AccountItem.GainLoss, Currency.UsDollar);
|
||||
dayPnL = Account.Get(AccountItem.RealizedProfitLoss, Currency.UsDollar);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -637,9 +778,24 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
|
||||
private BarData ConvertCurrentBar()
|
||||
{
|
||||
DateTime barTimeEt;
|
||||
try
|
||||
{
|
||||
var centralZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
|
||||
var easternZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
|
||||
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(
|
||||
DateTime.SpecifyKind(Time[0], DateTimeKind.Unspecified),
|
||||
centralZone);
|
||||
barTimeEt = TimeZoneInfo.ConvertTimeFromUtc(utcTime, easternZone);
|
||||
}
|
||||
catch
|
||||
{
|
||||
barTimeEt = Time[0];
|
||||
}
|
||||
|
||||
return NT8DataConverter.ConvertBar(
|
||||
Instrument.MasterInstrument.Name,
|
||||
Time[0],
|
||||
barTimeEt,
|
||||
Open[0],
|
||||
High[0],
|
||||
Low[0],
|
||||
@@ -761,6 +917,11 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
|
||||
private void ProcessStrategyIntent(StrategyIntent intent, StrategyContext context)
|
||||
{
|
||||
// In live/SIM: block if we haven't seen a genuine realtime bar yet (replay guard).
|
||||
// In Strategy Analyzer (State.Historical): always allow — backtest must execute normally.
|
||||
if (State == State.Realtime && !_realtimeBarSeen)
|
||||
return;
|
||||
|
||||
// Portfolio-level risk check — runs before per-strategy risk validation
|
||||
var portfolioDecision = PortfolioRiskManager.Instance.ValidatePortfolioRisk(Name, intent);
|
||||
if (!portfolioDecision.Allow)
|
||||
@@ -840,30 +1001,36 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
|
||||
private void SubmitOrderToNT8(OmsOrderRequest request, StrategyIntent intent)
|
||||
{
|
||||
// Circuit breaker gate
|
||||
if (State == State.Historical)
|
||||
if (State != State.Historical)
|
||||
{
|
||||
// Skip circuit breaker during backtest — wall-clock timeout is meaningless on historical data.
|
||||
}
|
||||
else if (_circuitBreaker != null && !_circuitBreaker.ShouldAllowOrder())
|
||||
{
|
||||
var state = _circuitBreaker.GetState();
|
||||
Print(string.Format("[SDK] Circuit breaker OPEN — order blocked: {0}", state.Reason));
|
||||
if (_logger != null)
|
||||
_logger.LogWarning("Circuit breaker blocked order: {0}", state.Reason);
|
||||
return;
|
||||
if (_circuitBreaker != null && !_circuitBreaker.ShouldAllowOrder())
|
||||
{
|
||||
var cbState = _circuitBreaker.GetState();
|
||||
Print(String.Format("[SDK] Circuit breaker OPEN — order blocked: {0}", cbState.Reason));
|
||||
if (_logger != null)
|
||||
_logger.LogWarning("Circuit breaker blocked order: {0}", cbState.Reason);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var orderName = string.Format("SDK_{0}_{1}", intent.Symbol, Guid.NewGuid().ToString("N").Substring(0, 12));
|
||||
bool useRunner = EnableRunner && request.Quantity >= 2;
|
||||
|
||||
int scalerQty = useRunner ? request.Quantity - 1 : request.Quantity;
|
||||
int runnerQty = useRunner ? 1 : 0;
|
||||
|
||||
string baseId = Guid.NewGuid().ToString("N").Substring(0, 12);
|
||||
_scalerSignalName = String.Format("SDK_{0}_S_{1}", intent.Symbol, baseId);
|
||||
_runnerSignalName = useRunner ? String.Format("SDK_{0}_R_{1}", intent.Symbol, baseId) : null;
|
||||
_breakevenMoved = false;
|
||||
_runnerActive = useRunner;
|
||||
|
||||
if (EnableFileLogging)
|
||||
{
|
||||
string grade = "N/A";
|
||||
string score = "N/A";
|
||||
string factors = string.Empty;
|
||||
|
||||
if (intent.Metadata != null && intent.Metadata.ContainsKey("confluence_score"))
|
||||
{
|
||||
var cs = intent.Metadata["confluence_score"] as NT8.Core.Intelligence.ConfluenceScore;
|
||||
@@ -871,55 +1038,46 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
{
|
||||
grade = cs.Grade.ToString();
|
||||
score = cs.WeightedScore.ToString("F3");
|
||||
|
||||
var sb = new System.Text.StringBuilder();
|
||||
foreach (var f in cs.Factors)
|
||||
sb.Append(string.Format("{0}={1:F2} ", f.Type, f.Score));
|
||||
sb.Append(String.Format("{0}={1:F2} ", f.Type, f.Score));
|
||||
factors = sb.ToString().TrimEnd();
|
||||
}
|
||||
}
|
||||
|
||||
FileLog(string.Format("SIGNAL {0} | Grade={1} | Score={2}", intent.Side, grade, score));
|
||||
FileLog(String.Format("SIGNAL {0} | Grade={1} | Score={2}", intent.Side, grade, score));
|
||||
if (!string.IsNullOrEmpty(factors))
|
||||
FileLog(string.Format(" Factors: {0}", factors));
|
||||
FileLog(string.Format("SUBMIT {0} {1} @ Market | Stop={2} Target={3}{4}",
|
||||
intent.Side,
|
||||
request.Quantity,
|
||||
intent.StopTicks,
|
||||
intent.TargetTicks,
|
||||
intent.Metadata != null && intent.Metadata.ContainsKey("dynamic_target_ticks") ? " [dynamic]" : ""));
|
||||
FileLog(String.Format(" Factors: {0}", factors));
|
||||
FileLog(String.Format("SUBMIT Scaler={0} Runner={1} Stop={2} Target={3}",
|
||||
scalerQty, runnerQty, intent.StopTicks,
|
||||
intent.TargetTicks.HasValue ? intent.TargetTicks.Value.ToString() : "none"));
|
||||
}
|
||||
|
||||
_executionAdapter.SubmitOrder(request, orderName);
|
||||
|
||||
// Register stop and target BEFORE submitting the entry order.
|
||||
// NT8 requires stop/target to be pre-registered to the signal name
|
||||
// so they are applied correctly in both backtest and live/SIM modes.
|
||||
// --- Submit scaler leg ---
|
||||
if (intent.StopTicks > 0)
|
||||
SetStopLoss(orderName, CalculationMode.Ticks, (int)intent.StopTicks, false);
|
||||
|
||||
SetStopLoss(_scalerSignalName, CalculationMode.Ticks, (int)intent.StopTicks, false);
|
||||
if (intent.TargetTicks.HasValue && intent.TargetTicks.Value > 0)
|
||||
SetProfitTarget(orderName, CalculationMode.Ticks, (int)intent.TargetTicks.Value);
|
||||
SetProfitTarget(_scalerSignalName, CalculationMode.Ticks, (int)intent.TargetTicks.Value);
|
||||
|
||||
if (request.Side == OmsOrderSide.Buy)
|
||||
EnterLong(scalerQty, _scalerSignalName);
|
||||
else
|
||||
EnterShort(scalerQty, _scalerSignalName);
|
||||
|
||||
// --- Submit runner leg (no fixed target — exits via trailing stop) ---
|
||||
if (useRunner)
|
||||
{
|
||||
if (request.Type == OmsOrderType.Market)
|
||||
EnterLong(request.Quantity, orderName);
|
||||
else if (request.Type == OmsOrderType.Limit && request.LimitPrice.HasValue)
|
||||
EnterLongLimit(request.Quantity, (double)request.LimitPrice.Value, orderName);
|
||||
else if (request.Type == OmsOrderType.StopMarket && request.StopPrice.HasValue)
|
||||
EnterLongStopMarket(request.Quantity, (double)request.StopPrice.Value, orderName);
|
||||
}
|
||||
else if (request.Side == OmsOrderSide.Sell)
|
||||
{
|
||||
if (request.Type == OmsOrderType.Market)
|
||||
EnterShort(request.Quantity, orderName);
|
||||
else if (request.Type == OmsOrderType.Limit && request.LimitPrice.HasValue)
|
||||
EnterShortLimit(request.Quantity, (double)request.LimitPrice.Value, orderName);
|
||||
else if (request.Type == OmsOrderType.StopMarket && request.StopPrice.HasValue)
|
||||
EnterShortStopMarket(request.Quantity, (double)request.StopPrice.Value, orderName);
|
||||
if (intent.StopTicks > 0)
|
||||
SetStopLoss(_runnerSignalName, CalculationMode.Ticks, (int)intent.StopTicks, false);
|
||||
// No SetProfitTarget on runner — trail stop will manage exit
|
||||
|
||||
if (request.Side == OmsOrderSide.Buy)
|
||||
EnterLong(runnerQty, _runnerSignalName);
|
||||
else
|
||||
EnterShort(runnerQty, _runnerSignalName);
|
||||
}
|
||||
|
||||
_executionAdapter.SubmitOrder(request, _scalerSignalName);
|
||||
|
||||
if (_circuitBreaker != null)
|
||||
_circuitBreaker.OnSuccess();
|
||||
}
|
||||
@@ -927,8 +1085,7 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
{
|
||||
if (_circuitBreaker != null)
|
||||
_circuitBreaker.OnFailure();
|
||||
|
||||
Print(string.Format("[SDK] SubmitOrderToNT8 failed: {0}", ex.Message));
|
||||
Print(String.Format("[SDK] SubmitOrderToNT8 failed: {0}", ex.Message));
|
||||
if (_logger != null)
|
||||
_logger.LogError("SubmitOrderToNT8 failed: {0}", ex.Message);
|
||||
throw;
|
||||
|
||||
@@ -23,6 +23,8 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
/// </summary>
|
||||
public class SimpleORBNT8 : NT8StrategyBase
|
||||
{
|
||||
private int _lastSignalDirection;
|
||||
|
||||
[NinjaScriptProperty]
|
||||
[Display(Name = "Opening Range Minutes", GroupName = "ORB Strategy", Order = 1)]
|
||||
[Range(5, 120)]
|
||||
@@ -38,6 +40,10 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
[Range(1, 50)]
|
||||
public int StopTicks { get; set; }
|
||||
|
||||
[NinjaScriptProperty]
|
||||
[Display(Name = "Force Session Reset On Start", GroupName = "ORB Strategy", Order = 10)]
|
||||
public bool ForceSessionReset { get; set; }
|
||||
|
||||
[NinjaScriptProperty]
|
||||
[Display(Name = "Profit Target Ticks", GroupName = "ORB Risk", Order = 2)]
|
||||
[Range(1, 100)]
|
||||
@@ -59,16 +65,24 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
|
||||
DailyLossLimit = 1000.0;
|
||||
MaxTradeRisk = 200.0;
|
||||
MaxOpenPositions = 1;
|
||||
MaxOpenPositions = 2;
|
||||
RiskPerTrade = 100.0;
|
||||
MinContracts = 1;
|
||||
MaxContracts = 3;
|
||||
|
||||
Calculate = Calculate.OnBarClose;
|
||||
BarsRequiredToTrade = 50;
|
||||
MinTradeGrade = 5;
|
||||
EnableLongTrades = true;
|
||||
// Long-only: short trades permanently disabled pending backtest confirmation
|
||||
EnableShortTrades = false;
|
||||
EnableAutoBreakeven = true;
|
||||
BreakevenTriggerTicks = 20;
|
||||
BreakevenOffsetTicks = 1;
|
||||
EnableRunner = true;
|
||||
RunnerTrailTicks = 20;
|
||||
ForceSessionReset = false;
|
||||
StartBehavior = StartBehavior.AdoptAccountPosition;
|
||||
}
|
||||
else if (State == State.Configure)
|
||||
{
|
||||
@@ -82,11 +96,24 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
{
|
||||
if (_strategyConfig != null && BarsArray != null && BarsArray.Length > 1)
|
||||
{
|
||||
DailyBarContext dailyContext = BuildDailyBarContext(0, 0.0, (double)Volume[0]);
|
||||
DailyBarContext dailyContext = BuildDailyBarContext(_lastSignalDirection, 0.0, (double)Volume[0]);
|
||||
_strategyConfig.Parameters["daily_bars"] = dailyContext;
|
||||
}
|
||||
|
||||
base.OnBarUpdate();
|
||||
|
||||
if (Position != null)
|
||||
{
|
||||
if (Position.MarketPosition == MarketPosition.Long)
|
||||
_lastSignalDirection = 1;
|
||||
else if (Position.MarketPosition == MarketPosition.Short)
|
||||
_lastSignalDirection = -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool GetForceSessionReset()
|
||||
{
|
||||
return ForceSessionReset;
|
||||
}
|
||||
|
||||
protected override IStrategy CreateSdkStrategy()
|
||||
@@ -160,6 +187,10 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
lines.Insert(endIdx + 6, string.Format("StopDollars : {0:C}", StopTicks * tickDollarValue));
|
||||
lines.Insert(endIdx + 7, string.Format("TargetDollars : {0:C}", TargetTicks * tickDollarValue));
|
||||
lines.Insert(endIdx + 8, string.Format("RR_Ratio : {0:F2}:1", (double)TargetTicks / StopTicks));
|
||||
lines.Insert(endIdx + 9, String.Format("AutoBreakeven : {0} @ {1}ticks + {2}tick offset",
|
||||
EnableAutoBreakeven, BreakevenTriggerTicks, BreakevenOffsetTicks));
|
||||
lines.Insert(endIdx + 10, String.Format("Runner : {0} | Trail={1}ticks",
|
||||
EnableRunner, RunnerTrailTicks));
|
||||
|
||||
return lines;
|
||||
}
|
||||
@@ -225,4 +256,3 @@ namespace NinjaTrader.NinjaScript.Strategies
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -203,7 +203,15 @@ namespace NT8.Strategies.Examples
|
||||
}
|
||||
|
||||
if (_tradeTaken)
|
||||
{
|
||||
if (_logger != null)
|
||||
_logger.LogDebug(
|
||||
"SimpleORBStrategy skip: trade already taken for session {0:yyyy-MM-dd}; bar={1:yyyy-MM-dd HH:mm}; symbol={2}",
|
||||
_currentSessionDate,
|
||||
bar.Time,
|
||||
context.Symbol);
|
||||
return null;
|
||||
}
|
||||
|
||||
var openingRange = _openingRangeHigh - _openingRangeLow;
|
||||
var volatilityBuffer = openingRange * (_stdDevMultiplier - 1.0);
|
||||
@@ -286,6 +294,15 @@ namespace NT8.Strategies.Examples
|
||||
|
||||
_tradeTaken = true;
|
||||
|
||||
if (_logger != null)
|
||||
_logger.LogDebug(
|
||||
"SimpleORBStrategy flag set: tradeTaken={0} session={1:yyyy-MM-dd}; bar={2:yyyy-MM-dd HH:mm}; side={3}; symbol={4}",
|
||||
_tradeTaken,
|
||||
_currentSessionDate,
|
||||
bar.Time,
|
||||
candidate.Side,
|
||||
candidate.Symbol);
|
||||
|
||||
if (_logger != null && score.Factors != null)
|
||||
{
|
||||
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
||||
@@ -347,7 +364,27 @@ namespace NT8.Strategies.Examples
|
||||
/// <param name="parameters">Parameter map.</param>
|
||||
public void SetParameters(Dictionary<string, object> parameters)
|
||||
{
|
||||
// Constructor-bound parameters intentionally remain immutable for deterministic behavior.
|
||||
if (parameters == null)
|
||||
return;
|
||||
|
||||
// force_session_reset: clear _tradeTaken and ORB state so a fresh live session
|
||||
// can trade even if historical replay set _tradeTaken before going realtime.
|
||||
if (parameters.ContainsKey("force_session_reset"))
|
||||
{
|
||||
var val = parameters["force_session_reset"];
|
||||
if (val is bool && (bool)val)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_tradeTaken = false;
|
||||
_openingRangeReady = false;
|
||||
_openingRangeHigh = Double.MinValue;
|
||||
_openingRangeLow = Double.MaxValue;
|
||||
if (_logger != null)
|
||||
_logger.LogInformation("ForceSessionReset: _tradeTaken cleared, ORB state reset for live session");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureInitialized()
|
||||
|
||||
Reference in New Issue
Block a user