Ejemplo n.º 1
0
    def __init__(self,
                 manager,
                 name,
                 symbols,
                 properties,
                 required=[],
                 mainBarsize=""):
        self.logger = MyLogger.getLogger(name,
                                         file=f"{name}.log",
                                         level=logging.INFO)
        self.clock = TradingClock.getInstance()
        self.manager: Manager = manager
        self.name = name
        self.id = uuid.uuid1()
        self.clock = TradingClock.getInstance()
        self.symbols = symbols
        self.mainBarsize = mainBarsize

        # Check properties
        self.__dict__ = {**self.__dict__, **properties}
        assert \
            all([rp in self.__dict__.keys() and self.__dict__[rp] is not None for rp in required]), \
            f"Missing required properties {[rp for rp in required if (rp not in self.__dict__.keys()) or (self.__dict__[rp] is None)]}"

        self.__symbols = {}  # map symbol to datas
        self.__requests = {}  # map requests to symbol

        self.indicators = {}

        # Call abstract setup method
        self.setup()
Ejemplo n.º 2
0
    def __init__(self, parent, simtracker, account, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.logger = MyLogger.getLogger('StratView')

        self.simtracker = simtracker
        self.account = account
        self.canvas = None
        self.legend = tk.Frame(self)
        self.legend.pack(side=tk.RIGHT)
Ejemplo n.º 3
0
    def __init__(self, endpoint):
        self.logger = MyLogger.getLogger('TestApp',
                                         file='trades.log',
                                         level=MyLogger.TRADE)
        self.clock = TradingClock.getInstance()
        self.datafactory = DataFactory.getInstance()

        self.endpoint = endpoint
        self.clock.add_callback(self.time_change)
        self.pending_orders = {}
        self.historical_subscribers = {}
Ejemplo n.º 4
0
    def __init__(self, startingcapital):
        self.logger = MyLogger.getLogger("ACC")
        self.datafactory = DataFactory.getInstance()
        self.clock = TradingClock.getInstance()
        self.clock.add_callback(self.time_change)
        self.orderLedger = {}
        self.portfolio = {}  # Portfolio(startingcapital)

        self.cash = startingcapital
        self.CASH = pd.Series()
        self.HOLDINGS = pd.Series()

        self.done = False
Ejemplo n.º 5
0
    def __init__(self, simtracker, account, strategies, rapid=False, times=None, setup_days=3, barsize="5 min"):
        threading.Thread.__init__(self)

        self.simtracker = simtracker
        self.account = account
        self.logger = MyLogger.getLogger('main')
        self.strategies = strategies
        self.symbols = functools.reduce(lambda a, b: set(a + b), [skwa["symbols"] for s, skwa in strategies])
        self.barsize = barsize
        self.rapid = rapid
        self.setup_days = setup_days

        if times is None:
            self.times = [
                datetime.time(10, 30),
                datetime.time(11, 30),
                datetime.time(12, 30),
                datetime.time(13, 30),
                datetime.time(14, 30),
                datetime.time(15, 30),
            ]
        else:
            self.times = times
Ejemplo n.º 6
0
def replace_empties(data, goal=None):
    logger = MyLogger.getLogger("RepUtil")

    if goal is not None and goal < data.index[-1]:
        logger.warn(f"Goal date {goal} is pre-data end {data.index[-1]}, resetting")
        goal = data.index[-1]

    dates = sorted(list(set(pd.Series(data.index).transform(lambda x: x.date()))))
    date = dates[0]
    end_date = dates[-1] if goal is None else goal.date()
    period = min([abs(d1 - d2) for d1, d2 in zip(data.index[1:], data.index[:-1])])

    while date <= end_date:
        if tcal.is_partial_trading_day(date) or tcal.is_trading_day(date):


            #TODO: Bug - min period changed if get a partial bar


            if period > datetime.timedelta(minutes=5):
                # TODO: Bit ugly.... shoed in
                missing_ranges = []
                if date not in dates:
                    missing_ranges = [[data.index[0].replace(year=date.year, month=date.month, day=date.day)]]
            else:
                ttimes = tcal.tradingtimes(date)
                if goal is None:
                    missing_times = ttimes[~ttimes.isin(data.index)]
                else:
                    missing_times = ttimes[~ttimes.isin(data.index) & (ttimes <= goal)]
                missing_ranges = []

                if len(missing_times):
                    # Blocks of missing data
                    missing_ranges.append([missing_times[0]])
                    for missing_time in missing_times[1:]:
                        previous = missing_ranges[-1][-1]

                        next_span = missing_time - previous
                        if next_span != period:
                            missing_ranges.append([missing_time])
                        else:
                            missing_ranges[-1].append(missing_time)

            # chuck repeated in there
            for missing_range in missing_ranges:
                try:
                    before = data[data.index < missing_range[0]]
                    after = data[data.index > missing_range[-1]]

                    previous = before.iloc[-1]

                    patch = pd.DataFrame({"Open": previous.Close, "High": previous.Close, "Low": previous.Close,
                                          "Close": previous.Close, "Adj Close": previous.Close, "Volume": 0},
                                         index=missing_range)


                    data = pd.concat([before, patch, after])
                    data = data[~data.index.duplicated(keep='last')]
                except Exception as e:
                    print(f"Repair failed for {e}")
        date += datetime.timedelta(days=1)
    return data
Ejemplo n.º 7
0
from Services.SimViewer import SimViewer

import pandas as pd

from Strategies.Breakouts import Breakouts
from Strategies.Crossover import Crossover
from Strategies.Crystal import CrystalV3
from Strategies.MACD import MACD
from Strategies.RocketCatcher import RocketCatcher
from Strategies.Testing import TestStrategy
from _config import TICKERS_LEDGER, ASX_GAME
import datetime

from enum import Enum

MyLogger.configure(level=20)

import matplotlib.pyplot as plt

plt.ioff()

if __name__ == "__main__":

    strategies = Enum('Strategy',
                      'Test Crystal RocketCatcher Breakouts MACD Crossover')
    strategy = strategies.Test

    DataFactory.repaired = True

    a = Account(5000)
    st = SimTracker()
Ejemplo n.º 8
0
 def __init__(self):
     if DataFactory.__instance != None:
         raise Exception("Singleton")
     else:
         self.logger = MyLogger.getLogger("DataFac")
         DataFactory.__instance = self
Ejemplo n.º 9
0
    def __init__(self, parent, simtracker, account, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)

        self.simtracker = simtracker
        self.account = account
        self.logger = MyLogger.getLogger("PView")

        tk.Button(self, text="Refresh", command=self.refresh, relief=tk.GROOVE, borderwidth=1) \
            .pack(side=tk.BOTTOM, expand=True, fill=tk.X)

        tk.Label(self, text="Orders").pack()
        self.orders_entry = tk.Entry(self)
        self.orders_entry.pack()
        self.orders_entry.bind('<Return>', self.refresh)

        self.orderstv_frame = tk.Frame(self)
        self.orderstv = ttk.Treeview(self.orderstv_frame)
        self.orderstv["columns"] = [
            "id", "Symbol", "Action", "Time", "Price", "Filled"
        ]
        self.orderstv["show"] = "headings"
        self.orderstv.heading("id", text="")
        self.orderstv.heading("Symbol", text="Symb")
        self.orderstv.heading("Action", text="Action")
        self.orderstv.heading("Time", text="Time")
        self.orderstv.heading("Price", text="Price")
        self.orderstv.heading("Filled", text="Filled")
        col_width = self.orderstv.winfo_width() // len(
            self.orderstv['columns'])
        for col in self.orderstv['columns']:
            self.orderstv.heading(col, anchor=tk.CENTER)
            self.orderstv.column(col, anchor=tk.CENTER,
                                 width=col_width)  # set column width
        self.orderstv.pack(fill=tk.BOTH, expand=True)
        self.orderstv_frame.pack(fill=tk.BOTH, expand=True)

        # treeScroll = ttk.Scrollbar(self.orderstv)
        # treeScroll.configure(command=self.orderstv.yview)
        # self.orderstv.configure(yscrollcommand=treeScroll.set)

        tk.Label(self, text="Portfolio").pack()

        self.holdingstv_frame = tk.Frame(self)
        self.holdingstv = ttk.Treeview(self.holdingstv_frame)
        self.holdingstv["columns"] = [
            "Symbol", "Vol", "Avg Price", "Price", "Change", "Realised"
        ]
        self.holdingstv["show"] = "headings"
        self.holdingstv.heading("Symbol", text="Symb")
        self.holdingstv.heading("Vol", text="Vol")
        self.holdingstv.heading("Avg Price", text="Avg Price")
        self.holdingstv.heading("Price", text="Price")
        self.holdingstv.heading("Change", text="%")
        self.holdingstv.heading("Realised", text="Realised")
        col_width = self.holdingstv.winfo_width() // len(
            self.holdingstv['columns'])
        for col in self.holdingstv['columns']:
            self.holdingstv.heading(col, anchor=tk.CENTER)
            self.holdingstv.column(col, anchor=tk.CENTER,
                                   width=col_width)  # set column width
        self.holdingstv.pack(fill=tk.BOTH, expand=True)
        self.holdingstv_frame.pack(fill=tk.BOTH, expand=True)

        # ttk.Separator(self, orient=tk.HORIZONTAL).pack(fill=tk.X, expand=1)

        tk.Label(self, text="Value").pack()

        self.plot_frame = tk.Frame(self, relief=tk.GROOVE, borderwidth=1)
        self.f = Figure(figsize=(5, 5), dpi=100)
        self.a = self.f.add_subplot(111)
        self.a.grid(True)
        self.a.xaxis.set_major_formatter(mdates.DateFormatter("%m-%d"))
        self.a.xaxis.set_minor_formatter(mdates.DateFormatter("%m-%d"))
        self.a.plot([TradingClock.getInstance().sync_datetime],
                    [self.account.value])
        # self.cash, = self.a.plot([TradingClock.getInstance().sync_datetime], [self.account.cash])
        # self.holdings, = self.a.plot([TradingClock.getInstance().sync_datetime], [self.account.holdings])

        self.canvas = FigureCanvasTkAgg(self.f, self.plot_frame)
        self.canvas.get_tk_widget().pack(side=tk.BOTTOM,
                                         fill=tk.BOTH,
                                         expand=True)
        self.plot_frame.pack(fill=tk.BOTH, expand=True)
