def atmTransaction(): atmType = str(input("Would you like to deposit or withdraw money?")) if atmType == "withdraw": atmWithdrawMoney = int( input("How much money would you like to withdraw?")) if atmWithdrawMoney <= Balance.getBalance() and atmWithdrawMoney > 0: Balance.amountToDeduct(atmWithdrawMoney) print("You have successfully withdrew $", atmWithdrawMoney) Menu.displayMenu() else: print( "You cannot withdraw that amount of money. Please enter a number within your balance." ) atmTransaction() elif atmType == "deposit": atmDepositMoney = int( input("How much money would you like to deposit?")) if atmDepositMoney <= 500000 and atmDepositMoney > 0: Balance.amountToAdd(atmDepositMoney) print("You have successfully deposited $", atmDepositMoney) Menu.displayMenu() else: print( "You cannot deposit that amount of money. Please enter a number within $1-$500,000." ) atmTransaction() else: print("You can only deposit or withdraw money. Please try again.") atmTransaction()
def sellStock(): print("Sell my stocks station.") ticker = str(input("Please enter your ticker to sell.")) quantity = int(input("How much stocks would you like to sell?")) stock_price = 150 amount = (stock_price * quantity) Balance.amountToAdd(amount) print("You have just sold ", ticker, " and the quantity = ", quantity, " total amount received is ", amount) print("Your account balance is: ", Balance.getBalance()) Menu.displayMenu()
def interestMoney(): print("Time to calculate your interest!") print("You have been a member of our bank for 2 years.") print("Your balance is ", int(Balance.getBalance())) print("The interest rate is 5%.") interest = (int(Balance.getBalance()) * 2 * (1 / 20)) print("Therefore, your interest is ", interest) print( "Congratulations! Because you looked at your interest, you have now gotten a free bonus in your balance! go check your balance to see!" ) Balance.balance = Balance.balance + interest
def card(): cardType = str(input("What type of card would you like to get?\n" "1. Credit Card\n" "2. Debit Card\n")) if cardType == "1": creditCardAmount = int(input("How much money would you like to place in your Credit Card?")) if creditCardAmount < Balance.getBalance() and creditCardAmount > 0: print("You now have a Credit Card with $", creditCardAmount, " in it.") elif cardType == "2": debitCardAmount = int(input("How much money would you like to place in your Debit Card?")) if debitCardAmount < Balance.getBalance() and debitCardAmount > 0: print("You now have a Debit Card with $", debitCardAmount, " in it.")
def display(): a = random.randint(50000, 500000) b = random.randint(50000, Balance.getBalance()) c = random.randint(50000, Balance.getBalance()) d = random.randint(50000, 500000) look = str(input("Would you like to look at your recent transactions?")) if look == "yes" or look == "y": print("Ok, here are your most recent transactions:\n", "Deposited $", a, "\nWithdrew $", b, "\nWithdrew $", c, "\nDeposited $", d) go_back = str(input("Would you like to go back to menu or exit?")) if go_back == "go back" or go_back == "back" or go_back == "menu": Menu.displayMenu() else: exit() else: Menu.displayMenu()
def __init__(self, initScript=None): """Init the flash Init Info: nuLiqphases = 2 nuStreamsIn = 2 """ super(LLStage, self).__init__(initScript) #Create a separator self.innerFlash = innerFlash = Flash.SimpleFlash() self.AddUnitOperation(innerFlash, FLASH) #Create a balance self.innerMixer = innerMixer = Balance.BalanceOp() self.AddUnitOperation(innerMixer, MIX) #Initialize params self.InitializeParameters() #Share the ports directly self.ports_mat_OUT = innerFlash.ports_mat_OUT self.ports_mat_IN = innerMixer.ports_mat_IN #Connect the balance to the separator self.ConnectPorts(MIX, OUT_PORT + str(0), FLASH, IN_PORT)
def __init__(self, initScript=None): """ set up the basic flowsheet """ UnitOperations.UnitOperation.__init__(self, initScript) self.feedBalance = Balance.BalanceOp() self.AddUnitOperation(self.feedBalance, 'FeedBalance') self.feedBalance.SetParameterValue(NUSTOUT_PAR + Balance.S_MAT, 1) self.feedBalance.SetParameterValue( Balance.BALANCETYPE_PAR, Balance.MOLE_BALANCE | Balance.ENERGY_BALANCE) self.SetParameterValue(NUSTIN_PAR + Balance.S_MAT, 1) self.SetParameterValue(NUSTIN_PAR + Balance.S_ENE, 1) self.splitter = SimpleComponentSplitter() self.splitter.borrowedSplits = self self.AddUnitOperation(self.splitter, 'Splitter') for port in self.splitter.GetPorts(MAT | OUT): self.BorrowChildPort(port, port.GetName()) self.ConnectPorts('FeedBalance', OUT_PORT + '0', 'Splitter', IN_PORT)
def Balance(self): qString = "nonce=" + str(self.nonce) sign = self.ComputeHash(qString) url = self.Url + "Account/Balance" response = self.Query(qString, url, sign) _json = json.loads(response.decode("utf-8")) return Balance(_json['BalanceNIS'], _json['BalanceLTC'], _json['BalanceBTC'])
def depositMoney(): depositAmount = int(input("How much money would you like to deposit? \n")) print("You are depositing: ", depositAmount) if Balance.getBalance() <= 0: print("Error: You cannot deposit that amount of money. You must deposit a natural number such as 1, 2, 3, or 4, but not 0 or a decimal. You can go as high as 100 or 100,000!") sleep(1) depositMoney() elif Balance.getBalance() >= 500000: print("Error: You cannot deposit that amount of money. You must deposit between between 0 and 500,000 dollars.") sleep(1) depositMoney() else: Balance.amountToAdd(depositAmount) print("You have successfully deposited ", depositAmount) print("Your new balance is ", Balance.getBalance()) sleep(1)
def buyStock(): print("Check out our latest stocks!") ticker = str(input("Please enter your ticker")) quantity = int(input("How much stocks would you like to buy?")) stock_price = 100 print("The current stock price is ", stock_price) if quantity > 100: print( "You are purchasing more than 100 stocks so you get a 5% discount." ) stock_price = stock_price - stock_price * 0.05 if quantity > 350: print("sorry, but you cannot buy more than 350 stocks.") else: amount = (stock_price * quantity) Balance.amountToDeduct(amount) print("You have just purchased ", ticker, " and the quantity = ", quantity, " total amount paid is ", amount) print("Your account balance is: ", Balance.getBalance()) Menu.displayMenu()
def menu(): print( "\n Welcome in NuBot_Phyton \n \n \t 1. Analiz and Signal \n \t 2. Strategy RSI \n \t 3. Strategy PingPong \n \t 4. Strategy PingPong2 \n \t 5. Strategy PingPong with SMA \n \t 6. Strategy PingPong with SMA TSL \n \t 7. Strategy BB \n \t 8. Strategy Scalping Depth \n \t 9. Balance" ) choice = input() if choice == "1": print( "Start Analiz and Signal \n------------------------------------------------------------------------------------------------------------------------------------" ) Analiz.StartAnaliz() if choice == "2": print( "Strategy RSI \n------------------------------------------------------------------------------------------------------------------------------------" ) Strategy_RSI.Strategy_RSI() if choice == "3": print( "Strategy PingPong \n------------------------------------------------------------------------------------------------------------------------------------" ) Strategy_PingPong.Strategy_PingPong() if choice == "4": print( "Strategy PingPong \n------------------------------------------------------------------------------------------------------------------------------------" ) Strategy_PingPong2.Strategy_PingPong2() if choice == "5": print( "Strategy PingPong with SMA \n------------------------------------------------------------------------------------------------------------------------------------" ) Strategy_PingPong_SMA.Strategy_PingPong_SMA() if choice == "6": print( "Strategy PingPong with SMA Trading Stop Loss \n------------------------------------------------------------------------------------------------------------------------------------" ) Strategy_PingPong_SMA_TSL.Strategy_PingPong_SMA_TSL() if choice == "7": print( "Strategy BB \n------------------------------------------------------------------------------------------------------------------------------------" ) Strategy_BB.Strategy_BB() if choice == "8": print( "Strategy Scalping Depth \n------------------------------------------------------------------------------------------------------------------------------------" ) Strategy_SD.Strategy_Scalping_Depth() if choice == "9": print( "Balance Account \n------------------------------------------------------------------------------------------------------------------------------------" ) Balance.MyBalance()
def withdrawMoney(): withdrawAmount = int(input("How much money would you like to withdraw? \n")) print("You are withdrawing: ", withdrawAmount) if Balance.getBalance() < withdrawAmount: print("Error: You cannot withdraw that amount of money. You must withdraw less than or equal to the amount of money you have. ") sleep(1) withdrawMoney() elif withdrawAmount <= 0: print("Error: You cannot withdraw that amount of money. You must withdraw between your amount and zero. ") sleep(1) withdrawMoney() elif withdrawAmount == str: print("Error: You cannot withdraw that amount. Please enter a number.") sleep(1) withdrawMoney() elif withdrawAmount <= Balance.getBalance() and withdrawAmount > 0: Balance.amountToDeduct(withdrawAmount) print("You have successfully withdrew $", withdrawAmount) print("Your new balance is ", Balance.getBalance()) sleep(1)
def __init__(self, initScript=None): """ create the ports and init the balance """ UnitOperations.UnitOperation.__init__(self, initScript) self.portOut0 = self.CreatePort(OUT | MAT, OUT_PORT + str(0)) self.portOut1 = self.CreatePort(OUT | MAT, OUT_PORT + str(1)) self.portIn = self.CreatePort(IN | MAT, IN_PORT) self._balance = Balance.Balance(Balance.MOLE_BALANCE | Balance.ENERGY_BALANCE) self._balance.AddInput(self.portIn) self._balance.AddOutput(self.portOut0) self._balance.AddOutput(self.portOut1) self.splits = SplitList( self) # list to hold split fraction signal ports self.borrowedSplits = None # used by containing op to be notified of split list changes
def get_balances(): #### Fetch free balances from exchanges and enter them into Balance objects. Should only run once during setup to prevent duplicate entries. Does not include balances currently allocated by exchanges for pending transactions. balancelist = [] for id in [*Exchanges]: balances = Exchanges[id].fetch_balance() for b in [*balances['free']]: amount = balances['free'][b] exchange = Exchanges[id] currency = Currencies[b] balancelist.append(Balance.Balance(amount, exchange, currency)) return balancelist
def __init__(self, initScript=None): super(ConvReactor, self).__init__(initScript) self.isoRxn = IsothermalConvReactor() self.AddUnitOperation(self.isoRxn, 'IsoRxn') self.isoRxn.containerUnitOp = self self.heater = Heater.Heater() self.AddUnitOperation(self.heater, 'RxnHeater') self.baln = Balance.BalanceOp() self.AddUnitOperation(self.baln, 'EneBalance') #Initialize with one energy In and Out as a default #The parameter QEXOTHERMIC_ISPOS_PAR will set the missing energy port self.baln.SetParameterValue(NUSTIN_PAR + Balance.S_ENE, 1) self.baln.SetParameterValue(NUSTOUT_PAR + Balance.S_ENE, 1) self.baln.SetParameterValue(Balance.BALANCETYPE_PAR, Balance.ENERGY_BALANCE) # to create an Energy Out port for export self.balEneSensor = Sensor.EnergySensor() self.AddUnitOperation(self.balEneSensor, 'BalEneSensor') self.eneSensor = Sensor.EnergySensor() self.AddUnitOperation(self.eneSensor, 'EneSensor') self.eneStream = Stream.Stream_Energy() self.AddUnitOperation(self.eneStream, 'EneStream') # connect the child unit ops self.ConnectPorts('IsoRxn', OUT_PORT + 'Q', 'EneBalance', IN_PORT + 'Q0') self.ConnectPorts('RxnHeater', IN_PORT + 'Q', 'EneBalance', OUT_PORT + 'Q0') self.ConnectPorts('IsoRxn', OUT_PORT, 'RxnHeater', IN_PORT) self.ConnectPorts('EneSensor', OUT_PORT, 'EneStream', IN_PORT) # self.ConnectPorts('BalEneSensor', SIG_PORT, 'EneSensor', SIG_PORT) # borrow child ports self.BorrowChildPort(self.eneStream.GetPort(OUT_PORT), OUT_PORT + 'Q') self.BorrowChildPort(self.isoRxn.GetPort(IN_PORT), IN_PORT) self.BorrowChildPort(self.heater.GetPort(OUT_PORT), OUT_PORT) self.BorrowChildPort(self.heater.GetPort(DELTAP_PORT), DELTAP_PORT) self.SetParameterValue(NURXN_PAR, 0) self.SetParameterValue(SIMULTANEOUSRXN_PAR, 1) self.SetParameterValue(QEXOTHERMIC_ISPOS_PAR, 1)
def __init__(self, initScript = None): """ create the ports and init the balance """ super(Valve, self).__init__(initScript) self.outPort = self.CreatePort(OUT|MAT, OUT_PORT) self.outPort.SetLocked(True) self.inPort = self.CreatePort(IN|MAT, IN_PORT) self.inPort.SetLocked(True) self.dpPort = self.CreatePort(SIG, DELTAP_PORT) self.dpPort.SetSignalType(DELTAP_VAR) self.dpPort.SetLocked(True) self._balance = Balance.Balance(Balance.MOLE_BALANCE|Balance.ENERGY_BALANCE) self._balance.AddInput(self.inPort) self._balance.AddOutput(self.outPort)
def __init__(self, initScript=None): super(EquilibriumReactor, self).__init__(initScript) self.itnRxn = InternalEqmReactor() self.AddUnitOperation(self.itnRxn, 'itnRxn') self.itnRxn.containerUnitOp = self self.baln = Balance.BalanceOp() self.AddUnitOperation(self.baln, 'EneBalance') self.baln.SetParameterValue(NUSTIN_PAR + Balance.S_ENE, 1) self.baln.SetParameterValue(Balance.BALANCETYPE_PAR, Balance.ENERGY_BALANCE) # to create an Energy Out port for export self.balEneSensor = Sensor.EnergySensor() self.AddUnitOperation(self.balEneSensor, 'BalEneSensor') self.eneSensor = Sensor.EnergySensor() self.AddUnitOperation(self.eneSensor, 'EneSensor') self.eneStream = Stream.Stream_Energy() self.AddUnitOperation(self.eneStream, 'EneStream') # connect the child unit ops self.ConnectPorts('itnRxn', OUT_PORT + 'Q', 'EneBalance', IN_PORT + 'Q0') self.ConnectPorts('EneSensor', OUT_PORT, 'EneStream', IN_PORT) self.ConnectPorts('BalEneSensor', SIG_PORT, 'EneSensor', SIG_PORT) # borrow child ports self.BorrowChildPort(self.eneStream.GetPort(OUT_PORT), OUT_PORT + 'Q') self.BorrowChildPort(self.itnRxn.GetPort(IN_PORT), IN_PORT) self.BorrowChildPort(self.itnRxn.GetPort(OUT_PORT), OUT_PORT) self.BorrowChildPort(self.itnRxn.GetPort(DELTAP_PORT), DELTAP_PORT) self.SetParameterValue(NURXN_PAR, 0) self.SetParameterValue(CALCOPTION_PAR, 1) #use table to correlate constant self.SetParameterValue(CONSTBASIS_PAR, 1) #use partial pressure to calculate constant self.SetParameterValue( BASISPUNIT_PAR, 'atm') #VMG pressure unit when partial pressure as basis self.SetParameterValue(QEXOTHERMIC_ISPOS_PAR, 1)
def UpdatePortsOut(self): """Update the amount and names of the ports out""" portNames = self.GetPortNames(MAT | OUT) nuLPorts = self.nuLPorts nuSPorts = self.nuSPorts #Get how many phases of each we actually have nuLPh = self.NumberLiqPhases() nuSPh = self.NumberSolidPhases() #Create or delete the liquid ports for i in range(nuLPorts, nuLPh, -1): p = self.GetPort(L_PORT + str(i - 1)) p.SetLocked(False) self.DeletePort(p) for i in range(nuLPorts, nuLPh): p = self.CreatePort(MAT | OUT, L_PORT + str(i)) p.SetLocked(True) #Create or delete the solid ports for i in range(nuSPorts, nuSPh, -1): p = self.GetPort(S_PORT + str(i - 1)) p.SetLocked(False) self.DeletePort(p) for i in range(nuSPorts, nuSPh): p = self.CreatePort(MAT | OUT, S_PORT + str(i)) p.SetLocked(True) #Update the port counts self.nuLPorts = nuLPh self.nuSPorts = nuSPh #Update the balance self.balance = Balance.Balance(Balance.MOLE_BALANCE | Balance.ENERGY_BALANCE) self.balance.AddInput(self.ports_mat_IN[IN_PORT]) for port in self.GetPorts(MAT | OUT): self.balance.AddOutput(port)
def __init__(self, initScript=None): """ Just do balance and conserve entropy isCompressor determines energy flow direction """ super(IdealPump, self).__init__(initScript) self.balance = Balance.Balance(Balance.MOLE_BALANCE | Balance.ENERGY_BALANCE) self.lastPIn = None self.lastPOut = None inPort = self.CreatePort(MAT | IN, IN_PORT) outPort = self.CreatePort(MAT | OUT, OUT_PORT) dpPort = self.CreatePort(SIG, DELTAP_PORT) dpPort.SetSignalType(DELTAP_VAR) qPort = self.CreatePort(ENE | IN, IN_PORT + 'Q') self.balance.AddInput((inPort, qPort)) self.balance.AddOutput(outPort) self.SetParameterValue(ISENTROPIC_PAR, 1)
def donateMoney(): global donateAmount donateAmount = int(input("How much money would you like to donate?")) if donateAmount > 0 and donateAmount < 500000: if donateAmount <= Balance.getBalance(): place1 = "Covid-19 Relief" place2 = "Pennies for the Poor" place3 = "Cancer Research Center" donatePlace = str(input("What charity would you like to donate to?\n" "1. Covid-19 Relief\n" "2. Pennies for the Poor\n" "3. Cancer Research Center\n")) if donatePlace == "1": Balance.amountToDeduct(donateAmount) print("You have successfully donated $ ", donateAmount," to ", place1, " charity.") elif donatePlace == "2": Balance.amountToDeduct(donateAmount) print("You have successfully donated $ ", donateAmount," to ", place2, " charity.") elif donatePlace == "3": Balance.amountToDeduct(donateAmount) print("You have successfully donated $ ", donateAmount," to ", place3, " charity.") else: print("Please enter an available charity to donate to!") donateMoney() else: print("You do not have enough money in your account to donate. You have $", Balance.getBalance(), " but you want to donate $", donateAmount) donateMoney() else: print("You cannot donate that amount of money. Please try again within the range of $0-$500,000.") donateMoney()
'/Game/PatchDLC/Steam/Gear/Weapons/SteamGun/Balance/Balance_SM_HYP_ShortStick', '/Game/PatchDLC/Event2/Gear/Weapon/_Unique/Pricker/Balance/Balance_SM_HYP_Pricker' ] #Now the Barrels smg_barrel=[ ] #Now the Materials smg_material=[ ] for bal in smg_bal_name: smg_bals=Balance.from_data(data, bal) mat_type=len(smg_bals.categories) for cat in smg_bals.categories: if cat.index==2: for barrel in smg_barrel: cat.add_part_name(barrel, 1) cat.select_multiple=True cat.num_min=1 cat.num_max=3 if cat.index==mat_type-1: for material in smg_material: cat.add_part_name(material, 1) break smg_bals.hotfix_full(mod)
def __init__(self, m, numCur): # numCur is the amount of currencies we are # going to be tracking across all the exchanges # eg, ltc/btc, ftc/btc would be 2 etc. # keep track of running time self.__started = time.time() # an array of market objects self.markets = m # this is the default order for currency self.currencies = ["ltc", "usd", "lsd"] # Use the pair object to creat an array of the # best currency markets # we may need to put the market name/index number # in the Pair object so that we can later match # The form that the pair objects in ask/bid will take # inside this arbitrage object is as follows, and # note: IS DIFFERENT FROM DEFAULT PAIR. # [price, quantity, index, marketbalance, marketidx] self.pairs = [] self.trades = [] for x in range(0, numCur): self.pairs.append(Pair('arb', x, 50, [dq, dq, dq], 0)) self.trades.append(Trades('arb', x, 50, 0)) # Variables to keep track of overall profit / trade # volume....This will need to be corrected for multiple # currency pairs as the price/volume is drasticlly different self.tprofit = D('0') self.ttrades = [] for x in range(0, numCur): self.ttrades.append(D('0')) # Strings for the logger self.last_arb = "" self.last_best = "" self.last_string = "" # This is for our draw screen function self.screen_update = time.time() # This sets up the balance sheets for all our currencies # we use this to tell if we are way off the mark and need # to buy/sell a currency to bring us back to a flat line self.market_balances = Balance() for m in self.markets: for k, v in m.balances.funds.items(): self.market_balances.funds[k] += v self.__initial_market_balances = copy.deepcopy(self.market_balances) # Write out our initial balances to our log file self.logger(self.stringFormat(0, 0, 0, 2)) # This lets our main loop know if we entered an arb state # so that we can run checkbooks/etc self.entered_arb = 0 # This is a counter, to check our books a couple times # then stop so we don't just check all the time as # really, unless there is a change in 3-5 minutes # there shouldnt be any further change self.arb_counter = 0 # # This is the discrepancy from the base balance we # are off in each market - should use to adjust order # trades in the future # # This is either + or - from the base # + means we should sell more (or buy less) # - means we should buy more (or sell less) # self.discrep = {'usd': D('0'), 'ltc': D('0'), 'btc': D('0')}
class Book(object): def __init__(self, m, numCur): # numCur is the amount of currencies we are # going to be tracking across all the exchanges # eg, ltc/btc, ftc/btc would be 2 etc. # keep track of running time self.__started = time.time() # an array of market objects self.markets = m # this is the default order for currency self.currencies = ["ltc", "usd", "lsd"] # Use the pair object to creat an array of the # best currency markets # we may need to put the market name/index number # in the Pair object so that we can later match # The form that the pair objects in ask/bid will take # inside this arbitrage object is as follows, and # note: IS DIFFERENT FROM DEFAULT PAIR. # [price, quantity, index, marketbalance, marketidx] self.pairs = [] self.trades = [] for x in range(0, numCur): self.pairs.append(Pair('arb', x, 50, [dq, dq, dq], 0)) self.trades.append(Trades('arb', x, 50, 0)) # Variables to keep track of overall profit / trade # volume....This will need to be corrected for multiple # currency pairs as the price/volume is drasticlly different self.tprofit = D('0') self.ttrades = [] for x in range(0, numCur): self.ttrades.append(D('0')) # Strings for the logger self.last_arb = "" self.last_best = "" self.last_string = "" # This is for our draw screen function self.screen_update = time.time() # This sets up the balance sheets for all our currencies # we use this to tell if we are way off the mark and need # to buy/sell a currency to bring us back to a flat line self.market_balances = Balance() for m in self.markets: for k, v in m.balances.funds.items(): self.market_balances.funds[k] += v self.__initial_market_balances = copy.deepcopy(self.market_balances) # Write out our initial balances to our log file self.logger(self.stringFormat(0, 0, 0, 2)) # This lets our main loop know if we entered an arb state # so that we can run checkbooks/etc self.entered_arb = 0 # This is a counter, to check our books a couple times # then stop so we don't just check all the time as # really, unless there is a change in 3-5 minutes # there shouldnt be any further change self.arb_counter = 0 # # This is the discrepancy from the base balance we # are off in each market - should use to adjust order # trades in the future # # This is either + or - from the base # + means we should sell more (or buy less) # - means we should buy more (or sell less) # self.discrep = {'usd': D('0'), 'ltc': D('0'), 'btc': D('0')} ################################### # # Orderbook getting section # # # This is the main function which gets all the orderbook data # from the redis server. # layout is as follows: # get key from redis which signals markets updated # get all the data from redis -> # process data into each market.pair # build master order book for each pair # done # return true if an update, false if no update # # # # def buildBooks(self, loc, initial=0): global perf_list perf_start = time.perf_counter() while True: try: #perf_start = time.perf_counter() pid = self.pairs[loc] tempd = {} r_server = redis.Redis(connection_pool=r_pool, charset="utf-9", decode_responses=True) r_pipe = r_server.pipeline() if initial == 1: zunion_flag = 1 else: zunion_flag = 0 for idx, mkt in enumerate(self.markets): # due to old structure, we must make a temp dict to store # data used for algos, namely the pos, mkt balance, and mkt idx mktb = mkt.balances.getAvail(self.currencies[loc]) # and the markets current btc balance mktbtc = mkt.balances.getAvail(UNDERLYING[loc]) tempd[mkt.mname] = { 'idx': idx, 'posa': 0, 'posb': 0, 'mktbtc': mktbtc, 'mktb': mktb, 'min_q': MIN_COIN } # this is seeing if an update passed since last time # we qeue up responses no matter what and will just # skip the 0's later if mkt.pairs[loc] != 0: r_pipe.zrange( mkt.mname + ":" + self.currencies[loc] + ":ask", 0, 25) r_pipe.zrevrange( mkt.mname + ":" + self.currencies[loc] + ":bid", 0, 25) zunion_flag = 1 if initial == 1: tempd[mkt.mname]['min_q'] = MIN_COIN else: try: tempd[mkt.mname]['min_q'] = mkt.pairs[ loc].min_trade_quantity() except: tempd[mkt.mname]['min_q'] = MIN_COIN else: r_pipe.echo('0') r_pipe.echo('0') if zunion_flag == 1: # Need a better solution for this if UNDERLYING[loc] == 'usd': ztempa = [ x.mname + ":" + self.currencies[loc] + ":ask" for x in self.markets if tempd[x.mname]['mktbtc'] > D('1') ] else: ztempa = [ x.mname + ":" + self.currencies[loc] + ":ask" for x in self.markets if tempd[x.mname]['mktbtc'] > MIN_BTC ] ztempb = [ x.mname + ":" + self.currencies[loc] + ":bid" for x in self.markets if tempd[x.mname]['mktb'] > tempd[x.mname]['min_q'] ] if ztempa: r_pipe.zunionstore( "ob:" + self.currencies[loc] + ":ask", ztempa) if ztempb: r_pipe.zunionstore( "ob:" + self.currencies[loc] + ":bid", ztempb) r_pipe.zrange("ob:" + self.currencies[loc] + ":ask", 0, 100) r_pipe.zrevrange("ob:" + self.currencies[loc] + ":bid", 0, 100) else: r_pipe.echo('0') r_pipe.echo('0') r_pipe.echo('0') r_pipe.echo('0') #perf_start = time.perf_counter() # so this will be a list as [[mkt1 ask's], [mkt1 bids], 0, 0, [mkt3 asks], ..., [zunion asks], [zunion bids]] resp = r_pipe.execute() #perf_end = time.perf_counter() # # from top to here, # this section is ~~.0028s # # #perf_start = time.perf_counter() # now parse the data # first reparse each individal markets pairs i = 0 for idx, mkt in enumerate(self.markets): if resp[i] == '0': i += 2 continue else: with lock: mkt.getBook(loc, [resp[i], resp[i + 1]], time.time()) i += 2 # # time here must be roughly ~~.002s # # now main book if resp[-1] != '0': # due to other places using this we need to lock here (eg: window thread calls this and # if these are deleted during update we will crash) perf_start = time.perf_counter() with lock: #[fee_price, quantity, pos, mkt balance, mkt idx, timer] pid.asks = [] for x in resp[-2]: order = x.split(":") mktb = tempd[order[3]]['mktb'] idx = tempd[order[3]]['idx'] pos = tempd[order[3]]['posa'] tempd[order[3]]['posa'] += 1 if D(order[1]) < tempd[order[3]]['min_q']: ignore, b = mkt.NullPrice() order[1] = b[1] order[2] = b[0] else: pid.asks.append([ D(order[2]), D(order[1]), pos, mktb, idx, float(order[4]) ]) pid.bids = [] for x in resp[-1]: order = x.split(":") mktb = tempd[order[3]]['mktb'] idx = tempd[order[3]]['idx'] pos = tempd[order[3]]['posb'] tempd[order[3]]['posb'] += 1 if D(order[1]) < tempd[order[3]]['min_q']: ignore, b = mkt.NullPrice() order[1] = b[1] order[2] = b[0] else: pid.bids.append([ D(order[2]), D(order[1]), pos, mktb, idx, float(order[4]) ]) perf_end = time.perf_counter() perf_list.append(perf_end - perf_start) # # sub block time is ~~.002s # # # This block from after r_pipe.execute # is ~~.004s # # time.sleep(.01) if initial == 1: break except: logger.exception("main arb build books") time.sleep(5) # Stub allows us to thread this function to allow quicker # execution def skewStub(self, x): if x.mname == 'BTCe' or x.mname == 'gdax' or x.mname == 'kraken' or x.mname == 'gemini': x.skew_order = 1 x.skew_cancel = 1 else: result = x.calcSkew(0) if result != True: if result == -2: x.skew_order = x.trade_lag x.skew_cancel = x.trade_lag else: try: x.cancelAllOrder() except: pass # This is a threaded subfunction which looks at each market and # sees if we need to canceltrades/update orderbook. # # The rules are as follows: # if need_update = 0 nothing is needed # # if need_update = 1 means trade succeded and we update books # if hold trade, most likely something failed so we don't go until # everything is checked. def setMarketBooks(self): if self.entered_arb != 1: if self.arb_counter > 0: self.arb_counter -= 1 prior = threading.active_count() p_timeout = time.time() for m in self.markets: t = threading.Thread(target=m.setBalance) t.start() while (threading.active_count() > prior) and (time.time() - 60 < p_timeout): time.sleep(1) # So arb has happened, we should set the counter to 3, then # continue with normal getting of balances. else: # Set to default of 4, so we check books four times, # then we should be good. self.arb_counter = 6 for m in self.markets: m.setBalance() self.sumBooks() self.logger(self.stringFormat(0, 0, 0, 2)) # This is going to process our initial book versus our current book # If it is way out of wack it will call fixBook which will initiate # a trade to correct the imbalance. def checkBooks(self): # First we ensure that all books are up to date # this also means that none should be held for m in self.markets: if m.need_update >= m.hold_trade > 0: return False cur_book = self.market_balances initial_b = self.__initial_market_balances for k, v in cur_book.funds.items(): # we don't want to balance btc at all if k == 'btc': continue # create the absolute average difference avg = (cur_book.funds[k] + initial_b.funds[k]) / 2 difference = cur_book.funds[k] - initial_b.funds[k] if avg != 0: abs_d = abs(difference / avg) else: abs_d = 0 # This implies that we are .06% off the starting values in # the coins so either we are ahead or behind. # either way we should try to come back to the # initial balance and take profit or eat loss if abs_d > .001: # min quantity on most markets is .01, so we cant correct here if k == 'usd' and abs(difference) < 6: continue # so we are going to buy or sell based on the diference self.logger("market needs to be fixed....{0}, {1}".format( k, difference)) # dont want to make use of discrep here, so null it out self.getDiscrep(k) self.fixBook(k, difference) # Since there was actually a market change we should reprint the balance # ticker tape. self.sumBooks() self.logger(self.stringFormat(0, 0, 0, 2)) # Since everything is now "fixed" we can set this to # 0 so we don't keep calling it self.entered_arb = 0 return True # This method fixes our orderbook by doing a one way trade def fixBook(self, coin, diff): try: for indexr, k in enumerate(self.currencies): if coin == k: pid = self.pairs[indexr] loc = indexr break # get the discrep discrep = self.getDiscrep(coin) # This means we need to buy the currency if diff < 0: top = pid.asks bysl = "ask" else: top = pid.bids bysl = "bid" quant = abs(diff + discrep) i = 0 counter = 0 while quant > 0 and i + 3 < len(top) and counter < 10: h = top[i] mkt = self.markets[h[4]] # So three possible iterations, we may get caught in a loop of low values if counter > 3 or i > 6: if quant < .01: # start lowering the amount of quant quant -= D(i) * D('.001') # we don't trade this pair on this exchange if mkt.pairs[loc] == 0: i += 1 continue # we shouldnt be here if we have a hold if mkt.hold_trade == 1: i += 1 continue with lock: try: if bysl == "ask": order = mkt.pairs[loc].getA(h[2]) else: order = mkt.pairs[loc].getB(h[2]) except IndexError: return min_quant = min(quant, order[1]) if not mkt.calcBalance(loc, coin, order[0], min_quant, bysl): i += 1 continue if mkt.pairs[loc].min_trade_quantity() > min_quant: i += 1 continue opts = { 'loc': loc, 'side': bysl, 'price': order[0], 'quantity': min_quant, 'ioc': True } # try not locking this section temp_q = mkt.postTrade(opts) if temp_q != -1: quant -= temp_q mkt.quickBalances(loc, [mkt, bysl, order, temp_q]) i = 0 counter += 1 except: logger.exception("in fixbook") # This adds up all the books into our one marketsheet def sumBooks(self): for k, v in self.market_balances.funds.items(): self.market_balances.funds[k] = 0 for m in self.markets: self.market_balances.funds[k] += m.balances.getCurrency(k) # checks if a market is held, if so return True def checkHoldTrade(self): for i, m in self.markets: if m.hold_trade == 1: return True return False # Creates custom strings for use in keeping track of arbs and # also for writing out to logs. def stringFormat(self, ask, bid, pairn, arb=0, p=D('0'), q=D('0')): ds = D('.00000001') if arb == 1: return "M:{6} [{0}:{1} a], [{2}:{3} b]ARB: Q:{4} P:{5}".format( ask[0].quantize(ds), # price self.markets[ask[4]].mname, # market bid[0].quantize(ds), self.markets[bid[4]].mname, q.quantize(ds), p, pairn) elif arb == 2: return "BAL: BTC: {0}, LTC: {2}, USD : {1}".format( self.market_balances.getCurrency('btc').normalize(), self.market_balances.getCurrency('usd').normalize(), self.market_balances.getCurrency('ltc').normalize()) else: return 'M:{4} [{0}:{1} a], [{2}:{3} b]'.format( ask[0].normalize(), self.markets[ask[4]].mname, bid[0].normalize(), self.markets[bid[4]].mname, pairn) # writes logs of everything def logger(self, strg): # just to prevent spamming the arb if self.last_string == strg: return else: filename = "logs/" + "arb.logs" f = open(filename, 'a') t = "T: {0} {1} \n".format(int(time.time()), strg) f.write(t) f.close() self.last_string = strg # Gets the amount we are off in each coin value # if we are getting this, we assume that we are # placing a trade, so nulls the value out on the # discrep value def getDiscrep(self, coin='ltc'): d = self.discrep[coin] self.discrep[coin] = D('0') return d def setDiscrep(self): cur_book = self.market_balances initial_b = self.__initial_market_balances for k, v in cur_book.funds.items(): if k == 'btc': continue else: self.discrep[k] = cur_book.funds[k] - initial_b.funds[k] # Just returns the difference from current balance - initial def coinBal(self, coin='btc'): bal = self.market_balances.getCurrency( coin) - self.__initial_market_balances.getCurrency(coin) return bal # Returns the initial balances def getIBal(self, coin='btc'): return self.__initial_market_balances.getCurrency(coin)
def interestCalculation(): (int(Balance.getBalance()) * 2 * (1 / 20))
def restart(): start11 = time.process_time() my_col = ['TIME', 'birga_x', 'birga_y', 'rates_x', 'rates_y', 'valin_x', 'valin_y', 'valout_y', 'volume_x', 'volume_y', 'start', 'step', 'back', 'profit', 'perc', 'volume'] if os.path.isfile(main_path_data + "\\all_data.csv"): pass else: final2 = pd.DataFrame(columns=my_col) final2.to_csv(main_path_data + "\\all_data.csv", header=True) pass hot = Hot_parser.loadRSS() live = Live_parser.restart() alfa = A_parser.loadRSS() birgi = {'alfa': alfa, 'live': live, 'hot': hot} birga = [] valin = [] valout = [] rates = [] volume = [] ########### Collected all kurses ############ def tab(item, value): for k, v in item.items(): list = k.split('/') abc = [0, 1, 2] for i in abc: birga.append(value) valin.append(list[0]) valout.append(list[1]) r = ("{0:,.10f}".format(float((item[k]['buy'][i][0])))) r2 = r.replace(',', '') v = ("{0:,.10f}".format(float((item[k]['buy'][i][1])))) v2 = v.replace(',', '') rates.append(r2) volume.append(v2) birga.append(value) valin.append(list[1]) valout.append(list[0]) r21 = ("{0:,.10f}".format(float((item[k]['sell'][i][0])))) r22 = r21.replace(',', '') v21 = ("{0:,.10f}".format(float((item[k]['sell'][i][1])))) v22 = v21.replace(',', '') rates.append(r22) volume.append(v22) return for value, item in birgi.items(): tab(item,value) dw = {'birga': birga, 'valin': valin, 'valout': valout, 'rates': rates, 'volume': volume} df = pd.DataFrame(data=dw) dfs2 = pd.merge(df, df, left_on=df['valout'], right_on=df['valin'], how='outer') dfs2['rates_x'] = dfs2['rates_x'].apply(pd.to_numeric, errors='coerce') dfs2['rates_y'] = dfs2['rates_y'].apply(pd.to_numeric, errors='coerce') dfs2['volume_x'] = dfs2['volume_x'].apply(pd.to_numeric, errors='coerce') dfs2['volume_y'] = dfs2['volume_y'].apply(pd.to_numeric, errors='coerce') dfs2.drop(['key_0'], axis = 1, inplace = True) dfs2['rates_y'] = dfs2['rates_y'].map('{:,.10f}'.format) dfs2['rates_x'] = dfs2['rates_x'].map('{:,.10f}'.format) ############### Main dataframe with all data #################### result = dfs2[(dfs2['valin_x'] == dfs2['valout_y'])] usdt = dfs2[(dfs2['valin_x'] == 'USD') & (dfs2['valout_y'] == 'USDT')] usd = dfs2[(dfs2['valin_x'] == 'USDT') & (dfs2['valout_y'] == 'USD')] final = result.append([usdt, usd]) final.reset_index(inplace=True, drop = True) final.reset_index(level=0, inplace=True) filter = final[(final['birga_x'] == final['birga_y']) & (final['rates_x'] < final['rates_y']) & (final['valin_x'] == final['valout_y'])] final = final.drop(filter['index'], axis=0) ######################## ADD COMMISSION ############################## var1 = final[final["valin_x"].isin(["USD", "USDT"])] var2 = final[final["valin_y"].isin(["USD", "USDT"])] var3 = final[(final["valin_x"] == "BTC") & (~final["valin_y"].isin(["USD", "USDT"]))] var4 = final[(final["valin_y"] == "BTC") & (~final["valin_x"].isin(["USD", "USDT"]))] var = {'var1': var1, 'var2': var2, 'var3': var3, 'var4': var4} def calc1(result): f = open(main_path_data + "\\commis.json") com = json.load(f) result.loc[:, 'start'] = "100" result.loc[:, "start"] = result["start"].str.replace(",", "").astype(float) result.loc[:, "rates_x"] = result["rates_x"].str.replace(",", "").astype(float) result.loc[:, "rates_y"] = result["rates_y"].str.replace(",", "").astype(float) result.loc[:, 'step'] = (result['start']) / ((result['rates_x'] * com['main'][result.iloc[0]['birga_x']])) result.loc[:, 'back'] = result['step'] * ((result['rates_y']) / com['main'][result.iloc[0]['birga_y']]) result.loc[:, 'profit'] = result['back'] - result['start'] result.loc[:, 'perc'] = (((result['profit']) / (result['start'])) * 100) f.close() return result def calc2(result): f = open(main_path_data + "\\commis.json") com = json.load(f) result.loc[:, 'start'] = "100" result.loc[:, "start"] = result["start"].str.replace(",", "").astype(float) result.loc[:, "rates_x"] = result["rates_x"].str.replace(",", "").astype(float) result.loc[:, "rates_y"] = result["rates_y"].str.replace(",", "").astype(float) result.loc[:, 'step'] = (result['start']) * ((result['rates_x'] / com['main'][result.iloc[0]['birga_x']])) result.loc[:, 'back'] = result['step'] / ((result['rates_y']) * com['main'][result.iloc[0]['birga_y']]) result.loc[:, 'profit'] = result['back'] - result['start'] result.loc[:, 'perc'] = (((result['profit']) / (result['start'])) * 100) f.close() return result dft = pd.DataFrame() for i, v in var.items(): if v.shape[0] > 0: if i == 'var1' or i == 'var3': dft = dft.append(calc1(v)) else: dft = dft.append(calc2(v)) now = dt.datetime.now() dft.loc[:, 'TIME'] = now.strftime("%H:%M:%S") dft.drop(['index'], axis=1, inplace=True) dft = dft[['TIME', 'birga_x', 'birga_y', 'rates_x', 'rates_y','valin_x','valin_y','valout_y','volume_x','volume_y','start','step','back','profit','perc']] dfs = dft valuta_main = Balance.balance() # valuta_main.to_csv(main_path_data + "\\balance.csv", index=False) def regim_filter(): fids = pd.DataFrame() ################################# REGIMS ########################################## if os.path.isfile(main_path_data + "\\regim.json"): f = open(main_path_data + "\\regim.json") regim = json.load(f) pass else: regim = {1: {"option": "off", "avtomat": "off", "val1": "", "val2": "", "val3": "", "birga1": "", "birga2": "", "profit": "", "order": "", "per": ""}} ooo = json.dumps(regim, indent=4) # Writing to sample.json with open(main_path_data + "\\regim.json", "w") as outfile: outfile.write(ooo) outfile.close() pass dfs['volume_x'] = dfs['volume_x'].apply(pd.to_numeric, errors='coerce') dfs['volume_y'] = dfs['volume_y'].apply(pd.to_numeric, errors='coerce') for i in regim: if regim[i]["option"] == 'active': if not regim[i]["per"]: dfs["volume_x"] = dfs["volume_x"].astype(float) dfs["volume_y"] = dfs["volume_y"].astype(float) filterx = dfs[dfs["volume_x"] < dfs["volume_y"]].index dfs.loc[filterx, "volume"] = dfs.loc[filterx, "volume_x"] filtery = dfs[dfs["volume_x"] > dfs["volume_y"]].index dfs.loc[filtery, "volume"] = dfs.loc[filtery, "volume_y"] dfs["volume"] = dfs["volume"].astype(float) dft = dfs[(dfs["birga_x"] == regim[i]["birga1"]) & (dfs["birga_y"] == regim[i]["birga2"]) & (dfs["valin_x"] == regim[i]["val1"]) & (dfs["valin_y"] == regim[i]["val2"]) & (dfs["valout_y"] == regim[i]["val3"]) & (dfs["perc"] > regim[i]["profit"]) & (dfs["volume"] > float(regim[i]["order"]))] if dft.shape[0] > 0: dft = dft[dft['volume'] == dft['volume'].max()] dft = dft.head(n=1) dft["regim"] = i if regim[i]["avtomat"] == 'on': if fids.shape[0] > 0: done = (time.process_time() - start11) dft["timer"] = done fids_b1 = fids[(fids['birga_x'] == dft.iloc[0]['birga_x']) & (fids['valin_x'] == dft.iloc[0]['valin_x']) & (fids['valin_y'] == dft.iloc[0]['valin_y'])] fids_b11 = fids[(fids['birga_x'] == dft.iloc[0]['birga_y']) & (fids['valin_x'] == dft.iloc[0]['valin_y']) & (fids['valin_y'] == dft.iloc[0]['valout_y'])] fids_b2 = fids[(fids['birga_y'] == dft.iloc[0]['birga_y']) & (fids['valin_x'] == dft.iloc[0]['valin_x']) & (fids['valin_y'] == dft.iloc[0]['valin_y'])] fids_b22 = fids[(fids['birga_y'] == dft.iloc[0]['birga_x']) & (fids['valin_y'] == dft.iloc[0]['valin_x']) & (fids['valout_y'] == dft.iloc[0]['valin_y'])] if fids_b1.shape[0] > 0: add_vol1 = float(fids_b1.iloc[0]['volume']) else: add_vol1 = 0 if fids_b11.shape[0] > 0: add_vol11 = float(fids_b1.iloc[0]['volume']) else: add_vol11 = 0 if fids_b2.shape[0] > 0: add_vol2 = float(fids_b1.iloc[0]['volume']) else: add_vol2 = 0 if fids_b22.shape[0] > 0: add_vol22 = float(fids_b1.iloc[0]['volume']) else: add_vol22 = 0 dft['volume'] = float(dft.iloc[0]['volume']) - add_vol1 - add_vol11 - add_vol2 - add_vol22 if dft.iloc[0]['volume'] > 0: valuta_new = pd.read_csv(main_path_data + "\\balance.csv") Avtomat.avtomat(dft, valuta_new, start11) fids = pd.concat([dft, fids], ignore_index=True, join='outer') continue else: continue else: done = (time.process_time() - start11) dft["timer"] = done valuta_new = pd.read_csv(main_path_data + "\\balance.csv") Avtomat.avtomat(dft, valuta_new, start11) fids = pd.concat([dft, fids], ignore_index=True, join='outer') continue else: done = (time.process_time() - start11) dft["timer"] = done fids = pd.concat([dft, fids], ignore_index=True, join='outer') continue else: continue else: dfs["volume_x"] = dfs["volume_x"].astype(float) dfs["volume_y"] = dfs["volume_y"].astype(float) filterx = dfs[dfs["volume_x"] < dfs["volume_y"]].index dfs.loc[filterx, "volume"] = dfs.loc[filterx, "volume_x"] * float(regim[i]["per"]) / 100 filtery = dfs[dfs["volume_x"] > dfs["volume_y"]].index dfs.loc[filtery, "volume"] = dfs.loc[filtery, "volume_y"] * float(regim[i]["per"]) / 100 dfs["volume"] = dfs["volume"].astype(float) dft = dfs[(dfs["birga_x"] == regim[i]["birga1"]) & (dfs["birga_y"] == regim[i]["birga2"]) & (dfs["valin_x"] == regim[i]["val1"]) & (dfs["valin_y"] == regim[i]["val2"]) & (dfs["valout_y"] == regim[i]["val3"]) & (dfs["perc"] > regim[i]["profit"]) & (dfs["volume"] > float(regim[i]["order"]))] if dft.shape[0] > 0: dft = dft[dft['volume'] == dft['volume'].max()] dft = dft.head(n=1) dft["regim"] = i if regim[i]["avtomat"] == 'on': if fids.shape[0] > 0: done = (time.process_time() - start11) dft["timer"] = done fids_b1 = fids[(fids['birga_x'] == dft.iloc[0]['birga_x']) & ( fids['valin_x'] == dft.iloc[0]['valin_x']) & ( fids['valin_y'] == dft.iloc[0]['valin_y'])] fids_b11 = fids[(fids['birga_x'] == dft.iloc[0]['birga_y']) & ( fids['valin_x'] == dft.iloc[0]['valin_y']) & ( fids['valin_y'] == dft.iloc[0]['valout_y'])] fids_b2 = fids[(fids['birga_y'] == dft.iloc[0]['birga_y']) & ( fids['valin_x'] == dft.iloc[0]['valin_x']) & ( fids['valin_y'] == dft.iloc[0]['valin_y'])] fids_b22 = fids[(fids['birga_y'] == dft.iloc[0]['birga_x']) & ( fids['valin_y'] == dft.iloc[0]['valin_x']) & ( fids['valout_y'] == dft.iloc[0]['valin_y'])] if fids_b1.shape[0] > 0: add_vol1 = float(fids_b1.iloc[0]['volume']) else: add_vol1 = 0 if fids_b11.shape[0] > 0: add_vol11 = float(fids_b1.iloc[0]['volume']) else: add_vol11 = 0 if fids_b2.shape[0] > 0: add_vol2 = float(fids_b1.iloc[0]['volume']) else: add_vol2 = 0 if fids_b22.shape[0] > 0: add_vol22 = float(fids_b1.iloc[0]['volume']) else: add_vol22 = 0 dft['volume'] = float(dft['volume']) - add_vol1 - add_vol11 - add_vol2 - add_vol22 if dft.iloc[0]['volume'] > 0: valuta_new = pd.read_csv(main_path_data + "\\balance.csv") Avtomat.avtomat(dft, valuta_new, start11) fids = pd.concat([dft, fids], ignore_index=True, join='outer') continue else: continue else: done = (time.process_time() - start11) dft["timer"] = done valuta_new = pd.read_csv(main_path_data + "\\balance.csv") Avtomat.avtomat(dft, valuta_new, start11) fids = pd.concat([dft, fids], ignore_index=True, join='outer') continue else: done = (time.process_time() - start11) dft["timer"] = done fids = pd.concat([dft, fids], ignore_index=True, join='outer') continue else: continue else: continue return fids fdf = regim_filter() df_all = pd.read_csv(main_path_data + "\\all_data.csv") valuta = pd.read_csv(main_path_data + "\\balance.csv") if df_all.shape[0] > 0: df_all['rates_y'] = df_all['rates_y'].map('{:,.6f}'.format) df_all['rates_x'] = df_all['rates_x'].map('{:,.6f}'.format) df_all['start'] = df_all['start'].map('{:,.6f}'.format) df_all['step'] = df_all['step'].map('{:,.6f}'.format) df_all['back'] = df_all['back'].map('{:,.6f}'.format) df_all['profit'] = df_all['profit'].map('{:,.6f}'.format) df_all['perc'] = df_all['perc'].map('{:,.3f}%'.format) else: pass return fdf, valuta, df_all
def reroll(self): self.first, self.second = Balance.balanceTeams(self.sample) self.text.set(f"{self.first}\n{self.second}")
'/Game/PatchDLC/Raid1/Gear/Weapons/TiggsBoom/Balance/Balance_SG_Torgue_TiggsBoom', '/Game/PatchDLC/Hibiscus/Gear/Weapon/_Unique/Shocker/Balance/Balance_SG_Torgue_ETech_Shocker' ] #Now the Barrels shotgun_barrel=[ ] #Now the Materials shotgun_material=[ ] for bal in shotgun_bal_name: shotgun_bals=Balance.from_data(data, bal) mat_type=len(shotgun_bals.categories) for cat in shotgun_bals.categories: if cat.index==2: for barrel in shotgun_barrel: cat.add_part_name(barrel, 1) cat.select_multiple=True cat.num_min=1 cat.num_max=3 if cat.index==mat_type-1: for material in shotgun_material: cat.add_part_name(material, 1) break shotgun_bals.hotfix_full(mod)
def __init__(self, initScript=None): """Init pump - build it from Idealpump, Heater and Set operations """ super(Pump, self).__init__(initScript) # the isentropic compressor self.ideal = IdealPump() self.AddUnitOperation(self.ideal, 'Ideal') # a heater to add the waste heat to the outlet self.waste = Heater.Heater() self.AddUnitOperation(self.waste, 'Waste') self.waste.GetPort(DELTAP_PORT).SetValue(0.0, FIXED_V) # connect them self.ConnectPorts('Ideal', OUT_PORT, 'Waste', IN_PORT) # energy sensors (needed for signals) self.idealQ = Sensor.EnergySensor() self.AddUnitOperation(self.idealQ, 'IdealQ') self.ConnectPorts('Ideal', IN_PORT + 'Q', 'IdealQ', OUT_PORT) self.wasteQ = Sensor.EnergySensor() self.AddUnitOperation(self.wasteQ, 'WasteQ') self.ConnectPorts('Waste', IN_PORT + 'Q', 'WasteQ', OUT_PORT) self.totalQ = Sensor.EnergySensor() self.AddUnitOperation(self.totalQ, 'TotalQ') # create a signal stream for the efficiency self.effStream = Stream.Stream_Signal() self.effStream.SetParameterValue(SIGTYPE_PAR, GENERIC_VAR) self.AddUnitOperation(self.effStream, 'EfficiencySig') #set relation between ideal and total Q self.set = Set.Set() self.AddUnitOperation(self.set, 'Set') self.set.SetParameterValue(SIGTYPE_PAR, ENERGY_VAR) self.set.GetPort(Set.ADD_PORT).SetValue(0.0, FIXED_V) self.ConnectPorts('TotalQ', SIG_PORT, 'Set', SIG_PORT + '0') self.ConnectPorts('IdealQ', SIG_PORT, 'Set', SIG_PORT + '1') self.ConnectPorts('EfficiencySig', OUT_PORT, 'Set', Set.MULT_PORT) # energy stream balance self.mix = Balance.BalanceOp() self.AddUnitOperation(self.mix, 'Mix') self.mix.SetParameterValue(NUSTIN_PAR + Balance.S_ENE, 1) self.mix.SetParameterValue(NUSTOUT_PAR + Balance.S_ENE, 2) self.mix.SetParameterValue(Balance.BALANCETYPE_PAR, Balance.ENERGY_BALANCE) # connect the mixer ports self.ConnectPorts('IdealQ', IN_PORT, 'Mix', OUT_PORT + 'Q0') self.ConnectPorts('WasteQ', IN_PORT, 'Mix', OUT_PORT + 'Q1') self.ConnectPorts('TotalQ', OUT_PORT, 'Mix', IN_PORT + 'Q0') # export the flow ports self.BorrowChildPort(self.ideal.GetPort(IN_PORT), IN_PORT) self.BorrowChildPort(self.waste.GetPort(OUT_PORT), OUT_PORT) self.BorrowChildPort(self.totalQ.GetPort(IN_PORT), IN_PORT + 'Q') self.BorrowChildPort(self.effStream.GetPort(IN_PORT), EFFICIENCY_PORT) self.BorrowChildPort(self.ideal.GetPort(DELTAP_PORT), DELTAP_PORT) #Change the type of the energy port such that it is in Work units and scaling self.totalQ.GetPort(IN_PORT).GetProperty().SetTypeByName(WORK_VAR)
class Market(object): def __init__(self, cur, url, rang=50, f=1.002, thrp=.02, thrm=0, mtq=[0, 0]): # An array of currency names self.curPairs = cur # The url is an ARRAY [] where 0 is the first bit # then we stop and continue after the curPair would be # added so that we have [0] + curPair + [1] for the # complete url. but our defURL will only have [0] and [1] self.defURL = url # The range or orderbook depth default 50 self.range = rang # Default fee is .2% # we write as 1.002 # This is a decimal from this point on self.fee = D(str(f)) # throttles should be deleted # Default throttle is 0 # this is time between calls self.throttle = thrm # we set this so that we can keep track self.throttle_updated = time.time() # Main orderbook pairs initialization process self.pairs = [] for i, x in enumerate(self.curPairs): if x != 0: # set the inverted bit if self.pairKey(x) == 'usd': self.pairs.append( Pair(self.mname, x, self.range, mtq[i], thrp, inv=1) ) # we make the currency pairs, thrp is the default pair throttle # non inverted, "normal" else: self.pairs.append( Pair(self.mname, x, self.range, mtq[i], thrp, inv=0) ) # we make the currency pairs, thrp is the default pair throttle else: self.pairs.append(x) # same process for trades history self.trades = [] for x in self.curPairs: if x != 0: self.trades.append( Trades(self.mname, x, self.range, thrp) ) # we make the currency pairs, thrp is the default pair throttle # now we open the trade file and get the last trade try: line = subprocess.check_output( ['tail', '-1', 'logs/trades/' + self.mname + '/' + x]) # now parse the trade y = line.split(',') self.trades[-1].last_trade = [ D(str(y[0])), D(str(y[1])), int(str(y[2])), int(str(y[3])), 'bid', str(time.time()) ] except: pass else: self.trades.append(x) # This is the balance sheet object self.balances = Balance() # this is the order array for an open "market maker" order self.open_order_mm = OrderList() # This indicates if the market is in some type of error # so we halt trading on it self.hold_trade = 0 # This variable indicates that we interacted in a trade # so we should call the cancelorders/setBalance # to update our book. self.need_update = 0 # Market was last alive at this point self.last_alive = time.time() # A way to count number of trades executed on this market self.totaltrades = 0 # Last quantity is a way for threading execution to get # the last traded amount since python threads cant # return the value that well. self.last_quantity_traded = D('-1') # The initial nonce is loaded from a saved file. This SHOULD # be quite close to the last one, but just in case we # will increment by 100 at the start to make sure we are not off # this could change later. # nonces are stored in nonce/ filename = "nonce/" + self.mname f = open(filename, 'r') self.initial_nonce = int(f.readline()) + 100 self.current_nonce = 0 f.close() self.writeNonce() # Function which gets initial balances for this market self.setBalance(initial=1) # skew for order placement, and order cancel self.skew_order = 10 self.skew_cancel = 10 # for competing on market making orders self.compete_price = [] for x in self.curPairs: self.compete_price.append(D('0')) # This should only be called while we are locked # so there really should be no cases where it is overwritten. def getNonce(self): self.current_nonce += 1 nonce = self.initial_nonce + self.current_nonce # This writes the nonce down if we are around 20 # in increments if (self.current_nonce % 20) == 0: self.writeNonce() return nonce # In some cases (exiting, etc) we may want to just write the nonce # no matter what def writeNonce(self): filename = "nonce/" + self.mname f = open(filename, 'w') f.write(str(self.current_nonce + self.initial_nonce)) f.close() # to make an API request that is other than the simple # get, eg post. This is usually trade, balance, etc calls # this is a broad general function which calls a formmating # function, formatPost which should be specific to each market # that function should return the url, header, and parameters. # # call will go as follows for a trade call: # market specific: postTrade -(calls)-> postPage # -(calls)-> formatPost -> return response.text # # def postPage(self, typ, params={}): resp = 0 url = 0 para = 0 resp = 0 try: session = requests.Session() url, para, head = self.formatPost(typ, params) response = session.post(url, headers=head, data=para, timeout=7, verify=False) # Setting verify False... session.close() resp = response.text except (ValueError, TypeError, requests.ConnectionError, requests.Timeout, requests.HTTPError, requests.RequestException): logger.exception("in postPage") resp = 0 # raise finally: self.postlog(url, typ, para, resp) return resp # The full trade call. This takes in params, then # formats, sends the trade, and if filled OK. if not # filled it cancels order and returns the quantity # traded. # Error status is a return of -1 # options is a dict structured as such: # { 'loc' : 0 , 1 (eg the pid loc # 'side' : bid, ask (req) # 'price': D('1') # 'quantity' : D('1') req # # 'post_only': if possible only put a post order (optional) # # } # def postTrade(self, options): # Always set quantity traded to -1 just incase # some error happens. self.last_quantity_traded = D('-1') # First we check to see if a trade is possible or # are we holding if self.hold_trade == 1: return D('-1') # Now we set our touched variable self.need_update = 1 # Due to some confusion earlier, I need to change the # bysl type around as what is happening is I am # FILLING a bysl with the opposite type # so if the incoming bysl is a bid, I must output # an ask order. if options['side'] == 'ask': options['side'] = 'bid' else: options['side'] = 'ask' try: params = self.formatTrade(options) response = self.postPage(self.trade_var, params) except (ValueError, TypeError, requests.ConnectionError, requests.Timeout, requests.HTTPError, requests.RequestException): logger.exception("in postTrade, after postPage()") self.hold_trade = 1 return D('-1') # This would mean that the data returned is not a normal # array. not very bad, but should require evaluation # likely to be caused by a wrong quantity/available try: q, id = self.parseTradeResponse(options['loc'], response) self.last_quantity_traded = D(q) except (ValueError, TypeError, KeyError): logger.exception("in postTrade, after parseTrade()") self.hold_trade = 1 return D('-1') # This means an error occured. if it is 0 we # absolutely need to cancel instead. # not success though is much better than something else # as it means the order was not placed/etc. so simply exit if q == D('-1'): self.hold_trade = 1 return D('-1') self.last_quantity_traded = D(q) return D(q) # # Delete page stub (more RESTful implementations) # # Quick stub for apis which implement the DELETE # command def deletePage(self, typ, params={}): resp = 0 url = 0 para = 0 try: session = requests.Session() url, para, head = self.formatPost(typ, params) response = session.delete(url, headers=head, data=para, timeout=15) session.close() resp = response.text except (ValueError, TypeError, requests.ConnectionError, requests.Timeout, requests.HTTPError, requests.RequestException): logger.exception("in deletePage") resp = 0 # raise finally: self.postlog(url, typ, para, resp) return resp # # Get process sections # # This returns the page text we do processing later in procBook, and procTrades # our entry variable is the currnecy OBJECT # this is so we can later factor in a throttle event def getPage(self, pairid, url=0): session = requests.Session() if url == 0: page = session.get(self.defURL[0] + pairid.name + self.defURL[1], timeout=5, verify=False) else: page = session.get(url, timeout=5, verify=False) session.close() return page.text # Orderbook section # This is the general form which is going to be using the # get page call, as well as will use the formatting # that is desired by the market. all the calls # are standard # This returns True if updated. # False will be for exception, throttle, error etc. def getBook(self, loc, content, timer): try: i = self.pairs[loc] # Now is [price, amount, fee price, invp, invq, invfp] # if is inverted the invp and price sections are swapped # the inversion is done at the exchange level, we always will # just place these in the correct position i.asks = [[D(b[0]), D(b[1]), D(b[2]), D(b[5]), D(b[6]), D(b[7])] for b in (x.split(":") for x in content[0])] i.bids = [[D(b[0]), D(b[1]), D(b[2]), D(b[5]), D(b[6]), D(b[7])] for b in (x.split(":") for x in content[1])] i.updated = float(timer) self.throttle_updated = time.time() return True except: logger.exception("in get book" + str(content)) i.updated = time.time() return False ################################################################### ################################################################### # fee structurce: # we take in the decimal price, decimal quantity # we check our fee variable from the market, # then we compute the total after fee's and return that amount # in the btc-e case as an example it takes .2% of the transaction # so we will instead return a quantity? # eg buying ltc from btc, btc-e takes an amount off the ltc you buy. # These give the changed QUANTITY back and is actually what markets # will do. The common way we will look at these is expecting # the exchange to take a cut in the primary currency only # so for ltc/btc it will only take cut out of the BTC side # so going btc -> ltc we pay higher btc price but get full ltc amount # going ltc -> btc again we lose out on BTC quantity not ltc. # some exchanges do this differently though so they need their # own functions to convert to this standard. # # This is what it costs to FILL a bid quote for us. def BuyFee(self, array): price = array[0] quantity = array[1] btc_flat = price * quantity btc_fee = btc_flat * self.fee return btc_fee # The loss that goes from selling for example LTC -> BTC # how much btc we actually get def SellFee(self, array): price = array[0] quantity = array[1] btc_flat = price * quantity btc_fee = btc_flat / self.fee return btc_fee # The Bid/Ask-FeePrice is the actual price that it would cost # us to fill. This is just looking at cost. Different markets # actually subtract the fee's differently from the quantity and # do not actually effect the price at all. # This should return the price after fee def BidFeePrice(self, array): price = array[0] quantity = array[1] idx = array[2] return [(price / self.fee), quantity, idx] # for ask def AskFeePrice(self, array): price = array[0] quantity = array[1] idx = array[2] return [(price * self.fee), quantity, idx] # general best viable orderbook price # i is the index location def bestPrice(self, loc, idx=0): pair = self.pairs[loc] if pair == 0: return self.NullPrice() else: newa = pair.quantask(idx) newa = [newa[3], newa[1], idx] newb = pair.quantbid(idx) newb = [newb[3], newb[1], idx] return newa, newb # in case we do not use the particular pair, or we error def NullPrice(self): return [D('999999'), D('0'), 0], [D('0'), D('0'), 0] ########################################################### ########################################################### ######### HELPER FUNCTION AREA # # COMPS AND SETTING ORDERS # ########################################################### # Helper function which checks in "general" if two decimals # are close to each other for us. def comp_decimal(self, x, y, sens=D('.0075')): avg = (x + y) / 2 diff = x - y if avg != 0: abs_d = abs(diff / avg) else: abs_d = 0 if abs_d > sens: return False else: return True # this abstracts the sub call to # the creation on our orderbook, # also handles updating the balance sheet # with the "available" def placeOrder(self, loc, side, contents): status = self.open_order_mm.placeOrder( self.pairKey(self.pairs[loc].name), side, contents) self.setAvailBook() return status def removeOrder(self, loc, side): status = self.open_order_mm.removeOrder( self.pairKey(self.pairs[loc].name), side) self.setAvailBook() return status def changeOrder(self, loc, side, quantity): status = self.open_order_mm.changeQuantity( self.pairKey(self.pairs[loc].name), side, quantity) self.setAvailBook() return status # # Inverting section # # for example, the btc/usd is not the format that we normally # use as we have written this in a 'base' btc format, eg: ltc/btc # using btc/usd with usd as the base confuses our algos. so # in the case where btc is not the base we must adjust. # changes from btc/usd to usd/btc assuming this: # price * btc = usd # --> btc = usd / price # will return the new 'quantity' which is # the amount which is the 'usd' portion # while the price is now 1/price def invertBase(self, price, quantity): # first we calculate usd, our new quantity usd = price * quantity # now we get the new price if price != D('0'): p2 = 1 / price else: p2 = D('0') return [p2, usd] # reverses the above transform # this is to go back for actually placing orders and interacting # with exchanges API's def revertBase(self, price, quantity): # this is the original price p1 = 1 / price # this is the original quantity btc = quantity / p1 return [p1, btc] # Health of exchange monitor # Checks on redis what last update was # if this is older than our expire time # we do the following: # 1) stop trading on exchange # 2) end the exchanges screen # 3) restart the screen # 4) get fresh book time # 5) check again in 1 minute to make sure the book is fresh # 6) lift trading ban def checkHealth(self): r_server = redis.Redis(connection_pool=r_pool, charset="utf-9", decode_responses=True) r_pipe = r_server.pipeline() alive = r_server.get(":".join([self.mname, 'alive'])) self.last_alive = float(alive) # has not updated in 60 seconds if time.time() - self.last_alive > 60: self.fixHealth() return False else: return True def fixHealth(self): self.hold_trade = 1 # Kill the old exchange process cmd = ['screen', '-X', '-S', self.mname, 'kill'] subprocess.run(cmd) time.sleep(1) # Restart exchange process cmd = [ 'screen', '-dm', '-S', self.mname, 'python3', 'exchanges/' + self.mname + '.py' ] subprocess.run(cmd) time.sleep(1) ##################### Balance Section ######################## # We will need to check our balances when we are making trades # to ensure that we have the funds available. # This function will take the type (eg, bid or ask) that IT # will be executing against. iow if we get a buy we are matching # an ask order, so we look to btc->coin and vice versa # This will then check our balances, calc the fees, and return # true is we have funds, false if not. def calcBalance(self, loc, coin, price, quantity, bysl): if bysl == "ask": btc_needed = self.BuyFee([price, quantity]) if btc_needed <= self.balances.getAvail(UNDERLYING[loc]): return True else: return False else: if quantity <= self.balances.getAvail(coin): return True else: return False # this sums up the orders on our open_order book # and subtracts the funds values from our balance # sheet to create an "available" balance which we # use for all checks def setAvailBook(self): oomm = {} for k, v in self.open_order_mm.open.items(): oomm[k] = self.open_order_mm.getOpenAmount(k) # this is special one off as btc is not kept # in the order list oomm['btc'] = self.open_order_mm.getOpenAmount('btc') self.balances.computeAvailable(oomm) # Main balance setting function # # We expect a dictionary of keys/values def setBalance(self, content=0, initial=0): t = time.time() - self.balances.updated if self.need_update > 0 or t > 1: try: if self.hold_trade == 1: # Lets cancel all the orders, pause, then we # we can try to get the new book ret = self.cancelAllOrder() time.sleep(1) if ret == False: return False if content == 0: content = self.postInfo() except (NameError, KeyError, ValueError, TypeError, requests.ConnectionError, requests.Timeout, requests.HTTPError, requests.RequestException): logger.exception("in setBalance after postInfo()") return False # This means we error out if content == {'none': 0}: logger.exception("in setBalance content is none") return False lock.acquire() # If it is initial setup, we just do this try: if initial == 1: for key, val in content.items(): if key.lower() in self.balances.funds: self.balances.setCurrency(key, D(str(val))) self.balances.funds_new = copy.deepcopy( self.balances.funds) self.balances.setComp() # Now we must assume it is not initial so we # need to take into account the old balance sheet # So what we are going to do is this, # 1) we set the new incoming data into funds_new # 2) compare the two funds sheets, if they match set # the "master" funds sheet. # 3) if they don't match, we check our third sheet, # funds_comp # 4) if funds_new and comp match, it means two data issues # from the server produced identical results, so # move that data into funds. # 5) they conflict, so move the funds_new into comp and # do not touch funds. else: for key, val in content.items(): if key.lower() in self.balances.funds: self.balances.setCurrencyNew(key, D(str(val))) if self.balances.checkNew() == True: self.balances.setComp() self.balances.setFunds() self.hold_trade = 0 elif self.balances.checkComp() == True: self.balances.setFunds() self.hold_trade = 0 else: self.balances.setComp() self.setAvailBook() self.balances.updated = time.time() self.need_update = 0 except (ValueError, TypeError, requests.ConnectionError, requests.Timeout, requests.HTTPError, requests.RequestException): logger.exception("in setbalance after locked loop") self.need_update = 1 self.hold_trade = 1 return False finally: lock.release() return True # This adjusts balances that were changed # This is only a partial adjustment and is overridden # by the loop getting the ACTUAL balance sheets. def quickBalances(self, loc, order): btc = UNDERLYING[loc] coin = CURRENCIES[loc] mkt = order[0] bysl = order[1] price = order[2][0] quant = order[3] if bysl == "ask": xbtc = self.BuyFee([price, quant, 0]) else: xbtc = self.SellFee([price, quant, 0]) btcc = self.balances.getCurrency(btc) curc = self.balances.getCurrency(coin) if bysl == "ask": self.balances.setCurrency(btc, btcc - xbtc) self.balances.setCurrency(coin, quant + curc) elif bysl == "bid": self.balances.setCurrency(coin, curc - quant) self.balances.setCurrency(btc, xbtc + btcc) self.setAvailBook() if quant > 0: self.totaltrades += 1 # stub for orderbook conversion used in findOrder def orderbookConversion(self, price, quantity): return price, quantity # this checks the orderbook to find if we can see # a matching order def findOrder(self, loc, price, quantity, side): pid = self.pairs[loc] if side == 'ask': book_side = pid.asks else: book_side = pid.bids # we need to perform a conversion here # in case the orderbook performs some # weird thing which is unexpected, like applying # or not applying the fee # eg: a bter conversion price, quantity = self.orderbookConversion(price, quantity) lock.acquire() try: if pid.inverted == 1: # 1 cent difference will show up as a +- 4 in the 8th place op = price.quantize(dq) else: op = price.quantize(self.pairs[loc].price_increment()) oq = quantity.quantize(self.pairs[loc].quantity_increment()) for x in book_side: if pid.inverted == 1: ap = x[0].quantize(dq) else: ap = x[0].quantize(self.pairs[loc].price_increment()) aq = x[1].quantize(self.pairs[loc].quantity_increment()) # only the price truly matters, the quantity is just # extra verification if op == ap: if oq == aq: # so both match, we found our order return [True, True] elif aq > oq: # only price matched BUT quantity is same # or higher, implies an existing order perhaps return [True, False] # we didnt find our order return [False, False] finally: lock.release() # Calculate Skew, which we mean to be the lag between when we place an order, # or action, and the orderbook of the market actually reports it. # We measure this by placing a small order, then seeing when it # shows up on the orderbook, timing that, then timing the cancellation # of that order def calcSkew(self, loc=0): # we don't actually use 'loc' at present, and just go by # checks on either drk or ltc as they are our most popular # currencies, and most likely to have some balance # Check to make sure we have a balance in the pair to trade on. if self.balances.getAvail( 'ltc') > 2 * self.pairs[loc].min_trade_quantity(): pid = self.pairs[0] else: return -2 mid = pid.midAsk() if mid[1] == 0: return False # These are higher than the mid price, and the quantity is small # times a random value which we can determine in our search random_end = random.random() * float( self.pairs[loc].min_trade_quantity()) our_quantity = self.pairs[loc].min_trade_quantity() + D( random_end).quantize(self.pairs[loc].quantity_increment()) our_price = mid[0] + self.pairs[loc].price_increment() # we want to find a price/quantity not on the book to make computation easier # THIS WILL NOT WORK ON FULL ORDER BOOKS v = 0 i = 0 while (v == 0 and i < 5): our_price += self.pairs[loc].price_increment() resp = self.findOrder(loc, our_price, our_quantity, 'ask') if resp == [False, False]: v = 1 else: i += 1 # this is true start of making the post, so is more accurate to us actuallyp lacing an order # since we are looking to see how long it takes to place an order and it show up on the # order book vs how long it takes from us posting to seeing if its on the book timer_order = time.perf_counter() opts = { 'loc': loc, 'side': 'ask', 'price': our_price, 'quantity': our_quantity } param = self.formatTrade(opts) try: resp = self.postPage(self.trade_var, param) except (KeyError, ValueError, TypeError, requests.ConnectionError, requests.Timeout, requests.HTTPError, requests.RequestException): logger.exception("in skewcalc after postpage") return False try: data = json.loads(resp) order_id = self.getOrderId(data) except (ValueError, KeyError, TypeError): logger.exception("in skewcalc after datalad") return False # Now we need to enter a loop and check for the order to show up end = 0 timer_end = 0 while (end == 0) and (timer_order + 30 > time.perf_counter()): resp = self.findOrder(loc, our_price, our_quantity, 'ask') if resp == [True, True]: timer_end = time.perf_counter() end = 1 break elif resp == [True, False] and self.mname == 'BTCe': timer_end = time.perf_counter() end = 1 break else: time.sleep(.00001) self.skew_order = timer_end - timer_order # Now we need to determine the time to cancel cancel_order = time.perf_counter() resp = self.cancelOrder(order_id, loc) cancel_end = 0 end = 0 while (end == 0) and (cancel_order + 30 > time.perf_counter()): resp = self.findOrder(loc, our_price, our_quantity, 'ask') if (resp == [False, False]) or (resp == [True, False]): cancel_end = time.perf_counter() end = 1 break else: time.sleep(.00001) self.skew_cancel = cancel_end - cancel_order # This means it failed somehow if self.skew_order < 0 or self.skew_cancel < 0: self.skew_order = 31 self.skew_cancel = 31 # no reason to cancel if we cancelled above try: self.cancelAllOrder() except: pass return True # This writes out to the trade log file, which should be a container # for every markets actual interactions with the exchange. def postlog(self, url=0, typ=0, params=0, response=0): filename = "logs/trade.logs" f = open(filename, 'a') a = "##################\n" b = "T:{0} ------>> {1} {2} {3}\n".format(int(time.time()), str(url), str(typ), str(a)) try: c = "<<------" + str(response) + "\n" except: c = "error encoding" + "\n" f.write(a + b + c + a) f.close() # This logger is for the order book. it dumps the freshly received book into # a file under the path of logs/orderbook/exchange/pair.name # the way it is written is by "timestamp --> 'exact html contents'" # this way of storing it will enable us to possibly rework or reformat # the servers replies without having stripped off or cleaned data in the # past. def orderbooklog(self, pair, resp=0): filename = "logs/orderbook/" + self.mname + "/" + pair.name f = open(filename, 'a') timestamp = str(time.time()) b = "--> " content = str(resp) + "\n" f.write(timestamp + b + content) f.close() def fakeTrade(self, loc, side, price, quant): self.last_quantity_traded = quant return True
def __init__(self, cur, url, rang=50, f=1.002, thrp=.02, thrm=0, mtq=[0, 0]): # An array of currency names self.curPairs = cur # The url is an ARRAY [] where 0 is the first bit # then we stop and continue after the curPair would be # added so that we have [0] + curPair + [1] for the # complete url. but our defURL will only have [0] and [1] self.defURL = url # The range or orderbook depth default 50 self.range = rang # Default fee is .2% # we write as 1.002 # This is a decimal from this point on self.fee = D(str(f)) # throttles should be deleted # Default throttle is 0 # this is time between calls self.throttle = thrm # we set this so that we can keep track self.throttle_updated = time.time() # Main orderbook pairs initialization process self.pairs = [] for i, x in enumerate(self.curPairs): if x != 0: # set the inverted bit if self.pairKey(x) == 'usd': self.pairs.append( Pair(self.mname, x, self.range, mtq[i], thrp, inv=1) ) # we make the currency pairs, thrp is the default pair throttle # non inverted, "normal" else: self.pairs.append( Pair(self.mname, x, self.range, mtq[i], thrp, inv=0) ) # we make the currency pairs, thrp is the default pair throttle else: self.pairs.append(x) # same process for trades history self.trades = [] for x in self.curPairs: if x != 0: self.trades.append( Trades(self.mname, x, self.range, thrp) ) # we make the currency pairs, thrp is the default pair throttle # now we open the trade file and get the last trade try: line = subprocess.check_output( ['tail', '-1', 'logs/trades/' + self.mname + '/' + x]) # now parse the trade y = line.split(',') self.trades[-1].last_trade = [ D(str(y[0])), D(str(y[1])), int(str(y[2])), int(str(y[3])), 'bid', str(time.time()) ] except: pass else: self.trades.append(x) # This is the balance sheet object self.balances = Balance() # this is the order array for an open "market maker" order self.open_order_mm = OrderList() # This indicates if the market is in some type of error # so we halt trading on it self.hold_trade = 0 # This variable indicates that we interacted in a trade # so we should call the cancelorders/setBalance # to update our book. self.need_update = 0 # Market was last alive at this point self.last_alive = time.time() # A way to count number of trades executed on this market self.totaltrades = 0 # Last quantity is a way for threading execution to get # the last traded amount since python threads cant # return the value that well. self.last_quantity_traded = D('-1') # The initial nonce is loaded from a saved file. This SHOULD # be quite close to the last one, but just in case we # will increment by 100 at the start to make sure we are not off # this could change later. # nonces are stored in nonce/ filename = "nonce/" + self.mname f = open(filename, 'r') self.initial_nonce = int(f.readline()) + 100 self.current_nonce = 0 f.close() self.writeNonce() # Function which gets initial balances for this market self.setBalance(initial=1) # skew for order placement, and order cancel self.skew_order = 10 self.skew_cancel = 10 # for competing on market making orders self.compete_price = [] for x in self.curPairs: self.compete_price.append(D('0'))