Replies

cAlgo_Development
25 Sep 2013, 11:41

Thank you for report. We will work on optimizing memory consumption.


@cAlgo_Development

cAlgo_Development
19 Sep 2013, 15:13

Indicator Example

Moving averages of several symbols on a single chart.



using System;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)]
    public class MultiSymbolMA : Indicator
    {
        private MovingAverage ma1, ma2, ma3;
        private MarketSeries series1, series2, series3;
        private Symbol symbol1, symbol2, symbol3;

        [Parameter(DefaultValue = "EURUSD")]
        public string Symbol1 { get; set; }

        [Parameter(DefaultValue = "EURAUD")]
        public string Symbol2 { get; set; }

        [Parameter(DefaultValue = "EURCAD")]
        public string Symbol3 { get; set; }

        [Parameter(DefaultValue = 14)]
        public int Period { get; set; }

        [Parameter(DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }

        [Output("MA Symbol 1", Color = Colors.Magenta)]
        public IndicatorDataSeries Result1 { get; set; }

        [Output("MA Symbol 2", Color = Colors.Red)]
        public IndicatorDataSeries Result2 { get; set; }

        [Output("MA Symbol 3", Color = Colors.Yellow)]
        public IndicatorDataSeries Result3 { get; set; }

        protected override void Initialize()
        {
            symbol1 = MarketData.GetSymbol(Symbol1);
            symbol2 = MarketData.GetSymbol(Symbol2);
            symbol3 = MarketData.GetSymbol(Symbol3);

            series1 = MarketData.GetSeries(symbol1, TimeFrame);
            series2 = MarketData.GetSeries(symbol2, TimeFrame);
            series3 = MarketData.GetSeries(symbol3, TimeFrame);

            ma1 = Indicators.MovingAverage(series1.Close, Period, MaType);
            ma2 = Indicators.MovingAverage(series2.Close, Period, MaType);
            ma3 = Indicators.MovingAverage(series3.Close, Period, MaType);
        }

        public override void Calculate(int index)
        {
            ShowOutput(symbol1, Result1, ma1, series1, index);
            ShowOutput(symbol2, Result2, ma2, series2, index);
            ShowOutput(symbol3, Result3, ma3, series3, index);
        }

        private void ShowOutput(Symbol symbol, IndicatorDataSeries result, MovingAverage movingAverage, MarketSeries series, int index)
        {
            int index2 = GetIndexByDate(series, MarketSeries.OpenTime[index]);
            result[index] = movingAverage.Result[index2];

            string text = string.Format("{0} {1}", symbol.Code, Math.Round(result[index], symbol.Digits));

            ChartObjects.DrawText(symbol.Code, text, index + 1, result[index], VerticalAlignment.Center, HorizontalAlignment.Right, Colors.Yellow);
        }

        private int GetIndexByDate(MarketSeries series, DateTime time)
        {
            for (int i = series.Close.Count - 1; i >= 0; i--)
                if (time == series.OpenTime[i])
                    return i;
            return -1;
        }
    }
}

 


@cAlgo_Development

cAlgo_Development
19 Sep 2013, 09:15

This code was always like this - Account.Positions always contained positions for all symbols.


@cAlgo_Development

cAlgo_Development
17 Sep 2013, 17:12

We are already working on it. Backtesting will be available very soon.


@cAlgo_Development

cAlgo_Development
17 Sep 2013, 12:59

We confirm that this is a bug. Will fix it ASAP.


@cAlgo_Development

cAlgo_Development
17 Sep 2013, 12:45

When you start backtesting there is a number of trendbars that are already presented in MarketSeries. Robots can build indicators based on these bars so we decided to show them on a chart as well.


@cAlgo_Development

cAlgo_Development
17 Sep 2013, 12:33

Second, if you leave the print statement in the indicator.  You will see that the time.Kind property starts out as unspecified and then changes to UTC no matter if the robot is using another time zone.

We've investigated your case. The problem is that your indicator is used inside a robot so robot's timezone is applied to it. This behavior is described here. When indicator is added directly to a chart UTC timezone is used so DateTime.Kind is UTC.

 

I Inserted the above code and it shows that the attribute.TimeZone property is returning UTC no matter what the robot is set to!!!!!

