예제 #1
0
 def get_spread(self, a, q=5, bias=0, spread_size=0.5, better=0):
     better = better or self.sp["better"]
     p = a.status["pos"]; q=abs(q)
     if not bias: bias = -p or q*u.sign(random.random()-0.49) # slight buy bias (:
     get = lambda cls,i: cls.lst[i]["price"] if len(cls.lst)-i>0 else 0
     if not get(a.mbids, 0) or not get(a.masks, 0): return # get_out if no bid or no ask !
     wbid, wask = [a.mbids.lst[-1]["price"] - better, a.masks.lst[-1]["price"] + better]
     for cls in [a.mbids, a.masks]:
         price = get(cls, 0) + better * min(1, bias / q) # increase with position
         price = u.between(wbid, price, wask)
         live = 0 if abs(p) > 3*q and cls.sens == u.sign(p) else 1
         for k in self.watch: self.prep[k] += cls.sens*q * self.assets[cls.name].status[k] # greeks if/after filled
         self.prep["trades"].append( {"name":cls.name, "price":price, "quantity": cls.sens*q, "live": live} )
예제 #2
0
 async def best_order1(self, a, q, lm=0, better=0, force_mod=False):
     better = better or self.sp["better"]
     sens = u.sign(q); cls = a.mbids if sens > 0 else a.masks
     p = cls.best_price()
     if not p: return {"price": 0} # there is no market price if best_price is 0
     h = {"name":a.name, "price": p + sens*better, "quantity": q, "order_type": lm, "live": 1}
     self.debug("trading:", h)
     return await self.execute_trade(h, force_mod)
예제 #3
0
def json_representation(data, code, headers=None):
    resp = utils.json_dumps(data)
    signature = utils.sign(resp)

    response = make_response(resp, code)
    response.headers.extend(headers or {})
    response.headers.add('signature', signature)
    response.headers.set("Content-Type", "application/json")
    return response
예제 #4
0
 async def random(self, q=0):  # this is stupid random trades.
     t = self
     m = t.master
     q = q or m.sp["quantity"]
     if random.random() < 0.5:  # only trade 25% (0.5*0.5) of the time
         for k, a in t.assets.items():  # place new orders
             if random.random() < 0.5: continue  # cancel half the time
             await m.best_order(
                 a,
                 u.sign(random.random() - 0.49) * (abs(q) or 1), "L")
예제 #5
0
    async def christian(self):  # this is stupid random trades.
        t = self
        m = t.master
        # mxcycles=2000
        # if t.num == mxcycles:
        #     t.info("final=", m.pairs)
        #     throw(ValueError("done"))

        # parameters
        siz = size_of_spread = m.sp[
            "quantity"]  # todo: put in config both siz and step
        step = m.sp[
            "step"]  # we probably pay 0.04 to open and cancel spread, no point for less. To be tested

        m.store = {}
        for pair, pr in m.pairs.items():
            pri = self.pairdiff(pair)
            if not pri: continue

            if not pr.get("pos"): pr.update({"pos": 0, "cur": 0})

            pr["cur"] = pri  # current price
            pos = pr["pos"]  # current pos
            dma = pr["dma"] = pri - pr[
                "avg"]  # difference with the "real" price
            tgt = pr["tgt"] = -int(round(dma / step,
                                         0))  # if dma > 0, we should sell
            sens = u.sign(tgt - pos) or 1
            # ex: dma>0 -> tgt = -10, pos = -7, sign = sign(-3) = -1

            def trade():
                for i in range(pos, tgt, sens):
                    if t.tradespread(siz * sens, pair): pr["pos"] += sens
                return pr["pos"]

            if tgt == 0 or u.sign(tgt) != u.sign(pr["pos"]):
                pos = trade()  # came back to mean: liquidate position

            # if abs(pr["pos"]) - abs(tgt) > 6: pos = trade() # not yet to mean, but lock in some profit in case it goes back

            if abs(tgt) > abs(pos): trade()  # increase position
예제 #6
0
    def best_order(self, a, q, name="standing", lm="L", add=None, better=None, force_mod=False):
        if not q: return
        sens = u.sign(q); mcls = a.mbids if sens > 0 else a.masks; ocls = mcls.orders
        if lm == "M": return [ocls.place_order, {"name":a.name, "quantity": q, "order_type": lm}]

        p = mcls.best_price()
        if not p: return # there is no market price if best_price is 0
        better = better if better != None else (self.sp["better"] or 0.01)
        pa = p+add if add != None else p + sens*better
        o = {"name":a.name, "price": pa, "quantity": q, "order_type": lm}
        allorders = ocls.get_live()
        x = exist = allorders[0] if len(allorders) else 0 # will modify the first order if it exists
        exc = lambda: [x.mock_modify_order, o] if exist else [ocls.place_order, o]
        return 0 if (x and abs(x.h["price"] - o["price"])<0.02) else exc()
예제 #7
0
    async def add_fill(self, f):
        o = f.order
        oid = o.order_id
        fp = round(f.fill_price, 2)
        fq = round(f.filled_quantity * u.sign(o.quantity))
        self.status["pos"] += fq
        self.status["cash"] -= fq * fp
        h = {
            "price": fp,
            "quantity": fq,
            "typ": "bids" if fq > 0 else "asks"
        }  #, "size":abs(fq)
        self.info(f"filled-{oid[-6:]} ({fq} at {fp})", h)

        ok = self.exist_order(oid, "fill_order", p=o.price, q=o.quantity)
        h["ok"] = 1 if ok else 0
        ok.fill(f) if ok else 0
        return [h, f]
예제 #8
0
    def fill(self, f):
        o = f.order
        oid = o.order_id
        op = round(f.fill_price, 2)
        oq = round(f.filled_quantity * u.sign(o.quantity))
        if self.cancelled:
            self.warning("Sorry, cancelled order was filled:",
                         self.show({"fill": oq}))

        def err(fv, typ, m):  # check (well you never know....)
            msg = f'{self.all.name}: {m} {typ} when filling {self.sid}: {fv} vs {self.h[typ]} {self.h}'
            self.fatal(msg)

        diff_price = d = self.h["price"] - op if self.h["price"] else 0
        if d != 0 and d * self.all.sens < 0: err(op, "price", "worse")
        if f.filled_quantity > abs(self.h["qleft"]):
            err(f.filled_quantity, 'quantity', 'too much')

        self.filled += oq
        self.h["qleft"] -= oq
        self.h["size"] -= f.filled_quantity
        if self.h["size"] <= 0: self.mark_cancelled()
        self.debug(f"filled-{self.sid}", self.show())
        return self