Skip to content

Commit

Permalink
Merge pull request #190 from stoqey/positions
Browse files Browse the repository at this point in the history
subscription.endEventReceived implemented
  • Loading branch information
rylorin authored Sep 19, 2023
2 parents 4115a9b + a0ec54f commit 2e1d601
Show file tree
Hide file tree
Showing 45 changed files with 725 additions and 574 deletions.
18 changes: 9 additions & 9 deletions .eslintrc → .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "rxjs"],
"extends": ["plugin:@typescript-eslint/recommended"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2020,
"project": ["tsconfig.json"],
"sourceType": "module"
},
"plugins": ["@typescript-eslint", "rxjs"],
"root": true,
"rules": {
"strict": "error",
"semi": ["error", "always"],
"quotes": ["error", "double"],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-duplicate-enum-values": "error",
"@typescript-eslint/no-explicit-any": 1,
"@typescript-eslint/no-inferrable-types": [
"warn",
{
"ignoreParameters": true
}
],
"@typescript-eslint/no-unsafe-declaration-merging": "error",
"@typescript-eslint/no-unused-vars": [
"warn",
{
Expand All @@ -29,12 +28,13 @@
"varsIgnorePattern": "^_"
}
],
"@typescript-eslint/no-duplicate-enum-values": "error",
"@typescript-eslint/no-unsafe-declaration-merging": "error",
"quotes": ["error", "double"],
"rxjs/no-async-subscribe": "error",
"rxjs/no-ignored-observable": "error",
"rxjs/no-ignored-subscription": "error",
"rxjs/no-unbound-methods": "error",
"rxjs/throw-error": "error"
"rxjs/throw-error": "error",
"semi": ["error", "always"],
"strict": "error"
}
}
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,18 @@
"@types/jest": "^29.5.4",
"@types/node": "^18.17.15",
"@types/source-map-support": "^0.5.7",
"@typescript-eslint/eslint-plugin": "^6.6.0",
"@typescript-eslint/parser": "^6.6.0",
"@typescript-eslint/eslint-plugin": "^6.7.0",
"@typescript-eslint/parser": "^6.7.0",
"ajv": "^8.12.0",
"eslint": "^8.49.0",
"eslint-plugin-jest": "^27.2.3",
"eslint-plugin-rxjs": "^5.0.3",
"jest": "^29.6.4",
"jest-environment-node": "^29.6.4",
"jest": "^29.7.0",
"jest-environment-node": "^29.7.0",
"jest-junit": "^16.0.0",
"ts-jest": "^29.1.1",
"typedoc": "^0.25.1",
"typescript": "^4.9.5"
"typescript": "^5.2.2"
},
"engines": {
"node": ">=18.0.0"
Expand Down
128 changes: 96 additions & 32 deletions src/api-next/api-next.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,9 @@ export class IBApiNext {
],
]);

