Topics
Replies
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
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
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);
}
}
@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, 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;
}
@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: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:
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);
}
if (position != null)
C# and .NET Programming - http://msdn.microsoft.com/en-us/library/orm-9780596521066-01-01.aspx
@admin
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