Пример #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()
Пример #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)
Пример #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 = {}
Пример #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
Пример #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
Пример #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
 def __init__(self):
     if DataFactory.__instance != None:
         raise Exception("Singleton")
     else:
         self.logger = MyLogger.getLogger("DataFac")
         DataFactory.__instance = self
Пример #8
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)
Пример #9
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
Пример #10
0
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),
        datetime.time(15, 30),
Пример #11
0
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,
                asx_listings.market_cap.values, asx_listings.low.values)
            if (0.01 < l < 5) and
            (s + ".AX" in tickers_ledger.TICKER.values) and (t.find("Ltd") > 0)
        ],
                              k=k)

    strat = 1
Пример #12
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") +