tailwind #9
18
main.py
18
main.py
@ -487,6 +487,7 @@
|
||||
import asyncio
|
||||
import os
|
||||
import threading
|
||||
from typing import List
|
||||
|
||||
import dotenv
|
||||
from flask import Flask, render_template
|
||||
@ -494,7 +495,7 @@ from flask_socketio import SocketIO
|
||||
|
||||
from bfxbot import BfxBot
|
||||
from bfxbot.currency import Symbol
|
||||
from bfxbot.models import SymbolStatus, Event, EventKind
|
||||
from bfxbot.models import PositionWrapper, SymbolStatus, Event, EventKind
|
||||
from strategy import TrailingStopStrategy
|
||||
|
||||
app = Flask(__name__)
|
||||
@ -548,7 +549,8 @@ def start_bot():
|
||||
API_SECRET = os.getenv("API_SECRET")
|
||||
|
||||
if not bot:
|
||||
bot = BfxBot(api_key=API_KEY, api_secret=API_SECRET, symbols=[Symbol.BTC], tick_duration=1)
|
||||
bot = BfxBot(api_key=API_KEY, api_secret=API_SECRET,
|
||||
symbols=[Symbol.BTC], tick_duration=20)
|
||||
strategy = TrailingStopStrategy()
|
||||
bot.set_strategy(Symbol.BTC, strategy)
|
||||
|
||||
@ -567,7 +569,17 @@ async def bot_loop():
|
||||
|
||||
@eh.on_event(EventKind.NEW_TICK)
|
||||
def on_new_tick(event: Event, status: SymbolStatus):
|
||||
socketio.emit("new_tick", {"tick": event.tick, "price": status.prices[event.tick]})
|
||||
tick = event.tick
|
||||
price = status.prices[event.tick]
|
||||
positions: List[PositionWrapper] = status.positions[event.tick] if event.tick in status.positions else []
|
||||
|
||||
# wrapping into json
|
||||
positions = list(map(lambda x: {"id": x.position.id, "symbol": x.position.symbol, "profit_loss": x.position.profit_loss,
|
||||
"profit_loss_percentage": x.position.profit_loss_percentage}, positions))
|
||||
|
||||
socketio.emit("new_tick", {"tick": tick,
|
||||
"price": price,
|
||||
"positions": positions})
|
||||
|
||||
await bot.start()
|
||||
|
||||
|
@ -1,17 +1,18 @@
|
||||
import React, { Component } from "react";
|
||||
import { Col, Container, Nav, Navbar, Row } from "react-bootstrap";
|
||||
import Plot from "react-plotly.js";
|
||||
import HCard from "./HCard";
|
||||
import RPlot from "./RPlot";
|
||||
import { RToast } from "./RToast";
|
||||
import { NewTickData, socket } from "../";
|
||||
import { NewTickData, PositionState, socket } from "../";
|
||||
import { PositionTable } from "./Tables";
|
||||
|
||||
type AppState = {
|
||||
current_price: number,
|
||||
current_tick: number,
|
||||
last_update: Date
|
||||
last_update: Date,
|
||||
positions: Array<PositionState>
|
||||
}
|
||||
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
@ -20,12 +21,18 @@ class App extends Component {
|
||||
state = {
|
||||
current_price: 0,
|
||||
current_tick: 0,
|
||||
last_update: new Date()
|
||||
last_update: new Date(),
|
||||
positions: []
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
socket.on("new_tick", (data: NewTickData) => {
|
||||
this.setState({ current_price: data.price, current_tick: data.tick, last_update: new Date() })
|
||||
this.setState({
|
||||
current_price: data.price,
|
||||
current_tick: data.tick,
|
||||
last_update: new Date(),
|
||||
positions: data.positions
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -44,6 +51,9 @@ class App extends Component {
|
||||
<HCard title="Current tick:" content={String(this.state.current_tick)} update={this.state.last_update}></HCard>
|
||||
<HCard title="Current price:" content={String(this.state.current_price)} update={this.state.last_update}></HCard>
|
||||
</Row>
|
||||
<Row>
|
||||
<PositionTable />
|
||||
</Row>
|
||||
</Col>
|
||||
|
||||
{/* Graph column */}
|
||||
|
57
websrc/components/Tables.tsx
Normal file
57
websrc/components/Tables.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import React from "react"
|
||||
import { Component } from "react"
|
||||
import { Container, Table } from "react-bootstrap"
|
||||
import { NewTickData, PositionState, socket } from '../';
|
||||
|
||||
|
||||
export class PositionTable extends Component<{}, { positions: Array<PositionState> }> {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
state = {
|
||||
positions: []
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
socket.on('new_tick', (data: NewTickData) => {
|
||||
this.setState({
|
||||
positions: data.positions
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
tableData() {
|
||||
return this.state.positions.map((position: PositionState, idx) => {
|
||||
return (<tr key={position.id}>
|
||||
<th>{position.id}</th>
|
||||
<th>{position.symbol}</th>
|
||||
<th>{position.profit_loss}</th>
|
||||
<th>{position.profit_loss_percentage} %</th>
|
||||
</tr>)
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container className="d-flex flex-column mt-2">
|
||||
<div className="border-bottom">
|
||||
<h2>Open positions</h2>
|
||||
</div>
|
||||
<Table id="positions" size="sm" hover striped bordered className="mt-2 text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Symbol</th>
|
||||
<th>P/L</th>
|
||||
<th>P/L %</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{this.tableData()}
|
||||
</tbody>
|
||||
</Table>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
}
|
@ -8,7 +8,15 @@ export const socket = io();
|
||||
|
||||
export type NewTickData = {
|
||||
tick: number,
|
||||
price: number
|
||||
price: number,
|
||||
positions: Array<PositionState>
|
||||
}
|
||||
|
||||
export type PositionState = {
|
||||
id: number,
|
||||
symbol: string,
|
||||
profit_loss: number,
|
||||
profit_loss_percentage: number
|
||||
}
|
||||
|
||||
socket.on("connect", function () {
|
||||
|
Loading…
Reference in New Issue
Block a user