Topics

Forum Topics not found

Replies

fxtradersystems
12 Oct 2020, 18:21

RE:

Jobauma said:

I want "[ Index - 55 ]" of an MA to be removed, so there are only 55 MA plots ( all the time ), from the last bar to 55 bars back. :)

 

Hi Jobauma,

We built that for you here: https://ctrader.com/algos/indicators/show/2432

If you need any dev work done, then we are available at development@fxtradersystems.com

Or you can get us at our website: fxtradersystems.com

Cheers,

Sam


@fxtradersystems

fxtradersystems
12 Oct 2020, 18:03

RE:

luca.tocchi said:

hi I would like that to whatever tf the bot works, the zig zag prints the monthly tf values

how can I do?

thanks 

 

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class Botdellasvolta : Robot
    {
        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("Stop Loss", Group = "Protection", DefaultValue = 0)]
        public int StopLoss { get; set; }

        [Parameter("Take Profit", Group = "Protection", DefaultValue = 5)]
        public int TakeProfit { get; set; }

        [Parameter(DefaultValue = 12)]
        public int Depth { get; set; }

        [Parameter(DefaultValue = 5)]
        public int Deviation { get; set; }

        [Parameter(DefaultValue = 3)]
        public int BackStep { get; set; }

        [Output("ZigZag", Color = Colors.OrangeRed)]
        public IndicatorDataSeries Result { get; set; }

        private ZigZag zigzag;

        protected override void OnStart()
        {
            MarketSeries data = MarketData.GetSeries(TimeFrame.Monthly);
            zigzag = Indicators.GetIndicator<ZigZag>(Depth, Deviation, BackStep);
        }

        double GetZigZagValue(DataSeries dataSeries, int indexFromEnd)
        {
            for (var i = MarketSeries.Close.Count - 1; i >= 0; i--)
            {
                if (!double.IsNaN(zigzag.Result[i]))
                {
                    if (indexFromEnd == 0)
                        return zigzag.Result[i];
                    indexFromEnd--;
                }
            }
            return double.NaN;
        }

        protected override void OnTick()
        {
            var lastValue = GetZigZagValue(zigzag.Result, 0);
            var previousValue = GetZigZagValue(zigzag.Result, 1);

            Print(lastValue);
            Print(previousValue);
        }
    }
}

 

This may be a little overcomplicated, but you could modify the ZigZag indicator to take a timeframe parameter as input.

You can then create your own custom bars by using: customBars = MarketData.GetBars(Timeframe);

In OnCalculate() you can then find the corresponding index of the current bar with the custom timeframe bar using:
int customIndex = customBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);

You can then have:

Result[index] = function(customIndex);

You have to be careful though if the function relies on the Result (ie. if you're using a moving average of the Result for another output), as it starts to generate an incorrect series.

 

Let us know if you need any further help or development work done @ fxtradersystems.com/support/ :)

Sam

fxtradersystems.com

 


@fxtradersystems

fxtradersystems
12 Oct 2020, 17:33

RE: RE: UserVoice

meiko.allmis said:

JS15 said:

Shading inbetween indicator lines. eg. having a shaded area between the top and bottom Bollinger Band or 2 moving averages.
Thanks

Would be happy to have this feature

This is possible by adding the [Cloud()] attribute before the [Indicator()] attribute.

I've built the request here: https://ctrader.com/algos/indicators/show/2431

If you need any dev work done in the future, we're happy to help.

Contactable via both: fxtradersystems.com/support/ and via email at development@fxtradersystems.com

Cheers,

Sam


@fxtradersystems

fxtradersystems
10 Oct 2020, 22:39

RE:

linton.nkambule said:

I'd like some code to create a bot that does some simple things:

1. opens positions based on the previous candles direction at the open of the new candle. ( would be nice to have an option to invert the position)

2. Adds a stop loss of a certain percentage which can be passed 100% of the previous candles high or low.

3. sets a take profit of the same number of pips as the stop loss. 

 

We saw the request, and built something for you now:

https://ctrader.com/algos/cbots/show/2424

Was a nice bit of coding to round off our Saturday.

If you fancy anything else built, you can fire us a message at development@fxtradersystems.com, or get in contact at: fxtradersystems.com/support/


@fxtradersystems

fxtradersystems
10 Oct 2020, 22:13 ( Updated at: 21 Dec 2023, 09:22 )

RE:

lookformoneyy said:

HI traders

I am looking for an indicator to draw the movement of the price after the closing and opening of candles.

I showing this for example:

 

this is not Zigzag . How is for cTrader somethink indicator ?

 

I will be grateful for pointing such an indicator on the ctrader :)

 

No worries, we heard your request, and just whipped up this for you:

https://ctrader.com/algos/indicators/show/2423

Let us know how you find it :)

 

If you want any further development work done, then you can email us at development@fxtradersystems.com or get in contact via fxtradersystems.com/support/


@fxtradersystems

fxtradersystems
10 Oct 2020, 19:25

RE: RE: Break Even Price

firemyst said:

I believe your calculations are incorrect.

For starters, you're using BID price everywhere. On Long/buy positions, you get the ASK price, not the BID price.

