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

268
trade.py
View File

@ -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
logging.basicConfig(
level=getenv('LOGLEVEL', 'INFO'),
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
class Trader(TradeOgre):
satoshi = .00000001 satoshi = .00000001
base_currency = 'BTC'
trade_currency = 'WOW'
trade_pair = f'{base_currency}-{trade_currency}'
class TradeOgre(object): def get_market_data(self):
def __init__(self): logging.info(f'Getting market data for trade pair {self.trade_pair}')
load_dotenv('.env') res = self.get_trade_pair(self.trade_pair)
self.base = 'https://tradeogre.com/api/v1' spread_btc = Decimal(res['ask']) - Decimal(res['bid'])
self.auth = HTTPBasicAuth( spread_sats = float(spread_btc / Decimal(self.satoshi))
getenv('TO_USER'), spread_perc = (spread_btc / Decimal(res['ask'])) * 100
getenv('TO_PASS') res['spread_btc'] = spread_btc
) res['spread_sats'] = spread_sats
res['spread_perc'] = spread_perc
logging.debug(res)
return res
def req(self, route, method='get', data={}): def store_market_data(self):
url = self.base + route res = self.get_market_data()
if method == 'get': logging.info(f'Storing market data for trade pair {self.trade_pair}')
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( t = Ticker(
trade_pair=trade_pair, trade_pair=self.trade_pair,
initial_price=tp_res['initialprice'], initial_price=res['initialprice'],
current_price=tp_res['price'], current_price=res['price'],
high_price=tp_res['high'], high_price=res['high'],
low_price=tp_res['low'], low_price=res['low'],
volume=tp_res['volume'], volume=res['volume'],
bid=tp_res['bid'], bid=res['bid'],
ask=tp_res['ask'], ask=res['ask'],
spread_btc=spreat_btc, spread_btc=res['spread_btc'],
spread_sats=spread_sats, spread_sats=res['spread_sats'],
spread_perc=spread_perc spread_perc=res['spread_perc']
) )
t.save() t.save()
logging.info(f'Stored market data as ID {t.id}')
return t
# get balances and store in db def store_balance(self, currency):
for c in base, currency: logging.info(f'Storing balance for currency {currency}')
gb_res = to.get_balance(c) res = self.get_balance(currency)
print(gb_res) logging.debug(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)
if sell['success']:
o = Order(
trade_pair='BTC-WOW',
trade_type='market_maker',
buy=False,
quantity=ask_amount,
price=to_ask,
uuid=sell['uuid']
)
o.save()
def check_orders(): def get_active_orders(self):
to = TradeOgre() logging.info('Getting active orders in local database')
orders = Order.select().where(Order.active==True) orders = Order.select().where(Order.active==True)
for order in orders: logging.debug(f'Found {len(orders)} in database')
print(order.uuid) return orders
o = to.get_order(order.uuid)
print(o) 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: if o['success'] is False:
order.active = False order.active = False
order.save() order.save()
logging.debug(f'Order {order.uuid} no longer active on TradeOgre. Setting inactive.')
sleep(5) 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=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)
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__': 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)

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)