- ago
I have taken a sample strategy for Tactical Allocation and have added these items:
- Choose # of assets open.
- Stop loss Pct.
- Same day stop loss.

However, it is not working right. for "Stop loss Pct" and "Same day stop loss". I have set the Stop Loss Pct to 10%.

Here is the Strategy Settings tab:



Here is the Position screen:



Here is my code:

CODE:
using System; using WealthLab.Core; using WealthLab.Backtest; using WealthLab.Data; using WealthLab.Indicators; using System.Drawing; using System.Collections.Generic; namespace WealthScript11 {    public class TacticalAssetRotation : UserStrategyBase    {       public TacticalAssetRotation()       {          AddParameter("Number of Buy Candidates", ParameterType.Int32, 6, 1, 10, 1);          AddParameter("Stop Loss Pct", ParameterType.Int32, 10, 2, 80, 2);       }       //declare private variables below       private TimeSeries avgROC;       private string seriesKey = "Average ROC";       //the list of symbols that we should buy each bar       private static List<BarHistory> buys = new List<BarHistory>();       //create the weight indicator and stash it into the BarHistory object for reference in PreExecute       public override void Initialize(BarHistory bars)       {                 //load the parameters          numParticipants = Parameters[0].AsInt;          stopLossPct = Parameters[1].AsInt;                 avgROC = (ROC.Series(bars.Close, 60) + ROC.Series(bars.Close, 120) + ROC.Series(bars.Close, 200)) / 3;          bars.Cache[seriesKey] = avgROC;       }       //this is called prior to the Execute loop, determine which symbols have the lowest average ROC       public override void PreExecute(DateTime dt, List<BarHistory> participants)       {          //store the symbols' AvgROC value in their BarHistory instances          foreach (BarHistory bh in participants)          {             TimeSeries symbolRoc = (TimeSeries)bh.Cache[seriesKey];             int idx = GetCurrentIndex(bh); //this returns the index of the BarHistory for the bar currently being processed             double rocVal = symbolRoc[idx];             //if the indicator isn't valid set a high value to avoid selection in rotation             if (idx < symbolRoc.FirstValidIndex)                rocVal = 1.0e6;             bh.UserData = rocVal; //save the current AvgROC value along with the BarHistory instance          }          //sort the participants by AvgROC value (lowest to highest)          participants.Sort((a, b) => a.UserDataAsDouble.CompareTo(b.UserDataAsDouble));          //keep the top 3 symbols          buys.Clear();          //for (int n = 0; n < 3; n++)          for (int n = 0; n < numParticipants; n++) // LARRY NEW LINE OF CODE          {             if (n >= participants.Count)                break;             buys.Add(participants[n]);          }       }       //execute the strategy rules here, this is executed once for each bar in the backtest history       public override void Execute(BarHistory bars, int idx)       {          bool inBuyList = buys.Contains(bars);          if (!HasOpenPosition(bars, PositionType.Long))          {                          //create the transation for use with same say stops             Transaction trans = null;                                 //no entry if not in the buy list             if (!inBuyList)                return;                                    if (inBuyList)             {                   trans = PlaceTrade(bars, TransactionType.Buy, OrderType.Market, 0, 0, "Buy Tactical");             }          }          else          {             //sell logic, sell if it's not in the buys list             if (!inBuyList)             {                //PlaceTrade(bars, TransactionType.Sell, OrderType.Market);                Backtester.CancelationCode = 284;                PlaceTrade(bars, TransactionType.Sell, OrderType.Market, 0, 0, "Sell Tactical");             }             else // this is not working right for stop loss exit                //stop loss exit                PlaceTrade(bars, TransactionType.Sell, OrderType.Stop, StopLoss(bars, idx), 0, "Stop Loss Tactical");          } // this is not working for Same bar exit       }       //same bar exits: profit or loss from execution price       public override void AssignAutoStopTargetPrices(Transaction trans, double basisPrice, double executionPrice)       {                trans.AutoStopLossPrice = Math.Round(executionPrice * (1 - (stopLossPct / 100)), 2);       }              //calcualte the stoploss price and return it       private double StopLoss(BarHistory bars, int idx)       {          return Math.Round(LastOpenPosition.EntryPrice * (1 - (stopLossPct / 100)), 2);       }       //private variables       int numParticipants,stopLossPct;    } }


Can you please take a look.

Thank you,
Larry

0
256
Solved
2 Replies

Reply

Bookmark

Sort
- ago
#1
Re: stopLossPct / 100. When doing a division of two double values you should indicate that explicitly, otherwise you may get a zero because in C# this is considered an integer division. You have to perform an implicit cast to double or specify the divisor as a double e.g.

double d1 = 123 / 456d;
double d2 = 123 / (double)456;
double d3 = 123 / 456.0;
0
Best Answer
- ago
#2
Eugene,

Got it.

Thank you,
Larry
0

Reply

Bookmark

Sort