Custom Library .dll works in one project but not another with same settings
Created at 04 Jan 2017, 17:00
AN
Custom Library .dll works in one project but not another with same settings
04 Jan 2017, 17:00
Hi,
I have created a custom class dll library to use in my cbots it works in one project but not another. It is probably easier to see in video so I did a quick video so you can see the actual issue.
https://www.youtube.com/watch?v=wDAKVkx2FxA&feature=youtu.be
My Questions:
- Do you need to put the custom dll library files in a certain directory on development machine and or the live machine running the robots?
- Why is the custom dll library working with one robot and not the other?
- Is there a log file that will tell me the exact error. I.E. the assembly that it is unable to load.
I will also include the full source files below in case that is something in my code causing the issue:
The Custom dll library file.
// This is the custom library dll file using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; // cAlgo References using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; //using cAlgo.API.Requests; namespace AI { public class TradeManager { private Robot myRobot; public TradeManager(Robot robot) { myRobot = robot; } /// <summary> /// This will close all open trades for the robotName when takePipsProfit is reached. /// It will close all open trades when all combined trades have make the specified pips profit. /// </summary> /// <param name="robotName">The label that this robot uses when opening trades.</param> /// <param name="takePipsProfit">The number of pips profit need for all open trades to be closed.</param> /// <returns>Returns true if trades are closed and false if no trades are closed.</returns> public bool CloseAllTradesWhenPipsReached(string robotName, double takePipsProfit) { var openPositions = myRobot.Positions.FindAll(robotName, myRobot.Symbol); double totalPips = 0.0; if (openPositions.Length > 0) { foreach (var order in openPositions) { totalPips += order.Pips; } if (totalPips >= takePipsProfit) { // Close all open orders for this robot for overall profit foreach (var order in openPositions) { myRobot.ClosePositionAsync(order); } return true; } } return false; } public void PrintTestMessage() { myRobot.Print("Trade Manager Class is working"); } } public enum TradeDirection { None, Buy, Sell } public enum AllowedTradeTypes { All, Buy, Sell } public enum TrendDirection { None, Up, Down } }
The TestBot that works with the library
// This TestBot works with my custom dll library using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; using AI; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)] public class TestBot : Robot { private TradeManager myTradeManager; [Parameter(DefaultValue = 0.0)] public double Parameter { get; set; } protected override void OnStart() { // Put your initialization logic here myTradeManager = new TradeManager(this); myTradeManager.PrintTestMessage(); } protected override void OnTick() { // Put your core logic here } protected override void OnStop() { // Put your deinitialization logic here } } }
My Trading Robot not working with the library
// The Robot I want to work with does not work with the custom dll library using System; using System.Linq; using cAlgo.API; using cAlgo.API.Indicators; using cAlgo.API.Internals; using cAlgo.Indicators; using AI; namespace cAlgo { [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)] public class BBandsValueTrade : Robot { private TradeManager myTradeManager; private BollingerBands myBB; private double lastTradePrice = 0.0; private long myTradeVolume; private TradeDirection myTradeDirection = TradeDirection.None; [Parameter("Robot Name", DefaultValue = "BBands Value Trade")] public string MyRobotName { get; set; } [Parameter("Trade Size (Lots)", DefaultValue = 0.01, MinValue = 0.01, Step = 0.01)] public double MyTradeSize { get; set; } [Parameter("Maximum Open Trades", DefaultValue = 5, MinValue = 1)] public int MyMaxOpenTrades { get; set; } [Parameter("Take Profit (Pips)", DefaultValue = 10.0, MinValue = 1.0)] public double MyTakeProfit { get; set; } [Parameter("Allowed Trade Directions", DefaultValue = AllowedTradeTypes.Buy)] public AllowedTradeTypes MyAllowedTradeDirections { get; set; } [Parameter("Source")] public DataSeries Source { get; set; } [Parameter("BB Periods", MinValue = 1, DefaultValue = 650)] public int BBPeriod { get; set; } [Parameter("BB Std", MinValue = 1, DefaultValue = 3)] public int BBStd { get; set; } protected override void OnStart() { Positions.Opened += OnPositionsOpened; myTradeManager = new TradeManager(this); myBB = Indicators.BollingerBands(Source, BBPeriod, BBStd, MovingAverageType.Simple); myTradeVolume = Symbol.QuantityToVolume(MyTradeSize); // This code checks whether any existing trades have been opened with this robot. // The only reason this would happen is if you stopped the robot with open trades // then started the robot again. var myOpenPositions = Positions.FindAll(MyRobotName, Symbol); if (myOpenPositions.Length > 0) { if (myOpenPositions[0].TradeType == TradeType.Buy) { myTradeDirection = TradeDirection.Buy; } else { myTradeDirection = TradeDirection.Sell; } } // No open positions so set trade direction to none else { myTradeDirection = TradeDirection.None; } } void OnPositionsOpened(PositionOpenedEventArgs obj) { lastTradePrice = obj.Position.EntryPrice; if (obj.Position.TradeType == TradeType.Buy) { myTradeDirection = TradeDirection.Buy; } else { myTradeDirection = TradeDirection.Sell; } } protected override void OnTick() { // Get All Open Positions for Current Symbol on This Robot var myOpenPositions = Positions.FindAll(MyRobotName, Symbol); if (myOpenPositions.Length > 0) { if (myTradeManager.CloseAllTradesWhenPipsReached(MyRobotName, MyTakeProfit)) { myTradeDirection = TradeDirection.None; } } } protected override void OnBar() { // Get All Open Positions for Current Symbol on This Robot var myOpenPositions = Positions.FindAll(MyRobotName, Symbol); // Only Open new trades or check for new trades if open positions // is less than max open trades allowed. if (myOpenPositions.Length < MyMaxOpenTrades) { var currentClose = MarketSeries.Close.Last(1); var previousClose = MarketSeries.Close.Last(2); var previousBottomBB = myBB.Bottom.Last(2); var previousTopBB = myBB.Top.Last(2); if (MyAllowedTradeDirections.Equals(AllowedTradeTypes.Buy) || MyAllowedTradeDirections.Equals(AllowedTradeTypes.All)) { // Only try to open new buy trade if no trades are open or existing buy trades are open if (myTradeDirection == TradeDirection.None || myTradeDirection == TradeDirection.Buy) { if (previousClose <= previousBottomBB && currentClose > previousBottomBB) { // Only open new trade if a new bar has closed since last trade // probably not needed for onBar just onTick method if (currentClose > lastTradePrice || currentClose < lastTradePrice) { // Open Buy Postion var result = ExecuteMarketOrder(TradeType.Buy, Symbol, myTradeVolume, MyRobotName); } } } } if (MyAllowedTradeDirections.Equals(AllowedTradeTypes.Sell) || MyAllowedTradeDirections.Equals(AllowedTradeTypes.All)) { // Only try to open new sell trade if no trades are open or existing sell trades are open if (myTradeDirection == TradeDirection.None || myTradeDirection == TradeDirection.Sell) { if (previousClose >= previousTopBB && currentClose < previousTopBB) { // Only open new trade if a new bar has closed since last trade // probably not needed for onBar just onTick method if (currentClose > lastTradePrice || currentClose < lastTradePrice) { // Open Sell Postion var result = ExecuteMarketOrder(TradeType.Sell, Symbol, myTradeVolume, MyRobotName); } } } } } } protected override void OnStop() { // Put your deinitialization logic here } } }
anthonyirwin82
05 Jan 2017, 15:38
Found Solution To Problem
Hi,
After doing some experimentation I found that the issue was not the custom class library but using the enumeration as a parameter for the robot.
I think this really sucks as I have to use an integer instead and cast that back the enumeration in the OnStart() method. It means that the robot interface for starting the robot has a meaningless number that has to be entered instead of a descriptive word.
I used Enums in MT4 fine and find it rather sad that they are not working in cAlgo which is supposed to be a more advanced system due to using C# programming language.
Anyway thought I would let everyone know what the problem was.
Thanks,
Anthony
@anthonyirwin82