def reset_prd_var(dip=False): if not dip: self.cur_hgst_p = 0 self.prd_start = None else: self.cur_hgst_p = self.sec_hgst_p self.prd_start = dt_to_str(dt) self.cur_lwst_p, self.sec_hgst_p = 100000000, 0
def lst_prd_append(dip=False): dict_prd = {"count": prd_count, "start": self.prd_start, "end": dt_to_str(dt)} if not dip: dict_prd['type'] = "R" else: dict_prd['type'] = "D" self.lst_prd.append(dict_prd)
def get_dates(date): date1 = dt_to_str(str_to_dt(date) - timedelta(line_length)) date2 = dt_to_str(str_to_dt(date) + timedelta(line_length)) return date1, date2
def get_trades(self, aut_stp_pct, sell_pct, sec_sell, hld_days): def reset_trading_var(): self.ent_trggerd, self.in_trade = False, False self.ent_dt, self.sell_trggerd = None, False self.brk_tke_hg, self.aut_stp, self.ent_p = 0, 0, 0 self.stp_loss, self.pre_ent_stp, self.hgst_brk_res_p = 0, 0, 0 self.hld_days_lft = 0 def add_trades(exit_p, use_prev_dt=False): self.rsult_p = n_decim(exit_p - self.ent_p) self.rsult_pct = n_decim((exit_p - self.ent_p) / self.ent_p * 100) self.arr_rsult_p = np.append(self.arr_rsult_p, self.rsult_p) self.arr_rsult_pct = np.append(self.arr_rsult_pct, self.rsult_pct) if not use_prev_dt: exit_dt = sdt else: exit_dt = prev_day_dt lst_trades.append((self.rsult_p, self.rsult_pct, self.ent_dt, n_decim(self.ent_p), exit_dt, n_decim(exit_p))) def pct_change(p1, p2): return 1 - ((p1 - p2) / p1) def qualify_trigger(initial=True): lwr_res_stop, lwr_res_p = 0, 0 for res_stats in sorted(self.dict_res_stats[prd_count]): (res_p, _, res_stop, res_take) = res_stats if res_p > cl: if cl > self.pre_ent_stp and res_p - cl > cl - lwr_res_p: self.pre_ent_stp = lwr_res_stop if initial: self.ent_trggerd = True self.hld_days_lft = hld_days elif not initial: reset_trading_var() break else: lwr_res_stop = res_stop lwr_res_p = res_p aut_stp_pct = num_to_pct(aut_stp_pct) sell_pct = num_to_pct(sell_pct) sec_sell = num_to_pct(sec_sell) self.hld_days = hld_days self.dict_trades = {} dict_triggers_copy = copy.deepcopy(self.dict_triggers) self.arr_rsult_p, self.arr_rsult_pct = np.array([]), np.array([]) for period in self.lst_prd: lst_trades = [] prev_day_dt, prev_day_cl = None, 0 (prd_count, prd_start, prd_end, prd_type) = period_info(period) reset_trading_var() six_months = datetime.timedelta(180) pre_period_start = dt_to_str(str_to_dt(prd_start) - six_months) for day in self.ohlc_table[pre_period_start:prd_end].itertuples(): (dt, op, hg, lw, cl) = day sdt = dt_to_str(dt) enter_new_trade = not self.in_trade and self.ent_trggerd if enter_new_trade and dt >= str_to_dt(prd_start): if self.hld_days_lft == 0: if op > self.pre_ent_stp: self.ent_dt = sdt self.ent_p = op self.in_trade = True self.aut_stp = n_decim(op * aut_stp_pct) else: reset_trading_var() else: if cl > op and cl > prev_day_cl: qualify_trigger(initial=False) self.hld_days_lft -= 1 else: reset_trading_var() else: self.ent_trggerd = False self.pre_ent_stp = 0 if self.sell_trggerd: add_trades(op) reset_trading_var() if self.in_trade and sdt in self.lst_earnings_dt: if np.busday_count(self.ent_dt, sdt) > 4: add_trades(prev_day_cl, use_prev_dt=True) reset_trading_var() if self.in_trade: higher_res_p, higher_res_take = 0, 0 for (res_p, *_) in self.dict_res_stats[prd_count]: if cl > res_p: if res_p > self.hgst_brk_res_p: self.hgst_brk_res_p = res_p self.brk_tke_hg = 0 break for res_stats in self.dict_res_stats[prd_count]: (res_p, _, res_stop, res_take) = res_stats same_zone = res_p == self.hgst_brk_res_p if res_stop < op and op < res_p and same_zone: if hg > higher_res_take and pct_change(hg, cl) < sell_pct or\ hg > higher_res_p and pct_change(hg, cl) < sec_sell: if cl < higher_res_p: self.sell_trggerd = True self.stp_loss = res_stop break elif res_p < op: if hg > higher_res_p: if cl < higher_res_p: if pct_change(hg, cl) < sec_sell: self.sell_trggerd = True self.brk_tke_hg = 0 if hg > higher_res_take: if cl < higher_res_p: if hg > self.brk_tke_hg: self.brk_tke_hg = hg if pct_change(hg, cl) < sell_pct: self.sell_trggerd = True self.brk_tke_hg = 0 if self.brk_tke_hg: if pct_change(self.brk_tke_hg, cl) < sell_pct: if cl < higher_res_p: self.sell_trggerd = True self.brk_tke_hg = 0 self.stp_loss = res_stop break higher_res_p = res_p higher_res_take = res_take if self.stp_loss > self.aut_stp: if lw < self.stp_loss: if op > self.stp_loss: add_trades(self.stp_loss) else: add_trades(op) reset_trading_var() else: if self.in_trade and lw < self.aut_stp: if op >= self.aut_stp: add_trades(self.aut_stp) else: add_trades(op) reset_trading_var() prev_day_dt = sdt prev_day_cl = cl for trigger in dict_triggers_copy[prd_count].copy(): (trg_dt, trg_p, trg_start_dt, trg_end_dt) = trigger if cl > trg_p and dt > trg_start_dt or dt > trg_end_dt: dict_triggers_copy[prd_count].remove(trigger) if self.in_trade or self.ent_trggerd: continue if cl > trg_p and dt == trg_end_dt: qualify_trigger() previous_day_loss = False breakout_day = True after_prd_end = str_to_dt(prd_end) + six_months if self.in_trade: for day in self.ohlc_table[prd_end:after_prd_end].itertuples(): (dt, op, hg, lw, cl) = day hgst_stp = n_decim(self.dict_res_stats[prd_count][0][2]) self.stp_loss = hgst_stp if cl < self.stp_loss and not breakout_day: add_trades(self.stp_loss) break if previous_day_loss: if cl < op: add_trades(cl) break if cl > op: previous_day_loss = False if cl < op: previous_day_loss = True breakout_day = False self.dict_trades[prd_count] = lst_trades
def lst_trg_add(): return dt_to_str(pot_dt1), pot_p1, pot_dt2, pot_inv_dt1
def get_triggers(self, days_apart, inv_days, hld_bef, hld_aft, hg_diff): def lst_trg_add(): return dt_to_str(pot_dt1), pot_p1, pot_dt2, pot_inv_dt1 self.dict_triggers = {} inv_dt = datetime.timedelta(inv_days) six_months = datetime.timedelta(180) hg_diff = hg_diff / 100 total_hld = hld_bef + hld_aft + 1 peak_i = hld_bef for period in self.lst_prd: prev_days_cl, prev_days_dt, lst_pot_trg, lst_trg = [], [], [], [] (prd_count, prd_start, prd_end, prd_type) = period_info(period) pre_period_start = dt_to_str(str_to_dt(prd_start) - six_months) selected_period = self.ohlc_table[pre_period_start:prd_end] for day in selected_period.itertuples(): (dt, op, hg, lw, cl) = day if len(prev_days_cl) > total_hld: del prev_days_cl[0] del prev_days_dt[0] if hg_lw_finder(peak_i, prev_days_cl): hg_dt = prev_days_dt[peak_i] hg_cl = prev_days_cl[peak_i] lst_pot_trg.append([hg_dt, hg_cl, hg_dt + inv_dt]) prev_days_cl.append(cl) prev_days_dt.append(dt) for pot_trigger in lst_pot_trg: (_, pot_trg_p, pot_inv_dt) = pot_trigger if cl > pot_trg_p and dt < pot_inv_dt: pot_trigger[2] = dt for index, pot_trg1 in enumerate(lst_pot_trg.copy()): (pot_dt1, pot_p1, pot_inv_dt1) = pot_trg1 for pot_trg2 in lst_pot_trg[index+1:].copy(): (pot_dt2, pot_p2, _) = pot_trg2 trg_pct_diff = (pot_p1 - pot_p2) / pot_p1 if pot_inv_dt1 >= pot_dt2 and np.busday_count(dt_to_str( pot_dt1), dt_to_str(pot_dt2)) > days_apart and\ trg_pct_diff <= hg_diff and trg_pct_diff >= 0: if len(lst_trg) > 0: added_to_list = False for index2, (trg_dt, *_) in enumerate(lst_trg): if pot_dt1 < str_to_dt(trg_dt): pot_dt1 = dt_to_str(pot_dt1) lst_trg.insert(index2, lst_trg_add()) added_to_list = True break if not added_to_list: lst_trg.append(lst_trg_add()) else: lst_trg.append(lst_trg_add()) break self.dict_triggers[prd_count] = sorted(lst_trg)
def get_periods(self, pct_drop, sec_drop, only_rec): def reset_prd_var(dip=False): if not dip: self.cur_hgst_p = 0 self.prd_start = None else: self.cur_hgst_p = self.sec_hgst_p self.prd_start = dt_to_str(dt) self.cur_lwst_p, self.sec_hgst_p = 100000000, 0 def test_pre_prd(years=10): test_dt = str(int(self.prd_start[:4]) - years) return self.ohlc_table[test_dt] def lst_prd_append(dip=False): dict_prd = {"count": prd_count, "start": self.prd_start, "end": dt_to_str(dt)} if not dip: dict_prd['type'] = "R" else: dict_prd['type'] = "D" self.lst_prd.append(dict_prd) def dict_prd_stats_add(): self.dict_prd_stats[prd_count] = (self.cur_hgst_p, self.cur_lwst_p) pct_drop = num_to_pct(pct_drop) sec_drop = num_to_pct(sec_drop) reset_prd_var() prd_count = 1 self.lst_prd, self.dict_prd_stats = [], {} for day in self.ohlc_table.itertuples(): (dt, op, hg, lw, cl) = day if not self.prd_start: if cl > self.cur_hgst_p: self.cur_hgst_p = cl if cl < (self.cur_hgst_p * pct_drop): self.prd_start = dt_to_str(dt) else: if cl > self.cur_hgst_p: try: test_pre_prd() except KeyError: reset_prd_var() continue lst_prd_append() dict_prd_stats_add() reset_prd_var() prd_count += 1 continue if cl < self.cur_lwst_p: self.cur_lwst_p = cl if not only_rec: if cl > (self.cur_lwst_p * 1.5) and cl > self.sec_hgst_p: self.sec_hgst_p = cl if self.sec_hgst_p and cl < (self.sec_hgst_p * sec_drop): try: test_pre_prd() except KeyError: reset_prd_var(dip=True) continue lst_prd_append(dip=True) dict_prd_stats_add() reset_prd_var(dip=True) prd_count += 1