Skip to content

Commit 18d83fb

Browse files
committed
Updates python framework to support python datetime
Updates nuget package to support conversion from C# DateTime to python datetime. Updates algorithms to reflect this change.
1 parent 326e804 commit 18d83fb

33 files changed

Lines changed: 142 additions & 173 deletions

Algorithm.CSharp/QuantConnect.Algorithm.CSharp.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
44
<PropertyGroup>
@@ -63,7 +63,7 @@
6363
<HintPath>..\packages\NodaTime.1.3.1\lib\net35-Client\NodaTime.dll</HintPath>
6464
</Reference>
6565
<Reference Include="Python.Runtime, Version=4.0.0.1, Culture=neutral, processorArchitecture=AMD64">
66-
<HintPath>..\packages\QuantConnect.pythonnet.1.0.1.1\lib\UCS4\Python.Runtime.dll</HintPath>
66+
<HintPath>..\packages\QuantConnect.pythonnet.1.0.2\lib\UCS4\Python.Runtime.dll</HintPath>
6767
<Private>True</Private>
6868
</Reference>
6969
<Reference Include="System" />
@@ -188,9 +188,9 @@
188188
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
189189
</PropertyGroup>
190190
<Error Condition="!Exists('..\packages\Accord.3.3.0\build\Accord.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Accord.3.3.0\build\Accord.targets'))" />
191-
<Error Condition="!Exists('..\packages\QuantConnect.pythonnet.1.0.1.1\build\QuantConnect.pythonnet.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\QuantConnect.pythonnet.1.0.1.1\build\QuantConnect.pythonnet.targets'))" />
191+
<Error Condition="!Exists('..\packages\QuantConnect.pythonnet.1.0.2\build\QuantConnect.pythonnet.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\QuantConnect.pythonnet.1.0.2\build\QuantConnect.pythonnet.targets'))" />
192192
</Target>
193-
<Import Project="..\packages\QuantConnect.pythonnet.1.0.1.1\build\QuantConnect.pythonnet.targets" Condition="Exists('..\packages\QuantConnect.pythonnet.1.0.1.1\build\QuantConnect.pythonnet.targets')" />
193+
<Import Project="..\packages\QuantConnect.pythonnet.1.0.2\build\QuantConnect.pythonnet.targets" Condition="Exists('..\packages\QuantConnect.pythonnet.1.0.2\build\QuantConnect.pythonnet.targets')" />
194194
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
195195
Other similar extension points exist, see Microsoft.Common.targets.
196196
<Target Name="BeforeBuild">

Algorithm.CSharp/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
<package id="Accord.Statistics" version="3.3.0" targetFramework="net45" />
77
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
88
<package id="NodaTime" version="1.3.1" targetFramework="net45" />
9-
<package id="QuantConnect.pythonnet" version="1.0.1.1" targetFramework="net45" />
9+
<package id="QuantConnect.pythonnet" version="1.0.2" targetFramework="net45" />
1010
</packages>

Algorithm.FSharp/QuantConnect.Algorithm.FSharp.fsproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
<Private>True</Private>
4545
</Reference>
4646
<Reference Include="Python.Runtime">
47-
<HintPath>..\packages\QuantConnect.pythonnet.1.0.1.1\lib\UCS4\Python.Runtime.dll</HintPath>
47+
<HintPath>..\packages\QuantConnect.pythonnet.1.0.2\lib\UCS4\Python.Runtime.dll</HintPath>
4848
<Private>True</Private>
4949
</Reference>
5050
<Reference Include="System" />
@@ -89,12 +89,12 @@
8989
</Otherwise>
9090
</Choose>
9191
<Import Project="$(FSharpTargetsPath)" />
92-
<Import Project="..\packages\QuantConnect.pythonnet.1.0.1.1\build\QuantConnect.pythonnet.targets" Condition="Exists('..\packages\QuantConnect.pythonnet.1.0.1.1\build\QuantConnect.pythonnet.targets')" />
92+
<Import Project="..\packages\QuantConnect.pythonnet.1.0.2\build\QuantConnect.pythonnet.targets" Condition="Exists('..\packages\QuantConnect.pythonnet.1.0.2\build\QuantConnect.pythonnet.targets')" />
9393
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
9494
<PropertyGroup>
9595
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
9696
</PropertyGroup>
97-
<Error Condition="!Exists('..\packages\QuantConnect.pythonnet.1.0.1.1\build\QuantConnect.pythonnet.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\QuantConnect.pythonnet.1.0.1.1\build\QuantConnect.pythonnet.targets'))" />
97+
<Error Condition="!Exists('..\packages\QuantConnect.pythonnet.1.0.2\build\QuantConnect.pythonnet.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\QuantConnect.pythonnet.1.0.2\build\QuantConnect.pythonnet.targets'))" />
9898
</Target>
9999
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
100100
Other similar extension points exist, see Microsoft.Common.targets.

