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

fix-graf
lza_menace 4 years ago
parent 1b060e24fe
commit bfc3e6b082

@ -1,164 +1,188 @@
#!/usr/bin/env python #!/usr/bin/env python
from argparse import ArgumentParser import logging
from os import getenv from os import getenv
from dotenv import load_dotenv from argparse import ArgumentParser
from requests import get as requests_get
from requests import post as requests_post
from requests.auth import HTTPBasicAuth
from decimal import Decimal from decimal import Decimal
from random import uniform from random import uniform
from pprint import pprint
from time import sleep from time import sleep
from db import Ticker, Balance, Order from db import Ticker, Balance, Order
from tradeogre import TradeOgre
satoshi = .00000001 logging.basicConfig(
level=getenv('LOGLEVEL', 'INFO'),
class TradeOgre(object): format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
def __init__(self): )
load_dotenv('.env')
self.base = 'https://tradeogre.com/api/v1' class Trader(TradeOgre):
self.auth = HTTPBasicAuth(
getenv('TO_USER'), satoshi = .00000001
getenv('TO_PASS') 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()
def req(self, route, method='get', data={}): logging.info(f'Stored market data as ID {t.id}')
url = self.base + route return t
if method == 'get':
r = requests_get(url, auth=self.auth) def store_balance(self, currency):
else: logging.info(f'Storing balance for currency {currency}')
r = requests_post(url, auth=self.auth, data=data) res = self.get_balance(currency)
return r.json() logging.debug(res)
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)
b = Balance( b = Balance(
currency=c, currency=currency,
total=gb_res['balance'], total=res['balance'],
available=gb_res['available'] available=res['available']
) )
b.save() b.save()
logging.info(f'Stored market data as ID {b.id}')
return b
def put_market_maker(): def store_balances(self):
to = TradeOgre() for cur in self.base_currency, self.trade_currency:
latest_ticker = Ticker.select().order_by(Ticker.date.desc()).get() self.store_balance(cur)
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()
sleep(3) sleep(3)
sell = to.submit_order('sell', 'BTC-WOW', ask_amount, '{:.8f}'.format(to_ask))
print(sell) def get_active_orders(self):
if sell['success']: 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( o = Order(
trade_pair='BTC-WOW', trade_pair=self.trade_pair,
trade_type='market_maker', trade_type=trade_type,
buy=False, buy=True,
quantity=ask_amount, quantity=bid_amount,
price=to_ask, price=bid_price,
uuid=sell['uuid'] uuid=buy['uuid']
) )
o.save() o.save()
logging.debug(f'Stored buy order as ID {o.id}')
def check_orders(): sleep(3)
to = TradeOgre()
orders = Order.select().where(Order.active==True) logging.info(f'Submitting sell order for {ask_amount} at {ask_price} {self.trade_pair}')
for order in orders: sell = self.submit_order('sell', self.trade_pair, ask_amount, ask_price)
print(order.uuid) logging.debug(sell)
o = to.get_order(order.uuid) if sell['success']:
print(o) o = Order(
if o['success'] is False: trade_pair=self.trade_pair,
order.active = False trade_type=trade_type,
order.save() buy=False,
sleep(5) 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__': if __name__ == '__main__':
parser = ArgumentParser(description='Helpful TradeOgre trading script') 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') parser.add_argument('-u', '--update-orders', action='store_true', help='Update status of orders')
args = parser.parse_args() args = parser.parse_args()
if args.trade: t = Trader()
put_market_maker() orders_counter = 0
balances_counter = 0
market_maker_counter = 0
if args.market_maker:
t.start_market_maker()
exit() exit()
if args.update_orders: if args.update_orders:
check_orders() t.update_orders()
exit()
if args.balances:
t.store_balances()
exit() exit()
while True: 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) sleep(60)

@ -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)