Replies

solark
02 Apr 2016, 00:05

RE: RE:

Sorry I tend to avoid C# and messed up on my on the fly translation, meant:

if ((Time - p.EntryTime).TotalMinutes >= 10.0) {
    //Over 10 minutes
}

 


@solark

solark
02 Apr 2016, 00:02

RE:

Either OnBar or OnTick (depends on your situtation) you'll want

if ((x.Robot.Time - p.EntryTime).TotalMinutes >= 10.0) {
    //Over 10 minutes
}

where `p` is your Position


@solark

solark
01 Apr 2016, 23:35 ( Updated at: 21 Dec 2023, 09:20 )

Pasting the snapshots apparently didn't work, using toolbar image insert:

 

Local

 

 

Remote:


@solark

solark
01 Apr 2016, 00:47

RE:

"if the close is like 5-10x lower than the high" 5-10x in relation to what? Don't you basically just want

(MarketSeries.High.Last(1) - MarketSeries.Close.Last(1)) / someThing > 5.0

then last bar is a 'bearish' candle? Or were you thinking of something else?


@solark

solark
29 Mar 2016, 00:23

Yes each point needs to have a unique ID in the context of the chart. Maybe just something like `"Label_Dot_" + count` where count is incremented everytime you draw an object. This may be what you're after.

...

        private double lastAverage = 0.0;
        private int count = 0;
...

        protected override void OnBar()
        {
            var positions = Positions.FindAll("label", Symbol);
            if(positions.Length > 0) {
                var avg = positions.Average(x => x.EntryPrice);
                ChartObjects.DrawLine("label_dot" + count.ToString(), MarketSeries.OpenTime.Last(1), lastAverage, MarketSeries.OpenTime.Last(0), avg, Colors.DarkGray, 2, LineStyle.Dots);
                lastAverage = avg;
                count++;
            }
            else {
                lastAverage = 0.0;
            }
                
        }

There will be a vertical line on entry, but you could work around that by checking if lastAverage is zero. This would be connected dotted lines, if you want dots you could just do shorten up the line and increase the thickness.


@solark

solark
28 Mar 2016, 23:18

Another "hacky" solution. Create a separate 'pause' cbot which simply modifies an environment variable (System.Environment). As long as this cbot is running a certain environment variable is set and when it's stopped the variable gets cleared. The main cbot could then determine it's pause/running state based off the environment variable. (pretty sure cbots run in their own appdomains and using the process environment variables should work fine, if not there's other ways).


@solark

solark
28 Mar 2016, 23:11

Maybe there's an "official" way but somehow I doubt it... The best solution would be to modify the code so that the Start/Stop button becomes the pause button. That is, make the bot's OnStart method lookup postions/orders using labels to continue from where it left off from. This is ideal since it puts you in a good spot for cases where you're forced to restart your bot. The down side is if you have a long startup time it may not be feasible.

The next best solution (imo) requires some general programming skills. Not to go to far in depth but ideally you'd create a separate program for the bots UI (pause button and other real-time settings) that would communicate with the actual cbot using standard inter-process methods (mutexes, named pipes, sockets, etc).

Another possibility (not recommended) have the actual cbot generate some ui OnStart. This is most likely not worth it, could effect the stability of cAlgo as a whole.

Quick hack solution would be to use "System.IO.File.Exists" to check for the presence of a dummy file which would represent whether the cbot should be paused or not. Generating/deleting the file could be done by a simple batch file you can run. If a shortcut to these batch files are placed on the desktop you can (right click shortcut, properties) assign an arbitrary hotkey to both of them. Then you would just hit your defined hotkeys to pause/resume the bot.

 

 


@solark

solark
28 Mar 2016, 22:36

RE:

The accessibility modified "private" in

private double SL;

doesn't make sense in this context. It makes sense when defining methods/properties/fields ('top level' definitions like 'LiczStopLoss'), not in the case of local variables (as in this case).

 

mardahl said:

I've found my error - i had to change the type of all variables from double to var.
I still don't know why is it so - it shouldn't compile either (but it does).


@solark

solark
28 Mar 2016, 21:55

Did you know if you flip a coin 100 times there's a ~0.80 chance of 5 consecutive heads? Or that if you could fold a piece of paper 42 times it would reach from the earth to the moon? Anyway, though I avoid this approach to risk/money management,  I'm not gonna assume you don't know the risks involved in martingale 'betting' and hopefully provide some help.
 

Simplest thing is to change where it's currently submitting an order to modifying some state variables, then use the state variables "OnBar" to decide on if and what order to submit. This is untested but the general idea:

 

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SampleMartingalecBot : Robot
    {
        [Parameter("Initial Quantity (Lots)", DefaultValue = 1, MinValue = 0.01, Step = 0.01)]
        public double InitialQuantity { get; set; }

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

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

        private Random random = new Random();
        private double tradeQuantity;
        private TradeType currentTradeType;
        private bool shouldEnter;

        protected override void OnStart()
        {
            Positions.Closed += OnPositionsClosed;
            currentTradeType = GetRandomTradeType();
            tradeQuantity = InitialQuantity;
            shouldEnter = true;
            //ExecuteOrder(InitialQuantity, currentTradeType);
        }

        protected override void OnBar()
        {
            if (shouldEnter)
            {
                shouldEnter = false;
                ExecuteOrder(tradeQuantity, currentTradeType);
            }
        }
        private void ExecuteOrder(double quantity, TradeType tradeType)
        {
            var volumeInUnits = Symbol.QuantityToVolume(quantity);
            var result = ExecuteMarketOrder(tradeType, Symbol, volumeInUnits, "Martingale", StopLoss, TakeProfit);

            if (result.Error == ErrorCode.NoMoney)
                Stop();
        }

        private void OnPositionsClosed(PositionClosedEventArgs args)
        {
            Print("Closed");
            var position = args.Position;

            if (position.Label != "Martingale" || position.SymbolCode != Symbol.Code)
                return;

            if (position.GrossProfit > 0)
            {
                shouldEnter = true;
                tradeQuantity = InitialQuantity;
                currentTradeType = GetRandomTradeType();
                //ExecuteOrder(InitialQuantity, GetRandomTradeType());
            }
            else
            {
                shouldEnter = true;
                tradeQuantity = position.Quantity * 2;
                currentTradeType = position.TradeType;
                //ExecuteOrder(position.Quantity * 2, position.TradeType);
            }
        }

        private TradeType GetRandomTradeType()
        {
            return random.Next(2) == 0 ? TradeType.Buy : TradeType.Sell;
        }
    }
}

 


@solark

solark
28 Mar 2016, 21:27

Try to run what you have and flip over to the "Log" tab. You should see that an exception is being thrown....

 

The condition

shortPosition == null && longPosition == null

guarantees that 'position' as defined within the if block as

Position position = Positions.Find(label, Symbol, TradeType.Sell);

will be null. As such 'position.NetProfit' will throw an exception.


@solark