In the strategy analyser simulation it works as expected, but when I use try to paper trade it using "control centre"-> strategies, the Print() output that I do indicates that the 100 lots has indeed been bought and held, but the "orders", "executions" and "trades" tabs are empty. There is no record of the trade having occurred despite the Positions[] array clearly showing that there is a position.
The code I am using is: [I have to make sure to run it in EUR or GBP with PeroidType and Period matching what is written in the program but that is by-the-by for now]
#region Using declarations using System; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; using System.Xml.Serialization; using NinjaTrader.Cbi; using NinjaTrader.Data; using NinjaTrader.Indicator; using NinjaTrader.Gui.Chart; using NinjaTrader.Strategy; #endregion // aStrategy is a test strategy to be executed within the multi instrument framework. namespace NinjaTrader.Strategy { public class aStrategy : Strategy { #region Variables public static Strategy so; public static int [] positions; // for output of required positons #endregion public static void executeOnInitialize(Strategy so) { so.Print("Enter executeOnInitialize()"); aStrategy.so = so; positions = new int[multiInstrumentTrader.nSyms]; so.Print("Exit executeOnInitialize()"); } public static void computeNewPositions() { so.Print("Enter computeNewPositions()"); for(int i=0; i<multiInstrumentTrader.nSyms; i++) { so.Print( " " + multiInstrumentTrader.assetSymbols[i] + " return = " + multiInstrumentTrader.assetReturns[i] ); positions[i] = 100; } so.Print("Exit computeNewPositions()"); } public static void executeOnDispose(Strategy so) { } } } // This namespace holds all strategies and is required. Do not change it. namespace NinjaTrader.Strategy { /// <summary> /// Multi instrument trading example/template /// </summary> [Description("Multi instrument trading example/template")] public class multiInstrumentTrader : Strategy { #region Variables #region userParameters public static PeriodType periodType = PeriodType.Second; public static int period = 10; public static uint nSyms = 2; public static string[] assetSymbols = {"$EURUSD", "$GBPUSD"}; #endregion userParameters public double [] price = new double[nSyms]; // Sample price in USD public static double [] assetReturns = new double[nSyms]; // current sample minus previous sample public static int [] positions = new int[nSyms]; public static bool [] assetSampled = new bool[nSyms]; // 1 = this asset has been sample for this time stamp public static int timeCounter; public enum positionSetting {Short=-1, Neutral, Long}; #endregion void adjustPositionTo(int i, int newPosition) { Position current = Positions[i]; Print(" Enter adustPosition() " + Time[0]); Print(" " + Instruments[i].FullName + ", " + Instruments[BarsInProgress].FullName); Print(" " + "Positions[" + i + "]=" + current); int side = 0; switch (current.MarketPosition) { case MarketPosition.Short : { side = -1; break;} case MarketPosition.Flat : { side = 0; break;} case MarketPosition.Long : { side = 1; break;} } positionSetting currentSide = (positionSetting) side; int delta = newPosition - side*current.Quantity; Print(" currentSide=" + currentSide ); Print(" delta=" + delta ); positionSetting direction = positionSetting.Neutral; if (delta < 0) direction = positionSetting.Short; if (delta > 0) direction = positionSetting.Long; if (delta == 0) direction = positionSetting.Neutral; Print(" direction=" + direction ); bool changingSides = current.Quantity < Math.Abs(delta); Print(" changingSides=" + changingSides ); if( ((currentSide == positionSetting.Neutral) || (currentSide == positionSetting.Short)) && (direction == positionSetting.Short) ) { Print(" A: EnterShort( " + Math.Abs(delta) + ") of " + Instruments[BarsInProgress].FullName + " " + Instruments[i].FullName); EnterShort(Math.Abs(delta)); } if( ((currentSide == positionSetting.Neutral) || (currentSide == positionSetting.Long)) && (direction == positionSetting.Long) ) { Print(" B: EnterLong( " + Math.Abs(delta) + ") of " + Instruments[BarsInProgress].FullName + " " + Instruments[i].FullName); EnterLong( Math.Abs(delta)); } if( (currentSide == positionSetting.Short) && (direction == positionSetting.Long) ) { if ( Math.Abs(delta) > current.Quantity ) { Print(" C: ExitShort( " + current.Quantity + ") of " + Instruments[BarsInProgress].FullName + " " + Instruments[i].FullName); ExitShort(current.Quantity ); Print(" D: EnterLong( " + (Math.Abs(delta) - current.Quantity) + ") of " + Instruments[BarsInProgress].FullName + " " + Instruments[i].FullName); EnterLong(Math.Abs(delta) - current.Quantity ); } else { Print(" E: ExitShort( " + Math.Abs(delta) + ") of " + Instruments[BarsInProgress].FullName + " " + Instruments[i].FullName); ExitShort(Math.Abs(delta)); } } if( (currentSide == positionSetting.Long) && (direction == positionSetting.Short) ) { if ( Math.Abs(delta) > current.Quantity ) { Print(" F: ExitLong( " + current.Quantity + ") of " + Instruments[BarsInProgress].FullName + " " + Instruments[i].FullName); ExitLong(current.Quantity ); Print(" G: EnterShort( " + (Math.Abs(delta) - current.Quantity) + ") of " + Instruments[BarsInProgress].FullName + " " + Instruments[i].FullName); EnterShort(Math.Abs(delta) - current.Quantity); } else { Print(" H: ExitLong( " + Math.Abs(delta) + ") of " + Instruments[BarsInProgress].FullName + " " + Instruments[i].FullName); ExitLong( Math.Abs(delta)); } } Print(" Exit adustPosition() "); } protected override void Initialize() { Print("Enter Initialize() " + Time[0]); CalculateOnBarClose = true; timeCounter = 0; for (int i=0;i<nSyms;i++) { // only add the non-primary series Print("Attempting to add symbol " + assetSymbols[i]); Print(" primary is " + Instruments[0].FullName); if(0 != String.Compare(assetSymbols[i], Instruments[0].FullName)){ Add(assetSymbols[i], periodType, period); Print(" added " + assetSymbols[i]); } else { Print(" this is the primary series."); } assetSampled[i] = false; // mark as un sampled } // INSERT INITIALISATION CALLS OF YOUR STRATEGIES HERE//// aStrategy.executeOnInitialize(this); Print(" Exit Initialize() "); } protected override void OnBarUpdate() { Print(" "); Print("Enter OnBarUpdate() " + Time[0]); Print(" " + Instruments[BarsInProgress].FullName); assetSampled[BarsInProgress] = true; // mark this instrument as sampled double price0; double price1; if ( Bars.CurrentBar > 0 ) { price0 = Closes[BarsInProgress][0]; price1 = Closes[BarsInProgress][1]; } else { price0 = 1; price1 = 1; } assetReturns[BarsInProgress] = price0 - price1; // have we now sampled all assets for this time stamp? bool allSampled = true; for(int i=0;i<nSyms;i++) allSampled = allSampled && assetSampled[i]; // If so then run forward one time step if(allSampled ) { aStrategy.computeNewPositions(); // call on the strategy to update it's positions[] aStrategy.positions.CopyTo(positions,0); // copy the strategies positions[] for(int i=0;i<nSyms;i++){ assetSampled[i] = false; } // mark all assets as unsampled } // call this every time, it will only alter positions when positions[] has changed (i.e. if allsampled) adjustPositionTo(BarsInProgress, positions[BarsInProgress]); Print("Exit OnBarUpdate() "); timeCounter = timeCounter + 1; } #region Properties #endregion } }
Comment