Algorithm.FSharp/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<packages>
33
<package id="NodaTime" version="1.3.1" targetFramework="net45" />
4-
<package id="QuantConnect.pythonnet" version="1.0.1.1" targetFramework="net45" />
4+
<package id="QuantConnect.pythonnet" version="1.0.2" targetFramework="net45" />
55
</packages>

Algorithm.Python/AddRemoveSecurityRegressionAlgorithm.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,24 @@ def Initialize(self):
3838

3939
def OnData(self, data):
4040
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.'''
41-
if self._lastAction is not None and self._lastAction.Date == self.Time.Date:
41+
if self._lastAction is not None and self._lastAction.date() == self.Time.date():
4242
return
4343

4444
if not self.Portfolio.Invested:
4545
self.SetHoldings(self.spy.Symbol, .5)
4646
self._lastAction = self.Time
4747

48-
if self.Time.DayOfWeek == DayOfWeek.Tuesday:
48+
if self.Time.weekday() == 1:
4949
self.aig = self.AddEquity("AIG")
5050
self.bac = self.AddEquity("BAC")
5151
self._lastAction = self.Time
5252

53-
if self.Time.DayOfWeek == DayOfWeek.Wednesday:
53+
if self.Time.weekday() == 2:
5454
self.SetHoldings(self.aig.Symbol, .25)
5555
self.SetHoldings(self.bac.Symbol, .25)
5656
self._lastAction = self.Time
5757

58-
if self.Time.DayOfWeek == DayOfWeek.Thursday:
58+
if self.Time.weekday() == 3:
5959
self.RemoveSecurity(self.aig.Symbol)
6060
self.RemoveSecurity(self.bac.Symbol)
6161
self._lastAction = self.Time

Algorithm.Python/CustomDataBitcoinAlgorithm.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@
1111
# See the License for the specific language governing permissions and
1212
# limitations under the License.
1313

14-
from datetime import date, timedelta
15-
import decimal
16-
import numpy as np
17-
import json
18-
1914
from clr import AddReference
2015
AddReference("System")
2116
AddReference("QuantConnect.Algorithm")
@@ -27,6 +22,11 @@
2722
from QuantConnect.Data import SubscriptionDataSource
2823
from QuantConnect.Python import PythonData
2924

25+
from datetime import date, timedelta, datetime
26+
import decimal
27+
import numpy as np
28+
import json
29+
3030

3131
class CustomDataBitcoinAlgorithm(QCAlgorithm):
3232
'''3.0 CUSTOM DATA SOURCE: USE YOUR OWN MARKET DATA (OPTIONS, FOREX, FUTURES, DERIVATIVES etc).
@@ -36,7 +36,7 @@ class CustomDataBitcoinAlgorithm(QCAlgorithm):
3636

3737
def Initialize(self):
3838
self.SetStartDate(2011, 9, 13)
39-
self.SetEndDate(DateTime.Now.Date.AddDays(-1))
39+
self.SetEndDate(datetime.now().date() - timedelta(1))
4040
self.SetCash(100000)
4141

4242
# Define the symbol and "type" of our generic data:
@@ -55,7 +55,7 @@ def OnData(self, data):
5555
self.SetHoldings(self.btc, 1)
5656
self.Debug("Buying BTC 'Shares': BTC: {0}".format(close))
5757

58-
self.Debug("Time: {0} {1} {2}".format(DateTime.Now.ToLongDateString(), DateTime.Now.ToLongTimeString(), close))
58+
self.Debug("Time: {0} {1}".format(datetime.now(), close))
5959

6060

6161
class Bitcoin(PythonData):
@@ -84,7 +84,7 @@ def Reader(self, config, line, date, isLiveMode):
8484
value = decimal.Decimal(liveBTC["last"])
8585
if value == 0: return None
8686

87-
coin.Time = DateTime.Now
87+
coin.Time = datetime.now()
8888
coin.Value = value
8989
coin["Open"] = float(liveBTC["open"])
9090
coin["High"] = float(liveBTC["high"])
@@ -111,7 +111,7 @@ def Reader(self, config, line, date, isLiveMode):
111111
value = decimal.Decimal(data[4])
112112
if value == 0: return None
113113

114-
coin.Time = DateTime.Now #DateTime.Parse(data[0], None)
114+
coin.Time = datetime.strptime(data[0], "%Y-%m-%d")
115115
coin.Value = value
116116
coin["Open"] = float(data[1])
117117
coin["High"] = float(data[2])

