Problem
Unfortunately,
TrendlineValue is not accessible to strategies running in the Strategy Monitor.
Solution
Here's Robert Sucher's
2-script solution:
- Compile the first script.
- Draw a Trendline
- Name the Trendline Resistance
- Click "Go" (or hit F5) to write the TL Resistance data to the file. (*This step is imperative!)
Then you only have to run the second script on the same symbol in the same scale. Script 2 will re-calculate the new value each day.
Also, if you delete or change the position of the Trendline, you need to click "Go" again to remove/change the data for the Resistance Trendline in the file.
Code
Script 1: Write Trendline Data to a fileAfter you draw and name (or delete) your trendline named "Resistance", click "Go" to run this script, which writes the data to a file in your Wealth-Lab User \Data directory named
MyTrendLineAlerts.txt. Repeat the process for any symbol and scale using this same script. The only thing to remember is to make sure you name the trendline the same name that you assign to
TLName in the script, which is "Resistance" here.
using System;
using System.IO;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
namespace WealthLab.Strategies
{
public class TrendlineDataToFile : WealthScript
{
public void AddStringToFile(string path, string str)
{
string temp = String.Empty;
if (File.Exists(path))
using (StreamReader sr = new StreamReader(path))
{
temp = sr.ReadToEnd();
}
using (StreamWriter file = new StreamWriter(path, true))
{
if (!temp.Contains(str))
file.WriteLine(str);
}
}
public void RemoveKeyRecordFromFile(string path, string key)
{
string temp = String.Empty;
if (!File.Exists(path)) return;
using (StreamReader sr = new StreamReader(path))
{
temp = sr.ReadToEnd();
}
string[] lines = temp.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
if (!temp.Contains(key)) return;
List<string> tlist = new List<string>();
using (StreamWriter file = new StreamWriter(path, false))
{
foreach (string s in lines)
{
if (!s.Contains(key))
tlist.Add(s);
}
}
File.WriteAllLines(path, tlist);
}
protected override void Execute()
{
string TLName = "Resistance";
int b1 = Bars.Count - 10;
double st1 = TrendlineValue( b1, TLName );
int b2 = Bars.Count - 5;
double st2 = TrendlineValue( b2, TLName );
double slope = (st2 - st1) / (b2 - b1);
string key = String.Format("{0},{1},{2},{3}", Bars.Symbol, Bars.Scale, Bars.BarInterval, TLName);
string s = key + String.Format(",{0},{1},{2}", Date[b2].ToString("yyyyMMdd"), st2, slope);
string path = Path.Combine(Application.UserAppDataPath, @"Data\MyTrendLineAlerts.txt");
// Always remove a previous entry and refresh if required
RemoveKeyRecordFromFile(path, key);
if (st2 != 0) // edit: I removed && slope != 0, since it's possible to draw a perfectly horizontal TL
{
AddStringToFile(path, s);
}
else
{
DrawLabel(PricePane, "Could not find Trendline named '" + TLName + "'", Color.Red);
}
}
}
}
Script 2: Read Trendline Data from a file (and create an Stop Alert)Of course, you can change the signal to BuyAtLimit or SellAtStop, etc. Note that this actually calculates the value of the trendline on the future bar, and, this script will work for you in the S. Monitor (or anywhere).
using System;
using System.IO;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
namespace WealthLab.Strategies
{
public class MyStrategy : WealthScript
{
protected override void Execute()
{
string TLName = "Resistance";
string path = Path.Combine(Application.UserAppDataPath, @"Data\MyTrendLineAlerts.txt");
if (!File.Exists(path))
{
DrawLabel(PricePane, "Could not find MyTrendLineAlerts.txt", Color.Red);
return;
}
string temp = String.Empty;
using (StreamReader sr = new StreamReader(path))
{
temp = sr.ReadToEnd();
}
string key = String.Format("{0},{1},{2},{3}", Bars.Symbol, Bars.Scale, Bars.BarInterval, TLName);
if (!temp.Contains(key))
{
DrawLabel(PricePane, "Could not find Trendline '" + TLName + "' for this Symbol & Scale", Color.Red);
return;
}
// Find the Trendline value for the last bar
string[] lines = temp.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
IFormatProvider format = new System.Globalization.CultureInfo("en-US");
foreach (string s in lines)
{
if (s.Contains(key)) // found the trendline for this symbol and scale
{
string[] data = s.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
//Index sample:
//0 1 2 3 4 5 6
//AAPL,Minute,30,Resistance,20140321,530.827,0.0794347826087687
DateTime dte = DateTime.ParseExact(data[4], "yyyyMMdd", format);
int b2 = DateTimeToBar(dte, true);
if (b2 == -1)
{
DrawLabel(PricePane, "Could not recreate Trendline '" + TLName + "' for current range", Color.Red);
break;
}
// Note that fbar is the NEXT future bar, so y is the value of the trendline 'tomorrow'
int fbar = Bars.Count;
double y = Convert.ToDouble(data[6]) * (fbar - b2) + Convert.ToDouble(data[5]);
BuyAtMarket(1);
SellAtStop(fbar, LastPosition, y, data[3]);
DrawLabel (PricePane, "TL Value is: " + y.ToString("0.000"));
break;
}
}
}
}
}