
Topics
Replies
whis.gg
17 Jun 2016, 00:48
RE:
kaliszczak1991 said:
if (rsi.Result.LastValue > 70) { Open(TradeType.Buy); } else if (rsi.Result.LastValue < 30) { Open(TradeType.Sell); } else if (rsi.Result.LastValue > 30) { Close(TradeType.Sell); } else if (rsi.Result.LastValue < 70) { Close(TradeType.Buy); }
Because you are using else if everywhere it never passes to the condition else if (rsi.Result.Last < 70) so there is still opened your first long position.
var position = Positions.Find("SampleRSI", Symbol, tradeType); if (position == null) // position contains long position which will never be closed ExecuteMarketOrder(tradeType, Symbol, Volume, "SampleRSI");
Because of that bot can't open another long.
Change else if just to if and it will be fine.
@whis.gg
whis.gg
17 Jun 2016, 00:36
Try it. It's working like a charm.
using System; using cAlgo.API; using cAlgo.API.Internals; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class CommissionCalculator : Robot { [Parameter(DefaultValue = 30)] public double CommissionPerMillion { get; set; } protected override void OnStart() { Positions.Opened += OnPositionsOpened; } private void OnPositionsOpened(PositionOpenedEventArgs obj) { double commissions = CommissionPerMillion / 1000000 * obj.Position.Volume / AccountCurrencyExchangeRate(); Print("Calculated: " + Math.Round(-commissions, 2)); Print("Actual: " + (obj.Position.Commissions)); } private double AccountCurrencyExchangeRate() { double rate = 1; string baseCurrency = Account.Currency; string counterCurrency = Symbol.Code.Substring(0, 3); if (baseCurrency != counterCurrency) { Symbol symbol = MarketData.GetSymbol(baseCurrency + counterCurrency); if (symbol != null) { rate = symbol.Bid; } else { symbol = MarketData.GetSymbol(counterCurrency + baseCurrency); rate = 1 / symbol.Bid; } } return rate; } } }
@whis.gg
whis.gg
16 Jun 2016, 23:43
( Updated at: 21 Dec 2023, 09:20 )
RE: RE: RE: RE: RE:
moneybiz said:
tmc. said:
moneybiz said:
How did you get that it's USD 100k but not EUR 100k?
So, for USD/CAD 100k traded is what USD or CAD?
For EUR/USD 100k traded is what EUR or USD?Part of this post was removed by moderator due to a violation of the EULA. Broker discussions are prohibited in cTDN.
Obviously base currency. For USDCAD it's USD, for EURUSD it's EUR. Commissions shown are in account currency USD.
@whis.gg
whis.gg
16 Jun 2016, 18:33
RE:
tmc. said:
Btw, the method I posted will work only if you set commission per mill in same currency as account. I will update that later on.
Actually it works across all currencies, since returned value is in account currency anyway. I am quite sure actual calculating process is rounding somewhere in the middle of calculation while my method isn't which is causing the difference.
tmc. said:
Actually multiple brokers have stated commission in USD but cTrader platform applies EUR.
Never mind, I was wrong about that.
moneybiz said:
The broker says: Commission of $3.00 per 100k traded.
100k traded what? Apples, cherries, EUR, USD?
It's commission of $3.00 per $100k traded (per side).
Let's assume your account currency is USD and current rate of EURUSD is 1.2500. If you trade 100k volume on EURUSD you are actually trading €100k as it's based currency of the pair. Therefore, calculation is following:
- $3.00 * 1.2500 = $3.75 per side
If you account currency was EUR:
- $3.00 * 1 = €3.00 = $3.75 per side
@whis.gg
whis.gg
16 Jun 2016, 15:13
You're right. I just noticed unnamed broker who has stated $3.00 per 100k traded is actually charging €3. Are they trying to rob us by giving false information?
Btw, the method I posted will work only if you set commission per mill in same currency as account. I will update that later on.
@whis.gg
whis.gg
16 Jun 2016, 13:45
I have noticed there are minimal differences. I think it's caused by different method of rounding. I have tried to implement direction of position, therefore take Ask instead of Bid into calculation but it wasn't fixing it. Let me know if you manage to improve it.
@whis.gg
whis.gg
16 Jun 2016, 02:45
The method works fine for me.
using System; using cAlgo.API; using cAlgo.API.Internals; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class CommissionCalculator : Robot { [Parameter(DefaultValue = 30)] public double CommissionPerMillion { get; set; } protected override void OnStart() { Positions.Opened += OnPositionsOpened; } private void OnPositionsOpened(PositionOpenedEventArgs obj) { double commissions = CommissionPerMillion / 1000000 * obj.Position.Volume / AccountCurrencyExchangeRate() * -2; Print("Calculated: " + Math.Round(commissions, 2)); Print("Actual: " + (obj.Position.Commissions * 2)); } private double AccountCurrencyExchangeRate() { string accountCurrency = Account.Currency; string tradedCurrency = Symbol.Code.Substring(0, 3); if (accountCurrency == tradedCurrency) { return 1; } else { Symbol symbol = MarketData.GetSymbol(accountCurrency + tradedCurrency); if (symbol != null) { return symbol.Bid; } else { symbol = MarketData.GetSymbol(tradedCurrency + accountCurrency); return 1 / symbol.Bid; } } } } }
@whis.gg
whis.gg
16 Jun 2016, 01:17
Lets say broker charges a commission fee of $45 USD per million traded. If your account is denominated in a currency other than USD you will need to convert this figure.
The calculation is performed as follows:
Commission Each Side = (trade size * $45 per million traded) * account currency exchange rate
Example:
- Trading 100,000 GBP/JPY with an account currency in EURO
- 0.000045 * 100,000= £4.50 (Base currency of the pair traded)
- To convert to Eur we must divide by the EUR/GBP rate
- EUR/GBP= 0.798
- Commission each way= €5.63
This will be charged when you enter and when you close the trade.
Part of this post was removed by moderator due to a violation of the EULA. Broker discussions are prohibited in cTDN.
@whis.gg
whis.gg
16 Jun 2016, 01:05
( Updated at: 21 Dec 2023, 09:20 )
Results for unnamed broker.
Filter set to 10000 pips.
19/01/2014 22:01:00.784 | Backtesting started 13/06/2016 23:59:59.747 | 25/05/2015 Negative spread: 63373.4 pips 13/06/2016 23:59:59.747 | 26/05/2015 Negative spread: 218132.6 pips 13/06/2016 23:59:59.747 | 27/05/2015 Negative spread: 202081.6 pips 13/06/2016 23:59:59.747 | 28/05/2015 Negative spread: 11550.1 pips 13/06/2016 23:59:59.747 | 29/05/2015 Negative spread: 290066.3 pips 13/06/2016 23:59:59.747 | 01/06/2015 Negative spread: 234630.1 pips 13/06/2016 23:59:59.747 | 02/06/2015 Negative spread: 377209.2 pips 13/06/2016 23:59:59.747 | 03/06/2015 Negative spread: 310437.4 pips 13/06/2016 23:59:59.747 | 04/06/2015 Negative spread: 390877.4 pips 13/06/2016 23:59:59.747 | 08/06/2015 Negative spread: 840852.4 pips 13/06/2016 23:59:59.747 | 09/06/2015 Negative spread: 10165.3 pips 13/06/2016 23:59:59.747 | 10/06/2015 Negative spread: 321649.7 pips 13/06/2016 23:59:59.747 | 11/06/2015 Negative spread: 233851.6 pips 13/06/2016 23:59:59.747 | 12/06/2015 Negative spread: 356911.1 pips 13/06/2016 23:59:59.747 | 15/06/2015 Negative spread: 302088.4 pips 13/06/2016 23:59:59.747 | 16/06/2015 Negative spread: 241474.1 pips 13/06/2016 23:59:59.747 | 17/06/2015 Negative spread: 518948.3 pips 13/06/2016 23:59:59.747 | 22/06/2015 Negative spread: 295252.5 pips 13/06/2016 23:59:59.747 | 23/06/2015 Negative spread: 261165 pips 13/06/2016 23:59:59.747 | 24/06/2015 Negative spread: 290066.6 pips 13/06/2016 23:59:59.747 | 25/06/2015 Negative spread: 207009.1 pips 13/06/2016 23:59:59.747 | 26/06/2015 Negative spread: 122347.6 pips 13/06/2016 23:59:59.747 | 01/07/2015 Negative spread: 257227 pips 13/06/2016 23:59:59.747 | 02/07/2015 Negative spread: 382292.1 pips 13/06/2016 23:59:59.747 | 03/07/2015 Negative spread: 94580.1 pips 13/06/2016 23:59:59.747 | 05/07/2015 Negative spread: 38531.3 pips 13/06/2016 23:59:59.747 | 06/07/2015 Negative spread: 163594.2 pips 13/06/2016 23:59:59.747 | 09/07/2015 Negative spread: 122429.8 pips 13/06/2016 23:59:59.747 | 10/07/2015 Negative spread: 139864.2 pips 13/06/2016 23:59:59.747 | 13/07/2015 Negative spread: 256186.6 pips 13/06/2016 23:59:59.747 | 14/07/2015 Negative spread: 276936.4 pips 13/06/2016 23:59:59.747 | 15/07/2015 Negative spread: 171471.6 pips 13/06/2016 23:59:59.747 | 16/07/2015 Negative spread: 108603.5 pips 13/06/2016 23:59:59.747 | 17/07/2015 Negative spread: 124232.1 pips 13/06/2016 23:59:59.747 | Backtesting finished
@whis.gg
whis.gg
16 Jun 2016, 00:58
Maybe sum of negative spreads in pips per day is even better approach for this solution.
using System; using System.Collections.Generic; using System.Linq; using cAlgo.API; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class NegativeSpreadAnalyzer : Robot { [Parameter(DefaultValue = 100)] public int MinNegativeSpreadInPipsPerDay { get; set; } public class DateWithNegativeSpread { public DateTime DateTime { get; set; } public double NegativeSpreadInPips { get; set; } } private List<DateWithNegativeSpread> dates = new List<DateWithNegativeSpread>(); private DateTime lastDay; private double negativeSpreadInPipsThisDay = 0; protected override void OnStart() { lastDay = Time.Date; } protected override void OnTick() { if (Time.Date >= lastDay.AddDays(1).Date) { negativeSpreadInPipsThisDay = 0; lastDay = Time.Date; } else if (Symbol.Spread < 0) { negativeSpreadInPipsThisDay -= Symbol.Spread / Symbol.PipSize; } if (negativeSpreadInPipsThisDay >= MinNegativeSpreadInPipsPerDay) { if (dates.Exists(x => x.DateTime.Date == Time.Date)) { dates[dates.FindIndex(x => x.DateTime.Date == Time.Date)].NegativeSpreadInPips = negativeSpreadInPipsThisDay; } else { dates.Add(new DateWithNegativeSpread { DateTime = Time.Date, NegativeSpreadInPips = negativeSpreadInPipsThisDay }); } } } protected override void OnStop() { foreach (var date in dates) { string text = string.Format("{0}\tNegative spread: {1} pips", date.DateTime.ToString("d"), Math.Round(date.NegativeSpreadInPips, 1)); Print(text); } } } }
@whis.gg
whis.gg
16 Jun 2016, 00:41
I quickly wrote this algo which finds all negative spreads and if there is more than defined per day it will save it into collection, when it stops your dates will be printed into log.
Run it as regular backtest with tick data and find all negative spreads. :)
using System; using System.Collections.Generic; using System.Linq; using cAlgo.API; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class NegativeSpreadAnalyzer : Robot { [Parameter(DefaultValue = 10)] public int SpreadsToGetFiltered { get; set; } public class DateWithNegativeSpread { public DateTime DateTime { get; set; } public int Spreads { get; set; } } private List<DateWithNegativeSpread> dates = new List<DateWithNegativeSpread>(); private DateTime last; private int negativeSpreads = 0; protected override void OnStart() { last = Time.Date; } protected override void OnTick() { if (Time.Date >= last.AddDays(1).Date) { negativeSpreads = 0; last = Time.Date; } else if (Symbol.Spread < 0) { negativeSpreads++; } if (negativeSpreads > SpreadsToGetFiltered) { if (dates.Exists(x => x.DateTime.Date == Time.Date)) { dates[dates.FindIndex(x => x.DateTime.Date == Time.Date)].Spreads = negativeSpreads; } else { dates.Add(new DateWithNegativeSpread { DateTime = Time.Date, Spreads = negativeSpreads }); } } } protected override void OnStop() { foreach (var date in dates) { string text = string.Format("{0}\tNegative spreads: {1}", date.DateTime.ToString("d"), date.Spreads); Print(text); } } } }
@whis.gg
whis.gg
15 Jun 2016, 23:35
Again, I advice you to exclude entire day. Position can be executed when spread is above 0 but it can go negative on following tick and make your TakeProfit get hit immediately. Your backtest would give you pretty much the same results.
using System.Collections.Generic; using System.Linq; private List<DateTime> excludedDates = new List<DateTime>(); protected override void OnStart() { excludedDates.Add(new DateTime(2015, 6, 2)); excludedDates.Add(new DateTime(2015, 6, 8)); } protected override void OnTick() { foreach (DateTime excluded in excludedDates) { if (Time.Date == excluded.Date) { return; } } }
@whis.gg
whis.gg
17 Jun 2016, 17:39
Here you go: /algos/indicators/show/1320
@whis.gg