move TradeOgre to its own module, setup all actions in the loop with counters, new Trader class

This commit is contained in:
lza_menace 2020-09-07 02:30:25 -07:00
parent 1b060e24fe
commit bfc3e6b082
2 changed files with 197 additions and 128 deletions

280
trade.py
View File

@ -1,164 +1,188 @@
#!/usr/bin/env python
from argparse import ArgumentParser
import logging
from os import getenv
from dotenv import load_dotenv
from requests import get as requests_get
from requests import post as requests_post
from requests.auth import HTTPBasicAuth
from argparse import ArgumentParser
from decimal import Decimal
from random import uniform
from pprint import pprint
from time import sleep
from db import Ticker, Balance, Order
from tradeogre import TradeOgre
logging.basicConfig(
level=getenv('LOGLEVEL', 'INFO'),
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
satoshi = .00000001
class Trader(TradeOgre):
class TradeOgre(object):
def __init__(self):
load_dotenv('.env')
self.base = 'https://tradeogre.com/api/v1'
self.auth = HTTPBasicAuth(
getenv('TO_USER'),
getenv('TO_PASS')
satoshi = .00000001
base_currency = 'BTC'
trade_currency = 'WOW'
trade_pair = f'{base_currency}-{trade_currency}'
def get_market_data(self):
logging.info(f'Getting market data for trade pair {self.trade_pair}')
res = self.get_trade_pair(self.trade_pair)
spread_btc = Decimal(res['ask']) - Decimal(res['bid'])
spread_sats = float(spread_btc / Decimal(self.satoshi))
spread_perc = (spread_btc / Decimal(res['ask'])) * 100
res['spread_btc'] = spread_btc
res['spread_sats'] = spread_sats
res['spread_perc'] = spread_perc
logging.debug(res)
return res
def store_market_data(self):
res = self.get_market_data()
logging.info(f'Storing market data for trade pair {self.trade_pair}')
t = Ticker(
trade_pair=self.trade_pair,
initial_price=res['initialprice'],
current_price=res['price'],
high_price=res['high'],
low_price=res['low'],
volume=res['volume'],
bid=res['bid'],
ask=res['ask'],
spread_btc=res['spread_btc'],
spread_sats=res['spread_sats'],
spread_perc=res['spread_perc']
)
t.save()
logging.info(f'Stored market data as ID {t.id}')
return t
def req(self, route, method='get', data={}):
url = self.base + route
if method == 'get':
r = requests_get(url, auth=self.auth)
else:
r = requests_post(url, auth=self.auth, data=data)
return r.json()
def get_trade_pair(self, pair):
route = f'/ticker/{pair}'
return self.req(route)
def get_balance(self, currency):
route = '/account/balance'
data = {'currency': currency}
return self.req(route, 'post', data)
def get_balances(self):
route = '/account/balances'
return self.req(route)
def submit_order(self, type, pair, quantity, price):
route = f'/order/{type}'
data = {'market': pair, 'quantity': quantity, 'price': price}
return self.req(route, 'post', data)
def get_order(self, uuid):
route = f'/account/order/{uuid}'
return self.req(route)
def get_metrics():
# define vars
to = TradeOgre()
base = 'BTC'
currency = 'WOW'
trade_pair = f'{base}-{currency}'
# get market data
tp_res = to.get_trade_pair(trade_pair)
print(tp_res)
spreat_btc = Decimal(tp_res['ask']) - Decimal(tp_res['bid'])
spread_sats = float(spreat_btc / Decimal(.00000001))
spread_perc = (spreat_btc / Decimal(tp_res['ask'])) * 100
# store market data in db
t = Ticker(
trade_pair=trade_pair,
initial_price=tp_res['initialprice'],
current_price=tp_res['price'],
high_price=tp_res['high'],
low_price=tp_res['low'],
volume=tp_res['volume'],
bid=tp_res['bid'],
ask=tp_res['ask'],
spread_btc=spreat_btc,
spread_sats=spread_sats,
spread_perc=spread_perc
)
t.save()
# get balances and store in db
for c in base, currency:
gb_res = to.get_balance(c)
print(gb_res)
def store_balance(self, currency):
logging.info(f'Storing balance for currency {currency}')
res = self.get_balance(currency)
logging.debug(res)
b = Balance(
currency=c,
total=gb_res['balance'],
available=gb_res['available']
currency=currency,
total=res['balance'],
available=res['available']
)
b.save()
logging.info(f'Stored market data as ID {b.id}')
return b
def put_market_maker():
to = TradeOgre()
latest_ticker = Ticker.select().order_by(Ticker.date.desc()).get()
if latest_ticker.spread_sats > 4:
bid_amount = uniform(80, 90)
ask_amount = uniform(80, 90)
to_bid = latest_ticker.bid + satoshi
to_ask = latest_ticker.ask - satoshi
buy = to.submit_order('buy', 'BTC-WOW', bid_amount, '{:.8f}'.format(to_bid))
print(buy)
if buy['success']:
o = Order(
trade_pair='BTC-WOW',
trade_type='market_maker',
buy=True,
quantity=bid_amount,
price=to_bid,
uuid=buy['uuid']
)
o.save()
def store_balances(self):
for cur in self.base_currency, self.trade_currency:
self.store_balance(cur)
sleep(3)
sell = to.submit_order('sell', 'BTC-WOW', ask_amount, '{:.8f}'.format(to_ask))
print(sell)
if sell['success']:
def get_active_orders(self):
logging.info('Getting active orders in local database')
orders = Order.select().where(Order.active==True)
logging.debug(f'Found {len(orders)} in database')
return orders
def update_orders(self):
logging.info('Updating orders in local database against TradeOgre')
for order in self.get_active_orders():
logging.debug(f'Checking order {order.uuid}')
o = self.get_order(order.uuid)
logging.debug(f'Found order: {o}')
if o['success'] is False:
order.active = False
order.save()
logging.debug(f'Order {order.uuid} no longer active on TradeOgre. Setting inactive.')
sleep(5)
def start_market_maker(self):
logging.info('Starting market maker')
latest = Ticker.select().order_by(Ticker.date.desc()).get()
trade_type = 'market_maker'
if len(self.get_active_orders()) > 5:
logging.info('Too many active orders in place. Skipping.')
return False
if latest.spread_sats > 4:
bid_amount = uniform(100, 130)
ask_amount = uniform(bid_amount - 6, bid_amount + 6)
bid_price = '{:.8f}'.format(latest.bid + self.satoshi)
ask_price = '{:.8f}'.format(latest.ask - self.satoshi)
logging.info(f'Submitting buy order for {bid_amount} at {bid_price} {self.trade_pair}')
buy = self.submit_order('buy', self.trade_pair, bid_amount, bid_price)
logging.debug(buy)
if buy['success']:
o = Order(
trade_pair='BTC-WOW',
trade_type='market_maker',
buy=False,
quantity=ask_amount,
price=to_ask,
uuid=sell['uuid']
trade_pair=self.trade_pair,
trade_type=trade_type,
buy=True,
quantity=bid_amount,
price=bid_price,
uuid=buy['uuid']
)
o.save()
logging.debug(f'Stored buy order as ID {o.id}')
sleep(3)
def check_orders():
to = TradeOgre()
orders = Order.select().where(Order.active==True)
for order in orders:
print(order.uuid)
o = to.get_order(order.uuid)
print(o)
if o['success'] is False:
order.active = False
order.save()
sleep(5)
logging.info(f'Submitting sell order for {ask_amount} at {ask_price} {self.trade_pair}')
sell = self.submit_order('sell', self.trade_pair, ask_amount, ask_price)
logging.debug(sell)
if sell['success']:
o = Order(
trade_pair=self.trade_pair,
trade_type=trade_type,
buy=False,
quantity=ask_amount,
price=ask_price,
uuid=sell['uuid']
)
o.save()
logging.debug(f'Stored sell order as ID {o.id}')
else:
logging.info(f'Not enough bid-ask spread ({latest.spread_sats} sats). Skipping market maker.')
if __name__ == '__main__':
parser = ArgumentParser(description='Helpful TradeOgre trading script')
parser.add_argument('-t', '--trade', action='store_true', help='Put in buy/sell orders')
parser.add_argument('-m', '--market-maker', action='store_true', help='Put in buy/sell orders')
parser.add_argument('-b', '--balances', action='store_true', help='Update coin balances of both base and currency')
parser.add_argument('-u', '--update-orders', action='store_true', help='Update status of orders')
args = parser.parse_args()
if args.trade:
put_market_maker()
t = Trader()
orders_counter = 0
balances_counter = 0
market_maker_counter = 0
if args.market_maker:
t.start_market_maker()
exit()
if args.update_orders:
check_orders()
t.update_orders()
exit()
if args.balances:
t.store_balances()
exit()
while True:
get_metrics()
t.store_market_data()
# update orders every 5 minutes
if orders_counter == 5:
t.update_orders()
orders_counter = 0
# update balances every 2 minutes
if balances_counter == 2:
t.store_balances()
balances_counter = 0
# start market makers every 3 minutes
if market_maker_counter == 3:
t.start_market_maker()
market_maker_counter = 0
orders_counter += 1
balances_counter += 1
market_maker_counter += 1
# sleep 1 minute
sleep(60)

45
tradeogre.py Normal file
View File

@ -0,0 +1,45 @@
from os import getenv
from dotenv import load_dotenv
from requests import get as requests_get
from requests import post as requests_post
from requests.auth import HTTPBasicAuth
class TradeOgre(object):
def __init__(self):
load_dotenv('.env')
self.base = 'https://tradeogre.com/api/v1'
self.auth = HTTPBasicAuth(
getenv('TO_USER'),
getenv('TO_PASS')
)
def req(self, route, method='get', data={}):
url = self.base + route
if method == 'get':
r = requests_get(url, auth=self.auth)
else:
r = requests_post(url, auth=self.auth, data=data)
return r.json()
def get_trade_pair(self, pair):
route = f'/ticker/{pair}'
return self.req(route)
def get_balance(self, currency):
route = '/account/balance'
data = {'currency': currency}
return self.req(route, 'post', data)
def get_balances(self):
route = '/account/balances'
return self.req(route)
def submit_order(self, type, pair, quantity, price):
route = f'/order/{type}'
data = {'market': pair, 'quantity': quantity, 'price': price}
return self.req(route, 'post', data)
def get_order(self, uuid):
route = f'/account/order/{uuid}'
return self.req(route)