When you use typeof(MarketHours).GetCustomAttributes() you get timezone that is declared at specified type (MarketHours indicator in this case) but not the timezone that is currently used.

Our solution that we will provide in future is TimeZone property that will be available from both robots and indicators and will contain currently used timezone.


@cAlgo_Development

cAlgo_Development
13 Sep 2013, 12:36

Example: Multi-symbol RSI robot

Robot below trades EURUSD if both EURUSD and EURJPY are overbought or oversold according to RSI indicator:

using System;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Requests;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot()]
    public class MultiSymbolRsiRobot : Robot
    {

        private const string MyLabel = "MultiSymbolRsiRobot";

        [Parameter("Periods", DefaultValue = 14)]
        public int Periods { get; set; }

        [Parameter("Volume", DefaultValue = 10000, MinValue = 1000)]
        public int Volume { get; set; }

        private RelativeStrengthIndex eurJpyRSI;
        private RelativeStrengthIndex eurUsdRSI;

        private Symbol eurUsd;

        protected override void OnStart()
        {
            var eurJpySeries = MarketData.GetSeries("EURJPY", TimeFrame);
            var eurUsdSeries = MarketData.GetSeries("EURUSD", TimeFrame);

            eurJpyRSI = Indicators.RelativeStrengthIndex(eurJpySeries.Close, Periods);
            eurUsdRSI = Indicators.RelativeStrengthIndex(eurUsdSeries.Close, Periods);

            eurUsd = MarketData.GetSymbol("EURUSD");
        }

        protected override void OnTick()
        {
            if (Trade.IsExecuting)
                return;

            if (eurUsdRSI.Result.LastValue > 70 && eurJpyRSI.Result.LastValue > 70)
            {
                ClosePosition(eurUsd, TradeType.Buy);
                OpenPosition(eurUsd, TradeType.Sell);
            }
            if (eurUsdRSI.Result.LastValue < 30 && eurJpyRSI.Result.LastValue < 30)
            {
                ClosePosition(eurUsd, TradeType.Sell);
                OpenPosition(eurUsd, TradeType.Buy);
            }
        }


        private void ClosePosition(Symbol symbol, TradeType tradeType)
        {
            foreach (Position position in Account.Positions)
            {
                if (position.Label == MyLabel && position.SymbolCode == symbol.Code && position.TradeType == tradeType)
                    Trade.Close(position);
            }
        }

        private void OpenPosition(Symbol symbol, TradeType tradeType)
        {
            if (HasPosition(symbol, tradeType))
                return;

            var request = new MarketOrderRequest(tradeType, Volume) 
            {
                Label = MyLabel,
                Symbol = symbol
            };

            Trade.Send(request);
        }

        private bool HasPosition(Symbol symbol, TradeType tradeType)
        {
            foreach (Position position in Account.Positions)
            {
                if (position.SymbolCode == symbol.Code && position.Label == MyLabel && position.TradeType == tradeType)
                    return true;
            }
            return false;
        }

    }
}

 


@cAlgo_Development

cAlgo_Development
13 Sep 2013, 12:26

We added new functionality to cAlgo - the ability for robots and indicators to work with multiple symbols. Now it's possible to use multiple symbol prices, OHLCV series and trade different symbols.

 

Requesting symbol

Robots and indicators can request a symbol specifying its symbol code. Symbol objects behave like the default Symbol object of a robot or indicator, containing current Ask, Bid, PipSize and other useful properties.

Symbol symbol = MarketData.GetSymbol("USDJPY");

Print("Symbol: {0}, Ask: {1}, Bid: {2}", symbol.Code, symbol.Ask, symbol.Bid);

 

Requesting OHLCV series

Robots and indicators can request OHLCV series for multiple symbols and timeframes and build indicators based on it.

MarketSeries series = MarketData.GetSeries("EURCAD", TimeFrame.Minute15);
MovingAverage ma = Indicators.SimpleMovingAverage(series.Close, 20);

Print("Symbol: {0}, TimeFrame: {1}", series.SymbolCode, series.TimeFrame);
Print("Last Close: {0}, Average Close: {1}", series.Close.LastValue, ma.Result.LastValue);

 

Trading multiple symbols

