def keep_back(self, time): reference_curr = "XXBT" balance = self.account.balance eq_bal = balance[reference_curr] elem = dict() for bal in balance: if bal != reference_curr and not bal in self.constant["donottrade"]: pair = bal + reference_curr if self.price.has_key(pair): elem[pair] = hf.get_closest_elem(self.price[pair], time) eq_bal += balance[bal] * self.price[pair][elem[pair]][1] else: #not able to translate the currency directly to the reference currency... pair = "XXBT" + bal elem[pair] = hf.get_closest_elem(self.price[pair], time) eq_bal += balance[bal] / self.price[pair][elem[pair]][2] self.keep = dict() self.keep["XXBT"] = eq_bal * self.constant["delta"] for pair in elem: if pair.find("XXBT") == 0: self.keep[pair[4:]] = self.constant[ "delta"] * eq_bal * self.price[pair][elem[pair]][1] elif self.price[pair][elem[pair]][2] != 0: self.keep[pair[:4]] = self.constant[ "delta"] * eq_bal / self.price[pair][elem[pair]][2] else: self.keep[pair[:4]] = 0
def keep_back(self,time): reference_curr = "XXBT" balance = self.account.balance eq_bal = balance[reference_curr] elem = dict() for bal in balance: if bal!=reference_curr and not bal in self.constant["donottrade"]: pair = bal+reference_curr if self.price.has_key(pair): elem[pair] = hf.get_closest_elem(self.price[pair],time) eq_bal += balance[bal]*self.price[pair][elem[pair]][1] else: #not able to translate the currency directly to the reference currency... pair = "XXBT"+bal elem[pair] = hf.get_closest_elem(self.price[pair],time) eq_bal += balance[bal]/self.price[pair][elem[pair]][2] self.keep = dict() self.keep["XXBT"] = eq_bal*self.constant["delta"] for pair in elem: if pair.find("XXBT")==0: self.keep[pair[4:]] = self.constant["delta"] * eq_bal * self.price[pair][elem[pair]][1] elif self.price[pair][elem[pair]][2] != 0: self.keep[pair[:4]] = self.constant["delta"] * eq_bal / self.price[pair][elem[pair]][2] else: self.keep[pair[:4]] = 0
def get_sell_advice(self, time): allow_trade = dict() elem = dict() for pair in self.pairs: elem[pair] = hf.get_closest_elem(self.ma[pair]["bid"], time) if elem[pair] > self.constant["alpha"]: allow_trade[pair] = self.ma[pair]["bid"][elem[pair]][1] else: allow_trade[pair] = -1 if not all(val == -1 for val in allow_trade.values()): perform_trades = dict() for (pair, v) in allow_trade.items(): change = (self.price[pair][elem[pair]][2] - v) / v if v!=-1 and change >= self.constant["gamma"] and\ not pair[:4] in self.constant["donottrade"] and\ not pair[4:] in self.constant["donottrade"] and\ self.account.balance[pair[:4]]-self.keep[pair[:4]] > 0: #Ensures, that there is enough amount on this currency to trade #Check if transaction does not exceed the self.keep amount perform_trades[pair] = min(self.account.balance[pair[:4]]-self.keep[pair[:4]],\ change*self.constant["beta"]*self.account.balance[pair[:4]]) if (perform_trades): self.keep_back(time) return perform_trades return []
def get_buy_advice(self, time): allow_trade = dict() elem = dict() for pair in self.pairs: elem[pair] = hf.get_closest_elem(self.ma[pair]["ask"], time) if elem[pair] > self.constant["alpha"]: allow_trade[pair] = self.ma[pair]["ask"][elem[pair]][1] else: allow_trade[pair] = -1 if not all(val == -1 for val in allow_trade.values()): perform_trades = dict() for (pair, v) in allow_trade.items(): change = (v - self.price[pair][elem[pair]][1]) / v if v!=-1 and change >= self.constant["gamma"] and \ not pair[:4] in self.constant["donottrade"] and \ not pair[4:] in self.constant["donottrade"] and \ self.account.balance[pair[4:]]-self.keep[pair[4:]] > 0: perform_trades[pair] = min(self.account.balance[pair[4:]] - self.keep[pair[4:]] , \ change *self.constant["beta"]*self.account.balance[pair[4:]] * self.price[pair][elem[pair]][2]) / \ self.price[pair][elem[pair]][1] if (perform_trades): self.keep_back(time) return perform_trades return []
def get_sell_advice(self,time): allow_trade = dict() elem = dict() for pair in self.pairs: elem[pair] = hf.get_closest_elem(self.ma[pair]["bid"],time) if elem[pair] > self.constant["alpha"]: allow_trade[pair]=self.ma[pair]["bid"][elem[pair]][1] else: allow_trade[pair]=-1 if not all(val==-1 for val in allow_trade.values()): perform_trades = dict() for (pair,v) in allow_trade.items(): change = (self.price[pair][elem[pair]][2]-v)/v if v!=-1 and change >= self.constant["gamma"] and\ not pair[:4] in self.constant["donottrade"] and\ not pair[4:] in self.constant["donottrade"] and\ self.account.balance[pair[:4]]-self.keep[pair[:4]] > 0: #Ensures, that there is enough amount on this currency to trade #Check if transaction does not exceed the self.keep amount perform_trades[pair] = min(self.account.balance[pair[:4]]-self.keep[pair[:4]],\ change*self.constant["beta"]*self.account.balance[pair[:4]]) if (perform_trades): self.keep_back(time) return perform_trades return []
def get_buy_advice(self,time): allow_trade = dict() elem = dict() for pair in self.pairs: elem[pair] = hf.get_closest_elem(self.ma[pair]["ask"],time) if elem[pair] > self.constant["alpha"]: allow_trade[pair]=self.ma[pair]["ask"][elem[pair]][1] else: allow_trade[pair]=-1 if not all(val==-1 for val in allow_trade.values()): perform_trades = dict() for (pair, v) in allow_trade.items(): change = (v-self.price[pair][elem[pair]][1])/v if v!=-1 and change >= self.constant["gamma"] and \ not pair[:4] in self.constant["donottrade"] and \ not pair[4:] in self.constant["donottrade"] and \ self.account.balance[pair[4:]]-self.keep[pair[4:]] > 0: perform_trades[pair] = min(self.account.balance[pair[4:]] - self.keep[pair[4:]] , \ change *self.constant["beta"]*self.account.balance[pair[4:]] * self.price[pair][elem[pair]][2]) / \ self.price[pair][elem[pair]][1] if (perform_trades): self.keep_back(time) return perform_trades return []
def get_sell_advice(self,time): allow_trade = dict() elem = dict() for pair in self.pairs: elem[pair] = hf.get_closest_elem(self.ma[pair]["bid"],time) if elem[pair] > self.constant["window"]: allow_trade[pair]=self.ma[pair]["bid"][elem[pair]][1] else: allow_trade[pair]=-1 if not all(val==-1 for val in allow_trade.values()): perform_trades = dict() for (pair,v) in allow_trade.items(): change = (self.price[pair][elem[pair]][2]-v)/v if v!=-1 and change >= self.constant["x_thresh"]: """ Things to take care of: - enough balance to sell (incl. the min_vol), - bought balance does not exceed it's max_vol value """ # Get equivalent balance first, translate the pair currencies into the base eq_bal,rel_bal = hf.get_eq_bal(self.account.balance,self.price,time,'XXBT') if pair[4:] in self.constant['max_vol']: max_vol = self.constant['max_vol'][pair[4:]] else: max_vol = self.constant['max_vol']['default'] if pair[:4] in self.constant['min_vol']: min_vol = self.constant['min_vol'][pair[:4]] else: min_vol = self.constant['min_vol']['default'] #The max relative amount, which will be traded fac = 0.0 sell_lim = 0 if pair[:4] in rel_bal and rel_bal[pair[:4]]: fac = self.account.balance[pair[:4]]/rel_bal[pair[:4]] sell_lim = max(rel_bal[pair[:4]]-min_vol,0) else: self.account.balance[str(pair[:4])] = 0 if not pair[4:] in rel_bal: rel_bal[str(pair[4:])] = 0 buy_lim = max(max_vol - rel_bal[pair[4:]],0) rel_amount = min(sell_lim, buy_lim) #The max absolute amount, which will be sold abs_amountSell = min(rel_amount*fac, change*self.constant["trade_factor"]*self.account.balance[pair[:4]]) if abs_amountSell>0.01: #Kraken's minimum amount to trade perform_trades[pair] = abs_amountSell if (perform_trades): self.check_max_vol(time) return perform_trades return []
def starting_balance(self,time): ref = "XXBT" start_factor = 0.4 #to avoid starting with 0.0001 or 5 xbt (or zeur, or xeth, ....) for bal in self.account.balance: max_vol = self.trader.constant['max_vol']['default'] if bal in self.trader.constant['max_vol']: max_vol = self.trader.constant['max_vol'][bal] if not bal == ref: pair = bal+ref if pair in self.trader.price: elem = hf.get_closest_elem(self.trader.price[pair],time) self.account.balance[bal] = start_factor/self.trader.price[pair][elem][1]*max_vol else: pair = ref+bal elem = hf.get_closest_elem(self.trader.price[pair],time) self.account.balance[bal] = start_factor*self.trader.price[pair][elem][2]*max_vol else: self.account.balance[bal] = 1*start_factor
def simulate(self,n=-1): """ Simulates a trader's performance. creates new the variables eq_bal as equivalent balance (i.e. all values are transfered into Bitcoins (XBT) in order to compare them easily - be careful, this depends heavily on the exchange rates!!!) """ pair = "XETHXXBT" #self.trader.price.iterkeys().next() i=0 if n==-1: n = len(self.trader.price[pair]) elem = dict() start_time = self.trader.price[pair][len(self.trader.price[pair])-n][0] end_time = dt.datetime.now() self.starting_balance(start_time) balance = self.account.balance # Important: this copys only the pointer. changing balance will change self.account.balance if not self.optimize: s_balance = self.account.balance.copy() start_bal,_ = hf.get_eq_bal(balance,self.trader.price,start_time,'ZEUR') end_bal,_ = hf.get_eq_bal(balance,self.trader.price,end_time,'ZEUR') for key in self.trader.price[pair][len(self.trader.price[pair])-n:]: i=i+1 #Sell action advice = self.trader.get_sell_advice(key[0]) sold = dict() credit_item = dict((key,0) for key in balance) for pair in sorted(advice, key=lambda key: advice[key],reverse=True): if not elem.has_key(pair): elem[pair] = 0 sellFX = pair[:4] buyFX = pair[4:] elem[pair] = hf.get_closest_elem(self.trader.price[pair],key[0],elem[pair]) #Check if sufficient funds # TODO: add transaction fees dependent on numbers of transaction (change 2nd last index) amountBuy = advice[pair]*self.trader.price[pair][elem[pair]][2]*(1-self.account.asset_pair[pair]['fees'][0][1]/100) if advice[pair] > min(self.trader.keep,0.01) : balance[sellFX] -= advice[pair] credit_item[buyFX] += amountBuy sold[pair] = [advice[pair], amountBuy, self.trader.price[pair][elem[pair]][2]] # buy action advice = self.trader.get_buy_advice(key[0]) bought = dict() for pair in sorted(advice, key=lambda key: advice[key],reverse=True): if not elem.has_key(pair): elem[pair] = 0 buyFX = pair[:4] sellFX= pair[4:] elem[pair] = hf.get_closest_elem(self.trader.price[pair],key[0],elem[pair]) sellAmount = advice[pair]*self.trader.price[pair][elem[pair]][1]*(1-self.account.asset_pair[pair]['fees'][0][1]/100) #Chek if enough money is left to buy if advice[pair] > 0.01 : balance[sellFX] -= sellAmount credit_item[buyFX] += advice[pair] bought[pair] = [sellAmount, advice[pair], self.trader.price[pair][elem[pair]][1]] # Write credit items to the account balance if credit_item: for curr in credit_item: balance[curr] += credit_item[curr] eq_bal,rel_bal = hf.get_eq_bal(balance,self.trader.price,key[0],'ZEUR') if not self.optimize: if sold or bought: print "-----\nPerformed trade ($): sell: "+str(sold)+" buy: "+str(bought) s_eq_bal,_ = hf.get_eq_bal(s_balance,self.trader.price,key[0],'ZEUR') for bal in rel_bal: rel_bal[bal] = round(rel_bal[bal]*100,1) print str(key[0])+" "+str(i)+", Equivalent in "+self.reference_curr+": " + str(round(eq_bal,2))+\ ",\n\t Compared to market ("+str(round(s_eq_bal,2))+"): " + str(round((eq_bal/s_eq_bal-1)*100,2))+\ "%,\n\t Compared to start ("+str(round(start_bal,2))+"): " + str(round((eq_bal/start_bal-1)*100,2))+"%."+\ "\nRelative balances[%]: "+str(sorted(rel_bal.items(), key=lambda x: x[1], reverse=True)) print "Start balance: "+str(start_bal) print "Market adjusted end balance: "+str(end_bal) print "Return: "+str(eq_bal/start_bal*100-100)+"%" print "-----------------------\nSingle Positions:" for bal in balance: print str(bal) + ": "+str(balance[bal]) return eq_bal
def get_sell_advice(self, time): allow_trade = dict() elem = dict() for pair in self.pairs: elem[pair] = hf.get_closest_elem(self.ma[pair]["bid"], time) if elem[pair] > self.constant["window"]: allow_trade[pair] = self.ma[pair]["bid"][elem[pair]][1] else: allow_trade[pair] = -1 if not all(val == -1 for val in allow_trade.values()): perform_trades = dict() for (pair, v) in allow_trade.items(): change = (self.price[pair][elem[pair]][2] - v) / v if v != -1 and change >= self.constant["x_thresh"]: """ Things to take care of: - enough balance to sell (incl. the min_vol), - bought balance does not exceed it's max_vol value """ # Get equivalent balance first, translate the pair currencies into the base eq_bal, rel_bal = hf.get_eq_bal(self.account.balance, self.price, time, 'XXBT') if pair[4:] in self.constant['max_vol']: max_vol = self.constant['max_vol'][pair[4:]] else: max_vol = self.constant['max_vol']['default'] if pair[:4] in self.constant['min_vol']: min_vol = self.constant['min_vol'][pair[:4]] else: min_vol = self.constant['min_vol']['default'] #The max relative amount, which will be traded fac = 0.0 sell_lim = 0 if pair[:4] in rel_bal and rel_bal[pair[:4]]: fac = self.account.balance[pair[:4]] / rel_bal[ pair[:4]] sell_lim = max(rel_bal[pair[:4]] - min_vol, 0) else: self.account.balance[str(pair[:4])] = 0 if not pair[4:] in rel_bal: rel_bal[str(pair[4:])] = 0 buy_lim = max(max_vol - rel_bal[pair[4:]], 0) rel_amount = min(sell_lim, buy_lim) #The max absolute amount, which will be sold abs_amountSell = min( rel_amount * fac, change * self.constant["trade_factor"] * self.account.balance[pair[:4]]) if abs_amountSell > 0.01: #Kraken's minimum amount to trade perform_trades[pair] = abs_amountSell if (perform_trades): self.check_max_vol(time) return perform_trades return []