Exemple #1
0
def show_ret_diff(dt, rdf, window = 1000, root1 = 'ZN',root2 = 'ZB', ax = plt):
    sym1 = utils.get_front_symbol(dt, root1)
    sym2 = utils.get_front_symbol(dt, root2)

    try:
        df1 = utils.load_day(dt, sym1)
        df2 = utils.load_day(dt, sym2)  
    except:
        return
    
    
    a1 = rdf[rdf.DATE == int(dt.strftime('%Y%m%d'))].true_bin - 10
    
    a2 = a1 + window
    
    ret1 = (df1.microprice.values[a1:a2] - df1.microprice.values[a1 - 10]) / float(df1.microprice.values[a1 - 10])
    ret2 = (df2.microprice.values[a1:a2] - df2.microprice.values[a1 - 10]) / float(df2.microprice.values[a1 - 10])
    
    ax.plot(ret1/ret2)
    
    #ax.plot(ret1)
    #ax.plot(ret2)
    
    try:
        ax.set_title(dt)
    except:
        ax.title(dt)
Exemple #2
0
def directional_bt(rdf,
                   stats,
                   stats2,
                   root = 'ZN',
                   entry_time = 5,
                   exit_time = 2000,
                   go_thres = 0,
                   size_mult= 10,
                  ):    
    data = {}

    for dt in sorted(rdf.DATE.unique()):
    
        ttt = rdf[rdf.DATE == dt]
    
        offset = ttt.true_bin.values[0]
        dtt = datetime.strptime(str(dt),'%Y%m%d')
        sym = utils.get_front_symbol(dtt, root) 
        try:
            df = utils.load_day(dtt, sym, res ='0', root=root)
        except:
            continue
        
        is_buy = True
        
        a_s = ttt.a_s.values[0]
              
        if a_s < go_thres:
            is_buy = True
        elif a_s  >= go_thres:
            is_buy = False
        else:
            continue
            
        res = utils.true_profit(df,
                      is_buy=is_buy,
                      size = np.abs(a_s*size_mult),
                      num_levels = max(1,int(np.abs(a_s) / 10.0)), 
                      offset1 = offset + entry_time, 
                      offset2 = offset + exit_time, 
                      mpi= utils.get_mpi(root, dt=dtt), 
                      tick_price = utils.get_dpt(root, dt=dtt))
        data[dt] = res
        
        results = {}
        results['data'] = data
        results['root'] = root
        results['entry_time'] = entry_time
        results['exit_time'] = exit_time
        results['go_thres'] = go_thres
        results['size_mult'] = size_mult
    return results
Exemple #3
0
def detect(rdf,root='ZN', dtt='20110708', window=100, ax=plt, make_picture=True, offset = 1800):
    dt = datetime.strptime(str(dtt), '%Y%m%d')
    
    offset = rdf[rdf.DATE == int(dt.strftime('%Y%m%d'))]['bin'].values[0] * 10
    
    try:
        sym = utils.get_front_symbol(dt, root)
        fine = utils.load_day(dt,sym, res='0',root=root)
    except:
        return -1
        
    sample_vol = (fine.buy_vol + fine.sell_vol).values[offset-window:offset+window]
    sample_price = fine.microprice.values[offset-window:offset+window]
    sample_price_diff = np.diff(sample_price)

    fine_offset_vol = offset - window + np.argmax(sample_vol)

    fine_offset_price1 = offset - window + np.argmax(sample_price_diff) + 1
    fine_offset_price2 = offset - window + np.argmin(sample_price_diff) + 1

    fine_offset = -1
    
    if fine_offset_price1 == fine_offset_vol or fine_offset_price2 == fine_offset_vol:
        fine_offset = fine_offset_vol
    else:
        vol_thres = np.max(sample_vol) / 10 
        for i in xrange(len(sample_vol)):
            if sample_vol[i] > vol_thres:
                fine_offset_vol = offset - window + i
                if fine_offset_price1 == fine_offset_vol or fine_offset_price2 == fine_offset_vol:
                    fine_offset = fine_offset_vol
                break
                
                
    a_s = rdf[rdf.DATE == int(dtt)].a_s.values[0]

    if make_picture == True:
        ax.plot(sample_vol, '-')
        ax.twinx().plot(sample_price - sample_price[0], 'r-')
        ax.set_title( '%s %s %s %d' % (sym, dtt, fine_offset, a_s))
    
    return fine_offset
