Skip to content

Commit 183fdfe

Browse files
committed
Use UTC datetimes everywhere
Now datetime math is done in UTC for simplicity. Furthermore, created_on_str is always UTC. Finally, a new migration for created_on and modified_on fields was created.
1 parent b99b81d commit 183fdfe

File tree

6 files changed

+195
-105
lines changed

6 files changed

+195
-105
lines changed

history/admin.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ def algo(self,obj):
2626
if trs.count:
2727
tr = trs[0]
2828
if tr.clf:
29-
html += "<a href="https://github.com/admin/history/classifiertest/{}">{}</a>".format(tr.clf.pk,tr.clf)
29+
html += "<a href="https://github.com/admin/history/classifiertest/{}">{}</a>".format(tr.clf.pk,tr.clf)
3030
if tr.made_by:
31-
html += "<a href="https://github.com/admin/history/predictiontest/{}">{}</a>".format(tr.made_by.pk,tr.made_by)
31+
html += "<a href="https://github.com/admin/history/predictiontest/{}">{}</a>".format(tr.made_by.pk,tr.made_by)
3232
return html
3333

3434
algo.allow_tags = True
@@ -82,6 +82,3 @@ def view_link(obj):
8282
list_display = ['pk', 'type','symbol', 'name', 'created_on', 'percent_correct', 'score', 'prediction_size', view_link]
8383

8484
admin.site.register(ClassifierTest, ClassifierTestAdmin)
85-
86-
87-

history/management/commands/alert_fail_cases.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
from django.core.management.base import BaseCommand
21
import datetime
3-
from history.models import PredictionTest, TradeRecommendation, get_time
2+
from django.utils import timezone
43
from django.conf import settings
4+
from django.core.management.base import BaseCommand
5+
from history.models import PredictionTest, TradeRecommendation
56

67
class Command(BaseCommand):
78

@@ -35,9 +36,10 @@ def handle(self, *args, **options):
3536
print(last_pt.created_on)
3637
print(last_trade.created_on)
3738

38-
# 7 hours thing is a hack for MST vs UTC timezone issues
39-
is_trader_running = last_trade.created_on > (get_time() - datetime.timedelta(hours=int(7)) - datetime.timedelta(minutes=int(15)))
40-
is_trainer_running = last_pt.created_on > (get_time() - datetime.timedelta(hours=int(7)) - datetime.timedelta(minutes=int(15)))
39+
# Since USE_TZ=True, created_on is already UTC, like timezone.now()
40+
fifteen_ago = timezone.now() - datetime.timedelta(minutes=15)
41+
is_trader_running = last_trade.created_on > fifteen_ago
42+
is_trainer_running = last_pt.created_on > fifteen_ago
4143

4244
if not is_trader_running:
4345
self.alert_email("not is_trader_running")

