chart data fixes
This commit is contained in:
69
bin/dev
69
bin/dev
@@ -553,6 +553,9 @@ deep_restart() {
|
||||
# Force restart iceberg-catalog since it depends on postgres and minio
|
||||
echo -e "${GREEN}→${NC} Force restarting iceberg-catalog (depends on postgres/minio)..."
|
||||
kubectl delete pod -l app=iceberg-catalog 2>/dev/null || true
|
||||
# Remove all sandbox deployments and services to free quota
|
||||
echo -e "${GREEN}→${NC} Removing all sandbox deployments and services..."
|
||||
kubectl delete deployments,services --all -n dexorder-sandboxes 2>/dev/null || true
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}Error: Unknown service '$service'${NC}"
|
||||
@@ -711,19 +714,75 @@ case "$COMMAND" in
|
||||
rebuild_images
|
||||
deploy_services
|
||||
else
|
||||
# Multiple services specified
|
||||
# Multiple services specified: rebuild ALL first, then deploy ALL together.
|
||||
# Deploying one-at-a-time causes each deploy to revert the previous service's
|
||||
# image tag override (each kubectl apply -k . only carries one tag at a time).
|
||||
sandbox_requested=0
|
||||
deploy_services_list=()
|
||||
|
||||
for service in "$@"; do
|
||||
rebuild_images "$service"
|
||||
|
||||
# Special handling for sandbox: delete sandbox deployments instead of applying kustomization
|
||||
if [ "$service" == "sandbox" ]; then
|
||||
sandbox_requested=1
|
||||
else
|
||||
deploy_services_list+=("$service")
|
||||
fi
|
||||
done
|
||||
|
||||
# Deploy all non-sandbox services together in one kustomize apply
|
||||
if [ ${#deploy_services_list[@]} -gt 0 ]; then
|
||||
if [ -f "$ROOT_DIR/.dev-image-tag" ]; then
|
||||
source "$ROOT_DIR/.dev-image-tag"
|
||||
fi
|
||||
|
||||
cd "$ROOT_DIR/deploy/k8s/dev"
|
||||
|
||||
# Template gateway-config if gateway is in the list
|
||||
for svc in "${deploy_services_list[@]}"; do
|
||||
if [ "$svc" == "gateway" ]; then
|
||||
sed -i "s/SANDBOX_TAG_PLACEHOLDER/$SANDBOX_TAG/g" "$ROOT_DIR/deploy/k8s/dev/configs/gateway-config.yaml"
|
||||
sed -i "s/SIDECAR_TAG_PLACEHOLDER/$SIDECAR_TAG/g" "$ROOT_DIR/deploy/k8s/dev/configs/gateway-config.yaml"
|
||||
"$SCRIPT_DIR/config-update" dev
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Build the images stanza for all services at once
|
||||
echo "" >> kustomization.yaml
|
||||
echo "# Image tags (added by bin/dev)" >> kustomization.yaml
|
||||
echo "images:" >> kustomization.yaml
|
||||
for svc in "${deploy_services_list[@]}"; do
|
||||
case "$svc" in
|
||||
relay) echo " - name: dexorder/ai-relay" >> kustomization.yaml; echo " newTag: $RELAY_TAG" >> kustomization.yaml ;;
|
||||
ingestor) echo " - name: dexorder/ai-ingestor" >> kustomization.yaml; echo " newTag: $INGEST_TAG" >> kustomization.yaml ;;
|
||||
flink) echo " - name: dexorder/ai-flink" >> kustomization.yaml; echo " newTag: $FLINK_TAG" >> kustomization.yaml ;;
|
||||
gateway) echo " - name: dexorder/ai-gateway" >> kustomization.yaml; echo " newTag: $GATEWAY_TAG" >> kustomization.yaml ;;
|
||||
web) echo " - name: dexorder/ai-web" >> kustomization.yaml; echo " newTag: $WEB_TAG" >> kustomization.yaml ;;
|
||||
lifecycle-sidecar|sidecar) echo " - name: dexorder/ai-lifecycle-sidecar" >> kustomization.yaml; echo " newTag: $SIDECAR_TAG" >> kustomization.yaml ;;
|
||||
esac
|
||||
done
|
||||
|
||||
kubectl apply -k .
|
||||
|
||||
sed -i '/# Image tags (added by bin\/dev)/,$d' kustomization.yaml
|
||||
|
||||
# Restore gateway-config placeholders if gateway was deployed
|
||||
for svc in "${deploy_services_list[@]}"; do
|
||||
if [ "$svc" == "gateway" ]; then
|
||||
sed -i "s/$SANDBOX_TAG/SANDBOX_TAG_PLACEHOLDER/g" "$ROOT_DIR/deploy/k8s/dev/configs/gateway-config.yaml"
|
||||
sed -i "s/$SIDECAR_TAG/SIDECAR_TAG_PLACEHOLDER/g" "$ROOT_DIR/deploy/k8s/dev/configs/gateway-config.yaml"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Handle sandbox separately
|
||||
if [ "$sandbox_requested" == "1" ]; then
|
||||
echo -e "${GREEN}→${NC} Deleting user container deployments in dexorder-sandboxes namespace..."
|
||||
kubectl delete deployments --all -n dexorder-sandboxes 2>/dev/null || true
|
||||
echo -e "${GREEN}✓ User containers will be recreated by gateway on next login${NC}"
|
||||
else
|
||||
deploy_service "$service"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
;;
|
||||
rebuild)
|
||||
|
||||
@@ -255,6 +255,19 @@ generatorOptions:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
type SnapshotMessage,
|
||||
type PatchMessage,
|
||||
} from '../workspace/index.js';
|
||||
import { resolutionToSeconds } from '../types/ohlc.js';
|
||||
|
||||
/**
|
||||
* Safe JSON stringifier that handles BigInt values
|
||||
@@ -487,7 +486,7 @@ export class WebSocketHandler {
|
||||
}
|
||||
const history = await ohlcService.fetchOHLC(
|
||||
payload.symbol,
|
||||
resolutionToSeconds(payload.resolution),
|
||||
payload.period_seconds,
|
||||
payload.from_time,
|
||||
payload.to_time,
|
||||
payload.countback
|
||||
|
||||
@@ -525,9 +525,9 @@ export class DuckDBClient {
|
||||
// Check if we have continuous data
|
||||
// For now, simple check: if we have any data, assume complete
|
||||
// TODO: Implement proper gap detection by checking for missing periods
|
||||
const periodMicros = BigInt(period_seconds) * 1000000n;
|
||||
const periodNanos = BigInt(period_seconds) * 1_000_000_000n;
|
||||
// end_time is exclusive, so expected count = (end - start) / period (no +1)
|
||||
const expectedBars = Number((end_time - start_time) / periodMicros);
|
||||
const expectedBars = Number((end_time - start_time) / periodNanos);
|
||||
|
||||
if (data.length < expectedBars * 0.95) { // Allow 5% tolerance
|
||||
this.logger.debug({
|
||||
|
||||
@@ -172,7 +172,7 @@ onBeforeUnmount(() => {
|
||||
}
|
||||
|
||||
.main-splitter :deep(.p-splitter-gutter-handle) {
|
||||
background: #1c1c1c !important;
|
||||
background: #2e2e2e !important;
|
||||
}
|
||||
|
||||
.chart-panel,
|
||||
|
||||
@@ -28,7 +28,7 @@ const rooms = computed(() => [{
|
||||
avatar: null,
|
||||
users: [
|
||||
{ _id: CURRENT_USER_ID, username: 'You' },
|
||||
{ _id: AGENT_ID, username: 'AI Agent', status: { state: isConnected.value ? 'online' : 'offline' } }
|
||||
{ _id: AGENT_ID, username: 'AI Agent' }
|
||||
],
|
||||
unreadCount: 0,
|
||||
typingUsers: isAgentProcessing.value ? [AGENT_ID] : []
|
||||
|
||||
@@ -79,6 +79,19 @@ export class WebSocketDatafeed implements IBasicDataFeed {
|
||||
}
|
||||
|
||||
private handleMessage(message: any): void {
|
||||
// On reconnect the server sends a fresh 'connected' message.
|
||||
// Any pending requests were sent on the old socket and will never be answered,
|
||||
// so reject them immediately so TradingView can retry on the new connection.
|
||||
if (message.type === 'connected' && this.pendingRequests.size > 0) {
|
||||
console.warn('[TradingView Datafeed] WebSocket reconnected — rejecting', this.pendingRequests.size, 'stale pending request(s)')
|
||||
for (const [requestId, pending] of this.pendingRequests) {
|
||||
clearTimeout(pending.timeout)
|
||||
pending.reject(new Error('WebSocket reconnected'))
|
||||
this.pendingRequests.delete(requestId)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Handle responses to pending requests
|
||||
if (message.request_id && this.pendingRequests.has(message.request_id)) {
|
||||
console.log('[TradingView Datafeed] Found pending request for:', message.request_id)
|
||||
@@ -186,10 +199,12 @@ export class WebSocketDatafeed implements IBasicDataFeed {
|
||||
if (response.symbol_info) {
|
||||
console.log('[TradingView Datafeed] Resolved symbol info:', response.symbol_info)
|
||||
|
||||
// Store the denominators for this symbol
|
||||
// Derive scale denominators from Nautilus precision fields.
|
||||
// price_precision=2 → tick divisor=100 (prices stored as integer cents)
|
||||
// size_precision=6 → base divisor=1_000_000 (volumes stored as integer micro-units)
|
||||
const symbolKey = response.symbol_info.ticker || response.symbol_info.name
|
||||
const tickDenom = response.symbol_info.tick_denominator || 1
|
||||
const baseDenom = response.symbol_info.base_denominator || 1
|
||||
const tickDenom = Math.pow(10, response.symbol_info.price_precision ?? 0)
|
||||
const baseDenom = Math.pow(10, response.symbol_info.size_precision ?? 0)
|
||||
|
||||
this.symbolDenominators.set(symbolKey, {
|
||||
tick: tickDenom,
|
||||
@@ -232,7 +247,7 @@ export class WebSocketDatafeed implements IBasicDataFeed {
|
||||
this.sendRequest<any>({
|
||||
type: 'get_bars',
|
||||
symbol: symbolKey,
|
||||
resolution: resolution,
|
||||
period_seconds: intervalToSeconds(resolution),
|
||||
from_time: periodParams.from,
|
||||
to_time: periodParams.to,
|
||||
countback: periodParams.countBack
|
||||
|
||||
Reference in New Issue
Block a user