Phase 0 completion: NT8 SDK core framework with risk management and position sizing
Some checks failed
Build and Test / build (push) Has been cancelled
Some checks failed
Build and Test / build (push) Has been cancelled
This commit is contained in:
105
.kilocode/rules/CODE_REVIEW_CHECKLIST.md
Normal file
105
.kilocode/rules/CODE_REVIEW_CHECKLIST.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# NT8 SDK - Code Review Checklist
|
||||
|
||||
## Pre-Commit Checklist for AI Agents
|
||||
|
||||
### ✅ Compatibility Check
|
||||
- [ ] All projects target `net48`
|
||||
- [ ] Language version set to `5.0` in all projects
|
||||
- [ ] No modern C# features used (records, nullable refs, string interpolation)
|
||||
- [ ] No .NET Core packages added
|
||||
- [ ] `.\verify-build.bat` passes with zero errors
|
||||
|
||||
### ✅ Architecture Compliance
|
||||
- [ ] All trading logic goes through IRiskManager
|
||||
- [ ] Strategies are thin plugins (signal generation only)
|
||||
- [ ] No direct market access from strategies
|
||||
- [ ] Proper error handling and logging
|
||||
|
||||
### ✅ Code Quality
|
||||
- [ ] All classes have proper constructors (no auto-properties with initializers)
|
||||
- [ ] Dictionary initialization uses `.Add()` method
|
||||
- [ ] String formatting uses `String.Format()` not interpolation
|
||||
- [ ] All interfaces properly implemented
|
||||
- [ ] Unit tests included for new functionality
|
||||
|
||||
### ✅ Testing Requirements
|
||||
- [ ] MSTest framework used (not xUnit)
|
||||
- [ ] Test coverage >80% for core components
|
||||
- [ ] All risk scenarios tested
|
||||
- [ ] Integration tests work with mock data
|
||||
|
||||
## Common Rejection Reasons
|
||||
|
||||
### ❌ Automatic Rejection
|
||||
1. **Uses C# 6+ features** (records, nullable refs, etc.)
|
||||
2. **Targets wrong framework** (.NET Core instead of Framework 4.8)
|
||||
3. **Adds incompatible packages** (Microsoft.Extensions.*)
|
||||
4. **Bypasses risk management** (direct order submission)
|
||||
5. **Build fails** (compilation errors, warnings)
|
||||
|
||||
### ⚠️ Review Required
|
||||
1. **Complex inheritance hierarchies**
|
||||
2. **Performance-critical code** (may need optimization later)
|
||||
3. **External dependencies** (evaluate NT8 compatibility)
|
||||
4. **Configuration changes** (verify impact on existing functionality)
|
||||
|
||||
## Review Process
|
||||
|
||||
### For Human Reviewers
|
||||
1. **Run verification**: `.\verify-build.bat`
|
||||
2. **Check guidelines**: Verify compliance with `AI_DEVELOPMENT_GUIDELINES.md`
|
||||
3. **Test coverage**: Ensure new features have adequate tests
|
||||
4. **Architecture review**: Confirm risk-first design maintained
|
||||
|
||||
### For AI Agents
|
||||
1. **Self-check**: Use this checklist before submitting
|
||||
2. **Build verification**: Always run build verification
|
||||
3. **Pattern matching**: Follow existing code patterns in the repo
|
||||
4. **Documentation**: Update relevant docs if needed
|
||||
|
||||
## Phase-Specific Guidelines
|
||||
|
||||
### Current Phase (Phase 1)
|
||||
- Focus on NT8 integration only
|
||||
- Implement basic order management
|
||||
- Enhance risk controls (Tier 2)
|
||||
- No UI work or advanced features
|
||||
|
||||
### Future Phases
|
||||
- Will be specified in separate guidelines
|
||||
- Do not implement features from future phases
|
||||
- Stay within current phase scope
|
||||
|
||||
## Examples of Good vs Bad Code
|
||||
|
||||
### ✅ Good (C# 5.0 Compatible)
|
||||
```csharp
|
||||
public class RiskDecision
|
||||
{
|
||||
public bool Allow { get; set; }
|
||||
public string RejectReason { get; set; }
|
||||
|
||||
public RiskDecision(bool allow, string rejectReason)
|
||||
{
|
||||
Allow = allow;
|
||||
RejectReason = rejectReason;
|
||||
}
|
||||
}
|
||||
|
||||
var metrics = new Dictionary<string, object>();
|
||||
metrics.Add("risk", 100.0);
|
||||
metrics.Add("reason", "Daily limit");
|
||||
```
|
||||
|
||||
### ❌ Bad (Modern C# - Will Not Compile)
|
||||
```csharp
|
||||
public record RiskDecision(bool Allow, string? RejectReason);
|
||||
|
||||
var metrics = new Dictionary<string, object>
|
||||
{
|
||||
["risk"] = 100.0,
|
||||
["reason"] = "Daily limit"
|
||||
};
|
||||
```
|
||||
|
||||
This checklist should be used by AI agents before every commit and by human reviewers for all pull requests.
|
||||
273
.kilocode/rules/CODE_STYLE_GUIDE.md
Normal file
273
.kilocode/rules/CODE_STYLE_GUIDE.md
Normal file
@@ -0,0 +1,273 @@
|
||||
# NT8 SDK Code Style Guide
|
||||
|
||||
## Required Patterns for AI Agents
|
||||
|
||||
### Class Declaration Pattern
|
||||
```csharp
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NT8.Core.SomeModule
|
||||
{
|
||||
/// <summary>
|
||||
/// Class description
|
||||
/// </summary>
|
||||
public class ClassName
|
||||
{
|
||||
private readonly Type _field;
|
||||
|
||||
/// <summary>
|
||||
/// Property description
|
||||
/// </summary>
|
||||
public Type PropertyName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor description
|
||||
/// </summary>
|
||||
public ClassName(Type parameter)
|
||||
{
|
||||
if (parameter == null) throw new ArgumentNullException("parameter");
|
||||
_field = parameter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method description
|
||||
/// </summary>
|
||||
public ReturnType MethodName(Type parameter)
|
||||
{
|
||||
// Implementation
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Interface Implementation Pattern
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// Interface description
|
||||
/// </summary>
|
||||
public interface IInterfaceName
|
||||
{
|
||||
/// <summary>
|
||||
/// Method description
|
||||
/// </summary>
|
||||
ReturnType MethodName(Type parameter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implementation description
|
||||
/// </summary>
|
||||
public class Implementation : IInterfaceName
|
||||
{
|
||||
public ReturnType MethodName(Type parameter)
|
||||
{
|
||||
// Implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Dictionary Initialization Pattern (C# 5.0)
|
||||
```csharp
|
||||
// ✅ REQUIRED Pattern
|
||||
var dictionary = new Dictionary<string, object>();
|
||||
dictionary.Add("key1", value1);
|
||||
dictionary.Add("key2", value2);
|
||||
|
||||
// ❌ FORBIDDEN Pattern
|
||||
var dictionary = new Dictionary<string, object>
|
||||
{
|
||||
["key1"] = value1,
|
||||
["key2"] = value2
|
||||
};
|
||||
```
|
||||
|
||||
### String Formatting Pattern (C# 5.0)
|
||||
```csharp
|
||||
// ✅ REQUIRED Pattern
|
||||
var message = String.Format("Processing {0} with value {1:F2}", name, amount);
|
||||
_logger.LogInformation("Order {0} status: {1}", orderId, status);
|
||||
|
||||
// ❌ FORBIDDEN Pattern
|
||||
var message = $"Processing {name} with value {amount:F2}";
|
||||
_logger.LogInformation($"Order {orderId} status: {status}");
|
||||
```
|
||||
|
||||
### Async Method Pattern (C# 5.0)
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// Async method description
|
||||
/// </summary>
|
||||
public async Task<ReturnType> MethodNameAsync(Type parameter)
|
||||
{
|
||||
// Async implementation
|
||||
var result = await SomeAsyncOperation();
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
### Error Handling Pattern
|
||||
```csharp
|
||||
public ReturnType MethodName(Type parameter)
|
||||
{
|
||||
if (parameter == null) throw new ArgumentNullException("parameter");
|
||||
|
||||
try
|
||||
{
|
||||
// Implementation
|
||||
return result;
|
||||
}
|
||||
catch (SpecificException ex)
|
||||
{
|
||||
_logger.LogError("Specific error occurred: {0}", ex.Message);
|
||||
throw; // or handle appropriately
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("Unexpected error: {0}", ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Test Class Pattern (MSTest)
|
||||
```csharp
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using NT8.Core.SomeModule;
|
||||
|
||||
namespace NT8.Core.Tests.SomeModule
|
||||
{
|
||||
[TestClass]
|
||||
public class ClassNameTests
|
||||
{
|
||||
private ClassName _target;
|
||||
|
||||
[TestInitialize]
|
||||
public void TestInitialize()
|
||||
{
|
||||
_target = new ClassName(/* parameters */);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MethodName_Condition_ExpectedResult()
|
||||
{
|
||||
// Arrange
|
||||
var input = /* test data */;
|
||||
|
||||
// Act
|
||||
var result = _target.MethodName(input);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(result.Success);
|
||||
Assert.AreEqual(expected, result.Value);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MethodName_InvalidInput_ThrowsException()
|
||||
{
|
||||
// Act & Assert
|
||||
Assert.ThrowsException<ArgumentNullException>(() => _target.MethodName(null));
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Configuration Class Pattern
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// Configuration class description
|
||||
/// </summary>
|
||||
public class ConfigurationClass
|
||||
{
|
||||
/// <summary>
|
||||
/// Property description
|
||||
/// </summary>
|
||||
public Type PropertyName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor with all required parameters
|
||||
/// </summary>
|
||||
public ConfigurationClass(Type parameter1, Type parameter2)
|
||||
{
|
||||
PropertyName1 = parameter1;
|
||||
PropertyName2 = parameter2;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Enum Pattern
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// Enum description
|
||||
/// </summary>
|
||||
public enum EnumName
|
||||
{
|
||||
/// <summary>
|
||||
/// First value description
|
||||
/// </summary>
|
||||
FirstValue,
|
||||
|
||||
/// <summary>
|
||||
/// Second value description
|
||||
/// </summary>
|
||||
SecondValue
|
||||
}
|
||||
```
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
### Classes and Interfaces
|
||||
- **Classes**: PascalCase (`RiskManager`, `PositionSizer`)
|
||||
- **Interfaces**: IPascalCase (`IRiskManager`, `IPositionSizer`)
|
||||
|
||||
### Methods and Properties
|
||||
- **Methods**: PascalCase (`ValidateOrder`, `CalculateSize`)
|
||||
- **Properties**: PascalCase (`Symbol`, `Quantity`)
|
||||
|
||||
### Fields and Variables
|
||||
- **Private fields**: _camelCase (`_logger`, `_riskConfig`)
|
||||
- **Local variables**: camelCase (`riskAmount`, `contracts`)
|
||||
- **Constants**: UPPER_CASE (`MAX_CONTRACTS`, `DEFAULT_TIMEOUT`)
|
||||
|
||||
### Parameters
|
||||
- **Parameters**: camelCase (`intent`, `context`, `config`)
|
||||
|
||||
## File Organization
|
||||
|
||||
### Using Statements Order
|
||||
```csharp
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using NT8.Core.Common.Models;
|
||||
using NT8.Core.Logging;
|
||||
```
|
||||
|
||||
### Namespace and Class Structure
|
||||
```csharp
|
||||
namespace NT8.Core.ModuleName
|
||||
{
|
||||
/// <summary>
|
||||
/// Class documentation
|
||||
/// </summary>
|
||||
public class ClassName
|
||||
{
|
||||
// 1. Private fields
|
||||
private readonly Type _field;
|
||||
|
||||
// 2. Public properties
|
||||
public Type Property { get; set; }
|
||||
|
||||
// 3. Constructor(s)
|
||||
public ClassName() { }
|
||||
|
||||
// 4. Public methods
|
||||
public void PublicMethod() { }
|
||||
|
||||
// 5. Private methods
|
||||
private void PrivateMethod() { }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
These patterns MUST be followed by all AI agents to ensure consistency and compatibility.
|
||||
204
.kilocode/rules/Compile error guidance.md
Normal file
204
.kilocode/rules/Compile error guidance.md
Normal file
@@ -0,0 +1,204 @@
|
||||
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.
|
||||
502
.kilocode/rules/Guidelines.md
Normal file
502
.kilocode/rules/Guidelines.md
Normal file
@@ -0,0 +1,502 @@
|
||||
o help ensure that NinjaTrader 8 (NT8) code compiles successfully the first time, every time, you can give your developers a clear set of compile-time directives, guardrails, and best practices. Below is a comprehensive guide you can use or adapt as a compile spec or code review checklist.
|
||||
|
||||
✅ NinjaTrader 8 Compile-Time Success Directives
|
||||
🧱 1. Code Structure & Class Guidelines
|
||||
|
||||
Each script must extend only the correct NT8 base class:
|
||||
|
||||
Indicator, Strategy, MarketAnalyzerColumn, etc.
|
||||
|
||||
Use [GeneratedCode] attributes only where required.
|
||||
|
||||
Avoid partial classes unless absolutely necessary.
|
||||
|
||||
🔍 2. File & Naming Conventions
|
||||
|
||||
Class name and file name must match.
|
||||
|
||||
No duplicate class names, even across namespaces.
|
||||
|
||||
Avoid reserved words or NT8 system identifiers.
|
||||
|
||||
📦 3. Namespace Hygiene
|
||||
|
||||
Always use:
|
||||
|
||||
using System;
|
||||
using NinjaTrader.Cbi;
|
||||
using NinjaTrader.Gui.Tools;
|
||||
using NinjaTrader.NinjaScript;
|
||||
using NinjaTrader.Data;
|
||||
using NinjaTrader.Gui;
|
||||
using NinjaTrader.NinjaScript.Strategies;
|
||||
using NinjaTrader.NinjaScript.Indicators;
|
||||
|
||||
|
||||
Avoid unnecessary or ambiguous using directives (e.g., from other frameworks).
|
||||
|
||||
🧪 4. Method & Lifecycle Integrity
|
||||
|
||||
Ensure these NT8 methods are implemented correctly:
|
||||
|
||||
protected override void OnStateChange()
|
||||
protected override void OnBarUpdate()
|
||||
protected override void OnMarketData(MarketDataEventArgs e) // if used
|
||||
|
||||
|
||||
Avoid:
|
||||
|
||||
Missing break statements in switch.
|
||||
|
||||
Logic in OnBarUpdate() without BarsInProgress checks when using multiple series.
|
||||
|
||||
🛡️ 5. Error-Free State Management
|
||||
|
||||
Always check states in OnStateChange():
|
||||
|
||||
if (State == State.SetDefaults) { ... }
|
||||
if (State == State.Configure) { ... }
|
||||
if (State == State.DataLoaded) { ... }
|
||||
|
||||
|
||||
Avoid placing runtime logic or order submissions in SetDefaults or Configure.
|
||||
|
||||
⛔ 6. No Runtime Calls at Compile-Time
|
||||
|
||||
Do not call:
|
||||
|
||||
Print() inside SetDefaults
|
||||
|
||||
AddDataSeries() inside wrong state
|
||||
|
||||
CalculateXXX() outside Configure
|
||||
|
||||
🧯 7. Null Checks and Bounds
|
||||
|
||||
Always check:
|
||||
|
||||
if (CurrentBar < X) return;
|
||||
if (BarsInProgress != 0) return; // If multi-series used
|
||||
if (mySeries == null) return;
|
||||
|
||||
|
||||
Prevent index out of range errors:
|
||||
|
||||
if (CurrentBar < myPeriod) return;
|
||||
double value = Close[0]; // Only if safe
|
||||
|
||||
🧰 8. Avoid Common Pitfalls
|
||||
|
||||
No empty catch blocks or silent exceptions.
|
||||
|
||||
No hardcoded bar indexes or array sizes.
|
||||
|
||||
Avoid referencing objects that may be null (e.g., BarsArray[1], SMA() without initialization).
|
||||
|
||||
📚 9. Dependencies & Resources
|
||||
|
||||
No external libraries unless they are approved and included in the solution.
|
||||
|
||||
Ensure all custom indicators or referenced strategies exist and are compiled.
|
||||
|
||||
📏 10. Strategy Parameters & UI Defaults
|
||||
|
||||
Provide all necessary [NinjaScriptProperty] parameters.
|
||||
|
||||
Set default values cleanly inside State.SetDefaults.
|
||||
|
||||
Use Name = "MyStrategy" for naming.
|
||||
|
||||
🧹 11. Code Hygiene & Readability
|
||||
|
||||
Consistent indentation, spacing, and braces.
|
||||
|
||||
No commented-out blocks of old code in final delivery.
|
||||
|
||||
Regions (#region) for each main section: Inputs, Initialization, Logic, etc.
|
||||
|
||||
🧪 12. Pre-Compile Self-Test Macro (Optional)
|
||||
|
||||
If feasible, add a conditional debug directive:
|
||||
|
||||
#if DEBUG
|
||||
Print("DEBUG: Compiling MyStrategy");
|
||||
#endif
|
||||
|
||||
✅ Pre-Delivery Checklist for Developers
|
||||
Checkpoint Status
|
||||
No compile errors or warnings ✅
|
||||
Clean OnStateChange() structure ✅
|
||||
Safe OnBarUpdate() logic ✅
|
||||
Proper BarsInProgress handling ✅
|
||||
All inputs and parameters declared ✅
|
||||
Class name matches file name ✅
|
||||
No unused using directives ✅
|
||||
Strategy or indicator tested ✅
|
||||
|
||||
|
||||
|
||||
|
||||
Here’s a practical compile-spec + guardrails you can hand to any dev so their NinjaTrader 8 code compiles cleanly the first time—no surprises, no Order Flow+ dependencies, and no signature mismatches.
|
||||
|
||||
NinjaTrader 8 “First-Time Compile” Spec
|
||||
0) Golden rules (pin these in the PR template)
|
||||
|
||||
Target base class: public class <Name> : Strategy in the namespace NinjaTrader.NinjaScript.Strategies.
|
||||
|
||||
File name = class name (e.g., ORBV4.cs contains public class ORBV4 : Strategy).
|
||||
|
||||
Correct override access: all NT8 overrides must be protected override, never public or private.
|
||||
|
||||
No dead APIs: do not implement OnStartUp() (doesn’t exist). Use OnStateChange() with state switches.
|
||||
|
||||
No Order Flow+ unless requested: never reference indicators like OrderFlow VWAP if the environment may not have it.
|
||||
|
||||
No invented enum values: never use things like OrderState.PendingSubmit or RejectedByExchange. Only use enums that exist in NT8.
|
||||
|
||||
Attributes present: using System.ComponentModel.DataAnnotations; for [Range] and [Display]. Use [NinjaScriptProperty] for user inputs.
|
||||
|
||||
Indicators & series created only in State.DataLoaded (not in State.SetDefaults).
|
||||
|
||||
Bar guards at top of OnBarUpdate: if (BarsInProgress != 0) return; if (CurrentBar < BarsRequiredToTrade) return;
|
||||
|
||||
Managed vs Unmanaged: pick exactly one model and stick to its API patterns in the whole file.
|
||||
|
||||
1) Required using directives (top of every strategy file)
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using NinjaTrader.Cbi;
|
||||
using NinjaTrader.Data;
|
||||
using NinjaTrader.Gui;
|
||||
using NinjaTrader.Gui.Chart;
|
||||
using NinjaTrader.Gui.Tools;
|
||||
using NinjaTrader.NinjaScript;
|
||||
using NinjaTrader.NinjaScript.Strategies;
|
||||
using NinjaTrader.NinjaScript.Indicators;
|
||||
|
||||
2) Required lifecycle pattern (no OnStartUp)
|
||||
protected override void OnStateChange()
|
||||
{
|
||||
if (State == State.SetDefaults)
|
||||
{
|
||||
Name = "StrategyName";
|
||||
Description = "Short description";
|
||||
Calculate = Calculate.OnBarClose; // Change only if truly needed
|
||||
IsInstantiatedOnEachOptimizationIteration = true;
|
||||
IsOverlay = false;
|
||||
BarsRequiredToTrade = 20;
|
||||
|
||||
// Defaults for public properties
|
||||
RiskTicks = 16;
|
||||
UseRthOnly = true;
|
||||
}
|
||||
else if (State == State.Configure)
|
||||
{
|
||||
// Set up data series, trading hours behavior, etc. (no indicators here)
|
||||
// Example: AddDataSeries(BarsPeriodType.Minute, 1);
|
||||
}
|
||||
else if (State == State.DataLoaded)
|
||||
{
|
||||
// Create indicators/series
|
||||
sma = SMA(20); // ✅ Allowed; built-in indicator
|
||||
// vwap = VWAP(...); // ❌ Avoid if Order Flow+ isn’t guaranteed
|
||||
}
|
||||
}
|
||||
|
||||
3) Correct signatures for event hooks (copy exactly)
|
||||
|
||||
OnBarUpdate
|
||||
|
||||
protected override void OnBarUpdate()
|
||||
{
|
||||
if (BarsInProgress != 0) return;
|
||||
if (CurrentBar < BarsRequiredToTrade) return;
|
||||
|
||||
// Strategy logic here
|
||||
}
|
||||
|
||||
|
||||
OnOrderUpdate (Managed or Unmanaged—signature is the same)
|
||||
|
||||
protected override void OnOrderUpdate(
|
||||
Order order,
|
||||
double limitPrice,
|
||||
double stopPrice,
|
||||
int quantity,
|
||||
int filled,
|
||||
double averageFillPrice,
|
||||
OrderState orderState,
|
||||
DateTime time,
|
||||
ErrorCode error,
|
||||
string nativeError)
|
||||
{
|
||||
// Observe state transitions or errors here
|
||||
}
|
||||
|
||||
|
||||
OnExecutionUpdate
|
||||
|
||||
protected override void OnExecutionUpdate(
|
||||
Execution execution,
|
||||
string executionId,
|
||||
double price,
|
||||
int quantity,
|
||||
MarketPosition marketPosition,
|
||||
string orderId,
|
||||
DateTime time)
|
||||
{
|
||||
// Post-fill logic here
|
||||
}
|
||||
|
||||
|
||||
OnPositionUpdate (when needed)
|
||||
|
||||
protected override void OnPositionUpdate(Position position, double averagePrice, int quantity, MarketPosition marketPosition)
|
||||
{
|
||||
// Position tracking here
|
||||
}
|
||||
|
||||
|
||||
Guardrail: If you ever see CS0507 (“cannot change access modifiers when overriding ‘protected’…”) it means you used public override or private override. Switch to protected override.
|
||||
|
||||
4) Property pattern (inputs that always compile)
|
||||
|
||||
Use [NinjaScriptProperty] + [Range] + [Display].
|
||||
|
||||
Put properties after fields, inside the strategy class.
|
||||
|
||||
#region Inputs
|
||||
[NinjaScriptProperty]
|
||||
[Range(1, int.MaxValue)]
|
||||
[Display(Name = "RiskTicks", GroupName = "Parameters", Order = 1)]
|
||||
public int RiskTicks { get; set; }
|
||||
|
||||
[NinjaScriptProperty]
|
||||
[Display(Name = "UseRthOnly", GroupName = "Parameters", Order = 2)]
|
||||
public bool UseRthOnly { get; set; }
|
||||
#endregion
|
||||
|
||||
5) Indicator & resource creation rules
|
||||
|
||||
Only instantiate indicators/Series in State.DataLoaded.
|
||||
|
||||
Never new built-in indicators; call factory methods (e.g., SMA(20)).
|
||||
|
||||
Don’t assume Order Flow+. If you need VWAP, either:
|
||||
|
||||
Use a custom rolling VWAP you implement locally, or
|
||||
|
||||
Wrap the reference behind a feature flag and compile-time fallbacks.
|
||||
|
||||
6) Managed orders “compile-safe” usage
|
||||
|
||||
Set targets/stops before entry on the same bar:
|
||||
|
||||
SetStopLoss(CalculationMode.Ticks, RiskTicks);
|
||||
SetProfitTarget(CalculationMode.Ticks, RiskTicks * 2);
|
||||
EnterLong(); // or EnterShort()
|
||||
|
||||
|
||||
Don’t mix EnterLong/Short with Unmanaged SubmitOrderUnmanaged() in the same strategy.
|
||||
|
||||
If using signals, use consistent signal names across entries/exits.
|
||||
|
||||
7) Unmanaged orders “compile-safe” usage (if chosen)
|
||||
|
||||
Opt-in once:
|
||||
|
||||
else if (State == State.Configure)
|
||||
{
|
||||
Calculate = Calculate.OnBarClose;
|
||||
// Enable unmanaged if needed
|
||||
// this.IsUnmanaged = true; // uncomment only if you’re actually using unmanaged
|
||||
}
|
||||
|
||||
|
||||
Always check Order objects for null before accessing fields.
|
||||
|
||||
Maintain your own OCO/quantity state.
|
||||
|
||||
Do not call Managed Set* methods in Unmanaged mode.
|
||||
|
||||
8) Enums & constants that trip compilers
|
||||
|
||||
Use only valid enum members. Examples that compile:
|
||||
|
||||
OrderAction.Buy, OrderAction.SellShort
|
||||
|
||||
OrderType.Market, OrderType.Limit, OrderType.StopMarket, OrderType.StopLimit
|
||||
|
||||
TimeInForce.Day, TimeInForce.Gtc
|
||||
|
||||
MarketPosition.Flat/Long/Short
|
||||
|
||||
OrderState.Accepted/Working/PartFilled/Filled/Cancelled/Rejected/Unknown (names vary by NT build; don’t invent “PendingSubmit”, “RejectedByBroker”, “RejectedByExchange”).
|
||||
|
||||
Use ToTime(Time[0]) or anchors like Times[0][0] for session-aware checks; avoid DateTime.Now for bar logic.
|
||||
|
||||
9) Safe OnBarUpdate header (paste into every strategy)
|
||||
protected override void OnBarUpdate()
|
||||
{
|
||||
if (BarsInProgress != 0) return;
|
||||
if (CurrentBar < BarsRequiredToTrade) return;
|
||||
if (UseRthOnly && !TradingHours.Contains(Time[0])) return; // requires proper session template
|
||||
|
||||
// Logic...
|
||||
}
|
||||
|
||||
10) Logging & messages
|
||||
|
||||
Use Print() for debug; never MessageBox.Show or Windows-only UI calls (breaks compile or runtime).
|
||||
|
||||
Wrap optional debug in a bool DebugMode input and guard if (DebugMode) Print(...).
|
||||
|
||||
11) Namespaces & class hygiene
|
||||
|
||||
Exactly one public strategy per file.
|
||||
|
||||
No top-level statements; everything inside the namespace/class.
|
||||
|
||||
No async/await; stick to synchronous NT8 patterns.
|
||||
|
||||
12) “No-surprises” build checks (optional but recommended)
|
||||
|
||||
If you run pre-lint or Roslyn analyzers externally, do not add NuGet packages inside NinjaTrader’s compile domain.
|
||||
|
||||
Keep analyzers in your editor/CI only, not as runtime dependencies in NT8.
|
||||
|
||||
13) Minimal, compile-safe template (drop-in)
|
||||
|
||||
Copy this as your starting point; it compiles on a vanilla NT8 (no Order Flow+).
|
||||
|
||||
// ============================================================================
|
||||
// Strategy Name : CompileSafeTemplate
|
||||
// Description : Minimal, first-time-compile-safe NinjaTrader 8 strategy
|
||||
// ============================================================================
|
||||
|
||||
#region Using declarations
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using NinjaTrader.Cbi;
|
||||
using NinjaTrader.Data;
|
||||
using NinjaTrader.Gui;
|
||||
using NinjaTrader.Gui.Chart;
|
||||
using NinjaTrader.Gui.Tools;
|
||||
using NinjaTrader.NinjaScript;
|
||||
using NinjaTrader.NinjaScript.Strategies;
|
||||
using NinjaTrader.NinjaScript.Indicators;
|
||||
#endregion
|
||||
|
||||
namespace NinjaTrader.NinjaScript.Strategies
|
||||
{
|
||||
public class CompileSafeTemplate : Strategy
|
||||
{
|
||||
private SMA sma;
|
||||
|
||||
#region Inputs
|
||||
[NinjaScriptProperty]
|
||||
[Range(1, int.MaxValue)]
|
||||
[Display(Name = "RiskTicks", GroupName = "Parameters", Order = 1)]
|
||||
public int RiskTicks { get; set; }
|
||||
|
||||
[NinjaScriptProperty]
|
||||
[Display(Name = "UseRthOnly", GroupName = "Parameters", Order = 2)]
|
||||
public bool UseRthOnly { get; set; }
|
||||
|
||||
[NinjaScriptProperty]
|
||||
[Display(Name = "DebugMode", GroupName = "Parameters", Order = 3)]
|
||||
public bool DebugMode { get; set; }
|
||||
#endregion
|
||||
|
||||
protected override void OnStateChange()
|
||||
{
|
||||
if (State == State.SetDefaults)
|
||||
{
|
||||
Name = "CompileSafeTemplate";
|
||||
Description = "Minimal, compile-safe NT8 strategy template";
|
||||
Calculate = Calculate.OnBarClose;
|
||||
IsOverlay = false;
|
||||
BarsRequiredToTrade = 20;
|
||||
IsInstantiatedOnEachOptimizationIteration = true;
|
||||
|
||||
// Defaults
|
||||
RiskTicks = 16;
|
||||
UseRthOnly = true;
|
||||
DebugMode = false;
|
||||
}
|
||||
else if (State == State.Configure)
|
||||
{
|
||||
// AddDataSeries(...) if needed
|
||||
}
|
||||
else if (State == State.DataLoaded)
|
||||
{
|
||||
sma = SMA(20);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnBarUpdate()
|
||||
{
|
||||
if (BarsInProgress != 0) return;
|
||||
if (CurrentBar < BarsRequiredToTrade) return;
|
||||
if (UseRthOnly && !TradingHours.Contains(Time[0])) return;
|
||||
|
||||
// Example trivial logic just to show structure (does nothing fancy)
|
||||
if (CrossAbove(Close, sma, 1) && Position.MarketPosition == MarketPosition.Flat)
|
||||
{
|
||||
SetStopLoss(CalculationMode.Ticks, RiskTicks);
|
||||
SetProfitTarget(CalculationMode.Ticks, RiskTicks * 2);
|
||||
EnterLong();
|
||||
if (DebugMode) Print($"EnterLong at {Time[0]}");
|
||||
}
|
||||
else if (CrossBelow(Close, sma, 1) && Position.MarketPosition == MarketPosition.Flat)
|
||||
{
|
||||
SetStopLoss(CalculationMode.Ticks, RiskTicks);
|
||||
SetProfitTarget(CalculationMode.Ticks, RiskTicks * 2);
|
||||
EnterShort();
|
||||
if (DebugMode) Print($"EnterShort at {Time[0]}");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnOrderUpdate(
|
||||
Order order, double limitPrice, double stopPrice, int quantity, int filled,
|
||||
double averageFillPrice, OrderState orderState, DateTime time,
|
||||
ErrorCode error, string nativeError)
|
||||
{
|
||||
if (DebugMode) Print($"OnOrderUpdate: {order?.Name} {orderState} {nativeError}");
|
||||
}
|
||||
|
||||
protected override void OnExecutionUpdate(
|
||||
Execution execution, string executionId, double price, int quantity,
|
||||
MarketPosition marketPosition, string orderId, DateTime time)
|
||||
{
|
||||
if (DebugMode) Print($"OnExecutionUpdate: {execution?.Name} {quantity}@{price}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
14) Quick dev checklist (paste in your repo README)
|
||||
|
||||
File name matches class name; class derives from Strategy.
|
||||
|
||||
All overrides are protected override and signatures match exactly.
|
||||
|
||||
No OnStartUp(); lifecycle is handled in OnStateChange.
|
||||
|
||||
All indicators/Series created in State.DataLoaded.
|
||||
|
||||
No Order Flow+ indicators unless explicitly requested.
|
||||
|
||||
OnBarUpdate starts with BarsInProgress and CurrentBar guards.
|
||||
|
||||
Inputs use [NinjaScriptProperty], [Range], [Display].
|
||||
|
||||
No invented enum values; only valid OrderState, MarketPosition, etc.
|
||||
|
||||
Managed vs Unmanaged is consistent; do not mix APIs.
|
||||
|
||||
No MessageBox/UI calls; optional logs gated behind DebugMode.
|
||||
|
||||
|
||||
|
||||
25
.kilocode/rules/archon.md
Normal file
25
.kilocode/rules/archon.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Archon Integration & Workflow
|
||||
|
||||
**CRITICAL: This project uses Archon for knowledge management, task tracking, and project organization.**
|
||||
|
||||
## Core Archon Workflow Principles
|
||||
|
||||
### The Golden Rule: Task-Driven Development with Archon
|
||||
|
||||
**MANDATORY: Always complete the full Archon task cycle before any coding:**
|
||||
|
||||
1. **Check Current Task** → Review task details and requirements
|
||||
2. **Research for Task** → Search relevant documentation and examples
|
||||
3. **Implement the Task** → Write code based on research
|
||||
4. **Update Task Status** → Move task from "todo" → "doing" → "review"
|
||||
5. **Get Next Task** → Check for next priority task
|
||||
6. **Repeat Cycle**
|
||||
|
||||
**Task Management Rules:**
|
||||
- Update all actions to Archon
|
||||
- Move tasks from "todo" → "doing" → "review" (not directly to complete)
|
||||
- Maintain task descriptions and add implementation notes
|
||||
- DO NOT MAKE ASSUMPTIONS - check project documentation for questions
|
||||
|
||||
|
||||
|
||||
243
.kilocode/rules/development_workflow.md
Normal file
243
.kilocode/rules/development_workflow.md
Normal file
@@ -0,0 +1,243 @@
|
||||
# NT8 Institutional SDK - Development Workflow
|
||||
|
||||
## 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.
|
||||
|
||||
## Archon Workflow Principles
|
||||
|
||||
The development process follows these core principles adapted from the Archon workflow:
|
||||
|
||||
### 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.
|
||||
139
.kilocode/rules/nt8compilespec.md
Normal file
139
.kilocode/rules/nt8compilespec.md
Normal file
@@ -0,0 +1,139 @@
|
||||
## Purpose
|
||||
A single source of truth to ensure **first-time compile** success for all NinjaTrader 8 strategies, indicators, and add-ons generated by an LLM.
|
||||
|
||||
---
|
||||
|
||||
## Golden Rules (Pin These)
|
||||
1. **NT8 only.** No NT7 APIs. If NT7 concepts appear, **silently upgrade** to NT8 (proper `OnStateChange()` and `protected override` signatures).
|
||||
2. **One file, one public class.** File name = class name. Put at the top: `// File: <ClassName>.cs`.
|
||||
3. **Namespaces:**
|
||||
- Strategies → `NinjaTrader.NinjaScript.Strategies`
|
||||
- Indicators → `NinjaTrader.NinjaScript.Indicators`
|
||||
4. **Correct override access:** All NT8 overrides are `protected override` (never `public` or `private`).
|
||||
5. **Lifecycle:** Use `OnStateChange()` with `State.SetDefaults`, `State.Configure`, `State.DataLoaded` to set defaults, add data series, and instantiate indicators/Series.
|
||||
6. **Indicator creation:** Instantiate indicators **once** in `State.DataLoaded`. Add to chart (if desired) in `State.Configure` via `AddChartIndicator()`.
|
||||
7. **Managed orders by default:** Use `SetStopLoss`/`SetProfitTarget` **before** entries on the same bar. Do **not** mix Managed & Unmanaged in the same file.
|
||||
8. **MTF discipline:** Add secondary series **only** in `State.Configure`. In `OnBarUpdate()`, gate logic with `BarsInProgress` and `CurrentBars[i]`.
|
||||
9. **No Order Flow+ by default:** Assume unavailable. If VWAP is needed, implement a **local fallback** or feature flag (OFF by default).
|
||||
10. **Valid enums only:** Use real NT8 members for `OrderState`, `MarketPosition`, etc.
|
||||
11. **Starter header in every strategy `OnBarUpdate()`:**
|
||||
```csharp
|
||||
if (BarsInProgress != 0) return;
|
||||
if (CurrentBar < BarsRequiredToTrade) return;
|
||||
|
||||
Required Using Block (Strategy)
|
||||
Always show details
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Windows.Media;
|
||||
using NinjaTrader.Cbi;
|
||||
using NinjaTrader.Data;
|
||||
using NinjaTrader.Gui;
|
||||
using NinjaTrader.Gui.Chart;
|
||||
using NinjaTrader.Gui.Tools;
|
||||
using NinjaTrader.NinjaScript;
|
||||
using NinjaTrader.NinjaScript.Strategies;
|
||||
using NinjaTrader.NinjaScript.Indicators;
|
||||
using NinjaTrader.NinjaScript.DrawingTools;
|
||||
|
||||
|
||||
Indicators omit some GUI usings unless needed.
|
||||
|
||||
Inputs Pattern
|
||||
|
||||
Use DataAnnotations so properties render properly in the UI:
|
||||
|
||||
Always show details
|
||||
[NinjaScriptProperty, Range(1, int.MaxValue)]
|
||||
[Display(Name = "Quantity", GroupName = "Parameters", Order = 0)]
|
||||
public int Quantity { get; set; } = 1;
|
||||
|
||||
[NinjaScriptProperty]
|
||||
[Display(Name = "DebugMode", GroupName = "Parameters", Order = 999)]
|
||||
public bool DebugMode { get; set; } = false;
|
||||
|
||||
Managed Order Rules
|
||||
|
||||
Call SetStopLoss and SetProfitTarget before you place an entry order.
|
||||
|
||||
Re-arm stops/targets when intended direction changes (e.g., flat→long or flat→short).
|
||||
|
||||
Use unique signal names per direction to bind OCO correctly (e.g., "L1", "S1").
|
||||
|
||||
Multi-Timeframe Rules
|
||||
|
||||
Add secondary series in State.Configure:
|
||||
|
||||
Always show details
|
||||
AddDataSeries(BarsPeriodType.Minute, 5);
|
||||
|
||||
|
||||
Guard in OnBarUpdate():
|
||||
|
||||
Always show details
|
||||
if (BarsInProgress == 1) { /* 5-min logic */ }
|
||||
if (CurrentBars[0] < BarsRequiredToTrade || CurrentBars[1] < 20) return;
|
||||
|
||||
Price Rounding & Tick Math
|
||||
|
||||
Always round to tick size to avoid rejections:
|
||||
|
||||
Always show details
|
||||
private double Rt(double p) => Instrument.MasterInstrument.RoundToTickSize(p);
|
||||
double target = Rt(Close[0] + 10 * TickSize);
|
||||
|
||||
Historical vs. Realtime
|
||||
Always show details
|
||||
private bool IsLive => State == State.Realtime;
|
||||
|
||||
|
||||
Avoid timers/threads/file I/O by default.
|
||||
|
||||
Common Safety Defaults
|
||||
Always show details
|
||||
Calculate = Calculate.OnBarClose;
|
||||
IsOverlay = false;
|
||||
BarsRequiredToTrade = 20;
|
||||
IsSuspendedWhileInactive = true;
|
||||
IsInstantiatedOnEachOptimizationIteration = true;
|
||||
|
||||
Valid NT8 Signatures (paste as needed)
|
||||
Always show details
|
||||
protected override void OnOrderUpdate(
|
||||
Order order, double limitPrice, double stopPrice, int quantity,
|
||||
int filled, double averageFillPrice, OrderState orderState,
|
||||
DateTime time, ErrorCode error, string nativeError) { }
|
||||
|
||||
protected override void OnExecutionUpdate(
|
||||
Execution execution, string executionId, double price, int quantity,
|
||||
MarketPosition marketPosition, string orderId, DateTime time) { }
|
||||
|
||||
protected override void OnMarketData(MarketDataEventArgs e) { }
|
||||
protected override void OnMarketDepth(MarketDepthEventArgs e) { }
|
||||
protected override void OnPositionUpdate(Position position, double averagePrice, int quantity, MarketPosition marketPosition) { }
|
||||
|
||||
Compile Checklist (Preflight)
|
||||
|
||||
NT8 only; no OnStartUp() or NT7 methods.
|
||||
|
||||
Exactly one public class; file name matches class name.
|
||||
|
||||
Required usings present.
|
||||
|
||||
Indicators/Series created in State.DataLoaded.
|
||||
|
||||
Starter header present in OnBarUpdate().
|
||||
|
||||
Managed orders only (unless explicitly asked otherwise).
|
||||
|
||||
Secondary series added only in State.Configure.
|
||||
|
||||
Enums & members verified against NT8.
|
||||
|
||||
Price rounding helper present for any custom prices.
|
||||
|
||||
DebugMode gating for Print() calls.
|
||||
""").format(date=datetime.date.today().isoformat())
|
||||
|
||||
files["NT8_Templates.md"] = textwrap.dedent("""
|
||||
Reference in New Issue
Block a user