Skip to content

Commit

Permalink
HistoricalTickLast
Browse files Browse the repository at this point in the history
  • Loading branch information
rylorin committed May 9, 2024
1 parent 05fdf1c commit 914d9ce
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 32 deletions.
16 changes: 8 additions & 8 deletions src/api-next/api-next.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1748,7 +1748,7 @@ export class IBApiNext {
* - OPTION_IMPLIED_VOLATILITY
* - FEE_RATE
* - REBATE_RATE
* @param useRTH Set to 0 to obtain the data which was also generated outside of the Regular Trading Hours, set to 1 to obtain only the RTH data
* @param useRTH Set to false to obtain the data which was also generated outside of the Regular Trading Hours, set to true to obtain only the RTH data
* @param formatDate Set to 1 to obtain the bars' time as yyyyMMdd HH:mm:ss, set to 2 to obtain it like system time format in seconds
*/
getHistoricalData(
Expand All @@ -1757,7 +1757,7 @@ export class IBApiNext {
durationStr: string,
barSizeSetting: BarSizeSetting,
whatToShow: WhatToShow,
useRTH: number,
useRTH: number | boolean,
formatDate: number,
): Promise<Bar[]> {
return lastValueFrom(
Expand Down Expand Up @@ -1927,14 +1927,14 @@ export class IBApiNext {
* @param startDateTime "20170701 12:01:00". Uses TWS timezone specified at login.
* @param endDateTime "20170701 13:01:00". In TWS timezone. Exactly one of start time and end time has to be defined.
* @param numberOfTicks Number of distinct data points. Max currently 1000 per request.
* @param useRTH Data from regular trading hours (1), or all available hours (0)
* @param useRTH Data from regular trading hours (true), or all available hours (false)
*/
getHistoricalTicksMid(
contract: Contract,
startDateTime: string,
endDateTime: string,
numberOfTicks: number,
useRTH: number,
useRTH: number | boolean,
): Observable<HistoricalTick[]> {
return this.subscriptions
.register<HistoricalTick[]>(
Expand Down Expand Up @@ -1995,15 +1995,15 @@ export class IBApiNext {
* @param startDateTime "20170701 12:01:00". Uses TWS timezone specified at login.
* @param endDateTime "20170701 13:01:00". In TWS timezone. Exactly one of start time and end time has to be defined.
* @param numberOfTicks Number of distinct data points. Max currently 1000 per request.
* @param useRTH Data from regular trading hours (1), or all available hours (0)
* @param useRTH Data from regular trading hours (true), or all available hours (false)
* @param ignoreSize A filter only used when the source price is Bid_Ask
*/
getHistoricalTicksBidAsk(
contract: Contract,
startDateTime: string,
endDateTime: string,
numberOfTicks: number,
useRTH: number,
useRTH: number | boolean,
ignoreSize: boolean,
): Observable<HistoricalTickBidAsk[]> {
return this.subscriptions
Expand Down Expand Up @@ -2063,14 +2063,14 @@ export class IBApiNext {
* @param startDateTime "20170701 12:01:00". Uses TWS timezone specified at login.
* @param endDateTime "20170701 13:01:00". In TWS timezone. Exactly one of start time and end time has to be defined.
* @param numberOfTicks Number of distinct data points. Max 1000 per request.
* @param useRTH Data from regular trading hours (1), or all available hours (0)
* @param useRTH Data from regular trading hours (true), or all available hours (false)
*/
getHistoricalTicksLast(
contract: Contract,
startDateTime: string,
endDateTime: string,
numberOfTicks: number,
useRTH: number,
useRTH: number | boolean,
): Observable<HistoricalTickLast[]> {
return this.subscriptions
.register<HistoricalTickLast[]>(
Expand Down
20 changes: 13 additions & 7 deletions src/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,14 @@ import OptionExerciseAction from "./data/enum/option-exercise-action";
import { BarSizeSetting } from "./historical/bar-size-setting";
import { HistogramEntry } from "./historical/histogramEntry";
import { HistoricalTick } from "./historical/historicalTick";
import { HistoricalTickBidAsk } from "./historical/historicalTickBidAsk";
import { HistoricalTickLast } from "./historical/historicalTickLast";
import {
HistoricalTickBidAsk,
TickAttribBidAsk,
} from "./historical/historicalTickBidAsk";
import {
HistoricalTickLast,
TickAttribLast,
} from "./historical/historicalTickLast";
import { ScannerSubscription } from "./market/scannerSubscription";
import { TickByTickDataType } from "./market/tickByTickDataType";
import { TickType } from "./market/tickType";
Expand Down Expand Up @@ -959,7 +965,7 @@ export class IBApi extends EventEmitter {
* - OPTION_IMPLIED_VOLATILITY
* - FEE_RATE
* - REBATE_RATE
* @param useRTH Set to 0 to obtain the data which was also generated outside of the Regular Trading Hours, set to 1
* @param useRTH Set to `false` to obtain the data which was also generated outside of the Regular Trading Hours, set to `true`
* to obtain only the RTH data
* @param formatDate Set to 1 to obtain the bars' time as yyyyMMdd HH:mm:ss, set to 2 to obtain it like system time
* format in seconds
Expand All @@ -973,7 +979,7 @@ export class IBApi extends EventEmitter {
durationStr: string,
barSizeSetting: BarSizeSetting,
whatToShow: WhatToShow,
useRTH: number,
useRTH: number | boolean,
formatDate: number,
keepUpToDate: boolean,
): IBApi {
Expand Down Expand Up @@ -1045,7 +1051,7 @@ export class IBApi extends EventEmitter {
endDateTime: string,
numberOfTicks: number,
whatToShow: WhatToShow,
useRTH: number,
useRTH: number | boolean,
ignoreSize: boolean,
): IBApi {
this.controller.schedule(() =>
Expand Down Expand Up @@ -2994,7 +3000,7 @@ export declare interface IBApi {
time: number,
price: number,
size: number,
tickAttribLast: unknown /* TODO: replace with TickAttribLast type as soon as available. */,
tickAttribLast: TickAttribLast,
exchange: string,
specialConditions: string,
) => void,
Expand Down Expand Up @@ -3029,7 +3035,7 @@ export declare interface IBApi {
askPrice: number,
bidSize: number,
askSize: number,
tickAttribBidAsk: unknown /* TODO: replace with TickAttribBidAsk type as soon as available. */,
tickAttribBidAsk: TickAttribBidAsk,
) => void,
): this;

Expand Down
4 changes: 2 additions & 2 deletions src/api/historical/historicalTickLast.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Attributes of a [[HistoricalTickBidAsk]].
*/
export interface TickAttribBidAsk {
export interface TickAttribLast {
/** TODO document */
pastLimit?: boolean;

Expand All @@ -19,7 +19,7 @@ export interface HistoricalTickLast {
time?: number;

/** Tick attribs of historical last tick. */
tickAttribBidAsk?: TickAttribBidAsk;
tickAttribLast?: TickAttribLast;

/** The last price of the historical tick. */
price?: number;
Expand Down
2 changes: 1 addition & 1 deletion src/core/io/decoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2405,7 +2405,7 @@ export class Decoder {
const specialConditions = this.readStr();
ticks[i] = {
time: time,
tickAttribBidAsk: {
tickAttribLast: {
pastLimit: (mask & (1 << 0)) !== 0,
unreported: (mask & (1 << 1)) !== 0,
},
Expand Down
4 changes: 2 additions & 2 deletions src/core/io/encoder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2101,7 +2101,7 @@ function tagValuesToTokens(tagValues: TagValue[]): unknown[] {
durationStr: string,
barSizeSetting: BarSizeSetting,
whatToShow: WhatToShow,
useRTH: number,
useRTH: number | boolean,
formatDate: number,
keepUpToDate: boolean,
chartOptions?: TagValue[],
Expand Down Expand Up @@ -2219,7 +2219,7 @@ function tagValuesToTokens(tagValues: TagValue[]): unknown[] {
endDateTime: string,
numberOfTicks: number,
whatToShow: WhatToShow,
useRth: number,
useRth: number | boolean,
ignoreSize: boolean,
miscOptions?: TagValue[],
): void {
Expand Down
99 changes: 99 additions & 0 deletions src/tests/unit/api-next-live/get-historical-ticks.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/**
* This file implements tests for the [[IBApiNext.getContractDetails]] function.
*/

import { Subscription } from "rxjs";
import { IBApiNext } from "../../..";
import { sample_etf } from "../sample-data/contracts";

describe("ApiNext: getContractDetails()", () => {
jest.setTimeout(10 * 1000);

const clientId = Math.floor(Math.random() * 32766) + 1; // ensure unique client

let api: IBApiNext;
let error$: Subscription;

beforeEach(() => {
api = new IBApiNext();

if (!error$) {
error$ = api.errorSubject.subscribe((error) => {
if (error.reqId === -1) {
console.warn(`${error.error.message} (Error #${error.code})`);
} else {
console.error(
`${error.error.message} (Error #${error.code}) ${
error.advancedOrderReject ? error.advancedOrderReject : ""
}`,
);
}
});
}

try {
api.connect(clientId);
} catch (error) {
console.error(error.message);
}
});

afterEach(() => {
if (api) {
api.disconnect();
api = undefined;
}
});

test("ETF historical ticks last", (done) => {
api
.getHistoricalTicksLast(sample_etf, "20240508-17:00:00", null, 1, true)
// eslint-disable-next-line rxjs/no-ignored-subscription
.subscribe({
next: (ticks) => {
// console.log(ticks.length, ticks);
expect(ticks.length).toEqual(17);
expect(ticks[0].time).toEqual(1715187600);
expect(ticks[0].price).toEqual(516.635);
expect(ticks[0].size).toEqual(1);
expect(ticks[0].exchange).toEqual("FINRA");
},
complete: () => {
done();
},
error: () => {
done("Some error occured!");
},
});
});

test("ETF historical bid/ask ticks", (done) => {
api
.getHistoricalTicksBidAsk(
sample_etf,
"20240508-17:00:00",
null,
1,
true,
true,
)
// eslint-disable-next-line rxjs/no-ignored-subscription
.subscribe({
next: (ticks) => {
// console.log(ticks.length, ticks);
expect(ticks.length).toEqual(34);
expect(ticks[0].time).toEqual(1715187599);
expect(ticks[0].priceBid).toEqual(516.62);
expect(ticks[0].priceAsk).toEqual(516.63);
expect(ticks[0].sizeBid).toEqual(1100);
expect(ticks[0].sizeAsk).toEqual(1400);
},
complete: () => {
done();
},
error: () => {
done("Some error occured!");
},
});
});
});
18 changes: 6 additions & 12 deletions src/tests/unit/api/historical-data.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
*/
import {
BarSizeSetting,
Contract,
EventName,
IBApi,
Option,
OptionType,
Stock,
WhatToShow,
} from "../../..";
import configuration from "../../../common/configuration";
import { sample_etf } from "../sample-data/contracts";

describe("IBApi Historical data Tests", () => {
jest.setTimeout(10 * 1000);
Expand Down Expand Up @@ -41,10 +40,9 @@ describe("IBApi Historical data Tests", () => {
let counter = 0;

ib.once(EventName.connected, () => {
const contract: Contract = new Stock("SPY");
ib.reqHistoricalData(
refId,
contract,
sample_etf,
"20231006-20:00:00",
"30 S",
BarSizeSetting.SECONDS_ONE,
Expand Down Expand Up @@ -176,10 +174,9 @@ describe("IBApi Historical data Tests", () => {
let counter = 0;

ib.once(EventName.connected, () => {
const contract: Contract = new Stock("SPY");
ib.reqHistoricalData(
refId,
contract,
sample_etf,
"20230904-20:00:00",
"1 M",
BarSizeSetting.WEEKS_ONE,
Expand Down Expand Up @@ -241,10 +238,9 @@ describe("IBApi Historical data Tests", () => {
let counter = 0;

ib.once(EventName.connected, () => {
const contract: Contract = new Stock("SPY");
ib.reqHistoricalData(
refId,
contract,
sample_etf,
"20230904-20:00:00",
"1 Y",
BarSizeSetting.MONTHS_ONE,
Expand Down Expand Up @@ -319,12 +315,10 @@ describe("IBApi Historical data Tests", () => {
if (reqId == refId) done(`[${reqId}] ${err.message} (#${code})`);
});

const contract: Contract = new Stock("SPY");

ib.connect().reqHistoricalTicks(
refId,
contract,
"20240102-16:00:00",
sample_etf,
"20240508-17:00:00",
null,
10,
WhatToShow.TRADES,
Expand Down

0 comments on commit 914d9ce

Please sign in to comment.