def _start(self, app_context, **kwargs): self.qty = self.get_stg_config_value("qty", 1) self.threshold = self.get_stg_config_value("threshold", 1) self.xiv = app_context.ref_data_mgr.get_inst('XIV', 'SMART') self.vxx = app_context.ref_data_mgr.get_inst('VXX', 'SMART') self.vxv = app_context.ref_data_mgr.get_inst('VXV', 'SMART') self.vix = app_context.ref_data_mgr.get_inst( 'VIX', 'SMART') # TODO: Review index instruments = [self.vxx, self.xiv, self.vix] self.vix_bar = app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.vix.get_symbol()) # non tradable self.vxv_bar = app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.vxv.get_symbol()) # non tradable self.xiv_bar = app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.xiv.get_symbol()) self.vxx_bar = app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.vxx.get_symbol()) self.vix_strm = BehaviorSubject(0) self.vxv_strm = BehaviorSubject(0) self.ratio_strm = rx.Observable \ .zip(self.vix_strm, self.vxv_strm, lambda x, y: x / y) \ .subscribe(self.on_ratio) super(VixVxvRatio, self)._start(app_context, **kwargs)
class VixVxvRatio(Strategy): def __init__(self, stg_id: str, stg_cls: str, state: StrategyState = None): super(VixVxvRatio, self).__init__(stg_id=stg_id, stg_cls=stg_cls, state=state) self.day_count = 0 self.order = None def _start(self, app_context: Context) -> None: self.qty = self._get_stg_config("qty", 1) self.threshold = self._get_stg_config("threshold", 1) self.xiv = app_context.ref_data_mgr.get_inst('XIV', 'SMART') self.vxx = app_context.ref_data_mgr.get_inst('VXX', 'SMART') self.vxv = app_context.ref_data_mgr.get_inst('VXV', 'SMART') self.vix = app_context.ref_data_mgr.get_inst( 'VIX', 'SMART') # TODO: Review index instruments = [self.vxx, self.xiv, self.vix] self.vix_bar = app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.vix.get_symbol()) # non tradable self.vxv_bar = app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.vxv.get_symbol()) # non tradable self.xiv_bar = app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.xiv.get_symbol()) self.vxx_bar = app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.vxx.get_symbol()) self.vix_strm = BehaviorSubject(0) self.vxv_strm = BehaviorSubject(0) self.ratio_strm = rx.Observable \ .zip(self.vix_strm, self.vxv_strm, lambda x, y: x / y) \ .subscribe(self.on_ratio) super(VixVxvRatio, self)._start(app_context) def _stop(self): super(VixVxvRatio, self)._stop() def on_bar(self, bar): if bar.inst_id == self.vix.id(): self.vix_strm.on_next(bar.close) elif bar.inst_id == self.vxv.id(): self.vxv_strm.on_next(bar.close) def on_ratio(self, ratio): # what is order is not filled and there is signal again? if self.order is None: # long XIV at the close when VIX index closed below the VXV index # long XIV when ratio < 0.92 if ratio < self.threshold[0]: # logger.info("%s,B,%.2f" % (bar.timestamp, bar.close)) self.order = self.market_order(inst_id=self.xiv.id(), action=Buy, qty=self.qty) # long VXX when ratio > 1.08 elif ratio > self.threshold[1]: # logger.info("%s,B,%.2f" % (bar.timestamp, bar.close)) self.order = self.market_order(inst_id=self.vxx, action=Buy, qty=self.qty)
class VixVxvRatio(Strategy): def __init__(self, stg_id=None, stg_configs=None): super(VixVxvRatio, self).__init__(stg_id=stg_id, stg_configs=stg_configs) self.day_count = 0 self.order = None def _start(self, app_context, **kwargs): self.qty = self.get_stg_config_value("qty", 1) self.threshold = self.get_stg_config_value("threshold", 1) self.xiv = app_context.ref_data_mgr.get_inst('XIV', 'SMART') self.vxx = app_context.ref_data_mgr.get_inst('VXX', 'SMART') self.vxv = app_context.ref_data_mgr.get_inst('VXV', 'SMART') self.vix = app_context.ref_data_mgr.get_inst('VIX', 'SMART') # TODO: Review index instruments = [self.vxx, self.xiv, self.vix] self.vix_bar = app_context.inst_data_mgr.get_series("Bar.%s.Time.86400" % self.vix.get_symbol()) # non tradable self.vxv_bar = app_context.inst_data_mgr.get_series("Bar.%s.Time.86400" % self.vxv.get_symbol()) # non tradable self.xiv_bar = app_context.inst_data_mgr.get_series("Bar.%s.Time.86400" % self.xiv.get_symbol()) self.vxx_bar = app_context.inst_data_mgr.get_series("Bar.%s.Time.86400" % self.vxx.get_symbol()) self.vix_strm = BehaviorSubject(0) self.vxv_strm = BehaviorSubject(0) self.ratio_strm = rx.Observable \ .zip(self.vix_strm, self.vxv_strm, lambda x, y: x / y) \ .subscribe(self.on_ratio) super(VixVxvRatio, self)._start(app_context, **kwargs) def _stop(self): super(VixVxvRatio, self)._stop() def on_bar(self, bar): if bar.inst_id == self.vix.id(): self.vix_strm.on_next(bar.close) elif bar.inst_id == self.vxv.id(): self.vxv_strm.on_next(bar.close) def on_ratio(self, ratio): # what is order is not filled and there is signal again? if self.order is None: # long XIV at the close when VIX index closed below the VXV index # long XIV when ratio < 0.92 if ratio < self.threshold[0]: # logger.info("%s,B,%.2f" % (bar.timestamp, bar.close)) self.order = self.market_order(inst_id=self.xiv.id(), action=OrdAction.BUY, qty=self.qty) # long VXX when ratio > 1.08 elif ratio > self.threshold[1]: # logger.info("%s,B,%.2f" % (bar.timestamp, bar.close)) self.order = self.market_order(inst_id=self.vxx, action=OrdAction.BUY, qty=self.qty)
def publish_value(self, initial_value, selector=None): """Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence and starts with initial_value. This operator is a specialization of Multicast using a BehaviorSubject. Example: res = source.publish_value(42) res = source.publish_value(42, lambda x: x.map(lambda y: y * y)) Keyword arguments: initial_value -- {Mixed} Initial value received by observers upon subscription. selector -- {Function} [Optional] Optional selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive immediately receive the initial value, followed by all notifications of the source from the time of the subscription on. Returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function. """ if selector: def subject_selector(): return BehaviorSubject(initial_value) return self.multicast(subject_selector=subject_selector, selector=selector) else: return self.multicast(BehaviorSubject(initial_value))
def _publish_value(initial_value: Any, mapper: Mapper = None) -> Callable[[Observable], Observable]: if mapper: def subject_factory(scheduler): return BehaviorSubject(initial_value) return ops.multicast(subject_factory=subject_factory, mapper=mapper) return ops.multicast(BehaviorSubject(initial_value))
def _start(self, app_context, **kwargs): self.ou_params = self.get_stg_config_value("ou_params", 1) self.gamma = self.get_stg_config_value("gamma", 1) self.bar_0 = app_context.inst_data_mgr.get_series("Bar.%s.Time.86400" % self.app_context.app_config.instrument_ids[0]) self.bar_0.start(app_context) self.bar_1 = app_context.inst_data_mgr.get_series("Bar.%s.Time.86400" % self.app_context.app_config.instrument_ids[1]) self.bar_1.start(app_context) self.instruments = self.app_context.app_config.instrument_ids self.log_spot_0 = BehaviorSubject(0) self.log_spot_1 = BehaviorSubject(0) self.spread_stream = rx.Observable \ .zip(self.log_spot_0, self.log_spot_1, lambda x, y: [x, y, x - y]) \ .subscribe(self.rebalance) super(PairTradingWithOUSpread, self)._start(app_context, **kwargs)
class ServerState: db_data = None monitor_data = None bc_monitorSub = BehaviorSubject(None) db_monitorSub = BehaviorSubject(None) bc_monitor = Observable db_monitor = Observable def set_db_data(self, data): self.db_data = data self.bc_monitor.map(self.set_db_data(self.db_data)).publish() def get_db_data(self): return self.db_datas def setMonitor(self, d): self.monitor_data = d def getMonitor(self): return self.monitor_data # select method will use to get observerable def select(self, observer_name): if observer_name == BC_MONITOR_SUB: return self.bc_monitorSub elif observer_name == DB_MONITOR_SUB: return self.db_monitorSub else: # print observer_name + ' is not recognize observable.' return None # dispatch method will use to update data on the observer def dispatch(self, observer_name, payload): if observer_name == BC_MONITOR_SUB: self.bc_monitorSub.on_next(payload) return payload elif observer_name == DB_MONITOR_SUB: self.db_monitorSub.on_next(payload) return payload else: # print observer_name + ' is not recognize observable.' return None
def main(inputs, starting_floor): floor_C = BehaviorSubject(starting_floor) inputs.floor_changed_S.subscribe(floor_C) calls_C = BehaviorSubject(set()) calls_S = inputs.called_S \ .map(lambda call: call.floor) \ .scan(lambda called_floors, floor: called_floors | set([floor]), set()) calls_S.subscribe(calls_C) selections_C = BehaviorSubject(set()) inputs.floor_selected_S \ .scan(lambda selections, floor: selections | set([floor]), set()) \ .subscribe(selections_C) resume_S = inputs.tick_S \ .with_latest_from(selections_C, lambda _, selections: first(selections)) \ .filter(cmp(not_, is_none)) # TODO (TS 2016-05-16) Don't fire if motor is already moving. motor_started_S = inputs.called_S \ .map(lambda call: call.floor) \ .merge(inputs.floor_selected_S, resume_S) \ .with_latest_from(floor_C, determine_direction) stop_for_call_S = inputs.floor_changed_S \ .with_latest_from(calls_C, arrived_on_called_floor) \ .filter(identity) \ .map(always(None)) stop_for_selection_S = inputs.floor_changed_S \ .with_latest_from(selections_C, arrived_on_selected_floor) \ .filter(identity) \ .map(always(None)) motor_stopped_S = Observable.merge(stop_for_call_S, stop_for_selection_S) motor_C = BehaviorSubject(None) motor_change_S = Observable.merge(motor_started_S, motor_stopped_S) motor_change_S.subscribe(motor_C) return motor_C
def _start(self, app_context: Context) -> None: self.ou_params = self._get_stg_config("ou_params", default=1) self.gamma = self._get_stg_config("gamma", default=1) self.instruments = app_context.config.get_app_config("instrumentIds") self.bar_0 = self.app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.instruments[0]) self.bar_1 = self.app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.instruments[1]) self.bar_0.start(app_context) self.bar_1.start(app_context) self.log_spot_0 = BehaviorSubject(0) self.log_spot_1 = BehaviorSubject(0) self.spread_stream = rx.Observable \ .zip(self.log_spot_0, self.log_spot_1, lambda x, y: [x, y, x - y]) \ .subscribe(self.rebalance) super(PairTradingWithOUSpread, self)._start(app_context)
class Player: def __init__(self, id, name, ws_subject, size, pos): self.id = id self.ws_subject = ws_subject self.name = name self.size = BehaviorSubject(size) self.pos = BehaviorSubject(pos) self.dir = BehaviorSubject(None) ws_subject.to_observable().map(lambda d: json.loads(d.data)).filter(lambda m: m["t"] == "d").subscribe(self.dir) self.dir.subscribe(lambda d: print(d)) def partial_data(self): return {"id": self.id, "size": self.size.value, "pos": self.pos.value} def full_data(self): data = self.partial_data() data["name"] = self.name return data
def __init__(self, id, name, ws_subject, size, pos): self.id = id self.ws_subject = ws_subject self.name = name self.size = BehaviorSubject(size) self.pos = BehaviorSubject(pos) self.dir = BehaviorSubject(None) ws_subject.to_observable().map(lambda d: json.loads(d.data)).filter(lambda m: m["t"] == "d").subscribe(self.dir) self.dir.subscribe(lambda d: print(d))
def _start(self, app_context, **kwargs): self.qty = self.get_stg_config_value("qty", 1) self.threshold = self.get_stg_config_value("threshold", 1) self.xiv = app_context.ref_data_mgr.get_inst('XIV', 'SMART') self.vxx = app_context.ref_data_mgr.get_inst('VXX', 'SMART') self.vxv = app_context.ref_data_mgr.get_inst('VXV', 'SMART') self.vix = app_context.ref_data_mgr.get_inst('VIX', 'SMART') # TODO: Review index instruments = [self.vxx, self.xiv, self.vix] self.vix_bar = app_context.inst_data_mgr.get_series("Bar.%s.Time.86400" % self.vix.get_symbol()) # non tradable self.vxv_bar = app_context.inst_data_mgr.get_series("Bar.%s.Time.86400" % self.vxv.get_symbol()) # non tradable self.xiv_bar = app_context.inst_data_mgr.get_series("Bar.%s.Time.86400" % self.xiv.get_symbol()) self.vxx_bar = app_context.inst_data_mgr.get_series("Bar.%s.Time.86400" % self.vxx.get_symbol()) self.vix_strm = BehaviorSubject(0) self.vxv_strm = BehaviorSubject(0) self.ratio_strm = rx.Observable \ .zip(self.vix_strm, self.vxv_strm, lambda x, y: x / y) \ .subscribe(self.on_ratio) super(VixVxvRatio, self)._start(app_context, **kwargs)
def _start(self, app_context, **kwargs): self.ou_params = self.get_stg_config_value("ou_params", 1) self.gamma = self.get_stg_config_value("gamma", 1) self.bar_0 = app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.app_context.app_config.instrument_ids[0]) self.bar_0.start(app_context) self.bar_1 = app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.app_context.app_config.instrument_ids[1]) self.bar_1.start(app_context) self.instruments = self.app_context.app_config.instrument_ids self.log_spot_0 = BehaviorSubject(0) self.log_spot_1 = BehaviorSubject(0) self.spread_stream = rx.Observable \ .zip(self.log_spot_0, self.log_spot_1, lambda x, y: [x, y, x - y]) \ .subscribe(self.rebalance) super(PairTradingWithOUSpread, self)._start(app_context, **kwargs)
class SerialHelper: ser = serial.Serial('/dev/ttyACM0', 115200) def __init__(self): self.messages = BehaviorSubject("") self.read() # def read(self, recieved): # while self.ser.in_waiting: # recieved(self.ser.readline()) # def read(self): self.threadObj = threading.Thread(target=worker, args=(self,)) self.threadObj.start() def setMessage(self, message): self.messages.on_next(message) def write(self, message): self.ser.write(message);
def __init__(self, new_players, exiting_players): self._new_players = [] self._players = [] self._removed_players = [] new_players.subscribe(self.add_player) exiting_players.subscribe(self.remove_player) # streams api self.new_players_broadcast = Subject() self.removed_players_broadcast = Subject() self.collisions = Subject() self.players = BehaviorSubject([]) self.players_count = self.players \ .map(lambda ps: len(ps))
def __init__(self, parent=None): super().__init__(parent) self._commandSubject = BehaviorSubject(kine.Command.arc(0, 0))
def subject_factory(scheduler): return BehaviorSubject(initial_value)
class Integrator: def __init__(self, new_players, exiting_players): self._new_players = [] self._players = [] self._removed_players = [] new_players.subscribe(self.add_player) exiting_players.subscribe(self.remove_player) # streams api self.new_players_broadcast = Subject() self.removed_players_broadcast = Subject() self.collisions = Subject() self.players = BehaviorSubject([]) self.players_count = self.players \ .map(lambda ps: len(ps)) def add_player(self, player): self._new_players.append(player) def remove_player(self, player): self._removed_players.append(player) def broadcast(self, message): for p in self._players: p.ws_subject.on_next(message) def update(self, dt): if len(self._new_players): self._do_add_players() self._integrate_speed(dt) self._collide() if len(self._removed_players): self._do_remove_players() def _collide(self): for a, b in combinations(self._players, 2): posa = a.pos.value posb = b.pos.value sizea = a.size.value sizeb = b.size.value distance = math.sqrt((posa["x"] - posb["x"]) ** 2 + (posa["y"] - posb["y"]) ** 2) if distance < sizea + sizeb: self.collisions.on_next((a, b)) def _integrate_speed(self, dt): for player in self._players: direction = player.dir.value if direction is not None \ and direction["x"] != 0 \ and direction["y"] != 0: position = player.pos.value speed = 300 * dt result = { "x": position["x"] + direction["x"] * speed, "y": position["y"] + direction["y"] * speed } player.pos.on_next(result) def _do_add_players(self): self._players.extend(self._new_players) self.new_players_broadcast.on_next( (self._players, self._new_players.copy())) self._new_players.clear() self.players.on_next(self._players) def _do_remove_players(self): for p in self._removed_players: self._players.remove(p) self.removed_players_broadcast.on_next( (self._players, self._removed_players.copy())) self._removed_players.clear() self.players.on_next(self._players)
class ServerState(): """description of class""" __metaclass__ = Singleton DEVICE_MODE = 'HBS' MAC_ADDRESS_HSU = '' LINK_STATE = '' NUM_OF_LINKS = 0 monitor_data = None SwCapabilities = None def setSwCapabilities(self, s): self.SwCapabilities = s def getSwCapabilities(self): self.SwCapabilities def setMonitor(self, d): self.monitor_data = d def getMonitor(self): return self.monitor_data #this stream will hold all hsu devices on the sector of the HBS hsuDevicesSub = BehaviorSubject(None) registeredHsusSub = BehaviorSubject({}) #this stream will hold the local monitor of the device monitorSub = BehaviorSubject(None) #this stream will hold the local recentEventSub of the device recentEventSub = BehaviorSubject(None) #api data stream systemSub = BehaviorSubject(None) deviceModeSub = BehaviorSubject(None) radioSub = BehaviorSubject(None) networkSub = BehaviorSubject(None) portsSub = BehaviorSubject(None) wifiSub = BehaviorSubject(None) #events streams onFlushingLogsSub = BehaviorSubject(None) #dispath method will use to update data on the observer def dispath(self, observer_name, payload): if observer_name == consts.MONITOR_SUB: self.monitorSub.on_next(payload) return payload elif observer_name == consts.SYSTEM_SUB: self.systemSub.on_next(payload) return payload #elif observer_name == consts.DEVICE_MODE_SUB: # self.deviceModeSub.on_next(payload) # return payload elif observer_name == consts.RADIO_SUB: self.radioSub.on_next(payload) return payload elif observer_name == consts.PORT_SUB: self.portsSub.on_next(payload) return payload elif observer_name == consts.WIFI_SUB: self.wifiSub.on_next(payload) return payload elif observer_name == consts.HSU_DEVICES_SUB: self.hsuDevicesSub.on_next(payload) return payload elif observer_name == consts.REGISTERED_HSU_SUB: self.registeredHsusSub.on_next(payload) return payload elif observer_name == consts.FLUSH_LOG_SUB: self.onFlushingLogsSub.on_next(payload) return payload else: print observer_name + ' is not recognize observable.' return None #select method will use to get observerable def select(self, observer_name): if observer_name == consts.MONITOR_SUB: return self.monitorSub elif observer_name == 'network': return self.networkSub elif observer_name == consts.SYSTEM_SUB: return self.systemSub #elif observer_name == consts.DEVICE_MODE_SUB: # return self.deviceModeSub elif observer_name == consts.RADIO_SUB: return self.radioSub elif observer_name == consts.PORT_SUB: return self.portsSub elif observer_name == consts.WIFI_SUB: return self.wifiSub elif observer_name == consts.NETWORK_SUB: return self.wifiSub elif observer_name == consts.HSU_DEVICES_SUB: return self.hsuDevicesSub elif observer_name == consts.REGISTERED_HSU_SUB: return self.registeredHsusSub elif observer_name == consts.FLUSH_LOG_SUB: return self.onFlushingLogsSub else: print observer_name + ' is not recognize observable.' return None def getDeviceMode(self): return self.DEVICE_MODE def setDeviceMode(self, mode): self.DEVICE_MODE = mode def getMacAdressHsu(self): return self.MAC_ADDRESS_HSU def setMacAdressHsu(self, address): self.MAC_ADDRESS_HSU = address @classmethod def setNumOfLinks(self, number): self.NUM_OF_LINKS = number @classmethod def getNumOfLinks(self): return self.NUM_OF_LINKS
def action1(scheduler, state=None): subject[0] = BehaviorSubject(100)
def __init__(self): self.messages = BehaviorSubject("") self.read()
class PairTradingWithOUSpread(Strategy): """ This is the baby version that assume the asset we are trading paris that the spread follows Ornstein-Uhlenbeck mean reverting process with known parameters in advance in reality this is not true So for more advanced version the strategy itself should able to call statistical inference logic to get the appreciation rate and volatility of the asset So now this class is used as testing purpose """ def __init__(self, stg_id=None, stg_configs=None): """ :param stg_id: :param portfolio: :param instruments: :param ou_params: a dictionary with k, theta, eta as keys :param gamma: risk preference :param trading_config: :return: """ super(PairTradingWithOUSpread, self).__init__(stg_id=stg_id, stg_configs=stg_configs) self.buy_order = None def _start(self, app_context, **kwargs): self.ou_params = self.get_stg_config_value("ou_params", 1) self.gamma = self.get_stg_config_value("gamma", 1) self.bar_0 = app_context.inst_data_mgr.get_series("Bar.%s.Time.86400" % self.app_context.app_config.instrument_ids[0]) self.bar_0.start(app_context) self.bar_1 = app_context.inst_data_mgr.get_series("Bar.%s.Time.86400" % self.app_context.app_config.instrument_ids[1]) self.bar_1.start(app_context) self.instruments = self.app_context.app_config.instrument_ids self.log_spot_0 = BehaviorSubject(0) self.log_spot_1 = BehaviorSubject(0) self.spread_stream = rx.Observable \ .zip(self.log_spot_0, self.log_spot_1, lambda x, y: [x, y, x - y]) \ .subscribe(self.rebalance) super(PairTradingWithOUSpread, self)._start(app_context, **kwargs) def _stop(self): super(PairTradingWithOUSpread, self)._stop() def on_bar(self, bar): # logger.info("%s,%s,%.2f" % (bar.inst_id, bar.timestamp, bar.close)) if bar.inst_id == self.instruments[0]: self.log_spot_0.on_next(math.log(bar.close)) elif bar.inst_id == self.instruments[1]: self.log_spot_1.on_next(math.log(bar.close)) def rebalance(self, spread_triple): if spread_triple[0] == 0: return # we have to rebalance on each bar k = self.ou_params['k'] eta = self.ou_params['eta'] theta = self.ou_params['theta'] spread = spread_triple[2] weight = k * (spread - theta) / eta ** 2 portfolio = self.get_portfolio() allocation_0 = -portfolio.total_equity * weight allocation_1 = portfolio.total_equity * weight # TODO: need to check if the portoflio.positions is empty delta_0 = allocation_0 delta_1 = allocation_1 if self.instruments[0] in portfolio.positions.keys(): delta_0 = allocation_0 - portfolio.positions[self.instruments[0]].current_value() if self.instruments[1] in portfolio.positions.keys(): delta_1 = allocation_1 - portfolio.positions[self.instruments[1]].current_value() qty = abs(delta_0) / spread_triple[0] # assume no lot size here if delta_0 > 0: self.market_order(inst_id=self.instruments[0], action=OrdAction.BUY, qty=qty) else: self.market_order(inst_id=self.instruments[0], action=OrdAction.SELL, qty=qty) qty = abs(delta_1) / spread_triple[1] # assume no lot size here if delta_1 > 0: self.market_order(inst_id=self.instruments[1], action=OrdAction.BUY, qty=qty) else: self.market_order(inst_id=self.instruments[1], action=OrdAction.SELL, qty=qty)
def action1(scheduler, state=None): nonlocal subject subject = BehaviorSubject(100)
class PairTradingWithOUSpread(Strategy): """ This is the baby version that assume the asset we are trading paris that the spread follows Ornstein-Uhlenbeck mean reverting process with known parameters in advance in reality this is not true So for more advanced version the strategy itself should able to call statistical inference logic to get the appreciation rate and volatility of the asset So now this class is used as testing purpose """ def __init__(self, stg_id: str, stg_cls: str, state: StrategyState = None): super(PairTradingWithOUSpread, self).__init__(stg_id=stg_id, stg_cls=stg_cls, state=state) self.buy_order = None def _start(self, app_context: Context) -> None: self.ou_params = self._get_stg_config("ou_params", default=1) self.gamma = self._get_stg_config("gamma", default=1) self.instruments = app_context.config.get_app_config("instrumentIds") self.bar_0 = self.app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.instruments[0]) self.bar_1 = self.app_context.inst_data_mgr.get_series( "Bar.%s.Time.86400" % self.instruments[1]) self.bar_0.start(app_context) self.bar_1.start(app_context) self.log_spot_0 = BehaviorSubject(0) self.log_spot_1 = BehaviorSubject(0) self.spread_stream = rx.Observable \ .zip(self.log_spot_0, self.log_spot_1, lambda x, y: [x, y, x - y]) \ .subscribe(self.rebalance) super(PairTradingWithOUSpread, self)._start(app_context) def _stop(self): super(PairTradingWithOUSpread, self)._stop() def on_bar(self, bar): # logger.info("%s,%s,%.2f" % (bar.inst_id, bar.timestamp, bar.close)) if bar.inst_id == self.instruments[0]: self.log_spot_0.on_next(math.log(bar.close)) elif bar.inst_id == self.instruments[1]: self.log_spot_1.on_next(math.log(bar.close)) def rebalance(self, spread_triple): if spread_triple[0] == 0: return # we have to rebalance on each bar k = self.ou_params['k'] eta = self.ou_params['eta'] theta = self.ou_params['theta'] spread = spread_triple[2] weight = k * (spread - theta) / eta**2 portfolio = self.get_portfolio() allocation_0 = -portfolio.total_equity * weight allocation_1 = portfolio.total_equity * weight # TODO: need to check if the portoflio.positions is empty delta_0 = allocation_0 delta_1 = allocation_1 if self.instruments[0] in portfolio.positions.keys(): delta_0 = allocation_0 - portfolio.positions[ self.instruments[0]].current_value() if self.instruments[1] in portfolio.positions.keys(): delta_1 = allocation_1 - portfolio.positions[ self.instruments[1]].current_value() qty = abs(delta_0) / spread_triple[0] # assume no lot size here if delta_0 > 0: self.market_order(inst_id=self.instruments[0], action=Buy, qty=qty) else: self.market_order(inst_id=self.instruments[0], action=Sell, qty=qty) qty = abs(delta_1) / spread_triple[1] # assume no lot size here if delta_1 > 0: self.market_order(inst_id=self.instruments[1], action=Buy, qty=qty) else: self.market_order(inst_id=self.instruments[1], action=Sell, qty=qty)
def rxValue(self, subj, pred, default): # -> BehaviorSubject: value = BehaviorSubject(default) self._rxValues[value] = (subj, pred, default) self._rxUpdate(subj, pred, default, value) return value
def __init__(self): self.data: Subject = Subject() self.threats: BehaviorSubject = BehaviorSubject(0)
class Backend(QObject): def __init__(self, parent=None): super().__init__(parent) self._commandSubject = BehaviorSubject(kine.Command.arc(0, 0)) @pyqtSlot() def forward(self): self._commandSubject.on_next(kine.Command.arc(0.5, 0.0)) @pyqtSlot() def backward(self): self._commandSubject.on_next(kine.Command.arc(-0.5, 0.0)) @pyqtSlot() def left(self): self._commandSubject.on_next(kine.Command.arc(0.5, 0.5)) @pyqtSlot() def right(self): self._commandSubject.on_next(kine.Command.arc(0.5, -0.5)) @pyqtSlot() def stop(self): self._commandSubject.on_next(kine.Command.arc(0.0, 0.0)) @pyqtSlot() def pivotLeft(self): self._commandSubject.on_next( kine.Command(velocity=0, angularVelocity=0.3)) @pyqtSlot() def pivotRight(self): self._commandSubject.on_next( kine.Command(velocity=0, angularVelocity=-0.3)) @pyqtSlot() def toOrigin(self): self._commandSubject.on_next( kine.Command.arc_to(self.robot.pose, Vec2.zero(), 0.5)) @property def commands(self): return self._commandSubject
def subject_selector(): return BehaviorSubject(initial_value)