Algorithm.Python/CustomDataNIFTYAlgorithm.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,6 @@
1111
# See the License for the specific language governing permissions and
1212
# limitations under the License.
1313

14-
from datetime import date, timedelta
15-
import decimal
16-
import numpy as np
17-
import math
18-
import json
19-
2014
from clr import AddReference
2115
AddReference("System")
2216
AddReference("QuantConnect.Algorithm")
@@ -27,6 +21,11 @@
2721
from QuantConnect.Algorithm import *
2822
from QuantConnect.Data import SubscriptionDataSource
2923
from QuantConnect.Python import PythonData
24+
from datetime import date, timedelta, datetime
25+
import decimal
26+
import numpy as np
27+
import math
28+
import json
3029

3130
class CustomDataNIFTYAlgorithm(QCAlgorithm):
3231
'''3.0 CUSTOM DATA SOURCE: USE YOUR OWN MARKET DATA (OPTIONS, FOREX, FUTURES, DERIVATIVES etc).
@@ -62,13 +61,13 @@ def OnData(self, data):
6261

6362
self.today.NiftyPrice = data[self.nifty].Close
6463

65-
if self.today.Date == data[self.nifty].Time:
64+
if self.today.date() == data[self.nifty].Time.date():
6665
self.prices.append(self.today)
6766
if len(self.prices) > self.minimumCorrelationHistory:
6867
self.prices.pop(0)
69-
68+
7069
# Strategy
71-
if self.Time.DayOfWeek != DayOfWeek.Wednesday: return
70+
if self.Time.weekday() != 2: return
7271

7372
cur_qnty = self.Portfolio[self.nifty].Quantity
7473
quantity = math.floor(self.Portfolio.TotalPortfolioValue * decimal.Decimal(0.9) / data[self.nifty].Close)
@@ -101,7 +100,7 @@ def Reader(self, config, line, date, isLiveMode):
101100
# Date, Open High Low Close Volume Turnover
102101
# 2011-09-13 7792.9 7799.9 7722.65 7748.7 116534670 6107.78
103102
data = line.split(',')
104-
index.Time = DateTime.ParseExact(data[0], "yyyy-MM-dd", None)
103+
index.Time = datetime.strptime(data[0], "%Y-%m-%d")
105104
index.Value = decimal.Decimal(data[4])
106105
index["Open"] = float(data[1])
107106
index["High"] = float(data[2])
@@ -130,7 +129,7 @@ def Reader(self, config, line, date, isLiveMode):
130129

131130
try:
132131
data = line.split(',')
133-
currency.Time = DateTime.Parse(data[0])
132+
currency.Time = datetime.strptime(data[0], "%Y-%m-%d")
134133
currency.Value = decimal.Decimal(data[1])
135134
currency["Close"] = float(data[1])
136135

@@ -144,7 +143,10 @@ def Reader(self, config, line, date, isLiveMode):
144143
class CorrelationPair:
145144
'''Correlation Pair is a helper class to combine two data points which we'll use to perform the correlation.'''
146145
def __init__(self, *args):
147-
self.NiftyPrice = 0 # Nifty price for this correlation pair
148-
self.CurrencyPrice = 0 # Currency price for this correlation pair
149-
self.Date = DateTime() # Date of the correlation pair
150-
if len(args) > 0: self.Date = args[0]
146+
self.NiftyPrice = 0 # Nifty price for this correlation pair
147+
self.CurrencyPrice = 0 # Currency price for this correlation pair
148+
self._date = datetime.min # Date of the correlation pair
149+
if len(args) > 0: self._date = args[0]
150+
151+
def date(self):
152+
return self._date

Algorithm.Python/DailyAlgorithm.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ def Initialize(self):
3838
ibm_security.SetLeverage(1.0)
3939
self.ibm = ibm_security.Symbol
4040
self.spy = spy_security.Symbol
41-
4241
self.macd = self.MACD(self.spy, 12, 26, 9, MovingAverageType.Wilders, Resolution.Daily, Field.Close)
4342
self.ema = self.EMA(self.ibm, 15*6, Resolution.Hour, Field.SevenBar)
4443
self.lastAction = None
@@ -55,7 +54,7 @@ def OnData(self, data):
5554
if data[self.ibm] is None:
5655
self.Log("Price Missing Time: %s"%str(self.Time))
5756
return
58-
if self.lastAction is not None and self.lastAction.Date == self.Time.Date: return
57+
if self.lastAction is not None and self.lastAction.date() == self.Time.date(): return
5958

6059
self.lastAction = self.Time
6160
holding = self.Portfolio[self.spy]

Algorithm.Python/DataConsolidationAlgorithm.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from QuantConnect.Indicators import *
2424
from QuantConnect.Data.Market import *
2525
from QuantConnect.Data.Consolidators import *
26-
26+
from datetime import timedelta
2727