Ejemplo n.º 10
0
    def snapshot_to_fig(snapshot, account=None, savefile=None):
        logger = MyLogger.getLogger('SS2Fig')
        legend_indicators = {}
        data = snapshot.data

        def getcolor(ii):
            colors = ["blue", "green", "red", "cyan", "magenta", "yellow"]
            return colors[ii % len(colors)]

        def get_addplot(ii, key, indicator, iargs):
            if "color" not in iargs:
                iargs["color"] = getcolor(ii)

            legend_indicators[key] = iargs["color"]
            if len(indicator) < len(data):
                missing_points = len(data) - len(indicator)
                indicator = pd.concat(
                    [indicator,
                     pd.Series([np.nan] * missing_points)])
                logger.warn(
                    f"Missing {missing_points} data points for indicator {key}"
                )

            return fplt.make_addplot(indicator, **iargs)

        indicator_adps = [
            get_addplot(i, key, indicator, iargs)
            for i, (key, (indicator,
                          iargs)) in enumerate(snapshot.indicators.items())
        ]

        trade_adps = []
        symbol = snapshot.contract.symbol
        period = min(
            [abs(d1 - d2) for d1, d2 in zip(data.index[1:], data.index[:-1])])

        if account is not None:
            # GET THE BUYS
            try:
                buy_times, buy_prices = map(
                    list,
                    zip(*[(order["time"], order["lastFillPrice"])
                          for id, order in account.orderLedger.items()
                          if order["contract"].symbol == symbol
                          and data.index[0] <= order["time"] <= data.index[-1]
                          and order["order"].action == "BUY"]))

                if len(buy_times):
                    if period > datetime.timedelta(minutes=5):
                        buy_times = [bt.date() for bt in buy_times]
                        buys = pd.Series([
                            buy_prices[buy_times.index(t)]
                            if t.date() in buy_times else np.nan
                            for t in data.index
                        ])
                    else:
                        buys = pd.Series([
                            buy_prices[buy_times.index(t)]
                            if t in buy_times else np.nan for t in data.index
                        ])

                    if np.any(~np.isnan(buys)):
                        trade_adps.append(
                            fplt.make_addplot(
                                buys.transform(lambda x: x * 0.9975),
                                scatter=True,
                                marker=r'$\uparrow$',
                                markersize=96,
                                color="green"))
            except ValueError as e:
                pass
            except Exception as e:
                logger.warn(f"Failed buy markers: {e}")

            # GET THE SELLS
            try:
                sell_times, sell_prices = map(
                    list,
                    zip(*[(order["time"], order["lastFillPrice"])
                          for id, order in account.orderLedger.items()
                          if order["contract"].symbol == symbol
                          and data.index[0] <= order["time"] <= data.index[-1]
                          and order["order"].action == "SELL"]))

                if len(sell_times):
                    if period > datetime.timedelta(minutes=5):
                        sell_times = [st.date() for st in sell_times]
                        sells = pd.Series([
                            sell_prices[sell_times.index(t)]
                            if t.date() in sell_times else np.nan
                            for t in data.index
                        ])
                    else:
                        sells = pd.Series([
                            sell_prices[sell_times.index(t)]
                            if t in sell_times else np.nan for t in data.index
                        ])

                    if np.any(~np.isnan(sells)):
                        trade_adps.append(
                            fplt.make_addplot(
                                sells.transform(lambda x: x * 1.0025),
                                scatter=True,
                                marker=r'$\downarrow$',
                                markersize=96,
                                color="red"))
            except ValueError as e:
                pass
            except Exception as e:
                logger.warn(f"Failed sell markers: {e}")

        mc = fplt.make_marketcolors(up='#7DFFB8',
                                    down='#FF7979',
                                    edge='black',
                                    wick='black',
                                    volume='in')
        s = fplt.make_mpf_style(base_mpl_style="seaborn",
                                mavcolors=["lightseagreen", "orange"],
                                facecolor="#F9FBFD",
                                gridcolor="#F2F2F2",
                                gridstyle="--",
                                marketcolors=mc)

        dates = list(set(pd.Series(data.index).transform(lambda x: x.date())))

        plotargs = {
            "type": 'candle',
            "style": s,
            "title": symbol,
            "ylabel": 'Price ($)',
            "volume": True,
            "addplot": indicator_adps + trade_adps,
            "returnfig": True
        }

        if savefile is not None:
            # if period == datetime.timedelta(days=1):
            #     data.index = pd.DatetimeIndex(pd.Series(data.index).transform(lambda x:x.date()), dtype=datetime.date)
            plotargs["savefig"] = savefile

        if type(data.index) != pd.DatetimeIndex:
            # TODO: shouldn't come here
            data.index = pd.DatetimeIndex(pd.to_datetime(data.index, utc=True))
            logger.warn("ERROR index not datetime")

        for addplots in [
                indicator_adps + trade_adps, indicator_adps, trade_adps, []
        ]:
            try:
                plotargs["addplot"] = addplots
                fig, ax = fplt.plot(data, **plotargs)
                break
            except:
                pass  #fig, ax = fplt.plot(data, **plotargs)

        if period <= datetime.timedelta(minutes=5):
            loc = mticker.MultipleLocator(73)
            ax[0].xaxis.set_major_locator(loc)
        else:
            loc = mticker.MultipleLocator(1)
            #loc = mticker.MultipleLocator(max(len(data)//20, 1))
            ax[0].xaxis.set_major_locator(loc)

        return fig, ax, legend_indicators