history/management/commands/trade.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from django.core.management.base import BaseCommand
22
from history.predict import predict_v2
3-
from history.models import Price, PredictionTest, Trade, TradeRecommendation, Balance, get_time, ClassifierTest
3+
from history.models import (Price, PredictionTest, Trade, TradeRecommendation,
4+
Balance, ClassifierTest)
45
from history.tools import get_utc_unixtime, print_and_log
56
import datetime
67
import time
@@ -186,7 +187,7 @@ def run_predictor(self, nn_index):
186187
confidence=confidence,
187188
recommendation=recommend,
188189
net_amount=-1 if recommend == 'SELL' else (1 if recommend == 'BUY' else 0),
189-
created_on_str=str(get_time().strftime('%Y-%m-%d %H:%M')))
190+
created_on_str=timezone.now().strftime('%Y-%m-%d %H:%M'))
190191
tr.save()
191192
self.trs[nn_index] = tr
192193
return recommend
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import models, migrations
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('history', '0003_auto_20160330_1920'),
11+
]
12+
13+
operations = [
14+
migrations.AlterField(
15+
model_name='balance',
16+
name='created_on',
17+
field=models.DateTimeField(auto_now_add=True, db_index=True),
18+
),
19+
migrations.AlterField(
20+
model_name='balance',
21+
name='modified_on',
22+
field=models.DateTimeField(auto_now=True),
23+
),
24+
migrations.AlterField(
25+
model_name='classifiertest',
26+
name='created_on',
27+
field=models.DateTimeField(auto_now_add=True),
28+
),
29+
migrations.AlterField(
30+
model_name='classifiertest',
31+
name='modified_on',
32+
field=models.DateTimeField(auto_now=True),
33+
),
34+
migrations.AlterField(
35+
model_name='deposit',
36+
name='created_on',
37+
field=models.DateTimeField(auto_now_add=True, db_index=True),
38+
),
39+
migrations.AlterField(
40+
model_name='deposit',
41+
name='modified_on',
42+
field=models.DateTimeField(auto_now=True),
43+
),
44+
migrations.AlterField(
45+
model_name='performancecomp',
46+
name='created_on',
47+
field=models.DateTimeField(auto_now_add=True, db_index=True),
48+
),
49+
migrations.AlterField(
50+
model_name='performancecomp',
51+
name='modified_on',
52+
field=models.DateTimeField(auto_now=True),
53+
),
54+
migrations.AlterField(
55+
model_name='predictiontest',
56+
name='created_on',
57+
field=models.DateTimeField(auto_now_add=True),
58+
),
59+
migrations.AlterField(
60+
model_name='predictiontest',
61+
name='modified_on',
62+
field=models.DateTimeField(auto_now=True),
63+
),
64+
migrations.AlterField(
65+
model_name='price',
66+
name='created_on',
67+
field=models.DateTimeField(auto_now_add=True, db_index=True),
68+
),
69+
migrations.AlterField(
70+
model_name='price',
71+
name='modified_on',
72+
field=models.DateTimeField(auto_now=True),
73+
),
74+
migrations.AlterField(
75+
model_name='trade',
76+
name='created_on',
77+
field=models.DateTimeField(auto_now_add=True, db_index=True),
78+
),
79+
migrations.AlterField(
80+
model_name='trade',
81+
name='modified_on',
82+
field=models.DateTimeField(auto_now=True),
83+
),
84+
migrations.AlterField(
85+
model_name='traderecommendation',
86+
name='created_on',
87+
field=models.DateTimeField(auto_now_add=True, db_index=True),
88+
),
89+
migrations.AlterField(
90+
model_name='traderecommendation',
91+
name='modified_on',
92+
field=models.DateTimeField(auto_now=True),
93+
),
94+
]

history/models.py

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,16 @@
2727
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis
2828

2929
import warnings
30-
warnings.filterwarnings("ignore", category=DeprecationWarning)
30+
warnings.filterwarnings("ignore", category=DeprecationWarning)
3131

3232

3333
def get_time():
34-
return localtime(timezone.now())
34+
return timezone.localtime(timezone.now())
35+
3536

3637
class TimeStampedModel(models.Model):
37-
created_on = models.DateTimeField(null=False, default=get_time, db_index=True)
38-
modified_on = models.DateTimeField(null=False, default=get_time)
38+
created_on = models.DateTimeField(null=False, auto_now_add=True, db_index=True)
39+
modified_on = models.DateTimeField(null=False, auto_now=True)
3940

4041
def get_readonly_fields(self, request, obj=None):
4142
return [f.name for f in self._meta.get_fields()]
@@ -46,10 +47,6 @@ def has_add_permission(self, request, obj=None):
4647
def has_delete_permission(self, request, obj=None):
4748
return False
4849

49-
def save(self, *args, **kwargs):
50-
self.modified_on = get_time()
51-
return super(TimeStampedModel, self).save(*args, **kwargs)
52-
5350
class Meta:
5451
abstract = True
5552

@@ -58,8 +55,8 @@ def url_to_edit_object(self):
5855
return '<a href="{0}">Edit {1}</a>'.format(url, escape(str(self)))
5956

6057
class AbstractedTesterClass(models.Model):
61-
created_on = models.DateTimeField(null=False, default=get_time)
62-
modified_on = models.DateTimeField(null=False, default=get_time)
58+
created_on = models.DateTimeField(null=False, auto_now_add=True)
59+
modified_on = models.DateTimeField(null=False, auto_now=True)
6360

6461
def get_readonly_fields(self, request, obj=None):
6562
return [f.name for f in self._meta.get_fields()]
@@ -70,17 +67,13 @@ def has_add_permission(self, request, obj=None):
7067
def has_delete_permission(self, request, obj=None):
7168
return False
7269

73-
def save(self, *args, **kwargs):
74-
self.modified_on = get_time()
75-
return super(AbstractedTesterClass, self).save(*args, **kwargs)
76-
7770
class Meta:
7871
abstract = True
7972

