Topics

Forum Topics not found

Replies

srubtsov
26 Feb 2020, 12:11

RE:

barancansahin88 said:

Senkou span A and senkou span b values are always same in my program, I couldnt fix the problem. How can i have true values of senkou span a and b?

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SampleSARTrailingStop : Robot
    {
        //Ichimoku Settings - NOT BE BE CHANGED UNLESS YOU KNOW WHAT YOU ARE DOING
        [Parameter(DefaultValue = 9)]
        private int tenkansen { get; set; }
        [Parameter(DefaultValue = 26)]
        private int kijunsen { get; set; }
        [Parameter(DefaultValue = 52)]
        private int senb { get; set; }
        public IndicatorDataSeries SenkouSpanB { get; set; }
        public IndicatorDataSeries SenkouSpanA { get; set; }


        IchimokuKinkoHyo ichimoku;


        protected override void OnStart()
        {
            ichimoku = Indicators.IchimokuKinkoHyo(tenkansen, kijunsen, senb);

        }

        protected override void OnBar()
        {
            var index = Bars.ClosePrices.Count;
            if (ichimoku.SenkouSpanB[index - 26] > Symbol.Ask && ichimoku.SenkouSpanB[index - 26] > Symbol.Ask)
            {
               
                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, 10000, "sat");
                
            }
            else if (ichimoku.SenkouSpanA[index - 26] < Symbol.Ask && ichimoku.SenkouSpanA[index - 26] < Symbol.Ask)
            {

                {
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, 10000, "al");
                    Print("SenkouSpanA Value = {0}", ichimoku.SenkouSpanA[index - 26]);
                    Print("SenkouSpanB Value = {0}", ichimoku.SenkouSpanB[index - 26]);
                    Print("ChikouSpan Value = {0}", ichimoku.ChikouSpan.LastValue);
                    Print("KijunSen Value = {0}", ichimoku.KijunSen.LastValue);
                }
            }
        }
    }
}

The problem is in private properties. Parameters can't be with `private` access modifier, it should be with `public`. So default value isn't applied to properties and they all contain zero value.


@srubtsov

srubtsov
21 Feb 2020, 15:30

Also possible to use method to get only symbol settings without any "live" data

var symbolInfo = Symbols.GetSymbolInfo("AUDDKK.spa");
if (symbolInfo != null)
    Print(string.Format("{0}, PipValue: {1}", symbolInfo.Name, symbolInfo.PipValue.ToString("F" + symbolInfo.Digits)));

@srubtsov

srubtsov
21 Feb 2020, 14:42

Which other indicators do you have on the chart?


@srubtsov

srubtsov
21 Feb 2020, 12:15

Use the exact time to get today's bar is not so good way, because a bar can be not created yet, bar creates exactly after the first tick in the bar. So the best way here to use BarOpened event.

protected override void OnStart()
{
    Bars eurgbpDailyBars = MarketData.GetBars(TimeFrame.Daily, "EURGBP");
    eurgbpDailyBars.BarOpened += OnEurgbpDailyBarOpened;
}

private void OnEurgbpDailyBarOpened(BarOpenedEventArgs args)
{
    Print("HighPrices.Last(1): " + args.Bars.HighPrices.Last(1));
}

 

 

@srubtsov

srubtsov
26 Nov 2019, 17:13

RE: RE: RE:

alex_mihail said:

Not text - I want to draw a shape ("X" for example) on the candlestick when the price crosses over Hull MA.

Maybe this will help you

Chart.DrawIcon("uniqueIconName", ChartIconType.Star, barIndex, yPrice, Color.White);

@srubtsov

srubtsov
19 Nov 2019, 14:58

RE: RE:

douglascvas said:

You mean "MarketSeries.Close.Count - 2"? The same happens.

What exactly do you mean? H1 bars are ok, but H4 bars aren't ok, right? There is the same reason. The cBot with previous last index uses completed H1 bars and non-completed H4 bars. But indicator on backtesting chart uses completed H1 and H4 bars. An indicator referenced in a cBot should work properly.


@srubtsov

srubtsov
11 Nov 2019, 14:24

At first look, in the cBot you call it only once at the beginning of a bar. So you have the close value with which bar started. The indicator takes completed bars in that case.


@srubtsov

srubtsov
08 Nov 2019, 10:36

Is there any way to instruct cAlgo to open VS 2017 instead of the broken 2015?

You just need to install the extension on VS 2017 `cBots and Custom Indicators` (VS -> Extensions -> Manage Extensions) or from here https://marketplace.visualstudio.com/items?itemName=Spotwareextensions.cBotsandCustomIndicators


@srubtsov

srubtsov
07 Nov 2019, 10:04

Usually, margin calculates for USD volume. Also usually symbol has dynamic leverage.


@srubtsov

srubtsov
07 Nov 2019, 09:41

depthOfMarket.AskEntries.Count

seem to be equal to zero so I can't obtain a ticker.

This is true only for the situation actually after creating. Next MarketOfDepth events should return valid values.

 

Also, for symbol ticker is more convenient to use `Symbol.Tick` event

var symbol = Symbols.GetSymbol("EURUSD");
symbol.Tick += symbolTickEventArgs => Print(string.Format("Bid: {0}, Ask: {1}, Symbol object: {2}", symbolTickEventArgs.Bid, symbolTickEventArgs.Ask, symbolTickEventArgs.Symbol));

@srubtsov

srubtsov
28 Oct 2019, 10:42

