need help to run my first bot
need help to run my first bot
24 Aug 2019, 23:29
hello everyone
I have been interested in coding bot in calgo recently since i found it way more easier to learn than mql but i have no background at coding at all and by watching some tutorial this is my frist bot:
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 NewcBot : Robot { [Parameter("Instance Name", DefaultValue = "001")] public string InstanceName { get; set; } [Parameter("Lot Size", DefaultValue = 0.1)] public double LotSize { get; set; } [Parameter("Source Dema")] public DataSeries SourceDema { get; set; } [Parameter("Source Tema")] public DataSeries SourceTema { get; set; } [Parameter("Period Dema", DefaultValue = 5, MinValue = 5, MaxValue = 100)] public int PeriodDema { get; set; } [Parameter("Period Tema", DefaultValue = 5, MinValue = 5, MaxValue = 100)] public int PeriodTema { get; set; } [Parameter("Calculate OnBar", DefaultValue = false)] public bool CalculateOnBar { get; set; } private DEMA Dema { get; set; } private TEMA Tema { get; set; } protected override void OnStart() { Dema = Indicators.GetIndicator<DEMA>(SourceDema, PeriodDema); Tema = Indicators.GetIndicator<TEMA>(SourceTema, PeriodTema); // Put your initialization logic here } protected override void OnTick() { if (CalculateOnBar) { return; } ManagePostions(); } protected override void OnBar() { if (!CalculateOnBar) { return; } ManagePostions(); } protected override void OnStop() { // Put your deinitialization logic here } private void ManagePostions() { if (Tema.Result.LastValue > Dema.Result.LastValue) { if (!IsPositionOpenByType(TradeType.Buy)) { OpenPosition(TradeType.Buy); } ClosePosition(TradeType.Sell); } if (Tema.Result.LastValue < Dema.Result.LastValue) { if (!IsPositionOpenByType(TradeType.Sell)) { OpenPosition(TradeType.Sell); } ClosePosition(TradeType.Buy); } } private void OpenPosition(TradeType type) { long Volume = Symbol.QuantityToVolume(LotSize); ExecuteMarketOrder(type, this.SymbolName, Volume, InstanceName, null, null); } private void ClosePosition(TradeType type) { var P = Positions.Find(InstanceName, this.SymbolName, type); if (P != null) { ClosePosition(P); } } private bool IsPositionOpenByType(TradeType type) { var P = Positions.FindAll(InstanceName, SymbolName, type); if (P.Count() >= 1) { return true; } return false; } } }
and these are the errors i get when building:
Error CS1061: 'cAlgo.Indicators.TEMA' does not contain a definition for 'Result' and no extension method 'Result' accepting a first argument of type 'cAlgo.Indicators.TEMA' could be found (are you missing a using directive or an assembly reference?)
Error CS1061: 'cAlgo.Indicators.DEMA' does not contain a definition for 'Result' and no extension method 'Result' accepting a first argument of type 'cAlgo.Indicators.DEMA' could be found (are you missing a using directive or an assembly reference?)
Error CS0618: 'cAlgo.API.Internals.Symbol.QuantityToVolume(double)' is obsolete: 'Use QuantityToVolumeInUnits instead'
Can anyone please teach me how to fix this?
Replies
alisalehicontact
25 Aug 2019, 12:20
RE:
Tatsuya said:
You don't need get set for variables,try this one instead:
private DEMA Dema; private TEMA Tema;I'd like to see the DEMA and TEMA code if the code above doesn't work.
Also the last error is just telling you that there is a newer API that does the same thing.
You can simply replace QuantityToVolume with QuantityToVolumeInUnits.
Thanks for your reply,that didnt work,this is the code for DEMA:
using System; using cAlgo.API; using cAlgo.API.Indicators; namespace cAlgo.Indicators { [Indicator(IsOverlay = true, AccessRights = AccessRights.None)] public class DEMA : Indicator { [Parameter] public DataSeries DataSource { get; set; } [Output("DEMA",Color = Colors.Yellow)] public IndicatorDataSeries dema { get; set; } [Parameter(DefaultValue = 14)] public int Period { get; set; } private ExponentialMovingAverage ema; private ExponentialMovingAverage ema2; protected override void Initialize() { ema = Indicators.ExponentialMovingAverage(DataSource,Period);//i need the correct DataSeries ema2 = Indicators.ExponentialMovingAverage(ema.Result,Period); } public override void Calculate(int index) { dema[index] = (2* ema.Result[index] - ema2.Result[index]); } }
and this is for TEMA:
using System; using cAlgo.API; using cAlgo.API.Indicators; namespace cAlgo.Indicators { [Indicator(IsOverlay = true, AccessRights = AccessRights.None)] public class TEMA : Indicator { [Output("TEMA")] public IndicatorDataSeries tema { get; set; } [Parameter("Data Source")] public DataSeries DataSource { get; set; } [Parameter(DefaultValue = 14)] public int Period { get; set; } private ExponentialMovingAverage ema1; private ExponentialMovingAverage ema2; private ExponentialMovingAverage ema3; protected override void Initialize() { ema1 = Indicators.ExponentialMovingAverage(DataSource,Period); ema2 = Indicators.ExponentialMovingAverage(ema1.Result,Period); ema3 = Indicators.ExponentialMovingAverage(ema2.Result,Period); } public override void Calculate(int index) { tema[index] = 3*ema1.Result[index] - 3*ema2.Result[index] + ema3.Result[index]; } }
and if I replace replace QuantityToVolume with QuantityToVolumeInUnits I get this Error:
Error CS0266: Cannot implicitly convert type 'double' to 'long'. An explicit conversion exists (are you missing a cast?)
and by the way I havent write the code for this two indicator, TEMA & DEMA cods are for user
qualitiedx2 |
@alisalehicontact
Tatsuya
25 Aug 2019, 21:38
Hope this code helps.
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 NewcBot : Robot { [Parameter("Instance Name", DefaultValue = "001")] public string InstanceName { get; set; } [Parameter("Lot Size", DefaultValue = 0.1)] public double LotSize { get; set; } [Parameter("Source Dema")] public DataSeries SourceDema { get; set; } [Parameter("Source Tema")] public DataSeries SourceTema { get; set; } [Parameter("Period Dema", DefaultValue = 5, MinValue = 5, MaxValue = 100)] public int PeriodDema { get; set; } [Parameter("Period Tema", DefaultValue = 5, MinValue = 5, MaxValue = 100)] public int PeriodTema { get; set; } [Parameter("Calculate OnBar", DefaultValue = false)] public bool CalculateOnBar { get; set; } private DEMA Dema; private TEMA Tema; protected override void OnStart() { Dema = Indicators.GetIndicator<DEMA>(SourceDema, PeriodDema); Tema = Indicators.GetIndicator<TEMA>(SourceTema, PeriodTema); } protected override void OnTick() { if (CalculateOnBar) { return; } ManagePostions(); } protected override void OnBar() { if (!CalculateOnBar) { return; } ManagePostions(); } protected override void OnStop() { // Put your deinitialization logic here } private void ManagePostions() { // When you want to grab data from indicators you need their IndicatorDataSeries. // Result wasn't either in one of them,in your case you had tema and dema. if (Tema.tema.LastValue > Dema.dema.LastValue) { if (!IsPositionOpenByType(TradeType.Buy)) { OpenPosition(TradeType.Buy); } ClosePosition(TradeType.Sell); } if (Tema.tema.LastValue < Dema.dema.LastValue) { if (!IsPositionOpenByType(TradeType.Sell)) { OpenPosition(TradeType.Sell); } ClosePosition(TradeType.Buy); } } private void OpenPosition(TradeType type) { // QuantityToVolumeInUnits returns double,not long therefore you either have to put it into double or cast it to long. // e.g. long Volume = (long)Symbol.QuantityToVolumeInUnits(LotSize); this also works. double Volume = Symbol.QuantityToVolumeInUnits(LotSize); ExecuteMarketOrder(type, this.SymbolName, Volume, InstanceName, null, null); } private void ClosePosition(TradeType type) { var P = Positions.Find(InstanceName, this.SymbolName, type); if (P != null) { ClosePosition(P); } } private bool IsPositionOpenByType(TradeType type) { var P = Positions.FindAll(InstanceName, SymbolName, type); if (P.Count() >= 1) { return true; } return false; } } }
@Tatsuya
alisalehicontact
26 Aug 2019, 13:49
RE:
Tatsuya said:
Hope this code helps.
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 NewcBot : Robot { [Parameter("Instance Name", DefaultValue = "001")] public string InstanceName { get; set; } [Parameter("Lot Size", DefaultValue = 0.1)] public double LotSize { get; set; } [Parameter("Source Dema")] public DataSeries SourceDema { get; set; } [Parameter("Source Tema")] public DataSeries SourceTema { get; set; } [Parameter("Period Dema", DefaultValue = 5, MinValue = 5, MaxValue = 100)] public int PeriodDema { get; set; } [Parameter("Period Tema", DefaultValue = 5, MinValue = 5, MaxValue = 100)] public int PeriodTema { get; set; } [Parameter("Calculate OnBar", DefaultValue = false)] public bool CalculateOnBar { get; set; } private DEMA Dema; private TEMA Tema; protected override void OnStart() { Dema = Indicators.GetIndicator<DEMA>(SourceDema, PeriodDema); Tema = Indicators.GetIndicator<TEMA>(SourceTema, PeriodTema); } protected override void OnTick() { if (CalculateOnBar) { return; } ManagePostions(); } protected override void OnBar() { if (!CalculateOnBar) { return; } ManagePostions(); } protected override void OnStop() { // Put your deinitialization logic here } private void ManagePostions() { // When you want to grab data from indicators you need their IndicatorDataSeries. // Result wasn't either in one of them,in your case you had tema and dema. if (Tema.tema.LastValue > Dema.dema.LastValue) { if (!IsPositionOpenByType(TradeType.Buy)) { OpenPosition(TradeType.Buy); } ClosePosition(TradeType.Sell); } if (Tema.tema.LastValue < Dema.dema.LastValue) { if (!IsPositionOpenByType(TradeType.Sell)) { OpenPosition(TradeType.Sell); } ClosePosition(TradeType.Buy); } } private void OpenPosition(TradeType type) { // QuantityToVolumeInUnits returns double,not long therefore you either have to put it into double or cast it to long. // e.g. long Volume = (long)Symbol.QuantityToVolumeInUnits(LotSize); this also works. double Volume = Symbol.QuantityToVolumeInUnits(LotSize); ExecuteMarketOrder(type, this.SymbolName, Volume, InstanceName, null, null); } private void ClosePosition(TradeType type) { var P = Positions.Find(InstanceName, this.SymbolName, type); if (P != null) { ClosePosition(P); } } private bool IsPositionOpenByType(TradeType type) { var P = Positions.FindAll(InstanceName, SymbolName, type); if (P.Count() >= 1) { return true; } return false; } } }
Thanks a lot man :) you just made my day,it works now
I did some backtest and optimization but the results were not great,then I changed it into two different Dema instead of Tema&Dema and the results were better,but I need to Add one more indicator to filter out the false signals and I think AdxVma is the right choise, this way when market is flat bot wont open a position.
This is the code for AdxVma:
using System; using cAlgo.API; namespace cAlgo.Indicators { [Indicator(IsOverlay = true, AccessRights = AccessRights.None)] public class AdxVma : Indicator { private double _k; private IndicatorDataSeries _iSeries; private IndicatorDataSeries _mdiSeries; private IndicatorDataSeries _mdmSeries; private IndicatorDataSeries _pdiSeries; private IndicatorDataSeries _pdmSeries; [Parameter] public DataSeries Source { get; set; } [Parameter(DefaultValue = 6)] public int Period { get; set; } [Output("Rising", Color = Colors.Green, PlotType = PlotType.Points, Thickness = 2)] public IndicatorDataSeries Rising { get; set; } [Output("Falling", Color = Colors.Red, PlotType = PlotType.Points, Thickness = 2)] public IndicatorDataSeries Falling { get; set; } [Output("Flat", Color = Colors.Gold, PlotType = PlotType.Points, Thickness = 2)] public IndicatorDataSeries Flat { get; set; } [Output("Result", Color = Colors.Black)] public IndicatorDataSeries Result { get; set; } protected override void Initialize() { _pdmSeries = CreateDataSeries(); _mdmSeries = CreateDataSeries(); _pdiSeries = CreateDataSeries(); _mdiSeries = CreateDataSeries(); _iSeries = CreateDataSeries(); _k = 1.0/Period; } public override void Calculate(int index) { if (index < Period) { _pdmSeries[index] = 0; _mdmSeries[index] = 0; _pdiSeries[index] = 0; _mdiSeries[index] = 0; _iSeries[index] = 0; _pdmSeries[index] = 0; Result[index] = Source[index]; return; } double pdm = Math.Max((Source[index] - Source[index - 1]), 0); double mdm = Math.Max((Source[index - 1] - Source[index]), 0); _pdmSeries[index] = ((1 - _k)*_pdmSeries[index - 1] + _k*pdm); _mdmSeries[index] = ((1 - _k)*_mdmSeries[index - 1] + _k*mdm); double sum = _pdmSeries[index] + _mdmSeries[index]; double pdi = 0.0; double mdi = 0.0; if (sum > double.Epsilon) { pdi = _pdmSeries[index]/sum; mdi = _mdmSeries[index]/sum; } _pdiSeries[index] = ((1 - _k)*_pdiSeries[index - 1] + _k*pdi); _mdiSeries[index] = ((1 - _k)*_mdiSeries[index - 1] + _k*mdi); double diff = Math.Abs(_pdiSeries[index] - _mdiSeries[index]); sum = _pdiSeries[index] + _mdiSeries[index]; if (sum > double.Epsilon) _iSeries[index] = ((1 - _k)*_iSeries[1] + _k*diff/sum); double hhv = Math.Max(_iSeries[index], _iSeries.Maximum(Period)); double llv = Math.Min(_iSeries[index], _iSeries.Minimum(Period)); diff = hhv - llv; double vIndex = 0; if (diff > double.Epsilon) vIndex = (_iSeries[index] - llv)/diff; Result[index] = (1 - _k*vIndex)*Result[index - 1] + _k*vIndex*Source[index]; Rising[index] = double.NaN; Falling[index] = double.NaN; Flat[index] = double.NaN; if (Result.IsRising()) Rising[index] = Result[index]; else if (Result.IsFalling()) Falling[index] = Result[index]; else Flat[index] = Result[index]; } } }
But now I have an other problem adding this code to my bot, I want the logic be like if AdxVma wasent flat open a position but this dosent work and I know mainly because my lack of knowledge in c# :(
this is the new code:
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 crossover2 : Robot { [Parameter("Instance Name", DefaultValue = "002")] public string InstanceName { get; set; } [Parameter("Lot Size", DefaultValue = 0.1)] public double LotSize { get; set; } [Parameter("Source Dema")] public DataSeries SourceDema { get; set; } [Parameter("Source Dema1")] public DataSeries SourceDema1 { get; set; } [Parameter("Period Dema", DefaultValue = 50, MinValue = 5, MaxValue = 100)] public int PeriodDema { get; set; } [Parameter("Period Dema1", DefaultValue = 27, MinValue = 5, MaxValue = 100)] public int PeriodDema1 { get; set; } [Parameter("Source AdxVma")] public DataSeries SourceAdxVma { get; set; } [Parameter("Period AdxVma", DefaultValue = 6, MinValue = 6, MaxValue = 14)] public int PeriodAdxVma { get; set; } [Parameter("Calculate OnBar", DefaultValue = false)] public bool CalculateOnBar { get; set; } private DEMA Dema; private DEMA Dema1; private AdxVma AdxVma; protected override void OnStart() { Dema = Indicators.GetIndicator<DEMA>(SourceDema, PeriodDema); Dema1 = Indicators.GetIndicator<DEMA>(SourceDema1, PeriodDema1); AdxVma = Indicators.GetIndicator<AdxVma>(SourceAdxVma, PeriodAdxVma); } protected override void OnTick() { if (CalculateOnBar) { return; } ManagePostions(); } protected override void OnBar() { if (!CalculateOnBar) { return; } ManagePostions(); } protected override void OnStop() { // Put your deinitialization logic here } private void ManagePostions() { // When you want to grab data from indicators you need their IndicatorDataSeries. // Result wasn't either in one of them,in your case you had tema and dema. if (Dema1.dema.LastValue > Dema.dema.LastValue) { if (!IsPositionOpenByType(TradeType.Buy)) { if (AdxVma.adxvma.Lastvalue != Flat[index] = Result[index]) OpenPosition(TradeType.Buy); } ClosePosition(TradeType.Sell); } if (Dema1.dema.LastValue < Dema.dema.LastValue) { if (!IsPositionOpenByType(TradeType.Sell)) { OpenPosition(TradeType.Sell); } ClosePosition(TradeType.Buy); } } private void OpenPosition(TradeType type) { // QuantityToVolumeInUnits returns double,not long therefore you either have to put it into double or cast it to long. // e.g. long Volume = (long)Symbol.QuantityToVolumeInUnits(LotSize); this also works. double Volume = Symbol.QuantityToVolumeInUnits(LotSize); ExecuteMarketOrder(type, this.SymbolName, Volume, InstanceName, null, null); } private void ClosePosition(TradeType type) { var P = Positions.Find(InstanceName, this.SymbolName, type); if (P != null) { ClosePosition(P); } } private bool IsPositionOpenByType(TradeType type) { var P = Positions.FindAll(InstanceName, SymbolName, type); if (P.Count() >= 1) { return true; } return false; } } }
@alisalehicontact
Tatsuya
25 Aug 2019, 10:58
You don't need get set for variables,try this one instead:
I'd like to see the DEMA and TEMA code if the code above doesn't work.
Also the last error is just telling you that there is a newer API that does the same thing.
You can simply replace QuantityToVolume with QuantityToVolumeInUnits.
@Tatsuya