Begin implementing trade management
This commit is contained in:
parent
e2a697dcc1
commit
5279217324
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 4.1.2 on 2022-10-17 18:07
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0008_trade'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='trade',
|
||||
name='exchange_id',
|
||||
field=models.CharField(blank=True, max_length=255, null=True),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,38 @@
|
|||
# Generated by Django 4.1.2 on 2022-10-17 18:18
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0009_trade_exchange_id'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='account',
|
||||
name='sandbox',
|
||||
field=models.BooleanField(default=False),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trade',
|
||||
name='direction',
|
||||
field=models.CharField(blank=True, choices=[('buy', 'Buy'), ('sell', 'Sell')], max_length=255, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='trade',
|
||||
name='status',
|
||||
field=models.CharField(blank=True, max_length=255, null=True),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trade',
|
||||
name='symbol',
|
||||
field=models.CharField(choices=[('BTCUSD', 'Bitcoin/USD')], max_length=255),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='trade',
|
||||
name='type',
|
||||
field=models.CharField(choices=[('market', 'Market'), ('limit', 'Limit')], max_length=255),
|
||||
),
|
||||
]
|
|
@ -1,5 +1,6 @@
|
|||
import logging
|
||||
|
||||
import ccxt
|
||||
import stripe
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
|
@ -67,11 +68,16 @@ class User(AbstractUser):
|
|||
|
||||
|
||||
class Account(models.Model):
|
||||
EXCHANGE_CHOICES = (
|
||||
("binance", "Binance"),
|
||||
("alpaca", "Alpaca"),
|
||||
)
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
name = models.CharField(max_length=255)
|
||||
exchange = models.CharField(max_length=255)
|
||||
exchange = models.CharField(choices=EXCHANGE_CHOICES, max_length=255)
|
||||
api_key = models.CharField(max_length=255)
|
||||
api_secret = models.CharField(max_length=255)
|
||||
sandbox = models.BooleanField(default=False)
|
||||
|
||||
|
||||
class Session(models.Model):
|
||||
|
@ -90,14 +96,71 @@ class Hook(models.Model):
|
|||
|
||||
|
||||
class Trade(models.Model):
|
||||
SYMBOL_CHOICES = (("BTCUSD", "Bitcoin/USD"),)
|
||||
TYPE_CHOICES = (
|
||||
("market", "Market"),
|
||||
("limit", "Limit"),
|
||||
)
|
||||
DIRECTION_CHOICES = (
|
||||
("buy", "Buy"),
|
||||
("sell", "Sell"),
|
||||
)
|
||||
account = models.ForeignKey(Account, on_delete=models.CASCADE)
|
||||
hook = models.ForeignKey(Hook, on_delete=models.CASCADE, null=True, blank=True)
|
||||
symbol = models.CharField(max_length=255)
|
||||
type = models.CharField(max_length=255)
|
||||
symbol = models.CharField(choices=SYMBOL_CHOICES, max_length=255)
|
||||
type = models.CharField(choices=TYPE_CHOICES, max_length=255)
|
||||
amount = models.FloatField()
|
||||
price = models.FloatField()
|
||||
stop_loss = models.FloatField(null=True, blank=True)
|
||||
take_profit = models.FloatField(null=True, blank=True)
|
||||
exchange_id = models.CharField(max_length=255, null=True, blank=True)
|
||||
status = models.CharField(max_length=255, null=True, blank=True)
|
||||
direction = models.CharField(
|
||||
choices=DIRECTION_CHOICES, max_length=255, null=True, blank=True
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._original = self
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
"""
|
||||
Override the save function to place the trade.
|
||||
"""
|
||||
if self.exchange_id is None:
|
||||
# the trade is not placed yet
|
||||
if self.account.exchange == "alpaca":
|
||||
account = ccxt.alpaca(
|
||||
{"apiKey": self.account.api_key, "secret": self.account.api_secret}
|
||||
)
|
||||
if self.account.sandbox:
|
||||
account.set_sandbox_mode(True)
|
||||
if self.type == "market":
|
||||
order = account.create_order(
|
||||
self.symbol, self.type, self.direction, self.amount
|
||||
)
|
||||
elif self.type == "limit":
|
||||
params = ""
|
||||
order = account.create_limit_order(
|
||||
self.symbol,
|
||||
self.type,
|
||||
self.direction,
|
||||
self.amount,
|
||||
self.price,
|
||||
params,
|
||||
)
|
||||
self.status = "filled"
|
||||
else:
|
||||
# there is a trade open
|
||||
# get trade
|
||||
# update trade
|
||||
pass
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
# close the trade
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
|
||||
class Callback(models.Model):
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
TRADE DETAILS
|
||||
{{ items }}
|
||||
{{ status }}
|
|
@ -98,7 +98,7 @@ class AccountAction(LoginRequiredMixin, APIView):
|
|||
if account_id:
|
||||
try:
|
||||
form = AccountForm(
|
||||
request.data, instance=account.objects.get(id=account_id)
|
||||
request.data, instance=Account.objects.get(id=account_id)
|
||||
)
|
||||
except account.DoesNotExist:
|
||||
message = "Account does not exist"
|
||||
|
|
Loading…
Reference in New Issue