Topics
05 Dec 2014, 00:00
 2644
 1
Replies

admin
07 Nov 2012, 11:03

Hello,

 

Thank you for the suggestion. We will think about implementing this in the future. For the time being we will do our best to help you in order to convert your code. You may ask all the questions necessary here as well as visit the API Reference page to see examples.

 

Best Regards

 


@admin

admin
07 Nov 2012, 10:51

Hello,

We are working hard to provide the most popular features and we can promise you that it is in our plans for implementation. You will not have to wait too long for it.

Best Regards

 


@admin

admin
07 Nov 2012, 10:35

Hello,

We will investigate but we need some information like what is the symbol you are testing, and which currency your account is in. The more information you can provide about the scenario by which you are receiving this will help.

Regards

 


@admin

admin
07 Nov 2012, 10:26

Hello,

 

Can you please clarify what you mean by "indicator appears" Is the problem when you build or when you add an instance to the chart?

We will investigate DirectionalMovementSystem as a referenced indicator in the meantime and the time it takes to build.

In the cases you describe above the code is identical, so what is it that differentiates one case from the other exactly?

 

Regards,

 


@admin

admin
07 Nov 2012, 10:00

Hello,

 

We will implement multitime frames soon and then you will be able to access properties of other symbols. Stay tuned!

 


@admin

admin
06 Nov 2012, 17:03

Hello,

 

Thank you for your suggestion. We understand the importance of this and we are taking it into serious consideration to add such a calculation in the backtesting environment. Most probably it will be added very soon.

 

 

 


@admin

admin
06 Nov 2012, 12:46

Hello,

 

The max drawdown is defined as the difference of the value at the peak before largest drop minus the lowest value before a new high divided by the value at the peak before largest drop.

So, a drawdown is established at a trough right before a new peak.

What you are describing is the percentage difference of the maximum value minus the minimum value.

We will have to think about implementing something like what you are describing but that will be somehing different that max drawdown.

 


@admin

admin
05 Nov 2012, 18:12

The max drawdown is calculated based on the following:

Max Drop of Long Consequtive Losing Trades after a winning trade(long or short)

((Balance after winning trade(long or short) - Balance after last loosing long trade)/Balance after winning trade(long or short) )*100

Max Drop of Short Consequtive Losing Trades after a winning trade(long or short)

((Balance after winning trade(long or short) - Balance after last loosing short trade)/Balance after winning trade(long or short) )*100

For example:

Number time Type Volume Commission S/L T/P Price Profit Balance
1 19.01.12 - 20:30 Buy 100000 6 1.53411 1.53411 1.45231 144 10144
2 19.01.12 - 20:31 Sell 100000 6 1.53411 1.53411 1.45231 -106 10038
3 19.01.12 - 20:32 Buy 100000 6 1.53411 1.53411 1.45231 -56 9982
4 19.01.12 - 20:33 Buy 100000 6 1.53411 1.53411 1.45231 -6 9976
5 19.02.12 - 20:30 Sell 100000 6 1.53411 1.53411 1.45231 344 10320
6 19.02.12 - 20:31 Buy 100000 6 1.53411 1.53411 1.45231 1494 11814
7 19.02.12 - 20:32 Buy 100000 6 1.53411 1.53411 1.45231 294 12108
8 19.03.12 - 20:30 Sell 100000 6 1.53411 1.53411 1.45231 -2006 10102
9 19.03.12 - 20:31 Sell 100000 6 1.53411 1.53411 1.45231 -156 9946
  Max Drop of Long Consequtive Losing Trades after a winning trade(long or short) Max Drop of Short Consequtive Losing Trades after a winning trade(long or short) Max Drop of all Consequtive Losing Trades after a winning trade(long or short)
Max DrawDown 1.66 17.86 17.86
Max. Drop of balance in % after a winning trade  ((10144 - 9976)/10144)*100 ((12108-9946)/12108)*100  

 

 

 


@admin

admin
05 Nov 2012, 17:33

The Sample Timer Display draws the countdown to the next bar on each tick in two formats on static positions on the chart. The first format is using the days and the second is using the total hours. It can be easily modified to other formats as well.

using System;
using cAlgo.API;