Exemple #4
0
def make_daily_returns_frame(roots,
                             true_offset,
                             dtt='20110708',
                             intervals = None):
    
    dt = datetime.strptime(str(dtt), '%Y%m%d')

    data = []
    for root in roots:
        root_data = []
        root_data.append(dtt)        
        root_data.append(root)
        sym = utils.get_front_symbol(dt, root) 
        
        has_data = True
    
        try:
            fine = utils.load_day(dt,sym, res='0',root=root)
        except:
            has_data = False
        
        if has_data and len(fine) <  288001:
            has_data = False
            print len(fine), dt, root
            
        if has_data:    
            for interval in intervals:
                root_data.append(fine.microprice.values[true_offset + interval])
        else:
            for interval in intervals:
                root_data.append(0)
        
        data.append(root_data)
        
        cols = ['DATE', 'ROOT']
        for interval in intervals:
            cols.append(interval)
        
    return pd.DataFrame(data, columns=cols)
Exemple #5
0
from utils import load_day

day_six_input = load_day(6, sample=False, split=False).split('\n\n')

# Part 1
n = 0
for group in day_six_input:
    c = set.union(*(set(row) for row in group.split()))
    n += len(c)
print(f'Part 1: {n}')

# Part 2
n = 0
for group in day_six_input:
    c = set.intersection(*(set(row) for row in group.split()))
    n += len(c)
print(f'Part 2: {n}')
Exemple #6
0
from utils import load_day

equations = load_day(18)


def find_closing_parens(s, idx, n_parens=1):
    lookup = {'(': 1, ')': -1}
    while n_parens >= 1:
        n_parens += lookup.get(s[idx], 0)
        idx += 1
    return idx - 1


def find_closing_space(s, idx):
    try:
        return s.index(' ', idx)
    except ValueError:
        return len(s)


def to_int_or_symbol(eq):
    try:
        return int(eq)
    except ValueError:
        return eq.strip()


def evaluate_equation(eq, eval_fn):
    idx = 0
    eq_parts = []
    while idx < len(eq):
Exemple #7
0
from itertools import combinations

from utils import load_day

# Part 1
day_one_input = {int(v) for v in load_day(1)}
for n in day_one_input:
    paired_value = 2020 - n
    if paired_value in day_one_input:
        break

print('Part 1: {}'.format(n * paired_value))

# Part 2
day_one_input = [int(v) for v in load_day(1)]
for combo in combinations(day_one_input, 3):
    if sum(combo) == 2020:
        break

print('Part 2: {}'.format(combo[0] * combo[1] * combo[2]))
Exemple #8
0
from collections import defaultdict

import numpy as np

from utils import load_day

data = load_day(16, split=False)

# Part 1
values, your_ticket, nearby_tickets = data.split('\n\n')
your_ticket = np.array([int(v) for v in your_ticket.split('\n')[1].split(',')])


def str_to_range(r):
    return tuple(int(v) for v in r.split('-'))


def find_all_ranges(values):
    all_ranges = {}
    for row in values.split('\n'):
        name, criteria = row.split(':')
        small, _, large = criteria.split()
        all_ranges[name] = [str_to_range(small), str_to_range(large)]
    return all_ranges


def valid_range(v, ranges):
    return any(r[0] <= v <= r[1] for r in ranges)


range_dict = find_all_ranges(values)
Exemple #9
0
import numpy as np

