Topics
Replies
admin
11 Oct 2012, 15:48
Calculate() is triggered for each new bar, so I don't think you need to force recalculation. You can test with a print statement.
Let me know if the code below is what you are looking for.
using System; using cAlgo.API; using cAlgo.API.Indicators; namespace cAlgo.Indicators { [Indicator(IsOverlay = true)] public class SupportResistance : Indicator { [Output("Resist", Color = Colors.Blue)] public IndicatorDataSeries LineResist { get; set; } [Output("Support", Color = Colors.LightBlue)] public IndicatorDataSeries LineSupport { get; set; } [Parameter("Shift", DefaultValue = 0)] public int Shift { get; set; } public int[] TrendMinor = new int[1]; //1 = Bullish ^ -1 = Bearish v public int[] TrendMajor = new int[1]; public override void Calculate(int index) { Array.Resize(ref TrendMinor, TrendMinor.Length + 1); Array.Resize(ref TrendMajor, TrendMajor.Length + 1); if (index < Shift + 1) { TrendMajor[index] = 1; TrendMinor[index] = 1; LineResist[index] = MarketSeries.High[index]; LineSupport[index] = MarketSeries.Low[index]; return; } LineResist[index - Shift] = LineResist[index - Shift - 1]; LineSupport[index - Shift] = LineSupport[index - Shift - 1]; //+------------------------------------------------------------------+ // MAJOR TREND REVERSAL CALCULATION //+------------------------------------------------------------------+ if (TrendMajor[index - Shift - 1] == 1 && MarketSeries.Low[index - Shift] < LineSupport[index - Shift]) { TrendMajor[index - Shift] = -1; TrendMinor[index - Shift] = -1; } else if (TrendMajor[index - Shift - 1] == -1 && MarketSeries.High[index - Shift] > LineResist[index - Shift]) { TrendMajor[index - Shift] = 1; TrendMinor[index - Shift] = 1; } else { TrendMajor[index - Shift] = TrendMajor[index - Shift - 1]; TrendMinor[index - Shift] = TrendMinor[index - Shift - 1]; } //+------------------------------------------------------------------+ // Find Signals //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ // MAJOR BULLISH TREND //+------------------------------------------------------------------+ if (TrendMajor[index - Shift] == 1) { //--- Bullish TrendMinor if (TrendMinor[index - Shift] == 1) { if (MarketSeries.High[index - Shift] < MarketSeries.High[index - Shift - 1]) { //--- End of bullish TrendMinor if (MarketSeries.High[index - Shift - 1] > LineResist[index - Shift - 1]) { LineResist[index - Shift] = MarketSeries.High[index - Shift - 1]; } TrendMinor[index - Shift] = -1; } } else //--- Bearish TrendMinor { if (MarketSeries.Low[index - Shift] > MarketSeries.Low[index - Shift - 1]) { //--- End of bearish TrendMinor if (MarketSeries.Low[index - Shift - 1] > LineSupport[index - Shift - 1]) { LineSupport[index - Shift] = MarketSeries.Low[index - Shift - 1]; } TrendMinor[index - Shift] = 1; } } } //+------------------------------------------------------------------+ // MAJOR BEARISH TREND //+------------------------------------------------------------------+ else { //--- Bearish TrendMinor if (TrendMinor[index - Shift] == -1) { if (MarketSeries.Low[index - Shift] > MarketSeries.Low[index - Shift - 1]) { //--- End of bullish TrendMinor if (MarketSeries.Low[index - Shift - 1] < LineSupport[index - Shift - 1]) { LineSupport[index - Shift] = MarketSeries.Low[index - Shift - 1]; } TrendMinor[index - Shift] = 1; } } else //--- Bullish TrendMinor { if (MarketSeries.High[index - Shift] < MarketSeries.High[index - Shift - 1]) { //--- End of bullish TrendMinor if (MarketSeries.High[index - Shift - 1] < LineResist[index - Shift - 1]) { LineResist[index - Shift] = MarketSeries.High[index - Shift - 1]; } TrendMinor[index - Shift] = -1; } } } } } }
@admin
admin
09 Oct 2012, 17:12
Yes you should initialize LineResist and LineSupport with some values and then return.
So,
public override void Calculate(int i) { if(i < Shift+1) { LineResist[i] = someValue; LineSupport[i] = someValue; return; } LineResist[i - Shift] = LineResist[i - Shift - 1]; LineSupport[i - Shift] = LineSupport[i - Shift - 1]; // etc. }
Consider uploading it to the indicators list
@admin
admin
09 Oct 2012, 16:44
Hello tradermatrix,
You are correct the previous code logic does not match your strategy with the two robots.
Try changing this method:
protected override void OnPositionClosed(Position closedPosition) { if (closedPosition.GrossProfit > 0) { ExecuteOrder(InitialVolume, closedPosition.TradeType); } else { ExecuteOrder((int)closedPosition.Volume * 2, closedPosition.TradeType); } }
@admin
admin
09 Oct 2012, 12:00
( Updated at: 23 Jan 2024, 13:11 )
Hello,
For modifying Pending Orders please visit: [/docs/reference/calgo/api/internals/itrade/modifypendingorder]
As far as the previous question for the Account and the Symbol, it is not very clear. Please try to be more specific. Are you getting a compiler error or runtime error or are you expecting the intellisense to automatically input those?
If you press a key then the dropdown list produced does contain Account as well as Symbol.
For Symbol please see: [/docs/reference/calgo/api/internals/symbol]
For Account please see:[/docs/reference/calgo/api/internals/iaccount]
Please let us know if this helps.
@admin
admin
09 Oct 2012, 11:38
You should be able to accomplish the same by just calling ExecuteOrder with the InitialVolume.
if (closedPosition.GrossProfit > 0) { ExecuteOrder(InitialVolume, GetTradeCommand()); } else if (_consecutiveLosses < consecutiveLosses) { ExecuteOrder((int)_position.Volume * 2, GetTradeCommand()); } else { ExecuteOrder(InitialVolume, GetTradeCommand()); }
@admin
admin
08 Oct 2012, 18:19
From what I understand from your code, one robot is selling and the other is buying, other than that the robots are identical.
Both robots execute trades according to this statement:
if the previously closed position generated profit execute the same trade with the initial volume, otherwise double the volume of the previous trade.
Is this what you are trying to accomplish? If not then please write a small description of your logic.
If this is indeed what you need then the only solution I can provide is that you just create two trades one buy and one sell each time:
i.e.
protected override void OnPositionClosed(Position closedPosition) { if (closedPosition.GrossProfit > 0) { ExecuteOrder(InitialVolume, TradeType.Buy); ExecuteOrder(InitialVolume, TradeType.Sell); } else { ExecuteOrder((int) position.Volume*2, position.TradeType); } }
@admin
admin
08 Oct 2012, 17:51
On Line 33:
private _consecutiveLosses
this is not a proper definition because it is missing the type (i.e. int)
Fix to:
private int _consecutiveLosses;
Line 92:
Stop() // missing semicolon
Fix to:
Stop();
Logical error on Line 73:
else if (closedPosition.GrossProfit > 0) { _consecutiveLosses = 0; } else if (closedPosition.GrossProfit > 0) { ExecuteOrder(InitialVolume, GetTradeCommand()); }
Please make sure you understand the meaning of an if-else statement:
if(conditionA) { // conditionA is true // if conditionA is not true execution of the program will not reach this line } else if(conditionB) { // this means conditionA is not true and conditionB is true // if conditionA is true or conditionB is not true execution of the program will not reach this line } else { // this means that neither conditionA is true nor conditionB is true // if conditionA or conditionB is true execution of the program will not reach this line }
If you need more help understanding if-else statements please refer to this article: http://msdn.microsoft.com/en-us/library/5011f09h.aspx
Alternatively, you may Google search if-else statements, there are ample examples online.
You may also post a description of what you are trying to accomplish with the if-else statement here.
@admin
admin
08 Oct 2012, 16:24
( Updated at: 21 Dec 2023, 09:20 )
The difference between double and double? is that "double" is a non nullable type whereas "double?" is a nullable type.
In other words, you cannot define a variable of type double like this:
double stoploss = null; // Compiler error
As far as stop loss and take profit are concerned, you could initialize it the value 0 and it would be fine as far as the compiler is concerned but if you forget to set it to a value other than zero before using it then it will produce a warning.
The proper way would be to define it as nullable, i.e.
double? stoploss = null;
Then if you wish to set the stop loss/ take profit parameters, you may do so, otherwise you should leave them as null or pass in the null value to the function that expects them. For instance, you may wish to set the take profit parameter but not the stop loss:
Trade.ModifyPosition(openedPosition, null, TakeProfit);
For more information on c# nullable types visit : http://msdn.microsoft.com/en-us/library/vstudio/1t3y8s4s.aspx
@admin
admin
08 Oct 2012, 15:32
Hello,
There is no internal method for counting consecutive losses but you may code one similar to this post: /forum/calgo-reference-samples/62
Let us know if this helped.
@admin
admin
08 Oct 2012, 15:29
UPDATED
This code is to identify the number of consecutive winning/losing trades.
//... private int _consecutiveLosses; private int _consecutiveWins; protected override void OnStart() { Positions.Closed += PositionsOnClosed; } //... private void PositionsOnClosed(PositionClosedEventArgs obj) { Position closedPosition = obj.Position; Print("position closed with {0} gross profit", closedPosition.GrossProfit); if (closedPosition.NetProfit <= 0) { _consecutiveWins = 0; _consecutiveLosses++; } else { _consecutiveLosses = 0; _consecutiveWins++; } Print("Position ID {0}", closedPosition.Id); Print("Consecutive Loses {0}", _consecutiveLosses); Print("Consecutive Wins {0}", _consecutiveWins); }
@admin
admin
08 Oct 2012, 11:47
Just in case here are the answers.
For the first post - Sample Martingale Robot modification to use Moving Average IsRising/IsFalling look at the following code:
using cAlgo.API; using cAlgo.API.Indicators; namespace cAlgo.Robots { [Robot] public class MartingaleMA : Robot { [Parameter("Initial Volume", DefaultValue = 10000, MinValue = 0)] public int InitialVolume { get; set; } [Parameter("Stop Loss", DefaultValue = 40, MinValue = 0)] public int StopLoss { get; set; } [Parameter("Take Profit", DefaultValue = 40, MinValue = 0)] public int TakeProfit { get; set; } [Parameter("Source")] public DataSeries Source { get; set; } [Parameter("Period", DefaultValue = 14, MinValue = 1)] public int Period { get; set; } [Parameter("Moving Average Type", DefaultValue = MovingAverageType.Simple)] public MovingAverageType MovingAverageType { get; set; } private Position _position; private MovingAverage _movingAverage; protected override void OnStart() { _movingAverage = Indicators.MovingAverage(Source, Period, MovingAverageType); ExecuteOrder(InitialVolume, GetTradeCommand()); } private void ExecuteOrder(int volume, TradeType tradeType) { Trade.CreateMarketOrder(tradeType, Symbol, volume); } protected override void OnPositionOpened(Position openedPosition) { _position = openedPosition; Trade.ModifyPosition(openedPosition, GetAbsoluteStopLoss(openedPosition, StopLoss), GetAbsoluteTakeProfit(openedPosition, TakeProfit)); } private double GetAbsoluteStopLoss(Position pos, int stopLossInPips) { return pos.TradeType == TradeType.Buy ? pos.EntryPrice - Symbol.PipSize * stopLossInPips : pos.EntryPrice + Symbol.PipSize * stopLossInPips; } private double GetAbsoluteTakeProfit(Position pos, int takeProfitInPips) { return pos.TradeType == TradeType.Buy ? pos.EntryPrice + Symbol.PipSize * takeProfitInPips : pos.EntryPrice - Symbol.PipSize * takeProfitInPips; } protected override void OnPositionClosed(Position closedPosition) { if (closedPosition.GrossProfit > 0) { ExecuteOrder(InitialVolume, GetTradeCommand()); } else { ExecuteOrder((int)_position.Volume * 2, _position.TradeType); } } private TradeType GetTradeCommand() { if (_movingAverage.Result.IsRising()) return TradeType.Buy; if (_movingAverage.Result.IsFalling()) return TradeType.Sell; return _position.TradeType; } protected override void OnError(Error error) { if (error.Code == ErrorCode.BadVolume) Stop(); } } }
For the second post, the TradeCommand() method returns TradeType, therefore:
private TradeType TradeCommand() { var lastIndex = MarketSeries.Close.Count - 1; double close = MarketSeries.Close[lastIndex - 1]; double lastClose = MarketSeries.Close[lastIndex - 2]; return close > lastClose ? TradeType.Buy : TradeType.Sell; }
And finally,
the semicolon at the end of the if-statement is producing the error, so remove the semicolon:
else if (closedPosition.TradeType == TradeType.Buy);
@admin
admin
08 Oct 2012, 09:39
( Updated at: 23 Jan 2024, 13:11 )
The total number of orders for the account is accessible via:
int totalActive = Account.Positions.Count; int totalPending = Account.PendingOrders.Count;
In order to manipulate orders in general you need to access them separately, for instance:
You will need two separate loops:
int totalat = 0; string symbol = "EURUSD"; foreach (var position in Account.Positions) { // position.SymbolCode is equal to the symbol parameter you choose when you run the robot. if (position.SymbolCode == symbol) totalat++; } foreach (var pendingOrder in Account.PendingOrders) { // pendingOrder.SymbolCode is equal to the symbol parameter you choose when you run the robot. if (pendingOrder.SymbolCode == symbol) totalat++; }
You can read more about pending orders here:
Pending orders: [/docs/reference/calgo/api/pendingorder]
You may also like to see a sample to create and manipulate multiple positions here.
@admin
admin
05 Oct 2012, 19:56
UPDATED
This code is a reference to handling multiple positions. This robot is intended to be used as an example and does not guarantee any particular outcome or profit of any kind.
using cAlgo.API; using cAlgo.API.Indicators; namespace cAlgo.Robots { [Robot] public class SampleMultiplePositions : Robot { private MovingAverage _fastMa; private MovingAverage _slowMa; [Parameter(DefaultValue = "Sample cBot")] public string cBotLabel { get; set; } [Parameter] public DataSeries SourceSeries { get; set; } [Parameter("MA Type")] public MovingAverageType MAType { get; set; } [Parameter("Slow Periods", DefaultValue = 10)] public int SlowPeriods { get; set; } [Parameter("Fast Periods", DefaultValue = 5)] public int FastPeriods { get; set; } [Parameter(DefaultValue = 100000)] public int Volume { get; set; } [Parameter("Stop Loss (pips)", DefaultValue = 100)] public int StopLoss { get; set; } [Parameter("Take Profit (pips)", DefaultValue = 100)] public int TakeProfit { get; set; } [Parameter("Trigger (pips)", DefaultValue = 10)] public int Trigger { get; set; } [Parameter("Trailing Stop (pips)", DefaultValue = 10)] public int TrailingStop { get; set; } [Parameter("MinBalance", DefaultValue = 5000)] public double MinBalance { get; set; } [Parameter("MinLoss", DefaultValue = -200.0)] public double MinLoss { get; set; } [Parameter(DefaultValue = 3)] public int MaxPositions { get; set; } protected override void OnStart() { _fastMa = Indicators.MovingAverage(SourceSeries, FastPeriods, MAType); _slowMa = Indicators.MovingAverage(SourceSeries, SlowPeriods, MAType); Positions.Opened += PositionsOnOpened; Positions.Closed += PositionsOnClosed; } protected override void OnBar() { var cBotPositions = Positions.FindAll(cBotLabel); if (cBotPositions.Length > MaxPositions) return; var currentSlowMa = _slowMa.Result.Last(0); var currentFastMa = _fastMa.Result.Last(0); var previousSlowMa = _slowMa.Result.Last(1); var previousFastMa = _fastMa.Result.Last(1); // Condition to Buy if (previousSlowMa > previousFastMa && currentSlowMa <= currentFastMa) ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, cBotLabel, StopLoss, TakeProfit); else if (previousSlowMa < previousFastMa && currentSlowMa >= currentFastMa) ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, cBotLabel, StopLoss, TakeProfit); // Some condition to close all positions if (Account.Balance < MinBalance) foreach (var position in cBotPositions) ClosePosition(position); // Some condition to close one position foreach (var position in cBotPositions) if (position.GrossProfit < MinLoss) ClosePosition(position); // Trailing Stop for all positions SetTrailingStop(); } private void PositionsOnOpened(PositionOpenedEventArgs obj) { Position openedPosition = obj.Position; if (openedPosition.Label != cBotLabel) return; Print("position opened at {0}", openedPosition.EntryPrice); } private void PositionsOnClosed(PositionClosedEventArgs obj) { Position closedPosition = obj.Position; if (closedPosition.Label != cBotLabel) return; Print("position closed with {0} gross profit", closedPosition.GrossProfit); } /// <summary> /// When the profit in pips is above or equal to Trigger the stop loss will start trailing the spot price. /// TrailingStop defines the number of pips the Stop Loss trails the spot price by. /// If Trigger is 0 trailing will begin immediately. /// </summary> private void SetTrailingStop() { var sellPositions = Positions.FindAll(cBotLabel, Symbol, TradeType.Sell); foreach (Position position in sellPositions) { double distance = position.EntryPrice - Symbol.Ask; if (distance < Trigger*Symbol.PipSize) continue; double newStopLossPrice = Symbol.Ask + TrailingStop*Symbol.PipSize; if (position.StopLoss == null || newStopLossPrice < position.StopLoss) ModifyPosition(position, newStopLossPrice, position.TakeProfit); } var buyPositions = Positions.FindAll(cBotLabel, Symbol, TradeType.Buy); foreach (Position position in buyPositions) { double distance = Symbol.Bid - position.EntryPrice; if (distance < Trigger*Symbol.PipSize) continue; double newStopLossPrice = Symbol.Bid - TrailingStop*Symbol.PipSize; if (position.StopLoss == null || newStopLossPrice > position.StopLoss) ModifyPosition(position, newStopLossPrice, position.TakeProfit); } } } }
@admin
admin
05 Oct 2012, 16:52
Hello,
You may code trailing stops in cAlgo. Please see Sample Buy Trailing and Sample Sell Trailing Robots in cAlgo as examples to code trailing stops.
You may also find the code here: /forum/calgo-reference-samples/55
Manual Trailing stops for cTrader is comming soon.
@admin
admin
05 Oct 2012, 16:48
Hello,
You may code trailing stops in cAlgo. Please see Sample Buy Trailing and Sample Sell Trailing Robots in cAlgo as examples to code trailing stops.
You may also find the code here: /forum/calgo-reference-samples/55
Manual Trailing stops for cTrader is comming soon.
@admin
admin
05 Oct 2012, 16:46
UPDATED
This robot is intended to be used as a sample and does not guarantee any particular outcome or profit of any kind. Use it at your own risk.
// ------------------------------------------------------------------------------------------------- // In "Sample Sell Trailing" Robot the user can set the variable "Trigger (pips)" // which defines the point where the Stop Loss will start trailing the order. // When the profit in pips is above or equal to "Trigger (pips)" the stop loss will start trailing the spot price. // Until this condition is met the user can set a normal Stop Loss using the "Stop Loss (pips)" variable. // Variable "Trailing Stop (pips)" defines the number of pips the Stop Loss trails the spot price by. // The user can select to also set a take profit in his order with parameter "Take Profit (pips)". // // ------------------------------------------------------------------------------------------------- using cAlgo.API; namespace cAlgo.Robots.Samples { [Robot("Sample Sell Trailing Robot", TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class SampleSellTrailing : Robot { [Parameter(DefaultValue = 10000)] public int Volume { get; set; } [Parameter("Stop Loss (pips)", DefaultValue = 50, MinValue = 1)] public int StopLoss { get; set; } [Parameter("Take Profit (pips)", DefaultValue = 50, MinValue = 1)] public int TakeProfit { get; set; } [Parameter("Trigger (pips)", DefaultValue = 20)] public int Trigger { get; set; } [Parameter("Trailing Stop (pips)", DefaultValue = 10)] public int TrailingStop { get; set; } protected override void OnStart() { ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SampleSellTrailing", StopLoss, TakeProfit); } protected override void OnTick() { var position = Positions.Find("SampleSellTrailing"); if (position == null) { Stop(); return; } var distance = Symbol.Ask - position.EntryPrice; if (distance >= Trigger * Symbol.PipSize) { double newStopLossPrice = Symbol.Ask + TrailingStop * Symbol.PipSize; if (position.StopLoss == null || newStopLossPrice < position.StopLoss) { ModifyPosition(position, newStopLossPrice, position.TakeProfit); } } } } }
@admin
admin
12 Oct 2012, 09:47
Hello,
Due to contractual agreement we are not at liberty to disclose this information.
A quick Google search will give you the answer.
@admin