In your calculation, your value could be negative as a result. For instance, assume ASK is 5, BID is 4, with a 1 pip spread. Thus your entry would be 5 (because the ASK could have been 5), so 4 - (5 + 1) = -2. For a long/buy position, the break even should be above the ASK price (obviously) and not below the BID price.

Second, your calculation (position.EntryPrice + Symbol.Spread) is adding a price value plus pips. You need to add price value plus the equivalent value in pips, so it should be:

(position.EntryPrice + (Symbol.Spread * Symbol.PipSize))

Hope that helps :-)

Hi @firemyst,

You were right, particularly with the ASK / BID relationship - this also means (we believe) that we don't need to include it in the distance calculation, as we can actually just get the current ASK/BID.

We've tested the following code in backtest on AUDJPY m30, both buy and sell positions, with lot sizes of 0.01, 1, and 10, and with spreads of 1 pip and 30 pips. It seems to work as intended, though for some trades falls 0.4-0.8 pips short of break even (resulting in a loss of £4 on a 10 lot trade). You could modify it to put an additional buffer of one pip if desired.

The only thing it hasn't come up against is commission and swaps in testing, but I believe these are both in the NetProfit figure (?) so it should still hold true.

Let us know if you find any more errors and we'd be happy to correct :)

 

private double CalculateBE(Position position)
        {
            // Breakeven is the entry price, plus proportional costs.
            double costFraction = (position.GrossProfit - position.NetProfit) / position.GrossProfit;

            double priceDistance;
            double bePriceLevel;

            if (position.TradeType == TradeType.Sell)
            {
                // Get the ask price, as you're trying to buy back
                priceDistance = Math.Abs(Ask - position.EntryPrice);
                bePriceLevel = position.EntryPrice - priceDistance * costFraction;
            }
            else
            {
                // Get the bid price as you're trying to sell back
                priceDistance = Math.Abs(Bid - position.EntryPrice);
                bePriceLevel = position.EntryPrice + priceDistance * costFraction;
            }

            return bePriceLevel;
        }

 

Made by fxtradersystems.com


@fxtradersystems

fxtradersystems
09 Oct 2020, 15:06

RE: Custom Indicator Loading from Daily CSV

fxtradersystems said:

Hi all,

Seems like a more efficient way to store information would be to initalise and load a key-value pair dictionary Dictionary<DateTime, double> such that you could search for the appropriate datetime amongst the keys, and return the double value for that index.

As we're using daily data, you could possibly get away with finding the date using:

DateTime currentDate = Bars.OpenTimes[index] - in the Calculate() method.

I am unsure as to whether this yet introduces a look-ahead bias (ie. it returns data from later that day, whereas it should return data from the day before); and it almost certainly won't be able to handle data not on a daily TF.

 

I whipped up some code for the idea here. Let me know if it works / any errors (particularly on the look-ahead bias), and I can update.

Warning: currently has to be stored exactly in the csv format: date;double (newline). @xabbu, if you are happy to send the CSV, I can tailor this for you.

 

using System;
using System.IO;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
using System.Globalization;

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class DailyCustomIndi : Indicator
    {
        [Parameter("Path to CSV:")]
        public string Path { get; set; }

        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }


        // Set up a dictionary to hold the dates and values
        Dictionary<DateTime, double> keyValuePairs = new Dictionary<DateTime, double>();
        int count;

        protected override void Initialize()
        {
            keyValuePairs = new Dictionary<DateTime, double>();
            count = 0;
            Print("keyValuePairs initialised");

            using (var reader = new StreamReader(Path))
            {
                Print("Streamer initialised");
                while (!reader.EndOfStream)
                {
                    // Use the reader to read in the lines
                    var line = reader.ReadLine();
                    var values = line.Split(';');

                    // Split out dates and values, and then convert them to datetime and double
                    string stringDate = values[0];
                    string stringIndi = values[1];

                    if (count != 0)
                    {
                        DateTime date = Convert.ToDateTime(stringDate, CultureInfo.InvariantCulture);
                        DateTime shortDate = CompactDate(date);
                        double doubleIndi = Double.Parse(stringIndi);

                        Print(shortDate.ToString() + ":" + doubleIndi.ToString());

                        // Add to dictionary
                        keyValuePairs.Add(shortDate, doubleIndi);
                    }
                    else
                    {
                        count = 1;
                    }

                }
                Print("Streamer finished");

            }
        }

        public override void Calculate(int index)
        {
            // Get the datetime of the current bar (at Index)
            DateTime indexDateTime = Bars.OpenTimes[index];
            DateTime shortIndexDate = CompactDate(indexDateTime);
            double indexResult;

            // Find the appropriate dateTime in the dictionary and then add to result:
            bool findSuccessful = keyValuePairs.TryGetValue(shortIndexDate, out indexResult);
            Print(shortIndexDate.ToString() + ": " + findSuccessful);

            if (findSuccessful)
            {
                Result[index] = indexResult;
            }
            else
            {
                Result[index] = double.NaN;
            }

        }

        public DateTime CompactDate(DateTime longDate)
        {
            DateTime shortDate = new DateTime(longDate.Year, longDate.Month, longDate.Day);
            return shortDate;
        }
    }
}

 