from utils import load_day

day_3_map = load_day(3)


def traverse_mountain(dx, dy, x=0, y=0):
    w = len(day_3_map[0])
    n_trees = 0
    while y < len(day_3_map):
        if day_3_map[y][x] == '#':
            n_trees += 1
        x, y = (x + dx) % w, (y + dy)
    return n_trees


# Part 1
trees = traverse_mountain(3, 1)
print('Part 1: {}'.format(trees))

# Part 2
slopes = [(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)]
all_trees = np.prod([traverse_mountain(*s) for s in slopes])
print('Part 2: {}'.format(all_trees))
Exemple #10
0

def rotate(x, y, degrees):
    theta = np.deg2rad(degrees)
    xp = x * cos(theta) - y * sin(theta)
    yp = x * sin(theta) + y * cos(theta)
    return round(xp), round(yp)


dirs = {
    'N': (0, 1),
    'S': (0, -1),
    'E': (1, 0),
    'W': (-1, 0),
}
commands = load_day(12, sample=False)

# Part 1
x, y = 0, 0
hx, hy = 1, 0
for command in commands:
    cmd, amt = command[0], int(command[1:])
    if cmd in ('N', 'S', 'E', 'W'):
        dx, dy = dirs[cmd]
        x += dx * amt
        y += dy * amt
    elif cmd in ('L', 'R'):
        degrees = amt if cmd == 'L' else -amt
        hx, hy = rotate(hx, hy, degrees)
    elif cmd == 'F':
        x += hx * amt
Exemple #11
0
import os

import numpy as np
from scipy.signal import convolve2d

from utils import load_day

photo_data = load_day(20, sample=False, split=False).split('\n\n')
w = int(np.sqrt(len(photo_data)))


def parse_all_photos(photo_data):
    photos = {}
    for photo in photo_data:
        photo_raw = photo.split('\n')
        photo_id = photo_raw[0].replace(':', '').split()[1]
        photo = np.array([
            [c == '#' for c in p]
            for p in photo_raw[1:]
        ])
        photos[photo_id] = photo
    return photos


def all_orientations(photo):
    photos = []
    for flip in [False, True]:
        p = photo.copy()
        if flip:
            p = np.fliplr(p)
        for _ in range(4):
Exemple #12
0
from collections import Counter, defaultdict

import numpy as np

from utils import load_day

day_ten_input = load_day(10, sample=False)
jolts = [int(d) for d in day_ten_input]

# Part 1
sort_jolts = [0] + sorted(jolts)
dj = np.array(sort_jolts[1:]) - np.array(sort_jolts)[:-1]
counts = Counter(dj)
print(f'Part 1: {(counts[3] + 1) * counts[1]}')

# Part 2
jolt_set = {0} | set(jolts)
options = defaultdict(lambda: 0, {max(jolt_set): 1})

for j in sorted(sort_jolts, reverse=True):
    for nj in range(j - 1, j - 4, -1):
        if nj in jolt_set:
            options[nj] += options[j]
print(f'Part 2: {options[0]}')
Exemple #13
0
from utils import load_day


day_eight_input = load_day(8, sample=False)

commands = []
state_change = {
    'jmp': lambda x: (int(x), 0),
    'nop': lambda x: (1, 0),
    'acc': lambda x: (1, int(x)),
    'none': lambda x: (None, None),
}
instr_swap = {'jmp': 'nop', 'nop': 'jmp', 'acc': 'none'}

for d in day_eight_input:
    instr, num = d.split()
    primary = state_change[instr](num)
    secondary = state_change[instr_swap[instr]](num)
    commands.append([primary, secondary])


# Part 1
line, accum = 0, 0
visited = set()
while line not in visited:
    visited.add(line)
    d_line, d_acc = commands[line][0]
    line += d_line
    accum += d_acc
print(f'Part 1: {accum}')
Exemple #14
0
from utils import load_day


