class Worker(object): def __init__(self, instrument, granularity, models_loc): while True: self.market_encoder = LSTMEncoder() self.actor_critic = ActorCritic() self.encoder_to_others = EncoderToOthers() try: self.market_encoder.load_state_dict(torch.load(models_loc + 'market_encoder.pt', map_location='cpu')) self.encoder_to_others.load_state_dict(torch.load(models_loc + 'encoder_to_others.pt', map_location='cpu')) self.actor_critic.load_state_dict(torch.load(models_loc + 'actor_critic.pt', map_location='cpu')) self.market_encoder = self.market_encoder.cpu() self.encoder_to_others = self.encoder_to_others.cpu() self.actor_critic = self.actor_critic.cpu() break except Exception: print("Failed to load models") time.sleep(0.1) self.models_loc = models_loc self.instrument = instrument self.granularity = granularity self.zeus = Zeus(instrument, granularity) self.live = False self.time_states = [] self.window = networks.WINDOW self.tradeable_percentage = 1 self.trade_percent = self.tradeable_percentage / 1000 def add_bar(self, bar): time_state = [[[bar.open, bar.high, bar.low, bar.close, np.log(bar.volume + 1e-1)]]] if len(self.time_states) == 0 or time_state != self.time_states[-1]: self.time_states.append(time_state) else: return if len(self.time_states) == self.window + 1: del self.time_states[0] if len(self.time_states) == self.window and self.live: in_ = self.zeus.position_size() available_ = self.zeus.units_available() percent_in = (in_ / (abs(in_) + available_ + 1e-9)) / self.tradeable_percentage input_time_states = torch.Tensor(self.time_states).view(self.window, 1, networks.D_BAR).cpu() mean = input_time_states[:, 0, :4].mean() std = input_time_states[:, 0, :4].std() input_time_states[:, 0, :4] = (input_time_states[:, 0, :4] - mean) / std spread_normalized = bar.spread / std market_encoding = self.market_encoder.forward(input_time_states) market_encoding = self.encoder_to_others.forward(market_encoding, torch.Tensor([spread_normalized]), torch.Tensor([percent_in])) policy, value = self.actor_critic.forward(market_encoding) # action = torch.argmax(policy).item() action = torch.multinomial(policy, 1).item() def place_action(desired_percent): current_percent_in = percent_in * self.tradeable_percentage if desired_percent == 0 and current_percent_in != 0: self.zeus.close_units(self.zeus.position_size()) elif desired_percent > 0 and current_percent_in > 0: if desired_percent > current_percent_in: total_tradeable = abs(self.zeus.position_size()) + self.zeus.units_available() self.zeus.place_trade(int(abs(desired_percent - current_percent_in) * total_tradeable), "Long") else: total_tradeable = abs(self.zeus.position_size()) + self.zeus.units_available() self.zeus.close_units(int(abs((desired_percent - current_percent_in)) * total_tradeable)) elif desired_percent > 0 and current_percent_in <= 0: self.zeus.close_units(self.zeus.position_size()) total_tradeable = abs(self.zeus.position_size()) + self.zeus.units_available() self.zeus.place_trade(int(abs(desired_percent) * total_tradeable), "Long") elif desired_percent < 0 and current_percent_in > 0: self.zeus.close_units(self.zeus.position_size()) total_tradeable = abs(self.zeus.position_size()) + self.zeus.units_available() self.zeus.place_trade(int(abs(desired_percent) * total_tradeable), "Short") elif desired_percent < 0 and current_percent_in <= 0: if desired_percent <= current_percent_in: total_tradeable = abs(self.zeus.position_size()) + self.zeus.units_available() self.zeus.place_trade(int(abs(desired_percent - current_percent_in) * total_tradeable), "Short") else: total_tradeable = abs(self.zeus.position_size()) + self.zeus.units_available() self.zeus.close_units(int(abs((desired_percent - current_percent_in)) * total_tradeable)) change_amounts = {0:-100, 1:-50, 2:-10, 3:-5, 4:-1, 5:0, 6:1, 7:5, 8:10, 9:50, 10:100} if action in change_amounts: desired_percent_in = (percent_in * self.tradeable_percentage) + (self.trade_percent * change_amounts[action]) desired_percent_in = np.clip(desired_percent_in, -self.tradeable_percentage, self.tradeable_percentage) place_action(desired_percent_in) print("instrument", self.instrument) print("purchased:", change_amounts[action]) print("percent in:", round(percent_in, 5)) for i, policy_ in enumerate(policy.tolist()[0]): print("probability {i}: {p}".format(i=i, p=round(policy_, 5))) print("-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-") torch.cuda.empty_cache() def run(self): self.market_encoder.eval() self.encoder_to_others.eval() self.actor_critic.eval() print("fetching last", self.window, "bars...") self.zeus.stream_bars(self.window, self.add_bar) print("going live...") self.live = True self.zeus = Zeus(self.instrument, self.granularity, live=True) self.zeus.stream_live(self.add_bar)
class Worker(object): def __init__(self, instrument, granularity, n_steps, models_loc): self.server = redis.Redis("localhost") self.instrument = instrument self.granularity = granularity self.zeus = Zeus(instrument, granularity) while True: # putting this while loop here because sometime the optimizer # is writing to the files and causes an exception # self.market_encoder = AttentionMarketEncoder(device='cpu') self.market_encoder = CNNEncoder().cpu() self.decoder = ClassifierDecoder().cpu() try: self.market_encoder.load_state_dict( torch.load(models_loc + 'market_encoder.pt')) self.decoder.load_state_dict( torch.load(models_loc + 'decoder.pt')) self.market_encoder = self.market_encoder.cpu() self.decoder = self.decoder.cpu() break except Exception as e: print(e) self.trajectory_steps = float( self.server.get("trajectory_steps").decode("utf-8")) self.window = networks.WINDOW self.n_steps = n_steps self.time_states = [] self.trade = None self.pos = None self.n_steps_future = 1 self.steps_since_trade = 1 self.cur_value = self.zeus.unrealized_balance() self.prev_value = self.cur_value self.n = 0 self.n_profit = 0 self.n_loss = 0 self.n_buy = 0 self.n_sell = 0 self.n_stay = 0 self.profit = 0 self.stop_loss = None self.take_profit = None def add_bar(self, bar): if self.pos == "Long" and self.trade is not None: if bar.close > self.take_profit or bar.close < self.stop_loss: self.zeus.close_trade(self.trade) self.trade = None elif self.pos == "Short" and self.trade is not None: if bar.close < self.take_profit or bar.close > self.stop_loss: self.zeus.close_trade(self.trade) self.trade = None time_state = torch.Tensor([ bar.open, bar.high, bar.low, bar.close, np.log(bar.volume + 1e-1) ]).view(1, 1, -1) self.time_states.append(time_state) if len(self.time_states) > self.window: del self.time_states[0] spread = bar.spread if len(self.time_states) == self.window and ( self.steps_since_trade >= self.n_steps_future or (self.pos != "Stay" and self.trade is None)): print(bar) print(self.trade) time_states_ = torch.cat(self.time_states, dim=1).clone() mean = time_states_[:, :, :4].contiguous().view(1, -1).mean(1).view( 1, 1, 1) std = time_states_[:, :, :4].contiguous().view(1, -1).std(1).view( 1, 1, 1) time_states_[:, :, :4] = (time_states_[:, :, :4] - mean) / std spread_ = torch.Tensor([spread]).view(1, 1, 1) / std time_states_ = time_states_.transpose(0, 1) self.n_steps_future = self.trajectory_steps # confidence_interval = np.random.exponential(0.0015) confidence_interval = 0.001 print("confidence:", confidence_interval) market_encoding = self.market_encoder.forward(time_states_) probabilities = self.decoder.forward( market_encoding, spread_ * std, std, torch.Tensor([confidence_interval])) print(probabilities) # action = int(torch.argmax(probabilities.squeeze())) # print("argmax") # action = int(torch.argmax(probabilities.squeeze()[:2])) # print("argmax without hold") action = int(torch.multinomial(probabilities.squeeze(), 1)) print("sampled") # action = int(torch.multinomial(probabilities.squeeze()[:2], 1)) # print("sampled without hold") # action = np.random.randint(0, 2) # print("random") if action == 0: self.stop_loss = self.time_states[-1][0, 0, 3] * ( 1 - confidence_interval) - spread self.take_profit = self.time_states[-1][0, 0, 3] * ( 1 + confidence_interval) - spread self.n_buy += 1 if self.pos != "Long": if self.trade is not None: self.zeus.close_trade(self.trade) self.trade = self.zeus.place_trade(100, "Long") self.pos = "Long" print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++++") elif action == 1: self.stop_loss = self.time_states[-1][0, 0, 3] * ( 1 + confidence_interval) - spread self.take_profit = self.time_states[-1][0, 0, 3] * ( 1 - confidence_interval) - spread self.n_sell += 1 if self.pos != "Short": if self.trade is not None: self.zeus.close_trade(self.trade) self.trade = self.zeus.place_trade(100, "Short") self.pos = "Short" print( "-------------------------------------------------------") else: self.stop_loss = None self.take_profit = None self.n_stay += 1 if self.trade is not None: self.zeus.close_trade(self.trade) self.trade = None self.pos = "Stay" print( "///////////////////////////////////////////////////////") self.cur_value = self.zeus.unrealized_balance() print(self.cur_value) self.steps_since_trade = 0 if self.prev_value < self.cur_value: self.n_profit += 1 elif self.prev_value > self.cur_value: self.n_loss += 1 self.profit += self.cur_value - self.prev_value self.n += 1 print("profit this trade:", self.cur_value - self.prev_value) print("profit:", self.profit) print("profit per trade:", self.profit / self.n) print("gain per trade:", self.profit / (self.n * 1000)) print("p loss:", self.n_loss / self.n) print("p profit:", self.n_profit / self.n) print("total trades:", self.n) print("p buy:", self.n_buy / self.n) print("p sell:", self.n_sell / self.n) print("p stay:", self.n_stay / self.n) print() self.prev_value = self.cur_value else: self.steps_since_trade += 1 def run(self): self.zeus.stream_bars(self.n_steps, self.add_bar)
class Worker(object): def __init__(self, instrument, granularity, n_steps, models_loc): self.server = redis.Redis("localhost") self.instrument = instrument self.granularity = granularity self.zeus = Zeus(instrument, granularity) while True: # putting this while loop here because sometime the optimizer # is writing to the files and causes an exception # self.market_encoder = AttentionMarketEncoder(device='cpu') self.market_encoder = CNNEncoder().cpu() self.decoder = Decoder().cpu() try: self.market_encoder.load_state_dict( torch.load(models_loc + 'market_encoder.pt')) self.decoder.load_state_dict( torch.load(models_loc + 'decoder.pt')) self.market_encoder = self.market_encoder.cpu() self.decoder = self.decoder.cpu() break except Exception as e: print(e) self.window = networks.WINDOW self.n_steps = n_steps self.time_states = [] self.trade = None self.pos = None self.n_steps_future = 1 self.steps_since_trade = 1 self.cur_value = self.zeus.unrealized_balance() self.prev_value = self.cur_value self.n = 0 self.n_profit = 0 self.n_loss = 0 self.n_buy = 0 self.n_sell = 0 self.n_stay = 0 self.profit = 0 def add_bar(self, bar): time_state = torch.Tensor([ bar.open, bar.high, bar.low, bar.close, np.log(bar.volume + 1e-1) ]).view(1, 1, -1) self.time_states.append(time_state) if len(self.time_states) > self.window: del self.time_states[0] spread = bar.spread if len( self.time_states ) == self.window and self.steps_since_trade >= self.n_steps_future: if self.trade is not None: self.zeus.close_trade(self.trade) time_states_ = torch.cat(self.time_states, dim=1).clone() mean = time_states_[:, :, :4].contiguous().view(1, -1).mean(1).view( 1, 1, 1) std = time_states_[:, :, :4].contiguous().view(1, -1).std(1).view( 1, 1, 1) time_states_[:, :, :4] = (time_states_[:, :, :4] - mean) / std spread_ = torch.Tensor([spread]).view(1, 1, 1) / std time_states_ = time_states_.transpose(0, 1) self.n_steps_future = np.random.randint(1, 60) self.n_steps_future = 30 print(self.n_steps_future) market_encoding = self.market_encoder.forward(time_states_) value_ = self.decoder.forward( market_encoding, spread_, torch.Tensor([self.n_steps_future]).log()) print(value_) # action = int(torch.argmax(torch.cat([value_.squeeze(), torch.Tensor([0])], dim=0))) # print("calculated with 0") action = int(torch.argmax(value_.squeeze())) print("calculated without 0") # action = np.random.randint(0, 2) # print("random") if action == 0: self.n_buy += 1 if self.pos != "Long": self.trade = self.zeus.place_trade(1000, "Long") self.pos = "Long" print( "+++++++++++++++++++++++++++++++++++++++++++++++++++++++") elif action == 1: self.n_sell += 1 if self.pos != "Short": self.trade = self.zeus.place_trade(1000, "Short") self.pos = "Short" print( "-------------------------------------------------------") else: self.n_stay += 1 self.trade = None self.pos = "Stay" print( "///////////////////////////////////////////////////////") self.cur_value = self.zeus.unrealized_balance() print(self.cur_value) self.steps_since_trade = 0 if self.prev_value < self.cur_value: self.n_profit += 1 elif self.prev_value > self.cur_value: self.n_loss += 1 self.profit += self.cur_value - self.prev_value self.n += 1 print("profit this trade:", self.cur_value - self.prev_value) print("profit:", self.profit) print("profit per trade:", self.profit / self.n) print("gain per trade:", self.profit / (self.n * 1000)) print("p loss:", self.n_loss / self.n) print("p profit:", self.n_profit / self.n) print("total trades:", self.n) print("p buy:", self.n_buy / self.n) print("p sell:", self.n_sell / self.n) print("p stay:", self.n_stay / self.n) print() self.prev_value = self.cur_value else: self.steps_since_trade += 1 def run(self): self.zeus.stream_bars(self.n_steps, self.add_bar)