|
|
@@ -45,7 +45,7 @@ def main() -> None:
|
|
|
commodities.sort(reverse=True)
|
|
|
for m in commodities:
|
|
|
print(f'{m.full_ticker:>8} {m.bid:5} {m.ask:5} {m.spread*100: 5.0f}% {m.chart_analysis.bids_filled:12.0f} '
|
|
|
- f'{m.chart_analysis.asks_filled:12.0f} {m.chart_analysis.profits:10.0f} {m.chart_analysis.p75_fill_time}')
|
|
|
+ f'{m.chart_analysis.asks_filled:12.0f} {m.chart_analysis.profits:10.0f} {format_td(m.chart_analysis.p75_fill_time)}')
|
|
|
print()
|
|
|
|
|
|
def check_cxos() -> None:
|
|
|
@@ -82,10 +82,13 @@ def analyze_price_chart(exchange_ticker: str, midpoint: float) -> ChartAnalysis:
|
|
|
if p['Interval'] == 'MINUTE_FIVE']
|
|
|
pcpoints.reverse()
|
|
|
five_min = 5 * 60 * 1000
|
|
|
+ cutoff = datetime.datetime.now(datetime.UTC) - datetime.timedelta(days=30)
|
|
|
asks_filled: list[AskFilled] = []
|
|
|
fill_time = []
|
|
|
r = ChartAnalysis(bids_filled=0, asks_filled=0, profits=0, p75_fill_time=datetime.timedelta.max)
|
|
|
for hist in pcpoints:
|
|
|
+ if datetime.datetime.fromtimestamp(hist['DateEpochMs'] // 1000, datetime.UTC) < cutoff:
|
|
|
+ continue
|
|
|
time = hist['DateEpochMs'] // five_min
|
|
|
bids = asks = 0
|
|
|
if hist['Low'] > midpoint:
|
|
|
@@ -129,6 +132,13 @@ def analyze_price_chart(exchange_ticker: str, midpoint: float) -> ChartAnalysis:
|
|
|
r.p75_fill_time = statistics.quantiles(fill_time, n=4)[2] * datetime.timedelta(minutes=5)
|
|
|
return r
|
|
|
|
|
|
+def format_td(td: datetime.timedelta) -> str:
|
|
|
+ if td == datetime.timedelta.max:
|
|
|
+ return '∞'
|
|
|
+ days, seconds = divmod(td.total_seconds(), 24 * 60 * 60)
|
|
|
+ hours = seconds / (60 * 60)
|
|
|
+ return f'{int(days)}d {hours:4.1f}h'
|
|
|
+
|
|
|
class ExchangeOrder(typing.TypedDict):
|
|
|
MaterialTicker: str
|
|
|
ExchangeCode: str
|