def find_num_loops(key, value=1):
    n, subject_num = 0, 7
    while value != key:
        value = (value * subject_num) % 20201227
        n += 1
    return n


def transform_key(subject_num, loop_size, value=1):
    for _ in range(loop_size):
        value = (value * subject_num) % 20201227
    return value


door_key, card_key = load_day(25)
door_key, card_key = int(door_key), int(card_key)
door_loops = find_num_loops(door_key)
card_loops = find_num_loops(card_key)

door_enc_key = transform_key(door_key, card_loops)
card_enc_key = transform_key(card_key, door_loops)

assert door_enc_key == card_enc_key
print(f'Part 1: {door_enc_key}')
Exemple #15
0
from collections import defaultdict

import numpy as np
from scipy.signal import convolve2d

from utils import load_day

commands = load_day(24)
all_tiles = defaultdict(bool)
dirs = {
    'ne': (1, 1),
    'nw': (-1, 1),
    'e': (2, 0),
    'w': (-2, 0),
    'se': (1, -1),
    'sw': (-1, -1),
}
neighbor_kern = np.array([
    [0, 1, 0, 1, 0],
    [1, 0, 0, 0, 1],
    [0, 1, 0, 1, 0],
]).transpose()


def turn_tile(cmd):
    idx, pos = 0, np.array([0, 0])
    while idx < len(cmd):
        if cmd[idx] in ('n', 's'):
            mv = dirs[cmd[idx:idx + 2]]
            idx += 2
        else:
Exemple #16
0
import numpy as np
from scipy.signal import convolve2d

from utils import load_day

rows = load_day(11)
mapping = {'.': 0, 'L': 1, '#': 2}
seats = np.array([[mapping[c] for c in r] for r in rows])


def find_equilibrium(neighbor_fn, n_allowed=4):
    occupied = np.zeros_like(seats)
    next_round = np.array(seats)
    while np.abs(next_round - occupied).sum() > 0:
        occupied = next_round
        n_neighbors = neighbor_fn(occupied)
        filled = (n_neighbors == 0)
        remained = (occupied & (n_neighbors < n_allowed))
        next_round = seats & (filled | remained)
    return next_round.sum()


# Part 1
sum_kernel = np.ones((3, 3))
sum_kernel[1, 1] = 0


def find_neighbors(occupied):
    return convolve2d(occupied, sum_kernel, 'same')

Exemple #17
0
import numpy as np

from utils import load_day

data = load_day(14)


def mask_to_int(mask):
    return int(''.join(mask), 2)


def bitmask(arr, c):
    return mask_to_int(['1' if v == c else '0' for v in arr])


# Part 1
regs = {}
for row in data:
    reg, value = row.split(' = ')
    if reg == 'mask':
        and_mask = bitmask(value, 'X')
        change_mask = np.bitwise_not(and_mask)
        change_value = mask_to_int([v if v != 'X' else '0' for v in value])
        or_mask = change_value & change_mask
    else:
        regs[reg] = (int(value) & and_mask) | or_mask
print(f'Part 1: {sum(regs.values())}')


# Part 2
def convert_iter_to_mask(masks, value):
Exemple #18
0
from utils import load_day


intro_nums = load_day(15, split=False).split(',')


def play_memory_game(intro_nums, count_to):
    nums = {int(n): i+1 for i, n in enumerate(intro_nums[:-1])}
    n = int(intro_nums[-1])
    for i in range(len(nums) + 1, count_to):
        prev_n = n
        n = (
            i - nums[n]
            if n in nums else
            0
        )
        nums[prev_n] = i
    return n


# Part 1
n = play_memory_game(intro_nums, 2020)
print(f'Part 1: {n}')


# Part 2
n = play_memory_game(intro_nums, 30000000)
print(f'Part 2: {n}')
Exemple #19
0
import numpy as np
from scipy import ndimage

from utils import load_day

start_board = load_day(17)


