Breakout fsp rt loop as non-closure for readability
							parent
							
								
									f6f4a0cd8d
								
							
						
					
					
						commit
						efd93d058a
					
				| 
						 | 
					@ -17,6 +17,7 @@
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
Financial signal processing for the peeps.
 | 
					Financial signal processing for the peeps.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					from functools import partial
 | 
				
			||||||
from typing import AsyncIterator, Callable, Tuple
 | 
					from typing import AsyncIterator, Callable, Tuple
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import trio
 | 
					import trio
 | 
				
			||||||
| 
						 | 
					@ -29,6 +30,8 @@ from .. import data
 | 
				
			||||||
from ._momo import _rsi, _wma
 | 
					from ._momo import _rsi, _wma
 | 
				
			||||||
from ._volume import _tina_vwap
 | 
					from ._volume import _tina_vwap
 | 
				
			||||||
from ..data import attach_shm_array
 | 
					from ..data import attach_shm_array
 | 
				
			||||||
 | 
					from ..data.feed import Feed
 | 
				
			||||||
 | 
					from ..data._sharedmem import ShmArray
 | 
				
			||||||
 | 
					
 | 
				
			||||||
log = get_logger(__name__)
 | 
					log = get_logger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,31 +65,19 @@ async def latency(
 | 
				
			||||||
            yield value
 | 
					            yield value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@tractor.stream
 | 
					 | 
				
			||||||
async def cascade(
 | 
					 | 
				
			||||||
    ctx: tractor.Context,
 | 
					 | 
				
			||||||
    brokername: str,
 | 
					 | 
				
			||||||
    src_shm_token: dict,
 | 
					 | 
				
			||||||
    dst_shm_token: Tuple[str, np.dtype],
 | 
					 | 
				
			||||||
    symbol: str,
 | 
					 | 
				
			||||||
    fsp_func_name: str,
 | 
					 | 
				
			||||||
) -> AsyncIterator[dict]:
 | 
					 | 
				
			||||||
    """Chain streaming signal processors and deliver output to
 | 
					 | 
				
			||||||
    destination mem buf.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    """
 | 
					 | 
				
			||||||
    src = attach_shm_array(token=src_shm_token)
 | 
					 | 
				
			||||||
    dst = attach_shm_array(readonly=False, token=dst_shm_token)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    func: Callable = _fsps[fsp_func_name]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # open a data feed stream with requested broker
 | 
					 | 
				
			||||||
    async with data.open_feed(brokername, [symbol]) as feed:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assert src.token == feed.shm.token
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async def fsp_compute(
 | 
					async def fsp_compute(
 | 
				
			||||||
 | 
					    ctx: tractor.Context,
 | 
				
			||||||
 | 
					    symbol: str,
 | 
				
			||||||
 | 
					    feed: Feed,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    src: ShmArray,
 | 
				
			||||||
 | 
					    dst: ShmArray,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fsp_func_name: str,
 | 
				
			||||||
 | 
					    func: Callable,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    task_status: TaskStatus[None] = trio.TASK_STATUS_IGNORED,
 | 
					    task_status: TaskStatus[None] = trio.TASK_STATUS_IGNORED,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
) -> None:
 | 
					) -> None:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # TODO: load appropriate fsp with input args
 | 
					    # TODO: load appropriate fsp with input args
 | 
				
			||||||
| 
						 | 
					@ -95,6 +86,12 @@ async def cascade(
 | 
				
			||||||
        sym: str,
 | 
					        sym: str,
 | 
				
			||||||
        stream,
 | 
					        stream,
 | 
				
			||||||
    ):
 | 
					    ):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # TODO: make this the actualy first quote from feed
 | 
				
			||||||
 | 
					        # XXX: this allows for a single iteration to run for history
 | 
				
			||||||
 | 
					        # processing without waiting on the real-time feed for a new quote
 | 
				
			||||||
 | 
					        yield {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # task cancellation won't kill the channel
 | 
					        # task cancellation won't kill the channel
 | 
				
			||||||
        with stream.shield():
 | 
					        with stream.shield():
 | 
				
			||||||
            async for quotes in stream:
 | 
					            async for quotes in stream:
 | 
				
			||||||
| 
						 | 
					@ -158,11 +155,48 @@ async def cascade(
 | 
				
			||||||
            # stream latest shm array index entry
 | 
					            # stream latest shm array index entry
 | 
				
			||||||
            await ctx.send_yield(index)
 | 
					            await ctx.send_yield(index)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@tractor.stream
 | 
				
			||||||
 | 
					async def cascade(
 | 
				
			||||||
 | 
					    ctx: tractor.Context,
 | 
				
			||||||
 | 
					    brokername: str,
 | 
				
			||||||
 | 
					    src_shm_token: dict,
 | 
				
			||||||
 | 
					    dst_shm_token: Tuple[str, np.dtype],
 | 
				
			||||||
 | 
					    symbol: str,
 | 
				
			||||||
 | 
					    fsp_func_name: str,
 | 
				
			||||||
 | 
					) -> AsyncIterator[dict]:
 | 
				
			||||||
 | 
					    """Chain streaming signal processors and deliver output to
 | 
				
			||||||
 | 
					    destination mem buf.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    src = attach_shm_array(token=src_shm_token)
 | 
				
			||||||
 | 
					    dst = attach_shm_array(readonly=False, token=dst_shm_token)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    func: Callable = _fsps[fsp_func_name]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # open a data feed stream with requested broker
 | 
				
			||||||
 | 
					    async with data.open_feed(brokername, [symbol]) as feed:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert src.token == feed.shm.token
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        last_len = new_len = len(src.array)
 | 
					        last_len = new_len = len(src.array)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fsp_target = partial(
 | 
				
			||||||
 | 
					            fsp_compute,
 | 
				
			||||||
 | 
					            ctx=ctx,
 | 
				
			||||||
 | 
					            symbol=symbol,
 | 
				
			||||||
 | 
					            feed=feed,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            src=src,
 | 
				
			||||||
 | 
					            dst=dst,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fsp_func_name=fsp_func_name,
 | 
				
			||||||
 | 
					            func=func
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        async with trio.open_nursery() as n:
 | 
					        async with trio.open_nursery() as n:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            cs = await n.start(fsp_compute)
 | 
					            cs = await n.start(fsp_target)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # Increment the underlying shared memory buffer on every
 | 
					            # Increment the underlying shared memory buffer on every
 | 
				
			||||||
            # "increment" msg received from the underlying data feed.
 | 
					            # "increment" msg received from the underlying data feed.
 | 
				
			||||||
| 
						 | 
					@ -176,7 +210,7 @@ async def cascade(
 | 
				
			||||||
                        # respawn the signal compute task if the source
 | 
					                        # respawn the signal compute task if the source
 | 
				
			||||||
                        # signal has been updated
 | 
					                        # signal has been updated
 | 
				
			||||||
                        cs.cancel()
 | 
					                        cs.cancel()
 | 
				
			||||||
                        cs = await n.start(fsp_compute)
 | 
					                        cs = await n.start(fsp_target)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        # TODO: adopt an incremental update engine/approach
 | 
					                        # TODO: adopt an incremental update engine/approach
 | 
				
			||||||
                        # where possible here eventually!
 | 
					                        # where possible here eventually!
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue