Skip to content

Commit

Permalink
Added trades view.
Browse files Browse the repository at this point in the history
  • Loading branch information
pnapoliJC committed Nov 19, 2020
1 parent b2fe4d3 commit 22ce6a4
Show file tree
Hide file tree
Showing 15 changed files with 234 additions and 17 deletions.
14 changes: 7 additions & 7 deletions web/api/assets/static/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
{
"files": {
"main.css": "/static/css/main.a749edfd.chunk.css",
"main.js": "/static/js/main.1f9d452c.chunk.js",
"main.js.map": "/static/js/main.1f9d452c.chunk.js.map",
"main.js": "/static/js/main.d98f7b8c.chunk.js",
"main.js.map": "/static/js/main.d98f7b8c.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.fb2d4e2c.js",
"runtime-main.js.map": "/static/js/runtime-main.fb2d4e2c.js.map",
"static/css/2.2881e0a5.chunk.css": "/static/css/2.2881e0a5.chunk.css",
"static/js/2.d6d8597c.chunk.js": "/static/js/2.d6d8597c.chunk.js",
"static/js/2.d6d8597c.chunk.js.map": "/static/js/2.d6d8597c.chunk.js.map",
"static/js/2.a17c4a6a.chunk.js": "/static/js/2.a17c4a6a.chunk.js",
"static/js/2.a17c4a6a.chunk.js.map": "/static/js/2.a17c4a6a.chunk.js.map",
"index.html": "/index.html",
"static/css/2.2881e0a5.chunk.css.map": "/static/css/2.2881e0a5.chunk.css.map",
"static/css/main.a749edfd.chunk.css.map": "/static/css/main.a749edfd.chunk.css.map",
"static/js/2.d6d8597c.chunk.js.LICENSE.txt": "/static/js/2.d6d8597c.chunk.js.LICENSE.txt",
"static/js/2.a17c4a6a.chunk.js.LICENSE.txt": "/static/js/2.a17c4a6a.chunk.js.LICENSE.txt",
"static/media/App.css": "/static/media/RobotoMono.31332165.ttf",
"static/media/semantic.less": "/static/media/outline-icons.ddae9b1b.woff"
},
"entrypoints": [
"static/js/runtime-main.fb2d4e2c.js",
"static/css/2.2881e0a5.chunk.css",
"static/js/2.d6d8597c.chunk.js",
"static/js/2.a17c4a6a.chunk.js",
"static/css/main.a749edfd.chunk.css",
"static/js/main.1f9d452c.chunk.js"
"static/js/main.d98f7b8c.chunk.js"
]
}
2 changes: 1 addition & 1 deletion web/api/assets/static/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="DTS Dashboard"/><title>Olympus - Dashboard</title><link href="/static/css/2.2881e0a5.chunk.css" rel="stylesheet"><link href="/static/css/main.a749edfd.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,a,l=r[0],f=r[1],i=r[2],c=0,s=[];c<l.length;c++)a=l[c],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var f=t[l];0!==o[f]&&(n=!1)}n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={1:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,function(r){return e[r]}.bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="/";var l=this.webpackJsonpdashboard=this.webpackJsonpdashboard||[],f=l.push.bind(l);l.push=r,l=l.slice();for(var i=0;i<l.length;i++)r(l[i]);var p=f;t()}([])</script><script src="/static/js/2.d6d8597c.chunk.js"></script><script src="/static/js/main.1f9d452c.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="DTS Dashboard"/><title>Olympus - Dashboard</title><link href="/static/css/2.2881e0a5.chunk.css" rel="stylesheet"><link href="/static/css/main.a749edfd.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,a,l=r[0],f=r[1],i=r[2],c=0,s=[];c<l.length;c++)a=l[c],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in f)Object.prototype.hasOwnProperty.call(f,n)&&(e[n]=f[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,i||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var f=t[l];0!==o[f]&&(n=!1)}n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={1:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,function(r){return e[r]}.bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="/";var l=this.webpackJsonpdashboard=this.webpackJsonpdashboard||[],f=l.push.bind(l);l.push=r,l=l.slice();for(var i=0;i<l.length;i++)r(l[i]);var p=f;t()}([])</script><script src="/static/js/2.a17c4a6a.chunk.js"></script><script src="/static/js/main.d98f7b8c.chunk.js"></script></body></html>
3 changes: 3 additions & 0 deletions web/api/assets/static/static/js/2.a17c4a6a.chunk.js

Large diffs are not rendered by default.

90 changes: 90 additions & 0 deletions web/api/assets/static/static/js/2.a17c4a6a.chunk.js.LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/

/*
object-assign
(c) Sindre Sorhus
@license MIT
*/

/*!
Copyright (c) 2015 Jed Watson.
Based on code that is Copyright 2013-2015, Facebook, Inc.
All rights reserved.
*/

/*!
Copyright (c) 2017 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/

/*! Moment Duration Format v2.2.2
* https://github.com/jsmreese/moment-duration-format
* Date: 2018-02-16
*
* Duration format plugin function for the Moment.js library
* http://momentjs.com/
*
* Copyright 2018 John Madhavan-Reese
* Released under the MIT license
*/

/** @license React v0.19.1
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v16.13.1
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v16.13.1
* react-is.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v16.13.1
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v16.2.0
* react.development.js
*
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

/** @license React v16.2.0
* react.production.min.js
*
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

//! moment.js
1 change: 1 addition & 0 deletions web/api/assets/static/static/js/2.a17c4a6a.chunk.js.map

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions web/api/assets/static/static/js/main.4ad813dc.chunk.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions web/api/assets/static/static/js/main.4ad813dc.chunk.js.map

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions web/api/assets/static/static/js/main.d98f7b8c.chunk.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions web/api/assets/static/static/js/main.d98f7b8c.chunk.js.map

Large diffs are not rendered by default.

26 changes: 18 additions & 8 deletions web/api/bot/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type Trade struct {
ID string `json:"id,omitempty"`
BinanceID string `json:"binance_id"`
BotID string `json:"bot_id"`
UserID int `json:"user_id"`
Time int64 `json:"time"`
Amount float32 `json:"amount"`
Action string `json:"signal"`
Expand Down Expand Up @@ -94,6 +95,15 @@ func Update(config *Config, key string, secret string, services *services.Servic
quantity = float32(math.Min(float64(totalPortfolioBtc * config.PortfolioRatio), float64(p["btc"].FreeFloat)))
}

_, err = r.Table("trades").Insert(Trade{
BinanceID: "",
BotID: config.ID,
UserID: 1,
Time: utils.Millis(),
Amount: quantity,
Action: side,
}).Run(services.DB)

if quantity < 0.00063 {
return []byte("quantity does not meet minimum BTC order"), errors.New("quantity does not meet minimum BTC order")
}
Expand All @@ -103,18 +113,18 @@ func Update(config *Config, key string, secret string, services *services.Servic
hmac := security.NewHMAC(params, secret)

resp = services.NewRequest("POST",
"https://api.binance.com/api/v3/order",
"https://api.binance.com/api/v3/order/test",
map[string]string{"X-MBX-APIKEY": key},
fmt.Sprintf("%s&signature=%s", params, hmac))

if resp != nil {
r.Table("trades").Insert(Trade{
BinanceID: "",
BotID: config.ID,
Time: utils.Millis(),
Amount: quantity,
Action: side,
})
//r.Table("trades").Insert(Trade{
// BinanceID: "",
// BotID: config.ID,
// Time: utils.Millis(),
// Amount: quantity,
// Action: side,
//})
}

return nil, errors.New("binance error: " + string(resp))
Expand Down
13 changes: 13 additions & 0 deletions web/api/server/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,19 @@ func GetPortfolio(ctx *fasthttp.RequestCtx, ps fasthttprouter.Params, services *
utils.JSON(ctx, p)
}

func GetTrades(ctx *fasthttp.RequestCtx, ps fasthttprouter.Params, services *services.Services) {
c, err := r.Table("trades").Filter(map[string]interface{}{"user_id": 1}).Run(services.DB)
if handleErr(ctx, err) {
return
}
defer c.Close()

var trades []bot.Trade
c.All(&trades)

utils.JSON(ctx, trades)
}

func CreateBot(ctx *fasthttp.RequestCtx, ps fasthttprouter.Params, services *services.Services) {
var b bot.Config
utils.FromJSON(ctx.Request.Body(), &b)
Expand Down
1 change: 1 addition & 0 deletions web/api/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ func (s *Server) Start() {
r.GET("/api/bot/all", s.chain(GetBots))

r.GET("/api/user/portfolio", s.chain(GetPortfolio))
r.GET("/api/user/trades", s.chain(GetTrades))
r.GET("/api/user", s.chain(GetUser))
r.OPTIONS("/api/user", s.chain(Empty))

Expand Down
3 changes: 2 additions & 1 deletion web/dashboard/src/reducers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ function getDefaultState(section) {
const stateAwareComponents = [
'site',
'home',
'profile'
'profile',
'history'
]

function getInitialState() {
Expand Down
2 changes: 2 additions & 0 deletions web/dashboard/src/routes.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Home from "./views/Home"
import History from "./views/History"
import Profile from "./views/Profile";

class Route {
Expand All @@ -14,6 +15,7 @@ class Route {

export const routes = [
new Route("/trading", "/trading", "Trading", "home", true, Home),
new Route("/history", "/history", "History", "history", true, History),
new Route("/profile", "/profile", "Profile", "user", true, Profile),
];

Expand Down
90 changes: 90 additions & 0 deletions web/dashboard/src/views/History.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React from 'react'
import { connect } from "react-redux";

import SmartView, { mapDispatchToProps } from "./SmartView";

import DataTable from '../components/DataTable';
import { Icon, Card, Label, Grid } from 'semantic-ui-react'
import { withToastManager } from 'react-toast-notifications';

import Moment from 'react-moment';

const columns = [
{
columns: [
{
Header: <span><Icon name="clock"/>Time</span>,
accessor: "time",
Cell: row =>
<Label style={{minWidth:50}} as='a' color='teal' image>
<Moment unix format="DD/MM/YYYY HH:mm:ss">{row.value / 1000}</Moment>
</Label>
},
{
Header: <span><Icon name="signal"/>Amount</span>,
accessor: 'amount',
Cell: row =>
<Label style={{minWidth:50}} color={"blue"}>
<Icon name="bitcoin"/>
{row.value.toFixed(10)}
</Label>
},
{
Header: <span><Icon name="chart bar"/>Signal</span>,
accessor: "signal",
Cell: row => {
let color = "green";
if (row.value === "SELL") {
color = "red";
}
return (
<Label style={{minWidth:50}} color={color}>
{row.value}
</Label>
);
}
}
]
}
]

export class History extends SmartView {
fetch() {
this.props.getData({
url: "/api/user/trades",
respKey: "history",
}, "history");
}

renderContent() {
if (!this.props.state.data.history) {
return <></>
}

return (
<Grid>

<Grid.Row centered>
<Card style={{padding: 40, minWidth: 800}}>
<h3>Past Trades</h3>
<DataTable
rowIdentifier={"id"}
windowWidth={this.props.siteState.windowWidth}
edit={false}
data={this.props.state ? this.props.state.data.history || [] : []}
columns={columns} />
</Card>
</Grid.Row>
</Grid>
)
}
}

function mapStateToProps(state) {
return {
state: state.base.history,
siteState: state.base.site
};
}

export default connect(mapStateToProps, mapDispatchToProps)(withToastManager(History));

0 comments on commit 22ce6a4

Please sign in to comment.