Script Indicator

From Haasonline Software Wiki
Jump to: navigation, search

Haasbot's Script Indicator is an Indicator for the Trade Bot. The Script Indicator is an indicator using a (user)script to determine the result. With Script Indicators you can create and share your own indicators. Ind-script-1024x482.jpg

Settings

The Script Indicator has only one setting: the full path to the script.

Language

The scripts are C#-scripts, using the CS-Script CLR.

Interface

All indicator scripts must implement the IIndicatorScript-interface:

    public enum IndicatorResult {Stay, Buy, Sell}
    public interface IIndicatorScript
    {
        string Name { get; }
        int PriceHistoryLimit { get; }
        void Init();
        IndicatorResult GetResult(IndicatorContext context);
        List<DataSerie> ChartDataSeries { get; }
        List<double> GetChartData(IndicatorContext context);
        List<ScriptParameter> GetParameters();
        void SetParameters(Dictionary<string,object> parameters);
    }


You can either to this by implementing all methods and properties of this interface, or by inheriting of IndicatorScriptBase. When inheriting of IndicatorScriptBase, you only have to override the methods and properties you want to be different than the default behavior.

Name
This property returns the name of the indicator. Haasbot will use this name for the indicator, instead of the general "Script Indicator", so it is clear for the user which script is being used. We advise to always override this property so you can give your script a meaningful name.
PriceHistoryLimit
With this property you can configure how much price points (Bid, Ask, High, Low, Volume) must be kept in memory by the IndicatorContext. Default is 50. Make sure this is big enough to have enough data to do the necessary calculations in your script, while keeping it small enough to reduce memory usage and unnecessary CPU load when doing these calculations.
Init
This method is executed after creating the script-object. You can use this to do any necessary initialization. The created script-object will stay in memory and will be used until the script is recompiled. An indicator-script is recompiled when Haasbot starts and when the Script Indicator settings-window is closed.
GetResult
This method will be executed every time Haasbot checks the indicator. It should return an IndicatorResult (Stay, Buy or Sell). An IndicatorContext-object is passed, containing current price details and a reference to the IndicatorAPI, giving access to historical price data for all supported platforms and currency pairs. The default behavior of this method is to always return Stay. Of course, overriding this method is a minimum requirement to have a meaningful indicator.
ChartDataSeries
ChartDataSeries is a property defining the chart lines which will be shown on the indicator chart. To change this, this property has to return a list of DataSerie-objects, which define the properties of one chart line.
For each line in the chart, you have to define a name, on which chart it has to be shown (1 or 2) and optionally a color. When no color is defined, Haasbot assigns a color automatically. For an example, see lines 65 to 76 in the example script. When the ChartDataSeries returns a non-empty list, the GetChartData-method should be overriden too.
GetChartData
This method returns the data points which have to be shown in the chart(s). It should return a list of double's, in the same order as the DataSeries returned by the ChartDataSeries-property. The length of the list returned by the ChartDataSeries-property should be the same length as the list returned by GetChartData. An IndicatorContext object is passed to this method. This method is called after calling GetResult(), so if any chart data is generated in the GetResult-method, you can store it in a class member, and return it in GetChartData to be shown on the indicator chart.
GetParameters
This method returns the parameters the user can configure for this script. It should return a list ScriptParameter objects. These ScriptParameter objects define for each parameter the name, current value, type and optionally some info text shown to the user. The user will be able to configure these parameters in the Haasbot user interface.
SetParameters
This method is called when the script parameters are saved in the Haasbot user interface. The argument is a dictionary with the parameter names as dictionary-keys, and the parameter values as dictionary-values. The type of the values is object, so you need to cast them to the correct type (the same type as you defined in the ScriptParameter in GetParameters). When only specific values or range of values is valid for a certain parameter, you can do the checks here and revert to the previous value if an invalid value was set by the user.
After SetParameters is called, the name of the script (the Name-property) is retrieved again. This way, when parameters are used in the name, the name is updated when the parameters are updated.

TA-Lib

In an indicator script you have access to TA-Lib for calculating any technical analysis indicators. All functions are static members of the static class Core in the namespace TicTacTec.TA.Library. It is not necessary to include external references to use TA-Lib. The PriceHistory-property in the IndicatorContext and the result of the method GetPriceInstrument in the IndicatorAPI contains multiple arrays of doubles (Asks, Bids, High, Low, Volume), which can directly be used as input for the TA-Lib-functions.

Creating classes

You can define your own classes and structs in a script. You only have to make sure the class implementing the IIndicatorScript-interface is the first class in the file.

Debugging

Writing to log-file

