Improves Universe Selection for python

In python algorithm using Universe Selection, the selector method should return a List<Symbol>. To make it more pythonic, we allow returning python list. The conversion is, then, performed in C# side.
This commit is contained in:
AlexCatarino
2017-09-26 13:31:57 +01:00
parent 7d2a67c086
commit 3da8449fea
4 changed files with 20 additions and 48 deletions
+14 -22
View File
@@ -102,8 +102,8 @@ namespace QuantConnect.Algorithm
/// <param name="pycoarse">Defines an initial coarse selection</param>
public void AddUniverse(PyObject pycoarse)
{
var coarse = ToFunc<IEnumerable<CoarseFundamental>, Symbol>(pycoarse);
AddUniverse(coarse);
var coarse = ToFunc<IEnumerable<CoarseFundamental>, object[]>(pycoarse);
AddUniverse(c => coarse(c).Select(x => (Symbol)x));
}
/// <summary>
@@ -114,9 +114,9 @@ namespace QuantConnect.Algorithm
/// <param name="pyfine">Defines a more detailed selection with access to more data</param>
public void AddUniverse(PyObject pycoarse, PyObject pyfine)
{
var coarse = ToFunc<IEnumerable<CoarseFundamental>, Symbol>(pycoarse);
var fine = ToFunc< IEnumerable<FineFundamental>, Symbol>(pyfine);
AddUniverse(coarse, fine);
var coarse = ToFunc<IEnumerable<CoarseFundamental>, object[]>(pycoarse);
var fine = ToFunc<IEnumerable<FineFundamental>, object[]>(pyfine);
AddUniverse(c => coarse(c).Select(x => (Symbol)x), f => fine(f).Select(x => (Symbol)x));
}
/// <summary>
@@ -128,8 +128,8 @@ namespace QuantConnect.Algorithm
/// <param name="pySelector">Function delegate that accepts a DateTime and returns a collection of string symbols</param>
public void AddUniverse(string name, Resolution resolution, PyObject pySelector)
{
var selector = ToFunc<DateTime, string>(pySelector);
AddUniverse(name, resolution, selector);
var selector = ToFunc<DateTime, object[]>(pySelector);
AddUniverse(name, resolution, d => selector(d).Select(x => (string)x));
}
/// <summary>
@@ -140,8 +140,8 @@ namespace QuantConnect.Algorithm
/// <param name="pySelector">Function delegate that accepts a DateTime and returns a collection of string symbols</param>
public void AddUniverse(string name, PyObject pySelector)
{
var selector = ToFunc<DateTime, string>(pySelector);
AddUniverse(name, selector);
var selector = ToFunc<DateTime, object[]>(pySelector);
AddUniverse(name, d => selector(d).Select(x => (string)x));
}
/// <summary>
@@ -155,8 +155,8 @@ namespace QuantConnect.Algorithm
/// <param name="pySelector">Function delegate that accepts a DateTime and returns a collection of string symbols</param>
public void AddUniverse(SecurityType securityType, string name, Resolution resolution, string market, UniverseSettings universeSettings, PyObject pySelector)
{
var selector = ToFunc<DateTime, string>(pySelector);
AddUniverse(securityType, name, resolution, market, universeSettings, selector);
var selector = ToFunc<DateTime, object[]>(pySelector);
AddUniverse(securityType, name, resolution, market, universeSettings, d => selector(d).Select(x => (string)x));
}
/// <summary>
@@ -403,7 +403,6 @@ namespace QuantConnect.Algorithm
/// Gets the symbols/string from a PyObject
/// </summary>
/// <param name="pyObject">PyObject containing symbols</param>
/// <param name="isEquity"></param>
/// <returns>List of symbols</returns>
public List<Symbol> GetSymbolsFromPyObject(PyObject pyObject)
{
@@ -465,26 +464,19 @@ namespace QuantConnect.Algorithm
/// <typeparam name="TSecond">The output type</typeparam>
/// <param name="pyObject">The python method</param>
/// <returns>A <see cref="System.Func{T, TResult}"/> that encapsulates the python method</returns>
private Func<T, IEnumerable<TSecond>> ToFunc<T, TSecond>(PyObject pyObject)
private Func<T, TSecond> ToFunc<T, TSecond>(PyObject pyObject)
{
var testMod =
"from clr import AddReference\n" +
"AddReference(\"System\")\n" +
"AddReference(\"System.Collections\")\n" +
"AddReference(\"QuantConnect.Common\")\n" +
"from System import Func\n" +
"from System.Collections.Generic import IEnumerable\n" +
"from QuantConnect import Symbol\n" +
"from QuantConnect.Data.Fundamental import FineFundamental\n" +
"from QuantConnect.Data.UniverseSelection import CoarseFundamental\n" +
"def to_func(pyobject, in_type, out_type):\n" +
" return Func[in_type, IEnumerable[out_type]](pyobject)";
" return Func[in_type, out_type](pyobject)";
using (Py.GIL())
{
dynamic toFunc = PythonEngine.ModuleFromString("x", testMod).GetAttr("to_func");
return toFunc(pyObject, typeof(T), typeof(TSecond))
.AsManagedObject(typeof(Func<T, IEnumerable<TSecond>>));
return toFunc(pyObject, typeof(T), typeof(TSecond)).AsManagedObject(typeof(Func<T, TSecond>));
}
}
}