Ejemplo n.º 11
0
from Services.Datafactory import DataFactory
from Services.MyLogger import MyLogger
from Services.SimTracker import SimTracker
from Services.SimViewer import StrategyView
from Services.TradingClock import TradingClock
from Strategies.Crystal import CrystalV3
from Strategies.RocketCatcher import RocketCatcher
from _config import TICKERS_LEDGER
from _devconfig import *

import random
import pandas as pd

if __name__ == "__main__":

    MyLogger.configure(20)
    logger = MyLogger.getLogger("MAIN")

    # services
    DataFactory.repaired = True
    DataFactory.live_data = True
    clock, datafactory = TradingClock.getInstance(), DataFactory.getInstance()

    # absolute times to check for an update
    times = [
        datetime.time(9, 30),
        datetime.time(10, 30),
        datetime.time(11, 30),
        datetime.time(12, 30),
        datetime.time(13, 30),
        datetime.time(14, 30),
Ejemplo n.º 12
0
from DataScrape.ScrapeReddit import ASX_LISTING
from Services.MyLogger import MyLogger
from Strategies.Crystal import CrystalV3
from Strategies.RocketCatcher import RocketCatcher
from _config import TICKERS_LEDGER

MyLogger.configure(level=MyLogger.TRADE)
from Components.Account import Account
from Services.Datafactory import DataFactory
from Components.Process import ThreadedTask

import pandas as pd
import random

if __name__ == "__main__":
    # TODO: proper portfolio
    # TODO: data cleaning
    # TODO: parmas

    DataFactory.repaired = True

    logger = MyLogger.getLogger("Optimiser",
                                file="optimiser.log",
                                level=MyLogger.OPTY)

    def get_random_symbols(k=25):
        tickers_ledger = pd.read_csv(TICKERS_LEDGER)
        asx_listings = pd.read_csv(ASX_LISTING)
        return random.choices([
            s for t, s, mc, l in
            zip(asx_listings.title.values, asx_listings.code.values,
Ejemplo n.º 13
0
import os

import pandas as pd

from DataScrape.ScrapeReddit import ASX_LISTING
from Datasets.scrape_data import replace_empties
from Services.Datafactory import DataFactory
from Services.MyLogger import MyLogger
from _config import TICKERS_LEDGER, ASX_GAME

if __name__ == "__main__":
    logger = MyLogger.getLogger("repair util", level=20)
    datafactory = DataFactory.getInstance()

    asx_game = pd.read_csv(ASX_GAME)

    to_replace = [s + ".AX" for s in asx_game.Code]

    print(f"TO REPLACE ({len(to_replace)}):")
    for i, ticker in enumerate(to_replace):
        DFS = DataFactory.repaired
        try:
            print(f"{ticker} ({i + 1}/{len(to_replace)})")

            datafactory.repaired = False
            data = datafactory.loadSymbol(ticker).dropna()
            repaired_data = replace_empties(data)

            datafactory.repaired = True
            repaired_data.to_csv(
                datafactory.getDataDir("5 min") +