8073
def url_to_edit_object(self):
8174
url = reverse('admin:{0}_{1}_change'.format(self._meta.app_label, self._meta.model_name), args=[self.id])
8275
return '<a href="{0}">Edit {1}</a>'.format(url, escape(str(self)))
83-
76+
8477
def confidence(self):
8578
related = self.related_mocks()
8679
related.exclude(percent_correct__isnull=True)
@@ -221,7 +214,7 @@ class PerformanceComp(TimeStampedModel):
221214
price_timerange_end = models.DateTimeField(null=True, default=None,db_index=True)
222215
tr_timerange_start = models.DateTimeField(null=True, default=None)
223216
tr_timerange_end = models.DateTimeField(null=True, default=None)
224-
217+
225218

226219
class TradeRecommendation(TimeStampedModel):
227220
symbol = models.CharField(max_length=30)
@@ -313,7 +306,7 @@ def get_classifier(self,train=True,test=True):
313306
price_datasets[1].append(do_buy)
314307
except Exception as e:
315308
pass
316-
309+
317310
data = price_datasets
318311
if self.timedelta_back_in_granularity_increments == 0:
319312
train_data = data
@@ -338,7 +331,7 @@ def get_classifier(self,train=True,test=True):
338331

339332
clf.fit(self.X_train, self.y_train)
340333
score = clf.score(self.X_test, self.y_test)
341-
334+
342335
# Plot the decision boundary. For that, we will assign a color to each
343336
# point in the mesh [self.x_min, m_max]x[self.y_min, self.y_max].
344337

@@ -347,7 +340,7 @@ def get_classifier(self,train=True,test=True):
347340
self.ravel_args.append(self.xz[i].ravel())
348341

349342
self._input = np.column_stack(self.ravel_args)
350-
343+
351344
if hasattr(clf, "decision_function"):
352345
self.Z = clf.decision_function(self._input)
353346
else:
@@ -370,7 +363,7 @@ def get_classifier(self,train=True,test=True):
370363
all_output = all_output + str(('stats_debug',stats))
371364
self.percent_correct = int(pct_correct*100)
372365
self.prediction_size = len(test_data[0])
373-
366+
374367
all_output = all_output + str((self.name,round(score*100)))
375368
self.score = score*100
376369
end_time = int(time.time())
@@ -400,7 +393,7 @@ def graph(self,filename):
400393
figure = plt.figure(figsize=(27, 9))
401394
figure.max_num_figures = 5
402395
matplotlib.figure.max_num_figures = 5
403-
i = 0
396+
i = 0
404397
cm = plt.cm.RdBu
405398
cm_bright = ListedColormap(['#00FF00','#FF0000', '#0000FF'])
406399
ax = plt.subplot(1, 1 , i)
@@ -530,9 +523,9 @@ def get_nn(self,train=True):
530523
except ImportError:
531524
FNN = buildNetwork(DS.indim, self.hiddenneurons, DS.outdim, bias=self.bias, recurrent=self.recurrent)
532525
FNN.randomize()
533-
526+
534527
TRAINER = BackpropTrainer(FNN, dataset=DS, learningrate = self.learningrate, \
535-
momentum=self.momentum, verbose=False, weightdecay=self.weightdecay)
528+
momentum=self.momentum, verbose=False, weightdecay=self.weightdecay)
536529

537530
if train:
538531
for i in range(self.epochs):
@@ -546,12 +539,12 @@ def recommend_trade(self,nn_price,last_sample, fee_amount = get_fee_amount()):
546539
fee_amount = fee_amount * settings.FEE_MANAGEMENT_STRATEGY # see desc in settings.py
547540
anticipated_percent_increase = (nn_price - last_sample) / last_sample
548541
if abs(anticipated_percent_increase) < fee_amount:
549-
should_trade = 'HOLD'
542+
should_trade = 'HOLD'
550543
elif anticipated_percent_increase > fee_amount:
551-
should_trade = 'BUY'
544+
should_trade = 'BUY'
552545
elif anticipated_percent_increase < fee_amount:
553546
should_trade = 'SELL'
554-
return should_trade
547+
return should_trade
555548

556549
def predict(self,sample):
557550
last_sample = sample[-1]

0 commit comments

Comments
 (0)