@ -27,6 +27,8 @@ const optionContractToTicker = ({
 
		
	
		
			
				
 
		
	
		
			
				type  PolygonResponse  =  {  
		
	
		
			
				  next_url? : string ; 
 
		
	
		
			
				  status : string ; 
 
		
	
		
			
				  resultsCount : number ; 
 
		
	
		
			
				  results : Array < { 
 
		
	
		
			
				    c : number ; 
 
		
	
		
			
				    h : number ; 
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -80,31 +82,33 @@ async function getOptionAggregates(
 
		
	
		
			
				      ) . json ( ) )  as  PolygonResponse , 
 
		
	
		
			
				    {  retries : 5 ,  factor : 2 ,  minTimeout : 1000 ,  maxTimeout : 60  *  1000  } 
 
		
	
		
			
				  ) ; 
 
		
	
		
			
				  if  ( ! latestBatchResponse . results )  { 
 
		
	
		
			
				  if  ( latestBatchResponse . status . toLowerCase ( )  !==  "ok" )  { 
 
		
	
		
			
				    console . log ( latestBatchResponse ) ; 
 
		
	
		
			
				    return ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				  let  latestBatch  =  latestBatchResponse . results . map ( ( result )  = >  ( { 
 
		
	
		
			
				    symbol :  underlyingSymbol , 
 
		
	
		
			
				    expirationDate , 
 
		
	
		
			
				    strike , 
 
		
	
		
			
				    type , 
 
		
	
		
			
				  if  ( latestBatchResponse . resultsCount  >  0 )  { 
 
		
	
		
			
				    let  latestBatch  =  latestBatchResponse . results . map ( ( result )  = >  ( { 
 
		
	
		
			
				      symbol :  underlyingSymbol , 
 
		
	
		
			
				      expirationDate , 
 
		
	
		
			
				      strike , 
 
		
	
		
			
				      type , 
 
		
	
		
			
				
 
		
	
		
			
				    tsStart :  ( result . t  ||  0 )  /  1000 , 
 
		
	
		
			
				    open : result.o , 
 
		
	
		
			
				    close : result.c , 
 
		
	
		
			
				    low : result.l , 
 
		
	
		
			
				    high : result.h , 
 
		
	
		
			
				  } ) ) ; 
 
		
	
		
			
				  await  pRetry ( 
 
		
	
		
			
				    ( )  = > 
 
		
	
		
			
				      clickhouse . insert ( { 
 
		
	
		
			
				        table :  "option_aggregates" , 
 
		
	
		
			
				        values : latestBatch , 
 
		
	
		
			
				        format :  "JSONEachRow" , 
 
		
	
		
			
				      } ) , 
 
		
	
		
			
				    {  retries : 5 ,  factor : 2 ,  minTimeout : 1000 ,  maxTimeout : 60  *  1000  } 
 
		
	
		
			
				  ) ; 
 
		
	
		
			
				      tsStart :  ( result . t  ||  0 )  /  1000 , 
 
		
	
		
			
				      open : result.o , 
 
		
	
		
			
				      close : result.c , 
 
		
	
		
			
				      low : result.l , 
 
		
	
		
			
				      high : result.h , 
 
		
	
		
			
				    } ) ) ; 
 
		
	
		
			
				    await  pRetry ( 
 
		
	
		
			
				      ( )  = > 
 
		
	
		
			
				        clickhouse . insert ( { 
 
		
	
		
			
				          table :  "option_aggregates" , 
 
		
	
		
			
				          values : latestBatch , 
 
		
	
		
			
				          format :  "JSONEachRow" , 
 
		
	
		
			
				        } ) , 
 
		
	
		
			
				      {  retries : 5 ,  factor : 2 ,  minTimeout : 1000 ,  maxTimeout : 60  *  1000  } 
 
		
	
		
			
				    ) ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				  await  pRetry ( 
 
		
	
		
			
				    ( )  = > 
 
		
	
		
			
				      clickhouse . insert ( { 
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -137,19 +141,19 @@ async function getNextBatchOfUnstartedOptionAggregates(
 
		
	
		
			
				  limit : number 
 
		
	
		
			
				) :  Promise < Array < OptionContractDay > >  {  
		
	
		
			
				  if  ( typeof  previousUnstartedOptionContract  ===  "undefined" )  { 
 
		
	
		
			
				    return ; 
 
		
	
		
			
				    return  [ ]  ; 
 
		
	
		
			
				  } 
 
		
	
		
			
				  const  optionContractsWithoutAggregates  =  await  pRetry ( 
 
		
	
		
			
				    ( )  = > 
 
		
	
		
			
				      query < OptionContractDay > ( ` 
 
		
	
		
			
				  const  queryContents  =  ` 
 
		
	
		
			
				    SELECT  
 
		
	
		
			
				      asOfDate , 
 
		
	
		
			
				      symbol ,  
 
		
	
		
			
				      expirationDate ,  
 
		
	
		
			
				      strike ,  
 
		
	
		
			
				      type 
 
		
	
		
			
				      type , 
 
		
	
		
			
				      argMax ( status ,  ts )  as  status 
 
		
	
		
			
				    FROM  amg_option_aggregate_sync_statuses 
 
		
	
		
			
				    WHERE  ( 
 
		
	
		
			
				    WHERE  symbol  IN  [ 'AAPL' , 'AMD' , 'GOOGL' , 'MSFT' , 'NFLX' ] 
 
		
	
		
			
				    AND  ( 
 
		
	
		
			
				      ( 
 
		
	
		
			
				        asOfDate  =  '${previousUnstartedOptionContract.asOfDate}' 
 
		
	
		
			
				        AND  symbol  =  '${previousUnstartedOptionContract.symbol}' 
 
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
			
			@ -177,13 +181,18 @@ async function getNextBatchOfUnstartedOptionAggregates(
 
		
	
		
			
				        asOfDate  >  '${previousUnstartedOptionContract.asOfDate}' 
 
		
	
		
			
				      ) 
 
		
	
		
			
				    ) 
 
		
	
		
			
				    AND  status  =  'not-started' 
 
		
	
		
			
				    GROUP  BY  asOfDate ,  symbol ,  expirationDate ,  strike ,  type 
 
		
	
		
			
				    HAVING  status  =  'not-started' 
 
		
	
		
			
				    ORDER  BY  asOfDate ,  symbol ,  expirationDate ,  strike ,  type 
 
		
	
		
			
				    LIMIT  $ { limit } 
 
		
	
		
			
				  ` ),
 
 
		
	
		
			
				  ` ;
 
 
		
	
		
			
				  //console.log(queryContents);
 
 
		
	
		
			
				  const  optionContractsWithoutAggregates  =  await  pRetry ( 
 
		
	
		
			
				    ( )  = >  query < OptionContractDay > ( queryContents ) , 
 
		
	
		
			
				    {  retries : 5 ,  factor : 2 ,  minTimeout : 1000 ,  maxTimeout : 60  *  1000  } 
 
		
	
		
			
				  ) ; 
 
		
	
		
			
				  return  optionContractsWithoutAggregates ; 
 
		
	
		
			
				  console . log ( ` Got  ${ optionContractsWithoutAggregates . length }  records ` ) ; 
 
		
	
		
			
				  return  optionContractsWithoutAggregates  ||  [ ] ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				/ * *  
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -194,91 +203,97 @@ async function getNextBatchOfUnstartedOptionAggregates(
 
		
	
		
			
				 *  so  as  to  start  afresh . 
 
		
	
		
			
				 * / 
 
		
	
		
			
				async  function  revertPendingSyncs() {  
		
	
		
			
				  const  pendingOptionContracts  =  await  query < { 
 
		
	
		
			
				    asOfDate : string ; 
 
		
	
		
			
				    symbol :  string ; 
 
		
	
		
			
				    expirationDate : string ; 
 
		
	
		
			
				    strike : number ; 
 
		
	
		
			
				    type :  "call"  |  "put" ; 
 
		
	
		
			
				    latestStatus :  "not-started"  |  "pending"  |  "done" ; 
 
		
	
		
			
				  } > ( ` 
 
		
	
		
			
				    SELECT  
 
		
	
		
			
				  const  batchSize  =  1000 ; 
 
		
	
		
			
				  let  pendingOptionContracts ; 
 
		
	
		
			
				  do  { 
 
		
	
		
			
				    pendingOptionContracts  =  await  query < { 
 
		
	
		
			
				      asOfDate : string ; 
 
		
	
		
			
				      symbol :  string ; 
 
		
	
		
			
				      expirationDate : string ; 
 
		
	
		
			
				      strike : number ; 
 
		
	
		
			
				      type :  "call"  |  "put" ; 
 
		
	
		
			
				      latestStatus :  "not-started"  |  "pending"  |  "done" ; 
 
		
	
		
			
				    } > ( ` 
 
		
	
		
			
				    SELECT 
 
		
	
		
			
				      asOfDate , 
 
		
	
		
			
				      symbol , 
 
		
	
		
			
				      expirationDate , 
 
		
	
		
			
				      strike , 
 
		
	
		
			
				      type 
 
		
	
		
			
				      type , 
 
		
	
		
			
				      argMax ( status ,  ts )  as  status 
 
		
	
		
			
				    FROM  amg_option_aggregate_sync_statuses 
 
		
	
		
			
				    WHERE  status  =  'pending' 
 
		
	
		
			
				    ORDER  BY  asOfDate ,  symbol ,  expirationDate ,  strike ,  type 
 
		
	
		
			
				  ` );
 
 
		
	
		
			
				  console . log ( 
 
		
	
		
			
				    "Pending operations:" , 
 
		
	
		
			
				    pendingOptionContracts . map ( 
 
		
	
		
			
				      ( {  asOfDate ,  symbol ,  expirationDate ,  strike ,  type  } )  = > 
 
		
	
		
			
				        ` ${ symbol }   ${ expirationDate }   ${ strike }   ${ type }   @   ${ asOfDate } ` 
 
		
	
		
			
				    ) 
 
		
	
		
			
				  ) ; 
 
		
	
		
			
				  await  pAll ( 
 
		
	
		
			
				    pendingOptionContracts . map ( 
 
		
	
		
			
				      ( {  asOfDate ,  symbol ,  expirationDate ,  strike ,  type  } )  = > 
 
		
	
		
			
				        ( )  = > 
 
		
	
		
			
				          pSeries ( [ 
 
		
	
		
			
				            // Delete option_contracts first, in case this `pAll` operation fails and we need to restart; so `option_contract_sync_statuses` "pending" rows are still there for the restart
 
 
		
	
		
			
				            ( )  = > 
 
		
	
		
			
				              clickhouse 
 
		
	
		
			
				                . command ( { 
 
		
	
		
			
				                  query :  ` 
 
		
	
		
			
				                  DELETE  FROM  option_aggregates  
 
		
	
		
			
				                  WHERE  symbol  =  '${symbol}'  
 
		
	
		
			
				                  AND  expirationDate  =  '${expirationDate}' 
 
		
	
		
			
				                  AND  strike  =  $ { strike } 
 
		
	
		
			
				                  AND  type  =  '${type}' 
 
		
	
		
			
				                  AND  toDate ( tsStart )  =  '${asOfDate}' 
 
		
	
		
			
				                ` ,
 
 
		
	
		
			
				                } ) 
 
		
	
		
			
				                . then ( ( )  = >  { 
 
		
	
		
			
				                  console . log ( ` Deleted aggregates for  ` ) ; 
 
		
	
		
			
				                } ) , 
 
		
	
		
			
				            ( )  = > 
 
		
	
		
			
				              clickhouse 
 
		
	
		
			
				                . insert ( { 
 
		
	
		
			
				                  table :  "amg_option_aggregate_sync_statuses" , 
 
		
	
		
			
				                  values :  [ 
 
		
	
		
			
				                    { 
 
		
	
		
			
				                      asOfDate , 
 
		
	
		
			
				                      symbol , 
 
		
	
		
			
				                      expirationDate , 
 
		
	
		
			
				                      strike , 
 
		
	
		
			
				                      type , 
 
		
	
		
			
				                      status :  "not-started" , 
 
		
	
		
			
				                    } , 
 
		
	
		
			
				                  ] , 
 
		
	
		
			
				                  format :  "JSONEachRow" , 
 
		
	
		
			
				                } ) 
 
		
	
		
			
				                . then ( ( )  = >  { 
 
		
	
		
			
				                  console . log ( ) ; 
 
		
	
		
			
				                } ) , 
 
		
	
		
			
				          ] ) 
 
		
	
		
			
				    ) , 
 
		
	
		
			
				    {  concurrency : 1  } 
 
		
	
		
			
				  ) ; 
 
		
	
		
			
				    WHERE  symbol  IN  [ 'AAPL' , 'AMD' , 'GOOGL' , 'MSFT' , 'NFLX' ] 
 
		
	
		
			
				    GROUP  BY  asOfDate ,  symbol ,  expirationDate ,  strike ,  type 
 
		
	
		
			
				    HAVING  status  =  'pending' 
 
		
	
		
			
				    LIMIT  $ { batchSize } 
 
		
	
		
			
				    ` );
 
 
		
	
		
			
				    console . log ( 
 
		
	
		
			
				      "Pending operations:" , 
 
		
	
		
			
				      pendingOptionContracts . map ( 
 
		
	
		
			
				        ( {  asOfDate ,  symbol ,  expirationDate ,  strike ,  type  } )  = > 
 
		
	
		
			
				          ` ${ symbol }   ${ expirationDate }   ${ strike }   ${ type }   @   ${ asOfDate } ` 
 
		
	
		
			
				      ) 
 
		
	
		
			
				    ) ; 
 
		
	
		
			
				    await  pSeries ( [ 
 
		
	
		
			
				      // Delete option_contracts first, in case this `pAll` operation fails and we need to restart; so `option_contract_sync_statuses` "pending" rows are still there for the restart
 
 
		
	
		
			
				      ( )  = > 
 
		
	
		
			
				        clickhouse 
 
		
	
		
			
				          . command ( { 
 
		
	
		
			
				            query :  ` 
 
		
	
		
			
				                    DELETE  FROM  option_aggregates  
 
		
	
		
			
				                    WHERE  ( symbol ,  expirationDate ,  strike ,  type ,  toDate ( tsStart ) )  
 
		
	
		
			
				                    IN  [ $ { pendingOptionContracts 
 
		
	
		
			
				                      . map ( 
 
		
	
		
			
				                        ( {  asOfDate ,  symbol ,  expirationDate ,  strike ,  type  } )  = > 
 
		
	
		
			
				                          ` (' ${ symbol } ', ' ${ expirationDate } ',  ${ strike } , ' ${ type } ', ' ${ asOfDate } ') ` 
 
		
	
		
			
				                      ) 
 
		
	
		
			
				                      . join ( "," ) } 
 
		
	
		
			
				                    ] 
 
		
	
		
			
				                  ` ,
 
 
		
	
		
			
				          } ) 
 
		
	
		
			
				          . then ( ( )  = >  { 
 
		
	
		
			
				            console . log ( ` Deleted  ${ pendingOptionContracts . length }  aggregates ` ) ; 
 
		
	
		
			
				          } ) , 
 
		
	
		
			
				      ( )  = > 
 
		
	
		
			
				        clickhouse 
 
		
	
		
			
				          . insert ( { 
 
		
	
		
			
				            table :  "amg_option_aggregate_sync_statuses" , 
 
		
	
		
			
				            values : pendingOptionContracts.map ( 
 
		
	
		
			
				              ( {  asOfDate ,  symbol ,  expirationDate ,  strike ,  type  } )  = >  ( { 
 
		
	
		
			
				                asOfDate , 
 
		
	
		
			
				                symbol , 
 
		
	
		
			
				                expirationDate , 
 
		
	
		
			
				                strike , 
 
		
	
		
			
				                type , 
 
		
	
		
			
				                status :  "not-started" , 
 
		
	
		
			
				              } ) 
 
		
	
		
			
				            ) , 
 
		
	
		
			
				            format :  "JSONEachRow" , 
 
		
	
		
			
				          } ) 
 
		
	
		
			
				          . then ( ( )  = >  { } ) , 
 
		
	
		
			
				    ] ) ; 
 
		
	
		
			
				  }  while  ( pendingOptionContracts . length  ===  batchSize ) ; 
 
		
	
		
			
				  await  clickhouse . command ( { 
 
		
	
		
			
				    query :  ` 
 
		
	
		
			
				      OPTIMIZE  TABLE  amg_option_aggregate_sync_statuses  FINAL 
 
		
	
		
			
				    ` ,
 
 
		
	
		
			
				  } ) ; 
 
		
	
		
			
				}  
		
	
		
			
				
 
		
	
		
			
				// First, revert 'pending' syncs:
  
		
	
		
			
				//await revertPendingSyncs();
  
		
	
		
			
				await  revertPendingSyncs ( ) ;  
		
	
		
			
				
 
		
	
		
			
				/ * *   S e c o n d ,   f o r   e a c h   o p t i o n   c o n t r a c t ,   g e t   a l l   o f   i t s   q u o t e s .  
		
	
		
			
				 * 
 
		
	
		
			
				 *  This  queries  Polygon  with  a  concurrency  of  . 
 
		
	
		
			
				 *  This  queries  Polygon  with  a  concurrency  of  1 6. 
 
		
	
		
			
				 * / 
 
		
	
		
			
				const  q  =  new  pQueue ( {  concurrency : } ) ;  
		
	
		
			
				const  q  =  new  pQueue ( {  concurrency : 1 6 } ) ;  
		
	
		
			
				/ * *   I n i t i a l i z e d   w i t h   t h e   l o w e s t   p o s s i b l e   o p t i o n   c o n t r a c t .  
		
	
		
			
				 *   It ' s  passed  into  ` getNextUnstartedSymbolAndAsOfDate() ` . 
 
		
	
		
			
				 * / 
 
		
	
		
			
				let  nextBatchOfUnstartedOptionContracts : Array < OptionContractDay >  =  [  
		
	
		
			
				  { 
 
		
	
		
			
				    asOfDate :  "2022-0 4-05 ", 
 
		
	
		
			
				    asOfDate :  "2022-0 3-27 ", 
 
		
	
		
			
				    symbol :  "A" , 
 
		
	
		
			
				    expirationDate :  "2022-02-01" , 
 
		
	
		
			
				    strike : 0 , 
 
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
			
			@ -289,8 +304,8 @@ while (
 
		
	
		
			
				  ( nextBatchOfUnstartedOptionContracts  = 
 
		
	
		
			
				    await  getNextBatchOfUnstartedOptionAggregates ( 
 
		
	
		
			
				      nextBatchOfUnstartedOptionContracts . pop ( ) , 
 
		
	
		
			
				      2 00
 
		
	
		
			
				    ) )  !==  null  
 
		
	
		
			
				      1 00
 
		
	
		
			
				    ) ) . length  !==  0 
 
		
	
		
			
				)  {  
		
	
		
			
				  await  pAll ( 
 
		
	
		
			
				    nextBatchOfUnstartedOptionContracts . map (