Robots in cAlgo can execute orders for different symbols. To do this, the robot must request the needed symbol by its code. Then, it will be possible to use it in a trade request:

 Symbol symbol = MarketData.GetSymbol("GBPCHF");
 ExecuteMarketOrder(TradeType.Buy, symbol, 10000);

The new version of our Demo cTrader and cAlgo is released and can be downloaded from www.spotware.com

Backtesting of Multi-symbol robots in not supported at least for now. It can be implemented in future.


@cAlgo_Development

cAlgo_Development
12 Sep 2013, 14:53

I have an account at IC markets and a VPS which is on net via Commercial Network Services in New York.

The IC markets cAlgo from this VPS connects to London-3 giving ~40ms latency. Is there no server closer to NY? Does this not defeat the purpose of having a VPS on net with your broker?

Our servers are located in London, so the simplest thing you can do is to move your VPS to London-based data-center. All major providers have data-centers in London.

 

I also login to my cAlgo account from my home desktop whilst is logged in on the VPS. At home in Australia I get connected to Sydney-3. I then notice that my VPS has connected to Sydney-3 also. Should this be happening?

cTrader and cAlgo automatically find closest proxy to connect to, but sometimes it can connect to wrong proxy. Right now we improve our best proxy algorithm so that probability of such wrong connections become almost zero.


@cAlgo_Development

cAlgo_Development
10 Sep 2013, 14:25

First, no matter If you change the timezone of the robot the new day occurs at the same time....

This is not the behavior I expect.  I expect that when robot time is set to UTC new day is at 21:00 ; If set to E.Europe new day should be 00:00.

Yes, new day starts at 17:00 EST. Time offset that trader chooses on main window status-bar and robot's timezone do not affect trend-bar aggregation rules.

 

You will see that the time.Kind property starts out as unspecified and then changes to UTC no matter if the robot is using another time zone.

This is very strange. Sounds like a bug, we will investigate this.


@cAlgo_Development

cAlgo_Development
06 Sep 2013, 11:07

The problem has been fixed already, the fix will be released on Monday


@cAlgo_Development

cAlgo_Development
05 Sep 2013, 10:42

You can pass parameter of TimeFrame type to an indicator, and inside it request Marketseries for this timeframe (details are here /forum/whats-new/1463 ).


@cAlgo_Development

cAlgo_Development
02 Sep 2013, 17:28

Please refresh your charts - historical data must be fixed.


@cAlgo_Development

cAlgo_Development
02 Sep 2013, 12:52

You can use FindSystemTimeZoneById() method:

    [Robot(TimeZone = TimeZones.CentralAmericaStandardTime)]
    public class TimeZonesRobot : Robot
    {
        protected override void OnStart()
        {
            TimeZoneInfo myTimeZone = TimeZoneInfo.FindSystemTimeZoneById(TimeZones.CentralAmericaStandardTime);
            Print("Time Zone: {0}, UTC Offset: {1}", myTimeZone.Id, myTimeZone.BaseUtcOffset);
        }
    }

 

If you want to grab timezone id directly from the attribute, you can use code from my previous post.


@cAlgo_Development

cAlgo_Development
02 Sep 2013, 12:44

All dates and times presented in a robot (market series, orders entry dates, server time) are presented in specified timezone, for example:

 

    [Robot(TimeZone = TimeZones.EEuropeStandardTime)]
    public class TimeZonesRobot : Robot
    {
        protected override void OnStart()
        {
            Print("Current bar open: {0}", MarketSeries.OpenTime.LastValue);
        }
    }

Prints "Current bar open: 02/09/2013 12:00:00"

At the same time

    [Robot(TimeZone = TimeZones.UTC)]
    public class TimeZonesRobot : Robot
    {
        protected override void OnStart()
        {
            Print("Current bar open: {0}", MarketSeries.OpenTime.LastValue);
        }
    }

Prints "Current bar open: 02/09/2013 09:00:00"


@cAlgo_Development

cAlgo_Development
02 Sep 2013, 11:58

Thank you for the report. We will fix this bug and correct the data.
 


@cAlgo_Development

cAlgo_Development
30 Aug 2013, 17:37

