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