You can write debug-info to a log file, by calling Logger.LogToFile(message) on the IndicatorContext-object. The message will be written (together with a timestamp) to a log-file. The log-file has the name of the script and is located at the Haasbot execution path.


Step-by-step debugging

Coming soon

Example script

  1. using HaasbotScripting;
  2. using HaasbotScripting.DataObjects;
  3. using System.Collections.Generic;
  4. using System.Drawing;
  5. using System;
  6.  
  7. public class ExampleScript : IndicatorScriptBase
  8. {
  9.     //Data to be shown in the indicator-chart:
  10.     private double buyPrice;
  11.     private double emaShort;
  12.     private double emaLong;
  13.  
  14.     //Parameters:
  15.     private int emaShortLength = 7;
  16.     private int emaLongLength = 30;
  17.  
  18.     public override string Name
  19.     {
  20.         get{ return "Script: EMA " + emaShortLength + "-" + emaLongLength; }
  21.     }
  22.  
  23.  
  24.     public override int PriceHistoryLimit
  25.     {
  26.         get { return 50; }
  27.     }
  28.  
  29.     public override List<ScriptParameter> GetParameters()
  30.     {
  31.         return new List<ScriptParameter>(){
  32.             new ScriptParameter(){Name = "EMA short length", 
  33.                                   Type = ScriptParameterType.Integer, 
  34.                                   Value = emaShortLength,
  35.                                   Info = "Multiplied with the indicator update interval"},
  36.             new ScriptParameter(){Name = "EMA long length", Type = ScriptParameterType.Integer, Value = emaLongLength}
  37.         };
  38.     }
  39.  
  40.     public override void SetParameters(Dictionary<string, object> parameters)
  41.     {
  42.         emaShortLength = (int) parameters["EMA short length"];
  43.         emaLongLength = (int) parameters["EMA long length"];
  44.     }
  45.  
  46.  
  47.  
  48.     public override IndicatorResult GetResult(IndicatorContext context)
  49.     {
  50.         PriceInstrument instrument = context.PriceHistory;
  51.  
  52.         int beginIndex, outNBElements;
  53.         double[] emaShortValues = new double[instrument.Count];
  54.         double[] emaLongValues = new double[instrument.Count];
  55.  
  56.         var emaShortReturnCode = TicTacTec.TA.Library.Core.Ema(0, instrument.Count - 1, instrument.Asks, emaShortLength, out beginIndex, out outNBElements, emaShortValues);
  57.         var emaLongReturnCode = TicTacTec.TA.Library.Core.Ema(0, instrument.Count - 1, instrument.Asks, emaLongLength, out beginIndex, out outNBElements, emaLongValues);
  58.  
  59.         if (emaShortReturnCode == TicTacTec.TA.Library.Core.RetCode.Success && emaLongReturnCode == TicTacTec.TA.Library.Core.RetCode.Success){    
  60.  
  61.             buyPrice = instrument.Asks[instrument.Count - 1]; //Take current (last) value
  62.  
  63.             if(outNBElements == 0){
  64.                 //We have not enough price history yet to calculate the EMA values
  65.                 emaShort = buyPrice;
  66.                 emaLong = buyPrice;
  67.                 return IndicatorResult.Stay;
  68.             }else{
  69.                 emaShort = emaShortValues[outNBElements - 1]; //Take current EMA (last one of the valid values)
  70.                 emaLong = emaLongValues[outNBElements - 1]; //Take current EMA (last one of the valid values)
  71.  
  72.                 context.Logger.LogToFile("EMA Short: " + emaShort + "\tEMA Long:" + emaLong); //Log to file
  73.  
  74.                 //Determine indicator signal
  75.                 if(emaShort > emaLong)
  76.                     return IndicatorResult.Buy;
  77.                 else if(emaLong > emaShort)
  78.                     return IndicatorResult.Sell;
  79.                 else
  80.                     return IndicatorResult.Stay;
  81.             }
  82.         }else{
  83.             context.Logger.LogToFile("EMA calculation failed."); //Log to file
  84.             return IndicatorResult.Stay;
  85.         }
  86.     }
  87.  
  88.     public override List<DataSerie> ChartDataSeries
  89.     {
  90.             get
  91.             {
  92.                 return new List<DataSerie>()
  93.                 {
  94.                     new DataSerie("Buy Price", 1),
  95.                     new DataSerie("EMA Short", 1, Color.LightBlue),
  96.                     new DataSerie("EMA Long", 1, Color.Orange)
  97.                 };
  98.             }
  99.     }
  100.  
  101.     public override List<double> GetChartData(IndicatorContext context)
  102.     {
  103.             return new List<double>()
  104.             {
  105.                 buyPrice, emaShort, emaLong
  106.             };
  107.     }
  108. }