summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlxf <sng@luxagraf.net>2022-01-06 10:01:13 -0500
committerlxf <sng@luxagraf.net>2022-01-06 10:01:13 -0500
commitc2acb9c93081956725e33808764e35c61cc7b90b (patch)
treef1b9608d10cc20b6b99bff9a6e2c646804ab2133
parentf33fa7a87769a444acbc388037c0c71b3b7fc36a (diff)
trad: started on simpler forms for updates and added profit to table
-rw-r--r--app/trading/admin.py4
-rw-r--r--app/trading/forms.py23
-rw-r--r--app/trading/migrations/0022_auto_20220104_1551.py22
-rw-r--r--app/trading/models.py23
-rw-r--r--app/trading/templates/trading/base.html2
-rw-r--r--app/trading/templates/trading/create_luxoptions_form.html2
-rw-r--r--app/trading/templates/trading/list.html2
-rw-r--r--app/trading/templates/trading/luxoptions_update_form.html70
-rw-r--r--app/trading/urls.py7
-rw-r--r--app/trading/views.py48
10 files changed, 181 insertions, 22 deletions
diff --git a/app/trading/admin.py b/app/trading/admin.py
index 3243f53..96e60ee 100644
--- a/app/trading/admin.py
+++ b/app/trading/admin.py
@@ -1,6 +1,6 @@
from django.contrib import admin
from django.db import models
-from .models import TradeJrnl, LuxOptionsTrade, LuxTrade, LuxOptionPurchase, LuxOptionContact
+from .models import TradeJrnl, LuxOptionsTrade, LuxTrade, LuxOptionPurchase, LuxOptionContract
from utils.widgets import AdminImageWidget, LGEntryForm
@@ -36,7 +36,7 @@ class LuxTradeAdmin(admin.ModelAdmin):
class LuxOptionContactInline(admin.StackedInline):
- model = LuxOptionContact
+ model = LuxOptionContract
extra = 0
fieldsets = (
(None, {
diff --git a/app/trading/forms.py b/app/trading/forms.py
index 60c6de6..cd2128d 100644
--- a/app/trading/forms.py
+++ b/app/trading/forms.py
@@ -1,13 +1,13 @@
from django import forms
from django.forms.utils import ValidationError
-from .models import LuxOptionContact
+from .models import LuxOptionContract
class LuxOptionsForm(forms.ModelForm):
contracts = forms.IntegerField()
class Meta:
- model = LuxOptionContact
+ model = LuxOptionContract
fields = [
'symbol',
'strike_price',
@@ -17,9 +17,16 @@ class LuxOptionsForm(forms.ModelForm):
'contracts'
]
- def save(self, commit=True):
- i = 0
- while i < int(self.cleaned_data['contracts']):
- print(i, "contracts")
- i = i+1
- return super(LuxOptionsForm, self).save(commit=commit)
+
+class LuxOptionsUpdateForm(forms.ModelForm):
+ contracts_to_close = forms.IntegerField()
+
+ class Meta:
+ model = LuxOptionContract
+ fields = [
+ 'symbol',
+ 'strike_price',
+ 'expiration_date',
+ 'contracts_to_close',
+ 'contract_close_price',
+ ]
diff --git a/app/trading/migrations/0022_auto_20220104_1551.py b/app/trading/migrations/0022_auto_20220104_1551.py
new file mode 100644
index 0000000..f074f29
--- /dev/null
+++ b/app/trading/migrations/0022_auto_20220104_1551.py
@@ -0,0 +1,22 @@
+# Generated by Django 3.2.7 on 2022-01-04 15:51
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('trading', '0021_auto_20220104_1039'),
+ ]
+
+ operations = [
+ migrations.RenameModel(
+ old_name='LuxOptionContact',
+ new_name='LuxOptionContract',
+ ),
+ migrations.AlterField(
+ model_name='luxoptionpurchase',
+ name='status',
+ field=models.IntegerField(choices=[(0, 'Open'), (1, 'Closed')], default=0),
+ ),
+ ]
diff --git a/app/trading/models.py b/app/trading/models.py
index 720b834..d96970f 100644
--- a/app/trading/models.py
+++ b/app/trading/models.py
@@ -223,8 +223,21 @@ class LuxOptionPurchase(models.Model):
def __str__(self):
return str(self.symbol)
+ def get_absolute_url(self):
+ return reverse('luxtrade:option-update', kwargs={"pk": self.pk})
+
def get_contract_count(self):
- return self.luxoptioncontact_set.count()
+ return self.luxoptioncontract_set.count()
+
+ def profit_loss(self):
+ total = 0
+ for option in self.luxoptioncontract_set.all():
+ if option.contract_close_price:
+ pl = option.contract_close_price - option.contract_open_price
+ else:
+ pl = 0
+ total = total + pl
+ return total*100
@property
def stop_price(self):
@@ -232,7 +245,7 @@ class LuxOptionPurchase(models.Model):
@property
def total_invested(self):
- return round(self.get_contract_count()*(self.luxoptioncontact_set.first().contract_open_price*100))
+ return round(self.get_contract_count()*(self.luxoptioncontract_set.first().contract_open_price*100))
@property
def trade_risk(self):
@@ -244,11 +257,11 @@ class LuxOptionPurchase(models.Model):
@property
def sell_half_at(self):
- return self.luxoptioncontact_set.first().contract_open_price*1.25
+ return self.luxoptioncontract_set.first().contract_open_price*1.25
@property
def contract_price(self):
- return self.luxoptioncontact_set.first().contract_open_price
+ return self.luxoptioncontract_set.first().contract_open_price
def save(self, *args, **kwargs):
if self.status == 1 and not self.close_date:
@@ -259,7 +272,7 @@ class LuxOptionPurchase(models.Model):
super(LuxOptionPurchase, self).save()
-class LuxOptionContact(models.Model):
+class LuxOptionContract(models.Model):
symbol = models.CharField(max_length=256)
strike_price = models.FloatField()
expiration_date = models.DateField()
diff --git a/app/trading/templates/trading/base.html b/app/trading/templates/trading/base.html
index 2d6e5da..9b9e6b0 100644
--- a/app/trading/templates/trading/base.html
+++ b/app/trading/templates/trading/base.html
@@ -15,7 +15,7 @@
<nav>
<span class="nav-item"><a href="{% url 'luxtrade:list' %}">Home</a></span>
<span class="nav-item"><a href="{% url 'luxtrade:testtrade' %}">Test Trade</a></span>
- <span class="nav-item"><a href="{% url 'luxtrade:testoptions' %}">Test Options</a></span>
+ <span class="nav-item"><a href="{% url 'luxtrade:option-create' %}">Test Options</a></span>
<span class="nav-item"><a href="https://wandererfinancial.com/{% now 'n-j-y'%}-todays-market/" target="_blank">Wanderer</a></span>
<span class="nav-item"><a href="https://www.tradingview.com/chart/1a1NjVtp/" target="_blank">Trading View</a></span>
<span class="nav-item"><a href="https://trade.tastyworks.com/index.html#/portfolioPage" target="_blank">Tastyworks</a></span>
diff --git a/app/trading/templates/trading/create_luxoptions_form.html b/app/trading/templates/trading/create_luxoptions_form.html
index 5fff0ae..937f90b 100644
--- a/app/trading/templates/trading/create_luxoptions_form.html
+++ b/app/trading/templates/trading/create_luxoptions_form.html
@@ -1,7 +1,7 @@
{% extends 'trading/base.html' %}
{% load typogrify_tags %}
{% block content %}
- <form id="id_form" action="{% url 'luxtrade:testoptions' %}" method="post" class="big">{% csrf_token %}
+ <form id="id_form" action="{% url 'luxtrade:option-create' %}" method="post" class="big">{% csrf_token %}
{% for field in form %}
<fieldset>
{{ field.errors }}
diff --git a/app/trading/templates/trading/list.html b/app/trading/templates/trading/list.html
index 3f6c3c0..be9b527 100644
--- a/app/trading/templates/trading/list.html
+++ b/app/trading/templates/trading/list.html
@@ -13,6 +13,7 @@
<th>% Portfolio Risk</th>
<th>25% profit at</th>
<th>Stop</th>
+ <th>Profit</th>
<th>Notes</th>
</tr>
</thead>
@@ -36,6 +37,7 @@
<td>{{object.portfolio_risk|floatformat:2}}%</td>
<td>${{object.sell_half_at|floatformat:2}}</td>
<td>${{object.stop_price|floatformat:2}}</td>
+ <td>${{object.profit_loss|floatformat:2}}</td>
<td class="notes">
{% if object.notes %}
<div class="wrapper">
diff --git a/app/trading/templates/trading/luxoptions_update_form.html b/app/trading/templates/trading/luxoptions_update_form.html
new file mode 100644
index 0000000..14c80c3
--- /dev/null
+++ b/app/trading/templates/trading/luxoptions_update_form.html
@@ -0,0 +1,70 @@
+{% extends 'trading/base.html' %}
+{% load typogrify_tags %}
+ {% block content %}
+ <form id="id_form" action="" method="post" class="big">{% csrf_token %}
+ {% for field in form %}
+ <fieldset>
+ {{ field.errors }}
+ {% if field.name == 'status' or field.name == 'call_put' %}
+ <label class="hide" for="id_status">Status:</label>{{ field }}
+ {% else %}
+ {% if field.name == 'strike_price' or field.name == 'expiration_date' %}<div class="hide">{%endif%}
+ {{ field.label_tag }} {{ field }}
+ {% if field.name == 'strike_price' or field.name == 'expiration_date' %}</div>{%endif%}
+ {% endif %}
+ {% if field.help_text %}
+ <p class="help">{{ field.help_text|safe }}</p>
+ {% endif %}
+ </fieldset>
+{% endfor %}
+ <dl>
+ <dt>R/R: </dt><dd id="id_rr"></dd>
+ <dt>% Portfolio: </dt><dd id="id_p_portfolio"></dd>
+ <dt>Risk per contract: </dt><dd id="id_risk_contract"></dd>
+ <dt>Total Risk: </dt><dd id="id_risk_total"></dd>
+ <dt>Total Invested: </dt><dd id="id_total"></dd>
+ </dl>
+ <div class="flex">
+ <input type="submit" name="post" class="btn" value="record purchase"/>
+ </div>
+ </form>
+ {% endblock %}
+
+ {% block js %}
+<script>
+function calcPercentPortfolio() {
+ var entry_price = document.getElementById("id_entry_price").value;
+ var stop_price = document.getElementById("id_stop_price").value;
+ var target_price = document.getElementById("id_target_price").value;
+ var contract_price = document.getElementById("id_contract_price").value;
+ var number_contracts = document.getElementById("id_number_contracts").value;
+ var delta = document.getElementById("id_delta").value;
+ var pp = (contract_price*number_contracts)*100/10000;
+ var total = (contract_price*number_contracts)*100;
+ var rr = (target_price-entry_price)/(entry_price-stop_price);
+ var risk_per = ((entry_price-stop_price)*delta/contract_price)*contract_price*100
+ var total_risk = (risk_per*number_contracts);
+ document.getElementById("id_p_portfolio").innerText = (pp*100).toFixed(2);
+ document.getElementById("id_risk_contract").innerText = "$"+risk_per.toFixed(2);
+ document.getElementById("id_risk_total").innerText = "$"+total_risk.toFixed(2);
+ document.getElementById("id_rr").innerText = rr.toFixed(2);
+ document.getElementById("id_total").innerText = "$"+total.toFixed(2);
+}
+id_form.addEventListener("input", function (e) {
+ calcPercentPortfolio();
+});
+var form = document.getElementById('id_form');
+function processForm(e) {
+ if (e.preventDefault) e.preventDefault();
+ if(!confirm("Do you really want to do this?")) {
+ return false;
+ }
+ form.submit();
+}
+if (form.attachEvent) {
+ form.attachEvent("submit", processForm);
+} else {
+ form.addEventListener("submit", processForm);
+}
+</script>
+ {% endblock %}
diff --git a/app/trading/urls.py b/app/trading/urls.py
index 6bb486a..912e2c7 100644
--- a/app/trading/urls.py
+++ b/app/trading/urls.py
@@ -18,7 +18,12 @@ urlpatterns = [
path(
'options-calc',
views.LuxOptionPurchaseCreateView.as_view(),
- name='testoptions'
+ name='option-create'
+ ),
+ path(
+ 'trade/options/<pk>',
+ views.LuxOptionsPurchaseEditView.as_view(),
+ name='option-update'
),
path(
'trade/options/<pk>',
diff --git a/app/trading/views.py b/app/trading/views.py
index b885d7c..69e1ace 100644
--- a/app/trading/views.py
+++ b/app/trading/views.py
@@ -3,8 +3,8 @@ from django.http import HttpResponseRedirect
from django.views.generic.edit import CreateView, UpdateView
from utils.views import PaginatedListView
-from .models import LuxTrade, LuxOptionsTrade, LuxOptionContact, LuxOptionPurchase
-from .forms import LuxOptionsForm
+from .models import LuxTrade, LuxOptionsTrade, LuxOptionContract, LuxOptionPurchase
+from .forms import LuxOptionsForm, LuxOptionsUpdateForm
class LuxTradeListView(PaginatedListView):
@@ -88,7 +88,7 @@ class OptionsModelFormView(CreateView):
class LuxOptionPurchaseCreateView(CreateView):
- model = LuxOptionContact
+ model = LuxOptionContract
fields = ['symbol']
success_url = '/trading/'
template_name = 'trading/create_luxoptions_form.html'
@@ -108,7 +108,7 @@ class LuxOptionPurchaseCreateView(CreateView):
)
print(form.cleaned_data['contracts'])
while i < int(form.cleaned_data['contracts']):
- c = LuxOptionContact.objects.create(
+ c = LuxOptionContract.objects.create(
symbol = form.cleaned_data['symbol'],
strike_price = form.cleaned_data['strike_price'],
expiration_date = form.cleaned_data['expiration_date'],
@@ -119,3 +119,43 @@ class LuxOptionPurchaseCreateView(CreateView):
i = i+1
return HttpResponseRedirect('/trading/')
return render(request, 'trading/create_luxoptions_form.html', {'form': form})
+
+class LuxOptionsPurchaseEditView(UpdateView):
+ model = LuxOptionPurchase
+ fields = [
+ 'symbol',
+ 'close_date',
+ 'status'
+ ]
+ success_url = '/trading/'
+ template_name = 'trading/luxoptions_update_form.html'
+
+
+ def get_context_data(self, **kwargs):
+ context = super(LuxOptionsPurchaseEditView, self).get_context_data(**kwargs)
+ obj = LuxOptionPurchase.objects.get(pk=self.object.pk)
+ context['form'] = LuxOptionsUpdateForm()
+ context['object'] = self.object
+ return context
+
+ def post(self, request, *args, **kwargs):
+ form = LuxOptionsForm(request.POST)
+ if form.is_valid():
+ i = 0
+ p = LuxOptionPurchase.objects.get(
+ symbol = form.cleaned_data['symbol'],
+ open_date = form.cleaned_data['open_date'],
+ )
+ print(form.cleaned_data['contracts_to_close'])
+ while i < int(form.cleaned_data['contracts_to_close']):
+ c = LuxOptionContract.objects.get(
+ symbol = form.cleaned_data['symbol'],
+ strike_price = form.cleaned_data['strike_price'],
+ expiration_date = form.cleaned_data['expiration_date'],
+ contract_open_price = form.cleaned_data['contract_open_price'],
+ call_put = form.cleaned_data['call_put'],
+ )
+ c.contract_close_price = form.cleaned_data['contract_close_price']
+ c.save()
+ return HttpResponseRedirect('/trading/')
+ return render(request, 'trading/create_luxoptions_form.html', {'form': form})