if (hasChanged) {
if (!subscription.endEventReceived) {
subscription.lastAllValue = cached;
} else if (hasChanged) {
subscription.next({
all: cached,
changed: accountSummaryUpdate,
Expand All @@ -450,6 +452,25 @@ export class IBApiNext {
}
};

/** accountSummaryEnd event handler */
private readonly onAccountSummaryEnd = (
subscriptions: Map<number, IBApiNextSubscription<MutableAccountSummaries>>,
reqId: number,
): void => {
// get the subscription
const subscription = subscriptions.get(reqId);
if (!subscription) {
return;
}

// get latest value on cache
const cached = subscription.lastAllValue ?? new MutableAccountSummaries();

// sent data to subscribers
subscription.endEventReceived = true;
subscription.next({ all: cached });
};

/**
* Create subscription to receive the account summaries of all linked accounts as presented in the TWS' Account Summary tab.
*
Expand Down Expand Up @@ -507,7 +528,10 @@ export class IBApiNext {
(reqId) => {
this.api.cancelAccountSummary(reqId);
},
[[EventName.accountSummary, this.onAccountSummary]],
[
[EventName.accountSummary, this.onAccountSummary],
[EventName.accountSummaryEnd, this.onAccountSummaryEnd],
],
`${group}:${tags}`,
);
}
Expand Down Expand Up @@ -713,7 +737,12 @@ export class IBApiNext {
accountName: string,
): void => {
this.logger.debug(LOG_TAG, `onAccountDownloadEnd(${accountName})`);
// TODO finish implementation
// notify all subscribers
subscriptions.forEach((subscription) => {
const all: AccountUpdate = subscription.lastAllValue ?? {};
subscription.endEventReceived = true;
subscription.next({ all });
});
};

/**
Expand Down Expand Up @@ -784,7 +813,9 @@ export class IBApiNext {
}
}

if (hasAdded) {
if (!subscription.endEventReceived) {
subscription.lastAllValue = cached;
} else if (hasAdded) {
subscription.next({
all: cached,
added: new MutableAccountPositions([[account, [updatedPosition]]]),
Expand All @@ -803,6 +834,19 @@ export class IBApiNext {
});
};

/** position end enumeration event handler */
private readonly onPositionEnd = (
subscriptions: Map<number, IBApiNextSubscription<MutableAccountPositions>>,
): void => {
// notify all subscribers
subscriptions.forEach((subscription) => {
const lastAllValue =
subscription.lastAllValue ?? new MutableAccountPositions();
subscription.endEventReceived = true;
subscription.next({ all: lastAllValue });
});
};

/**
* Create subscription to receive the positions on all accessible accounts.
*/
Expand All @@ -814,7 +858,10 @@ export class IBApiNext {
() => {
this.api.cancelPositions();
},
[[EventName.position, this.onPosition]],
[
[EventName.position, this.onPosition],
[EventName.positionEnd, this.onPositionEnd],
],
"getPositions",
);
}
Expand Down Expand Up @@ -2363,28 +2410,26 @@ export class IBApiNext {

// console.log("onScannerData", item);

const lastValue = subscription.lastValue ?? {
all: new Map<MarketScannerItemRank, MarketScannerItem>(),
allset: false,
};
const lastAllValue =
subscription.lastAllValue ??
new Map<MarketScannerItemRank, MarketScannerItem>();

const existing = lastValue.all.get(rank) != undefined;
lastValue.all.set(rank, item);
if (lastValue.allset) {
const existing = lastAllValue.get(rank) != undefined;
lastAllValue.set(rank, item);
if (subscription.endEventReceived) {
const updated: MarketScannerRows = new Map<
MarketScannerItemRank,
MarketScannerItem
>();
updated.set(rank, item);
subscription.next({
all: lastValue.all,
allset: lastValue.allset,
all: lastAllValue,
changed: existing ? updated : undefined,
added: existing ? undefined : updated,
});
} else {
// console.log("saving for future use", lastValue);
subscription.lastValue = lastValue;
subscription.lastAllValue = lastAllValue;
}
};

Expand All @@ -2403,18 +2448,13 @@ export class IBApiNext {
return;
}

const lastValue = subscription.lastValue ?? {
all: new Map<MarketScannerItemRank, MarketScannerItem>(),
};
const lastAllValue =
subscription.lastAllValue ??
new Map<MarketScannerItemRank, MarketScannerItem>();
const updated: IBApiNextItemListUpdate<MarketScannerRows> = {
all: lastValue.all,
allset: true,
added: lastValue.all,
all: lastAllValue,
};

// console.log("onScannerDataEnd", updated);

// subscription.next(updated);
subscription.endEventReceived = true;
subscription.next(updated);
};

Expand Down Expand Up @@ -2539,10 +2579,14 @@ export class IBApiNext {
orderStatus: undefined,
};
allOrders.push(addedOrder);
sub.next({
all: allOrders,
added: [addedOrder],
});
if (sub.endEventReceived) {
sub.next({
all: allOrders,
added: [addedOrder],
});
} else {
sub.lastAllValue = allOrders;
}
} else {
// update
const updatedOrder: OpenOrder = allOrders[changeOrderIndex];
Expand All @@ -2564,13 +2608,16 @@ export class IBApiNext {
};

/**
* Ends the subscrition once all openOrders are recieved
* Ends the subscription once all openOrders are recieved
* @param subscriptions: listeners
*/
private readonly onOpenOrderEnd = (
private readonly onOpenOrderComplete = (
subscriptions: Map<number, IBApiNextSubscription<OpenOrder[]>>,
): void => {
subscriptions.forEach((sub) => {
const allOrders = sub.lastAllValue ?? [];
sub.endEventReceived = true;
sub.next({ all: allOrders });
sub.complete();
});
};
Expand Down Expand Up @@ -2675,6 +2722,21 @@ export class IBApiNext {
});
};

/**
* Ends the subscription once all openOrders are recieved
* @param subscriptions: listeners
*/
private readonly onOpenOrderEnd = (
subscriptions: Map<number, IBApiNextSubscription<OpenOrder[]>>,
): void => {
// notify all subscribers
subscriptions.forEach((subscription) => {
const lastAllValue = subscription.lastAllValue ?? [];
subscription.endEventReceived = true;
subscription.next({ all: lastAllValue });
});
};

/**
* Requests all current open orders in associated accounts at the current moment.
*/
Expand All @@ -2690,7 +2752,7 @@ export class IBApiNext {
[EventName.openOrder, this.onOpenOrder],
[EventName.orderStatus, this.onOrderStatus],
[EventName.orderBound, this.onOrderBound],
[EventName.openOrderEnd, this.onOpenOrderEnd],
[EventName.openOrderEnd, this.onOpenOrderComplete],
],
"getAllOpenOrders", // use same instance id each time, to make sure there is only 1 pending request at time
)
Expand All @@ -2715,6 +2777,7 @@ export class IBApiNext {
[EventName.openOrder, this.onOpenOrder],
[EventName.orderStatus, this.onOrderStatus],
[EventName.orderBound, this.onOrderBound],
[EventName.openOrderEnd, this.onOpenOrderEnd],
],
"getOpenOrders", // use same instance id each time, to make sure there is only 1 pending request at time
);
Expand All @@ -2738,6 +2801,7 @@ export class IBApiNext {
[EventName.openOrder, this.onOpenOrder],
[EventName.orderStatus, this.onOrderStatus],
[EventName.orderBound, this.onOrderBound],
[EventName.openOrderEnd, this.onOpenOrderEnd],
],
"getAutoOpenOrders", // use same instance id each time, to make sure there is only 1 pending request at time
);
Expand Down
3 changes: 0 additions & 3 deletions src/api-next/common/item-list-update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ export interface ItemListUpdate<T> {
/** All items with its latest values, as received by TWS. */
readonly all: T;

/** all value is set with all items (ie not still being built = End message received from TWS) */
readonly allset?: boolean;

/** Items that have been added since last [[IBApiNextUpdate]]. */
readonly added?: T;

Expand Down
1 change: 0 additions & 1 deletion src/core/api-next/item-list-update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,5 @@ export class IBApiNextItemListUpdate<T> implements ItemListUpdate<T> {
public readonly added?: T,
public readonly changed?: T,
public readonly removed?: T,
public readonly allset?: boolean,
) {}
}
Loading

0 comments on commit 2e1d601

Please sign in to comment.