mirror of
https://git.wownero.com/lza_menace/totrader.git
synced 2024-08-15 00:33:13 +00:00
z
This commit is contained in:
parent
ee9d9f9283
commit
60a2998d80
7 changed files with 229 additions and 28 deletions
|
@ -8,10 +8,11 @@ def create_app():
|
|||
|
||||
@app.before_serving
|
||||
async def startup():
|
||||
from totrader.routes import meta, tasks
|
||||
from totrader.routes import meta, tasks, api
|
||||
from totrader import filters
|
||||
app.register_blueprint(meta.bp)
|
||||
app.register_blueprint(tasks.bp)
|
||||
app.register_blueprint(api.bp)
|
||||
app.register_blueprint(filters.bp)
|
||||
|
||||
return app
|
|
@ -51,6 +51,24 @@ class Order(Model):
|
|||
class Meta:
|
||||
database = db
|
||||
|
||||
class Trade(Model):
|
||||
trade_pair = CharField()
|
||||
trade_type = CharField()
|
||||
buy = BooleanField()
|
||||
quantity = DoubleField()
|
||||
price = DoubleField()
|
||||
date = DateTimeField()
|
||||
|
||||
class Meta:
|
||||
database = db
|
||||
|
||||
class BitcoinPrice(Model):
|
||||
price = DoubleField()
|
||||
date = DateTimeField(default=datetime.utcnow)
|
||||
|
||||
class Meta:
|
||||
database = db
|
||||
|
||||
class Earning(Model):
|
||||
trade_pair = CharField()
|
||||
quantity = DoubleField()
|
||||
|
@ -59,4 +77,4 @@ class Earning(Model):
|
|||
class Meta:
|
||||
database = db
|
||||
|
||||
db.create_tables([Ticker, Balance, Order, Earning])
|
||||
db.create_tables([Ticker, Balance, Order, Earning, Trade, BitcoinPrice])
|
||||
|
|
|
@ -1,13 +1,38 @@
|
|||
from quart import Blueprint, current_app
|
||||
from quart import Blueprint, current_app, jsonify
|
||||
|
||||
from totrader.models import *
|
||||
from totrader.tasks import trader
|
||||
|
||||
|
||||
bp = Blueprint('tasks', 'tasks', url_prefix='/api/tasks')
|
||||
bp = Blueprint('api', 'api', url_prefix='/api/v1')
|
||||
|
||||
|
||||
@bp.route('/store_ticker_data')
|
||||
async def store_ticker_data():
|
||||
current_app.add_background_task(trader.store_ticker_data)
|
||||
return '1'
|
||||
@bp.route('/get_ticker_data')
|
||||
async def get_ticker_data():
|
||||
ticker = Ticker.select().order_by(Ticker.date.desc()).limit(1).first()
|
||||
return jsonify({
|
||||
'price': ticker.current_price,
|
||||
'volume': ticker.volume,
|
||||
'bid': ticker.bid,
|
||||
'ask': ticker.ask,
|
||||
'spread_sats': ticker.spread_sats,
|
||||
'spread_btc': ticker.spread_btc,
|
||||
'spread_perc': ticker.spread_perc,
|
||||
'date': ticker.date
|
||||
})
|
||||
|
||||
@bp.route('/get_balances')
|
||||
async def get_balances():
|
||||
return jsonify({})
|
||||
|
||||
@bp.route('/get_bitcoin_price')
|
||||
async def get_bitcoin_price():
|
||||
return jsonify({})
|
||||
|
||||
@bp.route('/get_orders')
|
||||
async def get_orders():
|
||||
return jsonify({})
|
||||
|
||||
@bp.route('/get_trade_history')
|
||||
async def get_trade_history():
|
||||
return jsonify({})
|
||||
|
|
|
@ -10,4 +10,25 @@ bp = Blueprint('tasks', 'tasks', url_prefix='/api/tasks')
|
|||
@bp.route('/store_ticker_data')
|
||||
async def store_ticker_data():
|
||||
current_app.add_background_task(trader.store_ticker_data)
|
||||
return '1'
|
||||
return 'ok'
|
||||
|
||||
@bp.route('/store_balances')
|
||||
async def store_balances():
|
||||
current_app.add_background_task(trader.store_balances)
|
||||
return 'ok'
|
||||
|
||||
@bp.route('/store_orders')
|
||||
async def store_orders():
|
||||
current_app.add_background_task(trader.reconcile_orders)
|
||||
current_app.add_background_task(trader.update_orders)
|
||||
return 'ok'
|
||||
|
||||
@bp.route('/store_trade_history')
|
||||
async def store_trade_history():
|
||||
current_app.add_background_task(trader.update_trade_history)
|
||||
return 'ok'
|
||||
|
||||
@bp.route('/store_bitcoin_price')
|
||||
async def store_bitcoin_price():
|
||||
current_app.add_background_task(trader.update_bitcoin_price)
|
||||
return 'ok'
|
||||
|
|
|
@ -45,8 +45,76 @@ class Trader(TradeOgre):
|
|||
spread_perc=res['spread_perc']
|
||||
)
|
||||
t.save()
|
||||
logging.info(f'[MARKET] Stored market data as ID {t.id}')
|
||||
return True
|
||||
logging.info(f'[MARKET] Stored ticker data: {t.id}')
|
||||
|
||||
def store_balances(self):
|
||||
for currency in self.base_currency, self.trade_currency:
|
||||
logging.info(f'[BALANCE] Storing balances for currency {currency}')
|
||||
res = self.get_balance(currency)
|
||||
logging.debug(res)
|
||||
b = Balance(
|
||||
currency=currency,
|
||||
total=res['balance'],
|
||||
available=res['available']
|
||||
)
|
||||
b.save()
|
||||
logging.info(f'[BALANCE] Stored balances: {b.id}')
|
||||
|
||||
def get_active_orders(self):
|
||||
logging.info('[ORDERS] Getting active orders in local database')
|
||||
orders = Order.select().where(Order.active == True, Order.trade_pair == self.trade_pair)
|
||||
logging.debug(f'Found {len(orders)} in database')
|
||||
return orders
|
||||
|
||||
def reconcile_orders(self):
|
||||
logging.info('[ORDERS] Reconciling orders on TradeOgre with local database')
|
||||
to_orders = self.get_orders(self.trade_pair)
|
||||
for order in to_orders:
|
||||
if not Order.select().where(Order.uuid == order['uuid']).first():
|
||||
o = Order(
|
||||
trade_pair=order['market'],
|
||||
trade_type='manual',
|
||||
buy=order['type'] == 'buy',
|
||||
quantity=float(order['quantity']),
|
||||
price=float(order['price']),
|
||||
uuid=order['uuid'],
|
||||
date=datetime.utcfromtimestamp(order['date'])
|
||||
)
|
||||
o.save()
|
||||
logging.info(f'[ORDERS] Saved order {order["uuid"]} to the database')
|
||||
|
||||
def update_orders(self):
|
||||
logging.info('[ORDERS] Updating orders in local database against TradeOgre')
|
||||
for order in self.get_active_orders():
|
||||
logging.info(f'Checking order {order.uuid}')
|
||||
o = self.get_order(order.uuid)
|
||||
logging.info(f'Found order: {o}')
|
||||
if o['success'] is False:
|
||||
order.active = False
|
||||
order.save()
|
||||
logging.info(f'Order {order.uuid} no longer active on TradeOgre. Setting inactive.')
|
||||
|
||||
def update_trade_history(self):
|
||||
logging.info('Updating trade history for the ticker')
|
||||
for trade in self.get_history(self.trade_pair):
|
||||
tr = Trade(
|
||||
trade_pair=self.trade_pair,
|
||||
trade_type=trade['type'],
|
||||
buy=trade['type'] == 'buy',
|
||||
quantity=float(trade['quantity']),
|
||||
price=float(trade['price']),
|
||||
date=datetime.utcfromtimestamp(trade['date'])
|
||||
)
|
||||
tr.save()
|
||||
logging.info('Trade added to the database')
|
||||
|
||||
def update_bitcoin_price(self):
|
||||
logging.info('Updating Bitcoin price')
|
||||
r = self.get_bitcoin_price()
|
||||
bp = BitcoinPrice(
|
||||
price=float(r['price'])
|
||||
)
|
||||
bp.save()
|
||||
|
||||
|
||||
trader = Trader()
|
|
@ -27,23 +27,83 @@
|
|||
}
|
||||
}
|
||||
|
||||
// new Noty({
|
||||
// theme: 'relax',
|
||||
// layout: 'topCenter',
|
||||
// text: 'yo doggy',
|
||||
// timeout: 4500
|
||||
// }).show();
|
||||
|
||||
render() {
|
||||
// fetch latest data for the UI
|
||||
let updateAllData;
|
||||
// trigger background tasks to store data
|
||||
let storeMarketData;
|
||||
let storeBalances;
|
||||
let storeBitcoinPrice;
|
||||
let storeOrderStatuses;
|
||||
let storeTradeHistory;
|
||||
|
||||
function getAllData() {
|
||||
console.log('updating data');
|
||||
fetch('{{ url_for("api.get_ticker_data") }}')
|
||||
.then((response) => response.json())
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
});
|
||||
fetch('{{ url_for("api.get_balances") }}');
|
||||
fetch('{{ url_for("api.get_bitcoin_price") }}');
|
||||
fetch('{{ url_for("api.get_orders") }}');
|
||||
fetch('{{ url_for("api.get_trade_history") }}');
|
||||
}
|
||||
|
||||
if (this.state.looping) {
|
||||
storeMarketData = setInterval(function() {
|
||||
console.log('updating ticker data');
|
||||
fetch('{{ url_for("tasks.store_ticker_data") }}');
|
||||
}, 30000);
|
||||
storeBalances = setInterval(function() {
|
||||
console.log('storing balances');
|
||||
fetch('{{ url_for("tasks.store_balances") }}');
|
||||
}, 50000);
|
||||
storeBitcoinPrice = setInterval(function() {
|
||||
console.log('storing bitcoin price');
|
||||
fetch('{{ url_for("tasks.store_bitcoin_price") }}');
|
||||
}, 300000);
|
||||
storeOrderStatuses = setInterval(function() {
|
||||
console.log('storing order statuses');
|
||||
fetch('{{ url_for("tasks.store_orders") }}');
|
||||
}, 30000);
|
||||
storeTradeHistory = setInterval(function() {
|
||||
console.log('storing trade history');
|
||||
fetch('{{ url_for("tasks.store_trade_history") }}');
|
||||
}, 60000);
|
||||
updateAllData = setInterval(getAllData(), 10000);
|
||||
}
|
||||
|
||||
return(
|
||||
<div>
|
||||
<h1>we trade a lil {{ trade_currency }}</h1>
|
||||
<h1>we trade a lil {{ trade_currency | lower }}</h1>
|
||||
{this.state.looping && (
|
||||
<div>
|
||||
<p>market making is started</p>
|
||||
<button onClick={() => {
|
||||
this.setState({looping: false});
|
||||
clearInterval(storeMarketData);
|
||||
clearInterval(storeBalances);
|
||||
clearInterval(storeBitcoinPrice);
|
||||
clearInterval(storeOrderStatuses);
|
||||
clearInterval(storeTradeHistory);
|
||||
clearInterval(updateAllData);
|
||||
}}>Stop</button>
|
||||
</div>
|
||||
) || (
|
||||
<div>
|
||||
<p>market making is paused</p>
|
||||
<p>market making is stopped</p>
|
||||
<button onClick={() => {
|
||||
new Noty({
|
||||
theme: 'relax',
|
||||
layout: 'topCenter',
|
||||
text: 'yo doggy',
|
||||
timeout: 4500
|
||||
}).show();
|
||||
}}>sup boi</button>
|
||||
this.setState({looping: true});
|
||||
getAllData();
|
||||
}}>Start</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -53,7 +113,7 @@
|
|||
|
||||
// this.setState(prevState => {
|
||||
// let jasper = { ...prevState.jasper }; // creating copy of state variable jasper
|
||||
// jasper.name = 'someothername'; // update the name property, assign a new value
|
||||
// jasper.name = 'someothername'; // store the name property, assign a new value
|
||||
// return { jasper }; // return new object jasper object
|
||||
// });
|
||||
|
||||
|
@ -65,10 +125,4 @@
|
|||
// fetch('{{ url_for("tasks.store_ticker_data") }}');
|
||||
// }, 10000)
|
||||
|
||||
// store market data - 10s
|
||||
// update balances - 30s
|
||||
// update bitcoin price - 120s
|
||||
// update order status - 30s
|
||||
// get trade history - 60s
|
||||
|
||||
</script>
|
|
@ -57,3 +57,17 @@ class TradeOgre(object):
|
|||
route = f'/account/orders'
|
||||
data = {'market': pair}
|
||||
return self.req(route, 'post', data)
|
||||
|
||||
def get_bitcoin_price(self):
|
||||
url = 'https://api.coingecko.com/api/v3/coins/wownero'
|
||||
headers = {'accept': 'application/json'}
|
||||
data = {
|
||||
'localization': False,
|
||||
'tickers': False,
|
||||
'market_data': True,
|
||||
'community_data': False,
|
||||
'developer_data': False,
|
||||
'sparkline': False
|
||||
}
|
||||
r = requests_get(url, headers=headers, data=data)
|
||||
return {'price': r.json()['market_data']['current_price']['usd']}
|
||||
|
|
Loading…
Reference in a new issue