summaryrefslogtreecommitdiff
path: root/app/trading/models.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/trading/models.py')
-rw-r--r--app/trading/models.py174
1 files changed, 174 insertions, 0 deletions
diff --git a/app/trading/models.py b/app/trading/models.py
new file mode 100644
index 0000000..f9c9881
--- /dev/null
+++ b/app/trading/models.py
@@ -0,0 +1,174 @@
+import os
+from PIL import Image
+from django.db import models
+from django.db.models.signals import post_save
+from django.contrib.sitemaps import Sitemap
+from django.dispatch import receiver
+from django.urls import reverse
+from django.apps import apps
+from django.utils.html import format_html
+from django.utils import timezone
+from django.conf import settings
+from django.template.defaultfilters import slugify
+
+from media.models import LuxImage, LuxImageSize
+from media.utils import resize_image
+from utils.util import render_images, render_products, parse_video, markdown_to_html
+
+
+def get_upload_path(self, filename):
+ return "images/products/%s" % (filename)
+
+
+class Ticker(models.Model):
+ symbol = models.CharField(max_length=9)
+ name = models.CharField(max_length=243, blank=True, null=True)
+
+ def __str__(self):
+ return str(self.symbol)
+
+
+class OptionsTrade(models.Model):
+ date = models.DateTimeField()
+ symbol = models.ForeignKey(Ticker, null=True, on_delete=models.SET_NULL)
+ TRANSACTION_CODE = (
+ ('Trade', 'Trade'),
+ )
+ transaction_code = models.CharField(choices=TRANSACTION_CODE, max_length=25)
+ TRANSACTION_SUBCODE = (
+ ('Buy to Open', 'Buy to Open'),
+ ('Sell to Open', 'Sell to Open'),
+ ('Sell to Close', 'Sell to Close'),
+ )
+ transaction_subcode = models.CharField(choices=TRANSACTION_SUBCODE, max_length=25)
+ BUY_SELL = (
+ ('Buy', 'Buy'),
+ ('Sell', 'Sell'),
+ )
+ buy_sell = models.CharField(choices=BUY_SELL, max_length=4)
+ OPEN_CLOSE = (
+ ('Open', 'Open'),
+ ('Close', 'Close'),
+ )
+ open_close = models.CharField(choices=OPEN_CLOSE, max_length=5)
+ quantity = models.FloatField()
+ expiration_date = models.DateTimeField()
+ strike = models.FloatField()
+ CALL_PUT = (
+ ('C', 'Call'),
+ ('P', 'Put'),
+ )
+ call_put = models.CharField(choices=CALL_PUT, max_length=4)
+ price = models.FloatField()
+ fees = models.FloatField()
+ amount = models.FloatField()
+ description = models.TextField(blank=True)
+
+ def __str__(self):
+ return str(self.symbol)
+
+ def get_profit_by_symbol(self,t):
+ buy_amount = 0
+ sell_amount = 0
+ for o in OptionsTrade.objects.filter(symbol__symbol=t).filter(buy_sell="Sell"):
+ sell_amount+=o.amount+o.fees
+ for o in OptionsTrade.objects.filter(symbol__symbol=t).filter(buy_sell="Buy"):
+ buy_amount+=o.amount+o.fees
+ return buy_amount+sell_amount
+
+ def get_profit(self):
+ buy_amount = 0
+ sell_amount = 0
+ for o in OptionsTrade.objects.filter(buy_sell="Sell"):
+ sell_amount+=o.amount+o.fees
+ for o in OptionsTrade.objects.filter(buy_sell="Buy"):
+ buy_amount+=o.amount+o.fees
+ return buy_amount+sell_amount
+
+class LuxTrade(models.Model):
+ symbol = models.CharField(max_length=256)
+ date = models.DateTimeField(auto_now_add=True)
+ close_date = models.DateTimeField(null=True, blank=True)
+ open_date = models.DateTimeField(null=True, blank=True)
+ entry_price = models.FloatField()
+ stop_price = models.FloatField()
+ target_price = models.FloatField()
+ close_price = models.FloatField(null=True, blank=True)
+ shares = models.FloatField()
+ STATUS = (
+ (0, 'Open'),
+ (1, 'Closed'),
+ (2, 'Watching'),
+ )
+ status = models.IntegerField(choices=STATUS, default=2)
+
+ def __str__(self):
+ return str(self.symbol)
+
+ def get_absolute_url(self):
+ return reverse('luxtrade:detail', kwargs={"pk": self.pk})
+
+ @property
+ def risk_reward(self):
+ if self.stop_price > self.entry_price:
+ return "No risk"
+ else:
+ return (self.entry_price - self.stop_price)/(self.target_price-self.entry_price)
+
+ @property
+ def goal_dollars(self):
+ return (self.target_price*self.shares)-(self.entry_price*self.shares)
+
+ @property
+ def goal_percent(self):
+ return round((((self.target_price*self.shares)-(self.entry_price*self.shares))/self.amount_invested)*100, 2)
+
+ @property
+ def risk_dollars(self):
+ if self.stop_price > self.entry_price:
+ return 0
+ else:
+ return round((self.entry_price-self.stop_price)*self.shares, 2)
+
+ @property
+ def amount_invested(self):
+ return round(self.entry_price * self.shares, 2)
+
+ @property
+ def realized_dollars(self):
+ return (self.close_price*self.shares)-(self.entry_price*self.shares)
+
+ @property
+ def realized_percent(self):
+ return (self.realized_dollars/self.amount_invested)*100
+
+ def save(self, *args, **kwargs):
+ if self.status == 0 and not self.open_date:
+ self.open_date = timezone.now()
+ super(LuxTrade, self).save()
+
+class TradeJrnl(models.Model):
+ date = models.DateTimeField(auto_now_add=True)
+ body_markdown = models.TextField(blank=True)
+ body_html = models.TextField(null=True, blank=True)
+
+ def __str__(self):
+ return str(self.date)
+
+ @property
+ def get_previous_admin_url(self):
+ n = self.get_previous_by_read_date()
+ return reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name), args=[n.id])
+
+ @property
+ def get_next_admin_url(self):
+ model = apps.get_model(app_label=self._meta.app_label, model_name=self._meta.model_name)
+ try:
+ return reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name), args=[self.get_next_by_read_date().pk])
+ except model.DoesNotExist:
+ return ''
+
+ def save(self, *args, **kwargs):
+ md = render_images(self.body_markdown)
+ self.body_html = markdown_to_html(md)
+ super(TradeJrnl, self).save()