class MysqlDB(Databas, with_metaclass(FlyweightMeta)): def __init__(self, name, alias, zone=None): super(MysqlDB, self).__init__() self.name = name self.alias = alias self.zone = zone self.db_type = 'mysql'
class SqliteDB(Databas, with_metaclass(FlyweightMeta)): def __init__(self, uri, alias, zone): super(SqliteDB, self).__init__() self.uri = uri self.alias = alias self.zone = zone self.db_type = 'sqlite'
class Exchange(with_metaclass(FlyweightMeta)): def __init__(self, name): self.exchange_name = name self.base_currency = 'usd' def get_base_currency(self): return self.base_currency def __str__(self): return self.exchange_name
class ExchangeFactory(with_metaclass(FlyweightMeta)): def get_exchange(self, **kw): if kw['exchange'] == 'Okex': exch = Okex('Okex') elif kw['exchange'] == 'CoinOne': exch = CoinOne('CoinOne') elif kw['exchange'] == 'Bithumb': exch = Bithumb('Bithumb') else: exch = Exchange(name=kw['exchange']) return exch
class ExchangeRate(with_metaclass(FlyweightMeta)): supported_currency = ['CNY', 'JPY', 'HKD', 'EUR', 'KRW'] def __init__(self): super(ExchangeRate, self).__init__() self.base = 'usd' self.usd = 1.0 self.usdt = 1.0 self.cny = None self.jpy = None self.hkd = None self.eur = None self.krw = None
class SqliteDatabaseManager(DatabaseManager, with_metaclass(FlyweightMeta)): def __init__(self, *dbs): super(SqliteDatabaseManager, self).__init__() self.engine = create_engine('sqlite://', pool_size=20, pool_pre_ping=True, echo=False) self.attached_databases = dbs for db in dbs: self.engine.execute("attach database '{}' as {};".format( db.uri, db.alias)) Session = sessionmaker(bind=self.engine) self.session = Session() def __del__(self): self.session.close() def get_all_table_names(self): tb_names = [] for db in self.attached_databases: res = self.session.execute( "select name from {}.sqlite_master where type='table';".format( db.alias)) if res: tb_names.extend(['{}.{}'.format(db.alias, r[0]) for r in res]) return tb_names def get_table_names_from_db(self, db): tb_names = [] res = self.session.execute( "select name from {}.sqlite_master where type='table';".format( db.alias)) if res: tb_names.extend(['{}.{}'.format(db.alias, r[0]) for r in res]) return tb_names
class MysqlDatabaseManager(DatabaseManager, with_metaclass(FlyweightMeta)): def __init__(self, uri, *dbs): super(MysqlDatabaseManager, self).__init__() for db in dbs: if db.db_type != 'mysql': raise ValueError('Invalid DB Type') self.engine = create_engine(uri, echo=False) self.attached_dbs = dbs Session = sessionmaker(bind=self.engine) self.session = Session() def __del__(self): self.session.close() def get_all_table_names(self): tb_names = [] for db in self.attached_dbs: res = self.session.execute('show tables in {};'.format(db.name)) if res: tb_names.extend(['{}.{}'.format(db.name, r[0]) for r in res]) return tb_names def get_table_names_from_db(self, db): if db not in self.attached_dbs: raise ValueError('No such DB.') tb_names = [] res = self.session.execute('show tables in {}'.format(db.alias)) if res: tb_names.extend(['{}.{}'.format(db.alias, r[0]) for r in res]) return tb_names def is_table_empty(self, db, table_name): res = self.session.execute('select 1 from {}.{} limit 1;'.format( db.alias, table_name)) return res is not None def is_table_existed(self, db, table_name): tb_names = self.get_table_names_from_db(db) return '{}.{}'.format(db.alias, table_name) in tb_names
class ConfidentInstmtParser(with_metaclass(FlyweightMeta)): def __init__(self, zone_ini_file=None): self.zone_ini_file = zone_ini_file self.config = configparser.ConfigParser() if os.path.exists(zone_ini_file): self.config.read(zone_ini_file) else: raise Error('No Such Confident Zone Info File.') def is_confident(self, zone, instmt): try: if self.zone_ini_file is None: return False instmts = self.config.get(zone.upper(), 'instruments') if instmts: imts = list(map(lambda x: x.strip(), instmts.split(','))) return instmt in imts else: return False except Exception as e: return False
class ExchangeRate(with_metaclass(FlyweightMeta)): aliyun_uri = 'http://ali-waihui.showapi.com/waihui-transform?fromCode=' supported_currency = ['CNY', 'JPY', 'HKD', 'EUR', 'KRW'] def __init__(self): super(ExchangeRate, self).__init__() self.AppCode = '4a6b2d8ebc494dd6808d78919cfb5018' self.base = 'USD' self.usd = 1.0 self.usdt = 1.0 self.cny = 0.0 self.jpy = 0.0 self.hkd = 0.0 self.eur = 0.0 self.krw = 0.0 self.config = None self.lock = threading.Lock() self.exchange_rate_table_name = 'exchange_rate' #self.update_exchage_rate() def set_config(self, config): self.config = config def initialize_exchange_rate_table(self): stmt = ''' CREATE TABLE IF NOT EXISTS {}.{} (date_time varchar(25), cny decimal(20, 8), jpy decimal(20, 8), eur decimal(20, 8), krw decimal(20, 8), primary key (date_time) ); '''.format(self.config.mysql_db.alias, self.exchange_rate_table_name) if not self.config.db_mgr.is_table_existed( self.config.mysql_db, self.exchange_rate_table_name): try: self.config.db_mgr.session.execute(stmt) self.config.db_mgr.session.commit() except Exception as e: print(e) self.config.db_mgr.session.rollback() def update_exchage_rate(self): with requests.Session() as sess: try: self.lock.acquire() headers = { 'content-type': 'application/json', 'Authorization': 'APPCODE ' + self.AppCode } for item in ExchangeRate.supported_currency: res = sess.get(self.aliyun_uri + self.base + '&money=1' + '&toCode=' + item, headers=headers).json() if not res and not res['showapi_res_body'][ 'ret_code'] == '0': raise ValueError setattr(self, item.lower(), res['showapi_res_body']['money']) if not self.config: raise ValueError self.config.safe_exchage_rate(self.config.mysql_db.alias, self.exchange_rate_table_name, self.cny, self.jpy, self.eur, self.krw) except Exception as e: print(e) finally: self.lock.release() def __str__(self): return ' '.join([ '{}:{}'.format(x, getattr(self, x.lower())) for x in self.supported_currency ])
class MonitorConfig(with_metaclass(FlyweightMeta)): def __init__(self): super(MonitorConfig, self).__init__() self.config_file = None self.mysql_uri = None self.mysql_db = None self.rules = None self.mail_config = None self.rule_table_name = 'exchange_data_monitor_rules' self.lock = threading.Lock() def load_config(self, mysql_uri, mysql_db, config_file): self.mysql_uri = mysql_uri self.config_file = config_file with open(self.config_file, 'r') as f: content = json.loads(f.read()) self.mail_config = content['mail'] self.mysql_db = MysqlDB(mysql_db, mysql_db) self.db_mgr = MysqlDatabaseManager(self.mysql_uri, self.mysql_db) stmt = ''' CREATE TABLE IF NOT EXISTS {}.{} ( id int not null AUTO_INCREMENT, exch1 varchar(25), exch2 varchar(25), currency varchar(25), price_diff_threshold decimal(20, 8), direction varchar(25), succeeded_rule_id varchar(128), status varchar(16), primary key (id) ); '''.format(self.mysql_db.alias, self.rule_table_name) if not self.db_mgr.is_table_existed(self.mysql_db, self.rule_table_name): try: self.db_mgr.session.execute(stmt) self.db_mgr.session.commit() except Exception as e: print(e) self.db_mgr.session.rollback() self.fetch_rules() def fetch_rules(self): stmt = ''' select id, exch1, exch2, currency, price_diff_threshold, direction from {}.{} where status = 'active'; '''.format(self.mysql_db.alias, self.rule_table_name) try: self.lock.acquire() print('Fetching Rules') self.db_mgr.session.execute('flush table {}.{}'.format( self.mysql_db.alias, self.rule_table_name)) self.db_mgr.session.commit() res = self.db_mgr.session.execute(stmt) if self.rules: del self.rules self.rules = {} for item in res: self.rules[item[0]] = list(item[1:]) print(self.rules) except Exception as e: print(e) self.db_mgr.session.rollback() finally: self.lock.release() def deactive_rule(self, id): stmt = ''' update {}.{} set status = 'deactive' where id = {}; '''.format(self.mysql_db.alias, self.rule_table_name, id) try: self.lock.acquire() self.db_mgr.session.execute(stmt) self.db_mgr.session.commit() except Exception as e: print(e) finally: self.lock.release() def active_rule(self, id): stmt = ''' update {}.{} set status = 'active' where id = {}; '''.format(self.mysql_db.alias, self.rule_table_name, id) try: self.lock.acquire() self.db_mgr.session.execute(stmt) self.db_mgr.session.commit() except Exception as e: print(e) finally: self.lock.release() def get_succeeded_rule_ids(self, key): stmt = ''' select succeeded_rule_id from {}.{} where id = {}; '''.format(self.mysql_db.alias, self.rule_table_name, key) try: self.lock.acquire() res = self.db_mgr.session.execute(stmt).fetchone() if res[0]: ids = list( map(lambda x: int(x.strip()), re.split(',|\ |;', res[0]))) return ids else: return None except Exception as e: print(e) finally: self.lock.release() def safe_exchage_rate(self, dbalias, tablename, cny, jpy, eur, krw): date = datetime.utcnow().date().strftime("%Y%m%d") stmt = '''replace into {}.{} (date_time, cny, jpy, eur, krw) values ('{}', {}, {}, {}, {}); '''.format(dbalias, tablename, date, cny, jpy, eur, krw) try: self.lock.acquire() self.db_mgr.session.execute(stmt) self.db_mgr.session.commit() except Exception as e: print(e) finally: self.lock.release()