These are the next features planned for cAlgo (next release). As soon as the access to multiple timeframe data series is implemented, we will start implementation on the following features:

  • Access to multiple symbols (bid, ask, digits, etc)
  • Access to data series (OHLCV) for multiple symbols
  • Declaring parameters of Symbol type in robots / indicators
  • Trading for multiple symbols

@cAlgo_Development

cAlgo_Development
30 Aug 2013, 14:02

Multi-timeframe robot

This is the RSI robot. It uses a daily Average True Range value as a filter, i.e. it does not trade if the ATR value is greater than the specified parameter value:

 

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Requests;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC)]
    public class SampleRSIRobot : Robot
    {
        [Parameter("Max ATR Value", DefaultValue = 0.01)]
        public double MaxAtrValue { get; set; }

        private RelativeStrengthIndex rsi;
        private AverageTrueRange atr;

        protected override void OnStart()
        {
            rsi = Indicators.RelativeStrengthIndex(MarketSeries.Close, 14);

            var dailySeries = MarketData.GetSeries(TimeFrame.Daily);
            atr = Indicators.AverageTrueRange(dailySeries, 20, MovingAverageType.Simple);
        }

        protected override void OnTick()
        {
            if (Trade.IsExecuting)
                return;

            // Do nothing if daily ATR value > Max allowed value
            if (atr.Result.LastValue > MaxAtrValue)
                return;

            if (rsi.Result.LastValue < 30)
            {
                OpenPosition(TradeType.Buy);
            }
            else if (rsi.Result.LastValue > 70)
            {
                OpenPosition(TradeType.Sell);
            }
        }

        private void OpenPosition(TradeType tradeType)
        {
            foreach (var position in Account.Positions)
            {
                if (position.Label == "SampleRSIRobot" && position.TradeType != tradeType)
                {
                    Trade.Close(position);
                }
            }

            bool hasNeededPosition = Account.Positions.Any(position => position.Label == "SampleRSIRobot" && position.TradeType == tradeType);
            if (!hasNeededPosition)
            {
                var request = new MarketOrderRequest(tradeType, 10000) 
                {
                    Label = "SampleRSIRobot",
                    StopLossPips = 20
                };
                Trade.Send(request);
            }
        }
    }
}

 


@cAlgo_Development

cAlgo_Development
30 Aug 2013, 12:56

Indicator example: Multi-timeframe moving average

In this example, we output moving averages with the same period for different timeframes on a single chart:



Source code:

using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)]
    public class MultiTF_MA : Indicator
    {
        [Parameter(DefaultValue = 50)]
        public int Period { get; set; }

        [Output("MA", Color = Colors.Yellow)]
        public IndicatorDataSeries MA { get; set; }

        [Output("MA5", Color = Colors.Orange)]
        public IndicatorDataSeries MA5 { get; set; }

        [Output("MA10", Color = Colors.Red)]
        public IndicatorDataSeries MA10 { get; set; }

        private MarketSeries series5;
        private MarketSeries series10;

        private MovingAverage ma;
        private MovingAverage ma5;
        private MovingAverage ma10;

        protected override void Initialize()
        {
            series5 = MarketData.GetSeries(TimeFrame.Minute5);
            series10 = MarketData.GetSeries(TimeFrame.Minute10);

            ma = Indicators.MovingAverage(MarketSeries.Close, Period, MovingAverageType.Triangular);
            ma5 = Indicators.MovingAverage(series5.Close, Period, MovingAverageType.Triangular);
            ma10 = Indicators.MovingAverage(series10.Close, Period, MovingAverageType.Triangular);
        }

        public override void Calculate(int index)
        {
            MA[index] = ma.Result[index];

            var index5 = GetIndexByDate(series5, MarketSeries.OpenTime[index]);
            if (index5 != -1)
                MA5[index] = ma5.Result[index5];

            var index10 = GetIndexByDate(series10, MarketSeries.OpenTime[index]);
            if (index10 != -1)
                MA10[index] = ma10.Result[index10];
        }


        private int GetIndexByDate(MarketSeries series, DateTime time)
        {
            for (int i = series.Close.Count - 1; i > 0; i--)
            {
                if (time == series.OpenTime[i])
                    return i;
            }
            return -1;
        }
    }
}

 


@cAlgo_Development