Hi all,

I updated this^ comment, so that this code now works.

> Changed access permissions to full so that it can access the csv (you can also use FileSystem).
> Added a function to cut down the DateTimes so that the Bars.OpenTimes and dictionary keys were in the same format.
> Added a count = 0 to avoid reading the csv titles as input data (hacky I know, but works).

To be clear: ^that comment now gives output from the csv snippet xabbu sent me.

Hope this is useful!

Cheers,

Sam (fxtradersystems.com)


@fxtradersystems

fxtradersystems
09 Oct 2020, 13:09

Custom Indicator Loading from Daily CSV

Hi all,

Seems like a more efficient way to store information would be to initalise and load a key-value pair dictionary Dictionary<DateTime, double> such that you could search for the appropriate datetime amongst the keys, and return the double value for that index.

As we're using daily data, you could possibly get away with finding the date using:

DateTime currentDate = Bars.OpenTimes[index] - in the Calculate() method.

I am unsure as to whether this yet introduces a look-ahead bias (ie. it returns data from later that day, whereas it should return data from the day before); and it almost certainly won't be able to handle data not on a daily TF.

 

I whipped up some code for the idea here. Let me know if it works / any errors (particularly on the look-ahead bias), and I can update.

Warning: currently has to be stored exactly in the csv format: date;double (newline). @xabbu, if you are happy to send the CSV, I can tailor this for you.

 

using System;
using System.IO;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
using System.Globalization;

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class DailyCustomIndi : Indicator
    {
        [Parameter("Path to CSV:")]
        public string Path { get; set; }

        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }


        // Set up a dictionary to hold the dates and values
        Dictionary<DateTime, double> keyValuePairs = new Dictionary<DateTime, double>();
        int count;

        protected override void Initialize()
        {
            keyValuePairs = new Dictionary<DateTime, double>();
            count = 0;
            Print("keyValuePairs initialised");

            using (var reader = new StreamReader(Path))
            {
                Print("Streamer initialised");
                while (!reader.EndOfStream)
                {
                    // Use the reader to read in the lines
                    var line = reader.ReadLine();
                    var values = line.Split(';');

                    // Split out dates and values, and then convert them to datetime and double
                    string stringDate = values[0];
                    string stringIndi = values[1];

                    if (count != 0)
                    {
                        DateTime date = Convert.ToDateTime(stringDate, CultureInfo.InvariantCulture);
                        DateTime shortDate = CompactDate(date);
                        double doubleIndi = Double.Parse(stringIndi);

                        Print(shortDate.ToString() + ":" + doubleIndi.ToString());

                        // Add to dictionary
                        keyValuePairs.Add(shortDate, doubleIndi);
                    }
                    else
                    {
                        count = 1;
                    }

                }
                Print("Streamer finished");

            }
        }

        public override void Calculate(int index)
        {
            // Get the datetime of the current bar (at Index)
            DateTime indexDateTime = Bars.OpenTimes[index];
            DateTime shortIndexDate = CompactDate(indexDateTime);
            double indexResult;

            // Find the appropriate dateTime in the dictionary and then add to result:
            bool findSuccessful = keyValuePairs.TryGetValue(shortIndexDate, out indexResult);
            Print(shortIndexDate.ToString() + ": " + findSuccessful);

            if (findSuccessful)
            {
                Result[index] = indexResult;
            }
            else
            {
                Result[index] = double.NaN;
            }

        }

        public DateTime CompactDate(DateTime longDate)
        {
            DateTime shortDate = new DateTime(longDate.Year, longDate.Month, longDate.Day);
            return shortDate;
        }
    }
}

 


@fxtradersystems

fxtradersystems
06 Oct 2020, 13:46

Break Even Price

jeex said:

Cerunnos, that's why i called in some help.

Somehow my math brain becomes blind for simple calculations. I'm completely lost. Maybe a short vacation will help.

double totalCosts = Symbol.Spread + (((position.GrossProfit - position.NetProfit) / position.Volume / Symbol.PipValue)*2);

 

The way I thought about it, was that the costs were fixed for the trade (now NetProfit includes both way commisions), but the profit fluctuated. You could therefore calculate the fixed cost as a proportionate distance of the Bid from the entry price.

My calculations look like:

// Calculate the distance of the trade, less the spread.
double distance = Bid - (position.EntryPrice + Symbol.Spread);
// Figure out how much the costs of the trade are versus the Gross profit.
double cost_fraction = (position.GrossProfit - position.NetProfit) / position.GrossProfit;
// The gross profit is spread out over the entire distance of the trade from the entry price
// therefore add this fraction of the distance on to the entry price.
double breakEven = position.EntryPrice + cost_fraction * distance;

// Equivalently for a sell position:
double distance = (position.EntryPrice - Symbol.Spread) - Bid;
double cost_fraction = (position.GrossProfit - position.NetProfit) / position.GrossProfit;
double breakEven = position.EntryPrice - cost_fraction * distance;

 


@fxtradersystems