2828
class DataConsolidationAlgorithm(QCAlgorithm):
2929
'''Example algorithm giving an introduction into using IDataConsolidators.
@@ -48,14 +48,14 @@ def Initialize(self):
4848
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
4949

5050
self.SetStartDate(DateTime(2013, 10, 07, 9, 30, 0)) #Set Start Date
51-
self.SetEndDate(self.StartDate.AddDays(1)) #Set End Date
51+
self.SetEndDate(self.StartDate + timedelta(1)) #Set End Date
5252
# Find more symbols here: http://quantconnect.com/data
5353
equity = self.AddEquity("SPY")
5454
self.spy = equity.Symbol
5555

5656
# define our 30 minute trade bar consolidator. we can
5757
# access the 30 minute bar from the DataConsolidated events
58-
thirtyMinuteConsolidator = TradeBarConsolidator(TimeSpan.FromMinutes(30))
58+
thirtyMinuteConsolidator = TradeBarConsolidator(timedelta(minutes=30))
5959

6060
# attach our event handler. the event handler is a function that will
6161
# be called each time we produce a new consolidated piece of data.
@@ -72,7 +72,7 @@ def Initialize(self):
7272
# days. So we'll create a daily consolidator, and then wrap it with a 3 count consolidator.
7373

7474
# first define a one day trade bar -- this produces a consolidated piece of data after a day has passed
75-
oneDayConsolidator = TradeBarConsolidator(TimeSpan.FromDays(1))
75+
oneDayConsolidator = TradeBarConsolidator(timedelta(1))
7676

7777
# next define our 3 count trade bar -- this produces a consolidated piece of data after it sees 3 pieces of data
7878
threeCountConsolidator = TradeBarConsolidator(3)
@@ -107,11 +107,11 @@ def ThirtyMinuteBarHandler(self, sender, bar):
107107
will be the instance of the IDataConsolidator that invoked the event, but you'll almost never need that!'''
108108

109109
if self.__last is not None and bar.Close > self.__last.Close:
110-
self.Log("{0} >> SPY >> LONG >> 100 >> {1}".format(bar.Time.ToString("o"), self.Portfolio[self.spy].Quantity))
110+
self.Log("{0} >> SPY >> LONG >> 100 >> {1}".format(bar.Time, self.Portfolio[self.spy].Quantity))
111111
self.Order(self.spy, 100)
112112

113113
elif self.__last is not None and bar.Close < self.__last.Close:
114-
self.Log("{0} >> SPY >> SHORT >> 100 >> {1}".format(bar.Time.ToString("o"), self.Portfolio[self.spy].Quantity))
114+
self.Log("{0} >> SPY >> SHORT >> 100 >> {1}".format(bar.Time, self.Portfolio[self.spy].Quantity))
115115
self.Order(self.spy, -100)
116116

117117
self.__last = bar
@@ -121,5 +121,5 @@ def ThreeDayBarConsolidatedHandler(self, sender, bar):
121121
''' This is our event handler for our 3 day trade bar defined above in Initialize(). So each time the
122122
consolidator produces a new 3 day bar, this function will be called automatically. The 'sender' parameter
123123
will be the instance of the IDataConsolidator that invoked the event, but you'll almost never need that!'''
124-
self.Log("{0} >> Plotting!".format(bar.Time.ToString("o")))
124+
self.Log("{0} >> Plotting!".format(bar.Time))
125125
self.Plot(bar.Symbol, "3HourBar", bar.Close)

Algorithm.Python/ETFGlobalRotationAlgorithm.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
from QuantConnect.Algorithm import *
2323
from QuantConnect.Indicators import *
2424
from QuantConnect.Data.Market import *
25-
from AlgorithmPythonUtil import to_python_datetime
2625
from datetime import datetime, timedelta
2726

2827

@@ -67,17 +66,16 @@ def Initialize(self):
6766
def OnData(self, data):
6867
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.'''
6968
try:
70-
pyTime = to_python_datetime(self.Time)
7169
# the first time we come through here we'll need to do some
7270
# things such as allocation and initializing our symbol data
7371
if self.__first:
7472
self.__first = False
75-
self.__lastRotationTime = pyTime
73+
self.__lastRotationTime = self.Time
7674
return
7775

78-
delta = pyTime - self.__lastRotationTime
76+
delta = self.Time - self.__lastRotationTime
7977
if delta > self.__rotationInternal:
80-
self.__lastRotationTime = pyTime
78+
self.__lastRotationTime = self.Time
8179
for x in self.SymbolData: x.Update()
8280

8381
# pick which one is best from growth and safety symbols

0 commit comments

Comments
 (0)