namespace cAlgo.Robots
{
    [Robot]
    public class Timer:Robot
    {
        protected override void OnTick()
        {
            //Latest index
            int index = MarketSeries.OpenTime.Count - 1;
            // Current Open Time
            DateTime currentOpenTime = MarketSeries.OpenTime[index];
            // Current timeframe e.g. 1 min, 1 hour, etc.
            TimeSpan difftime = MarketSeries.OpenTime[index] - MarketSeries.OpenTime[index - 1];
            // Next Open Time
            DateTime nextOpenTime = currentOpenTime + difftime;
            // Time left to next open time
            TimeSpan timeLeft = nextOpenTime - Server.Time;
            
            int days = Convert.ToInt32(timeLeft.TotalDays);            
            int hours = Convert.ToInt32(timeLeft.TotalHours % 24);
            string countDownDays = "Days:" + days.ToString("00") + ":" + hours.ToString("00") + ":" + timeLeft.Minutes.ToString("00") + ":" + timeLeft.Seconds.ToString("00");
            // Draw text for countdown to next bar in days
            ChartObjects.DrawText("TimerDays", countDownDays, StaticPosition.TopLeft, Colors.Lime);
            
            int totalHours = Convert.ToInt32(timeLeft.TotalHours); 
            string countDownHours = "Hours:" + totalHours.ToString("00") + ":" + timeLeft.Minutes.ToString("00") + ":" + timeLeft.Seconds.ToString("00");                               
            // Draw text for countdown to next bar in hours
            ChartObjects.DrawText("TimerHours", countDownHours, StaticPosition.TopRight, Colors.Lime);
        }
    }
}




@admin

admin
02 Nov 2012, 11:10

Thank you for the suggestion.  We will provide that option in the near future. Stay tuned!

 


@admin

admin
01 Nov 2012, 12:30

Hello,

 

In the event OnPositionOpened GrossProfit will be very small. You can test it with a print statement. 

        protected override void OnPositionOpened(Position openedPosition)

        {

            position = openedPosition;

            // Pending Order Filled

            pendingOrder = null;

            Print("GrossProfit = {0}", position.GrossProfit);

            if (position.GrossProfit < MaxLoss)

            {              

                Trade.Close(position);                

            }

        }

So, if you set GrossProfit to be sufficiently small then the condition will become true. You can add another print statement right before Trade.Close to verify that it executes.
 
 
 

@admin

admin
01 Nov 2012, 11:48

Correct.

 


@admin

admin
31 Oct 2012, 16:18

Hello,

 

We are testing your code but have been unsuccessful thus far in regenerating neither a technical error nor multiple positions.

In any case we are sending you a modified version of your code which might be a little more clear to read which includes reseting the pendingorder field to ensure that this robot creates exactly one position/pending order each time. 

 

        private Position position;

        private PendingOrder pendingOrder;

        private HistoricalVolatility _Hvol;

        private WilliamsPctR _Wp;

 

        // Initialize Indicators

        protected override void OnStart()

        {

            _Hvol = Indicators.HistoricalVolatility(Source, HVPeriod, HVBarhistory, HVD);

            _Wp = Indicators.WilliamsPctR(WprPeriod);

 

        }

        protected override void OnTick()

        {

            if (Trade.IsExecuting) return;

            ResetPendingOrder();

            double Hvol = _Hvol.Result.LastValue;

            double Wp = _Wp.Result.LastValue;

            double Time = Server.Time.Hour;

            bool isTradingTime = Time >= 2 && Time <= 23;

            bool isHighVolatility = Hvol >= 0.003 && Hvol <= 0.020;

         

            if (isTradingTime && isHighVolatility && position == null && pendingOrder == null)

            {

                double? stopLoss;

                DateTime? expiration = Server.Time.AddSeconds(20);

 

                if (Wp < -80)

                {

                    stopLoss = Symbol.Bid - Symbol.PipSize*StopLoss;

                    Trade.CreateBuyStopOrder(Symbol, Volume, Symbol.Bid, stopLoss, null, expiration);

                }

                else if (Wp > -20)

                {

                    stopLoss = Symbol.Ask + Symbol.PipSize*StopLoss;

                    Trade.CreateSellStopOrder(Symbol, Volume, Symbol.Ask, stopLoss, null, expiration);

                }

            }

            if (position == null) return;

            if (position.TradeType == TradeType.Sell)

            {

                double distance = position.EntryPrice - Symbol.Ask;

                if (distance > Trigger*Symbol.PipSize)

                {

                    double newStopLossPrice = Symbol.Ask + TrailingStop*Symbol.PipSize;

                    if (position.StopLoss == null || newStopLossPrice < position.StopLoss)

                    {

                        Trade.ModifyPosition(position, newStopLossPrice, position.TakeProfit);

                    }

                }

            }

            else

            {

                double distance = Symbol.Bid - position.EntryPrice;

                if (distance > Trigger*Symbol.PipSize)

                {

                    double newStopLossPrice = Symbol.Bid - TrailingStop*Symbol.PipSize;

                    if (position.StopLoss == null || newStopLossPrice > position.StopLoss)

                    {

                        Trade.ModifyPosition(position, newStopLossPrice, position.TakeProfit);

                    }

                }

            }

        }

 

        private void ResetPendingOrder()

        {

            bool exists = false;

            foreach (var accountPendingOrder in Account.PendingOrders)

            {

                if (pendingOrder.Equals(accountPendingOrder))

                {

                    exists = true;

                    break;

                }

            }

            if (!exists)

                pendingOrder = null;

        }

        protected override void OnPendingOrderCreated(PendingOrder newOrder)

        {

            pendingOrder = newOrder;

            bool isLargeSpread = Symbol.Spread > 2;

            bool isLargeBidDiff = (pendingOrder.TargetPrice - Symbol.Bid)*Symbol.PipSize > 2;

            bool isLargeAskDiff = (Symbol.Ask - pendingOrder.TargetPrice)*Symbol.PipSize > 2;

 

            if (position != null || isLargeSpread || isLargeBidDiff || isLargeAskDiff)

            {

                Trade.DeletePendingOrder(pendingOrder);

                pendingOrder = null;

            }

        }

        protected override void OnPositionOpened(Position openedPosition)

        {

            position = openedPosition;

            // Pending Order Filled

            pendingOrder = null;

 

            if (position.GrossProfit < MaxLoss)

            {

                Trade.Close(position);

            }

        }

        protected override void OnPositionClosed(Position closedPosition)

        {            

            position = null;

        }                

    }

}

 

 

 

 