I see you use .NET Timers in that code. It's can be a source of the problem, because of cTrader doesn't guarantee successful work with multi-thread. You can find more info on that topic: https://ctrader.com/forum/cbot-support/22079


@srubtsov

srubtsov
28 Oct 2019, 10:24

lastvalue tick volume can also can also run into new bar.

Could you describe it with more details? Maybe with logs.


@srubtsov

srubtsov
25 Oct 2019, 16:18

Hi,

I don't understand exactly what do you want. But I think a time-based algorithm, not a good idea. For example, you don't have a guarantee about `OnBar` calls exactly at the start of the minute. m1 `OnBar` calls after the first bid changing in the new minute.


@srubtsov

srubtsov
25 Oct 2019, 16:08

Hi @FireMyst

You are right, indicators in cBots are lazy, they calculate only when you ask for any of output series.

Answers below for "good" indicator where all output series calculate inside `Calculate` method. If indicator has "strange" implementation, we have "strange" results.

Answer #1:

Calling any output series of indicator by any index will call `Calculate` method from the last calculated index to the last index of MarketSeries. And it updates all output series because of them calculates in `Calculate` method.

Answer #2:

Calling `Indicator.Calculate(MarketSeries.Close.Count - 1)` will calculate only that index. It is a bad practice, look at the method `Indicator.Calculate` like on private method. So those examples don't equivalent, but both first lines don't need here.


@srubtsov

srubtsov
21 Oct 2019, 10:28

RE:

FireMyst said:

Thank you @srubtsov for your explanation.

Your suggestion #2 has worked for me without any issues thus far.

The only limitation I can see with #2, given that the cTrader Timer implementation is an "interface", is you can't declare and have multiple distinct Timer objects within a cBot?

Yes, you are right, you can't create additional Timer instances and should use Timer property. But I think it possible to create improved timer based on Algo.Timer with some hack.


@srubtsov

srubtsov
18 Oct 2019, 10:36

It happens because .NET timers (System.Timers.Timer, System.Threading) use and create additional threads and cBot/Indicator can't guarantee successful interaction, not from the main thread with cTrader (drawing, printing log for example).

So, that problem possible to solve with two ways:

1. Use method `BeginInvokeOnMainThread(Action action)` - it synchronizes and executes action in main thread

private void CountDownTimerEvent(Object source, System.Timers.ElapsedEventArgs e)
{
    BeginInvokeOnMainThread(() =>
    {
        DateTime dt = Server.Time;
        Print("CDTE01: Server's Time: \"{0}\"", dt.ToString("HH:mm:ss"));
        Chart.DrawStaticText("staticText", "Server Time: " + dt.ToString("HH:mm:ss"), VerticalAlignment.Top,
            HorizontalAlignment.Right, Color.Goldenrod);
    });
}

2. Use timer from cAlgo.API. It's the best way because of that timer successfully works in backtesting.

protected override void OnStart()
{
    Timer.TimerTick += CountDownTimerEvent;
    var intervalInSeconds = 1;
    Timer.Start(intervalInSeconds);
}

private void CountDownTimerEvent()
{
    DateTime dt = Server.Time;
    Print("CDTE01: Server's Time: \"{0}\"", dt.ToString("HH:mm:ss"));
    Chart.DrawStaticText("staticText", "Server Time: " + dt.ToString("HH:mm:ss"), VerticalAlignment.Top,
        HorizontalAlignment.Right, Color.Goldenrod);
}

 


@srubtsov

srubtsov
31 Aug 2019, 15:45

Adding that code to the end of AssemblyInfo.cs of a class library project should help you

#if DEBUG
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations)]
#endif

@srubtsov

srubtsov
26 Aug 2019, 12:38

RE: RE:

FireMyst said:

I'll do you one better. Here's the source code needed to reproduce this issue. Details on what to do are in the comments.

Screen capture below too from Visual Studio showing the the breakpoints, and that it goes into the code block that the position's stoploss is zero immediately after fulfilling the order with a 1.2 pip SL.

What's happening to cause this?

Thank you.

In that case in backtesting problem is stop loss pips is less than spread. Spread is 1.6, StopLossPips is 1.2. Empty StopLoss for that is ok.

That is not so clear, currently in that case `TradeResult.IsSuccessful = true; TradeResult.ErrorCode = null`. In future versions it will be more clear, `ErrorCode` won't be null.


@srubtsov

srubtsov
26 Aug 2019, 10:34

I didn't understand exactly your question. But you can use `TradeType` as a parameter:

[Parameter]
public TradeType TradeType { get; set; }

 

Also, you shouldn't implement trailing stop loss, you can use it from cAlgo.API:

In a moment of creating an order with special parameter:

ExecuteMarketOrder(TradeType.Buy, SymbolName, Symbol.VolumeInUnitsMin, _robotLabel, stopLossPips, takeProfitPips, comment: null, hasTrailingStop: true);

Or modify an existing position (those methods won't work with null stop loss):

ModifyPosition(position, stopLossPips, takeProfitPips, true);
//or
position.ModifyTrailingStop(true);

 


@srubtsov

srubtsov
23 Aug 2019, 15:35

Hi,

It happens because of an indicator in a cBot doesn't create `IndicatorArea`. Create an indicator in a cBot doesn't equal to add indicator on the chart. You have several ways to solve the problem, for example: Check `IndicatorArea` on null and doesn't draw anything. Or if possible to use `Chart` use method:

private ChartArea GetChartArea()
{
    if (IndicatorArea == null) return Chart;
    return IndicatorArea;
}

 


@srubtsov