Skip to content

Commit 1900e1d

Browse files
authoredJun 12, 2018
Merge pull request QuantConnect#2109 from QuantConnect/bug-2091-indicator-register-throws
Improves Extensions.TryConvert to avoid test by exception
2 parents e04f3be + a4233c7 commit 1900e1d

File tree

3 files changed

+56
-11
lines changed

3 files changed

+56
-11
lines changed
 

‎Common/Extensions.cs

+13-9
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,7 @@ public static string ToSafeString(this PyObject pyObject)
10391039
public static bool TryConvert<T>(this PyObject pyObject, out T result)
10401040
{
10411041
result = default(T);
1042+
var type = typeof(T);
10421043

10431044
if (pyObject == null)
10441045
{
@@ -1049,26 +1050,29 @@ public static bool TryConvert<T>(this PyObject pyObject, out T result)
10491050
{
10501051
try
10511052
{
1052-
if (typeof(T) == typeof(Type))
1053+
// Special case: Type
1054+
if (typeof(Type).IsAssignableFrom(type))
1055+
{
1056+
result = (T)pyObject.AsManagedObject(type);
1057+
return true;
1058+
}
1059+
1060+
// Special case: IEnumerable
1061+
if (typeof(IEnumerable).IsAssignableFrom(type))
10531062
{
1054-
result = (T) (object) pyObject.As<Type>();
1063+
result = (T)pyObject.AsManagedObject(type);
10551064
return true;
10561065
}
10571066

10581067
var pythonType = pyObject.GetPythonType();
10591068
var csharpType = pythonType.As<Type>();
10601069

1061-
if (!typeof(T).IsAssignableFrom(csharpType))
1070+
if (!type.IsAssignableFrom(csharpType))
10621071
{
10631072
return false;
10641073
}
10651074

1066-
result = (T) pyObject.AsManagedObject(typeof(T));
1067-
1068-
if (result is IEnumerable)
1069-
{
1070-
return true;
1071-
}
1075+
result = (T)pyObject.AsManagedObject(type);
10721076

10731077
// If the PyObject type and the managed object names are the same,
10741078
// pyObject is a C# object wrapped in PyObject, in this case return true

‎Tests/Algorithm/AlgorithmRegisterIndicatorTests.cs

+27-2
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public void RegistersIndicatorProperly()
8484
}
8585
}
8686

87-
[Test, Ignore]
87+
[Test, Category("TravisExclude")]
8888
public void RegistersIndicatorProperlyPython()
8989
{
9090
var expected = 0;
@@ -117,7 +117,7 @@ public void RegistersIndicatorProperlyPython()
117117
}
118118
}
119119

120-
[Test, Ignore]
120+
[Test, Category("TravisExclude")]
121121
public void RegisterPythonCustomIndicatorProperly()
122122
{
123123
using (Py.GIL())
@@ -144,5 +144,30 @@ public void RegisterPythonCustomIndicatorProperly()
144144
Assert.Throws<ArgumentException>(() => _algorithm.RegisterIndicator(_spy, badIndicator, Resolution.Minute));
145145
}
146146
}
147+
148+
[Test, Category("TravisExclude")]
149+
public void RegistersIndicatorProperlyPythonScript()
150+
{
151+
var code = @"from clr import AddReference
152+
AddReference('System')
153+
AddReference('QuantConnect.Algorithm')
154+
AddReference('QuantConnect.Indicators')
155+
AddReference('QuantConnect.Common')
156+
157+
from System import *
158+
from QuantConnect import *
159+
from QuantConnect.Algorithm import *
160+
from QuantConnect.Indicators import *
161+
162+
algo = QCAlgorithm()
163+
forex = algo.AddForex('EURUSD', Resolution.Daily)
164+
indicator = IchimokuKinkoHyo('EURUSD', 9, 26, 26, 52, 26, 26)
165+
algo.RegisterIndicator(forex.Symbol, indicator, Resolution.Daily)";
166+
167+
using (Py.GIL())
168+
{
169+
Assert.DoesNotThrow(() => PythonEngine.ModuleFromString("RegistersIndicatorProperlyPythonScript", code));
170+
}
171+
}
147172
}
148173
}

‎Tests/Common/Util/ExtensionsTests.cs

+16
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,23 @@ public void PyObjectTryConvertAD()
385385
Assert.IsTrue(canConvert);
386386
Assert.IsNotNull(indicatorBaseTradeBar);
387387
Assert.IsAssignableFrom<AccumulationDistribution>(indicatorBaseTradeBar);
388+
}
389+
390+
[Test, Category("TravisExclude")]
391+
public void PyObjectTryConvertSymbolArray()
392+
{
393+
PyObject value;
394+
using (Py.GIL())
395+
{
396+
// Wrap a Symbol Array around a PyObject and convert it back
397+
value = new PyList(new[] { Symbols.SPY.ToPython(), Symbols.AAPL.ToPython() });
398+
}
388399

400+
Symbol[] symbols;
401+
var canConvert = value.TryConvert(out symbols);
402+
Assert.IsTrue(canConvert);
403+
Assert.IsNotNull(symbols);
404+
Assert.IsAssignableFrom<Symbol[]>(symbols);
389405
}
390406

391407
[Test, Category("TravisExclude")]

0 commit comments

Comments
 (0)
Please sign in to comment.