@admin

admin
30 Oct 2012, 12:59

Hello,

 

MarketSeries.High.LastValue is the same as MarketSeries.High[MarketSeries.High.Count-1].

It referes to the last bar high price. The last bar keeps changing until it becomes the previous to the last bar. Therefore the last value of the high, the low, and the close will keep changing.

Now, it might happen that the close will equal the high if the price is rising.

 


@admin

admin
30 Oct 2012, 11:57

Hello,

Could you tell us the timeframe you are using as well as the exact input parameters?  This way we can investigate further.
I presume that when you say multiple orders you mean simultaneous opennings of positions, correct?

Also, when you say moving the stop loss are you refering to programmatically modifying the position? Why do you suspect it creates a technical error?
Do you get an error message in the log? What exactly happens?

 


@admin

admin
29 Oct 2012, 15:46

Hello,

 

Yes, you are correct. It is in our plans to add an Auto Start option in the drop down menu of each algorithm in the robots/indicators list. This option when selected will start the robots/indicators upon start up of cAlgo.

 


@admin

admin
29 Oct 2012, 10:31

Hello,

 

We are not getting any double orders backtesting your robot. Can you make sure this is the only robot you are running and let us know?

You do need to include this event handler as well:

        protected override void OnPositionClosed(Position closedPosition)

        {

            position = null;

        }

 
Regards

 

 


@admin

admin
26 Oct 2012, 13:12

If you mean prevent any new requests from the server if there is a current request like to modify or open a position, then you can use this statement:

if (Trade.IsExecuting) return; This will exit the method call each time until the server has responded and thus prevent any further requests from the server.

Otherwise can you give me an example of what you mean? 

 

 


@admin

admin
26 Oct 2012, 12:49

Hello Jose,

 

In order for your robot to continue execution it means that it will be running on cAlgo which is in turn running on a remote machine, like a VPS. 

If you are running the robot in cAlgo which is installed on your machine it is not possible.

 


@admin

admin
26 Oct 2012, 12:31

OK. The problem is that you don't set the pendingorder field, therefore it is always null and the condition if (pendingorder == null) is always true.

So, on each tick the OnTick() event is called and a new pending order is requested from the server.

This statement if (Trade.IsExecuting) return; means that if a request is send to the server and the server did not respond yet then exit the method OnTick(). But if the server did respond this condition (Trade.IsExecuting) is false and the program continues execution with the following statements.

That is why you need to check if there is an order/position as well like you do: if (pendingorder == null) .

But the field that holds the information for the order/position needs to be set, i.e.

In your case you need to set the field pendingorder in the method OnPendingOrderCreated:

protected override void OnPendingOrderCreated(PendingOrder newOrder)
{
pendingorder = newOrder;
}

Also, this condition is always false and the pending order never gets deleted:

             if (pendingorder != null && pendingorder.SymbolCode == Symbol.Code)

             {

                 if (...)

                 {

                     Trade.DeletePendingOrder(pendingorder);

                 }

             }

 

A few more points.

This method never gets called. What is the intended purpose of it?

        private void OpenPosition(TradeType command)

        {

            if (position != null)

            {

                Trade.Close(position);

                position = null;

            }

 

            Trade.CreateMarketOrder(command, Symbol, Volume);

        }

This method is also never called:
 
        private void ClosePosition(Position position)
        {
            if (position == null) return;
            Trade.Close(position);
 
        }
 
Since this statement if (position == null) return; will exit the method in case the position is null, there is no need then to check later if the position is not null:

if (position != null)

 

 
 
 
 
 

@admin