def parse_initial_board(start_board, pad=6):
    n = len(start_board)
    mn = n + 2 * pad
    board = np.zeros((mn, mn, mn, mn))
    for row in start_board:
        for x in range(n):
            for y in range(n):
                board[pad, pad, x + pad, y + pad] = start_board[x][y] == '#'
    return board


def run_cube_rules(board, k, n):
    for i in range(n):
        n_neighbors = ndimage.convolve(board, k, mode='constant')
        remains_active = (board != 0.0) & ((n_neighbors == 2) |
                                           (n_neighbors == 3))
        becomes_active = np.logical_not(board) & (n_neighbors == 3)
        board = (remains_active | becomes_active).astype(float)
    return board


# Part 1
k = np.ones((3, 3, 3))
Exemple #20
0
from collections import deque
from itertools import combinations

from utils import load_day

is_sample = False
day_nine_input = load_day(9, sample=is_sample)
day_nine_input = [int(v) for v in day_nine_input]
preamble = 5 if is_sample else 25
values = day_nine_input


# Part 1
def is_valid(v, arr):
    return any([v == sum(p) for p in combinations(arr, 2)])


for idx in range(preamble, len(values) - 1):
    v = values[idx]
    p_arr = values[idx - preamble:idx]
    if not is_valid(v, p_arr):
        break

invalid_value = v
print(f'Part 1: {invalid_value}')

# Part 2
current_sum = 0
low, high = (0, 0)
while current_sum != invalid_value:
    if current_sum < invalid_value:
Exemple #21
0
import re
from collections import defaultdict, Counter
from itertools import chain
from utils import load_day

foods = load_day(21, sample=False)


def parse_allergen_mapping(foods):
    contains_mapping = defaultdict(set)
    all_foods = []
    for food in foods:
        food_names, contains_names = food.replace(')', '').split('(contains ')
        food_names = food_names.split()
        all_foods.extend(food_names)
        for n in contains_names.split(', '):
            if len(contains_mapping[n]) == 0:
                contains_mapping[n] = set(food_names)
            else:
                contains_mapping[n] &= set(food_names)
    return contains_mapping, all_foods


# Part 1
contains_mapping, all_foods = parse_allergen_mapping(foods)
may_have_allergen = set(chain(*contains_mapping.values()))
no_allergens = set(all_foods) - may_have_allergen
food_counts = Counter(all_foods)
no_allergen_count = sum([food_counts[f] for f in no_allergens])
print(f'Part 1: {no_allergen_count}')
Exemple #22
0
import numpy as np

from utils import load_day

data = load_day(22, split=False).split('\n\n')
p1_data = [int(c) for c in data[0].split('\n')[1:][::-1]]
p2_data = [int(c) for c in data[1].split('\n')[1:][::-1]]


def play_simple_game(p1_data, p2_data):
    p1_data, p2_data = list(p1_data), list(p2_data)
    while p1_data and p2_data:
        c1, c2 = p1_data.pop(), p2_data.pop()
        arr = p1_data if c1 > c2 else p2_data
        arr[0:0] = [min([c1, c2]), max(c1, c2)]
    return p1_data or p2_data


def score_hand(arr):
    values = np.array(arr) * np.array(range(1, len(arr) + 1))
    return values.sum()


# Part 1
winning_hand = play_simple_game(p1_data, p2_data)
print(f'Part 1: {score_hand(winning_hand)}')


def hand_id(d):
    return ' '.join([str(v) for v in d])
Exemple #23
0
from utils import load_day

day_five_input = load_day(5)
half_fn = lambda x, i: x[i]


def half(pos, is_high):
    low, high = pos
    h = (high - low) // 2
    return (high - h, high) if is_high else (low, low + h)


def find_seat(part):
    row, col = (1, 128), (1, 8)
    for c in part:
        if c == 'F' or c == 'B':
            row = half(row, c == 'B')
        elif c == 'L' or c == 'R':
            col = half(col, c == 'R')
    return row[0] - 1, col[0] - 1


