├── __init__.py
├── trade
├── __init__.py
├── migrations
│ ├── __init__.py
│ └── 0001_initial.py
├── templatetags
│ ├── __init__.py
│ ├── coins.py
│ ├── transactions.py
│ ├── coin_full_name.py
│ ├── value_to_cryptotoken.py
│ ├── wallet_information.py
│ └── summary_balance.py
├── templates
│ ├── account
│ │ ├── base.html
│ │ ├── messages
│ │ │ ├── logged_out.txt
│ │ │ ├── email_confirmed.txt
│ │ │ ├── email_deleted.txt
│ │ │ ├── password_set.txt
│ │ │ ├── primary_email_set.txt
│ │ │ ├── password_changed.txt
│ │ │ ├── email_confirmation_sent.txt
│ │ │ ├── unverified_primary_email.txt
│ │ │ ├── cannot_delete_primary_email.txt
│ │ │ └── logged_in.txt
│ │ ├── email
│ │ │ ├── email_confirmation_signup_message.txt
│ │ │ ├── email_confirmation_signup_subject.txt
│ │ │ ├── password_reset_key_subject.txt
│ │ │ ├── email_confirmation_subject.txt
│ │ │ ├── email_confirmation_message.txt
│ │ │ └── password_reset_key_message.txt
│ │ ├── snippets
│ │ │ └── already_logged_in.html
│ │ ├── signup_closed.html
│ │ ├── account_inactive.html
│ │ ├── password_reset_from_key_done.html
│ │ ├── password_set.html
│ │ ├── verification_sent.html
│ │ ├── password_reset_done.html
│ │ ├── logout.html
│ │ ├── verified_email_required.html
│ │ ├── email_confirm.html
│ │ ├── password_reset.html
│ │ ├── password_change.html
│ │ ├── signup.html
│ │ ├── password_reset_from_key.html
│ │ ├── email.html
│ │ └── login.html
│ ├── openid
│ │ ├── base.html
│ │ └── login.html
│ ├── socialaccount
│ │ ├── base.html
│ │ ├── snippets
│ │ │ ├── login_extra.html
│ │ │ └── provider_list.html
│ │ ├── messages
│ │ │ ├── account_connected.txt
│ │ │ ├── account_disconnected.txt
│ │ │ └── account_connected_other.txt
│ │ ├── authentication_error.html
│ │ ├── login_cancelled.html
│ │ ├── signup.html
│ │ └── connections.html
│ └── trade
│ │ ├── user_summaries.html
│ │ ├── wallet_info.html
│ │ ├── base.html
│ │ ├── coins.html
│ │ └── transactions.html
├── tests.py
├── static
│ ├── trade
│ │ └── 404.jpg
│ ├── images
│ │ ├── logo.png
│ │ └── cryptotokens
│ │ │ ├── .png
│ │ │ ├── dash.png
│ │ │ ├── lisk.png
│ │ │ ├── nem.png
│ │ │ ├── nxt.png
│ │ │ ├── ardor.png
│ │ │ ├── augur.png
│ │ │ ├── bitcoin.png
│ │ │ ├── decred.png
│ │ │ ├── factom.png
│ │ │ ├── monero.png
│ │ │ ├── potcoin.png
│ │ │ ├── ripple.png
│ │ │ ├── siacoin.png
│ │ │ ├── steem.png
│ │ │ ├── stratis.png
│ │ │ ├── syscoin.png
│ │ │ ├── tether.png
│ │ │ ├── viacoin.png
│ │ │ ├── zcash.png
│ │ │ ├── bitshares.png
│ │ │ ├── blackcoin.png
│ │ │ ├── blocknet.png
│ │ │ ├── digibyte.png
│ │ │ ├── dogecoin.png
│ │ │ ├── ethereum.png
│ │ │ ├── etheroll.png
│ │ │ ├── litecoin.png
│ │ │ ├── namecoin.png
│ │ │ ├── peercoin.png
│ │ │ ├── reddcoin.png
│ │ │ ├── bitcoindark.png
│ │ │ ├── bitconnect.png
│ │ │ ├── bytecoin-bcn.png
│ │ │ ├── counterparty.png
│ │ │ ├── gamecredits.png
│ │ │ ├── gnosis-gno.png
│ │ │ ├── maidsafecoin.png
│ │ │ ├── library-credit.png
│ │ │ ├── ethereum-classic.png
│ │ │ └── golem-network-tokens.png
│ ├── css
│ │ ├── images
│ │ │ ├── animated-overlay.gif
│ │ │ ├── ui-icons_222222_256x240.png
│ │ │ ├── ui-icons_2e83ff_256x240.png
│ │ │ ├── ui-icons_454545_256x240.png
│ │ │ ├── ui-icons_888888_256x240.png
│ │ │ ├── ui-icons_cd0a0a_256x240.png
│ │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png
│ │ │ ├── ui-bg_flat_75_ffffff_40x100.png
│ │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png
│ │ │ ├── ui-bg_glass_65_ffffff_1x400.png
│ │ │ ├── ui-bg_glass_75_dadada_1x400.png
│ │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png
│ │ │ ├── ui-bg_glass_95_fef1ec_1x400.png
│ │ │ └── ui-bg_highlight-soft_75_cccccc_1x100.png
│ │ ├── jqChart.css
│ │ ├── setup.css
│ │ ├── jqRangeSlider.css
│ │ └── style.css
│ ├── fonts
│ │ └── roboto
│ │ │ ├── Roboto-Bold.woff
│ │ │ ├── Roboto-Bold.woff2
│ │ │ ├── Roboto-Light.woff
│ │ │ ├── Roboto-Light.woff2
│ │ │ ├── Roboto-Medium.woff
│ │ │ ├── Roboto-Thin.woff
│ │ │ ├── Roboto-Thin.woff2
│ │ │ ├── Roboto-Medium.woff2
│ │ │ ├── Roboto-Regular.woff
│ │ │ └── Roboto-Regular.woff2
│ └── js
│ │ ├── coinmarketcup.js
│ │ ├── script.js
│ │ └── exporting.js
├── apps.py
├── forms.py
├── admin.py
├── views.py
└── models.py
├── ticker_app
├── __init__.py
├── migrations
│ ├── __init__.py
│ └── 0001_initial.py
├── tests.py
├── apps.py
├── admin.py
├── models.py
├── routers.py
└── views.py
├── tradeBOT
├── __init__.py
├── migrations
│ └── __init__.py
├── templatetags
│ ├── __init__.py
│ ├── get_coin_info.py
│ ├── get_exchange_coins.py
│ ├── relations.py
│ └── tradeBot_filters.py
├── tests.py
├── apps.py
├── consumers.py
├── templates
│ └── tradeBOT
│ │ ├── pairs.html
│ │ ├── coin_info.html
│ │ ├── Coins.html
│ │ ├── exchange_primary_coins.html
│ │ ├── relations.html
│ │ ├── index.html
│ │ ├── primary_coin_pairs.html
│ │ ├── user_primary.html
│ │ ├── to_trade.html
│ │ ├── orders.html
│ │ ├── test.html
│ │ └── get_primary_pairs.html
├── admin.py
├── models.py
└── views.py
├── user_profile
├── __init__.py
├── migrations
│ └── __init__.py
├── models.py
├── tests.py
├── admin.py
├── apps.py
├── views.py
└── templates
│ └── user_profile
│ └── profile.html
├── images
├── home_page.jpg
├── candelsticks.jpg
├── final_screen.jpg
└── ongrid-systems-cover.png
├── djangoTrade
├── __init__.py
├── routing.py
├── wsgi.py
├── celery.py
├── urls.py
└── settings.py
├── dump.json
├── templates
└── 404.html
├── manage.py
├── account
└── templates
│ └── account
│ ├── login.html
│ ├── register.html
│ └── profile.html
├── LICENSE
├── requirements.txt
├── .gitignore
└── README.md
/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/trade/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ticker_app/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tradeBOT/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/trade/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/user_profile/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ticker_app/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/trade/templatetags/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tradeBOT/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tradeBOT/templatetags/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/user_profile/migrations/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/trade/templates/account/base.html:
--------------------------------------------------------------------------------
1 | {% extends 'trade/base.html' %}
--------------------------------------------------------------------------------
/trade/templates/openid/base.html:
--------------------------------------------------------------------------------
1 | {% extends "socialaccount/base.html" %}
2 |
--------------------------------------------------------------------------------
/trade/templates/socialaccount/base.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 |
--------------------------------------------------------------------------------
/trade/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/ticker_app/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/tradeBOT/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/user_profile/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 |
3 | # Create your models here.
4 |
--------------------------------------------------------------------------------
/user_profile/tests.py:
--------------------------------------------------------------------------------
1 | from django.test import TestCase
2 |
3 | # Create your tests here.
4 |
--------------------------------------------------------------------------------
/images/home_page.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/images/home_page.jpg
--------------------------------------------------------------------------------
/user_profile/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 |
3 | # Register your models here.
4 |
--------------------------------------------------------------------------------
/djangoTrade/__init__.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 | from .celery import app as celery_app
--------------------------------------------------------------------------------
/images/candelsticks.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/images/candelsticks.jpg
--------------------------------------------------------------------------------
/images/final_screen.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/images/final_screen.jpg
--------------------------------------------------------------------------------
/trade/static/trade/404.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/trade/404.jpg
--------------------------------------------------------------------------------
/trade/static/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/logo.png
--------------------------------------------------------------------------------
/images/ongrid-systems-cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/images/ongrid-systems-cover.png
--------------------------------------------------------------------------------
/trade/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class TradeConfig(AppConfig):
5 | name = 'trade'
6 |
--------------------------------------------------------------------------------
/trade/templates/socialaccount/snippets/login_extra.html:
--------------------------------------------------------------------------------
1 | {% load socialaccount %}
2 |
3 | {% providers_media_js %}
4 |
5 |
--------------------------------------------------------------------------------
/trade/templates/account/messages/logged_out.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}You have signed out.{% endblocktrans %}
3 |
--------------------------------------------------------------------------------
/tradeBOT/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class TradebotConfig(AppConfig):
5 | name = 'tradeBOT'
6 |
--------------------------------------------------------------------------------
/ticker_app/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class TickerAppConfig(AppConfig):
5 | name = 'ticker_app'
6 |
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/.png
--------------------------------------------------------------------------------
/trade/templates/account/email/email_confirmation_signup_message.txt:
--------------------------------------------------------------------------------
1 | {% include "account/email/email_confirmation_message.txt" %}
2 |
--------------------------------------------------------------------------------
/trade/templates/account/email/email_confirmation_signup_subject.txt:
--------------------------------------------------------------------------------
1 | {% include "account/email/email_confirmation_subject.txt" %}
2 |
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/dash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/dash.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/lisk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/lisk.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/nem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/nem.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/nxt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/nxt.png
--------------------------------------------------------------------------------
/user_profile/apps.py:
--------------------------------------------------------------------------------
1 | from django.apps import AppConfig
2 |
3 |
4 | class UserProfileConfig(AppConfig):
5 | name = 'user_profile'
6 |
--------------------------------------------------------------------------------
/trade/static/css/images/animated-overlay.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/animated-overlay.gif
--------------------------------------------------------------------------------
/trade/static/fonts/roboto/Roboto-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/fonts/roboto/Roboto-Bold.woff
--------------------------------------------------------------------------------
/trade/static/fonts/roboto/Roboto-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/fonts/roboto/Roboto-Bold.woff2
--------------------------------------------------------------------------------
/trade/static/fonts/roboto/Roboto-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/fonts/roboto/Roboto-Light.woff
--------------------------------------------------------------------------------
/trade/static/fonts/roboto/Roboto-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/fonts/roboto/Roboto-Light.woff2
--------------------------------------------------------------------------------
/trade/static/fonts/roboto/Roboto-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/fonts/roboto/Roboto-Medium.woff
--------------------------------------------------------------------------------
/trade/static/fonts/roboto/Roboto-Thin.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/fonts/roboto/Roboto-Thin.woff
--------------------------------------------------------------------------------
/trade/static/fonts/roboto/Roboto-Thin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/fonts/roboto/Roboto-Thin.woff2
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/ardor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/ardor.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/augur.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/augur.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/bitcoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/bitcoin.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/decred.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/decred.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/factom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/factom.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/monero.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/monero.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/potcoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/potcoin.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/ripple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/ripple.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/siacoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/siacoin.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/steem.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/steem.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/stratis.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/stratis.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/syscoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/syscoin.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/tether.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/tether.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/viacoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/viacoin.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/zcash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/zcash.png
--------------------------------------------------------------------------------
/trade/templates/account/messages/email_confirmed.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}You have confirmed {{email}}.{% endblocktrans %}
3 |
--------------------------------------------------------------------------------
/trade/templates/account/messages/email_deleted.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}Removed e-mail address {{email}}.{% endblocktrans %}
3 |
--------------------------------------------------------------------------------
/trade/templates/account/messages/password_set.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}Password successfully set.{% endblocktrans %}
3 |
4 |
--------------------------------------------------------------------------------
/trade/templates/account/messages/primary_email_set.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}Primary e-mail address set.{% endblocktrans %}
3 |
--------------------------------------------------------------------------------
/trade/static/fonts/roboto/Roboto-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/fonts/roboto/Roboto-Medium.woff2
--------------------------------------------------------------------------------
/trade/static/fonts/roboto/Roboto-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/fonts/roboto/Roboto-Regular.woff
--------------------------------------------------------------------------------
/trade/static/fonts/roboto/Roboto-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/fonts/roboto/Roboto-Regular.woff2
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/bitshares.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/bitshares.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/blackcoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/blackcoin.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/blocknet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/blocknet.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/digibyte.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/digibyte.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/dogecoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/dogecoin.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/ethereum.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/ethereum.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/etheroll.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/etheroll.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/litecoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/litecoin.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/namecoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/namecoin.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/peercoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/peercoin.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/reddcoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/reddcoin.png
--------------------------------------------------------------------------------
/trade/templates/account/messages/password_changed.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}Password successfully changed.{% endblocktrans %}
3 |
4 |
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/bitcoindark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/bitcoindark.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/bitconnect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/bitconnect.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/bytecoin-bcn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/bytecoin-bcn.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/counterparty.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/counterparty.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/gamecredits.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/gamecredits.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/gnosis-gno.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/gnosis-gno.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/maidsafecoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/maidsafecoin.png
--------------------------------------------------------------------------------
/trade/static/css/images/ui-icons_222222_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/ui-icons_222222_256x240.png
--------------------------------------------------------------------------------
/trade/static/css/images/ui-icons_2e83ff_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/ui-icons_2e83ff_256x240.png
--------------------------------------------------------------------------------
/trade/static/css/images/ui-icons_454545_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/ui-icons_454545_256x240.png
--------------------------------------------------------------------------------
/trade/static/css/images/ui-icons_888888_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/ui-icons_888888_256x240.png
--------------------------------------------------------------------------------
/trade/static/css/images/ui-icons_cd0a0a_256x240.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/ui-icons_cd0a0a_256x240.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/library-credit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/library-credit.png
--------------------------------------------------------------------------------
/trade/templates/account/messages/email_confirmation_sent.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}Confirmation e-mail sent to {{email}}.{% endblocktrans %}
3 |
--------------------------------------------------------------------------------
/trade/templates/socialaccount/messages/account_connected.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}The social account has been connected.{% endblocktrans %}
3 |
--------------------------------------------------------------------------------
/trade/static/css/images/ui-bg_flat_0_aaaaaa_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/ui-bg_flat_0_aaaaaa_40x100.png
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/ethereum-classic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/ethereum-classic.png
--------------------------------------------------------------------------------
/trade/static/css/images/ui-bg_flat_75_ffffff_40x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/ui-bg_flat_75_ffffff_40x100.png
--------------------------------------------------------------------------------
/trade/static/css/images/ui-bg_glass_55_fbf9ee_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/ui-bg_glass_55_fbf9ee_1x400.png
--------------------------------------------------------------------------------
/trade/static/css/images/ui-bg_glass_65_ffffff_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/ui-bg_glass_65_ffffff_1x400.png
--------------------------------------------------------------------------------
/trade/static/css/images/ui-bg_glass_75_dadada_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/ui-bg_glass_75_dadada_1x400.png
--------------------------------------------------------------------------------
/trade/static/css/images/ui-bg_glass_75_e6e6e6_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/ui-bg_glass_75_e6e6e6_1x400.png
--------------------------------------------------------------------------------
/trade/static/css/images/ui-bg_glass_95_fef1ec_1x400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/ui-bg_glass_95_fef1ec_1x400.png
--------------------------------------------------------------------------------
/trade/templates/account/messages/unverified_primary_email.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}Your primary e-mail address must be verified.{% endblocktrans %}
3 |
--------------------------------------------------------------------------------
/trade/templates/socialaccount/messages/account_disconnected.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}The social account has been disconnected.{% endblocktrans %}
3 |
--------------------------------------------------------------------------------
/trade/static/images/cryptotokens/golem-network-tokens.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/images/cryptotokens/golem-network-tokens.png
--------------------------------------------------------------------------------
/trade/static/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OnGridSystems/CATEd/HEAD/trade/static/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png
--------------------------------------------------------------------------------
/trade/templates/account/messages/cannot_delete_primary_email.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}You cannot remove your primary e-mail address ({{email}}).{% endblocktrans %}
3 |
--------------------------------------------------------------------------------
/trade/templates/account/email/password_reset_key_subject.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% autoescape off %}
3 | {% blocktrans %}Password Reset E-mail{% endblocktrans %}
4 | {% endautoescape %}
--------------------------------------------------------------------------------
/trade/templates/socialaccount/messages/account_connected_other.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% blocktrans %}The social account is already connected to a different account.{% endblocktrans %}
3 |
--------------------------------------------------------------------------------
/trade/templates/account/email/email_confirmation_subject.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% autoescape off %}
3 | {% blocktrans %}Please Confirm Your E-mail Address{% endblocktrans %}
4 | {% endautoescape %}
5 |
--------------------------------------------------------------------------------
/trade/templates/account/messages/logged_in.txt:
--------------------------------------------------------------------------------
1 | {% load account %}
2 | {% load i18n %}
3 | {% user_display user as name %}
4 | {% blocktrans %}Successfully signed in as {{name}}.{% endblocktrans %}
5 |
--------------------------------------------------------------------------------
/trade/templates/trade/user_summaries.html:
--------------------------------------------------------------------------------
1 |
Total balance {{ btc | floatformat:"-8"}} BTC / {{ usd | floatformat:"-2" }} USD ({% now "DATETIME_FORMAT" %})
--------------------------------------------------------------------------------
/djangoTrade/routing.py:
--------------------------------------------------------------------------------
1 | from channels.routing import route
2 | from tradeBOT.consumers import ws_add, ws_disconnect
3 |
4 | channel_routing = [
5 | route("websocket.connect", ws_add, path=r'^/trade/'),
6 | route("websocket.disconnect", ws_disconnect),
7 | ]
8 |
--------------------------------------------------------------------------------
/trade/templates/account/snippets/already_logged_in.html:
--------------------------------------------------------------------------------
1 | {% load i18n %}
2 | {% load account %}
3 |
4 | {% user_display user as user_display %}
5 | {% trans "Note" %}: {% blocktrans %}you are already logged in as {{ user_display }}.{% endblocktrans %}
6 |
--------------------------------------------------------------------------------
/tradeBOT/consumers.py:
--------------------------------------------------------------------------------
1 | from channels import Group
2 |
3 |
4 | def ws_add(message):
5 | message.reply_channel.send({"accept": True})
6 | Group("trade").add(message.reply_channel)
7 |
8 |
9 | def ws_disconnect(message):
10 | Group("trade").discard(message.reply_channel)
11 |
--------------------------------------------------------------------------------
/dump.json:
--------------------------------------------------------------------------------
1 | [{"model": "trade.exchanges", "pk": 1, "fields": {"name": "poloniex", "info_frozen_key": "-isFrozen"}}, {"model": "trade.wallets", "pk": 1, "fields": {"name": "BTC"}}, {"model": "trade.wallets", "pk": 2, "fields": {"name": "ETH"}}, {"model": "trade.wallets", "pk": 3, "fields": {"name": "Yandex Money"}}]
--------------------------------------------------------------------------------
/trade/templatetags/coins.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from trade.models import UserBalance
3 |
4 | register = template.Library()
5 |
6 |
7 | @register.inclusion_tag('trade/coins.html')
8 | def get_coins(ue):
9 | coins = UserBalance.objects.filter(ue=ue).order_by('-total')
10 | return {'coins': coins}
11 |
--------------------------------------------------------------------------------
/tradeBOT/templates/tradeBOT/pairs.html:
--------------------------------------------------------------------------------
1 | {% load tradeBot_filters %}
2 | Available pairs:
3 | {% for pair in pairs %}
4 | {{ pair.main_coin.symbol }}-{{ pair.second_coin.symbol }}
5 | {% empty %}
6 | None
7 | {% endfor %}
--------------------------------------------------------------------------------
/trade/templates/account/signup_closed.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Sign Up Closed" %}{% endblock %}
6 |
7 | {% block content %}
8 | {% trans "Sign Up Closed" %}
9 |
10 | {% trans "We are sorry, but the sign up is currently closed." %}
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/trade/templatetags/transactions.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from trade.models import Transaction
3 |
4 | register = template.Library()
5 |
6 |
7 | @register.inclusion_tag('trade/transactions.html')
8 | def get_transactions(uw):
9 | transactions = Transaction.objects.all().order_by('-date')
10 | return {'transactions': transactions, 'item': uw}
11 |
--------------------------------------------------------------------------------
/ticker_app/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from ticker_app import models
3 |
4 |
5 | class ExchangeTickerAdmin(admin.ModelAdmin):
6 | list_display = [field.name for field in models.ExchangeTicker._meta.fields]
7 |
8 | class Meta:
9 | model = models.ExchangeTicker
10 |
11 | admin.site.register(models.ExchangeTicker, ExchangeTickerAdmin)
12 |
--------------------------------------------------------------------------------
/trade/templates/account/account_inactive.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Account Inactive" %}{% endblock %}
6 |
7 | {% block content %}
8 |
9 |
10 |
{% trans "Account Inactive" %}
11 |
12 |
{% trans "This account is inactive." %}
13 |
14 | {% endblock %}
15 |
--------------------------------------------------------------------------------
/trade/templates/account/password_reset_from_key_done.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 | {% block head_title %}{% trans "Change Password" %}{% endblock %}
5 |
6 | {% block content %}
7 |
8 |
9 |
{% trans "Change Password" %}
10 |
{% trans 'Your password is now changed.' %}
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/trade/templates/socialaccount/authentication_error.html:
--------------------------------------------------------------------------------
1 | {% extends "socialaccount/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Social Network Login Failure" %}{% endblock %}
6 |
7 | {% block content %}
8 | {% trans "Social Network Login Failure" %}
9 |
10 | {% trans "An error occurred while attempting to login via your social network account." %}
11 | {% endblock %}
12 |
--------------------------------------------------------------------------------
/templates/404.html:
--------------------------------------------------------------------------------
1 | {% load static %}
2 |
3 |
4 |
5 |
6 | You've ripped a hole in the fabric of the internet. Love, Chris from CSS-Tricks
7 |
8 |
9 |
11 |
12 |
--------------------------------------------------------------------------------
/tradeBOT/templates/tradeBOT/coin_info.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Rank: {{ coin.rank }}
4 |
5 |
6 | Price usd: {{ coin.price_usd | floatformat:'-2'}}
7 |
8 |
9 | Volume usd 24h: {{ coin.volume_usd_24h | floatformat:'-2'}}
10 |
11 |
12 | Available supply: {{ coin.available_supply | floatformat:'-2'}}
13 |
14 |
--------------------------------------------------------------------------------
/trade/templates/openid/login.html:
--------------------------------------------------------------------------------
1 | {% extends "openid/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}OpenID Sign In{% endblock %}
6 |
7 | {% block content %}
8 |
9 | {% trans 'OpenID Sign In' %}
10 |
11 |
12 |
17 |
18 | {% endblock %}
19 |
--------------------------------------------------------------------------------
/djangoTrade/wsgi.py:
--------------------------------------------------------------------------------
1 | """
2 | WSGI config for djangoTrade project.
3 |
4 | It exposes the WSGI callable as a module-level variable named ``application``.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/
8 | """
9 |
10 | import os
11 |
12 | from django.core.wsgi import get_wsgi_application
13 |
14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoTrade.settings")
15 |
16 | application = get_wsgi_application()
17 |
--------------------------------------------------------------------------------
/trade/templatetags/coin_full_name.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from django.template.defaultfilters import stringfilter
3 | from trade.models import Coin
4 |
5 | register = template.Library()
6 |
7 |
8 | @register.filter(name='get_full_name')
9 | @stringfilter
10 | def get_full_name(short_name):
11 | try:
12 | coin = Coin.objects.get(short_name=short_name.upper())
13 | return str(coin.full_name)
14 | except Coin.DoesNotExist:
15 | return '-'
16 |
--------------------------------------------------------------------------------
/tradeBOT/templatetags/get_coin_info.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from tradeBOT.models import CoinMarketCupCoin
3 |
4 | register = template.Library()
5 |
6 |
7 | @register.inclusion_tag('tradeBOT/coin_info.html')
8 | def coin_info(symbol):
9 | try:
10 | coin = CoinMarketCupCoin.objects.get(symbol=symbol)
11 | except CoinMarketCupCoin.DoesNotExist:
12 | return None
13 | except CoinMarketCupCoin.MultipleObjectsReturned:
14 | return None
15 | return {'coin': coin}
16 |
--------------------------------------------------------------------------------
/trade/templates/account/password_set.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Set Password" %}{% endblock %}
6 |
7 | {% block content %}
8 | {% trans "Set Password" %}
9 |
10 |
15 | {% endblock %}
16 |
--------------------------------------------------------------------------------
/tradeBOT/templates/tradeBOT/Coins.html:
--------------------------------------------------------------------------------
1 | {% if coins %}
2 | Exchange: {{ exch.exchange }}
3 |
4 |
5 |
6 | Name
7 | Symbol
8 |
9 |
10 |
11 | {% for coin in coins %}
12 |
13 | {{ coin.name }}
14 | {{ coin.symbol }}
15 |
16 | {% endfor %}
17 |
18 |
19 | {% endif %}
--------------------------------------------------------------------------------
/tradeBOT/templatetags/get_exchange_coins.py:
--------------------------------------------------------------------------------
1 | from django import template
2 |
3 | from trade.models import Exchanges
4 | from tradeBOT.models import ExchangeCoin
5 |
6 | register = template.Library()
7 |
8 |
9 | @register.inclusion_tag('tradeBOT/Coins.html')
10 | def exchange_coins(exch):
11 | exchange = Exchanges.objects.get(exchange=exch)
12 | exch_coins = ExchangeCoin.objects.filter(exchange=exchange).order_by('-is_active', 'name')
13 | return {
14 | 'exch': exchange,
15 | 'coins': exch_coins,
16 | }
17 |
--------------------------------------------------------------------------------
/trade/forms.py:
--------------------------------------------------------------------------------
1 | from django.forms import ModelForm
2 | from trade.models import UserExchange, UserWallet
3 | from django.contrib.auth.models import User
4 | from django import forms
5 | from django.forms.extras.widgets import SelectDateWidget
6 |
7 |
8 | class UserWalletForm(ModelForm):
9 | class Meta:
10 | model = UserWallet
11 | fields = ['wallet', 'address']
12 |
13 |
14 | class UserExchangesForm(ModelForm):
15 | class Meta:
16 | model = UserExchange
17 | fields = ['exchange', 'apikey', 'apisecret']
18 |
--------------------------------------------------------------------------------
/tradeBOT/templates/tradeBOT/exchange_primary_coins.html:
--------------------------------------------------------------------------------
1 | {% load relations %}
2 | {% for pc in primary_coins %}
3 |
12 | {% empty %}
13 | Netu primary coins
14 | {% endfor %}
--------------------------------------------------------------------------------
/trade/templates/socialaccount/login_cancelled.html:
--------------------------------------------------------------------------------
1 | {% extends "socialaccount/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Login Cancelled" %}{% endblock %}
6 |
7 | {% block content %}
8 |
9 | {% trans "Login Cancelled" %}
10 |
11 | {% url 'account_login' as login_url %}
12 |
13 | {% blocktrans %}You decided to cancel logging in to our site using one of your existing accounts. If this was a mistake, please proceed to sign in .{% endblocktrans %}
14 |
15 | {% endblock %}
16 |
--------------------------------------------------------------------------------
/trade/templates/account/verification_sent.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Verify Your E-mail Address" %}{% endblock %}
6 |
7 | {% block content %}
8 |
9 |
10 |
{% trans "Verify Your E-mail Address" %}
11 |
12 |
{% blocktrans %}We have sent an e-mail to you for verification. Follow the link provided to finalize the signup process. Please contact us if you do not receive it within a few minutes.{% endblocktrans %}
13 |
14 | {% endblock %}
15 |
--------------------------------------------------------------------------------
/tradeBOT/templates/tradeBOT/relations.html:
--------------------------------------------------------------------------------
1 | {% extends 'trade/base.html' %}
2 | {% load relations %}
3 | {% block content %}
4 |
5 | {% for exchange in exchanges %}
6 |
13 | {% endfor %}
14 |
15 | {% endblock %}
--------------------------------------------------------------------------------
/trade/templates/account/email/email_confirmation_message.txt:
--------------------------------------------------------------------------------
1 | {% load account %}{% user_display user as user_display %}{% load i18n %}{% autoescape off %}{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}Hello from {{ site_name }}!
2 |
3 | You're receiving this e-mail because user {{ user_display }} has given yours as an e-mail address to connect their account.
4 |
5 | To confirm this is correct, go to {{ activate_url }}
6 | {% endblocktrans %}{% endautoescape %}
7 | {% blocktrans with site_name=current_site.name site_domain=current_site.domain %}Thank you from {{ site_name }}!
8 | {{ site_domain }}{% endblocktrans %}
9 |
--------------------------------------------------------------------------------
/tradeBOT/templates/tradeBOT/index.html:
--------------------------------------------------------------------------------
1 | {% extends 'trade/base.html' %}
2 | {% block content %}
3 |
4 |
11 |
12 |
13 | Your trade coins
14 | {% for coin in user_coins %}
15 | {{ coin }}
16 | {% endfor %}
17 | {% endblock %}
--------------------------------------------------------------------------------
/trade/templates/account/password_reset_done.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 | {% load account %}
5 |
6 | {% block head_title %}{% trans "Password Reset" %}{% endblock %}
7 |
8 | {% block content %}
9 |
10 |
11 |
{% trans "Password Reset" %}
12 |
13 | {% if user.is_authenticated %}
14 | {% include "account/snippets/already_logged_in.html" %}
15 | {% endif %}
16 |
17 |
{% blocktrans %}We have sent you an e-mail. Please contact us if you do not receive it within a few minutes.{% endblocktrans %}
18 |
19 |
20 | {% endblock %}
21 |
--------------------------------------------------------------------------------
/trade/templates/account/email/password_reset_key_message.txt:
--------------------------------------------------------------------------------
1 | {% load i18n %}{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}Hello from {{ site_name }}!
2 |
3 | You're receiving this e-mail because you or someone else has requested a password for your user account.
4 | It can be safely ignored if you did not request a password reset. Click the link below to reset your password.{% endblocktrans %}
5 |
6 | {{ password_reset_url }}
7 |
8 | {% if username %}{% blocktrans %}In case you forgot, your username is {{ username }}.{% endblocktrans %}
9 |
10 | {% endif %}{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}Thank you for using {{ site_name }}!
11 | {{ site_domain }}{% endblocktrans %}
12 |
--------------------------------------------------------------------------------
/tradeBOT/templates/tradeBOT/primary_coin_pairs.html:
--------------------------------------------------------------------------------
1 | {% load get_coin_info %}
2 | {% for pair in pairs %}
3 |
15 | {% empty %}
16 | Netu pairs
17 | {% endfor %}
--------------------------------------------------------------------------------
/trade/templates/account/logout.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Sign Out" %}{% endblock %}
6 |
7 | {% block content %}
8 |
9 |
10 |
{% trans "Sign Out" %}
11 |
12 |
{% trans 'Are you sure you want to sign out?' %}
13 |
14 |
21 |
22 |
23 | {% endblock %}
24 |
--------------------------------------------------------------------------------
/tradeBOT/templatetags/relations.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from tradeBOT.models import ExchangeMainCoin, Pair
3 |
4 | register = template.Library()
5 |
6 |
7 | @register.inclusion_tag('tradeBOT/exchange_primary_coins.html')
8 | def exchange_primary_coins(exchange):
9 | try:
10 | primary_coins = ExchangeMainCoin.objects.filter(coin__exchange=exchange)
11 | return {'primary_coins': primary_coins}
12 | except ExchangeMainCoin.DoesNotExist:
13 | return None
14 |
15 |
16 | @register.inclusion_tag('tradeBOT/primary_coin_pairs.html')
17 | def primary_coin_pairs(primary_coin):
18 | try:
19 | pairs = Pair.objects.filter(main_coin=primary_coin.coin)
20 | return {'pairs': pairs}
21 | except Pair.DoesNotExist:
22 | return None
23 |
--------------------------------------------------------------------------------
/trade/templates/socialaccount/snippets/provider_list.html:
--------------------------------------------------------------------------------
1 | {% load socialaccount %}
2 |
3 | {% get_providers as socialaccount_providers %}
4 |
5 | {% for provider in socialaccount_providers %}
6 | {% if provider.id == "openid" %}
7 | {% for brand in provider.get_brands %}
8 |
9 | {{brand.name}}
13 |
14 | {% endfor %}
15 | {% endif %}
16 |
17 | {{provider.name}}
19 |
20 | {% endfor %}
21 |
22 |
--------------------------------------------------------------------------------
/user_profile/views.py:
--------------------------------------------------------------------------------
1 | from django.http import HttpResponse
2 | from trade.models import UserExchange
3 | from django.shortcuts import render
4 |
5 |
6 | # Create your views here.
7 | def profile(request):
8 | args = {'user': request.user}
9 | args['user_exchanges'] = UserExchange.objects.filter(user=args['user'])
10 | args['user_active_exchanges'] = args['user_exchanges'].filter(is_active=True)
11 | if request.POST:
12 | first_name = request.POST.get('firstname')
13 | last_name = request.POST.get('lastname')
14 | if first_name is not None:
15 | args['user'].first_name = first_name
16 | if last_name is not None:
17 | args['user'].last_name = last_name
18 | if last_name or first_name:
19 | args['user'].save()
20 | return render(request, 'user_profile/profile.html', args)
21 |
--------------------------------------------------------------------------------
/manage.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 |
4 | if __name__ == "__main__":
5 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoTrade.settings")
6 | try:
7 | from django.core.management import execute_from_command_line
8 | except ImportError:
9 | # The above import may fail for some other reason. Ensure that the
10 | # issue is really that Django is missing to avoid masking other
11 | # exceptions on Python 2.
12 | try:
13 | import django
14 | except ImportError:
15 | raise ImportError(
16 | "Couldn't import Django. Are you sure it's installed and "
17 | "available on your PYTHONPATH environment variable? Did you "
18 | "forget to activate a virtual environment?"
19 | )
20 | raise
21 | execute_from_command_line(sys.argv)
22 |
--------------------------------------------------------------------------------
/trade/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from .models import Exchanges, UserExchange, UserBalance, Coin, Wallets, UserWallet, UserHoldings, Transaction
3 |
4 |
5 | class TransactionAdmin(admin.ModelAdmin):
6 | list_display = ['name', 't_type', 'date', 'type', 'value']
7 |
8 | class Meta:
9 | model = Transaction
10 |
11 |
12 | class UserBalancesAdmin(admin.ModelAdmin):
13 | list_display = [field.name for field in UserBalance._meta.fields]
14 | list_filter = ['ue']
15 |
16 | class Meta:
17 | model = UserBalance
18 |
19 |
20 | admin.site.register(Exchanges)
21 | admin.site.register(UserExchange)
22 | admin.site.register(UserBalance, UserBalancesAdmin)
23 | admin.site.register(Coin)
24 | admin.site.register(Wallets)
25 | admin.site.register(Transaction, TransactionAdmin)
26 | admin.site.register(UserWallet)
27 | admin.site.register(UserHoldings)
28 |
--------------------------------------------------------------------------------
/trade/templates/socialaccount/signup.html:
--------------------------------------------------------------------------------
1 | {% extends "socialaccount/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Signup" %}{% endblock %}
6 |
7 | {% block content %}
8 | {% trans "Sign Up" %}
9 |
10 | {% blocktrans with provider_name=account.get_provider.name site_name=site.name %}You are about to use your {{provider_name}} account to login to
11 | {{site_name}}. As a final step, please complete the following form:{% endblocktrans %}
12 |
13 |
21 |
22 | {% endblock %}
23 |
--------------------------------------------------------------------------------
/account/templates/account/login.html:
--------------------------------------------------------------------------------
1 | {% extends 'trade/base.html' %}
2 | {% block content %}
3 |
21 | {% endblock %}
--------------------------------------------------------------------------------
/trade/templates/account/verified_email_required.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Verify Your E-mail Address" %}{% endblock %}
6 |
7 | {% block content %}
8 | {% trans "Verify Your E-mail Address" %}
9 |
10 | {% url 'account_email' as email_url %}
11 |
12 | {% blocktrans %}This part of the site requires us to verify that
13 | you are who you claim to be. For this purpose, we require that you
14 | verify ownership of your e-mail address. {% endblocktrans %}
15 |
16 | {% blocktrans %}We have sent an e-mail to you for
17 | verification. Please click on the link inside this e-mail. Please
18 | contact us if you do not receive it within a few minutes.{% endblocktrans %}
19 |
20 | {% blocktrans %}Note: you can still change your e-mail address .{% endblocktrans %}
21 |
22 |
23 | {% endblock %}
24 |
--------------------------------------------------------------------------------
/djangoTrade/celery.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import, unicode_literals
2 | import os
3 | from celery import Celery
4 | from django.conf import settings
5 | from kombu import Queue, Exchange
6 |
7 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoTrade.settings')
8 | app = Celery('djangoTrade')
9 | app.config_from_object('django.conf:settings')
10 | app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
11 | app.conf.task_queues = {
12 | Queue('high', Exchange('high'), routing_key='high'),
13 | Queue('normal', Exchange('normal'), routing_key='normal'),
14 | Queue('low', Exchange('low'), routing_key='low'),
15 | Queue('set_orders', Exchange('set_orders'), routing_key='set_orders'),
16 | }
17 | app.conf.task_default_queue = 'normal'
18 | app.conf.task_default_exchange_type = 'direct'
19 | app.conf.task_default_routing_key = 'normal'
20 |
21 |
22 | @app.task(bind=True)
23 | def debug_task(self):
24 | print('Request: {0!r}'.format(self.request))
25 |
--------------------------------------------------------------------------------
/trade/templates/trade/wallet_info.html:
--------------------------------------------------------------------------------
1 | {% load value_to_cryptotoken %}
2 | {% if success == 1 %}
3 |
4 |
5 | Trans total:
6 | {{ total_trans }} РС
7 |
8 |
9 | In trans total:
10 | {{ in_trans | length }} РС
11 |
12 |
13 | Out trans total:
14 | {{ out_trans | length }} РС
15 |
16 |
17 | In trans total value:
18 | {{ in_trans_sum | value_to_cryptotoken:uw }}
19 |
20 |
21 | Out trans total value:
22 | {{ out_trans_sum | value_to_cryptotoken:uw }}
23 |
24 |
25 | {% else %}
26 | Информация по данному кошельку отсутствует.
27 | {% endif %}
28 |
--------------------------------------------------------------------------------
/trade/templatetags/value_to_cryptotoken.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from trade.models import Transaction, UserWallet
3 |
4 | register = template.Library()
5 |
6 |
7 | @register.filter(name='value_to_cryptotoken')
8 | def value_to_cryptotoken(value, item):
9 | if type(item) == UserWallet:
10 | if item.wallet.name == 'ETH':
11 | return str(round(float(value / (10 ** 18)), 8)) + ' ETH'
12 | elif item.wallet.name == 'BTC':
13 | return str(round(float(value), 8)) + ' BTC'
14 | elif item.wallet.name == 'Yandex Money':
15 | return str(round(float(value), 2)) + ' RUR'
16 | elif type(item) == Transaction:
17 | if item.name[0] == 'E':
18 | return str(round(float(value / (10 ** 18)), 8)) + ' ETH'
19 | elif item.name[0] == 'B':
20 | return str(round(float(value), 8)) + ' BTC'
21 | elif item.name[0] == 'Y':
22 | return str(round(float(value), 2)) + ' RUR'
23 | else:
24 | return str(round(float(value), 2)) + ' ' + item.currency
25 |
--------------------------------------------------------------------------------
/trade/templatetags/wallet_information.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from trade.models import Transaction
3 |
4 | register = template.Library()
5 |
6 |
7 | @register.inclusion_tag('trade/wallet_info.html')
8 | def get_wallet_info(uw):
9 | transactions = Transaction.objects.filter(name=uw.wallet.name + str(uw.pk)).order_by('-date')
10 | if len(transactions) > 0:
11 | in_trans = list(transactions.filter(type='in'))
12 | out_trans = transactions.filter(type='out')
13 | in_trans_sum = 0
14 | out_trans_sum = 0
15 | for item in in_trans:
16 | in_trans_sum += item.value
17 | for item in out_trans:
18 | out_trans_sum += item.value
19 | return {'uw': uw,
20 | 'success': 1,
21 | 'total_trans': len(transactions),
22 | 'in_trans': in_trans,
23 | 'out_trans': out_trans,
24 | 'in_trans_sum': in_trans_sum,
25 | 'out_trans_sum': out_trans_sum
26 | }
27 | else:
28 | return {'success': 0}
29 |
--------------------------------------------------------------------------------
/trade/templates/account/email_confirm.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 | {% load account %}
5 |
6 | {% block head_title %}{% trans "Confirm E-mail Address" %}{% endblock %}
7 |
8 |
9 | {% block content %}
10 | {% trans "Confirm E-mail Address" %}
11 |
12 | {% if confirmation %}
13 |
14 | {% user_display confirmation.email_address.user as user_display %}
15 |
16 | {% blocktrans with confirmation.email_address.email as email %}Please confirm that {{ email }} is an e-mail address for user {{ user_display }}.{% endblocktrans %}
17 |
18 |
22 |
23 | {% else %}
24 |
25 | {% url 'account_email' as email_url %}
26 |
27 | {% blocktrans %}This e-mail confirmation link expired or is invalid. Please issue a new e-mail confirmation request .{% endblocktrans %}
28 |
29 | {% endif %}
30 |
31 | {% endblock %}
32 |
--------------------------------------------------------------------------------
/tradeBOT/templates/tradeBOT/user_primary.html:
--------------------------------------------------------------------------------
1 | {% if success %}
2 | Priority: {{ coin.priority }}
3 |
5 |
6 |
7 | Off
8 |
9 |
10 | On
11 |
12 |
13 | {% else %}
14 | Priority: 1
15 |
17 |
18 |
19 | Off
20 |
21 |
22 | On
23 |
24 |
25 | {% endif %}
26 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 OnGrid Systems
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/account/templates/account/register.html:
--------------------------------------------------------------------------------
1 | {% extends 'trade/base.html' %}
2 | {% block content %}
3 |
26 | {% endblock %}
--------------------------------------------------------------------------------
/ticker_app/models.py:
--------------------------------------------------------------------------------
1 | from django.db import models
2 | from trade import models as trade_models
3 |
4 |
5 | # Create your models here.
6 | class ExchangeTicker(models.Model):
7 | exchange_id = models.IntegerField()
8 | pair_id = models.IntegerField()
9 | high = models.DecimalField(max_digits=30, decimal_places=15)
10 | last = models.DecimalField(max_digits=30, decimal_places=15)
11 | low = models.DecimalField(max_digits=30, decimal_places=15)
12 | bid = models.DecimalField(max_digits=30, decimal_places=15)
13 | ask = models.DecimalField(max_digits=30, decimal_places=15)
14 | base_volume = models.DecimalField(max_digits=30, decimal_places=15, null=True, blank=True)
15 | percent_change = models.DecimalField(max_digits=10, decimal_places=8, default=0)
16 | date_time = models.DateTimeField(blank=False, null=False)
17 |
18 | def __str__(self):
19 | # return trade_models.Exchanges.objects.get(pk=self.exchange_id).name + ': ' + self.pair.main_coin.symbol.upper() + '-' + self.pair.second_coin.symbol.upper()
20 | return '{}: {}'.format(self.exchange_id, self.pair_id)
21 |
22 | class Meta:
23 | verbose_name = 'Данные тикера'
24 | verbose_name_plural = 'Данные тикеров'
25 |
--------------------------------------------------------------------------------
/trade/templates/account/password_reset.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 | {% load account %}
5 |
6 | {% block head_title %}{% trans "Password Reset" %}{% endblock %}
7 |
8 | {% block content %}
9 |
10 |
11 |
{% trans "Password Reset" %}
12 | {% if user.is_authenticated %}
13 | {% include "account/snippets/already_logged_in.html" %}
14 | {% endif %}
15 |
16 |
{% trans "Forgotten your password? Enter your e-mail address below, and we'll send you an e-mail allowing you to reset it." %}
17 |
18 |
26 |
27 |
{% blocktrans %}Please contact us if you have any trouble resetting your password.{% endblocktrans %}
28 |
29 |
30 | {% endblock %}
31 |
--------------------------------------------------------------------------------
/trade/static/css/jqChart.css:
--------------------------------------------------------------------------------
1 | .ui-jqchart {
2 | position: relative;
3 | }
4 |
5 | .ui-jqchart .ui-jqchart-toolbar {
6 | position: absolute;
7 | margin: 0;
8 | padding: 2px;
9 | list-style-type: none;
10 | white-space: nowrap;
11 | }
12 |
13 | .ui-jqchart .ui-jqchart-toolbar li {
14 | display: inline-block;
15 | vertical-align: top;
16 | margin: 0 2px;
17 | padding: 2px 0;
18 | cursor: pointer;
19 | }
20 |
21 | .ui-jqchart .ui-jqchart-toolbar span.ui-icon {
22 | float: left;
23 | margin: 0 2px;
24 | }
25 |
26 | .ui-jqchart .ui-jqchart-toolbar-separator {
27 | height: 16px;
28 | width: 1px;
29 | }
30 |
31 | .ui-jqchart .ui-jqchart-tooltip {
32 | position: absolute;
33 | white-space: nowrap;
34 | padding: .2em .4em;
35 | z-index: 9999;
36 | border: 1px solid #dddddd;
37 | color: #333333;
38 | background: white;
39 | -moz-border-radius: 4px;
40 | -webkit-border-radius: 4px;
41 | border-radius: 4px;
42 | -o-box-shadow: 0 0 5px #aaa;
43 | -moz-box-shadow: 0 0 5px #aaa;
44 | -webkit-box-shadow: 0 0 5px #aaa;
45 | box-shadow: 0 0 5px #aaa;
46 | }
47 |
48 | * html .ui-jqchart .ui-jqchart-tooltip {
49 | background-image: none;
50 | }
51 |
52 | body .ui-jqchart .ui-jqchart-tooltip {
53 | border-width: 2px;
54 | }
--------------------------------------------------------------------------------
/tradeBOT/templates/tradeBOT/to_trade.html:
--------------------------------------------------------------------------------
1 | {% load tradeBot_filters %}
2 | {% if to_trade %}
3 | Calculated values
4 | {% endif %}
5 |
6 |
7 |
8 | Pair
9 | Rate
10 | Type
11 | Price
12 | Amount
13 | Total
14 | Total + fee
15 | Fee
16 | Cause
17 | Date created
18 | Date updated
19 |
20 |
21 |
22 | {% for item in to_trade %}
23 |
24 | {{ item.user_pair.pair.main_coin.symbol.upper }}_{{ item.user_pair.pair.second_coin.symbol.upper }}
25 | {{ item.percent_react | multiple:100 | floatformat:'2' }}
26 | {{ item.type }}
27 | {{ item.price }}
28 | {{ item.amount }}
29 | {{ item.total }}
30 | {{ item.total_f }}
31 | {{ item.fee }}
32 | {{ item.cause }}
33 | {{ item.date_created | date:'d.m.Y H:i:s' }}
34 | {{ item.date_updated | date:'d.m.Y H:i:s' }}
35 |
36 | {% endfor %}
37 |
38 |
39 |
--------------------------------------------------------------------------------
/ticker_app/routers.py:
--------------------------------------------------------------------------------
1 | class DBRouter:
2 | def db_for_read(self, model, **hints):
3 | if model._meta.app_label == 'ticker_app':
4 | return 'portal_ticker'
5 | return None
6 |
7 | def db_for_write(self, model, **hints):
8 | if model._meta.app_label == 'ticker_app':
9 | return 'portal_ticker'
10 | return None
11 |
12 | def allow_relation(self, obj1, obj2, **hints):
13 | if obj1._meta.app_label == 'ticker_app' and obj2._meta.app_label == 'ticker_app':
14 | return True
15 | elif 'ticker_app' not in [obj1._meta.app_label, obj2._meta.app_label]:
16 | return None
17 | return False
18 |
19 | def allow_migrate(self, db, app_label, model_name=None, **hints):
20 | if app_label == 'ticker_app':
21 | return db == 'portal_ticker'
22 | elif db == 'portal_ticker':
23 | return False
24 | return None
25 |
26 |
27 | class PrimaryRouter:
28 | def db_for_read(self, model, **hints):
29 | return 'default'
30 |
31 | def db_for_write(self, model, **hints):
32 | return 'default'
33 |
34 | def allow_relation(self, obj1, obj2, **hints):
35 | db_list = ('default',)
36 | if obj1._state.db in db_list and obj2._state.db in db_list:
37 | return True
38 | return None
39 |
40 | def allow_migrate(self, db, app_label, model_name=None, **hints):
41 | return True
42 |
--------------------------------------------------------------------------------
/trade/templatetags/summary_balance.py:
--------------------------------------------------------------------------------
1 | from django import template
2 | from trade.models import UserWallet, UserExchange
3 | import requests
4 |
5 | register = template.Library()
6 |
7 |
8 | @register.filter
9 | def get_user_summaries_btc(user):
10 | btc_total = float(0)
11 | usd_total = float(0)
12 | wallets = UserWallet.objects.all()
13 | exchanges = UserExchange.objects.all()
14 | if wallets is not None:
15 | for wallet in wallets:
16 | usd_total += float(wallet.total_usd)
17 | if exchanges is not None:
18 | for exchange in exchanges:
19 | usd_total += float(exchange.total_usd)
20 | if usd_total > 0:
21 | btc_price = requests.get('https://api.cryptonator.com/api/full/btc-usd').json()
22 | btc_total = usd_total / float(btc_price['ticker']['price'])
23 | return btc_total
24 |
25 |
26 | @register.filter
27 | def get_user_summaries_usd(user):
28 | usd_total = float(0)
29 | wallets = UserWallet.objects.all()
30 | exchanges = UserExchange.objects.all()
31 | if wallets is not None:
32 | for wallet in wallets:
33 | usd_total += float(wallet.total_usd)
34 | if exchanges is not None:
35 | for exchange in exchanges:
36 | usd_total += float(exchange.total_usd)
37 | return usd_total
38 |
39 |
40 | @register.filter
41 | def as_percent_of(part, whole):
42 | try:
43 | return float(part) / whole * 100
44 | except (ValueError, ZeroDivisionError):
45 | return 0
46 |
--------------------------------------------------------------------------------
/ticker_app/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.5 on 2017-09-29 08:29
3 | from __future__ import unicode_literals
4 |
5 | from django.db import migrations, models
6 |
7 |
8 | class Migration(migrations.Migration):
9 |
10 | initial = True
11 |
12 | dependencies = [
13 | ]
14 |
15 | operations = [
16 | migrations.CreateModel(
17 | name='ExchangeTicker',
18 | fields=[
19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20 | ('exchange_id', models.IntegerField()),
21 | ('pair_id', models.IntegerField()),
22 | ('high', models.DecimalField(decimal_places=15, max_digits=30)),
23 | ('last', models.DecimalField(decimal_places=15, max_digits=30)),
24 | ('low', models.DecimalField(decimal_places=15, max_digits=30)),
25 | ('bid', models.DecimalField(decimal_places=15, max_digits=30)),
26 | ('ask', models.DecimalField(decimal_places=15, max_digits=30)),
27 | ('base_volume', models.DecimalField(blank=True, decimal_places=15, max_digits=30, null=True)),
28 | ('percent_change', models.DecimalField(decimal_places=8, default=0, max_digits=10)),
29 | ('date_time', models.DateTimeField()),
30 | ],
31 | options={
32 | 'verbose_name': 'Данные тикера',
33 | 'verbose_name_plural': 'Данные тикеров',
34 | },
35 | ),
36 | ]
37 |
--------------------------------------------------------------------------------
/trade/templates/trade/base.html:
--------------------------------------------------------------------------------
1 | {% load static %}
2 |
3 |
4 |
5 |
6 |
7 | TradeOnGrid
8 |
9 |
10 |
11 |
12 |
13 | {% block style %}{% endblock %}
14 |
15 |
16 |
17 |
27 |
28 | {% block content %}{% endblock %}
29 |
30 |
31 |
32 | {% block script %}{% endblock %}
33 |
34 |
--------------------------------------------------------------------------------
/trade/templates/account/password_change.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Change Password" %}{% endblock %}
6 |
7 | {% block content %}
8 |
9 |
10 |
{% trans "Change Password" %}
11 |
12 |
36 |
37 |
38 | {% endblock %}
--------------------------------------------------------------------------------
/tradeBOT/templates/tradeBOT/orders.html:
--------------------------------------------------------------------------------
1 | {% load tradeBot_filters %}
2 | {% if orders %}
3 |
4 |
5 |
6 | Pair
7 | Type
8 | Order number
9 | Price
10 | Amount
11 | Total
12 | Fee
13 | Fact total
14 | Fact fee
15 | Status
16 | Created
17 | Canceled/Closed
18 |
19 |
20 |
21 | {% for item in orders %}
22 |
23 | {{ item.pair.main_coin.symbol.upper }}_{{ item.pair.second_coin.symbol.upper }}
24 | {{ item.order_type }}
25 | {{ item.order_number }}
26 | {{ item.price }}
27 | {{ item.amount }}
28 | {{ item.total }}
29 | {{ item.fee }}
30 | {{ item.fact_total }}
31 | {{ item.fact_fee }}
32 | {% if item.cancel_desc %}{{ item.cancel_desc }}{% else %}Working{% endif %}
33 | {{ item.date_created | date:'d.m.Y H:i:s' }}
34 | {% if item.date_cancel %}{{ item.date_cancel | date:'d.m.Y H:i:s' }}{% else %}-{% endif %}
35 |
36 | {% endfor %}
37 |
38 |
39 | {% endif %}
40 |
--------------------------------------------------------------------------------
/tradeBOT/templates/tradeBOT/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 | Document
9 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | ghbdtn
34 | gjrf
35 | adawdadw
36 | adadadadad
37 |
38 | wdadadawdadwawdadadawdawdadadawdadwawdadadawdawdadadawdadw awdadadawdawdadadawdadwawdadadawdawdadadawdadwawdadadawdadwawdadadaw dadwawdadadawdadwawdadadawdadwawdadadawdadwawdadadawdadw
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/trade/templates/socialaccount/connections.html:
--------------------------------------------------------------------------------
1 | {% extends "socialaccount/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Account Connections" %}{% endblock %}
6 |
7 | {% block content %}
8 | {% trans "Account Connections" %}
9 |
10 | {% if form.accounts %}
11 | {% blocktrans %}You can sign in to your account using any of the following third party accounts:{% endblocktrans %}
12 |
13 |
14 |
41 |
42 | {% else %}
43 | {% trans 'You currently have no social network accounts connected to this account.' %}
44 | {% endif %}
45 |
46 | {% trans 'Add a 3rd Party Account' %}
47 |
48 |
49 | {% include "socialaccount/snippets/provider_list.html" with process="connect" %}
50 |
51 |
52 | {% include "socialaccount/snippets/login_extra.html" %}
53 |
54 | {% endblock %}
55 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | aiodns==1.1.1
2 | aiohttp==2.2.5
3 | amqp==2.2.2
4 | anyjson==0.3.3
5 | asgi-redis==1.4.2
6 | asgiref==1.1.2
7 | asn1crypto==0.22.0
8 | async-timeout==1.4.0
9 | attrs==17.2.0
10 | autobahn==17.7.1
11 | Automat==0.6.0
12 | Babel==2.4.0
13 | bcrypt==3.1.3
14 | billiard==3.5.0.3
15 | bittrex==0.1.4
16 | cchardet==2.1.1
17 | ccxt==1.8.49
18 | celery==4.1.0
19 | certifi==2017.4.17
20 | cffi==1.10.0
21 | channels==1.1.6
22 | chardet==3.0.4
23 | constantly==15.1.0
24 | coverage==4.4.1
25 | cryptography==1.9
26 | daemon==1.1
27 | daphne==1.3.0
28 | defusedxml==0.5.0
29 | Django==1.11.5
30 | django-allauth==0.32.0
31 | django-celery==3.2.1
32 | django-celery-beat==1.0.1
33 | django-extensions==2.0.6
34 | django-redis-sessions==0.5.6
35 | flower==0.9.1
36 | future==0.16.0
37 | gevent==1.2.2
38 | greenlet==0.4.12
39 | gunicorn==19.7.1
40 | hyperlink==17.3.0
41 | idna==2.5
42 | incremental==17.5.0
43 | jsonpickle==0.9.5
44 | kombu==4.1.0
45 | msgpack-python==0.4.8
46 | multidict==3.2.0
47 | mysqlclient==1.3.10
48 | oauthlib==2.0.2
49 | paramiko==2.2.1
50 | poloniex==0.0.7
51 | pyasn1==0.2.3
52 | pyasn1-modules==0.0.9
53 | pycares==2.3.0
54 | pycparser==2.17
55 | PyNaCl==1.1.2
56 | pyOpenSSL==17.0.0
57 | pyTelegramBotAPI==3.2.0
58 | python3-openid==3.1.0
59 | pytz==2018.4
60 | redis==2.10.5
61 | requests==2.18.4
62 | requests-oauthlib==0.8.0
63 | service-identity==17.0.0
64 | signalr-client==0.0.7
65 | six==1.10.0
66 | slackclient==1.0.9
67 | SQLAlchemy==1.2.6
68 | sseclient==0.0.18
69 | TelegramBotAPI==0.3.2
70 | tornado==4.2
71 | Twisted==17.5.0
72 | txaio==2.8.1
73 | urllib3==1.21.1
74 | vine==1.1.4
75 | websocket==0.2.1
76 | websocket-client==0.44.0
77 | websockets==3.3
78 | yandex-money-sdk==0.1.3
79 | yarl==0.12.0
80 | zope.interface==4.4.2
81 | pip==10.0.0
82 |
--------------------------------------------------------------------------------
/trade/templates/trade/coins.html:
--------------------------------------------------------------------------------
1 | {% load coin_full_name humanize %}
2 | {% if coins %}
3 |
4 |
5 |
6 | Coin
7 | Name
8 | Available
9 | On trade
10 | Total
11 |
12 | Btc value (~)
13 | Last update
14 |
15 |
16 |
17 | {% for coin in coins %}
18 |
19 | {{ coin.coin }}
20 | {{ coin.coin | get_full_name }}
21 | {{ coin.free }}
22 | {{ coin.used }}
23 | {{ coin.total }}
24 |
25 | {{ coin.btc_value }}
26 | {{ coin.last_update | naturaltime }}
27 |
28 | {% endfor %}
29 |
30 |
31 | {% else %}
32 |
33 |
34 |
35 | Name
36 |
37 | Available
38 | Last update
39 |
40 |
41 |
42 |
43 | Coins not ready yet
44 |
45 |
46 |
47 | {% endif %}
48 |
--------------------------------------------------------------------------------
/trade/templates/account/signup.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Signup" %}{% endblock %}
6 |
7 | {% block content %}
8 |
9 |
10 |
{% trans "Sign Up" %}
11 |
12 |
{% blocktrans %}Already have an account? Then please sign in .{% endblocktrans %}
13 |
14 |
40 |
41 |
42 | {% endblock %}
43 |
--------------------------------------------------------------------------------
/account/templates/account/profile.html:
--------------------------------------------------------------------------------
1 | {% extends 'trade/base.html' %}
2 | {% block content %}
3 | Мой профиль
4 |
5 |
6 |
7 |
Complete your user profile to increase your limits.
8 |
9 |
37 | {{ form.as_p }}
38 |
39 |
40 |
41 |
42 | {% endblock %}
--------------------------------------------------------------------------------
/trade/templates/account/password_reset_from_key.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 | {% block head_title %}{% trans "Change Password" %}{% endblock %}
5 |
6 | {% block content %}
7 |
8 |
9 |
{% if token_fail %}{% trans "Bad Token" %}{% else %}{% trans "Change Password" %}{% endif %}
10 |
11 | {% if token_fail %}
12 | {% url 'account_reset_password' as passwd_reset_url %}
13 |
{% blocktrans %}The password reset link was invalid, possibly because it has already been used. Please request a new password reset .{% endblocktrans %}
14 | {% else %}
15 | {% if form %}
16 |
42 | {% else %}
43 |
{% trans 'Your password is now changed.' %}
44 | {% endif %}
45 | {% endif %}
46 | {% endblock %}
47 |
--------------------------------------------------------------------------------
/trade/static/css/setup.css:
--------------------------------------------------------------------------------
1 | .chart-info {
2 | font-size: 0.8rem;
3 | min-width: 50%;
4 | float: right;
5 | display: flex;
6 | display: -webkit-flex;
7 | -webkit-justify-content: space-around;
8 | justify-content: space-around;
9 | }
10 |
11 | .btn-mini {
12 | padding: 1px 6px;
13 | height: 20px;
14 | line-height: 20px;
15 | }
16 |
17 | .graph-block, .order_table {
18 | border: 1px slategrey solid;
19 | background: #fafafa;
20 | }
21 |
22 | .exchange-coins-block {
23 | max-height: 600px;
24 | border: 1px slategrey solid;
25 | background: #fafafa;
26 | }
27 |
28 | .exchange-coins-block-scroll {
29 | overflow-y: scroll;
30 | max-height: 390px;
31 | font-size: 10px;
32 | }
33 |
34 | .header h5 {
35 | margin-top: 0 !important;
36 | }
37 |
38 | .header {
39 | padding: 10px 0 4px 0;
40 | }
41 |
42 | .directions_block {
43 | width: 100%;
44 | height: 300px;
45 | overflow-x: scroll;
46 | }
47 |
48 | .priceChangeUp {
49 | background-color: #ceebd3 !important;
50 | border-top: 1px double #27892f;
51 | border-bottom: 1px double #27892f;
52 | -webkit-transition: all .3s;
53 | -moz-transition: all .3s;
54 | -ms-transition: all .3s;
55 | -o-transition: all .3s;
56 | transition: all .3s;
57 | }
58 |
59 | .priceChangeDown {
60 | background-color: #f6d4d1 !important;
61 | border-top: 1px double #c02a1d;
62 | border-bottom: 1px double #c02a1d;
63 | -webkit-transition: all .3s;
64 | -moz-transition: all .3s;
65 | -ms-transition: all .3s;
66 | -o-transition: all .3s;
67 | transition: all .3s;
68 | }
69 |
70 | #buttons-zoom button, #buttons button {
71 | margin: -2px;
72 | border-radius: 0;
73 | background-image: linear-gradient(#ffffff, #c4d5db);
74 | background-color: white;
75 | box-shadow: none;
76 | border: 1px solid #91abac;
77 | color: black;
78 | border-left-width: 0;
79 | font-size: 11px;
80 | }
81 |
82 | #buttons-zoom div button:first-child, #buttons div button:first-child {
83 | border-top-left-radius: 10px;
84 | border-bottom-left-radius: 10px;
85 | }
86 |
87 | #buttons-zoom div button:last-child, #buttons div button:last-child {
88 | border-top-right-radius: 10px;
89 | border-bottom-right-radius: 10px;
90 | }
91 |
92 | .ui-jqchart-toolbar.ui-widget.ui-widget-content.ui-corner-all {
93 | position: absolute;
94 | right: 100px !important;
95 | left: auto !important;
96 | }
--------------------------------------------------------------------------------
/trade/static/css/jqRangeSlider.css:
--------------------------------------------------------------------------------
1 | .ui-jqrangeslider { position: relative; }
2 |
3 | .ui-jqrangeslider .ui-jqrangeslider-arrow-left { position: absolute; width: 18px; cursor: pointer; vertical-align: middle; }
4 | .ui-jqrangeslider .ui-jqrangeslider-arrow-icon-left { position: absolute; }
5 | .ui-jqrangeslider .ui-jqrangeslider-arrow-right { position: absolute; width: 18px; cursor: pointer; }
6 | .ui-jqrangeslider .ui-jqrangeslider-arrow-icon-right { position: absolute; }
7 | .ui-jqrangeslider .ui-jqrangeslider-handle-left { position: absolute; width: 12px; cursor: ew-resize; }
8 | .ui-jqrangeslider .ui-jqrangeslider-handle-icon-left { position: absolute; }
9 | .ui-jqrangeslider .ui-jqrangeslider-handle-right { position: absolute; width: 12px; cursor: ew-resize; }
10 | .ui-jqrangeslider .ui-jqrangeslider-handle-icon-right { position: absolute; }
11 | .ui-jqrangeslider .ui-jqrangeslider-slider-horizontal { position: absolute; cursor: move; cursor: grab; cursor: -moz-grab; }
12 | .ui-jqrangeslider .ui-jqrangeslider-slider-horizontal-dragging { cursor: -moz-grabbing; cursor: grabbing; }
13 | .ui-jqrangeslider .ui-jqrangeslider-background-horizontal { position: absolute; }
14 | .ui-jqrangeslider .ui-jqrangeslider-background-horizontal-left { position: absolute; }
15 | .ui-jqrangeslider .ui-jqrangeslider-background-horizontal-right { position: absolute; }
16 |
17 | .ui-jqrangeslider .ui-jqrangeslider-arrow-bottom { position: absolute; height: 18px; cursor: pointer; }
18 | .ui-jqrangeslider .ui-jqrangeslider-arrow-icon-bottom { position: absolute; }
19 | .ui-jqrangeslider .ui-jqrangeslider-arrow-top { position: absolute; height: 18px; cursor: pointer; }
20 | .ui-jqrangeslider .ui-jqrangeslider-arrow-icon-top { position: absolute; }
21 | .ui-jqrangeslider .ui-jqrangeslider-handle-bottom { position: absolute; height: 12px; cursor: ns-resize; }
22 | .ui-jqrangeslider .ui-jqrangeslider-handle-icon-bottom { position: absolute; }
23 | .ui-jqrangeslider .ui-jqrangeslider-handle-top { position: absolute; height: 12px; cursor: ns-resize; }
24 | .ui-jqrangeslider .ui-jqrangeslider-handle-icon-top { position: absolute; }
25 | .ui-jqrangeslider .ui-jqrangeslider-slider-vertical { position: absolute; cursor: move; cursor: grab; cursor: -moz-grab; }
26 | .ui-jqrangeslider .ui-jqrangeslider-slider-vertical-dragging { cursor: -moz-grabbing; cursor: grabbing; }
27 | .ui-jqrangeslider .ui-jqrangeslider-background-vertical { position: absolute; }
28 | .ui-jqrangeslider .ui-jqrangeslider-background-vertical-bottom { position: absolute; }
29 | .ui-jqrangeslider .ui-jqrangeslider-background-vertical-top { position: absolute; }
--------------------------------------------------------------------------------
/trade/templates/account/email.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 |
3 | {% load i18n %}
4 |
5 | {% block head_title %}{% trans "Account" %}{% endblock %}
6 |
7 | {% block content %}
8 |
9 |
10 |
{% trans "E-mail Addresses" %}
11 | {% if user.emailaddress_set.all %}
12 |
{% trans 'The following e-mail addresses are associated with your account:' %}
13 |
14 |
43 |
44 | {% else %}
45 |
{% trans 'Warning:'%} {% trans "You currently do not have any e-mail address set up. You should really add an e-mail address so you can receive notifications, reset your password, etc." %}
46 |
47 | {% endif %}
48 |
49 |
50 |
{% trans "Add E-mail Address" %}
51 |
52 |
57 |
58 |
59 | {% endblock %}
60 |
61 |
62 | {% block extra_body %}
63 |
76 | {% endblock %}
77 |
--------------------------------------------------------------------------------
/trade/templates/account/login.html:
--------------------------------------------------------------------------------
1 | {% extends "account/base.html" %}
2 | {% load i18n %}
3 | {% load account socialaccount %}
4 | {% block head_title %}{% trans "Sign In" %}{% endblock %}
5 | {% block content %}
6 |
7 |
8 |
{% trans "Sign In" %}
9 | {% get_providers as socialaccount_providers %}
10 | {% if socialaccount_providers %}
11 |
{% blocktrans with site.name as site_name %}Please sign in with one
12 | of your existing third party accounts. Or, sign up
13 | for a {{ site_name }} account and sign in below:{% endblocktrans %}
14 |
15 |
16 | {% include "socialaccount/snippets/provider_list.html" with process="login" %}
17 |
18 |
{% trans 'or' %}
19 |
20 | {% include "socialaccount/snippets/login_extra.html" %}
21 | {% endif %}
22 |
23 |
57 |
58 |
59 | {% endblock %}
60 |
--------------------------------------------------------------------------------
/ticker_app/views.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 | from django.core.serializers.json import DjangoJSONEncoder
3 | from django.http import HttpResponse
4 | from .models import ExchangeTicker
5 | from django.utils import timezone
6 | import datetime
7 | from tradeBOT.models import Extremum
8 | import json
9 |
10 |
11 | def get_ticker(request):
12 | if request.is_ajax():
13 | pair_id = request.POST.get('pair_id')
14 | intervale = int(request.POST.get('intervale'))
15 | zoom = request.POST.get('zoom')
16 | chart_data = {}
17 | ticker_list = []
18 | extremums_list = []
19 | intervales = []
20 | if zoom == 'all':
21 | ticker = list(ExchangeTicker.objects.values('date_time', 'last').filter(pair_id=pair_id))
22 | else:
23 | ticker = list(ExchangeTicker.objects.values('date_time', 'last').filter(pair_id=pair_id,
24 | date_time__gte=timezone.now() - datetime.timedelta(
25 | hours=int(zoom))))
26 | if len(ticker) > 0:
27 | extremums = Extremum.objects.filter(pair_id=pair_id,
28 | date__gte=ticker[0]['date_time'])
29 | for item in extremums:
30 | extremums_list.append([item.date, item.price, item.ext_type])
31 | s_date = ticker[0]['date_time']
32 | while s_date < timezone.now():
33 | intervales.append(s_date)
34 | s_date = s_date + datetime.timedelta(minutes=intervale)
35 | if len(intervales) > 0:
36 | s_date = intervales.pop(0)
37 | # print('От {} до {}'.format(s_date, s_date + datetime.timedelta(minutes=intervale)))
38 | s_chain = [x for x in ticker if
39 | s_date + datetime.timedelta(minutes=intervale) > x['date_time'] >= s_date]
40 | while len(intervales) > 0:
41 | try:
42 | ticker_list.append({'date': s_date,
43 | 'open': s_chain[0]['last'],
44 | 'close': s_chain[-1]['last'],
45 | 'low': min([x['last'] for x in s_chain]),
46 | 'high': max([x['last'] for x in s_chain])})
47 | except IndexError:
48 | pass
49 | s_date = intervales.pop(0)
50 | # print('Новая от {} до {}'.format(s_date, s_date + datetime.timedelta(minutes=intervale)))
51 | s_chain = [x for x in ticker if
52 | s_date + datetime.timedelta(minutes=intervale) > x['date_time'] >= s_date]
53 | # print("Выборка {}".format(s_chain))
54 | chart_data['ticker'] = ticker_list
55 | chart_data['extremums'] = extremums_list
56 | return HttpResponse(json.dumps(chart_data, cls=DjangoJSONEncoder), status=200)
57 |
--------------------------------------------------------------------------------
/tradeBOT/admin.py:
--------------------------------------------------------------------------------
1 | from django.contrib import admin
2 | from tradeBOT import models
3 |
4 |
5 | class CalculationsAdmin(admin.ModelAdmin):
6 | list_display = ['user_pair', 'type', 'depth_coef', 'price', 'amount', 'date_created']
7 |
8 | class Meta:
9 | model = models.Сalculations
10 |
11 |
12 | class UserOrderAdmin(admin.ModelAdmin):
13 | list_display = [field.name for field in models.UserOrder._meta.fields]
14 | list_filter = ['ue__exchange__name', 'order_type', 'ue__user__username']
15 |
16 | class Meta:
17 | model = models.UserOrder
18 |
19 |
20 | class UserPairInline(admin.TabularInline):
21 | model = models.UserPair
22 |
23 |
24 | class ExchangeCoinAdmin(admin.ModelAdmin):
25 | search_fields = ['symbol', 'name']
26 | list_filter = ['exchange']
27 |
28 | class Meta:
29 | model = models.ExchangeCoin
30 |
31 |
32 | class UserPairAdmin(admin.ModelAdmin):
33 | list_display = [field.name for field in models.UserPair._meta.fields]
34 | list_filter = ['user', 'pair__main_coin__exchange__name']
35 |
36 | class Meta:
37 | model = models.UserPair
38 |
39 |
40 | class CoinMarketCupCoinAdmin(admin.ModelAdmin):
41 | search_fields = ['name', 'symbol']
42 |
43 | def get_ordering(self, request):
44 | return ['rank']
45 |
46 | class Meta:
47 | model = models.CoinMarketCupCoin
48 |
49 |
50 | class PairAdmin(admin.ModelAdmin):
51 | search_fields = ['main_coin', 'second_coin']
52 | list_filter = ['main_coin__exchange__name']
53 | inlines = [UserPairInline]
54 |
55 |
56 | # class ExchangeTickerAdmin(admin.ModelAdmin):
57 | # list_display = [field.name for field in models.ExchangeTicker._meta.fields]
58 | # list_filter = ['exchange', 'pair']
59 | #
60 | # class Meta:
61 | # model = models.ExchangeTicker
62 |
63 |
64 | class OrderAdmin(admin.ModelAdmin):
65 | list_display = [field.name for field in models.Order._meta.fields]
66 | list_filter = ['pair', 'ue']
67 | search_fields = ['orderNumber']
68 |
69 | class Meta:
70 | model = models.Order
71 |
72 |
73 | class ToTradeAdmin(admin.ModelAdmin):
74 | list_display = [field.name for field in models.ToTrade._meta.fields]
75 | list_filter = ['user_pair__user_exchange', 'type', 'user_pair__pair']
76 |
77 | class Meta:
78 | model = models.ToTrade
79 |
80 |
81 | class ExtremumAdmin(admin.ModelAdmin):
82 | list_display = [field.name for field in models.Extremum._meta.fields]
83 |
84 | class Meta:
85 | model = models.Extremum
86 |
87 | admin.site.register(models.ExchangeCoin, ExchangeCoinAdmin)
88 | admin.site.register(models.UserPair, UserPairAdmin)
89 | admin.site.register(models.Pair, PairAdmin)
90 | admin.site.register(models.ExchangeMainCoin)
91 | admin.site.register(models.CoinMarketCupCoin, CoinMarketCupCoinAdmin)
92 | admin.site.register(models.UserMainCoinPriority)
93 | # admin.site.register(models.ExchangeTicker, ExchangeTickerAdmin)
94 | admin.site.register(models.Order, OrderAdmin)
95 | admin.site.register(models.ToTrade, ToTradeAdmin)
96 | admin.site.register(models.UserOrder, UserOrderAdmin)
97 | admin.site.register(models.UserCoinShare)
98 | admin.site.register(models.Сalculations, CalculationsAdmin)
99 | admin.site.register(models.Extremum, ExtremumAdmin)
100 |
--------------------------------------------------------------------------------
/tradeBOT/templates/tradeBOT/get_primary_pairs.html:
--------------------------------------------------------------------------------
1 | {% load tradeBot_filters get_coin_info %}
2 | {% if pairs %}
3 |
8 | {% for pair in pairs %}
9 |
10 |
55 |
60 |
61 | {% endfor %}
62 | {% endif %}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Linux template
3 | *~
4 |
5 | # temporary files which can be created if a process still has a handle open of a deleted file
6 | .fuse_hidden*
7 |
8 | # KDE directory preferences
9 | .directory
10 |
11 | # Linux trash folder which might appear on any partition or disk
12 | .Trash-*
13 |
14 | # .nfs files are created when an open file is removed but is still being accessed
15 | .nfs*
16 | ### Python template
17 | # Byte-compiled / optimized / DLL files
18 | __pycache__/
19 | *.py[cod]
20 | *$py.class
21 |
22 | # C extensions
23 | *.so
24 |
25 | # Distribution / packaging
26 | .Python
27 | build/
28 | develop-eggs/
29 | dist/
30 | downloads/
31 | eggs/
32 | .eggs/
33 | lib/
34 | lib64/
35 | parts/
36 | sdist/
37 | var/
38 | wheels/
39 | *.egg-info/
40 | .installed.cfg
41 | *.egg
42 | MANIFEST
43 |
44 | # PyInstaller
45 | # Usually these files are written by a python script from a template
46 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
47 | *.manifest
48 | *.spec
49 |
50 | # Installer logs
51 | pip-log.txt
52 | pip-delete-this-directory.txt
53 |
54 | # Unit test / coverage reports
55 | htmlcov/
56 | .tox/
57 | .coverage
58 | .coverage.*
59 | .cache
60 | nosetests.xml
61 | coverage.xml
62 | *.cover
63 | .hypothesis/
64 |
65 | # Translations
66 | *.mo
67 | *.pot
68 |
69 | # Django stuff:
70 | *.log
71 | .static_storage/
72 | .media/
73 | local_settings.py
74 |
75 | # Flask stuff:
76 | instance/
77 | .webassets-cache
78 |
79 | # Scrapy stuff:
80 | .scrapy
81 |
82 | # Sphinx documentation
83 | docs/_build/
84 |
85 | # PyBuilder
86 | target/
87 |
88 | # Jupyter Notebook
89 | .ipynb_checkpoints
90 |
91 | # pyenv
92 | .python-version
93 |
94 | # celery beat schedule file
95 | celerybeat-schedule
96 |
97 | # SageMath parsed files
98 | *.sage.py
99 |
100 | # Environments
101 | .env
102 | .venv
103 | env/
104 | venv/
105 | ENV/
106 | env.bak/
107 | venv.bak/
108 |
109 | # Spyder project settings
110 | .spyderproject
111 | .spyproject
112 |
113 | # Rope project settings
114 | .ropeproject
115 |
116 | # mkdocs documentation
117 | /site
118 |
119 | # mypy
120 | .mypy_cache/
121 | ### JetBrains template
122 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
123 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
124 |
125 | # User-specific stuff:
126 | .idea/**/workspace.xml
127 | .idea/**/tasks.xml
128 | .idea/dictionaries
129 |
130 | # Sensitive or high-churn files:
131 | .idea/**/dataSources/
132 | .idea/**/dataSources.ids
133 | .idea/**/dataSources.xml
134 | .idea/**/dataSources.local.xml
135 | .idea/**/sqlDataSources.xml
136 | .idea/**/dynamic.xml
137 | .idea/**/uiDesigner.xml
138 |
139 | # Gradle:
140 | .idea/**/gradle.xml
141 | .idea/**/libraries
142 |
143 | # CMake
144 | cmake-build-debug/
145 |
146 | # Mongo Explorer plugin:
147 | .idea/**/mongoSettings.xml
148 |
149 | ## File-based project format:
150 | *.iws
151 |
152 | ## Plugin-specific files:
153 |
154 | # IntelliJ
155 | out/
156 |
157 | # mpeltonen/sbt-idea plugin
158 | .idea_modules/
159 |
160 | # JIRA plugin
161 | atlassian-ide-plugin.xml
162 |
163 | # Cursive Clojure plugin
164 | .idea/replstate.xml
165 |
166 | # Crashlytics plugin (for Android Studio and IntelliJ)
167 | com_crashlytics_export_strings.xml
168 | crashlytics.properties
169 | crashlytics-build.properties
170 | fabric.properties
171 |
172 | .idea/
173 | /logs/
174 |
--------------------------------------------------------------------------------
/djangoTrade/urls.py:
--------------------------------------------------------------------------------
1 | """djangoTrade URL Configuration
2 |
3 | The `urlpatterns` list routes URLs to views. For more information please see:
4 | https://docs.djangoproject.com/en/1.11/topics/http/urls/
5 | Examples:
6 | Function views
7 | 1. Add an import: from my_app import views
8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
9 | Class-based views
10 | 1. Add an import: from other_app.views import Home
11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
12 | Including another URLconf
13 | 1. Import the include() function: from django.conf.urls import url, include
14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
15 | """
16 | from django.conf import settings
17 | from django.conf.urls import url, include
18 | from django.conf.urls.static import static
19 | from django.contrib import admin
20 | from trade import views as tradeViews
21 | from tradeBOT import views as tradeBOTViews
22 | from ticker_app import views as tickerViews
23 | from allauth import urls as allauth_urls
24 | from user_profile import views as user_profile_views
25 | from django.contrib.auth.decorators import permission_required
26 |
27 | urlpatterns = [
28 | url(r'^admin/', admin.site.urls),
29 | url(r'^accounts/', include(allauth_urls)),
30 | url(r'^profile/$', user_profile_views.profile, name='user_profile'),
31 | url(r'^change_status/$', permission_required('is_superuser')(tradeViews.change_status),
32 | name='change_status'),
33 | url(r'^$', tradeViews.index, name='index'),
34 | url(r'^exchange/$', permission_required('is_superuser')(tradeViews.exchange), name='exchange'),
35 | url(r'^wallet/$', permission_required('is_superuser')(tradeViews.wallet), name='wallet'),
36 | url(r'^api/$', tradeViews.get_holding, name='get_holding'),
37 | url(r'^transaction/new_comment/$',
38 | permission_required('is_superuser')(tradeViews.add_new_transaction_comment), name='new_comment'),
39 | url(r'^trade/setup/(?P[0-9]+)/$', tradeBOTViews.setup, name='tradeBotSetup'),
40 | url(r'^trade/addusercoin/$', tradeBOTViews.add_user_pair, name='add_user_pair'),
41 | url(r'^trade/changerank/$', tradeBOTViews.change_rank, name='changerank'),
42 | url(r'^trade/set_share/$', tradeBOTViews.set_share, name='set_share'),
43 | url(r'^trade/set_pair_add/$', tradeBOTViews.set_pair_add, name='set_pair_add'),
44 | url(r'^trade/delete_user_pair/$', tradeBOTViews.delete_user_pair, name='delete_user_pair'),
45 | url(r'^trade/change_primary_coin/$', tradeBOTViews.change_primary_coin, name='change_primary_coin'),
46 | url(r'^trade/change_primary_coin_rank/$', tradeBOTViews.change_primary_coin_rank,
47 | name='change_primary_coin_rank'),
48 | url(r'^trade/relations/$', tradeBOTViews.relations, name='relations'),
49 | url(r'^trade/exchange_script_activity/$', tradeBOTViews.change_user_exchange_script_activity,
50 | name='change_user_exchange_script_activity'),
51 | url(r'^trade/exchange_depth_to_trade/$', tradeBOTViews.exchange_depth_to_trade,
52 | name='exchange_depth_to_trade'),
53 | url(r'^trade/get_ticker/$', tickerViews.get_ticker, name='get_ticker'),
54 | url(r'^trade/get_new_orders_to_trade/$', tradeBOTViews.get_new_to_trade, name='get_new_to_trade'),
55 | ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
56 |
--------------------------------------------------------------------------------
/trade/templates/trade/transactions.html:
--------------------------------------------------------------------------------
1 | {% load value_to_cryptotoken %}
2 | {% if transactions %}
3 | {% if item.wallet.name != 'Yandex Money' %}
4 |
5 |
6 |
7 | Block Number
8 | From
9 | To
10 | Date
11 | Type
12 | Value
13 | Hash
14 |
15 |
16 |
17 | {% for transaction in transactions %}
18 |
19 | {{ transaction.number }}
20 | {% if transaction.t_from == item.address %}This Wallet {% else %}
21 | {{ transaction.t_from | safe }}{% endif %}
22 | {% if transaction.t_to == item.address %}This Wallet {% else %}
23 | {{ transaction.t_to | safe }}{% endif %}
24 | {{ transaction.date }}
25 |
26 | {% if transaction.type == 'in' %}
27 | {{ transaction.type }}
28 | {% elif transaction.type == 'out' %}
29 | {{ transaction.type }}
30 | {% endif %}
31 |
32 | {{ transaction.value | value_to_cryptotoken:item }}
33 | {{ transaction.hash }}
34 |
35 | {% endfor %}
36 |
37 |
38 | {% else %}
39 |
40 |
41 |
42 | Operation ID
43 | Date
44 | Type
45 | Amount
46 | Details
47 | Title
48 | Comment
49 |
50 |
51 |
52 | {% for transaction in transactions %}
53 |
54 | {{ transaction.number }}
55 | {{ transaction.date }}
56 |
57 | {% if transaction.type == 'in' %}
58 | {{ transaction.type }}
59 | {% elif transaction.type == 'out' %}
60 | {{ transaction.type }}
61 | {% endif %}
62 |
63 | {{ transaction.value | value_to_cryptotoken:item }}
64 | {{ transaction.details }}
65 | {{ transaction.title }}
66 | {{ transaction.comment }}
67 |
68 | {% endfor %}
69 |
70 |
71 | {% endif %}
72 | {% else %}
73 |
74 |
75 |
76 | Block Number
77 | From
78 | To
79 | Date
80 | Type
81 | Value
82 | BlockHash
83 | Hash
84 |
85 |
86 |
87 |
88 | История транзакций отсутствует
89 |
90 |
91 |
92 | {% endif %}
93 |
--------------------------------------------------------------------------------
/user_profile/templates/user_profile/profile.html:
--------------------------------------------------------------------------------
1 | {% extends 'trade/base.html' %}
2 | {% block content %}
3 | Мой профиль
4 |
5 |
6 |
7 |
Complete your user profile to increase your limits.
8 |
30 |
31 |
32 |
33 |
34 | Биржа
35 | Ключ
36 | Включена
37 | Корректна
38 |
39 |
40 |
41 | {% for item in user_exchanges %}
42 |
43 | {{ item.exchange.exchange }}
44 | {{ item.apikey | truncatechars:20 }}
45 |
46 | {% if item.is_active == True %}
47 |
49 | {% else %}
50 |
52 |
53 | {% endif %}
54 |
55 |
56 | {% if item.is_correct == True %}
57 |
59 | {% else %}
60 |
62 |
63 | {% endif %}
64 |
65 |
66 | {% endfor %}
67 |
68 |
69 |
Всего бирж: {{ user_exchanges | length }}
70 |
Из них активных: {{ user_active_exchanges | length }}
71 |
72 |
73 |
74 |
75 |
76 |
77 | {% endblock %}
--------------------------------------------------------------------------------
/tradeBOT/templatetags/tradeBot_filters.py:
--------------------------------------------------------------------------------
1 | from django import template
2 |
3 | from ticker_app.models import ExchangeTicker
4 | from tradeBOT.models import CoinMarketCupCoin, UserMainCoinPriority, Pair, ExchangeMainCoin, UserPair
5 | from trade.models import UserBalance
6 |
7 | register = template.Library()
8 |
9 |
10 | @register.filter(name='user_have_coin')
11 | def user_holdings(coin_symbol, user_exchange):
12 | try:
13 | user_hold = UserBalance.objects.get(ue_id=user_exchange, coin=coin_symbol)
14 | return user_hold.total
15 | except UserBalance.DoesNotExist:
16 | return 0
17 |
18 |
19 | @register.filter(name='get_coinmarket_id')
20 | def get_coinmarket_id(symbol):
21 | try:
22 | coin_market_id = CoinMarketCupCoin.objects.filter(symbol=symbol).earliest('rank')
23 | return coin_market_id.coin_market_id
24 | except CoinMarketCupCoin.DoesNotExist:
25 | return ''
26 |
27 |
28 | @register.inclusion_tag('tradeBOT/user_primary.html')
29 | def get_user_primary_coins(user_exchange, primary_coin):
30 | try:
31 | umcp = UserMainCoinPriority.objects.get(user_exchange=user_exchange, main_coin=primary_coin)
32 | return {'coin': umcp,
33 | 'success': True}
34 | except UserMainCoinPriority.DoesNotExist:
35 | return {'success': False}
36 |
37 |
38 | @register.inclusion_tag('tradeBOT/get_primary_pairs.html')
39 | def get_primary_pairs(coin, user_exchange):
40 | try:
41 | pairs = Pair.objects.filter(main_coin=coin, second_coin__rank__lte=100).order_by('is_active',
42 | 'second_coin__symbol')
43 | return {'pairs': pairs, 'user_exchange': user_exchange}
44 | except Pair.DoesNotExist:
45 | return None
46 |
47 |
48 | @register.filter(name='get_last')
49 | def get_last(pair, user_exchange):
50 | # return 0
51 | max_pk = ExchangeTicker.objects.filter(exchange_id=user_exchange.exchange.pk, pair_id=pair.pk).order_by(
52 | '-id').first().pk
53 | ticker = ExchangeTicker.objects.get(pk=max_pk).last
54 | if ticker is not None:
55 | return round(ticker, 8)
56 | else:
57 | return 0
58 |
59 |
60 | @register.filter(name='get_change_percent')
61 | def get_change_percent(pair, user_exchange):
62 | # return 0
63 | max_pk = ExchangeTicker.objects.filter(exchange_id=user_exchange.exchange.pk, pair_id=pair.pk).order_by(
64 | '-id').first().pk
65 | ticker = ExchangeTicker.objects.get(pk=max_pk).percent_change
66 | if ticker is not None:
67 | return round(ticker * 100, 2)
68 | else:
69 | return 0
70 |
71 |
72 | @register.filter(name='is_pair_active')
73 | def is_pair_active(user_pair, user_exchange_pk):
74 | main_coin = user_pair.pair.main_coin
75 | try:
76 | exch_primary = ExchangeMainCoin.objects.get(coin=main_coin)
77 | user_primary_coin = UserMainCoinPriority.objects.get(user_exchange_id=user_exchange_pk, main_coin=exch_primary)
78 | return user_primary_coin.is_active
79 | except ExchangeMainCoin.DoesNotExist:
80 | return False
81 | except UserMainCoinPriority.DoesNotExist:
82 | return True
83 |
84 |
85 | @register.filter(name='user_pair_rate_of_change')
86 | def user_pair_rate_of_change(user_pair_pk):
87 | try:
88 | user_pair = UserPair.objects.get(pk=user_pair_pk)
89 | return user_pair.rate_of_change
90 | except UserPair.DoesNotExist:
91 | return float(0)
92 |
93 |
94 | @register.filter(name='user_pair_interval_change')
95 | def user_pair_interval_change(user_pair_pk):
96 | try:
97 | user_pair = UserPair.objects.get(pk=user_pair_pk)
98 | return user_pair.change_interval
99 | except UserPair.DoesNotExist:
100 | return 0
101 |
102 |
103 | @register.filter(name='multiple')
104 | def multiple(value, factor):
105 | return value * factor
106 |
107 |
108 | @register.filter(name='haven_percent')
109 | def haven_percent(coin, ue):
110 | try:
111 | user_balance = UserBalance.objects.get(ue=ue, coin=coin.symbol.lower())
112 | coin_total_btc = user_balance.btc_value
113 | except UserBalance.DoesNotExist:
114 | coin_total_btc = 0
115 | return coin_total_btc / (ue.total_btc / 100)
116 |
--------------------------------------------------------------------------------
/trade/views.py:
--------------------------------------------------------------------------------
1 | import json
2 |
3 | import requests
4 | import re
5 | import djangoTrade.settings as settings
6 | from django.core import serializers
7 | from django.core.exceptions import ObjectDoesNotExist
8 | from django.http import HttpResponse
9 | from django.shortcuts import render, redirect
10 | from django.contrib.auth.decorators import login_required
11 | from trade.forms import UserExchangesForm, UserWalletForm
12 | from trade.models import UserExchange, Exchanges, UserBalance, UserWallet, Wallets, Transaction, UserHoldings
13 | from yandex_money.api import Wallet, ExternalPayment
14 | from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
15 | from django.core.serializers.json import DjangoJSONEncoder
16 |
17 |
18 | @login_required
19 | def index(request):
20 | transaction = Transaction.objects.all().order_by('-date')
21 | if len(transaction) > 0:
22 | paginator = Paginator(transaction, 100)
23 | page = request.GET.get('page')
24 | try:
25 | transactions = paginator.page(page)
26 | except PageNotAnInteger:
27 | transactions = paginator.page(1)
28 | except EmptyPage:
29 | transactions = paginator.page(paginator.num_pages)
30 | else:
31 | transactions = None
32 | args = {'exchange_form': UserExchangesForm(),
33 | 'wallet_form': UserWalletForm(),
34 | 'ue': UserExchange.objects.all(),
35 | 'uw': UserWallet.objects.all(),
36 | 'trans': transactions}
37 | return render(request, 'trade/home.html', args)
38 |
39 |
40 | def change_status(request):
41 | try:
42 | ue = UserExchange.objects.get(pk=request.POST['ue'])
43 | except ObjectDoesNotExist:
44 | return HttpResponse('none', status=200)
45 | ue.is_active = not ue.is_active
46 | ue.save()
47 | return HttpResponse('ok', status=200)
48 |
49 |
50 | @login_required
51 | def exchange(request):
52 | if request.method == 'POST':
53 | ue = UserExchange()
54 | ue.user = request.user
55 | ue.exchange = Exchanges.objects.get(pk=request.POST.get('exchange'))
56 | ue.apikey = request.POST.get('apikey')
57 | ue.apisecret = request.POST.get('apisecret')
58 | ue.total_btc = float(0)
59 | ue.save()
60 | return redirect(index)
61 |
62 |
63 | @login_required
64 | def wallet(request):
65 | if request.method == 'POST':
66 | wallet = Wallets.objects.get(pk=request.POST.get('wallet'))
67 | if wallet.name == 'Yandex Money':
68 | if not settings.YANDEX_MONEY_CLIENT_ID or not settings.YANDEX_MONEY_REDIRECT_URI or not \
69 | settings.YANDEX_MONEY_CLIENT_SECRET:
70 | return HttpResponse('You must define yandex money settings', status=404)
71 | scope = ['account-info', 'operation-history', 'operation-details']
72 | auth_url = Wallet.build_obtain_token_url(
73 | client_id=settings.YANDEX_MONEY_CLIENT_ID,
74 | redirect_uri=settings.YANDEX_MONEY_REDIRECT_URI,
75 | scope=scope) + '&response_type=code'
76 | return redirect(auth_url)
77 | else:
78 | uw = UserWallet()
79 | uw.user = request.user
80 | uw.address = request.POST.get('address')
81 | uw.wallet = wallet
82 | uw.save()
83 | elif request.method == 'GET':
84 | if not settings.YANDEX_MONEY_CLIENT_ID or not settings.YANDEX_MONEY_REDIRECT_URI or not \
85 | settings.YANDEX_MONEY_CLIENT_SECRET:
86 | return HttpResponse('You must define yandex money settings', status=404)
87 | access_token = Wallet.get_access_token(
88 | client_id=settings.YANDEX_MONEY_CLIENT_ID,
89 | redirect_uri=settings.YANDEX_MONEY_REDIRECT_URI,
90 | code=request.GET.get('code'),
91 | client_secret=settings.YANDEX_MONEY_CLIENT_SECRET
92 | )
93 | access_token = access_token['access_token']
94 | wallet = Wallet(access_token)
95 | account_info = wallet.account_info()
96 | uw = UserWallet()
97 | uw.wallet = Wallets.objects.get(name='Yandex Money')
98 | uw.access_token = access_token
99 | uw.user = request.user
100 | uw.address = account_info['account']
101 | uw.balance = account_info['balance']
102 | uw.save()
103 | return redirect(index)
104 |
105 |
106 | @login_required
107 | def get_holding(request):
108 | type_r = request.GET.get('type')
109 | if request.is_ajax():
110 | if type_r == 'names':
111 | names = []
112 | user_hold_names = UserHoldings.objects.values('type').distinct()
113 | if len(user_hold_names) > 0:
114 | for name in user_hold_names:
115 | names.append(name['type'])
116 | return HttpResponse(json.dumps(names), status=200)
117 | else:
118 | return HttpResponse('none', status=200)
119 | else:
120 | holdings = UserHoldings.objects.filter(type=type_r).order_by('date_time')
121 | list_hold = [obj.as_list() for obj in holdings]
122 | return HttpResponse(json.dumps(list_hold, cls=DjangoJSONEncoder), status=200)
123 |
124 |
125 | def add_new_transaction_comment(request):
126 | if request.POST:
127 | tr_id = request.POST.get('tr_id')
128 | comment = request.POST.get('comment')
129 | try:
130 | trans = Transaction.objects.get(pk=tr_id)
131 | trans.user_comment = comment
132 | trans.save()
133 | except Transaction.DoesNotExist:
134 | return HttpResponse('none', status=200)
135 | return HttpResponse('ok', status=200)
136 |
--------------------------------------------------------------------------------
/trade/models.py:
--------------------------------------------------------------------------------
1 | import datetime
2 |
3 | from decimal import Decimal
4 | from django.contrib.auth.models import User
5 | from django.db import models
6 | from pytz import utc
7 | import time
8 |
9 |
10 | class Exchanges(models.Model):
11 | name = models.CharField(max_length=255)
12 | info_frozen_key = models.CharField(max_length=31)
13 |
14 | def __str__(self):
15 | return self.name
16 |
17 | class Meta:
18 | verbose_name = "Биржа"
19 | verbose_name_plural = "Биржи"
20 |
21 |
22 | class UserExchange(models.Model):
23 | user = models.ForeignKey(User)
24 | exchange = models.ForeignKey(Exchanges)
25 | apikey = models.CharField(max_length=127)
26 | apisecret = models.CharField(max_length=255)
27 | is_active = models.BooleanField(default=False)
28 | is_active_script = models.BooleanField(default=False)
29 | is_correct = models.BooleanField(default=True)
30 | total_btc = models.DecimalField(max_digits=30, decimal_places=8)
31 | total_usd = models.DecimalField(max_digits=30, decimal_places=8, default=0)
32 | coefficient_of_depth = models.IntegerField(default=0)
33 | error = models.CharField(max_length=255, blank=True)
34 |
35 | def __str__(self):
36 | return self.user.username + ': ' + self.exchange.name + ' (' + str(self.pk) + ')'
37 |
38 | class Meta:
39 | verbose_name = "Биржа пользователя"
40 | verbose_name_plural = "Биржи пользователей"
41 |
42 |
43 | class UserBalance(models.Model):
44 | ue = models.ForeignKey(UserExchange)
45 | coin = models.CharField(max_length=10)
46 | total = models.DecimalField(max_digits=30, decimal_places=8, default=0)
47 | used = models.DecimalField(max_digits=30, decimal_places=8, default=0)
48 | free = models.DecimalField(max_digits=30, decimal_places=8, default=0)
49 | conversions = models.CharField(max_length=255)
50 | btc_value = models.DecimalField(max_digits=30, decimal_places=8, default=0)
51 | last_update = models.DateTimeField(auto_now=True)
52 |
53 | def __str__(self):
54 | return self.ue.exchange.name + ' ' + self.ue.user.username + ' ' + self.coin + ': ' + str(self.total)
55 |
56 | class Meta:
57 | verbose_name = "Баланс пользователя"
58 | verbose_name_plural = "Балансы пользователей"
59 |
60 |
61 | class Coin(models.Model):
62 | short_name = models.CharField(max_length=20)
63 | full_name = models.CharField(max_length=40)
64 |
65 | def __str__(self):
66 | return self.short_name + '-' + self.full_name
67 |
68 | class Meta:
69 | verbose_name = 'Криптовалюта'
70 | verbose_name_plural = 'Криптовалюты'
71 |
72 |
73 | class Wallets(models.Model):
74 | name = models.CharField(max_length=255)
75 |
76 | def __str__(self):
77 | return self.name
78 |
79 | class Meta:
80 | verbose_name = 'Кошелёк'
81 | verbose_name_plural = "Кошельки"
82 |
83 |
84 | class UserWallet(models.Model):
85 | user = models.ForeignKey(User)
86 | wallet = models.ForeignKey(Wallets)
87 | address = models.CharField(max_length=511)
88 | access_token = models.CharField(max_length=511, blank=True, default=None, null=True)
89 | balance = models.DecimalField(max_digits=30, decimal_places=8, default=0)
90 | total_btc = models.DecimalField(max_digits=30, decimal_places=8, default=0)
91 | total_usd = models.DecimalField(max_digits=30, decimal_places=8, default=0)
92 | last_update = models.DateTimeField(auto_now=True)
93 |
94 | def __str__(self):
95 | return '<' + self.user.username + ' ' + self.wallet.name + ': ' + str(self.balance) + '>'
96 |
97 | class Meta:
98 | verbose_name = 'Кошелёк пользователя'
99 | verbose_name_plural = 'Кошельки пользователей'
100 |
101 |
102 | class Transaction(models.Model):
103 | name = models.CharField(max_length=50)
104 | t_type = models.CharField(max_length=20)
105 | number = models.BigIntegerField(blank=False, null=False)
106 | date = models.DateTimeField(blank=False)
107 | t_from = models.TextField()
108 | t_to = models.TextField()
109 | type = models.CharField(max_length=10)
110 | value = models.DecimalField(max_digits=30, decimal_places=8, default=0)
111 | block_hash = models.CharField(max_length=127, default=None, null=True)
112 | hash = models.CharField(max_length=127)
113 | comment = models.TextField(default='', null=True)
114 | title = models.CharField(max_length=255, default='', null=True)
115 | details = models.CharField(max_length=255, default='', null=True)
116 | usd_value = models.DecimalField(max_digits=30, decimal_places=8, default=0)
117 | user_comment = models.CharField(max_length=255, blank=True, default=None, null=True)
118 | currency = models.CharField(max_length=10, blank=True, default=None, null=True)
119 |
120 | def __str__(self):
121 | return '<' + self.name + ' ' + self.type + ' ' + str(self.value) + '>'
122 |
123 | class Meta:
124 | verbose_name = 'Транзакциия'
125 | verbose_name_plural = 'Транзакции'
126 | unique_together = ('name', 't_type', 'hash')
127 |
128 |
129 | class UserHoldings(models.Model):
130 | user = models.ForeignKey(User)
131 | type = models.CharField(max_length=255)
132 | total_btc = models.DecimalField(max_digits=30, decimal_places=8, default=0)
133 | total_usd = models.DecimalField(max_digits=30, decimal_places=8, default=0)
134 | date_time = models.DateTimeField(blank=False)
135 |
136 | def __str__(self):
137 | return '<' + self.user.username + ' - ' + self.type + ': ' + str(self.total_btc) + '>'
138 |
139 | class Meta:
140 | verbose_name_plural = 'Истории балансов'
141 | verbose_name = 'История баланса'
142 |
143 | def as_list(self):
144 | return [
145 | int(time.mktime(self.date_time.timetuple()) * 1000),
146 | float(Decimal(self.total_btc).quantize(Decimal('.00000001')))
147 | ]
148 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://ongrid.pro/)
2 |
3 | 
4 | 
5 | 
6 |
7 |
8 | # CATEd - Cryptocurrency Analytics and Trading Engine for Django
9 |
10 | ## Overview
11 |
12 | [HabraHabr article in Russian](https://habrahabr.ru/users/proofx/posts/)
13 |
14 | CATEd is the cryptocurrency trading bot written on Python 3 with feature-rich management Web interface (Django, Celery).
15 |
16 | Main features:
17 | * View the status of exchange accounts, transactions and orders on them;
18 | * View the status of cold wallets and transactions details;
19 | * History of deposits and withdrawals on graphical diagram;
20 | * Configurable buy/sell/hold logic, (allowed tokens and proportions);
21 | * Keeping the balances of different tokens at the configured levels;
22 |
23 | 
24 |
25 | 
26 |
27 | ## Install
28 |
29 | You need python3, mysql-server, rabbitmq-server and redis-server to be installed.
30 |
31 | Create python virtual env and activate it in your favorite way.
32 |
33 | Clone project
34 | ```sh
35 | git clone git@github.com:OnGridSystems/CATEd.git
36 | ```
37 | Go to project dir
38 | ```sh
39 | cd CATEd
40 | ```
41 | Create mysql databases
42 | ```sh
43 | echo "create database trade character set utf8; create database celery_result; create database portal_ticker;" | mysql -u root
44 | ```
45 | And migrate
46 | ```sh
47 | python manage.py migrate
48 | ```
49 | Load initial data with some exchanges and wallets
50 | ```sh
51 | python manage.py loaddata dump.json
52 | ```
53 |
54 | Create you own superuser with
55 | ```sh
56 | python manage.py createsuperuser
57 | ```
58 | Before starting the bot should read the list of currencies from the site coinmarketcup.com. To do this run following code
59 | with activated virtual environment.
60 | ```sh
61 | read -d "" PYTASKS <<"EOF"
62 | from tradeBOT import tasks
63 | coinmarketcup = tasks.pull_coinmarketcup()
64 | EOF
65 | echo "$PYTASKS" | python manage.py shell
66 | ```
67 | And runserver
68 | ```sh
69 | python manage.py runserver
70 | ```
71 | Now you can add your api keys.
72 |
73 | **Add NEW api keys for use bot.**
74 |
75 | To do this open http://127.0.0.1:8000/ in your browser, login and click red "plus" button in the lower right corner.
76 |
77 | Bot uses several celery queues for trade, and main is triggered by a signal from a first worker named celery@worker_high.
78 | Another worker - worker_set_orders checks for already existing orders and try keeps them up to date.
79 | There are also queues low and normal, for calculating users' orders and pulling their balances.
80 |
81 | You can run celery in several terminal windows or screen sessions:
82 | ```sh
83 | celery worker -A djangoTrade -n worker_high -l info -c 1 -Q high
84 | celery worker -A djangoTrade -n worker_set_orders -l info -c 1 -Q set_orders
85 | celery worker -A djangoTrade -n worker_low -l info -c 2 -Q low
86 | celery worker -A djangoTrade -n worker_normal -l info -c 2 -Q normal
87 | ```
88 |
89 | Example of running celery with supervisor daemon:
90 |
91 | ```sh
92 | wget https://raw.githubusercontent.com/celery/celery/4.0/extra/generic-init.d/celeryd -O /etc/init.d/celeryd
93 | wget https://raw.githubusercontent.com/celery/celery/4.0/extra/generic-init.d/celerybeat -O /etc/init.d/celerybeat
94 | chmod +x /etc/init.d/celeryd /etc/init.d/celerybeat
95 |
96 | #add celery config
97 | read -d "" CELERYD_CFG <<"EOF"
98 | CELERYD_NODES="worker_set_orders worker_low worker_normal worker_high"
99 | CELERY_BIN="/opt/env/bin/python -m celery"
100 | CELERY_APP="djangoTrade"
101 | CELERYD_CHDIR="/opt/ongrid_portal"
102 | CELERYD_OPTS="-Q:worker_set_orders set_orders -Q:worker_low low -Q:worker_normal normal -Q:worker_high high -c:worker_set_orders 1 -c:worker_low 3 -c:worker_normal 3 -c:worker_high 1"
103 | CELERYD_LOG_FILE="/var/log/celery/%n%I.log"
104 | CELERYD_PID_FILE="/var/run/celery/%n.pid"
105 | CELERYD_USER="root"
106 | CELERYD_GROUP="root"
107 | DJANGO_SETTINGS_MODULE="djangoTrade.settings"
108 | CELERY_CREATE_DIRS=1
109 | SECRET_KEY="ada#qadaa2d#1232%!^*(&@(!&Y!*T!@(^F#!@F!@F!(@"
110 | EOF
111 | echo "$CELERYD_CFG" > /etc/default/celeryd
112 |
113 | read -d "" CELERYBEAT_CFG <<"EOF"
114 | CELERY_BIN="/opt/env/bin/python -m celery"
115 | CELERY_APP="djangoTrade"
116 | CELERYD_CHDIR="/opt/ongrid_portal"
117 | DJANGO_SETTINGS_MODULE="djangoTrade.settings"
118 | CELERYBEAT_USER="root"
119 | CELERYBEAT_GROUP="root"
120 | EOF
121 | echo "$CELERYBEAT_CFG" > /etc/default/celerybeat
122 |
123 | /etc/init.d/celeryd create-paths
124 | /etc/init.d/celeryd start
125 | /etc/init.d/celeryd stop
126 | /etc/init.d/celerybeat create-paths
127 | /etc/init.d/celerybeat start
128 | /etc/init.d/celerybeat stop
129 | sudo update-rc.d celeryd defaults
130 | sudo update-rc.d celerybeat defaults
131 | ```
132 |
133 | ## Authors
134 | * OnGrid Systems: [Site](https://ongrid.pro), [GitHub](https://github.com/OnGridSystems/), [FaceBook](https://www.facebook.com/ongrid.pro/), [Youtube](https://www.youtube.com/channel/UCT8s-f1FInO6ivn_dp-W34g), [LinkedIn](https://www.linkedin.com/company/ongridpro/)
135 | * Sergey Korotko [FaceBook](https://www.facebook.com/s.korotko), [GitHub](https://github.com/achievement008)
136 | * Dmitry Suldin [FaceBook](https://www.facebook.com/novator.klin), [GitHub](https://github.com/Klyaus)
137 | * Kirill Varlamov: [GitHub](https://github.com/ongrid/), [FaceBook](https://www.facebook.com/kirill.varlamov.12), [LinkedIn](https://www.linkedin.com/in/kvarlamo/)
138 |
139 | ## License
140 |
141 | Copyright (c) 2018 OnGrid Systems.
142 |
143 | Each file included in this repository is licensed under the [MIT license](LICENSE).
--------------------------------------------------------------------------------
/trade/static/css/style.css:
--------------------------------------------------------------------------------
1 | .main-nav {
2 | background: #388e3c;
3 | }
4 |
5 | .main-nav li {
6 | border-left: 1px solid #2e7d32;
7 | border-right: 1px solid #1b5e20;
8 | font-weight: bold;
9 | text-transform: uppercase;
10 | font-size: 14px;
11 | }
12 |
13 | .main-nav li:first-child {
14 | border-left: 1px solid #2e7d32;
15 | }
16 |
17 | .main-nav li a {
18 | color: lightgray;
19 | }
20 |
21 | .brand-logo img {
22 | margin: 0 auto;
23 | padding: 10px;
24 | }
25 |
26 | .exchange {
27 | width: 100%;
28 | text-align: center;
29 | }
30 |
31 |
32 | .exchange th {
33 | border: none;
34 | color: #1e2324;
35 | text-align: center;
36 | background: #a5d6a7;
37 | font-weight: bolder;
38 | }
39 | .user_coins td {
40 | border-bottom: 1px solid #e8e0e0;
41 | }
42 |
43 | .workers {
44 | width: 100%;
45 | text-align: center;
46 | }
47 |
48 | .workers td{
49 | border-left: 1px solid gray;
50 | border-bottom: 1px solid gray;
51 | }
52 |
53 | .workers td:last-child{
54 | border-right: 1px solid gray;
55 | }
56 |
57 |
58 | .workers th {
59 | border: none;
60 | color: #1e2324;
61 | text-align: center;
62 | background: #a5d6a7;
63 | font-weight: bolder;
64 | }
65 |
66 | .user_coins td:first-child {
67 | font-weight: bolder;
68 | text-align: left;
69 | text-transform: uppercase;
70 | }
71 |
72 | tr.balances td:last-child {
73 | text-align: right;
74 | }
75 |
76 | .mysize {
77 | font-size: 1.5rem !important;
78 | }
79 |
80 | .exchange-header th:nth-child(1) {
81 | width: 10% !important;
82 | }
83 |
84 | .main-content {
85 | margin-top: 30px;
86 | padding: 48px 0 48px 0;
87 | background-color: #e5f0e6;
88 | min-height: 200px;
89 | }
90 |
91 | .user-info {
92 | border-right: 1px solid lightgray;
93 | }
94 |
95 | .totalBTC {
96 | font-family: Roboto, serif;
97 | font-size: xx-large;
98 | display: block;
99 | text-align: center;
100 | }
101 |
102 | .wallet {
103 | padding: 20px;
104 | margin-bottom: 50px;
105 | background: #b3d5d6;
106 | }
107 |
108 | .transactions-table {
109 | max-width: 100%;
110 | width: 100%;
111 | }
112 |
113 | .transactions-table thead th {
114 | background: #009688;
115 | color: white;
116 | }
117 |
118 | .transactions-table tbody td {
119 | border-bottom: 1px solid grey;
120 | }
121 |
122 | .transactions-table tbody td:last-child {
123 | word-break: break-all;
124 | }
125 |
126 | .transaction-type {
127 | padding: 2px;
128 | border-radius: 2px;
129 | }
130 |
131 | .table-bordered {
132 | border: 1px solid #c7ecb8;
133 | border-collapse: separate;
134 | *border-collapse: collapsed;
135 | border-left: 0;
136 | -webkit-border-radius: 4px;
137 | -moz-border-radius: 4px;
138 | border-radius: 4px;
139 | }
140 |
141 | .table-bordered th,
142 | .table-bordered td {
143 | border-bottom: 1px solid #c7ecb8;
144 | }
145 |
146 | .fa-commenting {
147 | cursor: pointer;
148 | }
149 |
150 | .alert-new {
151 | padding: 10px;
152 | font-weight: bold;
153 | border-radius: 4px;
154 | font-size: 1.1rem;
155 | margin: 0 0 2em 0;
156 | }
157 |
158 | .transaction-info td {
159 | border-bottom: 1px solid grey;
160 | }
161 |
162 | .transaction-info {
163 | color: black;
164 | background: white;
165 | border: 1px solid white;
166 | text-align: left !important;
167 | }
168 |
169 | .second-nav {
170 | height: 26px;
171 | line-height: 26px;
172 | }
173 |
174 | .exchange-coins {
175 | border: 1px solid grey;
176 | width: 80%;
177 | border-spacing: 0;
178 | }
179 |
180 | .exchange-coins td {
181 | height: 30px;
182 | line-height: 30px;
183 | border-bottom: 1px solid grey
184 | }
185 |
186 | .exchange-coins td i {
187 | cursor: pointer;
188 | }
189 |
190 | .rank-up, .rank-down, .primary-rank {
191 | padding: 3px 5px;
192 | color: white;
193 | }
194 |
195 | .pair {
196 | background: #4caf50;
197 | }
198 |
199 | .unactive {
200 | background: #f44336 !important;
201 | }
202 |
203 | .pair-share {
204 | width: 80%;
205 | }
206 |
207 | .primary-coins {
208 | display: -webkit-flex;
209 | display: flex;
210 | -webkit-justify-content: space-around;
211 | justify-content: space-around;
212 | -webkit-flex-wrap: wrap;
213 | flex-wrap: wrap;
214 | }
215 |
216 | .primary-coin {
217 | width: 50%;
218 | text-align: center;
219 | padding: 10px;
220 | }
221 |
222 | .primary-rank {
223 | display: none !important;
224 | cursor: pointer;
225 | }
226 |
227 | .rank:hover .primary-rank {
228 | display: inline !important;
229 | }
230 |
231 | .border {
232 | border: 1px solid red;
233 | }
234 |
235 | ::-webkit-scrollbar {
236 | width: 3px;
237 | }
238 |
239 | #buttons, #buttons-zoom {
240 | padding: 10px;
241 | }
242 |
243 | .ui-jqchart-tooltip {
244 | background: white;
245 | color: black;
246 | padding: 10px;
247 | border-radius: 10px;
248 | z-index: 10;
249 | border: 1px solid black;
250 | }
251 |
252 | .coinmarketcap-currency-widget div {
253 | border-radius: 0 !important;
254 | }
255 | .coinmarketcap-currency-widget > div > div:last-child {
256 | opacity: 0;
257 | height: 0 !important;
258 | padding: 0 !important;
259 | }
260 |
261 | .pair-advanced {
262 | padding-bottom: 10px;
263 | }
264 |
265 | .pair-advanced input {
266 | width: 100px;
267 | }
268 |
269 | .active_pair {
270 | background-image: linear-gradient(#ebdf95, #fbf4c7 15%);
271 | border-right: 0;
272 | border-left: 0;
273 | }
274 |
275 | .active_pair td {
276 | border-top: 1px solid #f7ab1c !important;
277 | border-bottom: 1px solid #f7ab1c !important;
278 | }
279 |
280 | .pair_tr td{
281 | -webkit-transition: all .3s;
282 | -moz-transition: all .3s;
283 | -ms-transition: all .3s;
284 | -o-transition: all .3s;
285 | transition: all .3s;
286 | }
287 |
288 | .orders td {
289 | font-size: 10px;
290 | padding: 0 !important;
291 | }
--------------------------------------------------------------------------------
/trade/static/js/coinmarketcup.js:
--------------------------------------------------------------------------------
1 | !function(){var e;if(void 0===window.jQuery||"1.11.1"!==window.jQuery.fn.jquery){var t=document.createElement("script");t.setAttribute("type","text/javascript"),t.setAttribute("src","https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"),t.readyState?t.onreadystatechange=function(){"complete"!=this.readyState&&"loaded"!=this.readyState||a()}:t.onload=a,(document.getElementsByTagName("head")[0]||document.documentElement).appendChild(t)}else e=window.jQuery,n();function a(){e=window.jQuery.noConflict(!0),n()}function i(e){var t=" "+document.cookie,a=" "+e+"=",i=null,n=0,r=0;return t.length>0&&-1!=(n=t.indexOf(a))&&(n+=a.length,-1==(r=t.indexOf(";",n))&&(r=t.length),i=unescape(t.substring(n,r))),i}function n(){var t,a,n=(t=i("_locale")||void 0,a=!("object"!=typeof Intl||!Intl||"function"!=typeof Intl.NumberFormat),{toLocaleString:function(e,i){var n=Number(e);if(isNaN(n))return e;var r,o,c,l,s=i&&i.minDecimalPlaces,d=i&&i.maxDecimalPlaces;return void 0===s||void 0===d?(r=n,a?r.toLocaleString(t):r.toLocaleString()):(o=n,c=s,l=d,a?o.toLocaleString(t,{minimumFractionDigits:c,maximumFractionDigits:l}):o.toFixed(l))}});function r(e,t){var a=t;t=Math.pow(10,t);for(var i=["K","M","B","T"],r=i.length-1;r>=0;r--){var o=Math.pow(10,3*(r+1));if(o<=e){1e3==(e=Math.round(e*t/o)/t)&&r=1e3?n.toLocaleString(Math.round(e)):e>=1?n.toLocaleString(e,{minDecimalPlaces:8,maxDecimalPlaces:8}):e<1e-8?Number(e).toExponential(4):n.toLocaleString(e,{minDecimalPlaces:8,maxDecimalPlaces:8});return e}(e):function(e){e=e>=1?e>=1e5?n.toLocaleString(Math.round(e)):n.toLocaleString(e,{minDecimalPlaces:2,maxDecimalPlaces:2}):e<1e-6?Number(e).toExponential(2):n.toLocaleString(e,{minDecimalPlaces:6,maxDecimalPlaces:6});return e}(e)}function c(e,t,a){var i=t,n={btc:"฿",usd:"$",eur:"€",cny:"¥",gbp:"£",cad:"$",rub:" ",hkd:"$",jpy:"¥",aud:"$",brl:"R$",inr:"₹",krw:"₩",mxn:"$",idr:"Rp",chf:"Fr"};return e.toLowerCase()in n&&(i=n[e.toLowerCase()]+i),a&&(i=i+' '+e.toUpperCase()+" "),i}function l(e,t,a,i,l,s,d,p,m,u,h,g,v,f,x,y,b,w){var L=w?"https://s2.coinmarketcap.com/static/img/coins/64x64/"+w+".png":"https://files.coinmarketcap.com/static/widget/coins_legacy/64x64/"+e+".png",k="#093";m<0&&(k="#d14836"),m=n.toLocaleString(m,{minDecimalPlaces:2,maxDecimalPlaces:2}),valTickerHTML=v?"("+a+")":"",valPrice=s?o(s,i):"?",valPercentHTML=m?'('+m+"%)":"",valMarketCap=u?r(u,2):"?",valVolume=h?r(h,2):"?",d?(mainLineHeight=25,valPriceSecondary=p?o(p,d):"?",secondaryHTML=''+valPriceSecondary+" "+d+" "):(mainLineHeight=30,secondaryHTML="");var E="utm_medium=widget&utm_campaign=cmcwidget&utm_source="+location.hostname+"&utm_content="+e,P=' ';return P+=function(e,t,a,i,n,r,o,l){var s=0,d=0,p="",m="",u="";if(e&&s++,t&&s++,a&&s++,0==s)return"";1==s&&(d=100),2==s&&(d=49.8),3==s&&(d=33),e&&(borderWidth=0,(a||t)&&(borderWidth=1),p='
RANK '+r+"
");a&&(borderWidth=0,t&&(borderWidth=1),m='
MARKET CAP '+c(n,o,i)+"
");t&&(u='
VOLUME (24H) '+c(n,l,i)+"
");return detailedHTML='
'+p+m+u+"
",detailedHTML}(f,x,y,b,l,g,valMarketCap,valVolume),P+='
'}e(document).ready(function(e){e(".coinmarketcap-currency-widget").each(function(){var t=e(this).attr("data-currency"),a=e(this).data("currencyid"),i=e(this).attr("data-base").toUpperCase(),n=e(this).attr("data-secondary");n="BTC"==(n=n?n.toUpperCase():null)||"USD"==n?n:null;var r=e(this).attr("data-stats");r=(r=r?r.toUpperCase():null)==i?i:"USD";var o,c,s=!1!==e(this).data("ticker"),d=!1!==e(this).data("rank"),p=!1!==e(this).data("marketcap"),m=!1!==e(this).data("volume"),u=!1!==e(this).data("statsticker"),h=this;a?(o="https://widgets.coinmarketcap.com/v2/ticker/"+a+"/?ref=widget&convert="+i,c="volume_24h_"):(o="https://widgets.coinmarketcap.com/v1/ticker/"+t+"/?ref=widget&convert="+i,c="24h_volume_"),e.get({url:o,success:function(o){o=o.length?o[0]:o.data,t||(t=o.website_slug);var g="price_"+i.toLowerCase(),v=n?"price_"+n.toLowerCase():null,f="market_cap_"+r.toLowerCase(),x=c+r.toLowerCase(),y=parseFloat(o[g]),b=v?parseFloat(o[v]):null,w=parseInt(o[f]),L=parseInt(o[x]),k=o.name,E=o.symbol,P=Number(o.percent_change_24h),M=o.rank,C=l(t,k,E,i,r,y,n,b,P,w,L,M,s,d,m,p,u,a);e(h).html(C),e(h).find("a").css({"text-decoration":"none",color:"#428bca"})}})})})}}();
2 |
--------------------------------------------------------------------------------
/trade/static/js/script.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function () {
2 | $('select').material_select();
3 | $('.modal').modal();
4 | $('#yandex-wallet-add').hide();
5 |
6 | $('.input-field select').addClass('material');
7 |
8 | $('.change_status').on('click', function () {
9 | var ue = $(this).parent('form').find('input[name="user-exchange"]').val();
10 | var csrf = getCookie('csrftoken');
11 | $.ajax({
12 | url: '/change_status/',
13 | type: 'post',
14 | cache: !1,
15 | dataType: 'html',
16 | data: {
17 | ue: ue,
18 | csrfmiddlewaretoken: csrf
19 | },
20 | success: function (data) {
21 | data === 'ok' ? location.reload() : data === '{"location": "/change_status/"}' ? Materialize.toast('У Вас недостаточно прав', 2000) : Materialize.toast('Не удалось изменить статус', 2000);
22 | }
23 | });
24 | return false;
25 | });
26 | $('.api-incorrect').on('click', function () {
27 | Materialize.toast('Api Key/Secret is incorrect', 2000);
28 | return false;
29 | });
30 | $('#hidenull').on('click', function () {
31 | var hide = $(this).prop('checked');
32 | hide0balances(hide);
33 | });
34 | function hide0balances(hide) {
35 | if (hide) {
36 | for (var i = 0; i < $('.balance').length; i++) {
37 | var balance = $('.balance:eq(' + i + ')');
38 | if (parseFloat(balance.text().replace(",", ".")) == 0) {
39 | balance.parent('tr').hide();
40 | }
41 | }
42 | } else {
43 | $('.balances').show();
44 | }
45 | }
46 |
47 | $('#wallet').find('select').on('change', function () {
48 | var wallet = $("#wallet").find("select option:selected").text();
49 | if (wallet === 'Yandex Money') {
50 | $('#wallet').find('input#id_address').attr('disabled', true);
51 | $('#yandex-wallet-add').show();
52 | $('#add-wallet-but').text('Продолжить')
53 | } else {
54 | $('#yandex-wallet-add').hide();
55 | $('#wallet').find('input#id_address').attr('disabled', false);
56 | $('#add-wallet-but').text('Отправить')
57 | }
58 | });
59 |
60 | $('.fa-commenting').on('click', function () {
61 | $('#user_comment_modal').modal('open');
62 | $('input[name="tr_id"]').val($(this).attr('data-id'));
63 | });
64 | $('#comment-form').on('submit', function () {
65 | var f = $(this).serializeArray();
66 | $('i#trans' + f[1].value).parent('td').html(f[2].value);
67 | $.ajax({
68 | url: '/transaction/new_comment/',
69 | type: 'post',
70 | dataType: 'html',
71 | data: f,
72 | success: function (q) {
73 | if ('ok' === q) {
74 | $('#user_comment_modal').modal('close');
75 | $('#comment-form')[0].reset();
76 | $('i#trans' + f[1].value).parent('td').html(f[2].value);
77 | } else if ('none' === q) {
78 | Materialize.toast('Error while saving comment')
79 | }
80 | }
81 | });
82 | return false;
83 | });
84 | $('a.scrollto').on('click', function () {
85 | var name = $(this).attr('href').slice(1);
86 | $('.collapsible').collapsible('open', $('a[name="' + name + '"]').parent('li').index() - 3);
87 | });
88 | $('.tooltipped').tooltip({
89 | delay: 50,
90 | html: true
91 | });
92 | });
93 |
94 | function getCookie(name) {
95 | var cookieValue = null;
96 | if (document.cookie && document.cookie !== '') {
97 | var cookies = document.cookie.split(';');
98 | for (var i = 0; i < cookies.length; i++) {
99 | var cookie = jQuery.trim(cookies[i]);
100 | if (cookie.substring(0, name.length + 1) === (name + '=')) {
101 | cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
102 | break;
103 | }
104 | }
105 | }
106 | return cookieValue;
107 | }
108 |
109 | var grid = document.getElementById('grid');
110 |
111 | grid.onclick = function (e) {
112 | if (e.target.tagName != 'TH') return;
113 | sortGrid(e.target.cellIndex, e.target.getAttribute('data-type'));
114 | };
115 |
116 | function sortGrid(colNum, type) {
117 | var tbody = grid.getElementsByTagName('tbody')[0];
118 | var rowsArray = [].slice.call(tbody.rows);
119 | var compare;
120 | switch (type) {
121 | case 'number':
122 | compare = function (rowA, rowB) {
123 | return rowA.cells[colNum].innerHTML - rowB.cells[colNum].innerHTML;
124 | };
125 | break;
126 | case 'string':
127 | compare = function (rowA, rowB) {
128 | return rowA.cells[colNum].innerHTML > rowB.cells[colNum].innerHTML ? 1 : -1;
129 | };
130 | break;
131 | }
132 | rowsArray.sort(compare);
133 | grid.removeChild(tbody);
134 | for (var i = 0; i < rowsArray.length; i++) {
135 | tbody.appendChild(rowsArray[i]);
136 | }
137 | grid.appendChild(tbody);
138 | }
139 |
140 | Storage.prototype.setObject = function (key, value) {
141 | this.setItem(key, JSON.stringify(value));
142 | };
143 |
144 | Storage.prototype.getObject = function (key) {
145 | var value = this.getItem(key);
146 | try {
147 | return JSON.parse(value);
148 | }
149 | catch(err) {
150 | console.log("JSON parse failed for lookup of ", key, "\n error was: ", err);
151 | return null;
152 | }
153 | };
154 |
155 |
156 | // function initHashChanges() {
157 | // var h = window.location.hash;
158 | // var pair = h.toUpperCase();
159 | // pair = pair.substr(1, pair.length); // trim #
160 | //
161 | // // trace('on load hash is [' + h + ']');
162 | // // set this so we know not to override it with localStorage or default currencyPair
163 | // if (currencyPairArray.indexOf(pair) != -1) {
164 | // hasHashCurrencyPair = true;
165 | // }
166 | //
167 | // evaluateHash(h);
168 | //
169 | // window.onhashchange = function() {
170 | // // trace("hash changed: " + window.location.hash);
171 | // clearTimeout(hashTimer);
172 | // evaluateHash(window.location.hash);
173 | // };
174 | // }
--------------------------------------------------------------------------------
/djangoTrade/settings.py:
--------------------------------------------------------------------------------
1 | """
2 | Django settings for djangoTrade project.
3 |
4 | Generated by 'django-admin startproject' using Django 1.11.1.
5 |
6 | For more information on this file, see
7 | https://docs.djangoproject.com/en/1.11/topics/settings/
8 |
9 | For the full list of settings and their values, see
10 | https://docs.djangoproject.com/en/1.11/ref/settings/
11 | """
12 | from __future__ import absolute_import, unicode_literals
13 | import os
14 |
15 | # Celery options
16 | from kombu import Queue, Exchange
17 |
18 | CELERY_BROKER_URL = 'amqp://guest:guest@localhost//'
19 | CELERY_ACCEPT_CONTENT = ['json']
20 | CELERY_RESULT_BACKEND = 'db+mysql://root:@localhost/celery_result'
21 | CELERY_TASK_SERIALIZER = 'json'
22 | CELERY_TIMEZONE = 'Europe/Moscow'
23 | CELERY_SEND_TASK_ERROR_EMAILS = False
24 | CELERYD_MAX_TASKS_PER_CHILD = 5
25 |
26 | CELERY_ROUTES = {
27 | 'trade.tasks.pull_exchanges_balances': {'queue': 'low'},
28 | 'trade.tasks.pull_exchanges_tickers': {'queue': 'low'},
29 | }
30 |
31 | CELERY_CREATE_MISSING_QUEUES = True
32 |
33 | # AllAuth setting
34 | ACCOUNT_EMAIL_REQUIRED = True
35 | ACCOUNT_AUTHENTICATION_METHOD = 'username_email'
36 | ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 1
37 | LOGIN_REDIRECT_URL = '/'
38 | ACCOUNT_LOGOUT_REDIRECT_URL = '/'
39 | ACCOUNT_LOGOUT_ON_PASSWORD_CHANGE = True
40 |
41 | # redis sessions
42 | SESSION_ENGINE = 'redis_sessions.session'
43 |
44 | # Email
45 | EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
46 |
47 | DEFAULT_INDEX_TABLESPACE = 10
48 |
49 | ADMINS = (('Сергей', 'achievement008@gmail.com'),)
50 |
51 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
52 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
53 |
54 | # Quick-start development settings - unsuitable for production
55 | # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
56 |
57 | # SECURITY WARNING: keep the secret key used in production secret!
58 | SECRET_KEY = '1j&=q!62_%51y9!=97n=)bel8+#y+lup1bsy31d%s=sm!9q_c+'
59 |
60 | # SECURITY WARNING: don't run with debug turned on in production!
61 | DEBUG = True
62 |
63 | ALLOWED_HOSTS = ['*']
64 |
65 | # Application definition
66 |
67 | INSTALLED_APPS = [
68 | 'django.contrib.admin',
69 | 'django.contrib.auth',
70 | 'django.contrib.contenttypes',
71 | 'django.contrib.sessions',
72 | 'django.contrib.messages',
73 | 'django.contrib.staticfiles',
74 | 'django.contrib.sites',
75 | 'trade',
76 | 'tradeBOT',
77 | 'user_profile',
78 | 'django_celery_beat',
79 | 'allauth',
80 | 'allauth.account',
81 | 'allauth.socialaccount',
82 | 'django.contrib.humanize',
83 | 'ticker_app',
84 | 'django_extensions',
85 | 'channels',
86 | ]
87 |
88 | SITE_ID = 1
89 |
90 | MIDDLEWARE = [
91 | 'django.middleware.security.SecurityMiddleware',
92 | 'django.contrib.sessions.middleware.SessionMiddleware',
93 | 'django.middleware.common.CommonMiddleware',
94 | 'django.middleware.csrf.CsrfViewMiddleware',
95 | 'django.contrib.auth.middleware.AuthenticationMiddleware',
96 | 'django.contrib.messages.middleware.MessageMiddleware',
97 | 'django.middleware.clickjacking.XFrameOptionsMiddleware',
98 | ]
99 |
100 | AUTHENTICATION_BACKENDS = (
101 | 'django.contrib.auth.backends.ModelBackend',
102 | 'allauth.account.auth_backends.AuthenticationBackend',
103 | )
104 |
105 | ROOT_URLCONF = 'djangoTrade.urls'
106 |
107 | TEMPLATES = [
108 | {
109 | 'BACKEND': 'django.template.backends.django.DjangoTemplates',
110 | 'DIRS': [],
111 | 'APP_DIRS': True,
112 | 'OPTIONS': {
113 | 'context_processors': [
114 | 'django.template.context_processors.debug',
115 | 'django.template.context_processors.request',
116 | 'django.contrib.auth.context_processors.auth',
117 | 'django.contrib.messages.context_processors.messages',
118 | ],
119 | },
120 | },
121 | ]
122 |
123 | WSGI_APPLICATION = 'djangoTrade.wsgi.application'
124 |
125 | # Database
126 | # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
127 |
128 | DATABASES = {
129 | 'default': {
130 | 'ENGINE': 'django.db.backends.mysql',
131 | 'NAME': 'trade',
132 | 'USER': 'root',
133 | 'PASSWORD': '',
134 | 'default-character-set': 'utf-8',
135 | },
136 | 'portal_ticker': {
137 | 'ENGINE': 'django.db.backends.mysql',
138 | 'NAME': 'portal_ticker',
139 | 'USER': 'root',
140 | 'PASSWORD': '',
141 | }
142 | }
143 |
144 | DATABASE_ROUTERS = ['ticker_app.routers.DBRouter', 'ticker_app.routers.PrimaryRouter']
145 |
146 | # Password validation
147 | # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
148 |
149 | AUTH_PASSWORD_VALIDATORS = [
150 | {
151 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
152 | },
153 | {
154 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
155 | },
156 | {
157 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
158 | },
159 | {
160 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
161 | },
162 | ]
163 |
164 | # Internationalization
165 | # https://docs.djangoproject.com/en/1.11/topics/i18n/
166 |
167 | LANGUAGE_CODE = 'en-US'
168 |
169 | TIME_ZONE = 'Europe/Moscow'
170 |
171 | USE_I18N = True
172 |
173 | USE_L10N = True
174 |
175 | USE_TZ = True
176 |
177 | STATIC_URL = '/static/'
178 |
179 | LOGIN_URL = '/accounts/login/'
180 |
181 | # yandex money settings
182 | YANDEX_MONEY_CLIENT_ID = None # set before start
183 |
184 | YANDEX_MONEY_REDIRECT_URI = None # set before start
185 |
186 | YANDEX_MONEY_CLIENT_SECRET = None # set before start
187 |
188 | STATIC_ROOT = '/opt/portal_ongrid/static'
189 | MEDIA_ROOT = '/opt/portal_ongrid/media'
190 | MEDIA_URL = '/media/'
191 |
192 | # channels
193 | CHANNEL_LAYERS = {
194 | "default": {
195 | "BACKEND": "asgi_redis.RedisChannelLayer",
196 | "CONFIG": {
197 | "hosts": [("localhost", 6379)],
198 | },
199 | "ROUTING": "djangoTrade.routing.channel_routing",
200 | },
201 | }
202 |
203 | # минимальное значение изменения цены за секунду
204 | DEPTH_COEFFICIENT = 0.5
205 |
206 | # активные биржи для торговли
207 | TRADING_EXCHANGES = ['poloniex']
208 |
209 | # Time to life order, mins
210 | ORDER_TTL = 5
211 |
212 | # минимальное кол-во элементов серии
213 | RATE_CHANGE_SERIES_MIN_COUNT = 2
214 |
215 | # количество направлений
216 | DIRECTIONS_COUNT = 7
217 |
218 | # количество однонапрвленных (первых) направлений
219 | UNIDIRECTIONAL_COUNT = 4
220 |
--------------------------------------------------------------------------------
/trade/migrations/0001_initial.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | # Generated by Django 1.11.5 on 2017-09-29 08:29
3 | from __future__ import unicode_literals
4 |
5 | from django.conf import settings
6 | from django.db import migrations, models
7 | import django.db.models.deletion
8 |
9 |
10 | class Migration(migrations.Migration):
11 |
12 | initial = True
13 |
14 | dependencies = [
15 | migrations.swappable_dependency(settings.AUTH_USER_MODEL),
16 | ]
17 |
18 | operations = [
19 | migrations.CreateModel(
20 | name='Coin',
21 | fields=[
22 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
23 | ('short_name', models.CharField(max_length=20)),
24 | ('full_name', models.CharField(max_length=40)),
25 | ],
26 | options={
27 | 'verbose_name': 'Криптовалюта',
28 | 'verbose_name_plural': 'Криптовалюты',
29 | },
30 | ),
31 | migrations.CreateModel(
32 | name='Exchanges',
33 | fields=[
34 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
35 | ('name', models.CharField(max_length=255)),
36 | ('info_frozen_key', models.CharField(max_length=31)),
37 | ],
38 | options={
39 | 'verbose_name': 'Биржа',
40 | 'verbose_name_plural': 'Биржи',
41 | },
42 | ),
43 | migrations.CreateModel(
44 | name='Transaction',
45 | fields=[
46 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
47 | ('name', models.CharField(max_length=50)),
48 | ('t_type', models.CharField(max_length=20)),
49 | ('number', models.BigIntegerField()),
50 | ('date', models.DateTimeField()),
51 | ('t_from', models.TextField()),
52 | ('t_to', models.TextField()),
53 | ('type', models.CharField(max_length=10)),
54 | ('value', models.DecimalField(decimal_places=8, default=0, max_digits=30)),
55 | ('block_hash', models.CharField(default=None, max_length=127, null=True)),
56 | ('hash', models.CharField(max_length=127)),
57 | ('comment', models.TextField(default='', null=True)),
58 | ('title', models.CharField(default='', max_length=255, null=True)),
59 | ('details', models.CharField(default='', max_length=255, null=True)),
60 | ('usd_value', models.DecimalField(decimal_places=8, default=0, max_digits=30)),
61 | ('user_comment', models.CharField(blank=True, default=None, max_length=255, null=True)),
62 | ('currency', models.CharField(blank=True, default=None, max_length=10, null=True)),
63 | ],
64 | options={
65 | 'verbose_name': 'Транзакциия',
66 | 'verbose_name_plural': 'Транзакции',
67 | },
68 | ),
69 | migrations.CreateModel(
70 | name='UserBalance',
71 | fields=[
72 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
73 | ('coin', models.CharField(max_length=10)),
74 | ('total', models.DecimalField(decimal_places=8, default=0, max_digits=30)),
75 | ('used', models.DecimalField(decimal_places=8, default=0, max_digits=30)),
76 | ('free', models.DecimalField(decimal_places=8, default=0, max_digits=30)),
77 | ('conversions', models.CharField(max_length=255)),
78 | ('btc_value', models.DecimalField(decimal_places=8, default=0, max_digits=30)),
79 | ('last_update', models.DateTimeField(auto_now=True)),
80 | ],
81 | options={
82 | 'verbose_name': 'Баланс пользователя',
83 | 'verbose_name_plural': 'Балансы пользователей',
84 | },
85 | ),
86 | migrations.CreateModel(
87 | name='UserExchange',
88 | fields=[
89 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
90 | ('apikey', models.CharField(max_length=127)),
91 | ('apisecret', models.CharField(max_length=255)),
92 | ('is_active', models.BooleanField(default=False)),
93 | ('is_active_script', models.BooleanField(default=False)),
94 | ('is_correct', models.BooleanField(default=True)),
95 | ('total_btc', models.DecimalField(decimal_places=8, max_digits=30)),
96 | ('total_usd', models.DecimalField(decimal_places=8, default=0, max_digits=30)),
97 | ('coefficient_of_depth', models.IntegerField(default=0)),
98 | ('error', models.CharField(blank=True, max_length=255)),
99 | ('exchange', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='trade.Exchanges')),
100 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
101 | ],
102 | options={
103 | 'verbose_name': 'Биржа пользователя',
104 | 'verbose_name_plural': 'Биржи пользователей',
105 | },
106 | ),
107 | migrations.CreateModel(
108 | name='UserHoldings',
109 | fields=[
110 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
111 | ('type', models.CharField(max_length=255)),
112 | ('total_btc', models.DecimalField(decimal_places=8, default=0, max_digits=30)),
113 | ('total_usd', models.DecimalField(decimal_places=8, default=0, max_digits=30)),
114 | ('date_time', models.DateTimeField()),
115 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
116 | ],
117 | options={
118 | 'verbose_name': 'История баланса',
119 | 'verbose_name_plural': 'Истории балансов',
120 | },
121 | ),
122 | migrations.CreateModel(
123 | name='UserWallet',
124 | fields=[
125 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
126 | ('address', models.CharField(max_length=511)),
127 | ('access_token', models.CharField(blank=True, default=None, max_length=511, null=True)),
128 | ('balance', models.DecimalField(decimal_places=8, default=0, max_digits=30)),
129 | ('total_btc', models.DecimalField(decimal_places=8, default=0, max_digits=30)),
130 | ('total_usd', models.DecimalField(decimal_places=8, default=0, max_digits=30)),
131 | ('last_update', models.DateTimeField(auto_now=True)),
132 | ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
133 | ],
134 | options={
135 | 'verbose_name': 'Кошелёк пользователя',
136 | 'verbose_name_plural': 'Кошельки пользователей',
137 | },
138 | ),
139 | migrations.CreateModel(
140 | name='Wallets',
141 | fields=[
142 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
143 | ('name', models.CharField(max_length=255)),
144 | ],
145 | options={
146 | 'verbose_name': 'Кошелёк',
147 | 'verbose_name_plural': 'Кошельки',
148 | },
149 | ),
150 | migrations.AddField(
151 | model_name='userwallet',
152 | name='wallet',
153 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='trade.Wallets'),
154 | ),
155 | migrations.AddField(
156 | model_name='userbalance',
157 | name='ue',
158 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='trade.UserExchange'),
159 | ),
160 | migrations.AlterUniqueTogether(
161 | name='transaction',
162 | unique_together=set([('name', 't_type', 'hash')]),
163 | ),
164 | ]
165 |
--------------------------------------------------------------------------------
/trade/static/js/exporting.js:
--------------------------------------------------------------------------------
1 | /*
2 | Highcharts JS v5.0.12 (2017-05-24)
3 | Exporting module
4 |
5 | (c) 2010-2017 Torstein Honsi
6 |
7 | License: www.highcharts.com/license
8 | */
9 | (function(p){"object"===typeof module&&module.exports?module.exports=p:p(Highcharts)})(function(p){(function(e){var p=e.defaultOptions,t=e.doc,B=e.Chart,u=e.addEvent,K=e.removeEvent,H=e.fireEvent,n=e.createElement,D=e.discardElement,I=e.css,x=e.merge,E=e.pick,k=e.each,F=e.objectEach,y=e.extend,z=e.win,J=z.navigator.userAgent,G=e.SVGRenderer,L=e.Renderer.prototype.symbols,M=/Edge\/|Trident\/|MSIE /.test(J),N=/firefox/i.test(J);y(p.lang,{printChart:"Print chart",downloadPNG:"Download PNG image",downloadJPEG:"Download JPEG image",
10 | downloadPDF:"Download PDF document",downloadSVG:"Download SVG vector image",contextButtonTitle:"Chart context menu"});p.navigation={buttonOptions:{theme:{},symbolSize:14,symbolX:12.5,symbolY:10.5,align:"right",buttonSpacing:3,height:22,verticalAlign:"top",width:24}};p.exporting={type:"image/png",url:"https://export.highcharts.com/",printMaxWidth:780,scale:2,buttons:{contextButton:{className:"highcharts-contextbutton",menuClassName:"highcharts-contextmenu",symbol:"menu",_titleKey:"contextButtonTitle",
11 | menuItems:[{textKey:"printChart",onclick:function(){this.print()}},{separator:!0},{textKey:"downloadPNG",onclick:function(){this.exportChart()}},{textKey:"downloadJPEG",onclick:function(){this.exportChart({type:"image/jpeg"})}},{textKey:"downloadPDF",onclick:function(){this.exportChart({type:"application/pdf"})}},{textKey:"downloadSVG",onclick:function(){this.exportChart({type:"image/svg+xml"})}}]}}};e.post=function(a,b,c){var d=n("form",x({method:"post",action:a,enctype:"multipart/form-data"},c),
12 | {display:"none"},t.body);F(b,function(a,b){n("input",{type:"hidden",name:b,value:a},null,d)});d.submit();D(d)};y(B.prototype,{sanitizeSVG:function(a,b){if(b&&b.exporting&&b.exporting.allowHTML){var c=a.match(/<\/svg>(.*?$)/);c&&c[1]&&(c='\x3cforeignObject x\x3d"0" y\x3d"0" width\x3d"'+b.chart.width+'" height\x3d"'+b.chart.height+'"\x3e\x3cbody xmlns\x3d"http://www.w3.org/1999/xhtml"\x3e'+c[1]+"\x3c/body\x3e\x3c/foreignObject\x3e",a=a.replace("\x3c/svg\x3e",c+"\x3c/svg\x3e"))}return a=a.replace(/zIndex="[^"]+"/g,
13 | "").replace(/isShadow="[^"]+"/g,"").replace(/symbolName="[^"]+"/g,"").replace(/jQuery[0-9]+="[^"]+"/g,"").replace(/url\(("|")(\S+)("|")\)/g,"url($2)").replace(/url\([^#]+#/g,"url(#").replace(/.*?$/,"\x3c/svg\x3e").replace(/(fill|stroke)="rgba\(([ 0-9]+,[ 0-9]+,[ 0-9]+),([ 0-9\.]+)\)"/g,'$1\x3d"rgb($2)" $1-opacity\x3d"$3"').replace(/ /g,
14 | "\u00a0").replace(//g,"\u00ad")},getChartHTML:function(){this.inlineStyles();return this.container.innerHTML},getSVG:function(a){var b,c,d,v,l,g=x(this.options,a);t.createElementNS||(t.createElementNS=function(a,b){return t.createElement(b)});c=n("div",null,{position:"absolute",top:"-9999em",width:this.chartWidth+"px",height:this.chartHeight+"px"},t.body);d=this.renderTo.style.width;l=this.renderTo.style.height;d=g.exporting.sourceWidth||g.chart.width||/px$/.test(d)&&parseInt(d,10)||600;l=g.exporting.sourceHeight||
15 | g.chart.height||/px$/.test(l)&&parseInt(l,10)||400;y(g.chart,{animation:!1,renderTo:c,forExport:!0,renderer:"SVGRenderer",width:d,height:l});g.exporting.enabled=!1;delete g.data;g.series=[];k(this.series,function(a){v=x(a.userOptions,{animation:!1,enableMouseTracking:!1,showCheckbox:!1,visible:a.visible});v.isInternal||g.series.push(v)});k(this.axes,function(a){a.userOptions.internalKey||(a.userOptions.internalKey=e.uniqueKey())});b=new e.Chart(g,this.callback);a&&k(["xAxis","yAxis","series"],function(d){var c=
16 | {};a[d]&&(c[d]=a[d],b.update(c))});k(this.axes,function(a){var d=e.find(b.axes,function(b){return b.options.internalKey===a.userOptions.internalKey}),c=a.getExtremes(),f=c.userMin,c=c.userMax;!d||void 0===f&&void 0===c||d.setExtremes(f,c,!0,!1)});d=b.getChartHTML();d=this.sanitizeSVG(d,g);g=null;b.destroy();D(c);return d},getSVGForExport:function(a,b){var c=this.options.exporting;return this.getSVG(x({chart:{borderRadius:0}},c.chartOptions,b,{exporting:{sourceWidth:a&&a.sourceWidth||c.sourceWidth,
17 | sourceHeight:a&&a.sourceHeight||c.sourceHeight}}))},exportChart:function(a,b){b=this.getSVGForExport(a,b);a=x(this.options.exporting,a);e.post(a.url,{filename:a.filename||"chart",type:a.type,width:a.width||0,scale:a.scale,svg:b},a.formAttributes)},print:function(){var a=this,b=a.container,c=[],d=b.parentNode,e=t.body,l=e.childNodes,g=a.options.exporting.printMaxWidth,f,m;if(!a.isPrinting){a.isPrinting=!0;a.pointer.reset(null,0);H(a,"beforePrint");if(m=g&&a.chartWidth>g)f=[a.options.chart.width,void 0,
18 | !1],a.setSize(g,void 0,!1);k(l,function(a,b){1===a.nodeType&&(c[b]=a.style.display,a.style.display="none")});e.appendChild(b);z.focus();z.print();setTimeout(function(){d.appendChild(b);k(l,function(a,b){1===a.nodeType&&(a.style.display=c[b])});a.isPrinting=!1;m&&a.setSize.apply(a,f);H(a,"afterPrint")},1E3)}},contextMenu:function(a,b,c,d,e,l,g){var f=this,m=f.chartWidth,q=f.chartHeight,v="cache-"+a,h=f[v],r=Math.max(e,l),C,w;h||(f[v]=h=n("div",{className:a},{position:"absolute",zIndex:1E3,padding:r+
19 | "px"},f.container),C=n("div",{className:"highcharts-menu"},null,h),w=function(){I(h,{display:"none"});g&&g.setState(0);f.openMenu=!1},f.exportEvents.push(u(h,"mouseleave",function(){h.hideTimer=setTimeout(w,500)}),u(h,"mouseenter",function(){clearTimeout(h.hideTimer)}),u(t,"mouseup",function(b){f.pointer.inClass(b.target,a)||w()})),k(b,function(a){if(a){var b;b=a.separator?n("hr",null,null,C):n("div",{className:"highcharts-menu-item",onclick:function(b){b&&b.stopPropagation();w();a.onclick&&a.onclick.apply(f,
20 | arguments)},innerHTML:a.text||f.options.lang[a.textKey]},null,C);f.exportDivElements.push(b)}}),f.exportDivElements.push(C,h),f.exportMenuWidth=h.offsetWidth,f.exportMenuHeight=h.offsetHeight);b={display:"block"};c+f.exportMenuWidth>m?b.right=m-c-e-r+"px":b.left=c-r+"px";d+l+f.exportMenuHeight>q&&"top"!==g.alignOptions.verticalAlign?b.bottom=q-d-r+"px":b.top=d+l-r+"px";I(h,b);f.openMenu=!0},addButton:function(a){var b=this,c=b.renderer,d=x(b.options.navigation.buttonOptions,a),e=d.onclick,l=d.menuItems,
21 | g,f,m=d.symbolSize||12;b.btnCount||(b.btnCount=0);b.exportDivElements||(b.exportDivElements=[],b.exportSVGElements=[]);if(!1!==d.enabled){var q=d.theme,k=q.states,h=k&&k.hover,k=k&&k.select,r;delete q.states;e?r=function(a){a.stopPropagation();e.call(b,a)}:l&&(r=function(){b.contextMenu(f.menuClassName,l,f.translateX,f.translateY,f.width,f.height,f);f.setState(2)});d.text&&d.symbol?q.paddingLeft=E(q.paddingLeft,25):d.text||y(q,{width:d.width,height:d.height,padding:0});f=c.button(d.text,0,0,r,q,h,
22 | k).addClass(a.className).attr({title:b.options.lang[d._titleKey],zIndex:3});f.menuClassName=a.menuClassName||"highcharts-menu-"+b.btnCount++;d.symbol&&(g=c.symbol(d.symbol,d.symbolX-m/2,d.symbolY-m/2,m,m).addClass("highcharts-button-symbol").attr({zIndex:1}).add(f));f.add().align(y(d,{width:f.width,x:E(d.x,b.buttonOffset)}),!0,"spacingBox");b.buttonOffset+=(f.width+d.buttonSpacing)*("right"===d.align?-1:1);b.exportSVGElements.push(f,g)}},destroyExport:function(a){var b=a?a.target:this;a=b.exportSVGElements;
23 | var c=b.exportDivElements,d=b.exportEvents,e;a&&(k(a,function(a,d){a&&(a.onclick=a.ontouchstart=null,e="cache-"+a.menuClassName,b[e]&&delete b[e],b.exportSVGElements[d]=a.destroy())}),a.length=0);c&&(k(c,function(a,d){clearTimeout(a.hideTimer);K(a,"mouseleave");b.exportDivElements[d]=a.onmouseout=a.onmouseover=a.ontouchstart=a.onclick=null;D(a)}),c.length=0);d&&(k(d,function(a){a()}),d.length=0)}});G.prototype.inlineToAttributes="fill stroke strokeLinecap strokeLinejoin strokeWidth textAnchor x y".split(" ");
24 | G.prototype.inlineBlacklist=[/-/,/^(clipPath|cssText|d|height|width)$/,/^font$/,/[lL]ogical(Width|Height)$/,/perspective/,/TapHighlightColor/,/^transition/];G.prototype.unstyledElements=["clipPath","defs","desc"];B.prototype.inlineStyles=function(){function a(a){return a.replace(/([A-Z])/g,function(a,b){return"-"+b.toLowerCase()})}function b(c){function q(b,e){n=u=!1;if(l){for(A=l.length;A--&&!u;)u=l[A].test(e);n=!u}"transform"===e&&"none"===b&&(n=!0);for(A=v.length;A--&&!n;)n=v[A].test(e)||"function"===
25 | typeof b;n||r[e]!==b&&f[c.nodeName][e]!==b&&(-1!==d.indexOf(e)?c.setAttribute(a(e),b):p+=a(e)+":"+b+";")}var h,r,p="",w,n,u,A;if(1===c.nodeType&&-1===g.indexOf(c.nodeName)){h=z.getComputedStyle(c,null);r="svg"===c.nodeName?{}:z.getComputedStyle(c.parentNode,null);f[c.nodeName]||(m||(m=t.createElementNS(e.SVG_NS,"svg"),m.setAttribute("version","1.1"),t.body.appendChild(m)),w=t.createElementNS(c.namespaceURI,c.nodeName),m.appendChild(w),f[c.nodeName]=x(z.getComputedStyle(w,null)),m.removeChild(w));
26 | if(N||M)for(var y in h)q(h[y],y);else F(h,q);p&&(h=c.getAttribute("style"),c.setAttribute("style",(h?h+";":"")+p));"svg"===c.nodeName&&c.setAttribute("stroke-width","1px");"text"!==c.nodeName&&k(c.children||c.childNodes,b)}}var c=this.renderer,d=c.inlineToAttributes,v=c.inlineBlacklist,l=c.inlineWhitelist,g=c.unstyledElements,f={},m;b(this.container.querySelector("svg"));m.parentNode.removeChild(m)};L.menu=function(a,b,c,d){return["M",a,b+2.5,"L",a+c,b+2.5,"M",a,b+d/2+.5,"L",a+c,b+d/2+.5,"M",a,b+
27 | d-1.5,"L",a+c,b+d-1.5]};B.prototype.renderExporting=function(){var a=this,b=a.options.exporting,c=b.buttons,d=a.isDirtyExporting||!a.exportSVGElements;a.buttonOffset=0;a.isDirtyExporting&&a.destroyExport();d&&!1!==b.enabled&&(a.exportEvents=[],F(c,function(b){a.addButton(b)}),a.isDirtyExporting=!1);u(a,"destroy",a.destroyExport)};B.prototype.callbacks.push(function(a){a.renderExporting();u(a,"redraw",a.renderExporting);k(["exporting","navigation"],function(b){a[b]={update:function(c,d){a.isDirtyExporting=
28 | !0;x(!0,a.options[b],c);E(d,!0)&&a.redraw()}}})})})(p)});
29 |
--------------------------------------------------------------------------------
/tradeBOT/models.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth.models import User
2 | from django.db import models
3 | from trade.models import Exchanges, UserExchange
4 |
5 |
6 | # Create your models here.
7 | class ExchangeCoin(models.Model):
8 | exchange = models.ForeignKey(Exchanges)
9 | symbol = models.CharField(max_length=10)
10 | rank = models.IntegerField(default=0)
11 |
12 | def __str__(self):
13 | return self.exchange.name + ' ' + self.symbol
14 |
15 | class Meta:
16 | verbose_name = "Монета биржи"
17 | verbose_name_plural = "Монеты биржи"
18 |
19 |
20 | class UserPair(models.Model):
21 | user = models.ForeignKey(User)
22 | user_exchange = models.ForeignKey(UserExchange)
23 | pair = models.ForeignKey('Pair')
24 | rank = models.PositiveIntegerField(default=1)
25 | rate_of_change = models.DecimalField(max_digits=20, decimal_places=8, default=0)
26 |
27 | class Meta:
28 | verbose_name = "Пара пользователя"
29 | verbose_name_plural = "Пары пользователей"
30 |
31 | def __str__(self):
32 | return str(
33 | self.user_exchange) + ': ' + self.pair.main_coin.symbol.upper() + '_' + self.pair.second_coin.symbol.upper()
34 |
35 |
36 | class UserCoinShare(models.Model):
37 | user_exchange = models.ForeignKey(UserExchange)
38 | coin = models.ForeignKey(ExchangeCoin)
39 | share = models.DecimalField(decimal_places=2, max_digits=5, default=0)
40 |
41 | def __str__(self):
42 | return self.user_exchange.exchange.name + ': ' + self.coin.symbol + ' ' + str(self.share)
43 |
44 | class Meta:
45 | verbose_name = 'Доля валюты'
46 | verbose_name_plural = 'Доли валют'
47 |
48 |
49 | class ExchangeMainCoin(models.Model):
50 | coin = models.ForeignKey(ExchangeCoin)
51 |
52 | def __str__(self):
53 | return self.coin.exchange.name + ': ' + self.coin.symbol
54 |
55 | class Meta:
56 | verbose_name = "Главная монета биржи"
57 | verbose_name_plural = "Главные монеты биржи"
58 |
59 |
60 | class Pair(models.Model):
61 | main_coin = models.ForeignKey(ExchangeCoin, related_name='%(class)s_main_coin')
62 | second_coin = models.ForeignKey(ExchangeCoin, related_name='%(class)s_second_coin')
63 | is_active = models.BooleanField(default=True)
64 |
65 | def __str__(self):
66 | return self.main_coin.exchange.name + ': ' + self.main_coin.symbol.upper() + '_' + \
67 | self.second_coin.symbol.upper()
68 |
69 | class Meta:
70 | verbose_name = "Пара"
71 | verbose_name_plural = "Пары"
72 |
73 |
74 | class UserMainCoinPriority(models.Model):
75 | user_exchange = models.ForeignKey(UserExchange)
76 | main_coin = models.ForeignKey(ExchangeMainCoin)
77 | priority = models.PositiveIntegerField()
78 | is_active = models.BooleanField()
79 |
80 | def __str__(self):
81 | return '%s %s' % (self.user_exchange.exchange.name, self.main_coin)
82 |
83 | class Meta:
84 | verbose_name_plural = 'Главные монеты пользователей'
85 | verbose_name = 'Главная монета пользователя'
86 |
87 |
88 | class CoinMarketCupCoin(models.Model):
89 | coin_market_id = models.CharField(max_length=63, verbose_name="Внутренее имя", default='')
90 | name = models.CharField(max_length=63, verbose_name="Имя")
91 | symbol = models.CharField(max_length=15, verbose_name="Аббр")
92 | rank = models.PositiveIntegerField()
93 | price_usd = models.DecimalField(decimal_places=8, max_digits=30, verbose_name="Цена в USD")
94 | volume_usd_24h = models.DecimalField(decimal_places=8, max_digits=30, null=True)
95 | available_supply = models.DecimalField(decimal_places=8, max_digits=30, null=True)
96 | total_supply = models.DecimalField(decimal_places=8, max_digits=30, null=True)
97 |
98 | class Meta:
99 | verbose_name = 'Монета CoinMarketCup'
100 | verbose_name_plural = 'Монеты CoinMarketCup'
101 |
102 | def __str__(self):
103 | return self.name + ' ' + self.symbol
104 |
105 |
106 | class Order(models.Model):
107 | ue = models.ForeignKey(UserExchange)
108 | pair = models.CharField(max_length=50)
109 | globalTradeID = models.BigIntegerField()
110 | tradeID = models.BigIntegerField()
111 | orderNumber = models.BigIntegerField()
112 | category = models.CharField(max_length=50)
113 | type = models.CharField(max_length=10)
114 | amount = models.DecimalField(max_digits=20, decimal_places=8)
115 | rate = models.DecimalField(max_digits=20, decimal_places=8)
116 | fee = models.DecimalField(max_digits=10, decimal_places=8)
117 | total = models.DecimalField(max_digits=20, decimal_places=8)
118 | our_total = models.DecimalField(max_digits=20, decimal_places=8)
119 | is_ok = models.CharField(max_length=5)
120 | date_time = models.DateTimeField()
121 |
122 |
123 | class UserOrder(models.Model):
124 | ue = models.ForeignKey(UserExchange)
125 | pair = models.ForeignKey(Pair)
126 | order_type = models.CharField(max_length=5)
127 | order_number = models.BigIntegerField()
128 | main_coin_before_total = models.DecimalField(max_digits=20, decimal_places=10)
129 | main_coin_before_free = models.DecimalField(max_digits=20, decimal_places=10)
130 | main_coin_before_used = models.DecimalField(max_digits=20, decimal_places=10)
131 | second_coin_before_total = models.DecimalField(max_digits=20, decimal_places=10)
132 | second_coin_before_free = models.DecimalField(max_digits=20, decimal_places=10)
133 | second_coin_before_used = models.DecimalField(max_digits=20, decimal_places=10)
134 | main_coin_after_total = models.DecimalField(max_digits=20, decimal_places=10, default=None, blank=True, null=True)
135 | main_coin_after_free = models.DecimalField(max_digits=20, decimal_places=10, default=None, blank=True, null=True)
136 | main_coin_after_used = models.DecimalField(max_digits=20, decimal_places=10, default=None, blank=True, null=True)
137 | second_coin_after_total = models.DecimalField(max_digits=20, decimal_places=10, default=None, blank=True, null=True)
138 | second_coin_after_free = models.DecimalField(max_digits=20, decimal_places=10, default=None, blank=True, null=True)
139 | second_coin_after_used = models.DecimalField(max_digits=20, decimal_places=10, default=None, blank=True, null=True)
140 | price = models.DecimalField(max_digits=20, decimal_places=10)
141 | amount = models.DecimalField(max_digits=20, decimal_places=10)
142 | total = models.DecimalField(max_digits=20, decimal_places=10)
143 | fee = models.DecimalField(max_digits=8, decimal_places=5)
144 | fact_total = models.DecimalField(max_digits=20, decimal_places=10, default=None, blank=True, null=True)
145 | fact_fee = models.DecimalField(max_digits=7, decimal_places=5, default=None, blank=True, null=True)
146 | is_ok = models.NullBooleanField(default=None, blank=True, null=True)
147 | interim_main_coin = models.DecimalField(max_digits=20, decimal_places=10)
148 | date_created = models.DateTimeField(auto_now_add=True)
149 | date_cancel = models.DateTimeField(default=None, blank=True, null=True)
150 | cancel_desc = models.CharField(max_length=100, blank=True, null=True, default=None)
151 | date_updated = models.DateTimeField(auto_now=True)
152 | to_close = models.BooleanField(default=False)
153 |
154 | def __str__(self):
155 | return self.ue.user.username + ' ' + self.ue.exchange.name + ': ' + self.order_type + ' ' + self.pair.main_coin.symbol.upper() + '_' + self.pair.second_coin.symbol.upper()
156 |
157 | class Meta:
158 | verbose_name_plural = 'Ордера пользователей'
159 | verbose_name = 'Ордер пользователя'
160 | ordering = ('date_created',)
161 |
162 |
163 | class ToTrade(models.Model):
164 | user_pair = models.ForeignKey(UserPair, blank=False, null=False)
165 | type = models.CharField(max_length=10, blank=False, null=False)
166 | price = models.DecimalField(max_digits=16, decimal_places=8, blank=False, null=False)
167 | amount = models.DecimalField(max_digits=16, decimal_places=8, blank=False, null=False)
168 | total = models.DecimalField(max_digits=16, decimal_places=8, blank=False, null=False)
169 | total_f = models.DecimalField(max_digits=16, decimal_places=8, blank=False, null=False, default=0)
170 | fee = models.DecimalField(max_digits=16, decimal_places=8, blank=False, null=False)
171 | cause = models.CharField(max_length=255)
172 | date_created = models.DateTimeField(auto_now_add=True)
173 | date_updated = models.DateTimeField(auto_now=True)
174 |
175 | def __str__(self):
176 | return str(self.user_pair.pair) + ' ' + self.type
177 |
178 | class Meta:
179 | verbose_name = 'Пара готовая к торговле'
180 | verbose_name_plural = 'Пары готовые к торговле'
181 |
182 |
183 | class Сalculations(models.Model):
184 | user_pair = models.ForeignKey(UserPair)
185 | type = models.CharField(max_length=10)
186 | depth_coef = models.DecimalField(max_digits=16, decimal_places=8, blank=False, null=False)
187 | price = models.DecimalField(max_digits=16, decimal_places=8, blank=False, null=False)
188 | amount = models.DecimalField(max_digits=16, decimal_places=8, blank=False, null=False)
189 | bids = models.TextField(blank=True, null=True)
190 | asks = models.TextField(blank=True, null=True)
191 | date_created = models.DateTimeField(auto_now=True)
192 |
193 |
194 | class Extremum(models.Model):
195 | pair = models.ForeignKey(Pair)
196 | ext_type = models.CharField(max_length=10)
197 | price = models.DecimalField(max_digits=20, decimal_places=10)
198 | date = models.DateTimeField(auto_now=True)
199 |
200 | class Meta:
201 | verbose_name = 'Экстремум'
202 | verbose_name_plural = 'Экстремумы'
203 |
204 | def __str__(self):
205 | return self.pair.main_coin.symbol.upper() + '_' + self.pair.second_coin.symbol.upper() + ' ' + self.ext_type + ': ' + str(
206 | self.date)
207 |
--------------------------------------------------------------------------------
/tradeBOT/views.py:
--------------------------------------------------------------------------------
1 | from django.contrib.auth.decorators import login_required
2 | from django.db.models import Sum, Max, Min
3 | from django.http import HttpResponse
4 | from django.shortcuts import render, redirect
5 | from trade.models import UserExchange, Exchanges
6 | from tradeBOT.models import ExchangeCoin, Pair, ExchangeMainCoin, UserMainCoinPriority, UserPair, ToTrade, \
7 | UserCoinShare, UserOrder
8 |
9 |
10 | @login_required
11 | def setup(request, pk):
12 | args = {}
13 | try:
14 | args['user_exchange'] = UserExchange.objects.get(pk=pk)
15 | # args['user_exchange'] = UserExchange.objects.get(pk=pk, user=request.user)
16 | # args['user_pairs'] = UserPair.objects.filter(user=request.user,
17 | # user_exchange=args['user_exchange']).order_by(
18 | # '-rank')
19 | args['user_pairs'] = UserPair.objects.filter(user_exchange=args['user_exchange']).order_by(
20 | '-rank')
21 | args['primary_coins'] = ExchangeMainCoin.objects.filter(coin__exchange=args['user_exchange'].exchange).order_by(
22 | 'coin__symbol')
23 | args['to_trade'] = ToTrade.objects.filter(user_pair__user_exchange=args['user_exchange']).order_by(
24 | 'date_updated')
25 | args['orders'] = UserOrder.objects.filter(ue=args['user_exchange'])
26 | args['user_coins'] = UserCoinShare.objects.filter(user_exchange=args['user_exchange'])
27 | except UserExchange.DoesNotExist:
28 | return redirect('index')
29 | return render(request, 'tradeBOT/setup.html', args)
30 |
31 |
32 | def add_user_pair(request):
33 | if request.method == 'POST':
34 | pair_pk = request.POST.get('pair')
35 | user_exchange_pk = request.POST.get('user-exchange')
36 | try:
37 | pair = Pair.objects.get(pk=pair_pk)
38 | UserPair.objects.get_or_create(user=request.user, pair=pair, user_exchange_id=user_exchange_pk)
39 | UserCoinShare.objects.get_or_create(user_exchange_id=user_exchange_pk, coin=pair.second_coin)
40 | except Pair.DoesNotExist:
41 | pass
42 | return redirect('/trade/setup/' + str(user_exchange_pk) + '/')
43 |
44 |
45 | def change_rank(request):
46 | if request.is_ajax():
47 | pair_id = request.POST.get('pair_id')
48 | type_c = request.POST.get('type')
49 | try:
50 | user_pair = UserPair.objects.get(pk=pair_id, user=request.user)
51 | if type_c == 'up':
52 | user_pair.rank = user_pair.rank + 1
53 | user_pair.save()
54 | elif type_c == 'down':
55 | if user_pair.rank > 1:
56 | user_pair.rank = user_pair.rank - 1
57 | user_pair.save()
58 | except UserPair.DoesNotExist:
59 | return HttpResponse('false', status=200)
60 | return HttpResponse('ok', status=200)
61 |
62 |
63 | def set_share(request):
64 | user_coin_id = request.POST.get('coin')
65 | share = request.POST.get('share')
66 | user_exchange_pk = request.POST.get('user-exchange')
67 | if float(share) < 0:
68 | return HttpResponse('Invalid request', status=200)
69 | if float(share) == 0:
70 | try:
71 | user_coin = UserCoinShare.objects.get(pk=user_coin_id, user_exchange_id=user_exchange_pk,
72 | user_exchange__user=request.user)
73 | user_coin.share = 0
74 | user_coin.save()
75 | except UserCoinShare.DoesNotExist:
76 | return HttpResponse('Not your coin', status=200)
77 | return HttpResponse('ok', status=200)
78 | user_coin_share_summ = \
79 | UserCoinShare.objects.filter(user_exchange__user=request.user, user_exchange_id=user_exchange_pk).exclude(
80 | pk=user_coin_id).aggregate(
81 | Sum('share'))['share__sum']
82 | if user_coin_share_summ is None:
83 | user_coin_share_summ = 0
84 | if float(user_coin_share_summ) + float(share) > 100:
85 | return HttpResponse('Sum shares cant be more than 100', status=200)
86 | try:
87 | user_coin = UserCoinShare.objects.get(pk=user_coin_id, user_exchange__user=request.user)
88 | user_coin.share = share
89 | user_coin.save()
90 | except UserCoinShare.DoesNotExist:
91 | return HttpResponse('Not your coin', status=200)
92 | return redirect('/trade/setup/' + str(user_exchange_pk) + '/')
93 |
94 |
95 | def delete_user_pair(request):
96 | if request.is_ajax():
97 | user_pair_id = request.POST.get('pair_id')
98 | try:
99 | user_pair = UserPair.objects.get(pk=user_pair_id, user=request.user)
100 | user_pairs_with_this_coin = UserPair.objects.filter(pair__second_coin=user_pair.pair.second_coin)
101 | if len(user_pairs_with_this_coin) == 1:
102 | UserCoinShare.objects.get(coin=user_pair.pair.second_coin,
103 | user_exchange=user_pair.user_exchange).delete()
104 | user_pair.delete()
105 | except UserPair.DoesNotExist:
106 | return HttpResponse('Not your pair', status=200)
107 | return HttpResponse('ok', status=200)
108 |
109 |
110 | def relations(request):
111 | args = {'exchanges': Exchanges.objects.all()}
112 | return render(request, 'tradeBOT/relations.html', args)
113 |
114 |
115 | def change_user_exchange_script_activity(request):
116 | if request.is_ajax():
117 | user_exch_id = request.POST.get('user_exch')
118 | try:
119 | user_exch = UserExchange.objects.get(pk=user_exch_id, user=request.user)
120 | user_exch.is_active_script = not user_exch.is_active_script
121 | user_exch.save()
122 | return HttpResponse('true', status=200)
123 | except UserExchange.DoesNotExist:
124 | return HttpResponse('false', status=200)
125 |
126 |
127 | def change_primary_coin(request):
128 | if request.is_ajax():
129 | user_exch_pk = request.POST.get('user_exch')
130 | ue = UserExchange.objects.get(pk=user_exch_pk)
131 | coin_pk = request.POST.get('coin')
132 | coin = ExchangeMainCoin.objects.get(pk=coin_pk)
133 | try:
134 | user_primary_coin = UserMainCoinPriority.objects.get(user_exchange=ue, main_coin=coin)
135 | user_primary_coin.is_active = not user_primary_coin.is_active
136 | user_primary_coin.save()
137 | except UserMainCoinPriority.DoesNotExist:
138 | new_user_primary_coin = UserMainCoinPriority()
139 | new_user_primary_coin.main_coin = coin
140 | new_user_primary_coin.priority = 1
141 | new_user_primary_coin.user_exchange = ue
142 | new_user_primary_coin.is_active = False
143 | new_user_primary_coin.save()
144 | return HttpResponse('ok', status=200)
145 |
146 |
147 | def change_primary_coin_rank(request):
148 | if request.is_ajax():
149 | type_r = request.POST.get('type')
150 | ue_pk = request.POST.get('user_exch')
151 | coin_pk = request.POST.get('coin')
152 | ue = UserExchange.objects.get(pk=ue_pk)
153 | coin = ExchangeMainCoin.objects.get(pk=coin_pk)
154 | try:
155 | user_primary_coin = UserMainCoinPriority.objects.get(user_exchange=ue, main_coin=coin)
156 | if type_r == 'up':
157 | user_primary_coin.priority += 1
158 | elif type_r == 'down':
159 | if user_primary_coin.priority > 1:
160 | user_primary_coin.priority -= 1
161 | user_primary_coin.save()
162 | except UserMainCoinPriority.DoesNotExist:
163 | new_user_primary_coin = UserMainCoinPriority()
164 | new_user_primary_coin.main_coin = coin
165 | if type_r == 'up':
166 | new_user_primary_coin.priority = 2
167 | else:
168 | new_user_primary_coin.priority = 1
169 | new_user_primary_coin.user_exchange = ue
170 | new_user_primary_coin.is_active = True
171 | new_user_primary_coin.save()
172 | return HttpResponse('ok', status=200)
173 |
174 |
175 | def set_pair_add(request):
176 | if request.method == 'POST':
177 | pair_pk = request.POST.get('pair-pk')
178 | user_exchange_pk = request.POST.get('user-exchange-pk')
179 | rate_of_change = request.POST.get('rate_of_change')
180 | if rate_of_change == '':
181 | rate_of_change = 0
182 | try:
183 | UserPair.objects.filter(pk=pair_pk, user_exchange_id=user_exchange_pk).update(
184 | rate_of_change=rate_of_change)
185 | except UserPair.DoesNotExist:
186 | pass
187 | return redirect('/trade/setup/' + str(user_exchange_pk) + '/')
188 | else:
189 | return redirect('/')
190 |
191 |
192 | def get_new_to_trade(request):
193 | if request.is_ajax():
194 | ue_pk = request.POST.get('user_exch')
195 | already = request.POST.get('already')
196 | to_trade = ToTrade.objects.filter(user_pair__user_exchange_id=ue_pk)
197 | if len(to_trade) != int(already):
198 | return render(request, 'tradeBOT/to_trade.html', {'to_trade': to_trade})
199 | else:
200 | return HttpResponse('ok', status=200)
201 |
202 |
203 | def exchange_depth_to_trade(request):
204 | if request.method == 'POST':
205 | depth = request.POST.get('depth')
206 | exchange_pk = request.POST.get('user-exchange-pk')
207 | if depth == '':
208 | depth = 0
209 | try:
210 | ue = UserExchange.objects.get(user=request.user, pk=exchange_pk)
211 | ue.coefficient_of_depth = depth
212 | ue.save()
213 | except UserExchange.DoesNotExist:
214 | pass
215 | return redirect('/trade/setup/' + str(exchange_pk) + '/')
216 | else:
217 | return HttpResponse('Please use POST request', status=200)
218 |
--------------------------------------------------------------------------------