def model_transactions(self, my_candle, prior_signal, trader, prior_bank): ''' This is a basic model: 1. Spend full cash_bank at first BUY signal 2. Sell full crypto_bank at first SELL signal after a BUY. ''' # Delete the object if it already exists, we are re-calculating next Bank.objects.filter(crypto_candle=my_candle, user=trader).delete() # If current signal as the same as prior, we do not act, so bank will stay the same. if prior_signal != my_candle.signal: # This means we have cash on hand because prior action was SELL. if my_candle.signal == "BUY": my_bank = Bank(crypto_candle=my_candle, user=trader, crypto_bank=prior_bank.cash_bank / my_candle.period_close, cash_bank=0.0) buy_switch = "BUY" elif my_candle.signal == "SELL": my_bank = Bank(crypto_candle=my_candle, user=trader, crypto_bank=0.0, cash_bank=prior_bank.crypto_bank * my_candle.period_close) buy_switch = "SELL" else: my_bank = prior_bank buy_switch = my_candle.signal return (my_bank, buy_switch)
def transaction_history(self, trader_name="admin"): ''' Transaction history created for simulation subset. This is separate from self.update_signal because it always needs to go in chronological order whereas update_signal does not. ''' # initialize variables to be used in loop # we start with "SELL" because we haven't bought anything yet. buy_switch = "SELL" trader = get_user_model().objects.get_or_create( username=trader_name)[0] prior_sim = None # delete if bank object already exists, then re-create. Bank.objects.filter( signal_simulation__simulation=self.simulation, user=trader, signal_simulation__crypto_candle__crypto_traded=self.currency ).delete() for candle in self.candle_data.order_by('period_start_timestamp'): try: sim = get_object_or_404(SignalSimulation, crypto_candle=candle, simulation=self.simulation) except: # skip loop if SignalSimulation object is not found. next else: # Initialize our starting cash amount (we know it is beginning because there is no prior_sim. if prior_sim is None: my_bank = Bank( signal_simulation=sim, user=trader, # crypto_bank=(0.0), cash_bank='1.0') my_bank.save() elif sim.signal: # Remove HOLD signal, make sure it copies signal from prior day if sim.signal == "HOLD": if prior_sim.signal: sim.signal = prior_sim.signal # If we are missing prior signal, then we just assume "SELL" because we haven't bought. Because we are sorting by start date, this will only happen on day 1. else: sim.signal = "SELL" sim.save() # simulate our bank my_bank_results = self.create_transaction( sim, buy_switch, trader, my_bank) my_bank = my_bank_results[0] buy_switch = my_bank_results[1] prior_sim = sim return my_bank
def transaction_history(self, trader_name="admin"): ''' Transaction history created for simulation subset. This is separate from self.update_signal because it always needs to go in chronological order whereas update_signal does not. ''' # initialize variables to be used in loop buy_switch = "SELL" trader = get_user_model().objects.get_or_create( username=trader_name)[0] prior_sim = "" for candle in self.candle_subset.order_by('period_start_timestamp'): try: sim = get_object_or_404(SignalSimulation, crypto_candle=candle, simulation=self.simulation_obj) except: next else: # Initialize our starting cash amount. if prior_sim == "": # delete if bank object already exists, then re-create. Bank.objects.filter(signal_simulation=sim, user=trader).delete() my_bank = Bank( signal_simulation=sim, user=trader, # crypto_bank=(0.0), cash_bank='1.0') my_bank.save() elif sim.signal: # Remove HOLD signal, make sure it copies signal from prior day if sim.signal == "HOLD": sim.signal = prior_sim.signal sim.save() # simulate our bank my_bank_results = self.create_transaction( sim, buy_switch, trader, my_bank) my_bank = my_bank_results[0] buy_switch = my_bank_results[1] prior_sim = sim return my_bank
def create_transaction(self, my_sim, prior_signal, trader, prior_bank): ''' This is a basic model: 1. Spend full cash_bank at first BUY signal 2. Sell full crypto_bank at first SELL signal after a BUY. ''' # If current signal as the same as prior, we do not act, so bank will stay the same. if prior_signal != my_sim.signal and my_sim.signal != "HOLD": # This means we have cash on hand because prior action was SELL. if my_sim.signal == "BUY": my_bank = Bank( signal_simulation=my_sim, user=trader, crypto_bank=str( decimal.Decimal(prior_bank.cash_bank) / decimal.Decimal(my_sim.crypto_candle.period_close)), cash_bank=str(0.0)) buy_switch = "BUY" elif my_sim.signal == "SELL": my_bank = Bank( signal_simulation=my_sim, user=trader, crypto_bank=str(0.0), cash_bank=str( decimal.Decimal(prior_bank.crypto_bank) * decimal.Decimal(my_sim.crypto_candle.period_close))) buy_switch = "SELL" my_bank.save() else: my_bank = prior_bank buy_switch = my_sim.signal return (my_bank, buy_switch)
def update_signal(self): ''' Loops through candle subset to update signal and bank estimates. One-time update each time the data sources are updated. TODO (reminder): allow optional start/end date parameters ''' # initiate variables to be used in loop prior_candle = "" x = 0 buy_switch = "SELL" # for now, we are just trading with "admin" money trader_name = "admin" trader = get_user_model().objects.get_or_create(username=trader_name)[0] # below i want to make sure my delta is working along with my period interval. This will need to be updated once we introduce hourly intervals. if self.period_interval == "1d": delta_requirement = 1 # clear the fields before updating them self.candle_subset.update(signal=None, prior_period_candle=None) for candle in self.candle_subset.order_by('period_start_timestamp'): # For initial candle, we will initialize the bank and do nothing else. if prior_candle == "": Bank.objects.filter(crypto_candle=candle, user=trader).delete() my_bank = Bank(crypto_candle=candle, user=trader, crypto_bank=0.0, cash_bank=decimal.Decimal(1.0)) # Make sure we have required values to calculate signal: (1) a candle instance to compare against, (2) trend ratio to compare elif candle.search_trend.trend_ratio: candle_delta = candle.search_trend.date - prior_candle.search_trend.date # Make sure the two objects meet delta requirements if candle_delta.days == delta_requirement: result = self.calculate_signal(candle, prior_candle) # counting our success instances if result: x += 1 # simulate our bank my_bank_results = self.model_transactions(candle, buy_switch, trader, my_bank) my_bank = my_bank_results[0] buy_switch = my_bank_results[1] prior_candle = candle return f"Inserted {x} records on {timezone.now()}."