# Part 1
max_seat = 0
all_seat_ids = []
for row in day_five_input:
    row = find_seat(row)
    seat_id = row[0] * 8 + row[1]
    all_seat_ids.append(seat_id)
    max_seat = max(seat_id, max_seat)
Exemple #24
0
import re
from collections import defaultdict

from utils import load_day

day_seven_input = load_day(7, sample=False, split=True)

parents = defaultdict(set)
children = defaultdict(set)
for row in day_seven_input:
    bag = re.match(r'(.+) bags contain', row).groups()[0]
    for count, child in re.findall(r'(\d) (.+?) bag', row):
        parents[child].add(bag)
        children[bag].add((int(count), child))

# Part 1
to_check = ['shiny gold']
valid_bags = set()
while to_check:
    bag = to_check.pop()
    valid_bags.add(bag)
    to_check.extend(parents[bag])
print(f'Part 2: {len(valid_bags) - 1}')

# Part 2
to_add = [(1, 'shiny gold')]
total = 0
while to_add:
    p_num, bag = to_add.pop()
    total += p_num
    for c_num, child in children[bag]:
Exemple #25
0
def is_valid(orig_msg, rules_dict):
    valid_options = [(r, orig_msg) for r in rules_dict['0']]
    while valid_options:
        rule, msg = valid_options.pop()
        option = rule[0]
        if option in ['a', 'b']:
            if msg[0] == option:
                if len(rule) == 1 and len(msg) == 1:
                    return True
                elif len(rule) >= 2 and len(msg) >= 2:
                    valid_options.append((rule[1:], msg[1:]))
            continue
        for nx in rules_dict[option]:
            next_option = nx + rule[1:]
            valid_options.append((next_option, msg))
    return False


rows = load_day(19, split=False)

# Part 1
rules_dict, messages = parse_rules_and_messages(rows)
num_valid = sum([is_valid(s, rules_dict) for s in messages])
print(f'Part 1: {num_valid}')

# Part 2
rules_dict, messages = parse_rules_and_messages(rows, is_part_2=True)
num_valid = sum([is_valid(s, rules_dict) for s in messages])
print(f'Part 2: {num_valid}')
Exemple #26
0
        return HEIGHT_IN_FN(x.replace('in', ''))
    else:
        return False


def regex_match(r):
    return lambda x, r=r: bool(re.fullmatch(r, x))


REQUIRED_CODES = {'byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid'}
EYE_CODES = {'amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth'}
HEIGHT_CM_FN = valid_range(150, 193)
HEIGHT_IN_FN = valid_range(59, 76)


day_four_input = load_day(4, sample=False, split=False)

# Part 1
n_valid = 0
for passport in day_four_input.split('\n\n'):
    codes = parse_passport(passport).keys()
    missing_codes = REQUIRED_CODES - set(codes)
    n_valid += len(missing_codes) == 0


print(f'Part 1: {n_valid}')


# Part 2
IS_VALID_FNS = {
    'byr': valid_range(1920, 2002),
Exemple #27
0
from collections import Counter

from utils import load_day

# Part 1
n_correct = 0
for d in load_day(2):
    criteria, password = d.split(': ')
    valid_range, letter = criteria.split()
    valid_range = tuple(int(t) for t in valid_range.split('-'))

    pass_count = Counter(password)
    actual_count = pass_count[letter]
    if actual_count >= valid_range[0] and actual_count <= valid_range[1]:
        n_correct += 1

print(f'Part 1: {n_correct}')

# Part 2
n_correct = 0
for d in load_day(2):
    criteria, password = d.split(': ')
    valid_range, letter = criteria.split()

    l, r = tuple(int(t) for t in valid_range.split('-'))
    if (password[l - 1] == letter) ^ (password[r - 1] == letter):
        n_correct += 1
print(f'Part 2: {n_correct}')