velu130486
Topics
Replies
velu130486
06 Oct 2021, 11:00
( Updated at: 21 Dec 2023, 09:22 )
RE:
Thank you Ahmad for your quick support. Actually I dont want to have the historical data, I would like to know the VMA value at the same time in both M15 and H4 timeframe to filter the signals.
So I used the same indicator as below, please advice me if it is wrong.
vma = Indicators.GetIndicator<VariableMovingAverage>(6,TimeFrame.Hour4);
However when I do the backtest and print the values I found there is a difference between the printed values and actual chart values as attached.
And the values are not matching with live chart for the same time. Just want to know the reason for my better understanding or to know anything I did wrong.
Anyhow thanks again for your support, very much appreciated.
Thanks and Regards
R. Vadivelan
amusleh said:
Hi,
The indicator doesn't support multi time frame, it only has one parameter which is Period.
To make it multi time frame it should have a data series source parameter so you would be able to pass another time price series to it and indicator will use that instead of current chart price series.
Try this:
using System; using cAlgo.API; using cAlgo.API.Internals; namespace cAlgo { [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class VariableMovingAverage : Indicator { [Parameter(DefaultValue = 6)] public int Period { get; set; } [Parameter("TimeFrame")] public TimeFrame BaseTimeFrame { get; set; } [Output("Main", LineColor = "Cyan")] public IndicatorDataSeries Result { get; set; } private double K = 1; private IndicatorDataSeries pdmS, mdmS, pdiS, mdiS, iS, tempResult; private Bars _baseBars; protected override void Initialize() { _baseBars = MarketData.GetBars(BaseTimeFrame); K /= Period; pdmS = CreateDataSeries(); mdmS = CreateDataSeries(); pdiS = CreateDataSeries(); mdiS = CreateDataSeries(); iS = CreateDataSeries(); tempResult = CreateDataSeries(); } public override void Calculate(int index) { var baseIndex = _baseBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]); if (baseIndex < Period) return; double pdm = Math.Max(_baseBars[baseIndex].Close - _baseBars[baseIndex - 1].Close, 0), mdm = Math.Max(_baseBars[baseIndex - 1].Close - _baseBars[baseIndex].Close, 0); pdmS[index] = ((1 - K) * (double.IsNaN(pdmS[index - 1]) ? 0 : pdmS[index - 1]) + K * pdm); mdmS[index] = ((1 - K) * (double.IsNaN(mdmS[index - 1]) ? 0 : mdmS[index - 1]) + K * mdm); double pdi = pdmS[index] / (pdmS[index] + mdmS[index]); double mdi = mdmS[index] / (pdmS[index] + mdmS[index]); pdiS[index] = ((1 - K) * (double.IsNaN(pdiS[index - 1]) ? 0 : pdiS[index - 1]) + K * pdi); mdiS[index] = ((1 - K) * (double.IsNaN(mdiS[index - 1]) ? 0 : mdiS[index - 1]) + K * mdi); iS[index] = ((1 - K) * (double.IsNaN(iS[index - 1]) ? 0 : iS[index - 1]) + K * Math.Abs(pdiS[index] - mdiS[index]) / (pdiS[index] + mdiS[index])); double hhv = iS.Maximum(Period); double llv = iS.Minimum(Period); tempResult[index] = (1 - K * (iS[index] - llv) / (hhv - llv)) * (double.IsNaN(tempResult[index - 1]) ? 0 : tempResult[index - 1]) + _baseBars[baseIndex].Close * K * (iS[index] - llv) / (hhv - llv); if (index > Period * 10) Result[index] = tempResult[index]; } } }
I have added a new TimeFrame parameter on it, you can use it to pass an specific time frame to indicator so it will use that time frame price data instead of current time frame.
When using multiple time frames data the other time frame might not load all the historical data that your current chart time frame loaded, so you have to use LoadMoreHistory method of Bars to load more history based on your chart current amount of loaded data.
velu130486
01 Oct 2021, 14:12
RE:
Thanks Ahmad for your quick reply. I don't want complicate the things in my bot since I don't have enough knowledge on coding. So I will try to use Equity loss as condition for opening the positions.
Thanks and Regards
R. Vadivelan
amusleh said:
Hi,
You have to calculate each open position used margin, if your account deposit currency is USD you can do that by:
USD / XXX (ex: USD/CAD):
margin = contract size / leverage;
XXX / USD (ex: EUR/USD):
margin = current price * contract size / leverage;
if your account deposit currency is not USD then you have to convert it to that currency by using other FX cross symbols (which will become more complicated).
After you got the total margin used for example buy EURUSD position then you can check if you have enough margin for sell position or not.
Example:
private double GetUsedMargin(string symbolName, TradeType tradeType) { var symbol = Symbols.GetSymbol(symbolName); var positionsCopy = Positions.ToArray(); double usedMargin = 0; foreach (var position in positionsCopy) { if (position.SymbolName.Equals(symbolName, StringComparison.OrdinalIgnoreCase) && position.TradeType == tradeType) { usedMargin += symbolName.StartsWith("USD", StringComparison.OrdinalIgnoreCase) ? position.VolumeInUnits / Account.PreciseLeverage : symbol.Bid * position.VolumeInUnits / Account.PreciseLeverage; } } return usedMargin; }
The above method will give you the amount of used margin by a symbol buy or sell positions, the symbol must be in XXX/USD or USD/XXX format, otherwise it will not work.
Once you got a symbol buy/sell positions total margin you can use it on your if condition instead of Account.Margin.
velu130486
01 Oct 2021, 12:56
( Updated at: 21 Dec 2023, 09:22 )
RE:
Hi Ahmad,
Thanks for your kind reply and update to the cbot code. Sorry for the wrong wording "EquityLoss" in my coding, my intention is use margin as a filter for opening positions. (i.e.) Bot should open positions up to use of 10% margin.
Currently my bot opens buy and sell positions till I use 10% margin, once it is reached Cbot is not opening any positions.
Below is the scenario
From the above scenario, margin used is more than 10%, so Bot will not open new Buy Position in EURUSD/Sell position in GBPUSD however still 0.1 Sell Position of EUR/USD/0.1 buy position of GBPUSD can be opened because no margin is required. However Bot is not opening the same because of following condition.
var lossmargin = Account.Margin / maxEquity * 100;
if (autoMode2 && lossmargin <= 10)
Thanks and Regards
R. Vadivelan
amusleh said:
Hi,
For equity loss you don't have to use margin, instead you can calculate the percentage you are in loss by using only account equity and balance:
private void tradeExecution(TradeType type, string sym, string label) { var equityLossPercentage = (Account.Equity - Account.Balance) / Account.Balance * 100; if (autoMode2 && equityLossPercentage >= -10) { if (type == TradeType.Buy) { double close = lowBar[sym].ClosePrices.LastValue; double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin; double atr = ATR[sym].Result.LastValue; double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize); var tp_1st = Math.Round(gap, 0); var sl_1st = Math.Round((gap * 20), 0); automode2PositionCount(sym, TradeType.Buy, close + atr, close - atr); if (pcount > 0) { if (close > pAboveprice && pcountwithin == 0) ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", 0, 0); if (close < pBelowprice && pcountwithin == 0) ExecuteMarketOrder(TradeType.Buy, sym, minvolume * (pcount + 1), "EA", 0, 0); } else { ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", sl_1st, tp_1st); } Print(sym + " : BUY" + " ATR : " + gap + " Count: " + pcount + " Within: " + pcountwithin); } if (type == TradeType.Sell) { double close = lowBar[sym].ClosePrices.LastValue; double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin; double atr = ATR[sym].Result.LastValue; double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize); var tp_1st = Math.Round(gap, 0); var sl_1st = Math.Round((gap * 20), 0); automode2PositionCount(sym, TradeType.Sell, close + atr, close - atr); if (pcount > 0) { if (close > pAboveprice && pcountwithin == 0) ExecuteMarketOrder(TradeType.Sell, sym, minvolume * (pcount + 1), "EA", 0, 0); if (close < pBelowprice && pcountwithin == 0) ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", 0, 0); } else { ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", sl_1st, tp_1st); } Print(sym + " : SELL" + " ATR : " + gap + " Count : " + pcount + " Within : " + pcountwithin); } } else { Print(sym + " : Max Equity Drawdown Trade not allowed " + losspercentage); } }
For example, your account balance is 1000 and your equity is 900, it means you are down -10%.
velu130486
01 Oct 2021, 10:47
( Updated at: 21 Dec 2023, 09:22 )
RE:
Hi Ahmad,
I will try to explain better. As you said there is no problem in margin % calculation. So once the Buy position is opened by Bot, margin will be consumed 10% and it is fine. However when the bot generates sell signal, sell positions are not opened in my bot (even though no margin is required).
Main issue is due to the following condition, since the margin % > 10, it directly skip to last else statement.
if (autoMode2 && losspercentage <= EquityLoss)
I want to implement EquityLoss condition at the same time Bot should open only sell positions till 0.5 Lot.
In manual trading I can open the positions and margin is not increased, however in Auto trading Cbot not opening the sell positions.
Thanks and Regards
R. Vadivelan
amusleh said:
Hi,
I still don't understand your exact issue, the Account.Margin gives you the amount of used margin.
The 116 is the amount of margin you need for a 1:500 leverage account to open a 0.5 lots buy EURUSD position, and the 0.2 lots sell position doesn't cost you any extra margin.
Here is my used margin when I opened the first 0.5 lots buy position:
And here is my used margin after I opened the second sell position:
You see my used margin didn't increased at all, that's the exact value you get from Account.Margin.
So, the sell position doesn't increase your used margin, you are using 10% of your margin, if you want to keep opening positions then set the percentage of margin to 20% not 10%.
velu130486
30 Sep 2021, 12:45
RE:
Hi Ahmad,
I had modified the code based on Balance (as per your sample code), but still the new positions are not opening.
void tradeExecution(TradeType type, string sym, string label)
{
var losspercentage = Account.Margin / Account.Balance * 100;
if (autoMode2 && losspercentage <= 10)
{
if (type == TradeType.Buy)
{
double close = lowBar[sym].ClosePrices.LastValue;
double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
double atr = ATR[sym].Result.LastValue;
double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize);
var tp_1st = Math.Round(gap, 0);
var sl_1st = Math.Round((gap * 20), 0);
automode2PositionCount(sym, TradeType.Buy, close + atr, close - atr);
if (pcount > 0)
{
if (close > pAboveprice && pcountwithin == 0)
ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", 0, 0);
if (close < pBelowprice && pcountwithin == 0)
ExecuteMarketOrder(TradeType.Buy, sym, minvolume * (pcount + 1), "EA", 0, 0);
}
else
{
ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", sl_1st, tp_1st);
}
Print(sym + " : BUY" + " ATR : " + gap + " Count: " + pcount + " Within: " + pcountwithin);
}
if (type == TradeType.Sell)
{
double close = lowBar[sym].ClosePrices.LastValue;
double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
double atr = ATR[sym].Result.LastValue;
double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize);
var tp_1st = Math.Round(gap, 0);
var sl_1st = Math.Round((gap * 20), 0);
automode2PositionCount(sym, TradeType.Sell, close + atr, close - atr);
if (pcount > 0)
{
if (close > pAboveprice && pcountwithin == 0)
ExecuteMarketOrder(TradeType.Sell, sym, minvolume * (pcount + 1), "EA", 0, 0);
if (close < pBelowprice && pcountwithin == 0)
ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", 0, 0);
}
else
{
ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", sl_1st, tp_1st);
}
Print(sym + " : SELL" + " ATR : " + gap + " Count : " + pcount + " Within : " + pcountwithin);
}
}
else
{
Print(sym + " : Max Equity Drawdown Trade not allowed " + losspercentage);
}
}
As I said before the problem is happening on this line
if (autoMode2 && losspercentage <= 10)
Cbot open the Buy or Sell position when the losspercentage is less than 10, but when it is more than 10 it is directly go to last else statement, so no new positions are opened.
However my expectation is
New Sell position to be opened if existing Buy Position volume is more, because no margin is required
New Buy position to be opened if existing Sell Position volume is more, because no margin is required
For Ex I have starting balance 1000, Margin used 116, Buy Positions opened 0.5 Lot EUR/USD, Sell positions 0.2 Lot EUR/USD.
When the Cbot generate Buy Signal no new position to be opened because margin is more than 10%. However if the sell signal is provided it has to open a new position because no margin is required for Sell positions. However with the above code it go to last else statement.
Thanks and Regards
R. Vadivelan
amusleh said:
Hi,
I checked your code, there is no issue on your margin condition.
Can you just use balance not equity and see if it executes any trade or not.
I think your equity fell below your max margin loss percentage amount, and that stops the bot from opening new positions.
velu130486
29 Sep 2021, 13:53
RE:
Hi Ahmad,
Thanks for your quick reply. The Cbot posted in my previous post works fine even with while condition, however I had implemented the same condition in my multiple symbol Cbot, and it causes the problem.
I had pasted the extract of Cbot code below where the trade is executed, because the Original Cbot is more than 1500 lines since it filters the signal based on top-down analysis and indicators for multiple symbols.
I had implemented the margin check condition in line no 6, which will check margin is more than 10% or not before opening the orders. I had used “if” condition and it works fine however when I use “while” condition Ctrader is not responding.
Assuming that Cbot already opened 0.20 Lot buy positions with margin more than 10%, then I expect Cbot not to open any new Buy positions even though buy signal is provided. At the same time, I want the bot to open sell positions up to 0.20 Lot if there is a sell signal provided, because as you said Ctrader API Account.Margin value doesn't increase if you open an opposite position.
I had checked the live demo where the Cbot provide sell signals, but based on the condition implemented in line no 6, Cbot is not allowing to open any positions and directly executes the last else statement. I had already changed the margin check to 2nd if condition also but still not working.
Please help me to fix this problem, since I am trying to find a solution for last 1 week.
Thanks and Regards
R. Vadivelan
void tradeExecution(TradeType type, string sym, string label)
{
double maxEquity = Account.Balance > startEquity ? Account.Balance : startEquity;
var losspercentage = Account.Margin / maxEquity * 100;
if (autoMode2 && losspercentage <= EquityLoss)
{
if (type == TradeType.Buy)
{
double close = lowBar[sym].ClosePrices.LastValue;
double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
double atr = ATR[sym].Result.LastValue;
double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize);
var tp_1st = Math.Round(gap, 0);
var sl_1st = Math.Round((gap * 20), 0);
automode2PositionCount(sym, TradeType.Buy, close + atr, close - atr);
if (pcount > 0)
{
if (close > pAboveprice && pcountwithin == 0)
ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", 0, 0);
if (close < pBelowprice && pcountwithin == 0)
ExecuteMarketOrder(TradeType.Buy, sym, minvolume * (pcount + 1), "EA", 0, 0);
}
else
{
ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", sl_1st, tp_1st);
}
Print(sym + " : BUY" + " ATR : " + gap + " Count: " + pcount + " Within: " + pcountwithin);
}
if (type == TradeType.Sell)
{
double close = lowBar[sym].ClosePrices.LastValue;
double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
double atr = ATR[sym].Result.LastValue;
double gap = ATR[sym].Result.LastValue * (1 / Symbols.GetSymbol(sym).PipSize);
var tp_1st = Math.Round(gap, 0);
var sl_1st = Math.Round((gap * 20), 0);
automode2PositionCount(sym, TradeType.Sell, close + atr, close - atr);
if (pcount > 0)
{
if (close > pAboveprice && pcountwithin == 0)
ExecuteMarketOrder(TradeType.Sell, sym, minvolume * (pcount + 1), "EA", 0, 0);
if (close < pBelowprice && pcountwithin == 0)
ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", 0, 0);
}
else
{
ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", sl_1st, tp_1st);
}
Print(sym + " : SELL" + " ATR : " + gap + " Count : " + pcount + " Within : " + pcountwithin);
}
}
else
{
Print(sym + " : Max Equity Drawdown Trade not allowed " + losspercentage);
}
}
amusleh said:
Hi,
I just tested my posted code on a 2 year historical data back tester, it didn't hanged my PC nor it caused any other issue.
Back to your original code, the issue it not margin calculation, cTrader API Account.Margin value doesn't increase if you open an opposite position, you can test it.
The issue of not opening new positions most probably is caused by your condition that check the buy/sell count.
You are also using OnBar method on your code, which is executed once per each bar open, not on each tick, and that might be the cause because the method will be executed only when a new bar opens.
Try this:
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 AdvancedHedgingBot : Robot { [Parameter("Volume", DefaultValue = 1000, MinValue = 1, Step = 1)] public int Volume { get; set; } private double _Margin; private int noOfPositions = 4; private int pips = 2; protected override void OnStart() { _Margin = Account.Balance; ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY"); ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL"); } protected override void OnTick() { foreach (var position in Positions) { if (position.Pips > pips) { ClosePosition(position); } } if (Positions.Count < noOfPositions) { ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY"); ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL"); } int buyCount = 0; int sellCount = 0; foreach (var position in Positions) { if (position.TradeType == TradeType.Buy) buyCount++; if (position.TradeType == TradeType.Sell) sellCount++; } if (Account.Margin / _Margin * 100 <= 10) { Volume += 1000; noOfPositions += 2; pips++; ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY"); ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL"); } } } }
I removed your condition for buy/sell count check from if statement, you can add them back if you want to.
You don't have to nest if statements like that, you can add multiple conditions on a single if statement one after another:
if (Account.Margin / _Margin * 100 <= 10 && (buyCount == 0 || sellCount == 0)) { Volume += 1000; noOfPositions += 2; pips++; ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY"); ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL"); }
velu130486
29 Sep 2021, 10:43
RE:
Hi Ahmad,
Thanks for your modifications, I had already updated the while function in my multiple symbol multitimeframe based bot, however it results in Hanging of Ctrader. But the bot works fine with if condition. So is there any other alternate solution for this.
Thanks and Regards
R. Vadivelan
amusleh said:
Hi,
The code I posted uses your account live equity and compare it with the amount of used margin, if you want to use your starting account balance as initial value then try this:
using cAlgo.API; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class AdvancedHedgingBot : Robot { [Parameter("Volume", DefaultValue = 1000, MinValue = 1, Step = 1)] public int Volume { get; set; } private int noOfPositions = 4; private int pips = 2; private double _balance; protected override void OnStart() { _balance = Account.Balance; ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY"); ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL"); } protected override void OnTick() { foreach (var position in Positions) { if (position.Pips > pips) { ClosePosition(position); } } if (Positions.Count < noOfPositions) { ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY"); ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL"); } int buyCount = 0; int sellCount = 0; foreach (var position in Positions) { if (position.TradeType == TradeType.Buy) buyCount++; if (position.TradeType == TradeType.Sell) sellCount++; } // This will keep opening buy and sell positions unless your margin reach 10%, then it stops // It opens at most two buy and two sell positions (total 4) while (Account.Margin / _balance * 100 < 10 && buyCount + sellCount < 4) { if (buyCount < 2) { buyCount++; ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY"); } if (sellCount < 2) { sellCount++; ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL"); } } } } }
velu130486
27 Sep 2021, 16:57
RE:
Hi Ahmad,
I had tried your code and I found in backtesting still the positions are created eventhough the margin is more than 10%. Also during backtesting I found in some cases sell positions are not created (i.e.) only buy positions are created.
Thanks and Regards
R. Vadivelan
amusleh said:
Hi,
Try this:
using cAlgo.API; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class AdvancedHedgingBot : Robot { [Parameter("Volume", DefaultValue = 1000, MinValue = 1, Step = 1)] public int Volume { get; set; } private int noOfPositions = 4; private int pips = 2; protected override void OnStart() { ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY"); ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL"); } protected override void OnTick() { foreach (var position in Positions) { if (position.Pips > pips) { ClosePosition(position); } } if (Positions.Count < noOfPositions) { ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY"); ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL"); } int buyCount = 0; int sellCount = 0; foreach (var position in Positions) { if (position.TradeType == TradeType.Buy) buyCount++; if (position.TradeType == TradeType.Sell) sellCount++; } // This will keep opening buy and sell positions unless your margin reach 10%, then it stops // It opens at most two buy and two sell positions (total 4) while (Account.Margin / Account.Equity * 100 < 10 && buyCount + sellCount < 4) { if (buyCount < 2) { buyCount++; ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY"); } if (sellCount < 2) { sellCount++; ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL"); } } } } }
Modify it based on your needs, it uses a while loop to keep executing new positions until you reach 10% of account margin, then it stops.
velu130486
27 Sep 2021, 11:06
RE:
Thanks Ahmad for your quick reply. I will try it and update here.
Thanks and Regards
R. Vadivelan
amusleh said:
Hi,
Try this:
using cAlgo.API; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class AdvancedHedgingBot : Robot { [Parameter("Volume", DefaultValue = 1000, MinValue = 1, Step = 1)] public int Volume { get; set; } private int noOfPositions = 4; private int pips = 2; protected override void OnStart() { ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY"); ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL"); } protected override void OnTick() { foreach (var position in Positions) { if (position.Pips > pips) { ClosePosition(position); } } if (Positions.Count < noOfPositions) { ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY"); ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL"); } int buyCount = 0; int sellCount = 0; foreach (var position in Positions) { if (position.TradeType == TradeType.Buy) buyCount++; if (position.TradeType == TradeType.Sell) sellCount++; } // This will keep opening buy and sell positions unless your margin reach 10%, then it stops // It opens at most two buy and two sell positions (total 4) while (Account.Margin / Account.Equity * 100 < 10 && buyCount + sellCount < 4) { if (buyCount < 2) { buyCount++; ExecuteMarketOrder(TradeType.Buy, Symbol, Volume, "BUY"); } if (sellCount < 2) { sellCount++; ExecuteMarketOrder(TradeType.Sell, Symbol, Volume, "SELL"); } } } } }
Modify it based on your needs, it uses a while loop to keep executing new positions until you reach 10% of account margin, then it stops.
velu130486
09 Apr 2021, 19:53
RE:
Hi Algo developer,
I dont want to change the symbol in Cbot. Cbot will keep on running in the same symbol and it generates the signal on multiple pairs, I need a button to change the chart symbol from the windows form when the signal comes (say US30 in the above pictures). Currently I use your indicator to change the chart symbol first, then I click the symbol in windows form to execute the order, I want to avoid this 2 click while order execution, just want to know is it possible to do it in 1 click or not.
I dont know how to explain in technical terms and sorry for that. What I understood is this Cbot is executing the order based on the text box in windows form. So I need to change the symbol name with the same symbol what I click in chart switch indicator.
Thanks and Regards
R. Vadivelan
amusleh said:
Hi,
When a cBot is running on a chart it locks the chart, so you can't change the chart time frame or symbol unless you stop your cBot.
You can change a chart symbol or time frame with an indicator but not with a cBot.
Why you need such a feature?
velu130486
20 Jul 2020, 09:47
RE:
Hi Panagiotis,
Thanks for your reply and understand your position, I will try to fix it by myself.
PanagiotisCharalampous said:
Hi Vadivelan,
If you are looking for somebody to develop the logic for you then unfortunately I cannot help you. I cannot engage in custom development requests.
Best Regards,
Panagiotis
velu130486
20 Jul 2020, 08:48
RE:
Hi Panagiotis,
There is no problem in the code, only thing I need to make the changes as below to suit my requirement,
I want to adjust the gap only if the distance is more than the hedge gap, if it is less than hedge gap then the order price should remain fixed.
Let say Buy position is created at 119.60 and I enabled the constantDistanceHedge with 20 pips. As soon as the Buy position is created at 119.60 Cbot will create the pending sell order at 119.40 (i.e.) with the distance of 20 pips. If the price moves up I want the pending order price to be adjusted, but the price goes in opposite, I would like to keep the position at the same price so that it gets triggered to form a hedge.
if (constantDistanceHedge)
{
foreach (var order in PendingOrders)
{
if (order.Label == label && order.SymbolName == SymbolName && order.Comment != "Initial Order" && order != null)
{
var targetPrice = order.TradeType == TradeType.Buy ? Symbol.Bid : Symbol.Ask;
if ((targetPrice - order.TargetPrice) / Symbol.PipSize > Pipstep * Symbol.PipSize && order.TradeType == TradeType.Sell)
{
ModifyPendingOrderAsync(order, targetPrice - Pipstep * Symbol.PipSize);
}
else if ((order.TargetPrice - targetPrice) / Symbol.PipSize > Pipstep * Symbol.PipSize && order.TradeType == TradeType.Buy)
{
ModifyPendingOrderAsync(order, targetPrice + Pipstep * Symbol.PipSize);
}
}
}
PanagiotisCharalampous said:
Hi Vadivelan,
From first glance, I do not see any problem in the code. If this has been developed by a consultant, it would be better to talk to them.
Best Regards,
Panagiotis
velu130486
17 Jul 2020, 14:21
RE:
Hi Panagiotis,
Please find the Cbot which I had developed with a consultant. There is no major problem in the Cbot, but I want to make the changes/update only in the section constantDistanceHedge.
If this option is not enabled then the distance between market position and pending order will remain fixed, If I enable this option to yes, then the distance between market position and pending order is keep on updated with the distance of certain pips or based on ATR.
Now I want to adjust the gap only if the distance is more than the hedge gap, if it is less than hedge gap then the order price should remain fixed. Let say Buy position is created at 119.60 and I enabled the constantDistanceHedge with 20 pips.
As soon as the Buy position is created at 119.60 Cbot will create the pending sell order at 119.40 (i.e.) with the distance of 20 pips. If the price moves up I want the pending order price to be adjusted, but the price goes in opposite, I would like to keep the position at the same price so that it gets triggered to form a hedge.
Currently with constantDistanceHedge mode enabled gap will be adjusted in both direction, (i.e.) when the price goes down the position will also be moved down which means the position will not triggered.
Please let me know if I am not clear.
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class VadivelanRangeBot : Robot
{
[Parameter("Label Prefix", DefaultValue = "VRB")]
public string label { get; set; }
[Parameter("Running Mode", DefaultValue = RunningLevel.Standard)]
public RunningLevel runningMode { get; set; }
[Parameter("Initial orders pips away", DefaultValue = 5, MinValue = 1)]
public double initialOrderPipsAway { get; set; }
[Parameter("Hedge Gap Type", Group = "Hedge Gap", DefaultValue = GapType.ATR)]
public GapType gapType { get; set; }
[Parameter("Hedge Gap ATR Multiplier", Group = "Hedge Gap", DefaultValue = 3, MinValue = 1, Step = 0.1)]
public double hedgeGapMultiplier { get; set; }
[Parameter("Hedge order pips away", Group = "Hedge Gap", DefaultValue = 20, MinValue = 1)]
public double hedgeOrderPipsAway { get; set; }
[Parameter("Enable Constant Distance Hedge", DefaultValue = false)]
public bool constantDistanceHedge { get; set; }
[Parameter("Max Equity Drawdown %", DefaultValue = 10, MinValue = 1)]
public double maxEquityDrawdown { get; set; }
[Parameter("Stop Loss Type", DefaultValue = StopLossType.ATR)]
public StopLossType stoplossType { get; set; }
[Parameter("Stop Loss (pips)", DefaultValue = 100, MinValue = 1, Step = 1)]
public double stopLoss { get; set; }
[Parameter("Enable Add Spread to SL", DefaultValue = false)]
public bool enableAddSpread { get; set; }
[Parameter("Volume (lots)", DefaultValue = 0.1, MinValue = 0.01, Step = 0.01)]
public double volume { get; set; }
[Parameter("ATR Risk (%)", DefaultValue = 1, MinValue = 0.5)]
public double atrRiskPercentage { get; set; }
[Parameter("Take Profit Type", DefaultValue = TakeProfitType.SLMultiplier)]
public TakeProfitType takeProfitType { get; set; }
[Parameter("Take Profit (pips)", DefaultValue = 100, MinValue = 1, Step = 1)]
public double takeProfit { get; set; }
[Parameter("Take Profit (SL Multiplier)", DefaultValue = 1, MinValue = 1)]
public double takeProfitMultiplier { get; set; }
[Parameter("Type", Group = "Trailing Stop", DefaultValue = TrailingStopType.ATR)]
public TrailingStopType trailingStopType { get; set; }
[Parameter("ATR TSL Periods", Group = "Trailing Stop", DefaultValue = 21)]
public int atrPeriods { get; set; }
[Parameter("ATR TSL Multiplier", Group = "Trailing Stop", DefaultValue = 3)]
public double ATRMultiplier { get; set; }
[Parameter("Resume Bot", DefaultValue = false)]
public bool resumeBot { get; set; }
private bool isExecuting = false;
private double sellEntryPrice;
private double buyEntryPrice;
private double maxEquity;
private double stopLimitRangePips;
public double ATRMinimuStopLoss;
private AverageTrueRange atr;
private RelativeStrengthIndex rsi;
protected override void OnStart()
{
Print("The number of Digits the current symbol has is: {0}", Symbol.Digits);
label = label + SymbolName + TimeFrame;
atrRiskPercentage = atrRiskPercentage / 100;
stopLimitRangePips = 100;
ATRMinimuStopLoss = 5;
Positions.Opened += PositionsOnOpened;
volume = Symbol.QuantityToVolumeInUnits(volume);
volume = Symbol.NormalizeVolumeInUnits(volume);
maxEquityDrawdown = maxEquityDrawdown / 100;
maxEquity = Account.Equity;
atr = Indicators.AverageTrueRange(atrPeriods, MovingAverageType.Simple);
rsi = Indicators.RelativeStrengthIndex(MarketSeries.Close, 14);
if (!resumeBot)
{
isExecuting = true;
PlaceInitialTrades(TradeType.Buy);
PlaceInitialTrades(TradeType.Sell);
}
}
protected override void OnTick()
{
if (Account.Equity > maxEquity)
{
maxEquity = Account.Equity;
}
if ((maxEquity - Account.Equity) / maxEquity >= maxEquityDrawdown)
{
CloseAllOrders();
CloseAllPositions();
Print("Max Drawdown Hit - Bot Shutdown");
Stop();
}
Chart.DrawStaticText("MaxEquity", "Max Equity: $" + maxEquity, VerticalAlignment.Top, HorizontalAlignment.Right, Color.LimeGreen);
int orderCount = CountOrders();
int positionCount = CountPositions();
if (orderCount + positionCount == 0 && !isExecuting)
{
isExecuting = true;
PlaceInitialTrades(TradeType.Buy);
PlaceInitialTrades(TradeType.Sell);
return;
}
if (constantDistanceHedge)
{
foreach (var order in PendingOrders)
{
if (order.Label == label && order.SymbolName == SymbolName && order.Comment != "Initial Order" && order != null)
{
var targetPrice = order.TradeType == TradeType.Buy ? Symbol.Bid : Symbol.Ask;
if ((targetPrice - order.TargetPrice) / Symbol.PipSize > GapTypePips() * Symbol.PipSize && order.TradeType == TradeType.Sell)
{
ModifyPendingOrderAsync(order, targetPrice - GapTypePips() * Symbol.PipSize);
}
else if ((order.TargetPrice - targetPrice) / Symbol.PipSize > GapTypePips() * Symbol.PipSize && order.TradeType == TradeType.Buy)
{
ModifyPendingOrderAsync(order, targetPrice + GapTypePips() * Symbol.PipSize);
}
}
}
}
DisplayChartInfo();
ATRTrailingStop();
MomentumTrailingStop();
}
protected override void OnStop()
{
// Put your deinitialization logic here
}
private void PositionsOnOpened(PositionOpenedEventArgs args)
{
var position = args.Position;
if (position.Label == label && position.SymbolName == SymbolName)
{
if (stoplossType == StopLossType.None)
{
ModifyPosition(position, null, position.TakeProfit);
}
if (position.TradeType == TradeType.Sell)
{
sellEntryPrice = position.EntryPrice;
}
else
{
double newStopLoss = ATRSLPips() + addSpreadToStopLoss();
newStopLoss = Math.Round(newStopLoss, 0);
buyEntryPrice = position.EntryPrice;
}
isExecuting = false;
if (position.Comment != null)
{
string comment = position.Comment;
{
if (comment == "Initial Order")
{
CloseAllOrders();
if (runningMode == RunningLevel.Standard)
{
double newStopLoss = ATRSLPips() + addSpreadToStopLoss();
newStopLoss = Math.Round(newStopLoss, 0);
volume = CalculateVolume(newStopLoss);
double entryPrice = position.TradeType == TradeType.Buy ? Symbol.Bid - GapTypePips() * Symbol.PipSize : Symbol.Bid + GapTypePips() * Symbol.PipSize;
PlaceTrade(position.TradeType == TradeType.Buy ? TradeType.Sell : TradeType.Buy, entryPrice);
return;
}
if (runningMode == RunningLevel.TrendMode)
{
return;
}
if (runningMode == RunningLevel.TrendModePlusHedge)
{
double newStopLoss = ATRSLPips() + addSpreadToStopLoss();
newStopLoss = Math.Round(newStopLoss, 0);
volume = CalculateVolume(newStopLoss);
double entryPrice = position.TradeType == TradeType.Buy ? Symbol.Bid - (GapTypePips() * 2) * Symbol.PipSize : Symbol.Bid + (GapTypePips() * 2) * Symbol.PipSize;
PlaceTrade(position.TradeType == TradeType.Buy ? TradeType.Sell : TradeType.Buy, entryPrice);
entryPrice = position.TradeType == TradeType.Buy ? Symbol.Bid + (GapTypePips()) * Symbol.PipSize : Symbol.Bid - (GapTypePips() * Symbol.PipSize);
PlaceTrade(position.TradeType, entryPrice);
return;
}
}
}
}
}
}
private void CloseAllOrders()
{
foreach (var order in PendingOrders)
{
if (order.Label == label && order.SymbolName == SymbolName)
{
CancelPendingOrderAsync(order);
}
}
}
private void CloseAllPositions()
{
foreach (var position in Positions)
{
if (position.Label == label && position.SymbolName == SymbolName && position != null)
{
ClosePositionAsync(position);
}
}
}
private int CountOrders()
{
int count = 0;
foreach (var order in PendingOrders)
{
if (order.Label == label && order.SymbolName == SymbolName)
{
count++;
}
}
return count;
}
private int CountPositions()
{
var positions = Positions.FindAll(label, SymbolName);
return positions.Length;
}
private void PlaceInitialTrades(TradeType tradeType)
{
double currentPrice = tradeType == TradeType.Buy ? Symbol.Bid : Symbol.Ask;
double newStopLoss = ATRSLPips() + addSpreadToStopLoss();
newStopLoss = Math.Round(newStopLoss, 0);
volume = CalculateVolume(newStopLoss);
double entryPrice = tradeType == TradeType.Sell ? currentPrice - initialOrderPipsAway * Symbol.PipSize - addSpreadToStopLoss() * Symbol.PipSize : currentPrice + initialOrderPipsAway * Symbol.PipSize + addSpreadToStopLoss() * Symbol.PipSize;
if (currentPrice < entryPrice && tradeType == TradeType.Sell || currentPrice > entryPrice && tradeType == TradeType.Buy)
{
PlaceLimitOrderAsync(tradeType, SymbolName, volume, entryPrice, label, newStopLoss, TakeProfit(), null, "Initial Order");
}
else if (currentPrice > entryPrice && tradeType == TradeType.Sell || currentPrice < entryPrice && tradeType == TradeType.Buy)
{
PlaceStopLimitOrderAsync(tradeType, SymbolName, volume, entryPrice, stopLimitRangePips, label, newStopLoss, TakeProfit(), null, "Initial Order");
}
}
private void PlaceTrade(TradeType tradeType, double entryPrice)
{
double currentPrice = tradeType == TradeType.Buy ? Symbol.Bid : Symbol.Ask;
double newStopLoss = ATRSLPips() + addSpreadToStopLoss();
newStopLoss = Math.Round(newStopLoss, 0);
volume = CalculateVolume(newStopLoss);
if (currentPrice < entryPrice && tradeType == TradeType.Sell || currentPrice > entryPrice && tradeType == TradeType.Buy)
{
PlaceLimitOrderAsync(tradeType, SymbolName, volume, entryPrice, label, newStopLoss, TakeProfit());
}
else if (currentPrice > entryPrice && tradeType == TradeType.Sell || currentPrice < entryPrice && tradeType == TradeType.Buy)
{
PlaceStopLimitOrderAsync(tradeType, SymbolName, volume, entryPrice, stopLimitRangePips, label, newStopLoss, TakeProfit());
}
}
private void ATRTrailingStop()
{
if (trailingStopType != TrailingStopType.ATR)
{
Print("ATR TS false");
return;
}
var positions = Positions.FindAll(label, SymbolName);
if (positions.Length > 0)
{
double atrPips = (atr.Result.LastValue / Symbol.PipSize) * ATRMultiplier;
atrPips = Math.Round(atrPips, 1);
Print(atrPips);
foreach (var position in positions)
{
if (position.TradeType == TradeType.Buy && Symbol.Bid - (atrPips * Symbol.PipSize) > position.StopLoss)
{
//Print("Old sl price: " + position.StopLoss);
ModifyPosition(position, Symbol.Bid - (atrPips * Symbol.PipSize), position.TakeProfit);
//Print("New sl price: " + position.StopLoss);
}
else if (position.TradeType == TradeType.Sell && Symbol.Ask + (atrPips * Symbol.PipSize) < position.StopLoss)
{
//Print("Old sl price: " + position.EntryPrice);
ModifyPosition(position, Symbol.Ask + (atrPips * Symbol.PipSize), position.TakeProfit);
//Print("New sl price: " + position.StopLoss);
}
}
}
}
private void MomentumTrailingStop()
{
if (trailingStopType != TrailingStopType.Momentum)
{
return;
}
var positions = Positions.FindAll(label, SymbolName);
{
if (positions.Length > 0)
{
foreach (var position in positions)
{
if (position.TradeType == TradeType.Buy && position.StopLoss < position.EntryPrice)
{
var newStopLossPrice = Symbol.Ask - (Symbol.PipSize * stopLoss);
if (newStopLossPrice > position.StopLoss)
{
ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
else if (position.TradeType == TradeType.Sell && position.StopLoss > position.EntryPrice)
{
var newStopLossPrice = Symbol.Bid + (Symbol.PipSize * stopLoss);
if (newStopLossPrice < position.StopLoss)
{
ModifyPosition(position, newStopLossPrice, position.TakeProfit);
}
}
}
}
}
}
private double addSpreadToStopLoss()
{
if (enableAddSpread)
{
var spread = Math.Round(Symbol.Spread / Symbol.PipSize, 1);
Print("Spread added to stop loss (", spread, ")");
return spread;
}
return 0;
}
private void DisplayChartInfo()
{
double rsiValue = Math.Round(rsi.Result.LastValue, 1);
double atrPips = Math.Round(atr.Result.LastValue / Symbol.PipSize, 1);
double atrPipsMultiplied = Math.Round(atrPips * ATRMultiplier, 1);
Chart.DrawStaticText("DisplayInfo", "ATR Pips: " + atrPips + "\nATR Pips X: " + atrPipsMultiplied + "\nRSI: " + rsiValue, VerticalAlignment.Bottom, HorizontalAlignment.Right, Color.BlanchedAlmond);
}
private double CalculateVolume(double stopLoss)
{
if (stoplossType != StopLossType.ATR)
{
return volume;
}
var riskPerTrade = (Account.Equity) * (atrRiskPercentage);
double totalSLPipValue = (stopLoss + Symbol.Spread) * Symbol.PipValue;
if (totalSLPipValue / Account.Equity > atrRiskPercentage)
{
Print("ATR lot size is larger than atr risk %, bot stopped. Account capital too small to trade this instrument at this risk level");
Print("Total position SL size $" + totalSLPipValue);
Stop();
return -1;
}
double calculatedVolume = riskPerTrade / totalSLPipValue;
double normalizedCalculatedVolume = Symbol.NormalizeVolumeInUnits(calculatedVolume, RoundingMode.Down);
return normalizedCalculatedVolume;
}
private double GapTypePips()
{
if (gapType == GapType.ATR)
{
return ATRPips();
}
else
{
return hedgeOrderPipsAway;
}
}
private double ATRSLPips()
{
if (stoplossType != StopLossType.ATR)
{
return stopLoss;
}
double atrPips = (atr.Result.LastValue / Symbol.PipSize) * ATRMultiplier;
atrPips = Math.Round(atrPips, 1);
if (atrPips < ATRMinimuStopLoss)
{
atrPips = ATRMinimuStopLoss;
}
return atrPips;
}
private double ATRPips()
{
double atrPips = (atr.Result.LastValue / Symbol.PipSize) * hedgeGapMultiplier;
atrPips = Math.Round(atrPips, 1);
if (atrPips < ATRMinimuStopLoss)
{
atrPips = ATRMinimuStopLoss;
}
return atrPips;
}
private double? TakeProfit()
{
if (takeProfitType == TakeProfitType.None)
{
return null;
}
if (takeProfitType == TakeProfitType.SLMultiplier && stoplossType != StopLossType.None)
{
return Math.Round(stopLoss * takeProfitMultiplier, 1);
}
return Math.Round(takeProfit, 1);
}
public enum StopLossType
{
Manual,
ATR,
None
}
public enum TakeProfitType
{
Manual,
SLMultiplier,
None
}
public enum GapType
{
Manual,
ATR
}
public enum TrailingStopType
{
Momentum,
ATR,
None
}
public enum RunningLevel
{
Standard,
TrendMode,
TrendModePlusHedge
}
}
}
PanagiotisCharalampous said:
Hi Vadivelan,
Personally I did not understand what are you trying to do. It would be easier if you provided the complete cBot code and backtesting examples of what does the cBot do at the moment and what should it do instead.
Best Regards,
Panagiotis
Thanks and Regards
R. Vadivelan
velu130486
17 Jul 2020, 08:46
RE:
Dear All,
Could you please help me to solve the below problem.
velu130486 said:
Dear All,
I have the following code in my Cbot which enable to modify the pending order by maintain the distance of pip step. But please help me to modify the code to allow changes to be made if the distance is less than pip step and modify the distance only if the distance is more than pip step.
if (constantDistanceHedge) { foreach (var order in PendingOrders) { if (order.Label == label && order.SymbolName == SymbolName && order.Comment != "Initial Order" && order != null) { var targetPrice = order.TradeType == TradeType.Buy ? Symbol.Bid : Symbol.Ask; if ((targetPrice - order.TargetPrice) / Symbol.PipSize > Pipstep * Symbol.PipSize && order.TradeType == TradeType.Sell) { ModifyPendingOrderAsync(order, targetPrice - Pipstep * Symbol.PipSize); } else if ((order.TargetPrice - targetPrice) / Symbol.PipSize > Pipstep * Symbol.PipSize && order.TradeType == TradeType.Buy) { ModifyPendingOrderAsync(order, targetPrice + Pipstep * Symbol.PipSize); } } }
Available for any clarifications
Thanks in Advance
R. Vadivelan
Thanks in Advance
R. Vadivelan
velu130486
13 Jul 2020, 14:28
RE:
Hi Panagiotis,
Now I am able to create the stop order when the position is created. However could you please help how to avoid creating the new stop order when there is already a pending order in the distance of X pips. (i.e.) If there is already a pending order at a distance of 10 pips, I want to avoid create another stop order at the same distance +- 3 pips.
I tried to cancel the pending order, but it close all pending order for the symbol.
Or is there any possibility to cancel the pending order and create the multiple pending orders like entry price + 10 pips, +20 pips, +30 pips etc in 1 line or I need to create 1 by 1 in code
Thanks and Regards
R. Vadivelan
PanagiotisCharalampous said:
Hi Vadivelan,
Check here how to place stop orders in a cBot.
Best Regards,
Panagiotis
velu130486
05 Jul 2020, 01:27
Also to find a way to load parameters settings for various currency pairs easily into Cbot.
velu130486
03 Jul 2020, 12:11
( Updated at: 21 Dec 2023, 09:22 )
RE: RE:Cbot Strategy
Hi Panagiotis,
I had downloaded some source files from the below link and I found some files named strategies. Could you please advice how to link these strategies to the Cbot. I had already tried to save strategy file as Indicator/Cbot but not succeed. Could you please support what I have to do the strategy file to link into Cbot.
using cAlgo;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Lib;
namespace cAlgo.Strategies
{
public class ArgunesStrategy : Strategy
{
ExponentialMovingAverage ema5; // Close
SimpleMovingAverage sma8; // Open
ExponentialMovingAverage ema21; // Close
ExponentialMovingAverage ema55; // Close
public ArgunesStrategy(Robot robot) : base(robot)
{
Initialize();
}
protected override void Initialize()
{
ema5 = Robot.Indicators.ExponentialMovingAverage(Robot.MarketSeries.Close, 5);
sma8 = Robot.Indicators.SimpleMovingAverage(Robot.MarketSeries.Open, 8);
ema21 = Robot.Indicators.ExponentialMovingAverage(Robot.MarketSeries.Close, 21);
ema55 = Robot.Indicators.ExponentialMovingAverage(Robot.MarketSeries.Close, 55);
}
public override TradeType? signal()
{
if (!Robot.existBuyPositions() && (ema21.Result.LastValue > ema55.Result.LastValue) && (ema5.Result.HasCrossedAbove(sma8.Result, 0)))
{
Robot.closeAllSellPositions();
return TradeType.Buy;
}
if (!Robot.existSellPositions() && (ema21.Result.LastValue < ema55.Result.LastValue) && (ema5.Result.HasCrossedBelow(sma8.Result, 0)))
{
Robot.closeAllBuyPositions();
return TradeType.Sell;
}
return null;
}
}
}
using System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.Lib;
using cAlgo.Strategies;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class Argunes : Robot
{
#region cBot Parameters
[Parameter("Volume", DefaultValue = 100000, MinValue = 0)]
public int InitialVolume { get; set; }
[Parameter("Stop Loss", DefaultValue = 150)]
public int StopLoss { get; set; }
[Parameter("Take Profit", DefaultValue = 1000)]
public int TakeProfit { get; set; }
#endregion
#region cBot variables
OrderParams initialOP;
List<Strategy> strategies;
#endregion
protected override void OnStart()
{
base.OnStart();
double slippage = 2; // maximum slippage in point, if order execution imposes a higher slippage, the order is not executed.
string botPrefix = "Argunes"; // order prefix passed by the bot
string positionComment = string.Format("{0}-{1} {2}", botPrefix, Symbol.Code, TimeFrame); ; // order label passed by the bot
initialOP = new OrderParams(null, Symbol, InitialVolume, this.botName(), StopLoss, TakeProfit, slippage, positionComment, null, new List<double>() { 5, 3, 2 });
strategies = new List<Strategy>();
strategies.Add(new ArgunesStrategy(this));
}
protected override void OnTick()
{
}
protected override void OnBar()
{
base.OnBar();
controlRobot();
}
protected override void OnStop()
{
base.OnStop();
this.closeAllPositions();
}
private void controlRobot()
{
TradeType? tradeType = this.signal(strategies);
if (tradeType.HasValue)
{
initialOP.TradeType = tradeType.Value;
initialOP.Volume = InitialVolume;
this.splitAndExecuteOrder(initialOP);
}
}
}
velu130486 said:
Hi Panagiotis,
Actually I had downloaded the bot from this forum
https://ctrader.com/algos/cbots/show/505
But I got the error for missing Calgo.lib. Similar discussions are already done in the forum and I found the solution as posted earlier by forum members.
https://calgobots.codeplex.com/
I had downloaded the library files from the link and now I able to build the code, but not able to crack the reason for this error. If you could support for this error this will help us for the previous post also.
Thanks and Regards
R. Vadivelan
PanagiotisCharalampous said:
Hi Vadivelan,
I cannot even build this cBot. It uses cAlgo.Lib which I am not even aware of. Did you try contacting the developer?
Best Regards,
Panagiotis
velu130486
30 Jun 2020, 12:48
RE:
Hi Panagiotis,
I would like to place stop order. Currently the Bot place the Market order in the same direction once the price change by pip step say 10 pips. What I need at the same time place Stop order in the opposite direction with the distance of pip step from the current price.
For Ex Initially Bot place Buy order at X pips, once it is moved pip step X+10 then it place another buy order, Now I need to place sell stop order at X pips to form as a grid.
Thanks in Advance
R. Vadivelan
PanagiotisCharalampous said:
Hi Vadivelan,
What kind of order (market, stop, limit) and at which price do you want to place it?
Best Regards,
Panagiotis
velu130486
25 Jun 2020, 09:02
RE:
Hi Panagiotis,
Actually I had downloaded the bot from this forum
https://ctrader.com/algos/cbots/show/505
But I got the error for missing Calgo.lib. Similar discussions are already done in the forum and I found the solution as posted earlier by forum members.
https://calgobots.codeplex.com/
I had downloaded the library files from the link and now I able to build the code, but not able to crack the reason for this error. If you could support for this error this will help us for the previous post also.
Thanks and Regards
R. Vadivelan
PanagiotisCharalampous said:
Hi Vadivelan,
I cannot even build this cBot. It uses cAlgo.Lib which I am not even aware of. Did you try contacting the developer?
Best Regards,
Panagiotis
velu130486
21 Oct 2021, 10:49 ( Updated at: 22 Oct 2021, 14:28 )
RE:
Hi Ahmad,
Thanks for your reply. Actually my request is to double the volume on every 4th position count not based on time.
Because sometimes my bot create more than 4 - 6 positions within a hour depends on moving average signal. So the volume is increased on each and every position which I would like to control it, so I would like to increase the volume only on 4,8,12,16 position for both buy and sell positions etc.,
Thanks and Regards
R. Vadivelan
amusleh said: